sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #04427
[Merge] ~adam-collard/maas-ci/+git/system-tests:lxd-logger-name into ~maas-committers/maas-ci/+git/system-tests:master
Adam Collard has proposed merging ~adam-collard/maas-ci/+git/system-tests:lxd-logger-name into ~maas-committers/maas-ci/+git/system-tests:master.
Commit message:
Unify name of instance_name
lxd: configure named logger for all instance-related LXD ops
Requested reviews:
MAAS Committers (maas-committers)
For more details, see:
https://code.launchpad.net/~adam-collard/maas-ci/+git/system-tests/+merge/435598
--
Your team MAAS Committers is requested to review the proposed merge of ~adam-collard/maas-ci/+git/system-tests:lxd-logger-name into ~maas-committers/maas-ci/+git/system-tests:master.
diff --git a/systemtests/lxd.py b/systemtests/lxd.py
index 03a5f1d..72483f5 100644
--- a/systemtests/lxd.py
+++ b/systemtests/lxd.py
@@ -42,9 +42,10 @@ class CLILXD:
def __init__(self, logger: logging.Logger):
self.logger = logger
- def container_exists(self, name: str) -> bool:
+ def container_exists(self, instance_name: str) -> bool:
+ logger = self.logger.getChild(instance_name)
try:
- self._run(["lxc", "info", name])
+ self._run(["lxc", "info", instance_name], logger=logger)
except subprocess.CalledProcessError:
return False
else:
@@ -68,8 +69,9 @@ class CLILXD:
user_data: Optional[str] = None,
profile: Optional[str] = None,
) -> str:
+ logger = self.logger.getChild(name)
if not self.container_exists(name):
- self.logger.info(f"Creating container {name} (from {image})...")
+ logger.info(f"Creating container {name} (from {image})...")
cmd = [
"lxc",
"launch",
@@ -82,11 +84,11 @@ class CLILXD:
if profile is not None:
cmd.extend(["-p", profile])
cmd.append(name)
- self._run(cmd)
- self.logger.info(f"Container {name} created.")
- self.logger.info("Waiting for boot to finish...")
+ self._run(cmd, logger=logger)
+ logger.info(f"Container {name} created.")
+ logger.info("Waiting for boot to finish...")
- @retry(exceptions=CloudInitDisabled, tries=120, delay=1, logger=self.logger)
+ @retry(exceptions=CloudInitDisabled, tries=120, delay=1, logger=logger)
def _cloud_init_wait() -> None:
process = self.execute(
name, ["timeout", "2000", "cloud-init", "status", "--wait", "--long"]
@@ -98,7 +100,7 @@ class CLILXD:
)
_cloud_init_wait()
- self.logger.info("Boot finished.")
+ logger.info("Boot finished.")
return name
def get_or_create(
@@ -114,7 +116,7 @@ class CLILXD:
def push_file(
self,
- container: str,
+ instance_name: str,
source_file: str,
target_file: str,
uid: int = 0,
@@ -130,16 +132,17 @@ class CLILXD:
"--mode",
mode,
source_file,
- f"{container}{target_file}",
+ f"{instance_name}{target_file}",
]
if create_dirs:
args.append("--create-dirs")
- self._run(["lxc", "file", "--quiet", "push", *args])
+ logger = self.logger.getChild(instance_name)
+ self._run(["lxc", "file", "--quiet", "push", *args], logger=logger)
def push_text_file(
self,
- container: str,
+ instance_name: str,
content: str,
target_file: str,
uid: int = 0,
@@ -149,24 +152,25 @@ class CLILXD:
source_file.write(content.encode())
source_file.seek(0)
self.push_file(
- container,
+ instance_name,
source_file.name,
target_file,
uid=uid,
gid=gid,
)
- def file_exists(self, container: str, file_path: str) -> bool:
+ def file_exists(self, instance_name: str, file_path: str) -> bool:
try:
- self.quietly_execute(container, ["stat", file_path])
+ self.quietly_execute(instance_name, ["stat", file_path])
except subprocess.CalledProcessError:
return False
else:
return True
def pull_file(
- self, container: str, file_path: str, local_path: str
+ self, instance_name: str, file_path: str, local_path: str
) -> subprocess.CompletedProcess[str]:
+ logger = self.logger.getChild(instance_name)
return self._run(
[
"lxc",
@@ -174,12 +178,14 @@ class CLILXD:
"--quiet",
"pull",
"-r",
- f"{container}/{file_path}",
+ f"{instance_name}/{file_path}",
local_path,
],
+ logger=logger,
)
- def get_file_contents(self, container: str, file_path: str) -> str:
+ def get_file_contents(self, instance_name: str, file_path: str) -> str:
+ logger = self.logger.getChild(instance_name)
filename = os.path.basename(file_path)
with tempfile.TemporaryDirectory() as tempdir:
self._run(
@@ -188,9 +194,10 @@ class CLILXD:
"file",
"--quiet",
"pull",
- f"{container}{file_path}",
+ f"{instance_name}{file_path}",
f"{tempdir}/",
],
+ logger=logger,
)
with open(os.path.join(tempdir, filename), "r") as f:
return f.read()
@@ -219,9 +226,9 @@ class CLILXD:
return _retry_bad_handshake()
def _get_lxc_command(
- self, container: str, environment: Optional[dict[str, str]]
+ self, instance_name: str, environment: Optional[dict[str, str]]
) -> list[str]:
- lxc_command = ["lxc", "exec", "--force-noninteractive", container]
+ lxc_command = ["lxc", "exec", "--force-noninteractive", instance_name]
if environment is not None:
for key, value in environment.items():
lxc_command.extend(["--env", f"{key}={value}"])
@@ -230,13 +237,13 @@ class CLILXD:
def execute(
self,
- container: str,
+ instance_name: str,
command: list[str],
environment: Optional[dict[str, str]] = None,
) -> subprocess.CompletedProcess[str]:
__tracebackhide__ = True
- logger = self.logger.getChild(container)
- lxc_command = self._get_lxc_command(container, environment)
+ logger = self.logger.getChild(instance_name)
+ lxc_command = self._get_lxc_command(instance_name, environment)
# Suppress logging of the lxc wrapper for clearer logs
executor = partial(self._run, command, prefix=lxc_command, logger=logger)
@@ -244,13 +251,13 @@ class CLILXD:
def quietly_execute(
self,
- container: str,
+ instance_name: str,
command: list[str],
environment: Optional[dict[str, str]] = None,
) -> subprocess.CompletedProcess[str]:
"""Execute a command without logging it."""
__tracebackhide__ = True
- lxc_command = self._get_lxc_command(container, environment)
+ lxc_command = self._get_lxc_command(instance_name, environment)
executor = partial(
subprocess.run,
@@ -262,18 +269,21 @@ class CLILXD:
)
return self._run_with_logger(executor, None)
- def delete(self, instance: str) -> None:
- self._run(["lxc", "delete", "--force", instance])
+ def delete(self, instance_name: str) -> None:
+ logger = self.logger.getChild(instance_name)
+ self._run(["lxc", "delete", "--force", instance_name], logger=logger)
- def get_ip_address(self, container: str) -> str:
- @retry(
- exceptions=RuntimeError, tries=30, delay=2, backoff=1.1, logger=self.logger
- )
+ def get_ip_address(self, instance_name: str) -> str:
+ logger = self.logger.getChild(instance_name)
+
+ @retry(exceptions=RuntimeError, tries=30, delay=2, backoff=1.1, logger=logger)
def _get_ip_address() -> str:
- result = self._run(["lxc", "list", "--format", "json", container])
+ result = self._run(
+ ["lxc", "list", "--format", "json", instance_name], logger=logger
+ )
# lxc list does partial match, so we still need to find the entry
for entry in json.loads(result.stdout):
- if entry["name"] != container:
+ if entry["name"] != instance_name:
continue
for address in entry["state"]["network"]["eth0"]["addresses"]:
self.logger.info(f"Considering address: {address}")
@@ -315,34 +325,38 @@ class CLILXD:
["lxc", "profile", "device", "remove", profile_name, device_name],
)
- def collect_sos_report(self, container: str, output: str) -> None:
+ def collect_sos_report(self, instance_name: str, output: str) -> None:
container_tmp = "/tmp/sosreport"
output_dir = Path(f"{output}/sosreport")
- self.execute(container, ["apt", "install", "--yes", "sosreport"])
- self.execute(container, ["rm", "-rf", container_tmp])
- self.execute(container, ["mkdir", "-p", container_tmp])
+ self.execute(instance_name, ["apt", "install", "--yes", "sosreport"])
+ self.execute(instance_name, ["rm", "-rf", container_tmp])
+ self.execute(instance_name, ["mkdir", "-p", container_tmp])
self.execute(
- container,
+ instance_name,
["sos", "report", "--batch", "-o", "maas", "--tmp-dir", container_tmp],
)
output_dir.mkdir(parents=True, exist_ok=True)
journalctl = self.execute(
- container, ["journalctl", "--unit=vault", "--no-pager", "--output=cat"]
+ instance_name, ["journalctl", "--unit=vault", "--no-pager", "--output=cat"]
)
if journalctl.stdout:
(output_dir / "vault-journal").write_text(journalctl.stdout)
with tempfile.TemporaryDirectory(prefix="sosreport") as tempdir:
- self.pull_file(container, container_tmp, f"{tempdir}/")
+ self.pull_file(instance_name, container_tmp, f"{tempdir}/")
for f in os.listdir(f"{tempdir}/sosreport"):
os.rename(os.path.join(f"{tempdir}/sosreport", f), f"{output_dir}/{f}")
def list_instance_devices(self, instance_name: str) -> list[str]:
- result = self._run(["lxc", "config", "device", "list", instance_name])
+ logger = self.logger.getChild(instance_name)
+ result = self._run(
+ ["lxc", "config", "device", "list", instance_name], logger=logger
+ )
return result.stdout.splitlines()
def add_instance_device(
self, instance_name: str, name: str, device_config: DeviceConfig
) -> None:
+ logger = self.logger.getChild(instance_name)
self._run(
[
"lxc",
@@ -353,11 +367,13 @@ class CLILXD:
name,
device_config["type"],
]
- + fmt_lxd_options(device_config)
+ + fmt_lxd_options(device_config),
+ logger=logger,
)
def remove_instance_device(self, instance_name: str, device_name: str) -> None:
"""Remove a device from an instance."""
+ logger = self.logger.getChild(instance_name)
@retry(
exceptions=subprocess.CalledProcessError,
@@ -367,7 +383,8 @@ class CLILXD:
)
def _remove_device() -> subprocess.CompletedProcess[str]:
return self._run(
- ["lxc", "config", "device", "remove", instance_name, device_name]
+ ["lxc", "config", "device", "remove", instance_name, device_name],
+ logger=logger,
)
_remove_device()
@@ -379,12 +396,15 @@ class CLILXD:
return instances
def create_vm(self, instance_name: str, config: dict[str, str]) -> None:
+ logger = self.logger.getChild(instance_name)
args: list[str] = []
profile: Optional[str] = config.pop("profile", None)
if profile:
args += ["-p", profile]
args += list(chain.from_iterable(("-c", f"{k}={v}") for k, v in config.items()))
- self._run(["lxc", "init", "--empty", "--vm", instance_name] + args)
+ self._run(
+ ["lxc", "init", "--empty", "--vm", instance_name] + args, logger=logger
+ )
self._run(
[
"lxc",
@@ -394,22 +414,26 @@ class CLILXD:
instance_name,
"eth0",
"boot.priority=10",
- ]
+ ],
+ logger=logger,
)
def start(self, instance_name: str) -> subprocess.CompletedProcess[str]:
- return self._run(["lxc", "start", instance_name])
+ logger = self.logger.getChild(instance_name)
+ return self._run(["lxc", "start", instance_name], logger=logger)
def stop(
self, instance_name: str, force: bool = False
) -> subprocess.CompletedProcess[str]:
+ logger = self.logger.getChild(instance_name)
argv = ["lxc", "stop", instance_name]
if force:
argv.append("--force")
- return self._run(argv)
+ return self._run(argv, logger=logger)
def instance_status(self, instance_name: str) -> str:
- result = self._run(["lxc", "info", instance_name])
+ logger = self.logger.getChild(instance_name)
+ result = self._run(["lxc", "info", instance_name], logger=logger)
for line in result.stdout.splitlines():
key, value = line.split(": ", 1)
if key == "Status":
@@ -428,10 +452,11 @@ class CLILXD:
def restart(
self, instance_name: str, force: bool = False
) -> subprocess.CompletedProcess[str]:
+ logger = self.logger.getChild(instance_name)
argv = ["lxc", "restart", instance_name]
if force:
argv.append("--force")
- return self._run(argv)
+ return self._run(argv, logger=logger)
def fmt_lxd_options(cfg: DeviceConfig) -> list[str]:
Follow ups