Commit graph

1111 commits

Author SHA1 Message Date
Chris Evich
9ab7b493c1
Fix podman-remote build never utilizing cache
Previously, for podman-remote builds, the compat handler set
`OutputFormat` from the client only, with no default. When the client
didn’t send `outputformat`, Buildah got `""` but still produced OCI
images. Cache lookup then compared the candidate’s OCI manifest type to
`""` and rejected it.  Fix this by checking if `query.OutputFormat` is
empty, then if so set `format = buildah.OCIv1ImageManifest` before
calling Buildah, so cache checks match the OCI images that are actually
built.

Also fix a bug so podman-remote is correctly sent the `layers` option
even when it's false (by whatever means).  This makes the bindings match
the behavior of a regular `podman build`.

Produced with significant assistance from AI: Cursor <Auto>

Signed-off-by: Chris Evich <cevich@redhat.com>
2026-03-30 15:13:44 -04:00
Chris Evich
a27129f451
Align build behavior with v4.4.1-rhel
* Default layers=true for both Docker compat and libpod clients
* Allow builds to stop if a remote client disconnects.

Signed-off-by: Chris Evich <cevich@redhat.com>
2026-03-30 15:13:44 -04:00
Chris Evich
38a6120cad
compat: add flush after Aux encode in build API for Docker parity
Add flush() between Aux and Stream JSON objects in the build API response
to ensure each object is sent separately. Docker clients (e.g. docker-py)
expect one JSON object per read; without this flush, Aux and Stream could
be buffered together causing parse failures.

Backport of cdb00332da (Fix compat build API returning two JSON objects at once)
Closes: containers/podman#16360

AI-Attribution: Created/Modified with the assistance of AI: Cursor <Auto>

Signed-off-by: Chris Evich <cevich@redhat.com>
Made-with: Cursor
2026-03-30 15:13:43 -04:00
Lokesh Mandvekar
42eb6ed9c0
Add sha256: to images history id for docker compatibility
Add sha256: prefix to image IDs in compat API history responses for
Docker compatibility. Excludes bash test changes as those were already
added by the previous commit.

Fixes: https://github.com/containers/podman/issues/17762

(partial cherry-pick from commit edaf3b4d5e)

Signed-off-by: Lokesh Mandvekar <lsm5@redhat.com>
Signed-off-by: Chris Evich <cevich@redhat.com>
2026-03-30 15:13:38 -04:00
Daniel J Walsh
c3025e09ae
Use default_ulimits field in containers.conf
The default_ulimits field is currently ignored in podman run commands.
This PR fixes this.

Fixes: https://github.com/containers/podman/issues/17396

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
(cherry picked from commit 6046832f3e)
Signed-off-by: Lokesh Mandvekar <lsm5@redhat.com>
Signed-off-by: Chris Evich <cevich@redhat.com>
2026-03-30 15:13:37 -04:00
Lokesh Mandvekar
1f9ac52b9f
Add remote build functionality for podman-remote
(cherry picked from commit 7c2eb4006c)

This commit adds:
- Remote build implementation (build_remote.go)
- Version command for remote builds (version_remote.go)
- Fix error handling in images_build.go

Signed-off-by: Lokesh Mandvekar <lsm5@redhat.com>
2026-03-30 15:13:32 -04:00
Lokesh Mandvekar
421d11529e
Add build-tagged splits for libimage-dependent code
(cherry picked from commit 4231526e18)

The common v0.57.7 vendor bump added !remote build tags to libimage,
causing podman-remote builds to fail. This change splits files that
use libimage into separate _local and _remote variants:

- pkg/specgen/specgen_{local,remote}.go: Image field storage and methods
- pkg/api/handlers/types_local.go: ImageDataToImageInspect function
- cmd/podman/utils/error_local.go: ExitCodeFromBuildError function

This allows type definitions to be shared between remote and local
builds while keeping libimage-dependent implementations local-only.

Signed-off-by: Lokesh Mandvekar <lsm5@redhat.com>
2026-03-30 15:13:31 -04:00
Chris Evich
be7b956790
Fix compilation errors for v4.4.1-rhel compatibility
Align codebase with v4.4.1-rhel PodmanConfig structure
and API signatures to resolve compilation errors.

- Update all cfg.Engine.* references to
  cfg.ContainersConf.Engine.* or
  cfg.ContainersConfDefaultsRO.Engine.*
- Update all cfg.Network.* references to
  cfg.ContainersConf.Network.*
- Update all cfg.Containers.* references to
  cfg.ContainersConf.Containers.* or
  cfg.ContainersConfDefaultsRO.Containers.*
- Update cfg.Machine.* references to
  cfg.ContainersConfDefaultsRO.Machine.*
- Fix PodmanConfig initialization in config.go to use
  ContainersConf and ContainersConfDefaultsRO fields

- Add createOptions parameter to NetworkCreate method
  across all implementations (abi, tunnel, handlers)
- Update ContainerEngine interface to match new
  NetworkCreate signature
- Fix manager.Store call in secrets.go to use
  StoreOptions struct
- Update DiskUsage to handle 3 return values
- Fix NewConnectionWithIdentity call signature

- Remove duplicate setupRemoteConnection function
- Remove duplicate readRemoteCliFlags function
- Remove duplicate function declarations in
  container_path_resolution.go, oci_conmon_linux.go
- Comment out duplicate SpecGenToOCI and helper
  functions in oci.go/oci_linux.go
- Remove unused imports across multiple files
- Fix SSHMode flag handling (field doesn't exist in
  current PodmanConfig)

- Fix ns.NetNS type handling in container_internal_linux.go
- Add missing Terminal() method to Container struct
- Add missing SdNotifySocket field to ContainerConfig
- Fix DefaultCapabilities to use .Get() method
- Fix cgroups.AvailableControllers reference
- Fix ConmonPath type conversion (attributedstring.Slice)
- Add missing ErrNetworkConnected error definition
- Fix NetworkCreateOptions handling in secrets.go

- Update networking code to use getNetNSPathCommon helper
- Fix teardownNetwork method signature
- Fix makeInspectPorts to makeInspectPortBindings
- Remove hardcoded IsPasta() checks
- Fix runtime_libpod.go field access patterns

All changes align with the v4.4.1-rhel worktree structure
to ensure compatibility with upcoming cherry-picks.

Substantially Assisted-by AI: Cursor <auto>
Signed-off-by: Chris Evich <cevich@redhat.com>
2026-03-30 14:52:52 -04:00
tomsweeneyredhat
55775faaf9
Adjust for common bump
(cherry picked from commit e035eb4ffa)

The vendoring of Buildah dragged in a bump of common from v0.51.4 to
v0.57.7 which contained many changes to variable and function names.

Signed-off-by: tomsweeneyredhat <tsweeney@redhat.com>
Signed-off-by: Chris Evich <cevich@redhat.com>
2026-01-28 10:48:05 -05:00
Aditya R
75b236a2b4 compat,build: handle docker's preconfigured cacheTo,cacheFrom
Docker's newer clients popuates `cacheFrom` and `cacheTo` parameter
by default as empty array for all commands but buildah's design of
distributed cache expects this to be a repo not image hence parse
only the first populated repo and igore if empty array.

Signed-off-by: Aditya R <arajan@redhat.com>
2023-01-05 22:44:01 +00:00
tomsweeneyredhat
0f8ba63f04 [v4.2-rhel] Bump Buildah to v1.27.3
Bump Buildah to v1.27.3 which itself bumps opencontainers/selinux to
1.10.2, has fixes for the sticky bit, allows containers to be
restarted in a pod when they should be, a fix for a RHEL subscription issue,
 and s390x segv issues across RHEL 8.7 and 9.1 Zstreams

Addresses:
https://bugzilla.redhat.com/show_bug.cgi?id=2150416
https://bugzilla.redhat.com/show_bug.cgi?id=2150428
https://bugzilla.redhat.com/show_bug.cgi?id=2137294
https://bugzilla.redhat.com/show_bug.cgi?id=2149775
https://bugzilla.redhat.com/show_bug.cgi?id=2152027
https://bugzilla.redhat.com/show_bug.cgi?id=2152017
https://bugzilla.redhat.com/show_bug.cgi?id=2150433
https://bugzilla.redhat.com/show_bug.cgi?id=2150432
https://bugzilla.redhat.com/show_bug.cgi?id=2136928
https://bugzilla.redhat.com/show_bug.cgi?id=2149776
https://bugzilla.redhat.com/show_bug.cgi?id=2152026
https://bugzilla.redhat.com/show_bug.cgi?id=2152022
https://bugzilla.redhat.com/show_bug.cgi?id=2152042
https://bugzilla.redhat.com/show_bug.cgi?id=2152043

[NO NEW TESTS NEEDED]
Signed-off-by: tomsweeneyredhat <tsweeney@redhat.com>
2022-12-09 19:58:50 -05:00
Brent Baude
94d685c0d5 Prevent nil pointer deref in GetImage
Trying to print the image id on a failed inspect will result in a nil
pointer panic because the image will be nil.  Replace image.id with the
image name which is defined as a string without the use of inspect.

Fixes: bz#2131836

[NO NEW TESTS NEEDED]

Signed-off-by: Brent Baude <bbaude@redhat.com>
2022-10-05 00:54:26 +00:00
Jason T. Greene
8b9e5fb085 Use 8k buffer to help clients w/ broken parsing
Signed-off-by: Jason T. Greene <jason.greene@redhat.com>
2022-08-10 16:46:05 -04:00
Aditya R
9b0a1fa752 build: implement --cache-to,--cache-from and --cache-ttl
[NO NEW TESTS NEEDED]
[NO TESTS NEEDED]

Signed-off-by: Aditya R <arajan@redhat.com>
2022-08-10 16:46:04 -04:00
Vladimir Kochnev
e6ebfbd1e0 Set TLSVerify=true by default for API endpoints
Option defaults in API must be the same as in CLI.

```
% podman image push --help
% podman image pull --help
% podman manifest push --help
% podman image search --help
```

All of these CLI commands them have --tls-verify=true by default:
```
--tls-verify  require HTTPS and verify certificates when accessing the registry (default true)
```

As for `podman image build`, it doesn't have any means to control
`tlsVerify` parameter but it must be true by default.

Signed-off-by: Vladimir Kochnev <hashtable@yandex.ru>
2022-07-26 14:44:05 -04:00
Paul Holzinger
c4616510a2 API: libpod/create use correct default umask
Make sure containers created via API have the correct umask from
containers.conf set.

Fixes #15036

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2022-07-26 14:39:39 -04:00
Paul Holzinger
553a700966 compat api: always turn on network isolation for networks
Fix some network option parsing logic to use constants.
Always use the isolate option since this is what docker does.
Remove the icc option, this is different from isolate and it is not
implemented.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2022-07-26 14:36:20 -04:00
Paul Holzinger
aef8039d37 compat api: allow default bridge name for networks
Docker uses "bridge" as default network name so some tools expect this
to work with network list or inspect. To fix this we change "bridge" to
the podman default ("podman") name.

Fixes #14983

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2022-07-26 14:36:10 -04:00
Jakub Guzik
fa7e9f0f81 Compat API: unify pull/push and add missing progress info
Progress bar in JSONMessage is missing compared to docker output both in
pull and push. Additionaly, pull was not using JSONMessage while push
was using the type.
[NO NEW TESTS NEEDED]

Signed-off-by: Jakub Guzik <jguzik@redhat.com>
2022-07-26 14:27:23 -04:00
Valentin Rothberg
fde39edb9c remote push: show copy progress
`podman-remote push` has shown absolutely no progress at all. Fix that
by doing essentially the same as the remote-pull code does.

The get-free-out-of-jail-card for backwards compatibility is to let the
`quiet` parameter default to true.  Since the --quioet flag wasn't
working before either, older Podman clients do not set it.

Also add regression tests to make sure we won't regress again.

Fixes: #11554
Fixes: #14971
Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
2022-07-26 14:27:07 -04:00
Karthik Elango
6d84a9952f Podman stop --filter flag
Filter flag is added for podman stop and podman --remote stop. Filtering logic is implemented in
getContainersAndInputByContext(). Start filtering can be manipulated to use this logic as well to limit redundancy.

Signed-off-by: Karthik Elango <kelango@redhat.com>
2022-07-26 13:25:36 -04:00
Sascha Grunert
a78be890ee Switch to github.com/blang/semver/v4
Switch to the latest version of the now go module compatible release.

[NO NEW TESTS NEEDED]

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
2022-07-26 13:22:46 -04:00
openshift-ci[bot]
76422ecdbb
Merge pull request #14818 from rhatdan/wait
podman wait can take multiple conditions
2022-07-11 08:06:58 +00:00
Daniel J Walsh
96dd57ca50
podman wait can take multiple conditions
Podman wait should not be defaulting to just stopped.  By default
wait API waits for stopped and exited.  We should not override this on
the client side.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2022-07-08 05:26:56 -04:00
Sascha Grunert
a46f798831
pkg: switch to golang native error wrapping
We now use the golang error wrapping format specifier `%w` instead of
the deprecated github.com/pkg/errors package.

[NO NEW TESTS NEEDED]

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
2022-07-08 08:54:47 +02:00
openshift-ci[bot]
07a7a891ae
Merge pull request #14825 from jmguzik/fix_streaming_pod_stats
Fix streaming for libpod/pods/stats endpoint
2022-07-07 12:58:25 +00:00
openshift-ci[bot]
48c8923248
Merge pull request #14673 from idleroamer/fix-network-inspect-main
Fix network inspect compat API discrepancy
2022-07-07 11:55:30 +00:00
Paul Holzinger
cc6faddfaa
use c/common code for resize and CopyDetachable
Since conmon-rs also uses this code we moved it to c/common. Now podman
should has this also to prevent duplication.

[NO NEW TESTS NEEDED]

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2022-07-06 16:57:07 +02:00
Jakub Guzik
72aa00aca0 Fix streaming for libpod/pods/stats endpoint
This commit fixes libpod/pods/stats endpoint which should stream the data.
Additional option param is added to disable streaming and the delay value
to choose the desired delay between streamed messages (default 5s).

Signed-off-by: Jakub Guzik <jguzik@redhat.com>
2022-07-05 22:02:04 +02:00
🤓 Mostafa Emami
ee05bc0318 Fix network inspect compat API discrepancy
- containerInspect compat API expects field value PrefixLen
  instead of PrefixLength for type Address for SecondaryIPAddresses
- Add tests for network part of containerInspect compat api

Closes: containers#14674
Signed-off-by: 🤓 Mostafa Emami <mustafaemami@gmail.com>
2022-07-05 21:25:32 +02:00
Sascha Grunert
251d91699d
libpod: switch to golang native error wrapping
We now use the golang error wrapping format specifier `%w` instead of
the deprecated github.com/pkg/errors package.

[NO NEW TESTS NEEDED]

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
2022-07-05 16:06:32 +02:00
openshift-ci[bot]
2c9f0753da
Merge pull request #14534 from jakecorrenti/docker-compose-update-network-mtu
(rootful) docker-compose now updates network MTU
2022-07-05 13:46:23 +00:00
Jake Correnti
488eb3b74c (rootful) docker-compose now updates network MTU
Previously, the following network block did not update using
docker-compose:

```
networks:
  default:
    driver: bridge
    driver_opts:
      mtu: 9000
```

In the API, the network options were previously not being handled when the
network was being created. I translated the docker options into podman
options, and added the options to the network.

When doing `podman network inspect <network>`, the results now contain
`"mtu": "9000"`

Fixes: #14482

Signed-off-by: Jake Correnti <jcorrenti13@gmail.com>
2022-07-05 07:54:09 -04:00
Sascha Grunert
597de7a083
libpod/runtime: switch to golang native error wrapping
We now use the golang error wrapping format specifier `%w` instead of
the deprecated github.com/pkg/errors package.

[NO NEW TESTS NEEDED]

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
2022-07-04 15:39:00 +02:00
Aditya R
7bbfb3eb0d
api,images: add support for LookupManifest to Image remove API
ImagesBatchRemoval and ImageRemoval now honors and accepts
`LookupManifest` parameter which further tells libimage to resolve to
manifest list if it exists instead of actual image.

Following PR also makes `podman-remote manifest rm` functional which was
broken till now.

Closes: https://github.com/containers/podman/issues/14763

Signed-off-by: Aditya R <arajan@redhat.com>
2022-06-30 14:56:42 +05:30
openshift-ci[bot]
d8f197cc14
Merge pull request #14400 from cdoern/scp
podman image scp remote support & podman image scp tagging
2022-06-28 17:46:12 +00:00
openshift-ci[bot]
50fa651a4e
Merge pull request #14700 from shuttle-hq/bug/docker-compat-initialized
Docker compat returning unknown "initialized" for `status.status`
2022-06-28 14:07:04 +00:00
chesedo
cc49146332 Docker compat returning unknown "initialized" for status.status
Some background for this PR is in discussion #14641. In short, ever so often a container inspect will return a `status.status` of `initialized` from the Docker compat socket.

From the discussion I found these lines which tries to fix a "configured" status to "created".
c936d1e611/pkg/api/handlers/compat/containers.go (L291-L294)

However, commit 141de86862 (Revamp Libpod state strings for Docker compat) removed the "configured" return value from the `String()` method called on line 291 above. Thus, making the `if` check redundant as it will never hit. But the same commit also introduces a return for "initialized" which this `if` should probably have been adapted for.

Signed-off-by: Pieter Engelbrecht <pieter@shuttle.rs>
2022-06-28 15:50:45 +02:00
cdoern
6d3520e8b7 podman image scp remote support & podman image scp tagging
add support for podman-remote image scp as well as direct access via the API. This entailed
a full rework of the layering of image scp functions as well as the usual API plugging and type creation

also, implemented podman image scp tagging. which makes the syntax much more readable and allows users t tag the new image
they are loading to the local/remote machine:

allow users to pass a "new name" for the image they are transferring
`podman tag` as implemented creates a new image im `image list` when tagging, so this does the same
meaning that when transferring images with tags, podman on the remote machine/user will load two images
ex: `podman image scp computer1::alpine computer2::foobar` creates alpine:latest and localhost/foobar on the remote host

implementing tags means removal of the flexible syntax. In the currently released podman image scp, the user can either specify
`podman image scp source::img dest::` or `podman image scp dest:: source::img`. However, with tags this task becomes really hard to check
which is the image (src) and which is the new tag (dst). Removal of that streamlines the arg parsing process

Signed-off-by: Charlie Doern <cdoern@redhat.com>
2022-06-28 08:54:19 -04:00
openshift-ci[bot]
088665d2cf
Merge pull request #14654 from cdoern/cgroup
podman cgroup enhancement
2022-06-27 15:14:20 +00:00
cdoern
2792e598c7 podman cgroup enhancement
currently, setting any sort of resource limit in a pod does nothing. With the newly refactored creation process in c/common, podman ca now set resources at a pod level
meaning that resource related flags can now be exposed to podman pod create.

cgroupfs and systemd are both supported with varying completion. cgroupfs is a much simpler process and one that is virtually complete for all resource types, the flags now just need to be added. systemd on the other hand
has to be handeled via the dbus api meaning that the limits need to be passed as recognized properties to systemd. The properties added so far are the ones that podman pod create supports as well as `cpuset-mems` as this will
be the next flag I work on.

Signed-off-by: Charlie Doern <cdoern@redhat.com>
2022-06-24 15:39:15 -04:00
Valentin Rothberg
30e7cbccc1 libpod: fix wait and exit-code logic
This commit addresses three intertwined bugs to fix an issue when using
Gitlab runner on Podman.  The three bug fixes are not split into
separate commits as tests won't pass otherwise; avoidable noise when
bisecting future issues.

1) Podman conflated states: even when asking to wait for the `exited`
   state, Podman returned as soon as a container transitioned to
   `stopped`.  The issues surfaced in Gitlab tests to fail [1] as
   `conmon`'s buffers have not (yet) been emptied when attaching to a
   container right after a wait.  The race window was extremely narrow,
   and I only managed to reproduce with the Gitlab runner [1] unit
   tests.

2) The clearer separation between `exited` and `stopped` revealed a race
   condition predating the changes.  If a container is configured for
   autoremoval (e.g., via `run --rm`), the "run" process competes with
   the "cleanup" process running in the background.  The window of the
   race condition was sufficiently large that the "cleanup" process has
   already removed the container and storage before the "run" process
   could read the exit code and hence waited indefinitely.

   Address the exit-code race condition by recording exit codes in the
   main libpod database.  Exit codes can now be read from a database.
   When waiting for a container to exit, Podman first waits for the
   container to transition to `exited` and will then query the database
   for its exit code. Outdated exit codes are pruned during cleanup
   (i.e., non-performance critical) and when refreshing the database
   after a reboot.  An exit code is considered outdated when it is older
   than 5 minutes.

   While the race condition predates this change, the waiting process
   has apparently always been fast enough in catching the exit code due
   to issue 1): `exited` and `stopped` were conflated.  The waiting
   process hence caught the exit code after the container transitioned
   to `stopped` but before it `exited` and got removed.

3) With 1) and 2), Podman is now waiting for a container to properly
   transition to the `exited` state.  Some tests did not pass after 1)
   and 2) which revealed the third bug: `conmon` was executed with its
   working directory pointing to the OCI runtime bundle of the
   container.  The changed working directory broke resolving relative
   paths in the "cleanup" process.  The "cleanup" process error'ed
   before actually cleaning up the container and waiting "main" process
   ran indefinitely - or until hitting a timeout.  Fix the issue by
   executing `conmon` with the same working directory as Podman.

Note that fixing 3) *may* address a number of issues we have seen in the
past where for *some* reason cleanup processes did not fire.

[1] https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27119#note_970712864

Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>

[MH: Minor reword of commit message]

Signed-off-by: Matthew Heon <mheon@redhat.com>
2022-06-23 09:11:57 -04:00
Erik Sjölund
aa4279ae15 Fix spelling "setup" -> "set up" and similar
* Replace "setup", "lookup", "cleanup", "backup" with
  "set up", "look up", "clean up", "back up"
  when used as verbs. Replace also variations of those.

* Improve language in a few places.

Signed-off-by: Erik Sjölund <erik.sjolund@gmail.com>
2022-06-22 18:39:21 +02:00
openshift-ci[bot]
588d8ec371
Merge pull request #14662 from Luap99/api-json
API: containers/json always set application/json content type
2022-06-21 16:26:08 +00:00
Giuseppe Scrivano
1f539a2641
api: show the memory limit specified for the container
use the memory limit specified for the container instead of reading it
from the cgroup.  It is not reliable to read it from the cgroup since
the container could have been moved to a different cgroup and in
general the OCI runtime might create a sub-cgroup (like crun does).

Closes: https://github.com/containers/podman/issues/14676

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2022-06-21 12:06:33 +02:00
Paul Holzinger
bb5bd09ead
API: containers/json always set application/json content type
When we return no containers we just return `[]` but we still have to keep
the content type header `application/json` so external tools can correctly
parse the output.

Fixes #14647

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2022-06-20 14:07:56 +02:00
openshift-ci[bot]
e084f0ee1e
Merge pull request #14585 from Luap99/nolint
golangci-lint: enable nolintlint
2022-06-14 18:58:53 +00:00
openshift-ci[bot]
cffed099b8
Merge pull request #14561 from rhatdan/VENDOR
Update vendor of containers/buildah
2022-06-14 14:55:21 +00:00
Paul Holzinger
41528739ce
golangci-lint: enable nolintlint
The nolintlint linter does not deny the use of `//nolint`
Instead it allows us to enforce a common nolint style:
- force that a linter name must be specified
- do not add a space between `//` and `nolint`
- make sure nolint is only used when there is actually a problem

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2022-06-14 16:29:42 +02:00
openshift-ci[bot]
78ecdad5f8
Merge pull request #14580 from jakecorrenti/stats-on-non-running-container
Non-running containers now report statistics via the `podman stats`
2022-06-14 13:12:17 +00:00