lxc: code cleanup and docs polish from review

Code:
- Fix check_ssh_config_include() to do a case-insensitive line match
  (read_text().splitlines() instead of filter(None, map(..., open()))).
- Drop the default help_text= from _add_name_args(); callers now must
  supply an explicit string.
- Expand the DNSContainer class docstring.
- Fix sysctl comment: note that incus provides net.* virtualization
  so the sysctl only affects the container's network namespace.

Docs (doc/source/lxc.rst):
- Remove double blank line after page title; fix missing comma.
- Replace the plain-text root-access note with a .. caution:: block.
- Tighten the Quick-start section and lxc-test CLI entry.
This commit is contained in:
holger krekel
2026-03-08 18:12:49 +01:00
parent e2ec0cf2c5
commit 04ac2cf700
4 changed files with 36 additions and 44 deletions

View File

@@ -430,14 +430,8 @@ def _deploy_status(ct, local_hash, ix):
return f"IN-SYNC ({short})"
def _add_name_args(parser, help_text=None):
"""Add optional positional NAME arguments."""
parser.add_argument(
"names",
nargs="*",
metavar="NAME",
help=help_text or "Relay name(s) to operate on.",
)
def _add_name_args(parser, help_text):
parser.add_argument("names", nargs="*", metavar="NAME", help=help_text)
def _run_cmdeploy(subcmd, ct, ix, out, extra=None, **kwargs):

View File

@@ -95,8 +95,9 @@ class Incus:
user_ssh_config = Path.home() / ".ssh" / "config"
if not user_ssh_config.exists():
return False
lines = filter(None, map(str.strip, user_ssh_config.open("r")))
return f"Include {self.ssh_config_path}" in lines
lines = user_ssh_config.read_text().splitlines()
target = f"include {self.ssh_config_path}".lower()
return any(line.strip().lower() == target for line in lines)
def run(self, args, check=True, capture=True, input=None):
"""Run an incus command.
@@ -190,7 +191,7 @@ class Incus:
def delete_images(self):
"""Delete the cached base and relay images."""
for alias in (RELAY_IMAGE_ALIAS, BASE_IMAGE_ALIAS):
self.run(["image", "delete", alias], check=False)
self.run(["image", "delete", alias], check=False) # ok if absent
def list_managed(self):
"""Return list of dicts with name, ip, ipv6, domain, status, memory_usage."""
@@ -433,7 +434,8 @@ class RelayContainer(Container):
def disable_ipv6(self):
"""Disable IPv6 inside the container via sysctl."""
# incus provides net.* virtalization
# incus provides net.* virtualization for LXC containers so that
# these sysctls only affect the container's network namespace.
self.bash("""\
sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1
@@ -485,7 +487,7 @@ class RelayContainer(Container):
return shell(cmd, timeout=15).returncode == 0
def configure_dns(self, dns_ip):
"""Point this container's resolver at *dns_ip* and verify it works."""
"""Point this container's resolver at *dns_ip* and verify DNS is reachable."""
self.bash(f"""\
systemctl disable --now systemd-resolved 2>/dev/null || true
rm -f /etc/resolv.conf
@@ -535,7 +537,11 @@ class RelayContainer(Container):
class DNSContainer(Container):
"""Container handle for the PowerDNS name server."""
"""Container handle for the PowerDNS name server.
Manages the authoritative and recursive DNS services required for
name resolution in the local testing environment.
"""
def __init__(self, incus):
super().__init__(incus, DNS_CONTAINER_NAME, domain=DNS_DOMAIN)

View File

@@ -12,7 +12,7 @@ from cmdeploy.util import Out
pytestmark = pytest.mark.skipif(
not shutil.which("incus"),
reason="incus/lxc not installed",
reason="incus not installed",
)