diff options
-rwxr-xr-x | API.md | 9 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | RELEASE_NOTES.md | 56 | ||||
-rw-r--r-- | changelog.txt | 193 | ||||
-rw-r--r-- | cmd/podman/images.go | 81 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 5 | ||||
-rw-r--r-- | contrib/spec/podman.spec.in | 2 | ||||
-rw-r--r-- | docs/source/markdown/podman-pod-top.1.md | 48 | ||||
-rw-r--r-- | docs/source/markdown/podman-top.1.md | 4 | ||||
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | go.sum | 2 | ||||
-rw-r--r-- | libpod/image/filters.go (renamed from cmd/podman/imagefilters/filters.go) | 83 | ||||
-rw-r--r-- | libpod/image/image.go | 13 | ||||
-rw-r--r-- | pkg/adapter/runtime.go | 15 | ||||
-rw-r--r-- | pkg/adapter/runtime_remote.go | 22 | ||||
-rw-r--r-- | pkg/varlinkapi/images.go | 34 | ||||
-rw-r--r-- | vendor/github.com/containers/psgo/README.md | 2 | ||||
-rw-r--r-- | vendor/github.com/containers/psgo/internal/process/process.go | 23 | ||||
-rw-r--r-- | vendor/github.com/containers/psgo/psgo.go | 14 | ||||
-rw-r--r-- | vendor/modules.txt | 2 | ||||
-rw-r--r-- | version/version.go | 2 |
21 files changed, 461 insertions, 153 deletions
@@ -123,6 +123,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func ListImages() Image](#ListImages) +[func ListImagesWithFilters(filters: []string) Image](#ListImagesWithFilters) + [func ListPods() ListPodData](#ListPods) [func LoadImage(name: string, inputFile: string, quiet: bool, deleteFile: bool) MoreResponse](#LoadImage) @@ -892,6 +894,13 @@ See also [GetContainer](#GetContainer). method ListImages() [Image](#Image)</div> ListImages returns information about the images that are currently in storage. See also [InspectImage](#InspectImage). +### <a name="ListImagesWithFilters"></a>func ListImagesWithFilters +<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> + +method ListImagesWithFilters(filters: [[]string](#[]string)) [Image](#Image)</div> +ListImagesWithFilters returns information about the images that are currently in storage +after one or more filters has been applied. +See also [InspectImage](#InspectImage). ### <a name="ListPods"></a>func ListPods <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> @@ -3,7 +3,7 @@ export GOPROXY=https://proxy.golang.org GO ?= go DESTDIR ?= -EPOCH_TEST_COMMIT ?= ac73fd3fe5dcbf2647d589f9c9f37fe9531ed663 +EPOCH_TEST_COMMIT ?= 11541aec80c0fc588f675decd0ce759a4e353684 HEAD ?= HEAD CHANGELOG_BASE ?= HEAD~ CHANGELOG_TARGET ?= HEAD diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c16be818a..c8dac9ee0 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,61 @@ # Release Notes +## 1.7.0 +### Features +- Added support for setting a static MAC address for containers +- Added support for creating `macvlan` networks with `podman network create`, allowing Podman containers to be attached directly to networks the host is connected to +- The `podman image prune` and `podman container prune` commands now support the `--filter` flag to filter what will be pruned, and now prompts for confirmation when run without `--force` ([#4410](https://github.com/containers/libpod/issues/4410) and [#4411](https://github.com/containers/libpod/issues/4411)) +- Podman now creates CGroup namespaces by default on systems using CGroups v2 ([#4363](https://github.com/containers/libpod/issues/4363)) +- Added the `podman system reset` command to remove all Podman files and perform a factory reset of the Podman installation +- Added the `--history` flag to `podman images` to display previous names used by images ([#4566](https://github.com/containers/libpod/issues/4566)) +- Added the `--ignore` flag to `podman rm` and `podman stop` to not error when requested containers no longer exist +- Added the `--cidfile` flag to `podman rm` and `podman stop` to read the IDs of containers to be removed or stopped from a file +- The `podman play kube` command now honors Seccomp annotations ([#3111](https://github.com/containers/libpod/issues/3111)) +- The `podman play kube` command now honors `RunAsUser`, `RunAsGroup`, and `selinuxOptions` +- The output format of the `podman version` command has been changed to better match `docker version` when using the `--format` flag +- Rootless Podman will no longer initialize containers/storage twice, removing a potential deadlock preventing Podman commands from running while an image was being pulled ([#4591](https://github.com/containers/libpod/issues/4591)) +- Added `tmpcopyup` and `notmpcopyup` options to the `--tmpfs` and `--mount type=tmpfs` flags to `podman create` and `podman run` to control whether the content of directories are copied into tmpfs filesystems mounted over them +- Added support for disabling detaching from containers by setting empty detach keys via `--detach-keys=""` +- The `podman build` command now supports the `--pull` and `--pull-never` flags to control when images are pulled during a build + +### Bugfixes +- Fixed a bug where Podman would use an incorrect runtime directory as root, causing state to be deleted after root logged out and making Podman in systemd services not function properly +- Fixed a bug where the `--change` flag to `podman import` and `podman commit` was not being parsed properly in many cases +- Fixed a bug where detach keys specified in `libpod.conf` were not used by the `podman attach` and `podman exec` commands, which always used the global default `ctrl-p,ctrl-q` key combination ([#4556](https://github.com/containers/libpod/issues/4556)) +- Fixed a bug where rootless Podman was not able to run `podman pod stats` even on CGroups v2 enabled systems ([#4634](https://github.com/containers/libpod/issues/4634)) +- Fixed a bug where rootless Podman would fail on kernels without the `renameat2` syscall ([#4570](https://github.com/containers/libpod/issues/4570)) +- Fixed a bug where containers with chained network namespace dependencies (IE, container A using `--net container=B` and container B using `--net container=C`) would not properly mount `/etc/hosts` and `/etc/resolv.conf` into the container ([#4626](https://github.com/containers/libpod/issues/4626)) +- Fixed a bug where `podman run` with the `--rm` flag and without `-d` could, when run in the background, throw a 'container does not exist' error when attempting to remove the container after it exited +- Fixed a bug where named volume locks were not properly reacquired after a reboot, potentially leading to deadlocks when trying to start containers using the volume ([#4605](https://github.com/containers/libpod/issues/4605) and [#4621](https://github.com/containers/libpod/issues/4621)) +- Fixed a bug where Podman could not completely remove containers if sent SIGKILL during removal, leaving the container name unusable without the `podman rm --storage` command to complete removal ([#3906](https://github.com/containers/libpod/issues/3906)) +- Fixed a bug where checkpointing containers started with `--rm` was allowed when `--export` was not specified (the container, and checkpoint, would be removed after checkpointing was complete by `--rm`) ([#3774](https://github.com/containers/libpod/issues/3774)) +- Fixed a bug where the `podman pod prune` command would fail if containers were present in the pods and the `--force` flag was not passed ([#4346](https://github.com/containers/libpod/issues/4346)) +- Fixed a bug where containers could not set a static IP or static MAC address if they joined a non-default CNI network ([#4500](https://github.com/containers/libpod/issues/4500)) +- Fixed a bug where `podman system renumber` would always throw an error if a container was mounted when it was run +- Fixed a bug where `podman container restore` would fail with containers using a user namespace +- Fixed a bug where rootless Podman would attempt to use the journald events backend even on systems without systemd installed +- Fixed a bug where `podman history` would sometimes not properly identify the IDs of layers in an image ([#3359](https://github.com/containers/libpod/issues/3359)) +- Fixed a bug where containers could not be restarted when Conmon v2.0.3 or later was used +- Fixed a bug where Podman did not check image OS and Architecture against the host when starting a container +- Fixed a bug where containers in pods did not function properly with the Kata OCI runtime ([#4353](https://github.com/containers/libpod/issues/4353)) +- Fixed a bug where `podman info --format '{{ json . }}' would not produce JSON output ([#4391](https://github.com/containers/libpod/issues/4391)) +- Fixed a bug where Podman would not verify if files passed to `--authfile` existed ([#4328](https://github.com/containers/libpod/issues/4328)) +- Fixed a bug where `podman images --digest` would not always print digests when they were available +- Fixed a bug where rootless `podman run` could hang due to a race with reading and writing events +- Fixed a bug where rootless Podman would print warning-level logs despite not be instructed to do so ([#4456](https://github.com/containers/libpod/issues/4456)) +- Fixed a bug where `podman pull` would attempt to fetch from remote registries when pulling an unqualified image using the `docker-daemon` transport ([#4434](https://github.com/containers/libpod/issues/4434)) +- Fixed a bug where `podman cp` would not work if STDIN was a pipe +- Fixed a bug where `podman exec` could stop accepting input if anything was typed between the command being run and the exec session starting ([#4397](https://github.com/containers/libpod/issues/4397)) +- Fixed a bug where `podman logs --tail 0` would print all lines of a container's logs, instead of no lines ([#4396](https://github.com/containers/libpod/issues/4396)) +- Fixed a bug where the timeout for `slirp4netns` was incorrectly set, resulting in an extremely long timeout ([#4344](https://github.com/containers/libpod/issues/4344)) +- Fixed a bug where the `podman stats` command would print CPU utilizations figures incorrectly ([#4409](https://github.com/containers/libpod/issues/4409)) + +### Misc +- The fixes to runtime directory path as root can cause strange behavior if an upgrade is performed while containers are running +- Updated vendored Buildah to v1.11.6 +- Updated vendored containers/storage library to v1.15.3 +- Kata Containers runtimes (`kata-runtime`, `kata-qemu`, and `kata-fc`) are now present in the default libpod.conf, but will not be available unless Kata containers is installed on the system + ## 1.6.3 ### Features - Handling of the `libpod.conf` configuration file has seen major changes. Most significantly, rootless users will no longer automatically receive a complete configuration file when they first use Podman, and will instead only receive differences from the global configuration. diff --git a/changelog.txt b/changelog.txt index 615e2a135..a19c23934 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,196 @@ +- Changelog for v1.7.0-rc1 (2019-12-11) + * Update release notes for 1.7.0 + * docs: update podman-{pod-,}top man pages + * build(deps): bump github.com/containers/psgo from 1.3.2 to 1.4.0 + * Update containers/storage to v1.15.3 + * move image filters under libpod/images + * Re-add Fedora 31 migration code. + * macvlan networks + * Return empty runtime directory if we're not rootless + * build(deps): bump github.com/containers/storage from 1.15.0 to 1.15.2 + * Use terminal detach keys sequence specified in the config file + * Add ONBUILD support to --change + * Move Commit() to new parsing for --change + * test for #3920 (improper caching of tarballs in build) + * Enable multi-platform rpm building + * Completely rework --change parsing + * Avoid git warnings by using detach on checkout + * Improve hack/get_release_info.sh + * Bump Buildah to v1.11.6 + * rootless: enable stats test on cgroup v2 + * Improve dnf tests inside build_rpm.sh + * libpod: fix stats for rootless pods + * rootless: add fallback for renameat2 at runtime + * Attempt to install go-md2man only if missing + * Quick grammar touchup in rootless.md + * Allow chained network namespace containers + * Ensure volumes reacquire locks on state refresh + * Ignore ErrCtrRemoved when removing a container + * Add comment on rootless containers creating device nodes + * Updates on making doc building and debug optional + * troubleshooting: warn about secure boot + * libpod: fix case for executable file not found errors + * build: improved main makefile + * build: improved prepare.sh + * Fix podman-remote version to print client and server + * man page updated with examples of filter option + * install.md: added slirp4netns dependency to ubuntu + * Add podman system reset command + * fix commands.go to get links from correct directory + * Do not initialize store on rootless podman + * filter added to container prune command + * Disable checkpointing of containers started with --rm + * Make doc building in spec optional + * Donot install btrfs in RHEL/CentOS-8 + * oci: print only matching part for the errors + * command output fixed as per docker equivalent + * Detect Python executable in Makefile + * Improved build_rpm.sh + * Add support for image name history + * Remove containers when pruning a stopped pod. + * Allow --ip and --mac to be set when joining a CNI net + * Document other bind options on --volumes flag + * podman {pod,} rm/stop: add --ignore flag + * Discard errors from Shutdown in `system renumber` + * e2e/prune: run two top containers + * build(deps): bump github.com/containers/storage from 1.13.5 to 1.14.0 + * build(deps): bump gopkg.in/yaml.v2 from 2.2.5 to 2.2.7 + * build(deps): bump github.com/pkg/profile from 1.3.0 to 1.4.0 + * document updated for filter and until options + * filter added to image pruge command. + * config: use EventsLogger=file without systemd + * Error on netns not exist only when ctr is running + * Add ContainerStateRemoving + * play kube: handle seccomp labels + * podman rm/stop --cidfile + * container-restore: Fix restore with user namespace + * Add new test suite for build + * Also delete winsz fifo + * use pause image for check all + * timestamp related functions added + * Bump to Buildah v1.11.5 + * container create: os/arch check + * history: rewrite mappings + * codespell: spelling corrections + * Cirrus: Use branch-specific container tags + * warning added before image prune command + * create a separate install target for seccomp + * Add annotations in play kube + * Add pod annotations to container + * Add missing information to podman.1 man page + * Add support for make vendor-in-container + * Split up create config handling of namespaces and security + * test: add tests for --mac-address + * mount: add new options nocopyup|copyup for tmpfs + * Bump github.com/uber/jaeger-client-go + * libpod/config: default: use `crun` on Cgroups v2 + * podman images --digest: always list a digest + * events: make sure the write channel is always closed + * Add support for RunAsUser and RunAsGroup + * cni: enable tuning plugin + * podman: add support for specifying MAC + * vendor: updated ocicni for MAC address + * Makefile: add vendor-in-container + * rootless: provide workaround for missing renameat2 + * rootless: use SYS_renameat2 instead of __NR_renameat2 + * Add Kata Containers runtimes to libpod.conf + * help message: don't parse the config for cgroup-manager default + * fix bug check nonexist authfile + * Allow users to disable detach keys + * namespaces: by default create cgroupns on cgroups v2 + * Update installation - Ubuntu. [skip ci] + * pulling unqualified reference: make sure it's a docker reference + * Bump gopkg.in/yaml.v2 from 2.2.4 to 2.2.5 + * Set SELinux labels based on the security context in the kube.yaml + * Add links to readthedocs on docs/readme + * Bump development version to 1.6.4-dev + * Bump version in README to v1.6.3 + * Add release notes for v1.6.3 + * slirp4netns: fix timeout + * docs: Update "podman container rm -v" description + * logo: correct light source reflection + * stats: fix calculation for the CPU time + * [docs] Ensure we include section 5 documentation + * [Makefile] Fix docker documentation install and generation + * Fixed the JSON go template format for the 'info' action + * runtime: Fix typo + * Update link to Commands documentation + * cgroups: read correctly the CPU stats + * [CI:DOCS] make docs only prs + * Update rootless shortcomings with cgroup V2 information + * Bump github.com/onsi/gomega from 1.7.0 to 1.7.1 + * Validate contextdir on build + * Vendor in latest containers/buildah + * Bump github.com/onsi/ginkgo from 1.10.1 to 1.10.3 + * Refactor test to prevent panic + * logs: support --tail 0 + * Update document formatting and packaging code + * Restructure documentation dir + * add libpod/config + * Switch to bufio Reader for exec streams + * container start: fix regression when using name + * Fix selinux test for exec + * Cirrus: Disable F29 testing + * Wait for `mount` command to finish when mounting volume + * Cirrus: Fix upload_release_archive on branch or tag + * Fix cp from pipe + * libpod, rootless: create cgroup for conmon + * Bump github.com/json-iterator/go from 1.1.7 to 1.1.8 + * seccomp: use github.com/seccomp/containers-golang + * build: drop support for ostree + * stale action: add exempt-issue-label + * Processes execed into container should match container label + * Set default seccomp.json file for podman play kube + * images: distinguish between tags and digests + * API: report multiple digests for images + * pull/create: add --override-arch/--override-os flags + * image: don't get confused by lists + * Add e2e tests for manifest list support + * bump containers/image to v5.0.0, buildah to v1.11.4 + * goland autocorrections + * Makefile: fix embedding gitCommit + * Cirrus: Fix minor python deprecation warning + * Cirrus: Only upload tagged releases + * Fix spelling mistakes + * libpod: if slirp4netns fails, return its output + * update conmon to v2.0.2 in in_podman image + * bump cirrus images + * require conmon v2.0.1 + * require conmon v2.0.0 + * GitHub stale action + * enable dnsplugin for network create + * Add ensureState helper for checking container state + * Cleanup man pages + * Log warn instead of error for removing nonexistant container + * systemd: mask /sys/fs/cgroup/systemd/release_agent + * Add multiple networks explanation to docs + * rootless: raise an error with --network= + * Initial dump of man pages and first menus + * Return a better error for volume name conflicts + * Add documentation on options to volume create manpage + * Image volumes should not be mounted noexec + * stats: list all running containers unless specified otherwise + * rootless: detect no system session with --cgroup-manager=systemd + * add pip requirements file for rtd + * Initial checking for readthedocs + * Fix sig-proxy=false test and use image cache + * Add parsing for UID, GID in volume "o" option + * exec: remove unused var + * Rewrite backend for remote 'volume inspect' + * rootless: write storage overrides to the conf file + * Markdown Formatting Fixes + * Show volume options in 'volume inspect' + * System tests: make sure exec pid hash w/o leaking + * Bump gitvalidation epoch + * Bump to v1.6.3-dev + * check existing bridge names when creating networks + * Add support for anonymous volumes to `podman run -v` + * troubleshooting.md: document lingering mode + * rootless: do not enable lingering mode + * Add ability to redirect bash for run -i + * play kube: Container->Ctr + * play kube: refactor test suite + - Changelog for v1.6.2 (2019-10-17) * Finalize release notes for v1.6.2 * rootless: drop dependency on docker diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 6b16272f4..e42546a55 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -5,14 +5,12 @@ import ( "fmt" "reflect" "sort" - "strconv" "strings" "time" "unicode" "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/imagefilters" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/adapter" "github.com/docker/go-units" @@ -138,10 +136,10 @@ func init() { func imagesCmd(c *cliconfig.ImagesValues) error { var ( - filterFuncs []imagefilters.ResultFilter - image string + image string ) + ctx := getContext() runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand) if err != nil { return errors.Wrapf(err, "Could not get runtime") @@ -156,15 +154,9 @@ func imagesCmd(c *cliconfig.ImagesValues) error { if len(c.Filter) > 0 && image != "" { return errors.New("can not specify an image and a filter") } - ctx := getContext() - - if len(c.Filter) > 0 { - filterFuncs, err = CreateFilterFuncs(ctx, runtime, c.Filter, nil) - } else { - filterFuncs, err = CreateFilterFuncs(ctx, runtime, []string{fmt.Sprintf("reference=%s", image)}, nil) - } - if err != nil { - return err + filters := c.Filter + if len(filters) < 1 { + filters = append(filters, fmt.Sprintf("reference=%s", image)) } opts := imagesOptions{ @@ -179,26 +171,17 @@ func imagesCmd(c *cliconfig.ImagesValues) error { } opts.outputformat = opts.setOutputFormat() - images, err := runtime.GetImages() + filteredImages, err := runtime.GetFilteredImages(filters, false) if err != nil { return errors.Wrapf(err, "unable to get images") } - for _, image := range images { + for _, image := range filteredImages { if image.IsReadOnly() { opts.outputformat += "{{.ReadOnly}}\t" break } } - - var filteredImages []*adapter.ContainerImage - //filter the images - if len(c.Filter) > 0 || len(c.InputArgs) == 1 { - filteredImages = imagefilters.FilterImages(images, filterFuncs) - } else { - filteredImages = images - } - return generateImagesOutput(ctx, filteredImages, opts) } @@ -392,53 +375,3 @@ func GenImageOutputMap() map[string]string { } return values } - -// CreateFilterFuncs returns an array of filter functions based on the user inputs -// and is later used to filter images for output -func CreateFilterFuncs(ctx context.Context, r *adapter.LocalRuntime, filters []string, img *adapter.ContainerImage) ([]imagefilters.ResultFilter, error) { - var filterFuncs []imagefilters.ResultFilter - for _, filter := range filters { - splitFilter := strings.Split(filter, "=") - if len(splitFilter) < 2 { - return nil, errors.Errorf("invalid filter syntax %s", filter) - } - switch splitFilter[0] { - case "before": - before, err := r.NewImageFromLocal(splitFilter[1]) - if err != nil { - return nil, errors.Wrapf(err, "unable to find image %s in local stores", splitFilter[1]) - } - filterFuncs = append(filterFuncs, imagefilters.CreatedBeforeFilter(before.Created())) - case "after": - after, err := r.NewImageFromLocal(splitFilter[1]) - if err != nil { - return nil, errors.Wrapf(err, "unable to find image %s in local stores", splitFilter[1]) - } - filterFuncs = append(filterFuncs, imagefilters.CreatedAfterFilter(after.Created())) - case "readonly": - readonly, err := strconv.ParseBool(splitFilter[1]) - if err != nil { - return nil, errors.Wrapf(err, "invalid filter readonly=%s", splitFilter[1]) - } - filterFuncs = append(filterFuncs, imagefilters.ReadOnlyFilter(readonly)) - case "dangling": - danglingImages, err := strconv.ParseBool(splitFilter[1]) - if err != nil { - return nil, errors.Wrapf(err, "invalid filter dangling=%s", splitFilter[1]) - } - filterFuncs = append(filterFuncs, imagefilters.DanglingFilter(danglingImages)) - case "label": - labelFilter := strings.Join(splitFilter[1:], "=") - filterFuncs = append(filterFuncs, imagefilters.LabelFilter(ctx, labelFilter)) - case "reference": - referenceFilter := strings.Join(splitFilter[1:], "=") - filterFuncs = append(filterFuncs, imagefilters.ReferenceFilter(ctx, referenceFilter)) - default: - return nil, errors.Errorf("invalid filter %s ", splitFilter[0]) - } - } - if img != nil { - filterFuncs = append(filterFuncs, imagefilters.OutputImageFilter(img)) - } - return filterFuncs, nil -} diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index a3fd27ed6..2251050c3 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -784,6 +784,11 @@ method DeleteStoppedContainers() -> (containers: []string) # See also [InspectImage](#InspectImage). method ListImages() -> (images: []Image) +# ListImagesWithFilters returns information about the images that are currently in storage +# after one or more filters has been applied. +# See also [InspectImage](#InspectImage). +method ListImagesWithFilters(filters: []string) -> (images: []Image) + # GetImage returns information about a single image in storage. # If the image caGetImage returns be found, [ImageNotFound](#ImageNotFound) will be returned. method GetImage(id: string) -> (image: Image) diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in index 4a3704811..2b9621dbc 100644 --- a/contrib/spec/podman.spec.in +++ b/contrib/spec/podman.spec.in @@ -40,7 +40,7 @@ %global shortcommit_conmon %(c=%{commit_conmon}; echo ${c:0:7}) Name: podman -Version: 1.6.4 +Version: 1.7.0 Release: #COMMITDATE#.git%{shortcommit0}%{?dist} Summary: Manage Pods, Containers and Container Images License: ASL 2.0 diff --git a/docs/source/markdown/podman-pod-top.1.md b/docs/source/markdown/podman-pod-top.1.md index 48f10055a..6a1fa8c42 100644 --- a/docs/source/markdown/podman-pod-top.1.md +++ b/docs/source/markdown/podman-pod-top.1.md @@ -23,53 +23,11 @@ The latest option is not supported on the remote client. ## FORMAT DESCRIPTORS -The following descriptors are supported in addition to the AIX format descriptors mentioned in ps (1): - -**args**, **capbnd**, **capeff**, **capinh**, **capprm**, **comm**, **etime**, **group**, **hgroup**, **hpid**, **huser**, **label**, **nice**, **pcpu**, **pgid**, **pid**, **ppid**, **rgroup**, **ruser**, **seccomp**, **state**, **time**, **tty**, **user**, **vsz** - -**capbnd** - - Set of bounding capabilities. See capabilities (7) for more information. - -**capeff** - - Set of effective capabilities. See capabilities (7) for more information. - -**capinh** - - Set of inheritable capabilities. See capabilities (7) for more information. - -**capprm** - - Set of permitted capabilities. See capabilities (7) for more information. - -**hgroup** - - The corresponding effective group of a container process on the host. - -**hpid** - - The corresponding host PID of a container process. - -**huser** - - The corresponding effective user of a container process on the host. - -**label** - - Current security attributes of the process. - -**seccomp** - - Seccomp mode of the process (i.e., disabled, strict or filter). See seccomp (2) for more information. - -**state** - - Process state codes (e.g, **R** for *running*, **S** for *sleeping*). See proc(5) for more information. +Please refer to podman-top(1) for a full list of available descriptors. ## EXAMPLES -By default, `podman-top` prints data similar to `ps -ef`: +By default, `podman-pod-top` prints data similar to `ps -ef`: ``` $ podman pod top b031293491cc @@ -88,7 +46,7 @@ PID SECCOMP COMMAND %CPU ``` ## SEE ALSO -podman-pod(1), ps(1), seccomp(2), proc(5), capabilities(7) +podman-pod(1), podman-top(1), ps(1), seccomp(2), proc(5), capabilities(7) ## HISTORY August 2018, Originally compiled by Peter Hunt <pehunt@redhat.com> diff --git a/docs/source/markdown/podman-top.1.md b/docs/source/markdown/podman-top.1.md index 1410aa651..6a04ab91a 100644 --- a/docs/source/markdown/podman-top.1.md +++ b/docs/source/markdown/podman-top.1.md @@ -70,6 +70,10 @@ The following descriptors are supported in addition to the AIX format descriptor Process state codes (e.g, **R** for *running*, **S** for *sleeping*). See proc(5) for more information. +**stime** + + Process start time (e.g, "2019-12-09 10:50:36 +0100 CET). + ## EXAMPLES By default, `podman-top` prints data similar to `ps -ef`: @@ -13,7 +13,7 @@ require ( github.com/containers/buildah v1.11.6 github.com/containers/conmon v2.0.2+incompatible // indirect github.com/containers/image/v5 v5.0.0 - github.com/containers/psgo v1.3.2 + github.com/containers/psgo v1.4.0 github.com/containers/storage v1.15.3 github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect @@ -88,6 +88,8 @@ github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDpl github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/psgo v1.3.2 h1:jYfppPih3S/j2Yi5O14AXjd8GfCx1ph9L3YsoK3adko= github.com/containers/psgo v1.3.2/go.mod h1:ENXXLQ5E1At4K0EUsGogXBJi/C28gwqkONWeLPI9fJ8= +github.com/containers/psgo v1.4.0 h1:D8B4fZCCZhYgc8hDyMPCiShOinmOB1TP1qe46sSC19k= +github.com/containers/psgo v1.4.0/go.mod h1:ENXXLQ5E1At4K0EUsGogXBJi/C28gwqkONWeLPI9fJ8= github.com/containers/storage v1.13.4 h1:j0bBaJDKbUHtAW1MXPFnwXJtqcH+foWeuXK1YaBV5GA= github.com/containers/storage v1.13.4/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA= github.com/containers/storage v1.13.5 h1:/SUzGeOP2HDijpF7Yur21Ch6WTZC1BNeZF917CWcp5c= diff --git a/cmd/podman/imagefilters/filters.go b/libpod/image/filters.go index 0b08314ce..d545f1bfc 100644 --- a/cmd/podman/imagefilters/filters.go +++ b/libpod/image/filters.go @@ -1,29 +1,30 @@ -package imagefilters +package image import ( "context" "fmt" + "github.com/pkg/errors" "path/filepath" + "strconv" "strings" "time" - "github.com/containers/libpod/pkg/adapter" "github.com/containers/libpod/pkg/inspect" "github.com/sirupsen/logrus" ) // ResultFilter is a mock function for image filtering -type ResultFilter func(*adapter.ContainerImage) bool +type ResultFilter func(*Image) bool // Filter is a function to determine whether an image is included in // command output. Images to be outputted are tested using the function. A true // return will include the image, a false return will exclude it. -type Filter func(*adapter.ContainerImage, *inspect.ImageData) bool +type Filter func(*Image, *inspect.ImageData) bool // CreatedBeforeFilter allows you to filter on images created before // the given time.Time func CreatedBeforeFilter(createTime time.Time) ResultFilter { - return func(i *adapter.ContainerImage) bool { + return func(i *Image) bool { return i.Created().Before(createTime) } } @@ -31,14 +32,14 @@ func CreatedBeforeFilter(createTime time.Time) ResultFilter { // CreatedAfterFilter allows you to filter on images created after // the given time.Time func CreatedAfterFilter(createTime time.Time) ResultFilter { - return func(i *adapter.ContainerImage) bool { + return func(i *Image) bool { return i.Created().After(createTime) } } // DanglingFilter allows you to filter images for dangling images func DanglingFilter(danglingImages bool) ResultFilter { - return func(i *adapter.ContainerImage) bool { + return func(i *Image) bool { if danglingImages { return i.Dangling() } @@ -48,7 +49,7 @@ func DanglingFilter(danglingImages bool) ResultFilter { // ReadOnlyFilter allows you to filter images based on read/only and read/write func ReadOnlyFilter(readOnly bool) ResultFilter { - return func(i *adapter.ContainerImage) bool { + return func(i *Image) bool { if readOnly { return i.IsReadOnly() } @@ -59,7 +60,7 @@ func ReadOnlyFilter(readOnly bool) ResultFilter { // LabelFilter allows you to filter by images labels key and/or value func LabelFilter(ctx context.Context, labelfilter string) ResultFilter { // We need to handle both label=key and label=key=value - return func(i *adapter.ContainerImage) bool { + return func(i *Image) bool { var value string splitFilter := strings.Split(labelfilter, "=") key := splitFilter[0] @@ -83,7 +84,10 @@ func LabelFilter(ctx context.Context, labelfilter string) ResultFilter { func ReferenceFilter(ctx context.Context, referenceFilter string) ResultFilter { filter := fmt.Sprintf("*%s*", referenceFilter) filter = strings.Replace(filter, "/", "|", -1) - return func(i *adapter.ContainerImage) bool { + return func(i *Image) bool { + if len(referenceFilter) < 1 { + return true + } for _, name := range i.Names() { newName := strings.Replace(name, "/", "|", -1) match, err := filepath.Match(filter, newName) @@ -99,15 +103,15 @@ func ReferenceFilter(ctx context.Context, referenceFilter string) ResultFilter { } // OutputImageFilter allows you to filter by an a specific image name -func OutputImageFilter(userImage *adapter.ContainerImage) ResultFilter { - return func(i *adapter.ContainerImage) bool { +func OutputImageFilter(userImage *Image) ResultFilter { + return func(i *Image) bool { return userImage.ID() == i.ID() } } // FilterImages filters images using a set of predefined filter funcs -func FilterImages(images []*adapter.ContainerImage, filters []ResultFilter) []*adapter.ContainerImage { - var filteredImages []*adapter.ContainerImage +func FilterImages(images []*Image, filters []ResultFilter) []*Image { + var filteredImages []*Image for _, image := range images { include := true for _, filter := range filters { @@ -119,3 +123,54 @@ func FilterImages(images []*adapter.ContainerImage, filters []ResultFilter) []*a } return filteredImages } + +// createFilterFuncs returns an array of filter functions based on the user inputs +// and is later used to filter images for output +func (ir *Runtime) createFilterFuncs(filters []string, img *Image) ([]ResultFilter, error) { + var filterFuncs []ResultFilter + ctx := context.Background() + for _, filter := range filters { + splitFilter := strings.Split(filter, "=") + if len(splitFilter) < 2 { + return nil, errors.Errorf("invalid filter syntax %s", filter) + } + switch splitFilter[0] { + case "before": + before, err := ir.NewFromLocal(splitFilter[1]) + if err != nil { + return nil, errors.Wrapf(err, "unable to find image %s in local stores", splitFilter[1]) + } + filterFuncs = append(filterFuncs, CreatedBeforeFilter(before.Created())) + case "after": + after, err := ir.NewFromLocal(splitFilter[1]) + if err != nil { + return nil, errors.Wrapf(err, "unable to find image %s in local stores", splitFilter[1]) + } + filterFuncs = append(filterFuncs, CreatedAfterFilter(after.Created())) + case "readonly": + readonly, err := strconv.ParseBool(splitFilter[1]) + if err != nil { + return nil, errors.Wrapf(err, "invalid filter readonly=%s", splitFilter[1]) + } + filterFuncs = append(filterFuncs, ReadOnlyFilter(readonly)) + case "dangling": + danglingImages, err := strconv.ParseBool(splitFilter[1]) + if err != nil { + return nil, errors.Wrapf(err, "invalid filter dangling=%s", splitFilter[1]) + } + filterFuncs = append(filterFuncs, DanglingFilter(danglingImages)) + case "label": + labelFilter := strings.Join(splitFilter[1:], "=") + filterFuncs = append(filterFuncs, LabelFilter(ctx, labelFilter)) + case "reference": + referenceFilter := strings.Join(splitFilter[1:], "=") + filterFuncs = append(filterFuncs, ReferenceFilter(ctx, referenceFilter)) + default: + return nil, errors.Errorf("invalid filter %s ", splitFilter[0]) + } + } + if img != nil { + filterFuncs = append(filterFuncs, OutputImageFilter(img)) + } + return filterFuncs, nil +} diff --git a/libpod/image/image.go b/libpod/image/image.go index 129ccd376..c8583a1c5 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -216,6 +216,19 @@ func (ir *Runtime) Shutdown(force bool) error { return err } +// GetImagesWithFilters gets images with a series of filters applied +func (ir *Runtime) GetImagesWithFilters(filters []string) ([]*Image, error) { + filterFuncs, err := ir.createFilterFuncs(filters, nil) + if err != nil { + return nil, err + } + images, err := ir.GetImages() + if err != nil { + return nil, err + } + return FilterImages(images, filterFuncs), nil +} + func (i *Image) reloadImage() error { newImage, err := i.imageruntime.getImage(i.ID()) if err != nil { diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go index 069283bde..ac843b655 100644 --- a/pkg/adapter/runtime.go +++ b/pkg/adapter/runtime.go @@ -84,6 +84,15 @@ func getRuntime(runtime *libpod.Runtime) (*LocalRuntime, error) { }, nil } +// GetFilterImages returns a slice of images in containerimages that are "filtered" +func (r *LocalRuntime) GetFilteredImages(filters []string, rwOnly bool) ([]*ContainerImage, error) { + images, err := r.ImageRuntime().GetImagesWithFilters(filters) + if err != nil { + return nil, err + } + return r.ImagestoContainerImages(images, rwOnly) +} + // GetImages returns a slice of images in containerimages func (r *LocalRuntime) GetImages() ([]*ContainerImage, error) { return r.getImages(false) @@ -95,11 +104,15 @@ func (r *LocalRuntime) GetRWImages() ([]*ContainerImage, error) { } func (r *LocalRuntime) getImages(rwOnly bool) ([]*ContainerImage, error) { - var containerImages []*ContainerImage images, err := r.Runtime.ImageRuntime().GetImages() if err != nil { return nil, err } + return r.ImagestoContainerImages(images, rwOnly) +} + +func (r *LocalRuntime) ImagestoContainerImages(images []*image.Image, rwOnly bool) ([]*ContainerImage, error) { + var containerImages []*ContainerImage for _, i := range images { if rwOnly && i.IsReadOnly() { continue diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go index f9232897c..87b4999ce 100644 --- a/pkg/adapter/runtime_remote.go +++ b/pkg/adapter/runtime_remote.go @@ -200,6 +200,28 @@ func (r *LocalRuntime) GetRWImages() ([]*ContainerImage, error) { return r.getImages(true) } +func (r *LocalRuntime) GetFilteredImages(filters []string, rwOnly bool) ([]*ContainerImage, error) { + var newImages []*ContainerImage + images, err := iopodman.ListImagesWithFilters().Call(r.Conn, filters) + if err != nil { + return nil, err + } + for _, i := range images { + if rwOnly && i.ReadOnly { + continue + } + name := i.Id + if len(i.RepoTags) > 1 { + name = i.RepoTags[0] + } + newImage, err := imageInListToContainerImage(i, name, r) + if err != nil { + return nil, err + } + newImages = append(newImages, newImage) + } + return newImages, nil +} func (r *LocalRuntime) getImages(rwOnly bool) ([]*ContainerImage, error) { var newImages []*ContainerImage images, err := iopodman.ListImages().Call(r.Conn) diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index 604a455a5..1d46c5b71 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -35,26 +35,34 @@ import ( "github.com/sirupsen/logrus" ) -// ListImages lists all the images in the store -// It requires no inputs. -func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error { - images, err := i.Runtime.ImageRuntime().GetImages() +// ListImagesWithFilters returns a list of images that have been filtered +func (i *LibpodAPI) ListImagesWithFilters(call iopodman.VarlinkCall, filters []string) error { + images, err := i.Runtime.ImageRuntime().GetImagesWithFilters(filters) if err != nil { return call.ReplyErrorOccurred(fmt.Sprintf("unable to get list of images %q", err)) } + imageList, err := imagesToImageList(images) + if err != nil { + return call.ReplyErrorOccurred(fmt.Sprintf("unable to parse response", err)) + } + return call.ReplyListImagesWithFilters(imageList) +} + +// imagesToImageList converts a slice of Images to an imagelist for varlink responses +func imagesToImageList(images []*image.Image) ([]iopodman.Image, error) { var imageList []iopodman.Image for _, image := range images { labels, _ := image.Labels(getContext()) containers, _ := image.Containers() repoDigests, err := image.RepoDigests() if err != nil { - return err + return nil, err } size, _ := image.Size(getContext()) isParent, err := image.IsParent(context.TODO()) if err != nil { - return call.ReplyErrorOccurred(err.Error()) + return nil, err } i := iopodman.Image{ @@ -74,6 +82,20 @@ func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error { } imageList = append(imageList, i) } + return imageList, nil +} + +// ListImages lists all the images in the store +// It requires no inputs. +func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error { + images, err := i.Runtime.ImageRuntime().GetImages() + if err != nil { + return call.ReplyErrorOccurred(fmt.Sprintf("unable to get list of images %q", err)) + } + imageList, err := imagesToImageList(images) + if err != nil { + return call.ReplyErrorOccurred(fmt.Sprintf("unable to parse response", err)) + } return call.ReplyListImages(imageList) } diff --git a/vendor/github.com/containers/psgo/README.md b/vendor/github.com/containers/psgo/README.md index 55cb73a71..fed42c683 100644 --- a/vendor/github.com/containers/psgo/README.md +++ b/vendor/github.com/containers/psgo/README.md @@ -85,6 +85,8 @@ The ps library is compatible with all AIX format descriptors of the ps command-l - Seccomp mode of the process (i.e., disabled, strict or filter). See seccomp(2) for more information. - **state** - Process state codes (e.g, **R** for *running*, **S** for *sleeping*). See proc(5) for more information. +- **stime** + - Process start time (e.g, "2019-12-09 10:50:36 +0100 CET). We can try out different format descriptors with the psgo binary: diff --git a/vendor/github.com/containers/psgo/internal/process/process.go b/vendor/github.com/containers/psgo/internal/process/process.go index 20e40163f..a936cc4ef 100644 --- a/vendor/github.com/containers/psgo/internal/process/process.go +++ b/vendor/github.com/containers/psgo/internal/process/process.go @@ -188,23 +188,30 @@ func (p *Process) SetHostData() error { // ElapsedTime returns the time.Duration since process p was created. func (p *Process) ElapsedTime() (time.Duration, error) { - sinceBoot, err := strconv.ParseInt(p.Stat.Starttime, 10, 64) + startTime, err := p.StartTime() if err != nil { return 0, err } + return (time.Now()).Sub(startTime), nil +} + +// StarTime returns the time.Time when process p was started. +func (p *Process) StartTime() (time.Time, error) { + sinceBoot, err := strconv.ParseInt(p.Stat.Starttime, 10, 64) + if err != nil { + return time.Time{}, err + } clockTicks, err := host.ClockTicks() if err != nil { - return 0, err + return time.Time{}, err } - - sinceBoot = sinceBoot / clockTicks - bootTime, err := host.BootTime() if err != nil { - return 0, err + return time.Time{}, err } - created := time.Unix(sinceBoot+bootTime, 0) - return (time.Now()).Sub(created), nil + + sinceBoot = sinceBoot / clockTicks + return time.Unix(sinceBoot+bootTime, 0), nil } // CPUTime returns the cumlative CPU time of process p as a time.Duration. diff --git a/vendor/github.com/containers/psgo/psgo.go b/vendor/github.com/containers/psgo/psgo.go index 4986c9c71..30b8b74ce 100644 --- a/vendor/github.com/containers/psgo/psgo.go +++ b/vendor/github.com/containers/psgo/psgo.go @@ -310,6 +310,11 @@ var ( header: "STATE", procFn: processState, }, + { + normal: "stime", + header: "STIME", + procFn: processStartTime, + }, } ) @@ -715,6 +720,15 @@ func processTIME(p *process.Process, ctx *psContext) (string, error) { return fmt.Sprintf("%v", cpu), nil } +// processStartTime returns the start time of process p. +func processStartTime(p *process.Process, ctx *psContext) (string, error) { + sTime, err := p.StartTime() + if err != nil { + return "", err + } + return fmt.Sprintf("%v", sTime), nil +} + // processTTY returns the controlling tty (terminal) of process p. func processTTY(p *process.Process, ctx *psContext) (string, error) { ttyNr, err := strconv.ParseUint(p.Stat.TtyNr, 10, 64) diff --git a/vendor/modules.txt b/vendor/modules.txt index acd45d26d..580b4e8cd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -117,7 +117,7 @@ github.com/containers/image/v5/types github.com/containers/image/v5/version # github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b github.com/containers/libtrust -# github.com/containers/psgo v1.3.2 +# github.com/containers/psgo v1.4.0 github.com/containers/psgo github.com/containers/psgo/internal/capabilities github.com/containers/psgo/internal/cgroups diff --git a/version/version.go b/version/version.go index 129a2cd4b..e75d1e713 100644 --- a/version/version.go +++ b/version/version.go @@ -4,7 +4,7 @@ package version // NOTE: remember to bump the version at the top // of the top-level README.md file when this is // bumped. -const Version = "1.6.4-dev" +const Version = "1.7.0-dev" // RemoteAPIVersion is the version for the remote // client API. It is used to determine compatibility |