Merge remote-tracking branch 'origin/master' into chore/driver-standard
driver / standard (pull_request) Successful in 14s
driver / lint (pull_request) Successful in 11s
driver / types (pull_request) Failing after 42s
driver / test (3.10) (pull_request) Failing after 38s
driver / test (3.11) (pull_request) Failing after 38s
driver / test (3.12) (pull_request) Failing after 33s
driver / test (3.13) (pull_request) Failing after 30s
driver / lowest (pull_request) Failing after 17s
driver / security (pull_request) Failing after 45s
driver / build (pull_request) Successful in 22s
CI / driver (pull_request) Failing after 4m51s
driver / publish (pull_request) Skipped

# Conflicts:
#	napalm_linux/linux.py
This commit is contained in:
Christian Manivong committed 2026-10-23 08:29:05 +02:00
commit e0960085c7
5 files changed
+96 -36

No files matched your search

+17 -28
View File
@@ -28,6 +28,7 @@ from napalm.base.netmiko_helpers import netmiko_args
from napalm_device_types import (
APT_UPGRADABLE_COMMAND,
DNF_SECURITY_COMMAND,
AptProxyMixin,
ByteStream,
CommandResult,
ContainerEngineMixin,
@@ -39,7 +40,6 @@ from napalm_device_types import (
ListeningSocketsMixin,
OpenSshServerMixin,
OSDriver,
PackageProxyMixin,
ServiceClustersMixin,
ServicePackagesMixin,
SnmpAgentMixin,
@@ -284,8 +284,6 @@ _SNMP_INSTALL = {
"apk": "apk add --no-cache net-snmp net-snmp-tools 2>&1",
"pacman": "pacman -Sy --noconfirm net-snmp 2>&1",
}
_APT_PROXY_CONF = "/etc/apt/apt.conf.d/00proxy"
_PROXY_URL = re.compile(r"^https?://[A-Za-z0-9.\-\[\]:@%_~/]+$")
_USER_NAME = re.compile(r"^[a-z_][a-z0-9_.\-]{0,31}$")
#: What may stand in an snmpd.conf value: no whitespace, no quote, no comment.
_SNMP_WORD = re.compile(r"^[^\s\"#]+$")
@@ -317,7 +315,7 @@ def render_snmpd_conf(settings: SnmpAgentSettingsDict) -> str:
class LinuxDriver(
SnmpAgentMixin,
EnsurePackageMixin,
PackageProxyMixin,
AptProxyMixin,
KernelFactsMixin,
ServicePackagesMixin,
ListeningSocketsMixin,
@@ -1623,14 +1621,6 @@ class LinuxDriver(
return self._get_updates_pacman()
raise NotImplementedError(f"Package manager '{self._pkg_manager}' is not supported")
def get_package_proxy(self) -> str | None:
"""The proxy apt fetches through (``00proxy``); None for none or a non-apt host."""
if self._pkg_manager != "apt":
return None
conf = self._send(f"cat {_APT_PROXY_CONF} 2>/dev/null || true")
found = re.search(r'Acquire::http::Proxy\s+"([^"]+)"', conf)
return found.group(1) if found else None
def _get_updates_apt(self) -> list[UpdateDict]:
# apt list --upgradable does not need root; avoid sudo so it works even
# without a configured sudo password.
@@ -2131,24 +2121,23 @@ class LinuxDriver(
"snmpd enabled and running",
)
def configure_package_proxy(self, url: str) -> FixResultDict:
"""apt fetches through *url* (``/etc/apt/apt.conf.d/00proxy``); ``""`` removes it."""
# apt's proxy (napalm-device-types AptProxyMixin): the transports
def write() -> FixStepOutcomeDict:
if self._pkg_manager != "apt":
return {"ok": False, "output": f"package manager is {self._pkg_manager!r}, not apt"}
if not url:
return self._root_outcome(f"rm -f {_APT_PROXY_CONF}", 30, "proxy removed")
if not _PROXY_URL.match(url):
raise ValueError(f"not a proxy URL: {url!r}")
written = self._install_file_as_root(
_APT_PROXY_CONF, f'Acquire::http::Proxy "{url}";\n'
)
if written.exit_code:
return {"ok": False, "output": (written.stdout or written.stderr).strip()[-300:]}
return {"ok": True, "output": f"apt fetches through {url}"}
def _is_apt_host(self) -> bool:
return self._pkg_manager == "apt"
return run_fix_steps([("configure", write)])
def _run_apt_command(self, command: str) -> str:
"""On the exec channel: no prompt to mistake a line of apt's output for."""
return self.run_command(command, timeout=60).stdout
def _run_apt_root_command(self, command: str, done: str) -> FixStepOutcomeDict:
return self._root_outcome(command, 30, done)
def _write_apt_file(self, path: str, content: str) -> FixStepOutcomeDict:
written = self._install_file_as_root(path, content)
if written.exit_code:
return {"ok": False, "output": (written.stdout or written.stderr).strip()[-300:]}
return {"ok": True, "output": f"wrote {path}"}
def grant_container_engine_access(self, user: str) -> FixResultDict:
"""Add *user* to the ``docker`` group, so the engine answers without sudo."""