From 8eb7dcd871e275381e09ac51af138f2419a53518 Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Thu, 8 Oct 2026 08:48:37 +0200 Subject: [PATCH] refactor!: drop the Docker model DockerInfoDict, DockerContainerDict, DockerImageDict, DockerVolumeDict, DockerNetworkDict and the OSDriver declaration of get_docker_info() go. They described napalm-linux' old CLI reading, which napalm-linux 0.3.0 dropped. There is no container model here: netOrk reads and handles containers over the Engine API (NetOrk/netork#765, phase 9); this package only gives access to the engine. Version 4.0.0. --- napalm_device_types/models.py | 58 --------------------- napalm_device_types/os.py | 92 ---------------------------------- pyproject.toml | 2 +- tests/test_container_engine.py | 19 +++++++ 4 files changed, 20 insertions(+), 151 deletions(-) diff --git a/napalm_device_types/models.py b/napalm_device_types/models.py index 0b401ae..34535e4 100644 --- a/napalm_device_types/models.py +++ b/napalm_device_types/models.py @@ -813,64 +813,6 @@ class ApplyUpdatesResultDict(TypedDict): error: NotRequired[str] # error message if success is False -class DockerContainerDict(TypedDict): - """A Docker container entry as returned by ``docker ps -a``.""" - - id: str # short container ID - name: str # container name(s) - image: str # image reference - image_version: str # OCI org.opencontainers.image.version label; empty if absent - command: str # entrypoint / command - created: str # creation timestamp string - status: str # human-readable status (e.g. "Up 3 hours") - ports: str # port mapping string - state: str # "running", "exited", "paused", etc. - - -class DockerImageDict(TypedDict): - """A local Docker image entry as returned by ``docker images``.""" - - id: str # short image ID - repository: str # image repository - tag: str # image tag - size: str # human-readable size string (e.g. "187MB") - created: str # creation timestamp string - version: str # OCI org.opencontainers.image.version label; empty if absent - - -class DockerVolumeDict(TypedDict): - """A Docker volume entry as returned by ``docker volume ls``.""" - - name: str # volume name - driver: str # volume driver (e.g. "local") - mountpoint: str # host filesystem path - scope: str # "local" or "global" - - -class DockerNetworkDict(TypedDict): - """A Docker network entry as returned by ``docker network ls``.""" - - id: str # short network ID - name: str # network name - driver: str # network driver (e.g. "bridge", "host", "overlay") - scope: str # network scope - ipv6: str # "true" if IPv6 is enabled, "false" otherwise - internal: str # "true" if the network is internal, "false" otherwise - - -class DockerInfoDict(TypedDict): - """Return value of ``get_docker_info()``.""" - - available: bool # False if Docker is absent/inaccessible - permission_denied: NotRequired[bool] # True when socket access is denied - version: NotRequired[str] # Docker Engine version string - containers: NotRequired[List[DockerContainerDict]] - images: NotRequired[List[DockerImageDict]] - volumes: NotRequired[List[DockerVolumeDict]] - networks: NotRequired[List[DockerNetworkDict]] - outdated_images: NotRequired[List[str]] # image names with a newer remote digest - - class ContainerEngineDict(TypedDict): """One container engine a host offers (``container_engines()``). diff --git a/napalm_device_types/os.py b/napalm_device_types/os.py index 8a4bdce..c4bbae6 100644 --- a/napalm_device_types/os.py +++ b/napalm_device_types/os.py @@ -19,7 +19,6 @@ from napalm_device_types.health_metrics import HealthMetricsMixin from napalm_device_types.models import ( CronJobDict, DeviceActionResultDict, - DockerInfoDict, ProcessDict, SNMPConfigDict, UserDict, @@ -193,97 +192,6 @@ class OSDriver(UpdateMixin, ServiceControlMixin, PackageManagementMixin, HealthM """ ... - # ------------------------------------------------------------------ - # Docker - # ------------------------------------------------------------------ - - def get_docker_info(self) -> DockerInfoDict: - """ - Returns information about the local Docker environment. - - If Docker is not installed or the current user lacks access to the - Docker socket, returns ``{"available": False}``. When the user has - no socket permission, ``permission_denied`` is additionally set to - ``True``. - - When Docker is available the dict contains: - - * available (bool) - always ``True`` - * version (string) - Docker Engine version string - * containers (list) - all containers (running and stopped), each with: - - * id (string) - short container ID - * name (string) - container name(s) - * image (string) - image reference - * image_version (string) - OCI ``org.opencontainers.image.version`` label; empty if absent - * command (string) - entrypoint / command string - * created (string) - creation timestamp string - * status (string) - human-readable status (e.g. ``"Up 3 hours"``) - * ports (string) - port mapping string - * state (string) - ``"running"``, ``"exited"``, ``"paused"``, etc. - - * images (list) - local images, each with: - - * id (string) - short image ID - * repository (string) - image repository - * tag (string) - image tag - * size (string) - human-readable size string (e.g. ``"187MB"``) - * created (string) - creation timestamp string - * version (string) - OCI ``org.opencontainers.image.version`` label; empty if absent - - * volumes (list) - Docker volumes, each with: - - * name (string) - volume name - * driver (string) - volume driver - * mountpoint (string) - host filesystem path - * scope (string) - ``"local"`` or ``"global"`` - - * networks (list) - Docker networks, each with: - - * id (string) - short network ID - * name (string) - network name - * driver (string) - network driver (e.g. ``"bridge"``, ``"host"``, ``"overlay"``) - * scope (string) - network scope - * ipv6 (string) - ``"true"`` if IPv6 is enabled - * internal (string) - ``"true"`` if the network is internal - - * outdated_images (list of strings) - image names where the local digest - differs from the latest remote digest; empty list if all images are - current or update checks could not be performed. - - Example:: - - # Docker not installed: - {"available": False} - - # Docker installed, no socket permission: - {"available": False, "permission_denied": True} - - # Docker available: - { - "available": True, - "version": "Docker version 27.3.1, build ce12230", - "containers": [ - { - "id": "a1b2c3d4e5f6", - "name": "my-app", - "image": "nginx:latest", - "image_version": "1.27.0", - "command": "nginx -g 'daemon off;'", - "created": "2026-05-28 10:00:00 +0000 UTC", - "status": "Up 3 days", - "ports": "0.0.0.0:80->80/tcp", - "state": "running", - }, - ], - "images": [...], - "volumes": [], - "networks": [...], - "outdated_images": ["nginx:latest"], - } - """ - ... - # ------------------------------------------------------------------ # Generic device actions # ------------------------------------------------------------------ diff --git a/pyproject.toml b/pyproject.toml index 9fd1c2f..9354242 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "napalm-device-types" -version = "3.0.0" +version = "4.0.0" description = "Abstract device-type base classes for NAPALM drivers" readme = "README.md" requires-python = ">=3.10" diff --git a/tests/test_container_engine.py b/tests/test_container_engine.py index aaf48d2..53199a0 100644 --- a/tests/test_container_engine.py +++ b/tests/test_container_engine.py @@ -157,3 +157,22 @@ class TestPrivilegedCli: driver.open_container_engine("docker").stream_cli(["pull", "nginx"], privileged=True) assert driver.streams == [("docker pull nginx", True)] + + +class TestNoDockerModel: + """There is no container model here (NetOrk/netork#765): netOrk reads and + handles containers over the Engine API, so the CLI-shaped types and the + ``get_docker_info()`` declaration that served napalm-linux' old reading are gone.""" + + def test_the_docker_types_are_gone(self): + import napalm_device_types + from napalm_device_types import models + + for name in ("DockerInfoDict", "DockerContainerDict", "DockerImageDict"): + assert not hasattr(models, name), name + assert not hasattr(napalm_device_types, name), name + + def test_an_os_driver_declares_no_docker_reading(self): + from napalm_device_types import os as os_role + + assert "get_docker_info" not in os_role.__dict__.get("OSDriver", object).__dict__