sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #03715
[Merge] ~maas-committers/maas-ci/+git/system-tests:ansible-tests into ~maas-committers/maas-ci/+git/system-tests:master
Jack Lloyd-Walters has proposed merging ~maas-committers/maas-ci/+git/system-tests:ansible-tests into ~maas-committers/maas-ci/+git/system-tests:master.
Commit message:
Add system tests for Ansible Playbooks
Requested reviews:
MAAS Committers (maas-committers)
For more details, see:
https://code.launchpad.net/~maas-committers/maas-ci/+git/system-tests/+merge/433880
--
Your team MAAS Committers is requested to review the proposed merge of ~maas-committers/maas-ci/+git/system-tests:ansible-tests into ~maas-committers/maas-ci/+git/system-tests:master.
diff --git a/README.md b/README.md
index 2a998fc..52e2d75 100644
--- a/README.md
+++ b/README.md
@@ -50,7 +50,11 @@ for init in inits:
docstring = textwrap.fill(module.__doc__, 80)
cog.outl(f" - `{package}`: {docstring}\n")
]]] -->
-We have 4 test suites:
+We have 5 test suites:
+ - `ansible_tests`: Prepares a container running ansible, and clones maas/maas-ansible-playbooks,
+to test their MAAS topolgy is configurable with Ansible, and that the MAAS
+install behaves as expected under testing.
+
- `collect_sos_report`: Collect an SOS report from the test run.
- `env_builder`: Prepares a container with a running MAAS ready to run the tests, and writes a
diff --git a/lxd_configs/configure_lxd.sh b/lxd_configs/configure_lxd.sh
old mode 100644
new mode 100755
index 27fe4e6..cffcc1e
--- a/lxd_configs/configure_lxd.sh
+++ b/lxd_configs/configure_lxd.sh
@@ -24,7 +24,6 @@ cat maas_lab.profile | lxc profile edit prof-maas-lab
lxc profile create prof-maas-test
cat maas_test.profile | lxc profile edit prof-maas-test
-
lxc init vm1 --vm --empty -p prof-maas-test
VM1_MAC_ADDRESS=$(lxc config get vm1 volatile.eth0.hwaddr)
echo "VM1 mac_address is $VM1_MAC_ADDRESS"
diff --git a/systemtests/__init__.py b/systemtests/__init__.py
index 77623bb..93dfafa 100644
--- a/systemtests/__init__.py
+++ b/systemtests/__init__.py
@@ -1,6 +1,7 @@
import pytest
pytest.register_assert_rewrite(
+ "systemtests.ansible",
"systemtests.api",
"systemtests.region",
"systemtests.state",
diff --git a/systemtests/ansible.py b/systemtests/ansible.py
new file mode 100644
index 0000000..17c1a64
--- /dev/null
+++ b/systemtests/ansible.py
@@ -0,0 +1,442 @@
+import json
+import re
+import warnings
+from contextlib import contextmanager
+from logging import getLogger
+from typing import Optional
+
+import pytest
+
+from .lxd import get_lxd
+from .region import MAASRegion
+
+NAME = "systemtests.ansible"
+LOG = getLogger(NAME)
+
+
+class MissingRoleOnHost(Exception):
+ """Raised when a host is missing a role they were expected to have."""
+
+ pass
+
+
+class HostWithoutRole(Warning):
+ """Raised when a host does not have any assigned roles."""
+
+ pass
+
+
+class MAASRegionExtension(MAASRegion):
+ @property
+ def version(self) -> str:
+ v_info = json.loads(self.execute(["maas", "admin", "version", "read"]).stdout)
+ return v_info.get("version")
+
+ def login(self, user: str) -> None:
+ self.execute(
+ [
+ "maas",
+ "login",
+ "admin",
+ f"{self.url}/api/2.0/",
+ self.get_api_token(user),
+ ]
+ )
+
+
+class AnsibleShared:
+ config = {}
+ lxd = get_lxd(LOG)
+
+ def __init__(self, user: Optional[str] = "ubuntu") -> None:
+ self.base_filepath = f"/home/{user}"
+ self.host_file = f"{self.base_filepath}/hosts"
+ self.user = user
+
+ def __repr__(self) -> str:
+ return f"<{self.__class__.__name__} in container {self.name}"
+
+ def apt_install(self, module: str) -> None:
+ if self.has_container:
+ self.execute(["apt-get", "update", "-y"])
+ self.execute(["dpkg", "--configure", "-a"])
+ self.execute(["apt", "install", module, "-y"])
+
+ def module_exists(self, module: str) -> bool:
+ if self.has_container:
+ return bool(self.quietly_execute(["pip3", "list", "|", "grep", module]))
+
+ def pip_install(self, module: str) -> None:
+ if self.has_container:
+ if not self.module_exists(module):
+ self.execute(["pip3", "install", module, "-y"])
+ else:
+ self.execute(["pip3", "install", module, "--upgrade"])
+
+ @property
+ def has_container(self) -> bool:
+ return self.lxd.container_exists(self.name)
+
+ @property
+ def ip(self) -> str:
+ if self.has_container:
+ return self.lxd.get_ip_address(self.name)
+
+ def restart(self) -> None:
+ self.lxd.restart(self.name, True)
+
+ def execute(self, command: list[str]) -> str:
+ if isinstance(command, str):
+ command = command.split(" ")
+ return self.lxd.execute(self.name, command).stdout
+
+ def try_execute(self, command: list[str]) -> str:
+ try:
+ return self.execute(command)
+ except Exception as e:
+ LOG.warning(e)
+
+ def quietly_execute(self, command: list[str]) -> str:
+ return self.lxd.quietly_execute(self.name, command).stdout
+
+ def absolute_file_path(self, file_path: str) -> str:
+ if file_path[0] == "~":
+ file_path = f"{self.base_filepath}{file_path[1:]}"
+ return file_path
+
+ def abs_fp(self, file_path: str) -> str:
+ return self.absolute_file_path(file_path)
+
+ def file_exists(self, file_path: str) -> bool:
+ return self.lxd.file_exists(self.name, self.absolute_file_path(file_path))
+
+ def get_file_contents(self, file_path: str) -> str:
+ if file_path[0] == "~":
+ file_path = f"{self.base_filepath}{file_path[1:]}"
+ return self.lxd.get_file_contents(self.name, self.absolute_file_path(file_path))
+
+ def push_text_file(
+ self,
+ content: str,
+ target_file: str,
+ uid: int = 0,
+ gid: int = 0,
+ ) -> None:
+ self.lxd.push_text_file(
+ self.name, content, self.absolute_file_path(target_file), uid, gid
+ )
+
+ def append_to_file(self, content: str, file_path: str) -> None:
+ file_content = (
+ self.get_file_contents(file_path).split("\n")
+ if self.file_exists(file_path)
+ else []
+ )
+ if file_content[-1] == "":
+ file_content = file_content[:-1]
+ file_content.extend(
+ content.split("\n") if isinstance(content, str) else content
+ )
+ self.push_text_file("\n".join(file_content), file_path)
+
+ def update_config(
+ self, config: dict[str, str], role: Optional[str] = None
+ ) -> dict[str, str]:
+ if role:
+ if role not in self.roles:
+ raise MissingRoleOnHost()
+ self.roles[role] |= config
+ return self.roles[role]
+ self.config |= config
+ return self.config
+
+ def fetch_config(self, config_key: str, role: Optional[str] = None) -> str:
+ if role:
+ if role not in self.roles:
+ raise MissingRoleOnHost()
+ role_conf = self.roles.get(role)
+ if config_key in role_conf:
+ return role_conf.get(config_key)
+ return self.config.get(config_key)
+
+
+class AnsibleHost(AnsibleShared):
+ roles = {}
+
+ def __init__(
+ self,
+ name: str,
+ image: str,
+ user_data: dict[str, str],
+ profile: str,
+ ) -> None:
+ self.name = name
+ self.image = image
+ self.user_data = user_data
+ self.profile = profile
+ super().__init__(image.split(":")[0])
+ self.config["ansible_user"] = self.user
+
+ def role_setup(self, role: str) -> list[str]:
+ return [f"{k}={v}" for k, v in self.roles.get(role, {}).items()]
+
+ def host_setup(self, role: Optional[str] = None) -> str:
+ cfg = [f"{k}={v}" for k, v in self.config.items()]
+ if role:
+ cfg += self.role_setup(role)
+ return " ".join([f"{self.ip}"] + cfg)
+
+ def add_test_db(self):
+ self.update_config({"maas_postgres_uri": "maas-test-db:///"})
+ if self.has_container:
+ self.execute("snap install maas-test-db")
+ return self
+
+ def _add_role_(self, role: str, config: dict[str, str]) -> None:
+ self.roles[role] = config | {"ansible_user": self.user}
+
+ def _remove_role_(self, role: str) -> None:
+ self.roles.pop(role)
+
+ def has_role(self, role: str) -> bool:
+ return self.has_container and role in self.roles
+
+ @property
+ def region(self) -> MAASRegionExtension:
+ if self.has_region:
+ url = self.fetch_config("maas_url", "maas_region_controller")
+ snap_install = (
+ self.fetch_config("maas_installation_type", "maas_region_controller")
+ == "snap",
+ )
+ return MAASRegionExtension(url, url, self.name, snap_install)
+
+ @property
+ def has_rack(self) -> bool:
+ return self.has_role("maas_rack_controller")
+
+ @property
+ def has_region(self) -> bool:
+ return self.has_role("maas_region_controller")
+
+ @property
+ def has_region_rack(self) -> bool:
+ return self.has_role("maas_region_controller") and self.has_role(
+ "maas_rack_controller"
+ )
+
+ def add_rack(self, config: dict[str, str] = {}):
+ self._add_role_("maas_rack_controller", config)
+ return self
+
+ def add_region(self, config: dict[str, str] = {}):
+ self._add_role_("maas_region_controller", config)
+ return self
+
+ def add_region_rack(self, config: dict[str, str] = {}):
+ self._add_role_("maas_rack_controller", config)
+ self._add_role_("maas_region_controller", config)
+ return self
+
+ def remove_rack(self) -> None:
+ self._remove_role_("maas_rack_controller")
+
+ def remove_region(self) -> None:
+ self._remove_role_("maas_region_controller")
+
+ def remove_region_rack(self) -> None:
+ self._remove_role_("maas_rack_controller")
+ self._remove_role_("maas_region_controller")
+
+
+class AnsibleMain(AnsibleShared):
+ _inventory_ = set()
+ ssh_key_file = "/home/ubuntu/.ssh/id_rsa.pub"
+
+ def __init__(self, name: str) -> None:
+ self.name = name
+ super().__init__()
+ self.apt_install("python3")
+ self.apt_install("python3-pip")
+ self.pip_install("ansible")
+ self.clone_repo("maas", "maas-ansible-playbook")
+ assert self.public_ssh_key
+
+ def clone_repo(self, user: str, repo: str):
+ repo_path = f"{self.base_filepath}/{repo}"
+ if not self.lxd.file_exists(self.name, repo_path):
+ self.execute(
+ [
+ "git",
+ "clone",
+ f"https://github.com/{user}/{repo}.git",
+ f"{repo_path}",
+ ]
+ )
+
+ @property
+ def public_ssh_key(self) -> str:
+ if not self.file_exists(self.ssh_key_file):
+ self.execute(["ssh-keygen", "-t", "rsa", "-f", self.ssh_key_file[:-4]])
+ key = self.execute(["cat", self.ssh_key_file])
+ self.execute(["chmod", "600", self.ssh_key_file.replace(".pub", "")])
+ self.execute(["chmod", "600", self.ssh_key_file])
+ return " ".join(key.split()[:2])
+
+ def add_key_to_host(self, host: AnsibleHost, ssh_key_file: Optional[str] = None):
+ self.try_execute(
+ ["ssh-keygen", "-f", self.abs_fp("~/.ssh/known_hosts"), "-R", host.ip]
+ )
+ host.append_to_file(
+ self.public_ssh_key, f"{host.abs_fp('~/.ssh/authorized_keys')}"
+ )
+ self.try_execute(
+ [
+ "ssh",
+ "-i",
+ self.ssh_key_file,
+ "-o",
+ "StrictHostKeyChecking=no",
+ f"{host.user}@{host.ip}",
+ ]
+ )
+ self.execute(
+ [
+ "ssh-copy-id",
+ "-i",
+ self.ssh_key_file,
+ f"{host.user}@{host.ip}",
+ ]
+ )
+
+ @contextmanager
+ def collect_inventory(self) -> list[str]:
+ hosts = set()
+ for host in self._inventory_:
+ if not host.roles:
+ warnings.warn(
+ f"Empty host: {host.name} has not been assigned a role.",
+ HostWithoutRole,
+ )
+ self.lxd.create_container(
+ host.name,
+ host.image,
+ f"ssh_authorized_keys:\n- {self.public_ssh_key}",
+ )
+ if host.config.get("maas_postgres_uri", "") == "maas-test-db:///":
+ host.add_test_db()
+ self.add_key_to_host(host)
+ self._inventory_.add(host)
+ hosts.add(host)
+ yield hosts
+ for host in hosts:
+ self.remove_host(host, delete=True)
+
+ def _make_host_name_(self) -> str:
+ """Determine the smallest number not yet used as a name"""
+ name_scheme = "ansible-host"
+ nums = set(
+ [
+ int(re.search(r"\d+", host.name).group())
+ for host in self._inventory_
+ if re.match(rf"{name_scheme}-\d+", host.name)
+ ]
+ )
+ if nums:
+ return f"{name_scheme}-{min(set(range(1, max(nums)+2)) - nums)}"
+ return f"{name_scheme}-1"
+
+ def add_host(
+ self,
+ name: Optional[str] = None,
+ image: Optional[str] = "ubuntu:focal",
+ user_data: Optional[dict[str, str]] = {},
+ profile: Optional[str] = None,
+ ) -> AnsibleHost:
+ host = AnsibleHost(
+ f"{name if name else self._make_host_name_()}",
+ image,
+ user_data,
+ profile,
+ )
+ self._inventory_.add(host)
+ return host
+
+ def remove_host(self, host: AnsibleHost, delete: Optional[bool] = False) -> None:
+ self._inventory_.discard(host)
+ if delete:
+ self.lxd.delete(host.name)
+
+ def create_hosts_file(self) -> None:
+ inventory, inv = {}, []
+ for host in self._inventory_:
+ if not host.roles:
+ warnings.warn(
+ f"Empty host: {host.name} has not been assigned a role.",
+ HostWithoutRole,
+ )
+ continue
+ for role in host.roles:
+ inventory[role] = inventory.get(role, []) + [host]
+ for role, hosts in inventory.items():
+ inv.append(f"[{role}]")
+ inv.extend([host.host_setup(role) for host in hosts])
+ inv.append("")
+ if [True for key in inventory.keys() if "postgres" in key]:
+ inv.extend(
+ [
+ "[maas_postgres:children]",
+ "maas_postgres_primary",
+ "maas_postgres_secondary",
+ "",
+ ]
+ )
+ inventory_content = "\n".join(inv)
+ self.push_text_file(inventory_content, self.host_file)
+
+ def create_config_file(self) -> None:
+ path = "~/maas-ansible-playbook/ansible.cfg"
+ if not self.file_exists(path):
+ self.push_text_file("[defaults]\ninventory = hosts", path)
+ if "host_key_checking" not in self.get_file_contents(path):
+ self.append_to_file(["host_key_checking = False"], path)
+ if "remote_user" not in self.get_file_contents(path):
+ self.append_to_file(["remote_user = ubuntu"], path)
+ self.execute("mkdir -p /etc/ansible")
+ self.push_text_file(self.get_file_contents(path), "/etc/ansible/ansible.cfg")
+
+ def run_playbook(
+ self, playbook: Optional[str] = "site.yaml", debug: Optional[str] = "-v"
+ ) -> None:
+ self.create_hosts_file()
+ self.create_config_file()
+ cmd = [
+ "ansible-playbook",
+ f"{self.base_filepath}/maas-ansible-playbook/{playbook}",
+ "-i",
+ self.host_file,
+ "--private-key",
+ self.ssh_key_file[:-4],
+ ]
+ debug = re.match(r"-(v)+", debug).group()
+ if debug:
+ cmd.append(debug)
+ if self.config:
+ cfg = " ".join([f"{k}={v}" for k, v in self.config.items()])
+ cmd.append("--extra-vars")
+ cmd.append(f'"{cfg}"')
+ self.execute(cmd)
+
+
+@pytest.fixture(scope="session")
+def ansible_main() -> AnsibleMain:
+ """Set up a new LXD container with ansible installed."""
+ container_name = "ansible-main"
+ lxd = get_lxd(LOG)
+ lxd.get_or_create(container_name, "ubuntu:focal")
+ main = AnsibleMain(container_name)
+ yield main
+ for host in main._inventory_:
+ if host.has_container:
+ lxd.delete(host.name)
+ lxd.delete(container_name)
diff --git a/systemtests/ansible_tests/__init__.py b/systemtests/ansible_tests/__init__.py
new file mode 100644
index 0000000..7c571b3
--- /dev/null
+++ b/systemtests/ansible_tests/__init__.py
@@ -0,0 +1,5 @@
+"""
+Prepares a container running ansible, and clones maas/maas-ansible-playbooks,
+to test their MAAS topolgy is configurable with Ansible, and that the MAAS
+install behaves as expected under testing.
+"""
diff --git a/systemtests/ansible_tests/test_ansible.py b/systemtests/ansible_tests/test_ansible.py
new file mode 100644
index 0000000..74209e5
--- /dev/null
+++ b/systemtests/ansible_tests/test_ansible.py
@@ -0,0 +1,82 @@
+import pytest
+
+from systemtests.ansible import ansible_main
+
+
+@pytest.mark.usefixtures("ansible_main")
+class TestConfigSetup:
+ def test_setup_ansible_main(self, ansible_main: ansible_main) -> None:
+ assert ansible_main.module_exists("ansible")
+ assert ansible_main.lxd.file_exists(
+ ansible_main.name,
+ f"/home/{ansible_main.user}/maas-ansible-playbook/README.md",
+ )
+
+ def test_setup_maas_region(self, ansible_main: ansible_main) -> None:
+ host = ansible_main.add_host().add_region(
+ {
+ "maas_version": "3.2",
+ }
+ )
+ with ansible_main.collect_inventory() as inv:
+ assert inv == {host}
+ assert host.ip
+ host.update_config(
+ {"maas_url": f"http://{host.ip}:5240/MAAS"}, "maas_region_controller"
+ )
+
+ config = host.roles.get("maas_region_controller")
+ assert config == {
+ "ansible_user": "ubuntu",
+ "maas_version": "3.2",
+ "maas_url": f"http://{host.ip}:5240/MAAS",
+ }
+ assert not ansible_main._inventory_
+ assert not host.has_container
+
+
+@pytest.mark.usefixtures("ansible_main")
+class TestAnsibleMAAS:
+ def test_maas_region_installed(self, ansible_main: ansible_main) -> None:
+ host = (
+ ansible_main.add_host()
+ .add_test_db()
+ .add_region_rack({"maas_version": "3.2", "maas_installation_type": "snap"})
+ )
+ with ansible_main.collect_inventory():
+ ansible_main.update_config({"maas_url": f"http://{host.ip}:5240/MAAS"})
+ ansible_main.run_playbook("site.yaml")
+ maas_region = host.region
+ maas_region.login("admin")
+ assert maas_region.user_exists("admin")
+ assert maas_region.version
+
+ def test_maas_region_updated(self, ansible_main: ansible_main) -> None:
+ start_version = "3.0"
+ upgrade_version = "3.2"
+ host = (
+ ansible_main.add_host()
+ .add_test_db()
+ .add_region_rack(
+ {"maas_version": start_version, "maas_installation_type": "snap"}
+ )
+ )
+ with ansible_main.collect_inventory():
+ ansible_main.update_config({"maas_url": f"http://{host.ip}:5240/MAAS"})
+ ansible_main.run_playbook("site.yaml")
+ host.region.login("admin")
+ assert host.region.version[:3] == start_version
+
+ ansible_main.run_playbook("site.yaml")
+ assert host.region.version[:3] == upgrade_version
+
+ # def test_maas_region_tests_pass(self, ansible_main: ansible_main) -> None:
+ # host = ansible_main.add_host().add_region()
+ # with ansible_main.collect_inventory():
+ # ansible_main.update_config(
+ # {
+ # "maas_url": f"http://{host.ip}:5240/MAAS",
+ # }
+ # )
+ # ansible_main.run_playbook("site.yaml")
+ # assert host.region
diff --git a/tox.ini b/tox.ini
index aa171e3..cb72bf4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -26,7 +26,7 @@ passenv =
MAAS_SYSTEMTESTS_CLIENT_CONTAINER
MAAS_SYSTEMTESTS_LXD_PROFILE
-[testenv:{env_builder,collect_sos_report,general_tests}]
+[testenv:{env_builder,collect_sos_report,general_tests,ansible_tests}]
passenv = {[base]passenv}
[testenv:cog]
@@ -55,6 +55,11 @@ commands=
# passenv = {{[base]passenv}}
# """)
#]]]
+
+[testenv:{opelt,stunky,vm1}]
+description=Per-machine tests for {envname}
+passenv = {[base]passenv}
+
#[[[end]]]
[testenv:format]
Follow ups
-
[Merge] ~maas-committers/maas-ci/+git/system-tests:ansible-tests into ~maas-committers/maas-ci/+git/system-tests:master
From: Jack Lloyd-Walters, 2023-01-17
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-20
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-18
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS PASS
From: MAAS Lander, 2022-12-12
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS PASS
From: MAAS Lander, 2022-12-12
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS PASS
From: MAAS Lander, 2022-12-12
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS PASS
From: MAAS Lander, 2022-12-12
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-12
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS PASS
From: MAAS Lander, 2022-12-08
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-07
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-07
-
Re: [Merge] ~maas-committers/maas-ci/+git/system-tests:ansible-tests into ~maas-committers/maas-ci/+git/system-tests:master
From: Diego Mascialino, 2022-12-06
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-06
-
Re: [Merge] ~maas-committers/maas-ci/+git/system-tests:ansible-tests into ~maas-committers/maas-ci/+git/system-tests:master
From: Diego Mascialino, 2022-12-06
-
Re: [Merge] ~maas-committers/maas-ci/+git/system-tests:ansible-tests into ~maas-committers/maas-ci/+git/system-tests:master
From: Adam Collard, 2022-12-06
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS PASS
From: MAAS Lander, 2022-12-06
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS PASS
From: MAAS Lander, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-05
-
Re: [Merge] ~maas-committers/maas-ci/+git/system-tests:ansible-tests into ~maas-committers/maas-ci/+git/system-tests:master
From: Jack Lloyd-Walters, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-05
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-02
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-02
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-02
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-12-02
-
Re: [UNITTESTS] -b ansible-tests lp:~maas-committers/maas-ci/+git/system-tests into -b master lp:~maas-committers/maas-ci/+git/system-tests - TESTS FAILED
From: MAAS Lander, 2022-11-30