exec_run(cmd, socket=True) isn't implemented: blocks and only returns resulting stdout/stderr bytes
As per docs and docker API examples, c.exec_run(cmd, socket=True) should return immediately with socket to be used for process' stdin/out/err as the second value of the returned tuple. However, podman-py waits for the process to finish and it only returns final stdout/err bytes as the output.
Fiddling with stream and tty parameters doesn't make any change in the behaviour.
Given that googling for "PodmanClient" "exec_run" "socket=True" or "PodmanClient" "exec_run" "stdin=True" yields zero results in both cases, maybe it's fine that socket=True isn't implemented, but then socket, stdin and stream parameters to exec_run() shouldn't be mentioned in the docs at all, or at the very least, throw the NotImplementedError exception when calling exec_run() with either of these set to True?
versions
- Fedora 40: python3-podman-5.2.0-1.fc40.noarch
- RHEL 9: python3-podman-5.2.0-1.el9.noarch
Reproducers:
just outputs
>>> pc = PodmanClient(base_url=podman_sock)
>>> c = pc.containers.get(cont_name)
>>> res = c.exec_run(["bash", "-c", "echo -n 'hello'; sleep 10; echo 'world!'"], socket=True); type(res[1])
Actual results:
type(res[1])output only appears after 10 s- the type of
res[1]is<class 'bytes'>
Expected result: res is returned right away and its output field is socket object for further I/O
with stdin
>>> res = c.exec_run("bash", socket=True, stdin=True); type(res[1])
exit<enter>
Expected results: bash receives the exit command and ends itself
Actual results:
- bash never receives the
exitcommand - API waits for data that can't come
- no clean way to get out of the wait, keyboard interrupt in an interactive intepreter produces this traceback (on RHEL 9):
>>> sock = c.exec_run("bash", stdin=True, socket=True, tty=False) exit ^CTraceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.9/site-packages/podman/domain/containers.py", line 198, in exec_run start_resp = self.client.post( File "/usr/lib/python3.9/site-packages/podman/api/client.py", line 327, in post return self._request( File "/usr/lib/python3.9/site-packages/podman/api/client.py", line 425, in _request self.request( File "/usr/lib/python3.9/site-packages/requests/sessions.py", line 544, in request resp = self.send(prep, **send_kwargs) File "/usr/lib/python3.9/site-packages/requests/sessions.py", line 699, in send r.content File "/usr/lib/python3.9/site-packages/requests/models.py", line 831, in content self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b'' File "/usr/lib/python3.9/site-packages/requests/models.py", line 753, in generate for chunk in self.raw.stream(chunk_size, decode_content=True): File "/usr/lib/python3.9/site-packages/urllib3/response.py", line 628, in stream data = self.read(amt=amt, decode_content=decode_content) File "/usr/lib/python3.9/site-packages/urllib3/response.py", line 567, in read data = self._fp_read(amt) if not fp_closed else b"" File "/usr/lib/python3.9/site-packages/urllib3/response.py", line 533, in _fp_read return self._fp.read(amt) if amt is not None else self._fp.read() File "/usr/lib64/python3.9/http/client.py", line 463, in read n = self.readinto(b) File "/usr/lib64/python3.9/http/client.py", line 507, in readinto n = self.fp.readinto(b) File "/usr/lib64/python3.9/socket.py", line 704, in readinto return self._sock.recv_into(b) KeyboardInterrupt
hey @djasa , thanks for the detailed report. you are correct, exec_run differs in the implementation from docker python sdk. There are missing kwargs and some of the functionalities might not be there.
Furthermore, some commands might be in the docs as part of in progress work, then the work was dropped some time ago. We should definitely cleanup the docs a bit.
are you interested in taking care of the implementation of one or more arguments?
are you interested in taking care of the implementation of one or more arguments?
I'm sorry, it's out of my skills, I haven't yet even used socket-based APIs so far. 😅 It will be OK for me to use a call to podman exec as a work around, so even just docs fix or raising the NotImplementedError would be a good fix from my POV.
Got it, I will put it in the backlog. Thanks for the report, we got more interest around exec_run recently, so I hope to have it fixed soon
FYI: Based on the Podman API documentation the socket and stream parameters are not implemented, ref: ExecStart
The Docker Python SDK uses the exec_start method to start the exec which can handle the socket and stream parameters on API level.
So in my understanding, some changes are needed on Podman API side (or hacking in podman-py).