summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2020-10-19 02:49:27 -0400
committerGitHub <noreply@github.com>2020-10-19 02:49:27 -0400
commit7ffcab0854342844a44b2668bd9d98849bf935c8 (patch)
treec7c8b60c8d389314309c7e2e73e3b41f06988fbc
parent6ec96dc009d73cc2b0a3fa81149ca599b04252e4 (diff)
parent571ae9db7241ffbe1be4f254328cfd2e43369103 (diff)
downloadpodman-7ffcab0854342844a44b2668bd9d98849bf935c8.tar.gz
podman-7ffcab0854342844a44b2668bd9d98849bf935c8.tar.bz2
podman-7ffcab0854342844a44b2668bd9d98849bf935c8.zip
Merge pull request #7908 from rhatdan/diff
fix podman container exists and diff for storage containers
-rw-r--r--cmd/podman/containers/exists.go15
-rw-r--r--cmd/podman/containers/ps.go2
-rw-r--r--cmd/podman/diff.go5
-rw-r--r--cmd/podman/utils/alias.go2
-rw-r--r--completions/bash/podman558
-rw-r--r--docs/source/markdown/podman-container-exists.1.md14
-rw-r--r--docs/source/markdown/podman-ps.1.md78
-rw-r--r--libpod/diff.go20
-rw-r--r--libpod/runtime_cstorage.go4
-rw-r--r--pkg/api/handlers/libpod/containers.go30
-rw-r--r--pkg/bindings/containers/containers.go6
-rw-r--r--pkg/bindings/test/containers_test.go12
-rw-r--r--pkg/domain/entities/containers.go5
-rw-r--r--pkg/domain/entities/engine_container.go2
-rw-r--r--pkg/domain/infra/abi/containers.go16
-rw-r--r--pkg/domain/infra/tunnel/containers.go4
-rw-r--r--test/system/030-run.bats20
-rw-r--r--test/system/140-diff.bats22
18 files changed, 384 insertions, 431 deletions
diff --git a/cmd/podman/containers/exists.go b/cmd/podman/containers/exists.go
index 283f6df18..1d79b684d 100644
--- a/cmd/podman/containers/exists.go
+++ b/cmd/podman/containers/exists.go
@@ -12,10 +12,10 @@ var (
containerExistsDescription = `If the named container exists in local storage, podman container exists exits with 0, otherwise the exit code will be 1.`
existsCommand = &cobra.Command{
- Use: "exists CONTAINER",
+ Use: "exists [flags] CONTAINER",
Short: "Check if a container exists in local storage",
Long: containerExistsDescription,
- Example: `podman container exists containerID
+ Example: `podman container exists --external containerID
podman container exists myctr || podman run --name myctr [etc...]`,
RunE: exists,
Args: cobra.ExactArgs(1),
@@ -29,10 +29,19 @@ func init() {
Command: existsCommand,
Parent: containerCmd,
})
+ flags := existsCommand.Flags()
+ flags.Bool("external", false, "Check external storage containers as well as Podman containers")
}
func exists(cmd *cobra.Command, args []string) error {
- response, err := registry.ContainerEngine().ContainerExists(context.Background(), args[0])
+ external, err := cmd.Flags().GetBool("external")
+ if err != nil {
+ return err
+ }
+ options := entities.ContainerExistsOptions{
+ External: external,
+ }
+ response, err := registry.ContainerEngine().ContainerExists(context.Background(), args[0], options)
if err != nil {
return err
}
diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go
index 65bfc97da..41d309f51 100644
--- a/cmd/podman/containers/ps.go
+++ b/cmd/podman/containers/ps.go
@@ -58,7 +58,7 @@ func init() {
func listFlagSet(flags *pflag.FlagSet) {
flags.BoolVarP(&listOpts.All, "all", "a", false, "Show all the containers, default is only running containers")
flags.StringSliceVarP(&filters, "filter", "f", []string{}, "Filter output based on conditions given")
- flags.BoolVar(&listOpts.Storage, "storage", false, "Show containers in storage not controlled by Podman")
+ flags.BoolVar(&listOpts.Storage, "external", false, "Show containers in storage not controlled by Podman")
flags.StringVar(&listOpts.Format, "format", "", "Pretty-print containers to JSON or using a Go template")
flags.IntVarP(&listOpts.Last, "last", "n", -1, "Print the n last created containers (all states)")
flags.BoolVar(&listOpts.Namespace, "ns", false, "Display namespace information")
diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go
index 51a04bf46..9d2236abe 100644
--- a/cmd/podman/diff.go
+++ b/cmd/podman/diff.go
@@ -48,7 +48,10 @@ func diff(cmd *cobra.Command, args []string) error {
return containers.Diff(cmd, args, diffOpts)
}
- if found, err := registry.ContainerEngine().ContainerExists(registry.GetContext(), args[0]); err != nil {
+ options := entities.ContainerExistsOptions{
+ External: true,
+ }
+ if found, err := registry.ContainerEngine().ContainerExists(registry.GetContext(), args[0], options); err != nil {
return err
} else if found.Value {
return containers.Diff(cmd, args, diffOpts)
diff --git a/cmd/podman/utils/alias.go b/cmd/podman/utils/alias.go
index ff31e82ea..10b96fa98 100644
--- a/cmd/podman/utils/alias.go
+++ b/cmd/podman/utils/alias.go
@@ -21,6 +21,8 @@ func AliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
name = "time"
case "namespace":
name = "ns"
+ case "storage":
+ name = "external"
}
return pflag.NormalizedName(name)
}
diff --git a/completions/bash/podman b/completions/bash/podman
index 564d35f67..c08bb3352 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -755,10 +755,8 @@ _podman_attach() {
--detach-keys
"
local boolean_options="
- --help
- -h
- --latest
- -l
+ --help -h
+ --latest -l
--no-stdin
--sig-proxy
"
@@ -782,18 +780,13 @@ _podman_container_checkpoint() {
--export
"
local boolean_options="
- -a
- --all
- -h
- --help
- -k
- --keep
- -l
- --latest
- -R
- --leave-running
- --tcp-established
+ --all -a
+ --help -h
--ignore-rootfs
+ --keep -k
+ --latest -l
+ --leave-running -R
+ --tcp-established
"
case "$prev" in
-e|--export)
@@ -897,18 +890,14 @@ _podman_container_restore() {
--name
"
local boolean_options="
- -a
- --all
- -h
- --help
- -k
- --keep
- -l
- --latest
- --tcp-established
+ --all -a
+ --help -h
--ignore-rootfs
--ignore-static-ip
--ignore-static-mac
+ --keep -k
+ --latest -l
+ --tcp-established
"
case "$prev" in
-i|--import)
@@ -1015,9 +1004,8 @@ _podman_network_create() {
--subnet
"
local boolean_options="
- --disable-dns
- --help
- -h
+ --disable-dns
+ --help -h
--internal
"
_complete_ "$options_with_args" "$boolean_options"
@@ -1049,9 +1037,8 @@ _podman_network_inspect() {
_podman_network_ls() {
local options_with_args="
- --format
- -f
--filter
+ --format -f
"
local boolean_options="
--help
@@ -1072,10 +1059,8 @@ _podman_network_rm() {
local options_with_args="
"
local boolean_options="
- --force
- -f
- --help
- -h
+ --force -f
+ --help -h
"
_complete_ "$options_with_args" "$boolean_options"
@@ -1222,12 +1207,9 @@ _podman_system_prune() {
"
local boolean_options="
- -a
- --all
- -f
- --force
- -h
- --help
+ --all -a
+ --force -f
+ --help -h
--volumes
"
case "$cur" in
@@ -1287,12 +1269,9 @@ _podman_commit() {
--iidfile
"
local boolean_options="
- --help
- -h
- --pause
- -p
- --quiet
- -q
+ --help -h
+ --pause -p
+ --quiet -q
"
_complete_ "$options_with_args" "$boolean_options"
@@ -1309,15 +1288,13 @@ _podman_commit() {
_podman_build() {
local boolean_options="
--force-rm
- --help
- -h
+ --help -h
--layers
--no-cache
--pull
--pull-always
--pull-never
- --quiet
- -q
+ --quiet -q
--rm
--squash
--squash-all
@@ -1340,33 +1317,29 @@ _podman_build() {
--cpuset-cpus
--cpuset-mems
--creds
- -f
- --file
+ --file -f
--format
--iidfile
--ipc
--label
- -m
- --memory
+ --memory -m
--memory-swap
+ --mount
--net
--network
--pid
--runtime-flag
--security-opt
--shm-size
- -t
- --tag
+ --tag -t
--ulimit
--userns
- --userns-uid-map
--userns-gid-map
- --userns-uid-map-user
--userns-gid-map-group
+ --userns-uid-map
+ --userns-uid-map-user
--uts
- --mount
- --volume
- -v
+ --volume -v
"
case "$prev" in
@@ -1414,13 +1387,10 @@ _podman_exec() {
-w
"
local boolean_options="
- --help
- -h
- --latest
- -l
+ --help -h
+ --latest -l
--privileged
- --tty
- -t
+ --tty -t
"
case "$cur" in
-*)
@@ -1456,8 +1426,7 @@ _podman_history() {
--format
"
local boolean_options="
- --help
- -h
+ --help -h
--human -H
--no-trunc
--quiet -q
@@ -1540,12 +1509,9 @@ _podman_image_umount() {
_podman_image_unmount() {
local boolean_options="
- --all
- -a
- --help
- -h
- --force
- -f
+ --all -a
+ --help -h
+ --force -f
"
local options_with_args="
"
@@ -1563,10 +1529,8 @@ _podman_image_unmount() {
_podman_image_mount() {
local boolean_options="
- --all
- -a
- --help
- -h
+ --all -a
+ --help -h
"
local options_with_args="
@@ -1680,21 +1644,15 @@ _podman_image() {
_podman_images() {
local boolean_options="
- -a
- --all
+ --all -a
--digests
- --digests
- -f
- --filter
- -h
- --help
+ --filter -f
+ --help -h
--history
--no-trunc
- --notruncate
- -n
--noheading
- -q
- --quiet
+ --notruncate -n
+ --quiet -q
"
local options_with_args="
--format
@@ -1715,10 +1673,8 @@ _podman_images() {
_podman_inspect() {
local boolean_options="
- --help
- -h
- --latest
- -l
+ --help -h
+ --latest -l
"
local options_with_args="
--format
@@ -1785,12 +1741,9 @@ _podman_kill() {
--signal -s
"
local boolean_options="
- --all
- -a
- --help
- -h
- --latest
- -l
+ --all -a
+ --help -h
+ --latest -l
"
case "$cur" in
-*)
@@ -1808,14 +1761,10 @@ _podman_logs() {
--tail
"
local boolean_options="
- --follow
- -f
- --help
- -h
- --latest
- -l
- --timestamps
- -t
+ --follow -f
+ --help -h
+ --latest -l
+ --timestamps -t
"
_complete_ "$options_with_args" "$boolean_options"
@@ -1856,10 +1805,10 @@ _podman_manifest() {
_podman_manifest_add() {
local options_with_args="
--annotation
+ --arch
--authfile
--cert-dir
--creds
- --arch
--features
--os
--os-version
@@ -1946,20 +1895,18 @@ _podman_manifest_push() {
--cert-dir
--creds
--digestfile
- --format
- -f
+ --format -f
--sign-by
--signature-policy,
"
local boolean_options="
--all
+ --help -h
--purge
- --help
- -h
+ --quiet
--remove-signatures
--tls-verify
- --quiet
"
_complete_ "$options_with_args" "$boolean_options"
@@ -2001,13 +1948,10 @@ _podman_pull() {
--override-variant
"
local boolean_options="
- --all-tags
- -a
+ --all-tags -a
--disable-content-trust
- --help
- -h
- --quiet
- -q
+ --help -h
+ --quiet -q
--tls-verify
"
_complete_ "$options_with_args" "$boolean_options"
@@ -2035,14 +1979,10 @@ _podman_unmount() {
_podman_umount() {
local boolean_options="
- --all
- -a
- --help
- -h
- --force
- -f
- --latest
- -l
+ --all -a
+ --help -h
+ --force -f
+ --latest -l
"
local options_with_args="
"
@@ -2060,12 +2000,9 @@ _podman_umount() {
_podman_mount() {
local boolean_options="
- --all
- -a
- --help
- -h
- -l
- --latest
+ --all -a
+ --help -h
+ --latest -l
--notruncate
"
@@ -2088,19 +2025,17 @@ _podman_push() {
local boolean_options="
--compress
--digestflag
- --help
- -h
- --quiet
- -q
+ --help -h
+ --quiet -q
--tls-verify
"
local options_with_args="
- --authfile
- --format
- --cert-dir
- --creds
- --sign-by
+ --authfile
+ --cert-dir
+ --creds
+ --format
+ --sign-by
"
local all_options="$options_with_args $boolean_options"
@@ -2125,18 +2060,18 @@ _podman_container_run() {
--builtin-volume
--cap-add
--cap-drop
- --cgroup-parent
--cgroup-conf
+ --cgroup-parent
--cidfile
--conmon-pidfile
--cpu-period
--cpu-quota
--cpu-rt-period
--cpu-rt-runtime
- --cpuset-cpus
+ --cpu-shares -c
--cpus
+ --cpuset-cpus
--cpuset-mems
- --cpu-shares -c
--device
--device-cgroup-rule
--device-read-bps
@@ -2148,8 +2083,8 @@ _podman_container_run() {
--dns-search
--entrypoint
--env -e
- --env-host
--env-file
+ --env-host
--expose
--gidmap
--group-add
@@ -2165,15 +2100,15 @@ _podman_container_run() {
--ip
--ipc
--kernel-memory
- --label-file
--label -l
+ --label-file
--log-driver
--log-opt
--mac-address
--memory -m
+ --memory-reservation
--memory-swap
--memory-swappiness
- --memory-reservation
--name
--network
--no-healthcheck
@@ -2190,8 +2125,8 @@ _podman_container_run() {
--publish -p
--pull
--restart
- --runtime
--rootfs
+ --runtime
--security-opt
--shm-size
--stop-signal
@@ -2202,21 +2137,20 @@ _podman_container_run() {
--systemd
--tmpfs
--tz
- --umask
--uidmap
--ulimit
+ --umask
--user -u
--userns
--uts
- --volumes-from
--volume -v
+ --volumes-from
--workdir -w
"
local boolean_options="
--disable-content-trust=false
- --help
- -h
+ --help -h
--init
--interactive -i
--oom-kill-disable
@@ -2234,8 +2168,8 @@ _podman_container_run() {
--health-cmd
--health-interval
--health-retries
- --health-timeout
--health-start-period
+ --health-timeout
"
boolean_options="$boolean_options
--detach -d
@@ -2437,12 +2371,9 @@ _podman_restart() {
--time -t
"
local boolean_options="
- --all
- -a
- --help
- -h
- --latest
- -l
+ --all -a
+ --help -h
+ --latest -l
--running
"
case "$cur" in
@@ -2457,20 +2388,13 @@ _podman_restart() {
_podman_rm() {
local boolean_options="
- --all
- -a
+ --all -a
--cidfile
- --force
- -f
- --help
- -h
- --ignore
- -i
- --latest
- -l
- --storage
- --volumes
- -v
+ --force -f
+ --help -h
+ --ignore -i
+ --latest -l
+ --volumes -v
"
local options_with_args="
@@ -2490,12 +2414,9 @@ _podman_rm() {
_podman_rmi() {
local boolean_options="
- --all
- -a
- --force
- -f
- --help
- -h
+ --all -a
+ --force -f
+ --help -h
"
case "$cur" in
@@ -2510,13 +2431,11 @@ _podman_rmi() {
_podman_stats() {
local boolean_options="
- --all
- -a
- --help
- -h
- --no-stream
+ --all -a
--format
+ --help -h
--no-reset
+ --no-stream
"
case "$cur" in
@@ -2619,10 +2538,8 @@ _podman_save() {
"
local boolean_options="
--compress
- --help
- -h
- -q
- --quiet
+ --help -h
+ --quiet -q
"
case "$cur" in
@@ -2659,12 +2576,9 @@ _podman_port() {
local options_with_args="
"
local boolean_options="
- --all
- -a
- --help
- -h
- -l
- --latest
+ --all -a
+ --help -h
+ --latest -l
"
case "$cur" in
-*)
@@ -2690,14 +2604,14 @@ _podman_ps() {
"
local boolean_options="
--all -a
+ --external
--help -h
--latest -l
+ --namespace --ns
--no-trunc
--pod -p
--quiet -q
--size -s
- --storage
- --namespace --ns
--sync
"
_complete_ "$options_with_args" "$boolean_options"
@@ -2730,14 +2644,10 @@ _podman_start() {
"
local boolean_options="
- --attach
- -a
- -h
- --help
- -i
- --interactive
- --latest
- -l
+ --attach -a
+ --help -h
+ --interactive -i
+ --latest -l
--sig-proxy
"
case "$cur" in
@@ -2754,15 +2664,11 @@ _podman_stop() {
--time -t
"
local boolean_options="
- --all
- -a
+ --all -a
--cidfile
- -h
- --help
- --ignore
- -i
- --latest
- -l
+ --help -h
+ --ignore -i
+ --latest -l
"
case "$cur" in
-*)
@@ -2807,12 +2713,9 @@ _podman_varlink() {
_podman_wait() {
local options_with_args=""
local boolean_options="
- --help
- -h
- -i
- -l
- --interval
- --latest
+ --help -h
+ --interval -i
+ --latest -l
"
case "$cur" in
-*)
@@ -2846,19 +2749,16 @@ _podman_load() {
--input -i
"
local boolean_options="
- --help
- -h
- --quiet
- -q
+ --help -h
+ --quiet -q
"
_complete_ "$options_with_args" "$boolean_options"
}
_podman_cp() {
local boolean_options="
- --help
- -h
--extract
+ --help -h
--pause
"
_complete_ "$boolean_options"
@@ -2866,12 +2766,10 @@ _podman_cp() {
_podman_login() {
local options_with_args="
- --username
- -u
- --password
- -p
--authfile
--get-login
+ --password -p
+ --username -u
"
local boolean_options="
--help
@@ -2979,12 +2877,10 @@ _podman_play_kube() {
"
local boolean_options="
- -h
- --help
- --quiet
- -q
- --tls-verify
+ --help -h
+ --quiet -q
--seccomp-profile-root
+ --tls-verify
"
case "$cur" in
@@ -2999,10 +2895,9 @@ _podman_play_kube() {
_podman_events() {
local options_with_args="
- --help
- --h
--filter
--format
+ --help -h
--since
--until
"
@@ -3023,10 +2918,8 @@ _podman_container_runlabel() {
local boolean_options="
--display
- --help
- -h
- -q
- --quiet
+ --help -h
+ --quiet -q
--replace
--tls-verify
"
@@ -3044,8 +2937,7 @@ _podman_container_runlabel() {
_podman_image_sign() {
local options_with_args="
--cert-dir
- -d
- --directory
+ --directory -d
--sign-by
"
local boolean_options="
@@ -3065,9 +2957,8 @@ _podman_image_sign() {
_podman_image_trust_set() {
echo hello
local options_with_args="
- -f
- --type
- --pubkeysfile
+ --pubkeysfile -f
+ --type -t
"
local boolean_options="
--help
@@ -3087,10 +2978,8 @@ _podman_image_trust_show() {
local options_with_args="
"
local boolean_options="
- --help
- -h
- -j
- --json
+ --help -h
+ --json -j
--raw
"
case "$cur" in
@@ -3133,10 +3022,8 @@ _podman_images_prune() {
"
local boolean_options="
- -a
- --all
- -h
- --help
+ --all -a
+ --help -h
"
case "$cur" in
-*)
@@ -3151,10 +3038,8 @@ _podman_container_prune() {
"
local boolean_options="
- -f
- --force
- -h
- --help
+ --force -f
+ --help -h
"
case "$cur" in
-*)
@@ -3168,7 +3053,10 @@ _podman_container_exists() {
"
local boolean_options="
- "
+ --external
+ --help -h
+ "
+
case "$cur" in
-*)
COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
@@ -3221,8 +3109,7 @@ _podman_pod_create() {
"
local boolean_options="
- --help
- -h
+ --help -h
--infra
--replace
"
@@ -3234,14 +3121,10 @@ _podman_pod_kill() {
"
local boolean_options="
- --all
- -a
- --help
- -h
- --signal
- -s
- --latest
- -l
+ --all -a
+ --help -h
+ --latest -l
+ --signal -s
"
_complete_ "$options_with_args" "$boolean_options"
case "$cur" in
@@ -3256,8 +3139,7 @@ _podman_pod_kill() {
__podman_pod_ps() {
local options_with_args="
- -f
- --filter
+ --filter -f
--format
--sort
"
@@ -3267,14 +3149,11 @@ __podman_pod_ps() {
--ctr-ids
--ctr-names
--ctr-status
- --help
- -h
- -q
- --quiet
- --no-trunc
+ --help -h
--labels
- -l
- --latest
+ --latest -l
+ --no-trunc
+ --quiet -q
"
_complete_ "$options_with_args" "$boolean_options"
}
@@ -3312,12 +3191,9 @@ _podman_pod_restart() {
"
local boolean_options="
- --all
- -a
- --help
- -h
- --latest
- -l
+ --all -a
+ --help -h
+ --latest -l
"
_complete_ "$options_with_args" "$boolean_options"
case "$cur" in
@@ -3336,16 +3212,11 @@ _podman_pod_rm() {
"
local boolean_options="
- -a
- --all
- --help
- -h
- --ignore
- -i
- -f
- --force
- --latest
- -l
+ --all -a
+ --force -f
+ --help -h
+ --ignore -i
+ --latest -l
"
_complete_ "$options_with_args" "$boolean_options"
case "$cur" in
@@ -3364,12 +3235,9 @@ _podman_pod_start() {
"
local boolean_options="
- --all
- -a
- --help
- -h
- --latest
- -l
+ --all -a
+ --help -h
+ --latest -l
"
_complete_ "$options_with_args" "$boolean_options"
case "$cur" in
@@ -3384,21 +3252,16 @@ _podman_pod_start() {
_podman_pod_stop() {
local options_with_args="
- -t
- --time
--pod-id-file
+ --time -t
"
local boolean_options="
- --all
- -a
+ --all -a
--cleanup
- --help
- --ignore
- -i
- -h
- --latest
- -l
+ --help -h
+ --ignore -i
+ --latest -l
"
_complete_ "$options_with_args" "$boolean_options"
case "$cur" in
@@ -3416,12 +3279,9 @@ _podman_pod_pause() {
"
local boolean_options="
- --all
- -a
- --help
- -h
- --latest
- -l
+ --all -a
+ --help -h
+ --latest -l
"
_complete_ "$options_with_args" "$boolean_options"
case "$cur" in
@@ -3439,12 +3299,9 @@ _podman_pod_unpause() {
"
local boolean_options="
- --all
- -a
- --help
- -h
- --latest
- -l
+ --all -a
+ --help -h
+ --latest -l
"
_complete_ "$options_with_args" "$boolean_options"
case "$cur" in
@@ -3459,10 +3316,8 @@ _podman_pod_unpause() {
_podman_pod_inspect() {
local options_with_args="
- --format
- -f
- --latest
- -l
+ --format -f
+ --latest -l
"
_complete_ "$options_with_args"
@@ -3476,6 +3331,7 @@ _podman_pod() {
"
subcommands="
create
+ inspect
kill
pause
ps
@@ -3486,7 +3342,6 @@ _podman_pod() {
stop
top
unpause
- inspect
"
local aliases="
list
@@ -3507,10 +3362,8 @@ _podman_pod() {
_podman_volume_create() {
local options_with_args="
--driver
- --label
- -l
- --opt
- -o
+ --label -l
+ --opt -o
"
local boolean_options="
@@ -3524,15 +3377,12 @@ _podman_volume_create() {
_podman_volume_ls() {
local options_with_args="
--filter
- --format
- -f
+ --format -f
"
local boolean_options="
- --help
- -h
- --quiet
- -q
+ --help -h
+ --quiet -q
"
_complete_ "$options_with_args" "$boolean_options"
@@ -3545,10 +3395,8 @@ _podman_volume_inspect() {
"
local boolean_options="
- --all
- -a
- --help
- -h
+ --all -a
+ --help -h
"
_complete_ "$options_with_args" "$boolean_options"
@@ -3566,12 +3414,9 @@ _podman_volume_rm() {
local options_with_args=""
local boolean_options="
- --all
- -a
- --force
- -f
- --help
- -h
+ --all -a
+ --force -f
+ --help -h
"
_complete_ "$options_with_args" "$boolean_options"
@@ -3589,10 +3434,8 @@ _podman_volume_prune() {
local options_with_args=""
local boolean_options="
- --force
- -f
- --help
- -h
+ --force -f
+ --help -h
"
_complete_ "$options_with_args" "$boolean_options"
@@ -3600,15 +3443,14 @@ _podman_volume_prune() {
_podman_volume() {
local boolean_options="
- --help
- -h
+ --help -h
"
subcommands="
create
inspect
ls
- rm
prune
+ rm
"
local aliases="
list
@@ -3639,19 +3481,17 @@ _podman_podman() {
--network-cmd-path
--root
--runroot
+ --runtime
--storage-driver
--storage-opt
--tmpdir
- --runtime
--url
"
local boolean_options="
- --help
+ --help -h
+ --remote -r
--syslog
- --version
- -h
- -r, --remote
- -v
+ --version -v
"
commands="
attach
@@ -3682,12 +3522,12 @@ _podman_podman() {
mount
network
pause
+ play
pod
port
ps
pull
push
- play
restart
rm
rmi
diff --git a/docs/source/markdown/podman-container-exists.1.md b/docs/source/markdown/podman-container-exists.1.md
index 3cc13e73a..d81a38515 100644
--- a/docs/source/markdown/podman-container-exists.1.md
+++ b/docs/source/markdown/podman-container-exists.1.md
@@ -4,7 +4,7 @@
podman-container-exists - Check if a container exists in local storage
## SYNOPSIS
-**podman container exists** *container*
+**podman container exists** [*options*] *container*
## DESCRIPTION
**podman container exists** checks if a container exists in local storage. The **ID** or **Name**
@@ -14,6 +14,9 @@ was an issue accessing the local storage.
## OPTIONS
+**--external**=*true|false*
+Check for external containers as well as Podman containers. These external containers are generally created via other container technology such as Buildah or CRI-O.
+
**-h**, **--help**
Print usage statement
@@ -24,7 +27,6 @@ Check if an container called `webclient` exists in local storage (the container
$ podman container exists webclient
$ echo $?
0
-$
```
Check if an container called `webbackend` exists in local storage (the container does not actually exist).
@@ -32,7 +34,13 @@ Check if an container called `webbackend` exists in local storage (the container
$ podman container exists webbackend
$ echo $?
1
-$
+```
+
+Check if an container called `ubi8-working-container` created via Buildah exists in local storage (the container does not actually exist).
+```
+$ podman container exists --external ubi8-working-container
+$ echo $?
+1
```
## SEE ALSO
diff --git a/docs/source/markdown/podman-ps.1.md b/docs/source/markdown/podman-ps.1.md
index 58d3358e5..90f147222 100644
--- a/docs/source/markdown/podman-ps.1.md
+++ b/docs/source/markdown/podman-ps.1.md
@@ -34,23 +34,33 @@ all the containers information. By default it lists:
Show all the containers created by Podman, default is only running containers.
-Note: Podman shares containers storage with other tools such as Buildah and CRI-O. In some cases these `external` containers might also exist in the same storage. Use the `--storage` option to see these external containers. External containers show the 'storage' status.
+Note: Podman shares containers storage with other tools such as Buildah and CRI-O. In some cases these `external` containers might also exist in the same storage. Use the `--external` option to see these external containers. External containers show the 'storage' status.
-**--pod**, **-p**
-
-Display the pods the containers are associated with
-
-**--storage**
+**--external**
Display external containers that are not controlled by Podman but are stored in containers storage. These external containers are generally created via other container technology such as Buildah or CRI-O and may depend on the same container images that Podman is also using. External containers are denoted with either a 'buildah' or 'storage' in the COMMAND and STATUS column of the ps output. Only used with the --all option.
-**--no-trunc**
+**--filter**, **-f**
-Display the extended information
+Filter what containers are shown in the output.
+Multiple filters can be given with multiple uses of the --filter flag.
+If multiple filters are given, only containers which match all of the given filters will be shown.
+Results will be drawn from all containers, regardless of whether --all was given.
-**--quiet**, **-q**
+Valid filters are listed below:
-Print the numeric IDs of the containers only
+| **Filter** | **Description** |
+| --------------- | -------------------------------------------------------------------------------- |
+| id | [ID] Container's ID |
+| name | [Name] Container's name |
+| label | [Key] or [Key=Value] Label assigned to a container |
+| exited | [Int] Container's exit code |
+| status | [Status] Container's status: 'created', 'exited', 'paused', 'running', 'unknown' |
+| ancestor | [ImageName] Image or descendant used to create container |
+| before | [ID] or [Name] Containers created before this container |
+| since | [ID] or [Name] Containers created since this container |
+| volume | [VolumeName] or [MountpointDestination] Volume mounted in container |
+| health | [Status] healthy or unhealthy |
**--format**=*format*
@@ -74,15 +84,9 @@ Valid placeholders for the Go template are listed below:
| .Labels | All the labels assigned to the container |
| .Mounts | Volumes mounted in the container |
-**--sort**
-
-Sort by command, created, id, image, names, runningfor, size, or status",
-Note: Choosing size will sort by size of rootFs, not alphabetically like the rest of the options
-Default: created
-
-**--size**, **-s**
+**--help**, **-h**
-Display the total file size
+Print usage statement
**--last**, **-n**
@@ -98,31 +102,27 @@ The latest option is not supported on the remote client.
Display namespace information
-**--filter**, **-f**
+**--no-trunc**
-Filter what containers are shown in the output.
-Multiple filters can be given with multiple uses of the --filter flag.
-If multiple filters are given, only containers which match all of the given filters will be shown.
-Results will be drawn from all containers, regardless of whether --all was given.
+Display the extended information
-Valid filters are listed below:
+**--pod**, **-p**
-| **Filter** | **Description** |
-| --------------- | -------------------------------------------------------------------------------- |
-| id | [ID] Container's ID |
-| name | [Name] Container's name |
-| label | [Key] or [Key=Value] Label assigned to a container |
-| exited | [Int] Container's exit code |
-| status | [Status] Container's status: 'created', 'exited', 'paused', 'running', 'unknown' |
-| ancestor | [ImageName] Image or descendant used to create container |
-| before | [ID] or [Name] Containers created before this container |
-| since | [ID] or [Name] Containers created since this container |
-| volume | [VolumeName] or [MountpointDestination] Volume mounted in container |
-| health | [Status] healthy or unhealthy |
+Display the pods the containers are associated with
-**--help**, **-h**
+**--quiet**, **-q**
-Print usage statement
+Print the numeric IDs of the containers only
+
+**--sort**
+
+Sort by command, created, id, image, names, runningfor, size, or status",
+Note: Choosing size will sort by size of rootFs, not alphabetically like the rest of the options
+Default: created
+
+**--size**, **-s**
+
+Display the total file size
**--sync**
@@ -181,7 +181,7 @@ CONTAINER ID IMAGE COMMAND CREATED STATUS
```
```
-$ podman ps --storage -a
+$ podman ps --external -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69ed779d8ef9f redis:alpine "redis-server" 25 hours ago Created 6379/tcp k8s_container1_podsandbox1_redhat.test.crio_redhat-test-crio_1
38a8a78596f9 docker.io/library/busybox:latest buildah 2 hours ago storage busybox-working-container
diff --git a/libpod/diff.go b/libpod/diff.go
index 5335d701c..43f4d2e96 100644
--- a/libpod/diff.go
+++ b/libpod/diff.go
@@ -62,18 +62,22 @@ func (r *Runtime) ApplyDiffTarStream(to string, diff io.Reader) error {
func (r *Runtime) getLayerID(id string) (string, error) {
var toLayer string
toImage, err := r.imageRuntime.NewFromLocal(id)
+ if err == nil {
+ return toImage.TopLayer(), nil
+ }
+
+ targetID, err := r.store.Lookup(id)
if err != nil {
- toCtr, err := r.store.Container(id)
+ targetID = id
+ }
+ toCtr, err := r.store.Container(targetID)
+ if err != nil {
+ toLayer, err = layers.FullID(r.store, targetID)
if err != nil {
- toLayer, err = layers.FullID(r.store, id)
- if err != nil {
- return "", errors.Errorf("layer, image, or container %s does not exist", id)
- }
- } else {
- toLayer = toCtr.LayerID
+ return "", errors.Errorf("layer, image, or container %s does not exist", id)
}
} else {
- toLayer = toImage.TopLayer()
+ toLayer = toCtr.LayerID
}
return toLayer, nil
}
diff --git a/libpod/runtime_cstorage.go b/libpod/runtime_cstorage.go
index 03eebeefc..61fdd42d3 100644
--- a/libpod/runtime_cstorage.go
+++ b/libpod/runtime_cstorage.go
@@ -52,6 +52,10 @@ func (r *Runtime) ListStorageContainers() ([]*StorageContainer, error) {
return finalCtrs, nil
}
+func (r *Runtime) StorageContainer(idOrName string) (*storage.Container, error) {
+ return r.store.Container(idOrName)
+}
+
// RemoveStorageContainer removes a container from c/storage.
// The container WILL NOT be removed if it exists in libpod.
// Accepts ID or full name of container.
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 7dde51102..7e6481321 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v2/pkg/api/handlers/compat"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/infra/abi"
"github.com/containers/podman/v2/pkg/ps"
"github.com/gorilla/schema"
"github.com/pkg/errors"
@@ -18,9 +19,30 @@ import (
)
func ContainerExists(w http.ResponseWriter, r *http.Request) {
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ // Now use the ABI implementation to prevent us from having duplicate
+ // code.
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+
name := utils.GetName(r)
- _, err := runtime.LookupContainer(name)
+ query := struct {
+ External bool `schema:"external"`
+ }{
+ // override any golang type defaults
+ }
+
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ return
+ }
+
+ options := entities.ContainerExistsOptions{
+ External: query.External,
+ }
+
+ report, err := containerEngine.ContainerExists(r.Context(), name, options)
if err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr {
utils.ContainerNotFound(w, name, err)
@@ -30,7 +52,11 @@ func ContainerExists(w http.ResponseWriter, r *http.Request) {
return
}
- utils.WriteResponse(w, http.StatusNoContent, "")
+ if report.Value {
+ utils.WriteResponse(w, http.StatusNoContent, "")
+ } else {
+ utils.ContainerNotFound(w, name, define.ErrNoSuchCtr)
+ }
}
func ListContainers(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index 708ad06cb..b5cd2128b 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -322,12 +322,14 @@ func Wait(ctx context.Context, nameOrID string, condition *define.ContainerStatu
// Exists is a quick, light-weight way to determine if a given container
// exists in local storage. The nameOrID can be a container name
// or a partial/full ID.
-func Exists(ctx context.Context, nameOrID string) (bool, error) {
+func Exists(ctx context.Context, nameOrID string, external bool) (bool, error) {
conn, err := bindings.GetClient(ctx)
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/exists", nil, nil, nameOrID)
+ params := url.Values{}
+ params.Set("external", strconv.FormatBool(external))
+ response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/exists", params, nil, nameOrID)
if err != nil {
return false, err
}
diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go
index 408b4769d..0fb677768 100644
--- a/pkg/bindings/test/containers_test.go
+++ b/pkg/bindings/test/containers_test.go
@@ -405,7 +405,7 @@ var _ = Describe("Podman containers ", func() {
It("podman bogus container does not exist in local storage", func() {
// Bogus container existence check should fail
- containerExists, err := containers.Exists(bt.conn, "foobar")
+ containerExists, err := containers.Exists(bt.conn, "foobar", false)
Expect(err).To(BeNil())
Expect(containerExists).To(BeFalse())
})
@@ -415,7 +415,7 @@ var _ = Describe("Podman containers ", func() {
var name = "top"
_, err := bt.RunTopContainer(&name, bindings.PFalse, nil)
Expect(err).To(BeNil())
- containerExists, err := containers.Exists(bt.conn, name)
+ containerExists, err := containers.Exists(bt.conn, name, false)
Expect(err).To(BeNil())
Expect(containerExists).To(BeTrue())
})
@@ -425,7 +425,7 @@ var _ = Describe("Podman containers ", func() {
var name = "top"
cid, err := bt.RunTopContainer(&name, bindings.PFalse, nil)
Expect(err).To(BeNil())
- containerExists, err := containers.Exists(bt.conn, cid)
+ containerExists, err := containers.Exists(bt.conn, cid, false)
Expect(err).To(BeNil())
Expect(containerExists).To(BeTrue())
})
@@ -435,7 +435,7 @@ var _ = Describe("Podman containers ", func() {
var name = "top"
cid, err := bt.RunTopContainer(&name, bindings.PFalse, nil)
Expect(err).To(BeNil())
- containerExists, err := containers.Exists(bt.conn, cid[0:12])
+ containerExists, err := containers.Exists(bt.conn, cid[0:12], false)
Expect(err).To(BeNil())
Expect(containerExists).To(BeTrue())
})
@@ -455,7 +455,7 @@ var _ = Describe("Podman containers ", func() {
Expect(err).To(BeNil())
err = containers.Kill(bt.conn, name, "SIGINT")
Expect(err).To(BeNil())
- _, err = containers.Exists(bt.conn, name)
+ _, err = containers.Exists(bt.conn, name, false)
Expect(err).To(BeNil())
})
@@ -466,7 +466,7 @@ var _ = Describe("Podman containers ", func() {
Expect(err).To(BeNil())
err = containers.Kill(bt.conn, cid, "SIGTERM")
Expect(err).To(BeNil())
- _, err = containers.Exists(bt.conn, cid)
+ _, err = containers.Exists(bt.conn, cid, false)
Expect(err).To(BeNil())
})
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 3b6dd106f..46b169284 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -246,6 +246,11 @@ type ExecOptions struct {
WorkDir string
}
+// ContainerExistsOptions describes the cli values to check if a container exists
+type ContainerExistsOptions struct {
+ External bool
+}
+
// ContainerStartOptions describes the val from the
// CLI needed to start a container
type ContainerStartOptions struct {
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 803a59932..a20d3b404 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -21,7 +21,7 @@ type ContainerEngine interface {
ContainerDiff(ctx context.Context, nameOrID string, options DiffOptions) (*DiffReport, error)
ContainerExec(ctx context.Context, nameOrID string, options ExecOptions, streams define.AttachStreams) (int, error)
ContainerExecDetached(ctx context.Context, nameOrID string, options ExecOptions) (string, error)
- ContainerExists(ctx context.Context, nameOrID string) (*BoolReport, error)
+ ContainerExists(ctx context.Context, nameOrID string, options ContainerExistsOptions) (*BoolReport, error)
ContainerExport(ctx context.Context, nameOrID string, options ContainerExportOptions) error
ContainerInit(ctx context.Context, namesOrIds []string, options ContainerInitOptions) ([]*ContainerInitReport, error)
ContainerInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]*ContainerInspectReport, []error, error)
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 614fd5fe0..60dbbce6c 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -74,11 +74,19 @@ func getContainersByContext(all, latest bool, names []string, runtime *libpod.Ru
return
}
-// TODO: Should return *entities.ContainerExistsReport, error
-func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string) (*entities.BoolReport, error) {
+// ContainerExists returns whether the container exists in container storage
+func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string, options entities.ContainerExistsOptions) (*entities.BoolReport, error) {
_, err := ic.Libpod.LookupContainer(nameOrID)
- if err != nil && errors.Cause(err) != define.ErrNoSuchCtr {
- return nil, err
+ if err != nil {
+ if errors.Cause(err) != define.ErrNoSuchCtr {
+ return nil, err
+ }
+ if options.External {
+ // Check if container exists in storage
+ if _, storageErr := ic.Libpod.StorageContainer(nameOrID); storageErr == nil {
+ err = nil
+ }
+ }
}
return &entities.BoolReport{Value: err == nil}, nil
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index eb591d23d..7913d79cd 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -29,8 +29,8 @@ func (ic *ContainerEngine) ContainerRunlabel(ctx context.Context, label string,
return errors.New("not implemented")
}
-func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string) (*entities.BoolReport, error) {
- exists, err := containers.Exists(ic.ClientCxt, nameOrID)
+func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string, options entities.ContainerExistsOptions) (*entities.BoolReport, error) {
+ exists, err := containers.Exists(ic.ClientCxt, nameOrID, options.External)
return &entities.BoolReport{Value: exists}, err
}
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index 28dc7c7a7..f7c48da8d 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -460,4 +460,24 @@ json-file | f
is "$output" "$expect" "podman run with --tz=local, matches host"
}
+@test "podman container exists" {
+ rand=$(random_string 30)
+ run_podman 1 container exists myctr
+
+ run_podman create --name myctr $IMAGE /bin/true
+ run_podman container exists myctr
+
+ # Create a container that podman does not know about
+ run buildah from $IMAGE
+ cid="$output"
+
+ # exists should fail
+ run_podman 1 container exists $cid
+
+ # exists should succeed
+ run_podman container exists --external $cid
+
+ run buildah rm $cid
+}
+
# vim: filetype=sh
diff --git a/test/system/140-diff.bats b/test/system/140-diff.bats
index 01ec5430e..d0f33e438 100644
--- a/test/system/140-diff.bats
+++ b/test/system/140-diff.bats
@@ -32,4 +32,26 @@ load helpers
run_podman rm $n
}
+@test "podman diff with buildah container " {
+ rand_file=$(random_string 10)
+ run buildah from --name buildahctr $IMAGE
+ run buildah run buildahctr sh -c "touch /$rand_file;rm /etc/services"
+
+ run_podman diff --format json buildahctr
+
+ # Expected results for each type of diff
+ declare -A expect=(
+ [added]="/$rand_file"
+ [changed]="/etc"
+ [deleted]="/etc/services"
+ )
+
+ for field in ${!expect[@]}; do
+ result=$(jq -r -c ".${field}[]" <<<"$output")
+ is "$result" "${expect[$field]}" "$field"
+ done
+
+ run buildah rm buildahctr
+}
+
# vim: filetype=sh