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

GET operation failed - when running podman as sudo

Open D3vil0p3r opened this issue 1 year ago • 5 comments

I want to get podman info without specifying a base uri, by using podman.from_env() (as occurs for python docker lib).

When I run sudo systemctl start podman and I run the code

import podman
from podman import PodmanClient

client = podman.from_env()

print("Podman client:", client)

try:
    print("Base URL:", client.api.base_url)
    print("Version:", client.version())
    print("Client Info:", client.info())
except Exception as e:
    print("Error occurred while accessing client attributes:", e)

produces:

Podman client: <podman.client.PodmanClient object at 0x787de8633680>

Base URL: ParseResult(scheme='http+unix', netloc='%2Ftmp%2Fpodmanpy-runtime-dir-fallback-root%2Fpodman%2Fpodman.sock', path='', params='', query='', fragment='')

Error occurred while accessing client attributes: http://%2Ftmp%2Fpodmanpy-runtime-dir-fallback-root%2Fpodman%2Fpodman.sock/v5.2.0/libpod/version (GET operation failed)

The script works only if I run podman service as user by systemctl start --user podman.

D3vil0p3r avatar Oct 24 '24 16:10 D3vil0p3r

hi, I can reproduce it with

systemctl stop --user podman
systemctl stop --user podman.sock
systemctl restart podman
python script.py

What do you suggest here @D3vil0p3r ? Graceful error handling?

cc: @jwhonce : was this discussed in the past already?

inknos avatar Oct 24 '24 16:10 inknos

Thank you for the answer. By your systemctl restart podman, you should have prompted pkexec for password, so podman also in your case is run as root. If you tried by systemctl restart --user podman it worked correctly. The problem arises only by root mode.

D3vil0p3r avatar Oct 24 '24 16:10 D3vil0p3r

you should have prompted pkexec for password

I am not sure if this is the right action since podman can run rootless (actually that's one of its strengths). I would encourage the user to start the --user service instead or to rerun the script via sudo.

I am thinking to catch it via an exception and printing some useful message like:

    Podman service might not be available for the user. Try this for a fix.

        systemctl --user start podman

Actually, I just tried to do sudo python script.py (which afaik is the same as pkexec) and the situation fails again (correctly imho). Likewise, the script fails even when run in a root shell.


I would still wait for a second opinion from @jwhonce who might know more about it. I am positively convinced this might have popped out in the past

inknos avatar Oct 24 '24 16:10 inknos

you should have prompted pkexec for password

I am not sure if this is the right action since podman can run rootless (actually that's one of its strengths). I would encourage the user to start the --user service instead or to rerun the script via sudo.

sorry, probably I explained not well. When you run systemctl restart podman (with no sudo and with no --user), the system forces to run that command as sudo. Here the evidence: Image

D3vil0p3r avatar Oct 24 '24 17:10 D3vil0p3r

I would add... is it possible to implement the raising of exception when podman is down and returns that GET operation failed at the same manner occurs on docker py?

In docker py, it generates the following one when run docker.from_env() with docker is down. It would be nice to have the same behavior also for podman py:

Python 3.12.7 (main, Oct  1 2024, 11:15:50) [GCC 14.2.1 20240910] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import podman
>>> from podman import PodmanClient
>>> client = podman.from_env()
>>> import docker
>>> from docker import DockerClient
>>> client = docker.from_env()
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/urllib3/connectionpool.py", line 716, in urlopen
    httplib_response = self._make_request(
                       ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/urllib3/connectionpool.py", line 416, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python3.12/site-packages/urllib3/connection.py", line 244, in request
    super(HTTPConnection, self).request(method, url, body=body, headers=headers)
  File "/usr/lib/python3.12/http/client.py", line 1336, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/lib/python3.12/http/client.py", line 1382, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.12/http/client.py", line 1331, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.12/http/client.py", line 1091, in _send_output
    self.send(msg)
  File "/usr/lib/python3.12/http/client.py", line 1035, in send
    self.connect()
  File "/usr/lib/python3.12/site-packages/docker/transport/unixconn.py", line 26, in connect
    sock.connect(self.unix_socket)
FileNotFoundError: [Errno 2] No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/requests/adapters.py", line 667, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/urllib3/connectionpool.py", line 802, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/urllib3/util/retry.py", line 552, in increment
    raise six.reraise(type(error), error, _stacktrace)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/urllib3/packages/six.py", line 769, in reraise
    raise value.with_traceback(tb)
  File "/usr/lib/python3.12/site-packages/urllib3/connectionpool.py", line 716, in urlopen
    httplib_response = self._make_request(
                       ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/urllib3/connectionpool.py", line 416, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python3.12/site-packages/urllib3/connection.py", line 244, in request
    super(HTTPConnection, self).request(method, url, body=body, headers=headers)
  File "/usr/lib/python3.12/http/client.py", line 1336, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/lib/python3.12/http/client.py", line 1382, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.12/http/client.py", line 1331, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.12/http/client.py", line 1091, in _send_output
    self.send(msg)
  File "/usr/lib/python3.12/http/client.py", line 1035, in send
    self.connect()
  File "/usr/lib/python3.12/site-packages/docker/transport/unixconn.py", line 26, in connect
    sock.connect(self.unix_socket)
urllib3.exceptions.ProtocolError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/docker/api/client.py", line 223, in _retrieve_server_version
    return self.version(api_version=False)["ApiVersion"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docker/api/daemon.py", line 181, in version
    return self._result(self._get(url), json=True)
                        ^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docker/utils/decorators.py", line 44, in inner
    return f(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docker/api/client.py", line 246, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/requests/adapters.py", line 682, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.12/site-packages/docker/client.py", line 94, in from_env
    return cls(
           ^^^^
  File "/usr/lib/python3.12/site-packages/docker/client.py", line 45, in __init__
    self.api = APIClient(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docker/api/client.py", line 207, in __init__
    self._version = self._retrieve_server_version()
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/docker/api/client.py", line 230, in _retrieve_server_version
    raise DockerException(
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

The reason of this further request is to not allow the script to go ahead and produce other errors downstream.

D3vil0p3r avatar Oct 24 '24 19:10 D3vil0p3r