`podman wait --condition=exited` (and `=stopped`) returns immediately with
exit code 0 for a container that was created but never started. This
matches Docker's `not-running` semantics, but leaves no way to block until
the container has actually run and exited.
Move the Docker wait conditions from the compat API into libpod, so that
they are available to the CLI and the libpod REST API, and let the compat
handler use them instead of its own implementation:
* next-exit: wait for the next "died" event regardless of the current
state and return its exit code. Like Docker, removal also ends the wait
* not-running: the same as exited
* removed: wait until the container has been removed and return its exit
code, or 0 if it never ran
The docker compat handler uses the new `ready` callback in
`WaitForConditionWithInterval` to send its headers to keep the fix for #28514
Behavior changes of the compat API:
* not-running on a never-started container now always returns 0, before
they could ping-pong between -1 and 0
* next-exit returns when the container is removed, instead of blocking
forever, and fails if the event stream ends without a died event
* removed polls the container state at the wait interval
Fixes: #27423
Co-authored-by: Jan Rodák <hony.com@seznam.cz>
Co-authored-by: Tom Sweeney <tsweeney@redhat.com>
Signed-off-by: Dan Čermák <dcermak@suse.com>
Assisted-by: Claude Opus 5.5
Assisted-by: Gemini 4 Argon
ContainerWait() reports errors of the individual waits in the report and
not as its own error, which WaitContainerLibpod ignored. Wait failures then
result in a 200 instead of erroring out
Also do not write a second response after an internal server error
Signed-off-by: Dan Čermák <dcermak@suse.com>
Assisted-by: Claude Opus 5.5
Update the generated Swagger specification so that Libpod API paths include the required version prefix. Keep the unversioned ping endpoint unchanged, reuse the version path parameter, and add tests for the path rewriting logic.
Fixes: #15376
Signed-off-by: JJordan0K <69581081+JJordan0C@users.noreply.github.com>
- Read system_cpu_usage from /proc/stat (first 7 CPU fields, including idle) instead of cgroups.SystemCPUUsage(), matching Docker semantics.
- Use CPU values from GetContainerStats() instead of a second cgroup read to avoid a timing gap.
- Populate precpu_stats on stream=false with a 100 ms sampling pauseso the Docker CPU% formula returns a directionally correc snapshot. This only affects the compat per-container endpoint; podman-remote stats uses a separate libpod handler.
- Return cpu_stats.cpu as 0 for one-shot=true since the two samples are only milliseconds apart.
- Replace direct precpu copy instead of JSON marshal/unmarshal round-trip.
- Propagate errors via fmt.Errorf instead of logrus.Errorf, letting callers decide how to handle them. Parse errors in /proc/stat fields are hard errors instead of silently returning partial data.
- Document that --no-stream CPU% is a coarse ~100 ms snapshot; streaming gives 5-second interval readings.
Fixes: https://github.com/podman-container-tools/podman/issues/28761
Fixes: https://github.com/podman-container-tools/podman/issues/24730
Fixes: https://github.com/podman-container-tools/podman/issues/29912
Fixes: https://github.com/podman-container-tools/podman/issues/25709
Signed-off-by: Jan Rodák <hony.com@seznam.cz>
Adds a -l/--label CLI flag to podman kube play and wires it through
the API, bindings, and ABI so user-provided labels are applied to pods,
PVCs, and secrets created from Kubernetes YAML.
Key features:
- Labels are merged with YAML labels (CLI takes precedence)
- Validation uses Kubernetes qualified-name rules (RFC1123 subdomains)
- Value validation enforces 63-char limit and charset rules
- Separate merge and validate functions (SOLID principle)
- Uses maps.Clone for cleaner merging
Fixes:
- Removed incorrect annotations size limit from label validation
- Refactored to call annotations.IsQualifiedName for key validation
- Added proper documentation for max key length enforcement
Closes#26450
Signed-off-by: Sakthi Harish <sakthi.harish@edgeverve.com>
When fetching build context tarballs for use in a build, pay attention
to the tlsVerify setting at the command line (in non-remote cases) or in
the build query (in remote cases), and whatever proxy settings are set
in the current environment for whichever process is connecting to a
server that may or may not be using TLS.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Buildah added some variants of APIs that should improve support for
cancellation, so let's use them.
Remove the import alias for its copier package in
cmd/podman/containers/cp.go and libpod/container_copy_common.go to be
more friendly to grep.
Update the "prune leftover build containers" test to intentionally leave
some behind during its setup instead of SIGKILLing a build process.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Docker documents `dead` and `restarting` as valid values for the
`status` filter on `/containers/json`. Podman returns HTTP 500 when
either of them is used even though no Podman container can ever be in
those states.
Ignore these values in the compat API. If they are the only status
filters, return an empty list like Docker does. Invalid status values
still return an error.
The libpod API still rejects these values since they are Docker
specific. Update the libpod API docs to list the states Podman
actually supports.
Reference:
https://docs.docker.com/reference/api/engine/version/v1.51/#tag/Container/operation/ContainerListFixes: #28904
Signed-off-by: Rudraksha Singh <rudraksharss@gmail.com>
Docker clients send the seccomp profile JSON itself in
HostConfig.SecurityOpt (the docker CLI reads the profile file
client-side and inlines it). The compat API treated the value as a path
to a profile file, so container create failed with "file name too
long". This breaks docker-compat tooling that passes seccomp profiles
through the socket, like Nextcloud AIO and forgejo-runner.
Add a SeccompProfile field to specgen for inline profile content,
next to the existing SeccompProfilePath, as requested in review of the
earlier PR that tried to fix this (#28985). The compat create handler
extracts inline profiles (values starting with "{") from SecurityOpt
and sets the new field. Path-based values and "unconfined" keep their
current meaning, and duplicate seccomp options resolve last-one-wins,
like docker.
Fixes: #27710
Signed-off-by: r-vdp <ramses@well-founded.dev>
Docker documents HostConfig.PidsLimit 0 as unlimited, but runc sets
pids.max=1 for OCI pids.limit 0. Normalize 0 to -1 when building the
OCI spec so native CLI, compat API, and kube play behave consistently.
Fixes: https://github.com/podman-container-tools/podman/issues/29826
Signed-off-by: Jan Rodák <hony.com@seznam.cz>
Docker API v1.44 omits the Created field (previously,
it was the zero value of 0001-01-01T00:00:00Z) if
the Created field is missing from the image config.
Omit it when zero from the compat API GET /images/{id}/json
(using `info.Created` instead of the previous `l.Created()`
that is set to `Now()` in storage/images.go when empty).
Add a test creating an image with the Created field missing.
Fixes: https://redhat.atlassian.net/browse/RUN-3317
Signed-off-by: Marek Simek <msimek@redhat.com>
This is a small Docker compat fix with the API exec endpoints.
With Docker, sending a bare Exec Create (command only, nothing
else set) and then an Exec Start without Detach set performs
a detached exec. With Podman, we threw an error that at least one
stream must be attached to. Fix is trivial; look up the session
before start, check the config for attach streams, and force
detach on if none are set.
Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Fixed the compat container update path so it preserves the existing restart policy unless the request explicitly includes a new one, and added a regression test for it.
Fixes: #29790
Signed-off-by: Srijan Keshri <212402043+arcusbuilds@users.noreply.github.com>
Allow deployments and scheduled jobs to update a selected group of
containers without checking every auto-update-enabled application.
Reuse the existing container filters and expose them through the CLI,
remote bindings, and REST API.
Filter update candidates while preserving systemd unit and pod restart
behavior. Document the selection semantics and cover filtered updates,
invalid input, remote requests, and pod restarts in the existing tests.
Signed-off-by: Evan Purkhiser <git@evanpurkhiser.com>
The Docker-compatible network API omitted the IPRange field from the IPAM
config even though Libpod stores this data, so tools reading the Docker
API could not see the configured IP range.
Map Libpod's LeaseRange to Docker-compatible IPAMConfig.IPRange when it
aligns with a full CIDR span derived from FirstIPInSubnet/LastIPInSubnet,
and add an integration test that creates a network via the compat API with
an explicit IPRange and asserts it is returned on inspect.
The span is matched with bit arithmetic rather than by trying every prefix
length: the network address is start-1, and XORing that with end yields the
host mask, which identifies the prefix in a single pass. net/netip carries
the address handling throughout - Unmap collapses 4-in-6, Prev gives the
network address, and Masked confirms the network is aligned to the prefix.
Fixes: #28378
Signed-off-by: aayushbaluni <73417844+aayushbaluni@users.noreply.github.com>
create and run already take --pidfile, but the path is fixed at create
time and reused on every start. Toolbx wants a fresh path per start so it
can learn the PID of the container's entry point, which names the stamp
file the entry point creates once it is initialized, before running
podman exec.
Add the same flag to start. libpod's Container.Start now returns the PID
of the container's main process, read while the container lock is still
held right after the OCI runtime started it, so the value always belongs
to the process this start launched. For a container that is already
running it returns the PID of that process together with
ErrCtrStateRunning, read under the same lock that saw the running state.
start --pidfile writes this PID to the requested path.
The flag only works for a single container and is rejected together with
--attach. As documented for create and run --pidfile, it is not
available on the remote client; start returns an error there rather than
silently ignoring the flag.
Fixes: #25849
Signed-off-by: Marek Nogacki <no.marek@gmail.com>
processMultipartQuadlets previously deferred closing each multipart part
and file inside the loop, leaking descriptors until the handler returned.
It also opened files with os.Create, silently overwriting earlier files if
a request contained parts with duplicate names.
Align processMultipartQuadlets with the manifests multipart upload handler:
- Wrap each part processing in a closure so part and file descriptors close
immediately on each loop iteration.
- Use os.OpenFile with os.O_CREATE|os.O_EXCL|os.O_WRONLY (0600) so duplicate
filenames return an error instead of silently overwriting.
- Sanitize filenames using filepath.Base to prevent directory traversal.
- Add unit tests verifying multiple file extraction, duplicate name rejection,
and path traversal sanitization.
Fixes: #29752
Signed-off-by: Madhosh Yagnik <madhosh1yagnik@gmail.com>
Until now the default could only be expressed by leaving the option off, which
reads as an omission rather than a choice and gives a script no way to say it
wants the archive transferred as podman save wrote it.
Accept none as a format meaning exactly that. It is taken on the API path too,
so both interfaces share one vocabulary, and it is treated as the absence of a
format throughout: nothing is compressed, a level attached to it is rejected the
same way a level with no format is, and the local user to user transfer has
nothing to warn about ignoring.
The remote client still leaves it off the request, so naming the default does
not make a transfer fail against a service that predates these options.
Signed-off-by: Scott Callaway <github@scottcallaway.co.uk>
The tunnel engine builds its own ScpOptions, so without this the flags parse
fine under podman --remote and are then dropped, transferring uncompressed with
no indication that anything was ignored.
Carry both options through the bindings to the libpod ImageScp handler, which
hands them to ExecuteTransfer the same way the local path does, and document
them on the endpoint.
This is also the point at which the transfer's own validation becomes reachable
over HTTP, so map it accordingly: a rejected format or level is the caller's
mistake and answers 400, not the 500 every error from the transfer used to
produce.
Signed-off-by: Scott Callaway <github@scottcallaway.co.uk>
Looks like it picked up new deprecated matches so we need some more
nolint to silence them where we still need them for backwards compat in
the API.
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Rootless Podman with the cgroupfs manager cannot create a cgroup parent outside its delegated subtree, and container creation already leaves the parent unset there. Reporting "cgroupfs" makes buildx pin its BuildKit container to /docker/buildx, which crun then fails to create with EPERM.
Report "none", as rootless Docker does.
Fixes: #27824
Signed-off-by: Victor Irzak <victor.irzak@zomp.com>
Existing KillContainer handling uses HTTP status code 409 when the request cannot be performed because of the current container state. HTTP status code 404 is also used when the target container does not exist.
In contrast, errors from the stats handler are not reflected in the HTTP status code. The HTTP status code is always 200, and the errors are recorded only as generic errors in the server log.
To maintain compatibility with both streaming enabled and disabled, this change treats obtaining at least one complete unit of response content as the response contract. It then keeps the response content consistent with the HTTP status code.
Signed-off-by: Hiroaki KAWAI <hiroaki.kawai@gmail.com>
Since I use go 1.26 the go fix does not have all the rules built in,
there are newer ones in modernize so run the explicitly to fix more code
for go 1.26.
Signed-off-by: Paul Holzinger <pholzing@redhat.com>