diff --git a/.github/workflows/integration_test.yaml b/.github/workflows/integration_test.yaml index 8f9a8ba6..7a8319b3 100644 --- a/.github/workflows/integration_test.yaml +++ b/.github/workflows/integration_test.yaml @@ -41,12 +41,16 @@ jobs: arch: - {id: amd64, builder-label: ubuntu-22.04, tester-arch: x64} - {id: arm64, builder-label: ARM64, tester-arch: ARM64} - suite: ["k8s", "etcd", "ceph"] + suite: [k8s, etcd, ceph] + exclude: + - {id: {arch: arm64}, suite: ceph} with: identifier: ${{ matrix.arch.id }}-${{ matrix.suite }} builder-runner-label: ${{ matrix.arch.builder-label }} charmcraft-channel: ${{ needs.charmcraft-channel.outputs.channel }} - extra-arguments: ${{needs.extra-args.outputs.args}} -k test_${{ matrix.suite }} + extra-arguments: >- + ${{needs.extra-args.outputs.args}} -k test_${{ matrix.suite }} + ${{ matrix.arch.id == 'arm64' && ' --lxd-containers' || '' }} juju-channel: 3/stable load-test-enabled: false provider: lxd diff --git a/charms/worker/k8s/templates/snap_installation.yaml b/charms/worker/k8s/templates/snap_installation.yaml index 31244c6d..f8528062 100644 --- a/charms/worker/k8s/templates/snap_installation.yaml +++ b/charms/worker/k8s/templates/snap_installation.yaml @@ -5,7 +5,9 @@ amd64: - name: k8s install-type: store channel: edge + classic: true arm64: - name: k8s install-type: store channel: edge + classic: true \ No newline at end of file diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 90c8fa0e..ffd7857a 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -6,6 +6,7 @@ import contextlib import json import logging +import re import shlex from dataclasses import dataclass, field from itertools import chain @@ -92,6 +93,23 @@ class Charm: arch: str path: Path _charmfile: Optional[Path] = None + _URL_RE = re.compile(r"ch:(?P\w+)/(?P\w+)/(?P.+)") + + @staticmethod + def craft_url(charm: str, series: str, arch: str) -> str: + """Craft a charm URL. + + Args: + charm: Charm name + series: Cloud series + arch: Cloud architecture + + Returns: + string: URL to the charm + """ + if m := Charm._URL_RE.match(charm): + charm = m.group("charm") + return f"ch:{arch}/{series}/{charm}" @property def metadata(self) -> dict: @@ -145,19 +163,25 @@ class Bundle: ops_test: Instance of the pytest-operator plugin path: Path to the bundle file content: Loaded content from the path + arch: Cloud Architecture render: Path to a rendered bundle applications: Mapping of applications in the bundle. """ ops_test: OpsTest path: Path + arch: str _content: Mapping = field(default_factory=dict) @property def content(self) -> Mapping: """Yaml content of the bundle loaded into a dict""" if not self._content: - self._content = yaml.safe_load(self.path.read_bytes()) + loaded = yaml.safe_load(self.path.read_bytes()) + series = loaded.get("series", "focal") + for app in loaded["applications"].values(): + app["charm"] = Charm.craft_url(app["charm"], series=series, arch=self.arch) + self._content = loaded return self._content @property @@ -168,6 +192,7 @@ def applications(self) -> Mapping[str, dict]: @property def render(self) -> Path: """Path to written bundle config to be deployed.""" + self.add_constraints({"arch": self.arch}) target = self.ops_test.tmp_path / "bundles" / self.path.name target.parent.mkdir(exist_ok=True, parents=True) yaml.safe_dump(self.content, target.open("w")) @@ -204,18 +229,6 @@ def add_constraints(self, constraints: Dict[str, str]): existing.update(constraints) app["constraints"] = " ".join(f"{k}={v}" for k, v in existing.items()) - def add_constraints(self, constraints: Dict[str, str]): - """Add constraints to applications. - - Args: - constraints: Mapping of constraints to add to applications. - """ - for app in self.applications.values(): - val: str = app["constraints"] - existing = dict(kv.split("=", 1) for kv in val.split()) - existing.update(constraints) - app["constraints"] = " ".join(f"{k}={v}" for k, v in existing.items()) - async def cloud_arch(ops_test: OpsTest) -> str: """Return current architecture of the selected controller @@ -338,14 +351,26 @@ async def deploy_model( log.fatal("Failed to determine model: model_name=%s", model_name) +def bundle_file(request) -> Path: + """Fixture to get bundle file. + + Args: + request: pytest request object + + Returns: + path to test's bundle file + """ + _file = "test-bundle.yaml" + bundle_marker = request.node.get_closest_marker("bundle_file") + if bundle_marker: + _file = bundle_marker.args[0] + return Path(__file__).parent / "data" / _file + + @pytest_asyncio.fixture(scope="module") async def kubernetes_cluster(request: pytest.FixtureRequest, ops_test: OpsTest): """Deploy local kubernetes charms.""" - bundle_file = "test-bundle.yaml" - bundle_marker = request.node.get_closest_marker("bundle_file") - if bundle_marker: - bundle_file = bundle_marker.args[0] - bundle_path = Path(__file__).parent / "data" / bundle_file + bundle_path = bundle_file(request) model = "main" with ops_test.model_context(model) as the_model: @@ -362,7 +387,7 @@ async def kubernetes_cluster(request: pytest.FixtureRequest, ops_test: OpsTest): charm_files = await asyncio.gather( *[charm.resolve(request.config.option.charm_files) for charm in charms] ) - bundle = Bundle(ops_test, bundle_path) + bundle = Bundle(ops_test, bundle_path, arch) _type, _vms = await cloud_type(ops_test) if _type == "lxd" and not _vms: log.info("Drop lxd machine constraints") @@ -372,7 +397,6 @@ async def kubernetes_cluster(request: pytest.FixtureRequest, ops_test: OpsTest): bundle.add_constraints({"virt-type": "virtual-machine"}) if request.config.option.apply_proxy: await cloud_proxied(ops_test) - bundle.add_constraints({"arch": arch}) for path, charm in zip(charm_files, charms): bundle.switch(charm.app_name, path) async with deploy_model(request, ops_test, model, bundle) as the_model: @@ -388,7 +412,7 @@ async def grafana_agent(kubernetes_cluster: Model): machine_series = juju.utils.get_version_series(data["base"].split("@")[1]) await kubernetes_cluster.deploy( - f"ch:{machine_arch}/{machine_series}/grafana-agent", + Charm.craft_url("grafana-agent", machine_series, machine_arch), channel="stable", series=machine_series, )