From 878ca04bbc1031d325567dd4ebc31467b4890a20 Mon Sep 17 00:00:00 2001 From: yhaliaw Date: Thu, 30 Oct 2025 10:46:30 +0800 Subject: [PATCH 01/10] Setup a restart backoff for the github-runner-manager service --- src/manager_service.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/manager_service.py b/src/manager_service.py index ac3b5b1479..1427c6c28f 100644 --- a/src/manager_service.py +++ b/src/manager_service.py @@ -200,6 +200,7 @@ def _setup_service_file(config_file: Path, log_file: Path, log_level: str) -> No f"""\ [Unit] Description=Runs the github-runner-manager service + StartLimitIntervalSec=0 [Service] Type=simple @@ -209,6 +210,9 @@ def _setup_service_file(config_file: Path, log_file: Path, log_level: str) -> No {GITHUB_RUNNER_MANAGER_ADDRESS} --port {GITHUB_RUNNER_MANAGER_PORT} \ --python-path {str(python_path)} --log-level {log_level} Restart=on-failure + RestartSec=30 + RestartSteps=5 + RestartMaxDelaySec=600 KillMode=process StandardOutput=append:{log_file} StandardError=append:{log_file} From 37da1a37f4ef850d04973a9a8b9be4488b974907 Mon Sep 17 00:00:00 2001 From: yhaliaw Date: Fri, 31 Oct 2025 09:21:25 +0800 Subject: [PATCH 02/10] Fix lint setting --- github-runner-manager/pyproject.toml | 2 +- .../src/github_runner_manager/metrics/runner.py | 8 ++++---- pyproject.toml | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/github-runner-manager/pyproject.toml b/github-runner-manager/pyproject.toml index d485400770..e01bbb8327 100644 --- a/github-runner-manager/pyproject.toml +++ b/github-runner-manager/pyproject.toml @@ -48,8 +48,8 @@ omit = [ fail_under = 73 show_missing = true - [tool.pylint.'MESSAGES CONTROL'] +good-names = ["ParamT", "ReturnT"] # see https://github.com/pydantic/pydantic/issues/1961#issuecomment-759522422 extension-pkg-whitelist = "pydantic" # Ignore W0511 TODO comments because the functions are subject to refactor. diff --git a/github-runner-manager/src/github_runner_manager/metrics/runner.py b/github-runner-manager/src/github_runner_manager/metrics/runner.py index 163ac95bad..76fcd96e66 100644 --- a/github-runner-manager/src/github_runner_manager/metrics/runner.py +++ b/github-runner-manager/src/github_runner_manager/metrics/runner.py @@ -303,15 +303,15 @@ def _parse_metrics_contents(metrics_contents_map: dict[Path, str | None]) -> _Pa if pre_job := metrics_contents_map.get(PRE_JOB_METRICS_FILE_PATH, None): try: pre_job_metrics = PreJobMetrics.parse_obj(json.loads(pre_job)) - except (json.JSONDecodeError, ValidationError): - logger.warning("Corrupt pre-job metrics: %s") + except (json.JSONDecodeError, ValidationError) as err: + logger.warning("Corrupt pre-job metrics: %s", err) post_job_metrics: PostJobMetrics | None = None if post_job := metrics_contents_map.get(POST_JOB_METRICS_FILE_PATH, None): try: post_job_metrics = PostJobMetrics.parse_obj(json.loads(post_job)) - except (json.JSONDecodeError, ValidationError): - logger.warning("Corrupt post-job metrics %s") + except (json.JSONDecodeError, ValidationError) as err: + logger.warning("Corrupt post-job metrics %s", err) return _ParsedMetricContents( runner_installed_timestamp=runner_installed_timestamp, diff --git a/pyproject.toml b/pyproject.toml index 25bb82caa4..e5121fb41b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,7 @@ markers = [ ] [tool.pylint.'MESSAGES CONTROL'] +good-names = ["ParamT", "ReturnT"] # see https://github.com/pydantic/pydantic/issues/1961#issuecomment-759522422 extension-pkg-whitelist = "pydantic" # Ignore W0511 TODO comments because the functions are subject to refactor. From 2e3361b79518f14b0acc76fb439ff9af53630d77 Mon Sep 17 00:00:00 2001 From: yhaliaw Date: Fri, 31 Oct 2025 10:27:29 +0800 Subject: [PATCH 03/10] Fix juju constaint for integration test --- tests/integration/conftest.py | 1 + tests/integration/helpers/common.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index b50ff03ab8..030b77af6e 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -469,6 +469,7 @@ async def app_openstack_runner_fixture( constraints={ "root-disk": 50 * 1024, "mem": 2 * 1024, + "virt-type": "virtual-machine", }, config={ OPENSTACK_CLOUDS_YAML_CONFIG_NAME: clouds_yaml_contents, diff --git a/tests/integration/helpers/common.py b/tests/integration/helpers/common.py index 0146cbb015..a217471eba 100644 --- a/tests/integration/helpers/common.py +++ b/tests/integration/helpers/common.py @@ -46,7 +46,7 @@ DISPATCH_E2E_TEST_RUN_OPENSTACK_WORKFLOW_FILENAME = "e2e_test_run_openstack.yaml" MONGODB_APP_NAME = "mongodb" -DEFAULT_RUNNER_CONSTRAINTS = {"root-disk": 15} +DEFAULT_RUNNER_CONSTRAINTS = {"root-disk": 15, "virt-type": "virtual-machine"} logger = logging.getLogger(__name__) From 2ed9c8c47d8656b31cff6f2ab1f18b4aab301699 Mon Sep 17 00:00:00 2001 From: yhaliaw Date: Fri, 31 Oct 2025 16:06:39 +0800 Subject: [PATCH 04/10] Update the deployment of image-builder and other charm in tests --- tests/integration/conftest.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 030b77af6e..e9541c8f3a 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -421,6 +421,9 @@ async def image_builder_fixture( application_name=application_name, channel="latest/edge", config=image_builder_config, + constraints={ + "virt-type": "virtual-machine", + }, ) else: app = model.applications[image_builder_app_name] @@ -588,7 +591,9 @@ async def app_no_wait_fixture( @pytest_asyncio.fixture(scope="module", name="tmate_ssh_server_app") async def tmate_ssh_server_app_fixture(model: Model) -> AsyncIterator[Application]: """tmate-ssh-server charm application related to GitHub-Runner app charm.""" - tmate_app: Application = await model.deploy("tmate-ssh-server", channel="edge") + tmate_app: Application = await model.deploy( + "tmate-ssh-server", channel="edge", constraints={"virt-type": "virtual-machine"} + ) return tmate_app @@ -738,7 +743,9 @@ async def app_for_metric_fixture( async def mongodb_fixture(model: Model, existing_app_suffix: str | None) -> Application: """Deploy MongoDB.""" if not existing_app_suffix: - mongodb = await model.deploy(MONGODB_APP_NAME, channel="6/edge") + mongodb = await model.deploy( + MONGODB_APP_NAME, channel="6/edge", constraints={"virt-type": "virtual-machine"} + ) else: mongodb = model.applications["mongodb"] return mongodb From 07631f41728647a09eff7f8bb837848d90e3b4d8 Mon Sep 17 00:00:00 2001 From: yhaliaw Date: Mon, 3 Nov 2025 22:45:06 +0800 Subject: [PATCH 05/10] Add cores constraint for image builder in integration test --- tests/integration/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index e9541c8f3a..bcfb58af27 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -422,6 +422,7 @@ async def image_builder_fixture( channel="latest/edge", config=image_builder_config, constraints={ + "cores": 2, "virt-type": "virtual-machine", }, ) From 63ef21b401934e0455fa5d54494773f022016957 Mon Sep 17 00:00:00 2001 From: yhaliaw Date: Thu, 6 Nov 2025 21:02:43 +0800 Subject: [PATCH 06/10] Remove the virt-type hack --- tests/integration/conftest.py | 12 +++--------- tests/integration/helpers/common.py | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index bcfb58af27..bf9f9a01a7 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -421,10 +421,6 @@ async def image_builder_fixture( application_name=application_name, channel="latest/edge", config=image_builder_config, - constraints={ - "cores": 2, - "virt-type": "virtual-machine", - }, ) else: app = model.applications[image_builder_app_name] @@ -473,7 +469,6 @@ async def app_openstack_runner_fixture( constraints={ "root-disk": 50 * 1024, "mem": 2 * 1024, - "virt-type": "virtual-machine", }, config={ OPENSTACK_CLOUDS_YAML_CONFIG_NAME: clouds_yaml_contents, @@ -593,7 +588,8 @@ async def app_no_wait_fixture( async def tmate_ssh_server_app_fixture(model: Model) -> AsyncIterator[Application]: """tmate-ssh-server charm application related to GitHub-Runner app charm.""" tmate_app: Application = await model.deploy( - "tmate-ssh-server", channel="edge", constraints={"virt-type": "virtual-machine"} + "tmate-ssh-server", + channel="edge", ) return tmate_app @@ -744,9 +740,7 @@ async def app_for_metric_fixture( async def mongodb_fixture(model: Model, existing_app_suffix: str | None) -> Application: """Deploy MongoDB.""" if not existing_app_suffix: - mongodb = await model.deploy( - MONGODB_APP_NAME, channel="6/edge", constraints={"virt-type": "virtual-machine"} - ) + mongodb = await model.deploy(MONGODB_APP_NAME, channel="6/edge") else: mongodb = model.applications["mongodb"] return mongodb diff --git a/tests/integration/helpers/common.py b/tests/integration/helpers/common.py index a217471eba..0146cbb015 100644 --- a/tests/integration/helpers/common.py +++ b/tests/integration/helpers/common.py @@ -46,7 +46,7 @@ DISPATCH_E2E_TEST_RUN_OPENSTACK_WORKFLOW_FILENAME = "e2e_test_run_openstack.yaml" MONGODB_APP_NAME = "mongodb" -DEFAULT_RUNNER_CONSTRAINTS = {"root-disk": 15, "virt-type": "virtual-machine"} +DEFAULT_RUNNER_CONSTRAINTS = {"root-disk": 15} logger = logging.getLogger(__name__) From 2a7eff9ad99e3d5252a6f223172d703d935d10ec Mon Sep 17 00:00:00 2001 From: yhaliaw Date: Thu, 13 Nov 2025 13:08:25 +0800 Subject: [PATCH 07/10] Remove an extra blank line --- .github/workflows/docs.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index aeffd9cf9e..38379d38f5 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -11,4 +11,3 @@ jobs: secrets: inherit with: linkcheck-files: "'*.md' 'docs/**/*.md' 'terraform/**/*.md' './**/*.rst'" - From 90a5fc7b11441034f5de955df2d4dbe2c59353b7 Mon Sep 17 00:00:00 2001 From: Christopher Bartz Date: Wed, 12 Nov 2025 08:17:50 +0100 Subject: [PATCH 08/10] use rustup for more recent toolchain --- charmcraft.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/charmcraft.yaml b/charmcraft.yaml index 09e6a6060e..72266be193 100644 --- a/charmcraft.yaml +++ b/charmcraft.yaml @@ -10,8 +10,12 @@ parts: - git # for installing git source of pylxd - libffi-dev # for cffi - libssl-dev # for cryptography - - rust-all # for cryptography - pkg-config # for cryptography + build-snaps: + - rustup # for cryptography + override-build: | + rustup default stable + craftctl default bases: - build-on: - name: "ubuntu" From 99fe0d1870a490a2aa65662dd48a4c2a5d8aa3d4 Mon Sep 17 00:00:00 2001 From: Christopher Bartz Date: Wed, 12 Nov 2025 09:31:06 +0100 Subject: [PATCH 09/10] remove unused fixture --- tests/integration/test_prometheus_metrics.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/test_prometheus_metrics.py b/tests/integration/test_prometheus_metrics.py index f5fa99feb6..907f148ddb 100644 --- a/tests/integration/test_prometheus_metrics.py +++ b/tests/integration/test_prometheus_metrics.py @@ -79,7 +79,6 @@ def prometheus_app_fixture(k8s_juju: jubilant.Juju): return k8s_juju.status().apps["prometheus-k8s"] -@pytest.mark.usefixtures("switch_microk8s_controller") @pytest.fixture(scope="module", name="grafana_app") def grafana_app_fixture(k8s_juju: jubilant.Juju, prometheus_app: AppStatus): """Deploy prometheus charm.""" From 6b55c1c8ee078ad56ed361122b8a4564e39c587a Mon Sep 17 00:00:00 2001 From: Christopher Bartz Date: Wed, 12 Nov 2025 09:14:00 +0100 Subject: [PATCH 10/10] remove unused fixture --- tests/integration/test_prometheus_metrics.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tests/integration/test_prometheus_metrics.py b/tests/integration/test_prometheus_metrics.py index 907f148ddb..8bf8e53eed 100644 --- a/tests/integration/test_prometheus_metrics.py +++ b/tests/integration/test_prometheus_metrics.py @@ -40,19 +40,6 @@ def k8s_juju_fixture(request: pytest.FixtureRequest) -> Generator[jubilant.Juju, yield juju -# juju.offer is not controller aware, we should manually switch to the microk8s controller. -@pytest.fixture(scope="function", name="switch_microk8s_controller") -def switch_microk8s_controller_fixture(k8s_juju: jubilant.Juju, juju: jubilant.Juju): - """Switch to the MicroK8s controller.""" - original_model_controller_name = juju.model - assert ( - original_model_controller_name - ), f"model & controller name not set: {original_model_controller_name}" - - yield - - -@pytest.mark.usefixtures("switch_microk8s_controller") @pytest.fixture(scope="module", name="prometheus_app") def prometheus_app_fixture(k8s_juju: jubilant.Juju): """Deploy prometheus charm."""