Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DockerClient.info() doesn't work with podman #592

Open
LewisGaul opened this issue May 22, 2024 · 3 comments
Open

DockerClient.info() doesn't work with podman #592

LewisGaul opened this issue May 22, 2024 · 3 comments
Labels
podman Specific to podman

Comments

@LewisGaul
Copy link
Collaborator

LewisGaul commented May 22, 2024

In [2]: import python_on_whales as pow
In [3]: podman = pow.DockerClient(client_call=["podman"])
In [4]: podman.info()
Out[4]: SystemInfo(id=None, containers=None, containers_running=None, containers_paused=None, containers_stopped=None, images=None, driver=None, driver_status=None, docker_root_dir=None, system_status=None, plugins=Plugins(volume=['local'], network=['bridge', 'macvlan'], authorization=None, log=['k8s-file', 'none', 'journald']), memory_limit=None, swap_limit=None, kernel_memory=None, cpu_cfs_period=None, cpu_cfs_quota=None, cpu_shares=None, cpu_set=None, pids_limit=None, oom_kill_disable=None, ipv4_forwarding=None, bridge_nf_iptables=None, bridge_nf_ip6tables=None, debug=None, nfd=None, n_goroutines=None, system_time=None, logging_driver=None, cgroup_driver=None, n_events_listener=None, kernel_version=None, operating_system=None, os_type=None, architecture=None, n_cpu=None, mem_total=None, index_server_address=None, registry_config=None, generic_resources=None, http_proxy=None, https_proxy=None, no_proxy=None, name=None, labels=None, experimental_build=None, server_version=None, cluster_store=None, runtimes=None, default_runtime=None, swarm=None, live_restore_enabled=None, isolation=None, init_binary=None, containerd_commit=None, runc_commit=None, init_commit=None, security_options=None, product_license=None, warnings=None, client_info=None)

This is arguably podman's fault for not maintaining compatibility with this command :(

Here's what you get from podman:

$podman info -f '{{json .}}' | jq
{
  "host": {
    "arch": "amd64",
    "buildahVersion": "1.23.1",
    "cgroupManager": "cgroupfs",
    "cgroupVersion": "v1",
    "cgroupControllers": [],
    "conmon": {
      "package": "conmon: /usr/libexec/podman/conmon",
      "path": "/usr/libexec/podman/conmon",
      "version": "conmon version 2.1.0, commit: "
    },
    "cpus": 8,
    "distribution": {
      "distribution": "ubuntu",
      "version": "20.04",
      "codename": "focal"
    },
    "eventLogger": "file",
    "hostname": "CSCO-W-PF34CGA7",
    "idMappings": {
      "gidmap": [
        {
          "container_id": 0,
          "host_id": 1000,
          "size": 1
        },
        {
          "container_id": 1,
          "host_id": 100000,
          "size": 65536
        }
      ],
      "uidmap": [
        {
          "container_id": 0,
          "host_id": 1000,
          "size": 1
        },
        {
          "container_id": 1,
          "host_id": 100000,
          "size": 65536
        }
      ]
    },
    "kernel": "5.15.133.1-microsoft-standard-WSL2",
    "logDriver": "k8s-file",
    "memFree": 6798467072,
    "memTotal": 8176771072,
    "ociRuntime": {
      "name": "crun",
      "package": "crun: /usr/bin/crun",
      "path": "/usr/bin/crun",
      "version": "crun version UNKNOWN\ncommit: ea1fe3938eefa14eb707f1d22adff4db670645d6\nspec: 1.0.0\n+SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL"
    },
    "os": "linux",
    "remoteSocket": {
      "path": "/mnt/wslg/runtime-dir/podman/podman.sock"
    },
    "serviceIsRemote": false,
    "security": {
      "apparmorEnabled": false,
      "capabilities": "CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT",
      "rootless": true,
      "seccompEnabled": true,
      "seccompProfilePath": "/usr/share/containers/seccomp.json",
      "selinuxEnabled": false
    },
    "slirp4netns": {
      "executable": "/usr/bin/slirp4netns",
      "package": "slirp4netns: /usr/bin/slirp4netns",
      "version": "slirp4netns version 1.1.8\ncommit: unknown\nlibslirp: 4.3.1-git\nSLIRP_CONFIG_VERSION_MAX: 3\nlibseccomp: 2.4.3"
    },
    "swapFree": 2147483648,
    "swapTotal": 2147483648,
    "uptime": "100h 57m 37.95s (Approximately 4.17 days)",
    "linkmode": "dynamic"
  },
  "store": {
    "configFile": "/home/legaul/.config/containers/storage.conf",
    "containerStore": {
      "number": 1,
      "paused": 0,
      "running": 1,
      "stopped": 0
    },
    "graphDriverName": "overlay",
    "graphOptions": {
      "overlay.mount_program": {
        "Executable": "/usr/bin/fuse-overlayfs",
        "Package": "fuse-overlayfs: /usr/bin/fuse-overlayfs",
        "Version": "fusermount3 version: 3.9.0\nfuse-overlayfs: version 1.5\nFUSE library version 3.9.0\nusing FUSE kernel interface version 7.31"
      }
    },
    "graphRoot": "/home/legaul/.local/share/containers/storage",
    "graphStatus": {
      "Backing Filesystem": "extfs",
      "Native Overlay Diff": "false",
      "Supports d_type": "true",
      "Using metacopy": "false"
    },
    "imageStore": {
      "number": 15
    },
    "runRoot": "/mnt/wslg/runtime-dir/containers",
    "volumePath": "/home/legaul/.local/share/containers/storage/volumes"
  },
  "registries": {
    "search": [
      "docker.io",
      "quay.io"
    ]
  },
  "plugins": {
    "volume": [
      "local"
    ],
    "network": [
      "bridge",
      "macvlan"
    ],
    "log": [
      "k8s-file",
      "none",
      "journald"
    ]
  },
  "version": {
    "APIVersion": "3.4.2",
    "Version": "3.4.2",
    "GoVersion": "go1.15.2",
    "GitCommit": "",
    "BuiltTime": "Thu Jan  1 01:00:00 1970",
    "Built": 0,
    "OsArch": "linux/amd64"
  }
}

Is there anything we can do about this in PoW, or is the statement that we'll only support CLIs compatible with docker?

@LewisGaul LewisGaul added the podman Specific to podman label May 22, 2024
@gabrieldemarmiesse
Copy link
Owner

It makes sense that the info is different as podman and docker work differently internally, so I'm not blaming them for this.

What I see is that we may need a better support for docker/podman differences. Looking at the popularity of Docker vs Podman: https://github.com/moby/moby vs https://github.com/containers/podman, I think it's fair to say that we should also support the kwirks of podman correctly.

Seeing long-term, I think we'll need better support for the podman/docker differences, but at the moment, would it be possible to fit the information of podman info into the DockerInfo pydantic model? Some fields won't be equivalent, but we can do a best effort here. What do you think?

@LewisGaul
Copy link
Collaborator Author

What I see is that we may need a better support for docker/podman differences. Looking at the popularity of Docker vs Podman: https://github.com/moby/moby vs https://github.com/containers/podman, I think it's fair to say that we should also support the kwirks of podman correctly.

I'm happy to hear this :)

Seeing long-term, I think we'll need better support for the podman/docker differences, but at the moment, would it be possible to fit the information of podman info into the DockerInfo pydantic model? Some fields won't be equivalent, but we can do a best effort here. What do you think?

I'm not particularly keen on this idea, I'm not sure stuff would map very well and it would create transition friction if we then switch to handling it in a more complete way.

Do you have any initial thoughts on how we might support docker/podman differences in cases like this? One option would be to just return different objects based on which is being used, e.g. DockerSystemInfo or PodmanSystemInfo, which the caller would then have to handle appropriately. Alternatively something more like the pathlib approach for Posix/Windows paths where you get either a DockerClient or PodmanClient object. The latter would probably be my preferred option, where we'd then just need to get the class hierarchy right to allow code sharing where desired.

@gabrieldemarmiesse
Copy link
Owner

I'm not particularly keen on this idea, I'm not sure stuff would map very well and it would create transition friction if we then switch to handling it in a more complete way.
I understand, I saw this more as a quick win solution. But yeah if it creates more problems than it solves, let's drop it.

Concerning the option with DockerCLient and PodmanClient, indeed the whole difficulty will be with the class hierarchy.

One solution we can explore too, would be to make DockerClient generic, like list or dict. See https://mypy.readthedocs.io/en/stable/generics.html for a detailed explanation.
We could have DockerClient["podman"] and DockerClient["docker"] and return the correct type depending on the situation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
podman Specific to podman
Projects
None yet
Development

No branches or pull requests

2 participants