aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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/podman9
-rw-r--r--docs/source/markdown/podman-container-exists.1.md12
-rw-r--r--docs/source/markdown/podman-ps.1.md78
-rw-r--r--pkg/api/handlers/libpod/containers.go19
-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.go10
-rw-r--r--pkg/domain/infra/tunnel/containers.go4
-rw-r--r--test/system/030-run.bats5
15 files changed, 121 insertions, 65 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..9ed64ce3a 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -2468,7 +2468,6 @@ _podman_rm() {
-i
--latest
-l
- --storage
--volumes
-v
"
@@ -2696,7 +2695,7 @@ _podman_ps() {
--pod -p
--quiet -q
--size -s
- --storage
+ --external
--namespace --ns
--sync
"
@@ -3168,7 +3167,11 @@ _podman_container_exists() {
"
local boolean_options="
- "
+ --external
+ -h
+ --help
+ "
+
case "$cur" in
-*)
COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
diff --git a/docs/source/markdown/podman-container-exists.1.md b/docs/source/markdown/podman-container-exists.1.md
index b8be07cb9..3d151cfce 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
@@ -33,6 +36,13 @@ $ 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
podman(1)
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/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 8068ea1b8..7e6481321 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -19,13 +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)
- report, err := containerEngine.ContainerExists(r.Context(), 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)
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 191ad8eec..60dbbce6c 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -75,15 +75,17 @@ func getContainersByContext(all, latest bool, names []string, runtime *libpod.Ru
}
// ContainerExists returns whether the container exists in container storage
-func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string) (*entities.BoolReport, error) {
+func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string, options entities.ContainerExistsOptions) (*entities.BoolReport, error) {
_, err := ic.Libpod.LookupContainer(nameOrID)
if err != nil {
if errors.Cause(err) != define.ErrNoSuchCtr {
return nil, err
}
- // Check if container exists in storage
- if _, storageErr := ic.Libpod.StorageContainer(nameOrID); storageErr == nil {
- err = nil
+ 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 1bb4e68ac..98e30c83d 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 a82743c70..f7c48da8d 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -471,8 +471,11 @@ json-file | f
run buildah from $IMAGE
cid="$output"
+ # exists should fail
+ run_podman 1 container exists $cid
+
# exists should succeed
- run_podman container exists $cid
+ run_podman container exists --external $cid
run buildah rm $cid
}