mirror of
https://github.com/containers/podman.git
synced 2025-06-23 02:18:13 +08:00
add podman container|image exists
Add an exists subcommand to podman container and podman image that allows users to verify the existence of a container or image by ID or name. The return code can be 0 (success), 1 (failed to find), or 125 (failed to work with runtime). Issue #1845 Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
@ -9,6 +9,7 @@ var (
|
|||||||
attachCommand,
|
attachCommand,
|
||||||
checkpointCommand,
|
checkpointCommand,
|
||||||
cleanupCommand,
|
cleanupCommand,
|
||||||
|
containerExistsCommand,
|
||||||
commitCommand,
|
commitCommand,
|
||||||
createCommand,
|
createCommand,
|
||||||
diffCommand,
|
diffCommand,
|
||||||
|
83
cmd/podman/exists.go
Normal file
83
cmd/podman/exists.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podman/libpodruntime"
|
||||||
|
"github.com/containers/libpod/libpod"
|
||||||
|
"github.com/containers/libpod/libpod/image"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
imageExistsDescription = `
|
||||||
|
podman image exists
|
||||||
|
|
||||||
|
Check if an image exists in local storage
|
||||||
|
`
|
||||||
|
|
||||||
|
imageExistsCommand = cli.Command{
|
||||||
|
Name: "exists",
|
||||||
|
Usage: "Check if an image exists in local storage",
|
||||||
|
Description: imageExistsDescription,
|
||||||
|
Action: imageExistsCmd,
|
||||||
|
ArgsUsage: "IMAGE-NAME",
|
||||||
|
OnUsageError: usageErrorHandler,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
containerExistsDescription = `
|
||||||
|
podman container exists
|
||||||
|
|
||||||
|
Check if a container exists in local storage
|
||||||
|
`
|
||||||
|
|
||||||
|
containerExistsCommand = cli.Command{
|
||||||
|
Name: "exists",
|
||||||
|
Usage: "Check if a container exists in local storage",
|
||||||
|
Description: containerExistsDescription,
|
||||||
|
Action: containerExistsCmd,
|
||||||
|
ArgsUsage: "CONTAINER-NAME",
|
||||||
|
OnUsageError: usageErrorHandler,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func imageExistsCmd(c *cli.Context) error {
|
||||||
|
args := c.Args()
|
||||||
|
if len(args) > 1 || len(args) < 1 {
|
||||||
|
return errors.New("you may only check for the existence of one image at a time")
|
||||||
|
}
|
||||||
|
runtime, err := libpodruntime.GetRuntime(c)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "could not get runtime")
|
||||||
|
}
|
||||||
|
defer runtime.Shutdown(false)
|
||||||
|
if _, err := runtime.ImageRuntime().NewFromLocal(args[0]); err != nil {
|
||||||
|
if errors.Cause(err) == image.ErrNoSuchImage {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func containerExistsCmd(c *cli.Context) error {
|
||||||
|
args := c.Args()
|
||||||
|
if len(args) > 1 || len(args) < 1 {
|
||||||
|
return errors.New("you may only check for the existence of one container at a time")
|
||||||
|
}
|
||||||
|
runtime, err := libpodruntime.GetRuntime(c)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "could not get runtime")
|
||||||
|
}
|
||||||
|
defer runtime.Shutdown(false)
|
||||||
|
if _, err := runtime.LookupContainer(args[0]); err != nil {
|
||||||
|
if errors.Cause(err) == libpod.ErrNoSuchCtr {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -9,6 +9,7 @@ var (
|
|||||||
buildCommand,
|
buildCommand,
|
||||||
historyCommand,
|
historyCommand,
|
||||||
importCommand,
|
importCommand,
|
||||||
|
imageExistsCommand,
|
||||||
inspectCommand,
|
inspectCommand,
|
||||||
loadCommand,
|
loadCommand,
|
||||||
lsImagesCommand,
|
lsImagesCommand,
|
||||||
|
@ -2178,6 +2178,22 @@ _podman_container_runlabel() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_podman_container_exists() {
|
||||||
|
local options_with_args="
|
||||||
|
"
|
||||||
|
|
||||||
|
local boolean_options="
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
_podman_image_exists() {
|
||||||
|
local options_with_args="
|
||||||
|
"
|
||||||
|
|
||||||
|
local boolean_options="
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
_podman_pod_create() {
|
_podman_pod_create() {
|
||||||
local options_with_args="
|
local options_with_args="
|
||||||
--cgroup-parent
|
--cgroup-parent
|
||||||
|
40
docs/podman-container-exists.1.md
Normal file
40
docs/podman-container-exists.1.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
% PODMAN(1) Podman Man Pages
|
||||||
|
% Brent Baude
|
||||||
|
% November 2018
|
||||||
|
# NAME
|
||||||
|
podman-container-exists- Check if a container exists in local storage
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
**podman container exists**
|
||||||
|
[**-h**|**--help**]
|
||||||
|
CONTAINER
|
||||||
|
|
||||||
|
# DESCRIPTION
|
||||||
|
**podman container exists** checks if a container exists in local storage. The **ID** or **Name**
|
||||||
|
of the container may be used as input. Podman will return an exit code
|
||||||
|
of `0` when the container is found. A `1` will be returned otherwise. An exit code of `125` indicates there
|
||||||
|
was an issue accessing the local storage.
|
||||||
|
|
||||||
|
## Examples ##
|
||||||
|
|
||||||
|
Check if an container called `webclient` exists in local storage (the container does actually exist).
|
||||||
|
```
|
||||||
|
$ sudo podman container exists webclient
|
||||||
|
$ echo $?
|
||||||
|
0
|
||||||
|
$
|
||||||
|
```
|
||||||
|
|
||||||
|
Check if an container called `webbackend` exists in local storage (the container does not actually exist).
|
||||||
|
```
|
||||||
|
$ sudo podman container exists webbackend
|
||||||
|
$ echo $?
|
||||||
|
1
|
||||||
|
$
|
||||||
|
```
|
||||||
|
|
||||||
|
## SEE ALSO
|
||||||
|
podman(1)
|
||||||
|
|
||||||
|
# HISTORY
|
||||||
|
November 2018, Originally compiled by Brent Baude (bbaude at redhat dot com)
|
@ -20,6 +20,7 @@ The container command allows you to manage containers
|
|||||||
| create | [podman-create(1)](podman-create.1.md) | Create a new container. |
|
| create | [podman-create(1)](podman-create.1.md) | Create a new container. |
|
||||||
| diff | [podman-diff(1)](podman-diff.1.md) | Inspect changes on a container or image's filesystem. |
|
| diff | [podman-diff(1)](podman-diff.1.md) | Inspect changes on a container or image's filesystem. |
|
||||||
| exec | [podman-exec(1)](podman-exec.1.md) | Execute a command in a running container. |
|
| exec | [podman-exec(1)](podman-exec.1.md) | Execute a command in a running container. |
|
||||||
|
| exists | [podman-exists(1)](podman-container-exists.1.md) | Check if a container exists in local storage |
|
||||||
| export | [podman-export(1)](podman-export.1.md) | Export a container's filesystem contents as a tar archive. |
|
| export | [podman-export(1)](podman-export.1.md) | Export a container's filesystem contents as a tar archive. |
|
||||||
| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a container or image's configuration. |
|
| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a container or image's configuration. |
|
||||||
| kill | [podman-kill(1)](podman-kill.1.md) | Kill the main process in one or more containers. |
|
| kill | [podman-kill(1)](podman-kill.1.md) | Kill the main process in one or more containers. |
|
||||||
|
40
docs/podman-image-exists.1.md
Normal file
40
docs/podman-image-exists.1.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
% PODMAN(1) Podman Man Pages
|
||||||
|
% Brent Baude
|
||||||
|
% November 2018
|
||||||
|
# NAME
|
||||||
|
podman-image-exists- Check if an image exists in local storage
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
**podman image exists**
|
||||||
|
[**-h**|**--help**]
|
||||||
|
IMAGE
|
||||||
|
|
||||||
|
# DESCRIPTION
|
||||||
|
**podman image exists** checks if an image exists in local storage. The **ID** or **Name**
|
||||||
|
of the image may be used as input. Podman will return an exit code
|
||||||
|
of `0` when the image is found. A `1` will be returned otherwise. An exit code of `125` indicates there
|
||||||
|
was an issue accessing the local storage.
|
||||||
|
|
||||||
|
## Examples ##
|
||||||
|
|
||||||
|
Check if an image called `webclient` exists in local storage (the image does actually exist).
|
||||||
|
```
|
||||||
|
$ sudo podman image exists webclient
|
||||||
|
$ echo $?
|
||||||
|
0
|
||||||
|
$
|
||||||
|
```
|
||||||
|
|
||||||
|
Check if an image called `webbackend` exists in local storage (the image does not actually exist).
|
||||||
|
```
|
||||||
|
$ sudo podman image exists webbackend
|
||||||
|
$ echo $?
|
||||||
|
1
|
||||||
|
$
|
||||||
|
```
|
||||||
|
|
||||||
|
## SEE ALSO
|
||||||
|
podman(1)
|
||||||
|
|
||||||
|
# HISTORY
|
||||||
|
November 2018, Originally compiled by Brent Baude (bbaude at redhat dot com)
|
@ -14,6 +14,7 @@ The image command allows you to manage images
|
|||||||
| Command | Man Page | Description |
|
| Command | Man Page | Description |
|
||||||
| -------- | ----------------------------------------- | ------------------------------------------------------------------------------ |
|
| -------- | ----------------------------------------- | ------------------------------------------------------------------------------ |
|
||||||
| build | [podman-build(1)](podman-build.1.md) | Build a container using a Dockerfile. |
|
| build | [podman-build(1)](podman-build.1.md) | Build a container using a Dockerfile. |
|
||||||
|
| exists | [podman-exists(1)](podman-image-exists.1.md) | Check if a image exists in local storage |
|
||||||
| history | [podman-history(1)](podman-history.1.md) | Show the history of an image. |
|
| history | [podman-history(1)](podman-history.1.md) | Show the history of an image. |
|
||||||
| import | [podman-import(1)](podman-import.1.md) | Import a tarball and save it as a filesystem image. |
|
| import | [podman-import(1)](podman-import.1.md) | Import a tarball and save it as a filesystem image. |
|
||||||
| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a image or image's configuration. |
|
| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a image or image's configuration. |
|
||||||
|
15
libpod/image/errors.go
Normal file
15
libpod/image/errors.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package image
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Copied directly from libpod errors to avoid circular imports
|
||||||
|
var (
|
||||||
|
// ErrNoSuchCtr indicates the requested container does not exist
|
||||||
|
ErrNoSuchCtr = errors.New("no such container")
|
||||||
|
// ErrNoSuchPod indicates the requested pod does not exist
|
||||||
|
ErrNoSuchPod = errors.New("no such pod")
|
||||||
|
// ErrNoSuchImage indicates the requested image does not exist
|
||||||
|
ErrNoSuchImage = errors.New("no such image")
|
||||||
|
)
|
@ -252,7 +252,7 @@ func (i *Image) getLocalImage() (*storage.Image, error) {
|
|||||||
// The image has a registry name in it and we made sure we looked for it locally
|
// The image has a registry name in it and we made sure we looked for it locally
|
||||||
// with a tag. It cannot be local.
|
// with a tag. It cannot be local.
|
||||||
if decomposedImage.hasRegistry {
|
if decomposedImage.hasRegistry {
|
||||||
return nil, errors.Errorf("%s", imageError)
|
return nil, errors.Wrapf(ErrNoSuchImage, imageError)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ func (i *Image) getLocalImage() (*storage.Image, error) {
|
|||||||
return repoImage, nil
|
return repoImage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.Wrapf(err, imageError)
|
return nil, errors.Wrapf(ErrNoSuchImage, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns the image ID as a string
|
// ID returns the image ID as a string
|
||||||
|
85
test/e2e/exists_test.go
Normal file
85
test/e2e/exists_test.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
. "github.com/containers/libpod/test/utils"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Podman image|container exists", func() {
|
||||||
|
var (
|
||||||
|
tempdir string
|
||||||
|
err error
|
||||||
|
podmanTest *PodmanTestIntegration
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
tempdir, err = CreateTempDirInTempDir()
|
||||||
|
if err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
podmanTest = PodmanTestCreate(tempdir)
|
||||||
|
podmanTest.RestoreAllArtifacts()
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
podmanTest.Cleanup()
|
||||||
|
f := CurrentGinkgoTestDescription()
|
||||||
|
timedResult := fmt.Sprintf("Test: %s completed in %f seconds", f.TestText, f.Duration.Seconds())
|
||||||
|
GinkgoWriter.Write([]byte(timedResult))
|
||||||
|
|
||||||
|
})
|
||||||
|
It("podman image exists in local storage by fq name", func() {
|
||||||
|
session := podmanTest.Podman([]string{"image", "exists", ALPINE})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
})
|
||||||
|
It("podman image exists in local storage by short name", func() {
|
||||||
|
session := podmanTest.Podman([]string{"image", "exists", "alpine"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
})
|
||||||
|
It("podman image does not exist in local storage", func() {
|
||||||
|
session := podmanTest.Podman([]string{"image", "exists", "alpine9999"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
|
})
|
||||||
|
It("podman container exists in local storage by name", func() {
|
||||||
|
setup := podmanTest.RunTopContainer("foobar")
|
||||||
|
setup.WaitWithDefaultTimeout()
|
||||||
|
Expect(setup.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
session := podmanTest.Podman([]string{"container", "exists", "foobar"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
})
|
||||||
|
It("podman container exists in local storage by container ID", func() {
|
||||||
|
setup := podmanTest.RunTopContainer("")
|
||||||
|
setup.WaitWithDefaultTimeout()
|
||||||
|
Expect(setup.ExitCode()).To(Equal(0))
|
||||||
|
cid := setup.OutputToString()
|
||||||
|
|
||||||
|
session := podmanTest.Podman([]string{"container", "exists", cid})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
})
|
||||||
|
It("podman container exists in local storage by short container ID", func() {
|
||||||
|
setup := podmanTest.RunTopContainer("")
|
||||||
|
setup.WaitWithDefaultTimeout()
|
||||||
|
Expect(setup.ExitCode()).To(Equal(0))
|
||||||
|
cid := setup.OutputToString()[0:12]
|
||||||
|
|
||||||
|
session := podmanTest.Podman([]string{"container", "exists", cid})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
})
|
||||||
|
It("podman container does not exist in local storage", func() {
|
||||||
|
session := podmanTest.Podman([]string{"container", "exists", "foobar"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
Reference in New Issue
Block a user