diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml index 801904c7..780a93fc 100644 --- a/.github/workflows/integration_test.yaml +++ b/.github/workflows/integration_test.yaml @@ -3,17 +3,16 @@ name: Integration tests on: pull_request: schedule: - - cron: "0 15 * * SAT" + - cron: "0 15 * * SAT" concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: integration-tests: - uses: - canonical/operator-workflows/.github/workflows/integration_test.yaml@main + uses: canonical/operator-workflows/.github/workflows/integration_test.yaml@test/get-workflow-version-action secrets: inherit with: juju-channel: 3.6/stable @@ -28,5 +27,5 @@ jobs: allure-report: if: ${{ !cancelled() && github.event_name == 'schedule' }} needs: - - integration-tests + - integration-tests uses: canonical/operator-workflows/.github/workflows/allure_report.yaml@main diff --git a/docs/changelog.md b/docs/changelog.md index 4d65d883..50752304 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,6 +1,9 @@ +## [#213 Fix proxy setup] +* Fix proxy setup for image-relation joined hook. + ## [#219 Use Juju secrets](https://github.com/canonical/github-runner-image-builder-operator/pull/219) (2026-04-17) * Add new `openstack-password-secret` configuration option to securely store OpenStack passwords using Juju secrets. * Deprecated `openstack-password` configuration option (still supported for backward compatibility). diff --git a/src/charm.py b/src/charm.py index cdecae48..3ecddb83 100755 --- a/src/charm.py +++ b/src/charm.py @@ -102,7 +102,7 @@ def _on_upgrade_charm(self, _: ops.UpgradeCharmEvent) -> None: def _on_config_changed(self, _: ops.ConfigChangedEvent) -> None: """Handle charm configuration change events.""" builder_config_state = state.BuilderConfig.from_charm(charm=self) - self._setup_proxy_environment(builder_config_state.proxy) + self.setup_proxy_environment(builder_config_state.proxy) if not self._is_any_image_relation_ready(cloud_config=builder_config_state.cloud_config): return # The following lines should be covered by integration tests. @@ -119,7 +119,7 @@ def _on_config_changed(self, _: ops.ConfigChangedEvent) -> None: def _on_image_relation_changed(self, evt: ops.RelationChangedEvent) -> None: """Handle charm image relation changed event.""" builder_config_state = state.BuilderConfig.from_charm(charm=self) - self._setup_proxy_environment(builder_config_state.proxy) + self.setup_proxy_environment(builder_config_state.proxy) if not evt.unit: logger.info("No unit in image relation changed event. Skipping image building.") return @@ -158,7 +158,7 @@ def _on_image_relation_changed(self, evt: ops.RelationChangedEvent) -> None: def _on_run(self, _: RunEvent) -> None: """Handle the run event.""" builder_config_state = state.BuilderConfig.from_charm(charm=self) - self._setup_proxy_environment(builder_config_state.proxy) + self.setup_proxy_environment(builder_config_state.proxy) if not self._is_any_image_relation_ready(cloud_config=builder_config_state.cloud_config): return # The following line should be covered by the integration test. @@ -172,14 +172,14 @@ def _on_run_action(self, event: ops.ActionEvent) -> None: event: The run action event. """ builder_config_state = state.BuilderConfig.from_charm(charm=self) - self._setup_proxy_environment(builder_config_state.proxy) + self.setup_proxy_environment(builder_config_state.proxy) if not self._is_any_image_relation_ready(cloud_config=builder_config_state.cloud_config): event.fail("Image relation not yet ready.") return # The following line should be covered by the integration test. self._run() # pragma: nocover - def _setup_proxy_environment(self, proxy_config: state.ProxyConfig | None) -> None: + def setup_proxy_environment(self, proxy_config: state.ProxyConfig | None) -> None: """Set up proxy environment variables. Args: @@ -197,7 +197,7 @@ def _setup_builder(self) -> None: """Set up the builder application.""" builder_config_state = state.BuilderConfig.from_charm(charm=self) - self._setup_proxy_environment(builder_config_state.proxy) + self.setup_proxy_environment(builder_config_state.proxy) builder.initialize( app_init_config=builder.ApplicationInitializationConfig( diff --git a/src/image.py b/src/image.py index ba82ccaa..57011999 100644 --- a/src/image.py +++ b/src/image.py @@ -6,7 +6,7 @@ import json import logging from collections import defaultdict -from typing import Mapping, TypedDict, cast +from typing import TYPE_CHECKING, Mapping, TypedDict, cast import ops @@ -14,6 +14,9 @@ import charm_utils import state +if TYPE_CHECKING: + from charm import GithubRunnerImageBuilderCharm + logger = logging.getLogger(__name__) @@ -34,7 +37,7 @@ class ImageRelationData(TypedDict, total=False): class Observer(ops.Object): """The image relation observer.""" - def __init__(self, charm: ops.CharmBase): + def __init__(self, charm: "GithubRunnerImageBuilderCharm"): """Initialize the observer and register event handlers. Args: @@ -55,6 +58,7 @@ def _on_image_relation_joined(self, event: ops.RelationJoinedEvent) -> None: event: The event emitted when a relation is joined. """ build_config = state.BuilderConfig.from_charm(charm=self.charm) + self.charm.setup_proxy_environment(build_config.proxy) proxy = state.ProxyConfig.from_env() if not build_config.cloud_config.upload_cloud_ids: self.model.unit.status = ops.BlockedStatus( diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py index 67117818..18d2a12a 100644 --- a/tests/unit/test_charm.py +++ b/tests/unit/test_charm.py @@ -325,7 +325,7 @@ def test_setup_proxy_environment_with_proxy_config( no_proxy="localhost,127.0.0.1", ) - charm._setup_proxy_environment(proxy_config) + charm.setup_proxy_environment(proxy_config) assert os.environ["http_proxy"] == "http://proxy.example.com:8080" assert os.environ["https_proxy"] == "https://proxy.example.com:8443" diff --git a/tests/unit/test_image.py b/tests/unit/test_image.py index b072da07..f91110f4 100644 --- a/tests/unit/test_image.py +++ b/tests/unit/test_image.py @@ -77,7 +77,11 @@ def test__on_image_relation_joined( act: when _on_image_relation_joined hook is fired. assert: update_relation_data is called. """ - monkeypatch.setattr(state.BuilderConfig, "from_charm", MagicMock()) + mock_build_config = MagicMock() + mock_build_config.proxy = None + monkeypatch.setattr( + state.BuilderConfig, "from_charm", MagicMock(return_value=mock_build_config) + ) monkeypatch.setattr(state.CloudsAuthConfig, "from_unit_relation_data", MagicMock()) monkeypatch.setattr(builder, "install_clouds_yaml", MagicMock()) monkeypatch.setattr(builder, "get_latest_images", MagicMock(return_value="test-id"))