podman-py icon indicating copy to clipboard operation
podman-py copied to clipboard

Windows support

Open apyrgio opened this issue 6 months ago • 7 comments

Reading the project description, I see that:

In libpod, the URI can be a unix domain socket(UDS) or TCP. The TCP connection has not been implemented in this package yet.

My understanding is that podman-py cannot be used in Windows environments, where Unix Domain Sockets are not supported. Are there any plans to support an alternative backend in the near future?

apyrgio avatar Jun 04 '25 15:06 apyrgio

Podman-py already supports windows "in a way". Let me be clear.

Currently, podman works on Windows in a WSL2 environment, and that's Linux. As long as podman-py is installed inside the machine, then it will be able to communicate with podman socket, and therefore it's supported.

Within the podman machine, you can run dnf commands to get python-podman installed (podman machine ssh dnf -y install python-podman. Just be sure to allocate enough space in the machine with --disk-size during podman machine init.

Finally, on Linux and everywhere the socket is exposed outside the machine, you can get the socket uri and speak to podman directly without having the requirement of podman-py to be installed inside the podman machine. I don't recall now how WSL2 handles sockets, BUT I believe that since podman machine runs in a VM it could be enough to install python-podman it in the WSL2 VM and control podman from the socket. Again, I don't have a Win machine at hand today, but I could take a look and blog about if you want to pursue this way.

inknos avatar Jun 04 '25 15:06 inknos

Within the podman machine, you can run dnf commands to get python-podman installed (podman machine ssh dnf -y install python-podman. Just be sure to allocate enough space in the machine with --disk-size during podman machine init.

Got it, makes sense. It is a way indeed to use podman-py bindings in Windows. I guess my perspective here is from a Python application running on the Windows host. In that case, this application can't use podman-py directly, so the next best thing is to use it indirectly via podman machine ssh plus some scaffolding in the VM. Let me know if I got it wrong.

I don't recall now how WSL2 handles sockets, BUT I believe that since podman machine runs in a VM it could be enough to install python-podman it in the WSL2 VM and control podman from the socket.

I think so as well. You still can't connect from the Windows host to that socket (see https://github.com/microsoft/WSL/issues/8321) but it should work from within the VM. The problem remains that a native Windows app cannot use the Python bindings to do that. Well, unless you do Python shenanigans like Mitogen, but I digress.

Anyhow, if the TCP/SSH connection were to be supported in the future, that could be a way for native Windows apps to use these bindings. Any idea if this is in the making?

apyrgio avatar Jun 04 '25 16:06 apyrgio

Got it, makes sense. It is a way indeed to use podman-py bindings in Windows. I guess my perspective here is from a Python application running on the Windows host. In that case, this application can't use podman-py directly, so the next best thing is to use it indirectly via podman machine ssh plus some scaffolding in the VM. Let me know if I got it wrong.

right

Anyhow, if the TCP/SSH connection were to be supported in the future, that could be a way for native Windows apps to use these bindings. Any idea if this is in the making?

I believe... it could be done already. Again, pulling things from brain, but I believe that if WSL2 can be exposed via ssh then it's trivial (you'd need to use the sock of the podman machine of course)

PodmanClient(base_url="ssh://[email protected]:22/run/podman/podman.sock?secure=True, identity="~alice/.ssh/api_ed25519")

inknos avatar Jun 04 '25 16:06 inknos

Oh wow, I didn't realize that the ssh:// endpoint is already a thing. It's even documented right in the Podman-py docs (https://podman-py.readthedocs.io/en/latest/index.html), but this comment threw me off:

https://github.com/containers/podman-py/blob/108d9f3ad354b457cf08a90ca6938d3566e6725d/README.md?plain=1#L38-L40

Perhaps this comment should be removed to not contradict the docs?

Also, I happen to have a Windows VM with Podman Desktop installed where I can test things at.

For instance, I can find the connection endpoint with:

PS C:\Users\dz> podman system connection list
Name        URI                                                          Identity                                                    Default     ReadWrite
test        ssh://[email protected]:50529/run/user/1000/podman/podman.sock  C:\Users\dz\.local\share\containers\podman\machine\machine  true        true
test-root   ssh://[email protected]:50529/run/podman/podman.sock            C:\Users\dz\.local\share\containers\podman\machine\machine  false       true

If I pass this endpoint to PodmanClient, I can initialize it successfully:

>>> client = PodmanClient(base_url="http+ssh://[email protected]:50529/run/user/1000/podman/podman.sock", identity=r"C:\Users\dz\.local\share\containers\podman\machine\machine")

If I try to use it though, I get the following error:

>>> client.containers.list()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\podman\domain\containers_manager.py", line 89, in list
    response = self.client.get("/containers/json", params=params)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\podman\api\client.py", line 266, in get
    return self._request(
           ^^^^^^^^^^^^^^
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\podman\api\client.py", line 440, in _request
    self.request(
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\requests\sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\requests\sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\requests\adapters.py", line 667, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\urllib3\connectionpool.py", line 493, in _make_request
    conn.request(
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\urllib3\connection.py", line 445, in request
    self.endheaders()
  File "C:\Users\dz\AppData\Local\Programs\Python\Python312\Lib\http\client.py", line 1333, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Users\dz\AppData\Local\Programs\Python\Python312\Lib\http\client.py", line 1093, in _send_output
    self.send(msg)
  File "C:\Users\dz\AppData\Local\Programs\Python\Python312\Lib\http\client.py", line 1037, in send
    self.connect()
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\podman\api\ssh.py", line 197, in connect
    sock = SSHSocket(self.uri, self.identity)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\dz\AppData\Local\pypoetry\Cache\virtualenvs\dangerzone-DU-xYaP2-py3.12\Lib\site-packages\podman\api\ssh.py", line 44, in __init__
    super().__init__(socket.AF_UNIX, socket.SOCK_STREAM)
                     ^^^^^^^^^^^^^^
AttributeError: module 'socket' has no attribute 'AF_UNIX'

It seems that it tries to create a UDS connection nevertheless. Should it be the case?

apyrgio avatar Jun 04 '25 17:06 apyrgio

I was trying the same right now.

Ideas:

  1. It might be worth playing with socket(socket.AF_INET, socket.SOCK_STREAM).
  2. It is definitely possible to interoperate with AF_UNIX and WSL~~2~~ (Edit: not sure if with WSL2 actually, which is the one we support)

I'll look it up tomorrow. ~~I guess that either it's possible already or it's going to be a quick change~~ that will bring in a lot of value

Edit: I went through the post again and added strikethrough

inknos avatar Jun 04 '25 17:06 inknos

It might be worth playing with socket(socket.AF_INET, socket.SOCK_STREAM).

Hm, I can experiment with this as well, it may be an easy fix.

It is definitely possible to interoperate with AF_UNIX and WSL2 (Edit: not sure if with WSL2 actually, which is the one we support)

I'm pretty sure it's for WSL1, but it's worth checking if there's any new development in that area. Thanks again for taking a look at this 🙂

apyrgio avatar Jun 05 '25 08:06 apyrgio

Docker and its Python package work well on Windows. I hope Podman will work too.

On WIndows, Docker uses Named Pipe by default:

https://github.com/docker/docker-py/blob/6e6a273573fe77f00776b30de0685162a102e43f/docker/api/client.py#L153 https://github.com/docker/docker-py/blob/main/docker/transport/npipeconn.py https://github.com/docker/docker-py/blob/main/docker/transport/npipesocket.py

but it seems to support SSH on Windows too with AF_INET SSH socket: https://github.com/docker/docker-py/blob/main/docker/transport/sshconn.py

Ark-kun avatar Sep 18 '25 07:09 Ark-kun