summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/specgen.go20
-rw-r--r--cmd/podman/containers/create.go48
-rw-r--r--cmd/podman/containers/run.go9
-rw-r--r--cmd/podman/healthcheck/run.go13
-rw-r--r--cmd/podman/images/tag.go22
-rw-r--r--cmd/podman/images/untag.go22
-rw-r--r--cmd/podman/manifest/inspect.go13
-rw-r--r--cmd/podman/manifest/remove.go13
-rw-r--r--cmd/podman/system/renumber.go11
-rw-r--r--cmd/podman/system/unshare.go9
-rw-r--r--docs/source/markdown/podman-auto-update.1.md2
-rw-r--r--docs/source/markdown/podman-container-exists.1.md2
-rw-r--r--docs/source/markdown/podman-healthcheck-run.1.md2
-rw-r--r--docs/source/markdown/podman-image-exists.1.md2
-rw-r--r--docs/source/markdown/podman-manifest-add.1.md2
-rw-r--r--docs/source/markdown/podman-manifest-annotate.1.md2
-rw-r--r--docs/source/markdown/podman-manifest-push.1.md2
-rw-r--r--docs/source/markdown/podman-mount.1.md4
-rw-r--r--docs/source/markdown/podman-network-inspect.1.md2
-rw-r--r--docs/source/markdown/podman-network-rm.1.md2
-rw-r--r--docs/source/markdown/podman-pod-prune.1.md2
-rw-r--r--docs/source/markdown/podman-rmi.1.md4
-rw-r--r--docs/source/markdown/podman-system-migrate.1.md2
-rw-r--r--docs/source/markdown/podman-system-reset.1.md2
-rw-r--r--docs/source/markdown/podman-umount.1.md8
-rw-r--r--docs/source/markdown/podman-unshare.1.md2
-rw-r--r--docs/source/markdown/podman-untag.1.md4
-rw-r--r--go.mod2
-rw-r--r--go.sum2
-rwxr-xr-xhack/man-page-checker72
-rw-r--r--libpod/runtime_ctr.go4
-rw-r--r--pkg/api/handlers/compat/exec.go3
-rw-r--r--pkg/specgen/generate/container_create.go3
-rw-r--r--pkg/specgen/specgen.go2
-rw-r--r--pkg/systemd/generate/containers.go2
-rw-r--r--pkg/systemd/generate/containers_test.go2
-rw-r--r--pkg/util/utils.go6
-rw-r--r--test/e2e/create_test.go13
-rw-r--r--test/python/dockerpy/README.md40
-rw-r--r--test/python/dockerpy/__init__.py (renamed from test/test_dockerpy/__init__.py)0
-rw-r--r--test/python/dockerpy/tests/__init__.py0
-rw-r--r--test/python/dockerpy/tests/common.py105
-rw-r--r--test/python/dockerpy/tests/constant.py13
-rw-r--r--test/python/dockerpy/tests/test_containers.py (renamed from test/test_dockerpy/test_containers.py)43
-rw-r--r--test/python/dockerpy/tests/test_images.py (renamed from test/test_dockerpy/test_images.py)84
-rw-r--r--test/python/dockerpy/tests/test_info_version.py (renamed from test/test_dockerpy/test_info_version.py)12
-rw-r--r--test/system/015-help.bats18
-rw-r--r--test/system/030-run.bats41
-rw-r--r--test/test_dockerpy/README.md30
-rw-r--r--test/test_dockerpy/common.py85
-rw-r--r--test/test_dockerpy/constant.py13
-rw-r--r--vendor/github.com/containers/common/pkg/apparmor/apparmor.go6
-rw-r--r--vendor/github.com/containers/common/pkg/apparmor/apparmor_linux.go9
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go6
-rw-r--r--vendor/github.com/containers/common/version/version.go4
-rw-r--r--vendor/modules.txt3
56 files changed, 515 insertions, 334 deletions
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 599e003e8..1f6fbbe98 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -520,7 +520,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
case "label":
// TODO selinux opts and label opts are the same thing
s.ContainerSecurityConfig.SelinuxOpts = append(s.ContainerSecurityConfig.SelinuxOpts, con[1])
- s.Annotations[define.InspectAnnotationLabel] = con[1]
+ s.Annotations[define.InspectAnnotationLabel] = strings.Join(s.ContainerSecurityConfig.SelinuxOpts, ",label=")
case "apparmor":
s.ContainerSecurityConfig.ApparmorProfile = con[1]
s.Annotations[define.InspectAnnotationApparmor] = con[1]
@@ -535,7 +535,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.SeccompPolicy = c.SeccompPolicy
- // TODO: should parse out options
s.VolumesFrom = c.VolumesFrom
// Only add read-only tmpfs mounts in case that we are read-only and the
@@ -547,22 +546,10 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.Mounts = mounts
s.Volumes = volumes
- // TODO any idea why this was done
- // devices := rtc.Containers.Devices
- // TODO conflict on populate?
- //
- // if c.Changed("device") {
- // devices = append(devices, c.StringSlice("device")...)
- // }
-
for _, dev := range c.Devices {
s.Devices = append(s.Devices, specs.LinuxDevice{Path: dev})
}
- // TODO things i cannot find in spec
- // we dont think these are in the spec
- // init - initbinary
- // initpath
s.Init = c.Init
s.InitPath = c.InitPath
s.Stdin = c.Interactive
@@ -587,11 +574,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.Rlimits = append(s.Rlimits, rl)
}
- // Tmpfs: c.StringArray("tmpfs"),
-
- // TODO how to handle this?
- // Syslog: c.Bool("syslog"),
-
logOpts := make(map[string]string)
for _, o := range c.LogOptions {
split := strings.SplitN(o, "=", 2)
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 45ce00c86..c48a739ff 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -6,11 +6,12 @@ import (
"os"
"strings"
- "github.com/containers/libpod/libpod/define"
-
"github.com/containers/common/pkg/config"
+ "github.com/containers/image/v5/storage"
+ "github.com/containers/image/v5/transports/alltransports"
"github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/registry"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/errorhandling"
"github.com/containers/libpod/pkg/specgen"
@@ -108,12 +109,15 @@ func create(cmd *cobra.Command, args []string) error {
return err
}
+ imageName := args[0]
if !cliVals.RootFS {
- if err := pullImage(args[0]); err != nil {
+ name, err := pullImage(args[0])
+ if err != nil {
return err
}
+ imageName = name
}
- s := specgen.NewSpecGenerator(args[0], cliVals.RootFS)
+ s := specgen.NewSpecGenerator(imageName, cliVals.RootFS)
if err := common.FillOutSpecGen(s, &cliVals, args); err != nil {
return err
}
@@ -211,30 +215,44 @@ func createInit(c *cobra.Command) error {
return nil
}
-func pullImage(imageName string) error {
- br, err := registry.ImageEngine().Exists(registry.GetContext(), imageName)
- if err != nil {
- return err
- }
+func pullImage(imageName string) (string, error) {
pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull)
if err != nil {
- return err
+ return "", err
}
- if !br.Value || pullPolicy == config.PullImageAlways {
+
+ // Check if the image is missing and hence if we need to pull it.
+ imageMissing := true
+ imageRef, err := alltransports.ParseImageName(imageName)
+ switch {
+ case err != nil:
+ // Assume we specified a local image withouth the explicit storage transport.
+ fallthrough
+
+ case imageRef.Transport().Name() == storage.Transport.Name():
+ br, err := registry.ImageEngine().Exists(registry.GetContext(), imageName)
+ if err != nil {
+ return "", err
+ }
+ imageMissing = !br.Value
+ }
+
+ if imageMissing || pullPolicy == config.PullImageAlways {
if pullPolicy == config.PullImageNever {
- return errors.Wrapf(define.ErrNoSuchImage, "unable to find a name and tag match for %s in repotags", imageName)
+ return "", errors.Wrapf(define.ErrNoSuchImage, "unable to find a name and tag match for %s in repotags", imageName)
}
- _, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
+ pullReport, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
Authfile: cliVals.Authfile,
Quiet: cliVals.Quiet,
OverrideArch: cliVals.OverrideArch,
OverrideOS: cliVals.OverrideOS,
})
if pullErr != nil {
- return pullErr
+ return "", pullErr
}
+ imageName = pullReport.Images[0]
}
- return nil
+ return imageName, nil
}
func openCidFile(cidfile string) (*os.File, error) {
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go
index cb307c38f..4b287838e 100644
--- a/cmd/podman/containers/run.go
+++ b/cmd/podman/containers/run.go
@@ -125,10 +125,13 @@ func run(cmd *cobra.Command, args []string) error {
return err
}
+ imageName := args[0]
if !cliVals.RootFS {
- if err := pullImage(args[0]); err != nil {
+ name, err := pullImage(args[0])
+ if err != nil {
return err
}
+ imageName = name
}
if cliVals.Replace {
@@ -166,7 +169,7 @@ func run(cmd *cobra.Command, args []string) error {
runOpts.Detach = cliVals.Detach
runOpts.DetachKeys = cliVals.DetachKeys
cliVals.PreserveFDs = runOpts.PreserveFDs
- s := specgen.NewSpecGenerator(args[0], cliVals.RootFS)
+ s := specgen.NewSpecGenerator(imageName, cliVals.RootFS)
if err := common.FillOutSpecGen(s, &cliVals, args); err != nil {
return err
}
@@ -196,7 +199,7 @@ func run(cmd *cobra.Command, args []string) error {
return nil
}
if runRmi {
- _, rmErrors := registry.ImageEngine().Remove(registry.GetContext(), []string{args[0]}, entities.ImageRemoveOptions{})
+ _, rmErrors := registry.ImageEngine().Remove(registry.GetContext(), []string{imageName}, entities.ImageRemoveOptions{})
if len(rmErrors) > 0 {
logrus.Errorf("%s", errors.Wrapf(errorhandling.JoinErrors(rmErrors), "failed removing image"))
}
diff --git a/cmd/podman/healthcheck/run.go b/cmd/podman/healthcheck/run.go
index 5612910cb..17ddf17b6 100644
--- a/cmd/podman/healthcheck/run.go
+++ b/cmd/podman/healthcheck/run.go
@@ -12,12 +12,13 @@ import (
var (
healthcheckRunDescription = "run the health check of a container"
healthcheckrunCommand = &cobra.Command{
- Use: "run [flags] CONTAINER",
- Short: "run the health check of a container",
- Long: healthcheckRunDescription,
- Example: `podman healthcheck run mywebapp`,
- RunE: run,
- Args: cobra.ExactArgs(1),
+ Use: "run CONTAINER",
+ Short: "run the health check of a container",
+ Long: healthcheckRunDescription,
+ Example: `podman healthcheck run mywebapp`,
+ RunE: run,
+ Args: cobra.ExactArgs(1),
+ DisableFlagsInUseLine: true,
}
)
diff --git a/cmd/podman/images/tag.go b/cmd/podman/images/tag.go
index dae3416c4..859489552 100644
--- a/cmd/podman/images/tag.go
+++ b/cmd/podman/images/tag.go
@@ -9,22 +9,24 @@ import (
var (
tagDescription = "Adds one or more additional names to locally-stored image."
tagCommand = &cobra.Command{
- Use: "tag [flags] IMAGE TARGET_NAME [TARGET_NAME...]",
- Short: "Add an additional name to a local image",
- Long: tagDescription,
- RunE: tag,
- Args: cobra.MinimumNArgs(2),
+ Use: "tag IMAGE TARGET_NAME [TARGET_NAME...]",
+ Short: "Add an additional name to a local image",
+ Long: tagDescription,
+ RunE: tag,
+ Args: cobra.MinimumNArgs(2),
+ DisableFlagsInUseLine: true,
Example: `podman tag 0e3bbc2 fedora:latest
podman tag imageID:latest myNewImage:newTag
podman tag httpd myregistryhost:5000/fedora/httpd:v2`,
}
imageTagCommand = &cobra.Command{
- Args: tagCommand.Args,
- Use: tagCommand.Use,
- Short: tagCommand.Short,
- Long: tagCommand.Long,
- RunE: tagCommand.RunE,
+ Args: tagCommand.Args,
+ DisableFlagsInUseLine: true,
+ Use: tagCommand.Use,
+ Short: tagCommand.Short,
+ Long: tagCommand.Long,
+ RunE: tagCommand.RunE,
Example: `podman image tag 0e3bbc2 fedora:latest
podman image tag imageID:latest myNewImage:newTag
podman image tag httpd myregistryhost:5000/fedora/httpd:v2`,
diff --git a/cmd/podman/images/untag.go b/cmd/podman/images/untag.go
index 266a3f115..5d1274895 100644
--- a/cmd/podman/images/untag.go
+++ b/cmd/podman/images/untag.go
@@ -8,22 +8,24 @@ import (
var (
untagCommand = &cobra.Command{
- Use: "untag [flags] IMAGE [NAME...]",
- Short: "Remove a name from a local image",
- Long: "Removes one or more names from a locally-stored image.",
- RunE: untag,
- Args: cobra.MinimumNArgs(1),
+ Use: "untag IMAGE [NAME...]",
+ Short: "Remove a name from a local image",
+ Long: "Removes one or more names from a locally-stored image.",
+ RunE: untag,
+ Args: cobra.MinimumNArgs(1),
+ DisableFlagsInUseLine: true,
Example: `podman untag 0e3bbc2
podman untag imageID:latest otherImageName:latest
podman untag httpd myregistryhost:5000/fedora/httpd:v2`,
}
imageUntagCommand = &cobra.Command{
- Args: untagCommand.Args,
- Use: untagCommand.Use,
- Short: untagCommand.Short,
- Long: untagCommand.Long,
- RunE: untagCommand.RunE,
+ Args: untagCommand.Args,
+ DisableFlagsInUseLine: true,
+ Use: untagCommand.Use,
+ Short: untagCommand.Short,
+ Long: untagCommand.Long,
+ RunE: untagCommand.RunE,
Example: `podman image untag 0e3bbc2
podman image untag imageID:latest otherImageName:latest
podman image untag httpd myregistryhost:5000/fedora/httpd:v2`,
diff --git a/cmd/podman/manifest/inspect.go b/cmd/podman/manifest/inspect.go
index 5112aa5b2..861f4be4f 100644
--- a/cmd/podman/manifest/inspect.go
+++ b/cmd/podman/manifest/inspect.go
@@ -12,12 +12,13 @@ import (
var (
inspectCmd = &cobra.Command{
- Use: "inspect [flags] IMAGE",
- Short: "Display the contents of a manifest list or image index",
- Long: "Display the contents of a manifest list or image index.",
- RunE: inspect,
- Example: "podman manifest inspect localhost/list",
- Args: cobra.ExactArgs(1),
+ Use: "inspect IMAGE",
+ Short: "Display the contents of a manifest list or image index",
+ Long: "Display the contents of a manifest list or image index.",
+ RunE: inspect,
+ Example: "podman manifest inspect localhost/list",
+ Args: cobra.ExactArgs(1),
+ DisableFlagsInUseLine: true,
}
)
diff --git a/cmd/podman/manifest/remove.go b/cmd/podman/manifest/remove.go
index 4d345efc0..815a3f0a8 100644
--- a/cmd/podman/manifest/remove.go
+++ b/cmd/podman/manifest/remove.go
@@ -12,12 +12,13 @@ import (
var (
removeCmd = &cobra.Command{
- Use: "remove [flags] LIST IMAGE",
- Short: "Remove an entry from a manifest list or image index",
- Long: "Removes an image from a manifest list or image index.",
- RunE: remove,
- Example: `podman manifest remove mylist:v1.11 sha256:15352d97781ffdf357bf3459c037be3efac4133dc9070c2dce7eca7c05c3e736`,
- Args: cobra.ExactArgs(2),
+ Use: "remove LIST IMAGE",
+ Short: "Remove an entry from a manifest list or image index",
+ Long: "Removes an image from a manifest list or image index.",
+ RunE: remove,
+ Example: `podman manifest remove mylist:v1.11 sha256:15352d97781ffdf357bf3459c037be3efac4133dc9070c2dce7eca7c05c3e736`,
+ Args: cobra.ExactArgs(2),
+ DisableFlagsInUseLine: true,
}
)
diff --git a/cmd/podman/system/renumber.go b/cmd/podman/system/renumber.go
index b90640de3..39cd15dd7 100644
--- a/cmd/podman/system/renumber.go
+++ b/cmd/podman/system/renumber.go
@@ -22,11 +22,12 @@ var (
`
renumberCommand = &cobra.Command{
- Use: "renumber",
- Args: validate.NoArgs,
- Short: "Migrate lock numbers",
- Long: renumberDescription,
- Run: renumber,
+ Use: "renumber",
+ Args: validate.NoArgs,
+ DisableFlagsInUseLine: true,
+ Short: "Migrate lock numbers",
+ Long: renumberDescription,
+ Run: renumber,
}
)
diff --git a/cmd/podman/system/unshare.go b/cmd/podman/system/unshare.go
index e5d41e06d..109bab9ed 100644
--- a/cmd/podman/system/unshare.go
+++ b/cmd/podman/system/unshare.go
@@ -13,10 +13,11 @@ import (
var (
unshareDescription = "Runs a command in a modified user namespace."
unshareCommand = &cobra.Command{
- Use: "unshare [flags] [COMMAND [ARG ...]]",
- Short: "Run a command in a modified user namespace",
- Long: unshareDescription,
- RunE: unshare,
+ Use: "unshare [COMMAND [ARG ...]]",
+ DisableFlagsInUseLine: true,
+ Short: "Run a command in a modified user namespace",
+ Long: unshareDescription,
+ RunE: unshare,
Example: `podman unshare id
podman unshare cat /proc/self/uid_map,
podman unshare podman-script.sh`,
diff --git a/docs/source/markdown/podman-auto-update.1.md b/docs/source/markdown/podman-auto-update.1.md
index 90e581e42..f37280cda 100644
--- a/docs/source/markdown/podman-auto-update.1.md
+++ b/docs/source/markdown/podman-auto-update.1.md
@@ -4,7 +4,7 @@
podman-auto-update - Auto update containers according to their auto-update policy
## SYNOPSIS
-**podman auto-update**
+**podman auto-update** [*options*]
## DESCRIPTION
`podman auto-update` looks up containers with a specified "io.containers.autoupdate" label (i.e., the auto-update policy).
diff --git a/docs/source/markdown/podman-container-exists.1.md b/docs/source/markdown/podman-container-exists.1.md
index 3b4ca33e4..d24df2fc8 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** [*options*] *container*
+**podman container exists** *container*
## DESCRIPTION
**podman container exists** checks if a container exists in local storage. The **ID** or **Name**
diff --git a/docs/source/markdown/podman-healthcheck-run.1.md b/docs/source/markdown/podman-healthcheck-run.1.md
index 21f2d9b20..546d847eb 100644
--- a/docs/source/markdown/podman-healthcheck-run.1.md
+++ b/docs/source/markdown/podman-healthcheck-run.1.md
@@ -4,7 +4,7 @@
podman\-healthcheck\-run - Run a container healthcheck
## SYNOPSIS
-**podman healthcheck run** [*options*] *container*
+**podman healthcheck run** *container*
## DESCRIPTION
diff --git a/docs/source/markdown/podman-image-exists.1.md b/docs/source/markdown/podman-image-exists.1.md
index 3b7127b64..59f2145cc 100644
--- a/docs/source/markdown/podman-image-exists.1.md
+++ b/docs/source/markdown/podman-image-exists.1.md
@@ -4,7 +4,7 @@
podman-image-exists - Check if an image exists in local storage
## SYNOPSIS
-**podman image exists** [*options*] *image*
+**podman image exists** *image*
## DESCRIPTION
**podman image exists** checks if an image exists in local storage. The **ID** or **Name**
diff --git a/docs/source/markdown/podman-manifest-add.1.md b/docs/source/markdown/podman-manifest-add.1.md
index 82f2071b9..44815def5 100644
--- a/docs/source/markdown/podman-manifest-add.1.md
+++ b/docs/source/markdown/podman-manifest-add.1.md
@@ -4,7 +4,7 @@
podman\-manifest\-add - Add an image to a manifest list or image index
## SYNOPSIS
-**podman manifest add** *listnameorindexname* *imagename*
+**podman manifest add** [*options*] *listnameorindexname* *imagename*
## DESCRIPTION
diff --git a/docs/source/markdown/podman-manifest-annotate.1.md b/docs/source/markdown/podman-manifest-annotate.1.md
index 4450de7fd..25ad4642e 100644
--- a/docs/source/markdown/podman-manifest-annotate.1.md
+++ b/docs/source/markdown/podman-manifest-annotate.1.md
@@ -4,7 +4,7 @@
podman\-manifest\-annotate - Add or update information about an entry in a manifest list or image index
## SYNOPSIS
-**podman manifest annotate** [options...] *listnameorindexname* *imagemanifestdigest*
+**podman manifest annotate** [*options*] *listnameorindexname* *imagemanifestdigest*
## DESCRIPTION
diff --git a/docs/source/markdown/podman-manifest-push.1.md b/docs/source/markdown/podman-manifest-push.1.md
index ab3287a7c..33b2a24c5 100644
--- a/docs/source/markdown/podman-manifest-push.1.md
+++ b/docs/source/markdown/podman-manifest-push.1.md
@@ -4,7 +4,7 @@
podman\-manifest\-push - Push a manifest list or image index to a registry
## SYNOPSIS
-**podman manifest push** [options...] *listnameorindexname* *transport:details*
+**podman manifest push** [*options*] *listnameorindexname* *transport:details*
## DESCRIPTION
Pushes a manifest list or image index to a registry.
diff --git a/docs/source/markdown/podman-mount.1.md b/docs/source/markdown/podman-mount.1.md
index c7bfedb48..eaed1051e 100644
--- a/docs/source/markdown/podman-mount.1.md
+++ b/docs/source/markdown/podman-mount.1.md
@@ -4,9 +4,9 @@
podman\-mount - Mount a working container's root filesystem
## SYNOPSIS
-**podman mount** [*container* ...]
+**podman mount** [*options*] [*container* ...]
-**podman container mount** [*container* ...]
+**podman container mount** [*options*] [*container* ...]
## DESCRIPTION
Mounts the specified containers' root file system in a location which can be
diff --git a/docs/source/markdown/podman-network-inspect.1.md b/docs/source/markdown/podman-network-inspect.1.md
index 86fa2552e..c75c6788a 100644
--- a/docs/source/markdown/podman-network-inspect.1.md
+++ b/docs/source/markdown/podman-network-inspect.1.md
@@ -4,7 +4,7 @@
podman\-network\-inspect - Displays the raw CNI network configuration for one or more networks
## SYNOPSIS
-**podman network inspect** [*network* ...]
+**podman network inspect** [*options*] [*network* ...]
## DESCRIPTION
Display the raw (JSON format) network configuration. This command is not available for rootless users.
diff --git a/docs/source/markdown/podman-network-rm.1.md b/docs/source/markdown/podman-network-rm.1.md
index c71f0d8fd..9ce4d1cd8 100644
--- a/docs/source/markdown/podman-network-rm.1.md
+++ b/docs/source/markdown/podman-network-rm.1.md
@@ -4,7 +4,7 @@
podman\-network\-rm - Remove one or more CNI networks
## SYNOPSIS
-**podman network rm** [*network...*]
+**podman network rm** [*options*] [*network...*]
## DESCRIPTION
Delete one or more Podman networks.
diff --git a/docs/source/markdown/podman-pod-prune.1.md b/docs/source/markdown/podman-pod-prune.1.md
index 5b74adade..5b4c4661c 100644
--- a/docs/source/markdown/podman-pod-prune.1.md
+++ b/docs/source/markdown/podman-pod-prune.1.md
@@ -4,7 +4,7 @@
podman-pod-prune - Remove all stopped pods and their containers
## SYNOPSIS
-**podman pod prune**
+**podman pod prune** [*options*]
## DESCRIPTION
**podman pod prune** removes all stopped pods and their containers from local storage.
diff --git a/docs/source/markdown/podman-rmi.1.md b/docs/source/markdown/podman-rmi.1.md
index 2e093e9c8..58280e831 100644
--- a/docs/source/markdown/podman-rmi.1.md
+++ b/docs/source/markdown/podman-rmi.1.md
@@ -4,9 +4,9 @@
podman\-rmi - Removes one or more locally stored images
## SYNOPSIS
-**podman rmi** *image* [...]
+**podman rmi** [*options*] *image* [...]
-**podman image rm** *image* [...]
+**podman image rm** [*options*] *image* [...]
## DESCRIPTION
Removes one or more locally stored images.
diff --git a/docs/source/markdown/podman-system-migrate.1.md b/docs/source/markdown/podman-system-migrate.1.md
index 28db56dee..baabfd14b 100644
--- a/docs/source/markdown/podman-system-migrate.1.md
+++ b/docs/source/markdown/podman-system-migrate.1.md
@@ -4,7 +4,7 @@
podman\-system\-migrate - Migrate existing containers to a new podman version
## SYNOPSIS
-**podman system migrate**
+**podman system migrate** [*options*]
## DESCRIPTION
**podman system migrate** migrates containers to the latest podman version.
diff --git a/docs/source/markdown/podman-system-reset.1.md b/docs/source/markdown/podman-system-reset.1.md
index 432f275f4..f290e26d5 100644
--- a/docs/source/markdown/podman-system-reset.1.md
+++ b/docs/source/markdown/podman-system-reset.1.md
@@ -4,7 +4,7 @@
podman\-system\-reset - Reset storage back to initial state
## SYNOPSIS
-**podman system reset**
+**podman system reset** [*options*]
## DESCRIPTION
**podman system reset** removes all pods, containers, images and volumes.
diff --git a/docs/source/markdown/podman-umount.1.md b/docs/source/markdown/podman-umount.1.md
index 100c47b32..31a213f28 100644
--- a/docs/source/markdown/podman-umount.1.md
+++ b/docs/source/markdown/podman-umount.1.md
@@ -4,13 +4,13 @@
podman\-umount - Unmount a working container's root filesystem
## SYNOPSIS
-**podman umount** *container* [...]
+**podman umount** [*options*] *container* [...]
-**podman container umount** *container* [...]
+**podman container umount** [*options*] *container* [...]
-**podman container unmount** *container* [...]
+**podman container unmount** [*options*] *container* [...]
-**podman unmount** *container* [...]
+**podman unmount** [*options*] *container* [...]
## DESCRIPTION
Unmounts the specified containers' root file system, if no other processes
diff --git a/docs/source/markdown/podman-unshare.1.md b/docs/source/markdown/podman-unshare.1.md
index f2eb02814..239213981 100644
--- a/docs/source/markdown/podman-unshare.1.md
+++ b/docs/source/markdown/podman-unshare.1.md
@@ -4,7 +4,7 @@
podman\-unshare - Run a command inside of a modified user namespace
## SYNOPSIS
-**podman unshare** [*options*] [*--*] [*command*]
+**podman unshare** [*--*] [*command*]
## DESCRIPTION
Launches a process (by default, *$SHELL*) in a new user namespace. The user
diff --git a/docs/source/markdown/podman-untag.1.md b/docs/source/markdown/podman-untag.1.md
index c83a0544c..d6ed7f3ea 100644
--- a/docs/source/markdown/podman-untag.1.md
+++ b/docs/source/markdown/podman-untag.1.md
@@ -4,9 +4,9 @@
podman\-untag - Removes one or more names from a locally-stored image
## SYNOPSIS
-**podman untag** [*options*] *image* [*name*[:*tag*]...]
+**podman untag** *image* [*name*[:*tag*]...]
-**podman image untag** [*options*] *image* [*name*[:*tag*]...]
+**podman image untag** *image* [*name*[:*tag*]...]
## DESCRIPTION
Remove one or more names from an image in the local storage. The image can be referred to by ID or reference. If a no name is specified, all names are removed the image. If a specified name is a short name and does not include a registry `localhost/` will be prefixed (e.g., `fedora` -> `localhost/fedora`). If a specified name does not include a tag `:latest` will be appended (e.g., `localhost/fedora` -> `localhost/fedora:latest`).
diff --git a/go.mod b/go.mod
index d02dfa0b4..64981efc1 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921
github.com/containernetworking/plugins v0.8.6
github.com/containers/buildah v1.15.0
- github.com/containers/common v0.14.0
+ github.com/containers/common v0.14.3
github.com/containers/conmon v2.0.18+incompatible
github.com/containers/image/v5 v5.5.1
github.com/containers/psgo v1.5.1
diff --git a/go.sum b/go.sum
index fdc506fac..e069825da 100644
--- a/go.sum
+++ b/go.sum
@@ -70,6 +70,8 @@ github.com/containers/buildah v1.15.0 h1:p9cYJwcQ5Fnv0iBeHAFwHR0K+kcv7LbyAjUtc+H
github.com/containers/buildah v1.15.0/go.mod h1:j0AY2kWpmaOPPV5GKDJY9dMtekk5WMmMhcB+z0OW+vc=
github.com/containers/common v0.14.0 h1:hiZFDPf6ajKiDmojN5f5X3gboKPO73NLrYb0RXfrQiA=
github.com/containers/common v0.14.0/go.mod h1:9olhlE+WhYof1npnMJdyRMX14/yIUint6zyHzcyRVAg=
+github.com/containers/common v0.14.3 h1:LNsRPkap5Q/EqPyhiLKRZg8u629U8CEeoB49ilG6ZR4=
+github.com/containers/common v0.14.3/go.mod h1:9olhlE+WhYof1npnMJdyRMX14/yIUint6zyHzcyRVAg=
github.com/containers/conmon v2.0.18+incompatible h1:rjwjNnE756NuXcdE/uUmj4kDbrykslPuBMHI31wh43E=
github.com/containers/conmon v2.0.18+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.4.4/go.mod h1:g7cxNXitiLi6pEr9/L9n/0wfazRuhDKXU15kV86N8h8=
diff --git a/hack/man-page-checker b/hack/man-page-checker
index 17d85d65d..d2cc6c6e1 100755
--- a/hack/man-page-checker
+++ b/hack/man-page-checker
@@ -3,6 +3,14 @@
# man-page-checker - validate and cross-reference man page names
#
+verbose=
+for i; do
+ case "$i" in
+ -v|--verbose) verbose=verbose ;;
+ esac
+done
+
+
die() {
echo "$(basename $0): $*" >&2
exit 1
@@ -65,6 +73,61 @@ for md in $(ls -1 *-*.1.md | grep -v remote);do
fi
done
+# Helper function: compares man page synopsis vs --help usage message
+function compare_usage() {
+ local cmd="$1"
+ local from_man="$2"
+
+ # Sometimes in CI we run before podman gets built.
+ test -x ../../../bin/podman || return
+
+ # Run 'cmd --help', grab the line immediately after 'Usage:'
+ local help_output=$(../../../bin/$cmd --help)
+ local from_help=$(echo "$help_output" | grep -A1 '^Usage:' | tail -1)
+
+ # strip off command name from both
+ from_man=$(sed -e "s/\*\*$cmd\*\*[[:space:]]*//" <<<"$from_man")
+ from_help=$(sed -e "s/^[[:space:]]*$cmd[[:space:]]*//" <<<"$from_help")
+
+ # man page lists 'foo [*options*]', help msg shows 'foo [flags]'.
+ # Make sure if one has it, the other does too.
+ if expr "$from_man" : "\[\*options\*\]" >/dev/null; then
+ if expr "$from_help" : "\[flags\]" >/dev/null; then
+ :
+ else
+ echo "WARNING: $cmd: man page shows '[*options*]', help does not show [flags]"
+ rc=1
+ fi
+ elif expr "$from_help" : "\[flags\]" >/dev/null; then
+ echo "WARNING: $cmd: --help shows [flags], man page does not show [*options*]"
+ rc=1
+ fi
+
+ # Strip off options and flags; start comparing arguments
+ from_man=$(sed -e 's/^\[\*options\*\][[:space:]]*//' <<<"$from_man")
+ from_help=$(sed -e 's/^\[flags\][[:space:]]*//' <<<"$from_help")
+
+ # Args in man page are '*foo*', in --help are 'FOO'. Convert all to
+ # UPCASE simply because it stands out better to the eye.
+ from_man=$(sed -e 's/\*\([a-z-]\+\)\*/\U\1/g' <<<"$from_man")
+
+ # FIXME: one of the common patterns is for --help to show 'POD [POD...]'
+ # but man page show 'pod ...'. This conversion may help one day, but
+ # not yet: there are too many inconsistencies such as '[pod ...]'
+ # (brackets) and 'pod...' (no space between).
+# from_help=$(sed -e 's/\([A-Z]\+\)[[:space:]]\+\[\1[[:space:]]*\.\.\.\]/\1 .../' <<<"$from_help")
+
+ # Compare man-page and --help usage strings. For now, do so only
+ # when run with --verbose.
+ if [[ "$from_man" != "$from_help" ]]; then
+ if [ -n "$verbose" ]; then
+ printf "%-25s man='%s' help='%s'\n" "$cmd:" "$from_man" "$from_help"
+ # Yeah, we're not going to enable this as a blocker any time soon.
+ # rc=1
+ fi
+ fi
+}
+
# Pass 3: compare synopses.
#
# Make sure the SYNOPSIS line in podman-foo.1.md reads '**podman foo** ...'
@@ -87,9 +150,7 @@ for md in *.1.md;do
cmd=$(echo "$synopsis" | sed -e 's/\(.*\)\*\*.*/\1/' | tr -d \*)
md_nodash=$(basename "$md" .1.md | tr '-' ' ')
if [[ $md_nodash = 'podman auto update' ]]; then
- # podman-auto-update.1.md is special cased as it's structure differs
- # from that of other man pages where main and sub-commands split by
- # dashes.
+ # special case: the command is "auto-update", with a hyphen
md_nodash='podman auto-update'
fi
if [ "$cmd" != "$md_nodash" -a "$cmd" != "podman-remote" ]; then
@@ -111,8 +172,9 @@ for md in *.1.md;do
# (for debugging, and getting a sense of standard conventions)
#printf " %-32s ------ '%s'\n" $md "$synopsis"
- # FIXME: some day: run ./bin/podman "args", extract Usage,
- # strip off [flags] and [options], then compare arguments
+ # If bin/podman is available, run "cmd --help" and compare Usage
+ # messages. This is complicated, so do it in a helper function.
+ compare_usage "$md_nodash" "$synopsis"
done
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 0431861b5..f1752cbeb 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -83,6 +83,8 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
return nil, errors.Wrapf(err, "converting containers.conf ShmSize %s to an int", r.config.Containers.ShmSize)
}
ctr.config.ShmSize = size
+ ctr.config.StopSignal = 15
+ ctr.config.StopTimeout = r.config.Engine.StopTimeout
} else {
// This is a restore from an imported checkpoint
ctr.restoreFromCheckpoint = true
@@ -107,8 +109,6 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
ctr.state.BindMounts = make(map[string]string)
- ctr.config.StopTimeout = r.config.Engine.StopTimeout
-
ctr.config.OCIRuntime = r.defaultOCIRuntime.Name()
// Set namespace based on current runtime namespace
diff --git a/pkg/api/handlers/compat/exec.go b/pkg/api/handlers/compat/exec.go
index 8f7016903..dae76c061 100644
--- a/pkg/api/handlers/compat/exec.go
+++ b/pkg/api/handlers/compat/exec.go
@@ -62,7 +62,8 @@ func ExecCreateHandler(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
- exitCommandArgs, err := generate.CreateExitCommandArgs(storageConfig, runtimeConfig, false, true, true)
+ // Automatically log to syslog if the server has log-level=debug set
+ exitCommandArgs, err := generate.CreateExitCommandArgs(storageConfig, runtimeConfig, logrus.IsLevelEnabled(logrus.DebugLevel), true, true)
if err != nil {
utils.InternalServerError(w, err)
return
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index ea6f938a8..7b4fbebf4 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -114,8 +114,7 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
}
options = append(options, opts...)
- // TODO: Enable syslog support - we'll need to put this in SpecGen.
- exitCommandArgs, err := CreateExitCommandArgs(rt.StorageConfig(), rtc, false, s.Remove, false)
+ exitCommandArgs, err := CreateExitCommandArgs(rt.StorageConfig(), rtc, logrus.IsLevelEnabled(logrus.DebugLevel), s.Remove, false)
if err != nil {
return nil, err
}
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 46ff8c716..3d5bf03e5 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -129,7 +129,7 @@ type ContainerBasicConfig struct {
Sysctl map[string]string `json:"sysctl,omitempty"`
// Remove indicates if the container should be removed once it has been started
// and exits
- Remove bool `json:"remove"`
+ Remove bool `json:"remove,omitempty"`
// PreserveFDs is a number of additional file descriptors (in addition
// to 0, 1, 2) that will be passed to the executed process. The total FDs
// passed will be 3 + PreserveFDs.
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index bf6cb81b8..333f8ef88 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -69,8 +69,6 @@ type containerInfo struct {
const containerTemplate = headerTemplate + `
{{- if .BoundToServices}}
-RefuseManualStart=yes
-RefuseManualStop=yes
BindsTo={{- range $index, $value := .BoundToServices -}}{{if $index}} {{end}}{{ $value }}.service{{end}}
After={{- range $index, $value := .BoundToServices -}}{{if $index}} {{end}}{{ $value }}.service{{end}}
{{- end}}
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index 80f0996a1..e108251ea 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -88,8 +88,6 @@ Description=Podman container-foobar.service
Documentation=man:podman-generate-systemd(1)
Wants=network.target
After=network-online.target
-RefuseManualStart=yes
-RefuseManualStop=yes
BindsTo=a.service b.service c.service pod.service
After=a.service b.service c.service pod.service
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 917f57742..1d8941b4d 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -419,12 +419,6 @@ func ParseIDMapping(mode namespaces.UsernsMode, uidMapSlice, gidMapSlice []strin
if len(uidMapSlice) == 0 && len(gidMapSlice) != 0 {
uidMapSlice = gidMapSlice
}
- if len(uidMapSlice) == 0 && subUIDMap == "" && os.Getuid() != 0 {
- uidMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getuid())}
- }
- if len(gidMapSlice) == 0 && subGIDMap == "" && os.Getuid() != 0 {
- gidMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getgid())}
- }
if subUIDMap != "" && subGIDMap != "" {
mappings, err := idtools.NewIDMappings(subUIDMap, subGIDMap)
diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go
index 52ce0b46a..44bb5c45f 100644
--- a/test/e2e/create_test.go
+++ b/test/e2e/create_test.go
@@ -458,4 +458,17 @@ var _ = Describe("Podman create", func() {
Expect(session.ExitCode()).To(Equal(0))
}
})
+
+ It("podman create sets default stop signal 15", func() {
+ ctrName := "testCtr"
+ session := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE, "/bin/sh"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"inspect", ctrName})
+ inspect.WaitWithDefaultTimeout()
+ data := inspect.InspectContainerToJSON()
+ Expect(len(data)).To(Equal(1))
+ Expect(data[0].Config.StopSignal).To(Equal(uint(15)))
+ })
})
diff --git a/test/python/dockerpy/README.md b/test/python/dockerpy/README.md
new file mode 100644
index 000000000..22908afc6
--- /dev/null
+++ b/test/python/dockerpy/README.md
@@ -0,0 +1,40 @@
+# Dockerpy regression test
+
+Python test suite to validate Podman endpoints using dockerpy library
+
+## Running Tests
+
+To run the tests locally in your sandbox (Fedora 32):
+
+```shell script
+# dnf install python3-docker
+```
+
+### Run the entire test suite
+
+```shell
+# cd test/python/dockerpy
+# PYTHONPATH=/usr/bin/python python -m unittest discover .
+```
+
+Passing the -v option to your test script will instruct unittest.main() to enable a higher level of verbosity, and produce detailed output:
+
+```shell
+# cd test/python/dockerpy
+# PYTHONPATH=/usr/bin/python python -m unittest -v discover .
+```
+
+### Run a specific test class
+
+```shell
+# cd test/python/dockerpy
+# PYTHONPATH=/usr/bin/python python -m unittest -v tests.test_images
+```
+
+### Run a specific test within the test class
+
+```shell
+# cd test/python/dockerpy
+# PYTHONPATH=/usr/bin/python python -m unittest tests.test_images.TestImages.test_import_image
+
+```
diff --git a/test/test_dockerpy/__init__.py b/test/python/dockerpy/__init__.py
index e69de29bb..e69de29bb 100644
--- a/test/test_dockerpy/__init__.py
+++ b/test/python/dockerpy/__init__.py
diff --git a/test/python/dockerpy/tests/__init__.py b/test/python/dockerpy/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/python/dockerpy/tests/__init__.py
diff --git a/test/python/dockerpy/tests/common.py b/test/python/dockerpy/tests/common.py
new file mode 100644
index 000000000..f83f4076f
--- /dev/null
+++ b/test/python/dockerpy/tests/common.py
@@ -0,0 +1,105 @@
+import os
+import pathlib
+import subprocess
+import sys
+import time
+
+from docker import APIClient
+
+from . import constant
+
+alpineDict = {
+ "name": "docker.io/library/alpine:latest",
+ "shortName": "alpine",
+ "tarballName": "alpine.tar"
+}
+
+
+def get_client():
+ client = APIClient(base_url="http://localhost:8080", timeout=15)
+ return client
+
+
+client = get_client()
+
+
+def podman():
+ binary = os.getenv("PODMAN_BINARY")
+ if binary is None:
+ binary = "../../../bin/podman"
+ return binary
+
+
+def restore_image_from_cache(TestClass):
+ alpineImage = os.path.join(constant.ImageCacheDir,
+ alpineDict["tarballName"])
+ if not os.path.exists(alpineImage):
+ os.makedirs(constant.ImageCacheDir, exist_ok=True)
+ client.pull(constant.ALPINE)
+ image = client.get_image(constant.ALPINE)
+ tarball = open(alpineImage, mode="wb")
+ for frame in image:
+ tarball.write(frame)
+ tarball.close()
+ else:
+ subprocess.run(
+ [podman(), "load", "-i", alpineImage],
+ shell=False,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ check=True,
+ )
+
+
+def flush_image_cache(TestCase):
+ for f in pathlib.Path(constant.ImageCacheDir).glob("*"):
+ f.unlink(f)
+
+
+def run_top_container():
+ c = client.create_container(image=constant.ALPINE,
+ command='/bin/sleep 5',
+ name=constant.TOP)
+ client.start(container=c.get("Id"))
+ return c.get("Id")
+
+
+def enable_sock(TestClass):
+ TestClass.podman = subprocess.Popen(
+ [
+ podman(), "system", "service", "tcp:localhost:8080",
+ "--log-level=debug", "--time=0"
+ ],
+ shell=False,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ )
+ time.sleep(2)
+
+
+def terminate_connection(TestClass):
+ TestClass.podman.terminate()
+ stdout, stderr = TestClass.podman.communicate(timeout=0.5)
+ if stdout:
+ print("\nService Stdout:\n" + stdout.decode('utf-8'))
+ if stderr:
+ print("\nService Stderr:\n" + stderr.decode('utf-8'))
+
+ if TestClass.podman.returncode > 0:
+ sys.stderr.write("podman exited with error code {}\n".format(
+ TestClass.podman.returncode))
+ sys.exit(2)
+
+
+def remove_all_containers():
+ containers = client.containers(quiet=True)
+ for c in containers:
+ client.remove_container(container=c.get("Id"), force=True)
+
+
+def remove_all_images():
+ allImages = client.images()
+ for image in allImages:
+ client.remove_image(image, force=True)
diff --git a/test/python/dockerpy/tests/constant.py b/test/python/dockerpy/tests/constant.py
new file mode 100644
index 000000000..b44442d02
--- /dev/null
+++ b/test/python/dockerpy/tests/constant.py
@@ -0,0 +1,13 @@
+BB = "docker.io/library/busybox:latest"
+NGINX = "docker.io/library/nginx:latest"
+ALPINE = "docker.io/library/alpine:latest"
+ALPINE_SHORTNAME = "alpine"
+ALPINELISTTAG = "docker.io/library/alpine:3.10.2"
+ALPINELISTDIGEST = "docker.io/library/alpine@sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb"
+ALPINEAMD64DIGEST = "docker.io/library/alpine@sha256:acd3ca9941a85e8ed16515bfc5328e4e2f8c128caa72959a58a127b7801ee01f"
+ALPINEAMD64ID = "961769676411f082461f9ef46626dd7a2d1e2b2a38e6a44364bcbecf51e66dd4"
+ALPINEARM64DIGEST = "docker.io/library/alpine@sha256:db7f3dcef3d586f7dd123f107c93d7911515a5991c4b9e51fa2a43e46335a43e"
+ALPINEARM64ID = "915beeae46751fc564998c79e73a1026542e945ca4f73dc841d09ccc6c2c0672"
+infra = "k8s.gcr.io/pause:3.2"
+TOP = "top"
+ImageCacheDir = "/tmp/podman/imagecachedir"
diff --git a/test/test_dockerpy/test_containers.py b/test/python/dockerpy/tests/test_containers.py
index 34fe82c18..6b89688d4 100644
--- a/test/test_dockerpy/test_containers.py
+++ b/test/python/dockerpy/tests/test_containers.py
@@ -1,18 +1,15 @@
-
-import unittest
-import docker
-import requests
import os
-from docker import Client
-from . import constant
-from . import common
import time
+import unittest
+
+import requests
+
+from . import common, constant
client = common.get_client()
-class TestContainers(unittest.TestCase):
- podman = None
+class TestContainers(unittest.TestCase):
topContainerId = ""
def setUp(self):
@@ -33,6 +30,7 @@ class TestContainers(unittest.TestCase):
@classmethod
def tearDownClass(cls):
common.terminate_connection(cls)
+ common.flush_image_cache(cls)
return super().tearDownClass()
def test_inspect_container(self):
@@ -42,16 +40,15 @@ class TestContainers(unittest.TestCase):
self.assertEqual(error.exception.response.status_code, 404)
# Inspect valid container by name
container = client.inspect_container(constant.TOP)
- self.assertIn(TestContainers.topContainerId , container["Id"])
+ self.assertIn(TestContainers.topContainerId, container["Id"])
# Inspect valid container by Id
container = client.inspect_container(TestContainers.topContainerId)
- self.assertIn(constant.TOP , container["Name"])
+ self.assertIn(constant.TOP, container["Name"])
def test_create_container(self):
# Run a container with detach mode
container = client.create_container(image="alpine", detach=True)
- self.assertEqual(len(container),2)
-
+ self.assertEqual(len(container), 2)
def test_start_container(self):
# Start bogus container
@@ -65,9 +62,9 @@ class TestContainers(unittest.TestCase):
# self.assertEqual(error.exception.response.status_code, 304)
# Create a new container and validate the count
- client.create_container(image=constant.ALPINE,name="container2")
- containers = client.containers(quiet=True,all=True)
- self.assertEqual(len(containers),2)
+ client.create_container(image=constant.ALPINE, name="container2")
+ containers = client.containers(quiet=True, all=True)
+ self.assertEqual(len(containers), 2)
def test_stop_container(self):
# Stop bogus container
@@ -82,7 +79,10 @@ class TestContainers(unittest.TestCase):
# Stop a running container and validate the state
client.stop(TestContainers.topContainerId)
container = client.inspect_container(constant.TOP)
- self.assertIn(container["State"]["Status"],"stopped exited",)
+ self.assertIn(
+ container["State"]["Status"],
+ "stopped exited",
+ )
def test_restart_container(self):
# Restart bogus container
@@ -109,12 +109,12 @@ class TestContainers(unittest.TestCase):
# Remove container by ID with force
client.remove_container(TestContainers.topContainerId, force=True)
containers = client.containers()
- self.assertEqual(len(containers),0)
+ self.assertEqual(len(containers), 0)
def test_remove_container_without_force(self):
# Validate current container count
containers = client.containers()
- self.assertTrue(len(containers),1)
+ self.assertTrue(len(containers), 1)
# Remove running container should throw error
with self.assertRaises(requests.HTTPError) as error:
@@ -125,7 +125,7 @@ class TestContainers(unittest.TestCase):
client.stop(TestContainers.topContainerId)
client.remove_container(TestContainers.topContainerId)
containers = client.containers()
- self.assertEqual(len(containers),0)
+ self.assertEqual(len(containers), 0)
def test_pause_container(self):
# Pause bogus container
@@ -151,7 +151,6 @@ class TestContainers(unittest.TestCase):
client.pause(TestContainers.topContainerId)
self.assertEqual(error.exception.response.status_code, 500)
-
def test_unpause_container(self):
# Unpause bogus container
with self.assertRaises(requests.HTTPError) as error:
@@ -173,7 +172,7 @@ class TestContainers(unittest.TestCase):
# Add container and validate the count
client.create_container(image="alpine", detach=True)
containers = client.containers(all=True)
- self.assertEqual(len(containers),2)
+ self.assertEqual(len(containers), 2)
# Not working for now......checking
# # List container with filter by id
diff --git a/test/test_dockerpy/test_images.py b/test/python/dockerpy/tests/test_images.py
index c88353b79..5eae61c2f 100644
--- a/test/test_dockerpy/test_images.py
+++ b/test/python/dockerpy/tests/test_images.py
@@ -1,17 +1,18 @@
-
+import os
+import stat
import unittest
+from os import remove
+from stat import ST_SIZE
+
import docker
import requests
-import os
-from docker import Client
-from . import constant
-from . import common
+
+from . import common, constant
client = common.get_client()
-class TestImages(unittest.TestCase):
- podman = None
+class TestImages(unittest.TestCase):
def setUp(self):
super().setUp()
common.restore_image_from_cache(self)
@@ -25,13 +26,12 @@ class TestImages(unittest.TestCase):
super().setUpClass()
common.enable_sock(cls)
-
@classmethod
def tearDownClass(cls):
common.terminate_connection(cls)
+ common.flush_image_cache(cls)
return super().tearDownClass()
-
# Inspect Image
def test_inspect_image(self):
@@ -43,46 +43,46 @@ class TestImages(unittest.TestCase):
# Tag Image
- # Validates if invalid image name is given a bad response is encountered.
+# Validates if invalid image name is given a bad response is encountered.
+
def test_tag_invalid_image(self):
with self.assertRaises(requests.HTTPError):
- client.tag("dummy","demo")
-
-
+ client.tag("dummy", "demo")
# Validates if the image is tagged successfully.
def test_tag_valid_image(self):
- client.tag(constant.ALPINE,"demo",constant.ALPINE_SHORTNAME)
+ client.tag(constant.ALPINE, "demo", constant.ALPINE_SHORTNAME)
alpine_image = client.inspect_image(constant.ALPINE)
for x in alpine_image["RepoTags"]:
- if("demo:alpine" in x):
+ if ("demo:alpine" in x):
self.assertTrue
self.assertFalse
# Validates if name updates when the image is retagged.
@unittest.skip("dosent work now")
def test_retag_valid_image(self):
- client.tag(constant.ALPINE_SHORTNAME, "demo","rename")
+ client.tag(constant.ALPINE_SHORTNAME, "demo", "rename")
alpine_image = client.inspect_image(constant.ALPINE)
self.assertNotIn("demo:test", alpine_image["RepoTags"])
# List Image
- # List All Images
+# List All Images
+
def test_list_images(self):
allImages = client.images()
self.assertEqual(len(allImages), 1)
# Add more images
client.pull(constant.BB)
allImages = client.images()
- self.assertEqual(len(allImages) , 2)
-
+ self.assertEqual(len(allImages), 2)
- # List images with filter
- filters = {'reference':'alpine'}
- allImages = client.images(filters = filters)
- self.assertEqual(len(allImages) , 1)
+ # List images with filter
+ filters = {'reference': 'alpine'}
+ allImages = client.images(filters=filters)
+ self.assertEqual(len(allImages), 1)
# Search Image
+
def test_search_image(self):
response = client.search("alpine")
for i in response:
@@ -94,22 +94,25 @@ class TestImages(unittest.TestCase):
# Image Exist (No docker-py support yet)
# Remove Image
+
def test_remove_image(self):
# Check for error with wrong image name
with self.assertRaises(requests.HTTPError):
client.remove_image("dummy")
allImages = client.images()
- self.assertEqual(len(allImages) , 1)
+ self.assertEqual(len(allImages), 1)
alpine_image = client.inspect_image(constant.ALPINE)
client.remove_image(alpine_image)
allImages = client.images()
- self.assertEqual(len(allImages) , 0)
+ self.assertEqual(len(allImages), 0)
# Image History
+
def test_image_history(self):
# Check for error with wrong image name
with self.assertRaises(requests.HTTPError):
- client.remove_image("dummy")
+ client.history("dummy")
+
imageHistory = client.history(constant.ALPINE)
alpine_image = client.inspect_image(constant.ALPINE)
for h in imageHistory:
@@ -119,28 +122,37 @@ class TestImages(unittest.TestCase):
# Prune Image (No docker-py support yet)
+ def test_get_image_dummy(self):
+ # FIXME: seems to be an error in the library
+ self.skipTest("Documentation and library do not match")
+ # Check for error with wrong image name
+ with self.assertRaises(docker.errors.ImageNotFound):
+ client.get_image("dummy")
+
# Export Image
def test_export_image(self):
client.pull(constant.BB)
- file = os.path.join(constant.ImageCacheDir , "busybox.tar")
if not os.path.exists(constant.ImageCacheDir):
os.makedirs(constant.ImageCacheDir)
- # Check for error with wrong image name
- with self.assertRaises(requests.HTTPError):
- client.get_image("dummy")
- response = client.get_image(constant.BB)
- image_tar = open(file,mode="wb")
- image_tar.write(response.data)
- image_tar.close()
- os.stat(file)
+
+ image = client.get_image(constant.BB)
+
+ file = os.path.join(constant.ImageCacheDir, "busybox.tar")
+ tarball = open(file, mode="wb")
+ for frame in image:
+ tarball.write(frame)
+ tarball.close()
+ sz = os.path.getsize(file)
+ self.assertGreater(sz, 0)
+
# Import|Load Image
def test_import_image(self):
allImages = client.images()
self.assertEqual(len(allImages), 1)
- file = os.path.join(constant.ImageCacheDir , "busybox.tar")
+ file = os.path.join(constant.ImageCacheDir, "alpine.tar")
client.import_image_from_file(filename=file)
allImages = client.images()
self.assertEqual(len(allImages), 2)
diff --git a/test/test_dockerpy/test_info_version.py b/test/python/dockerpy/tests/test_info_version.py
index be1a2aab9..e3ee18ec7 100644
--- a/test/test_dockerpy/test_info_version.py
+++ b/test/python/dockerpy/tests/test_info_version.py
@@ -1,11 +1,10 @@
import unittest
-import docker
-from docker import Client
-from . import constant
-from . import common
+
+from . import common, constant
client = common.get_client()
+
class TestInfo_Version(unittest.TestCase):
podman = None
@@ -31,16 +30,15 @@ class TestInfo_Version(unittest.TestCase):
common.terminate_connection(cls)
return super().tearDownClass()
-
def test_Info(self):
self.assertIsNotNone(client.info())
def test_info_container_details(self):
info = client.info()
- self.assertEqual(info["Containers"],1)
+ self.assertEqual(info["Containers"], 1)
client.create_container(image=constant.ALPINE)
info = client.info()
- self.assertEqual(info["Containers"],2)
+ self.assertEqual(info["Containers"], 2)
def test_version(self):
self.assertIsNotNone(client.version())
diff --git a/test/system/015-help.bats b/test/system/015-help.bats
index 14af8e1a4..3d05b44fe 100644
--- a/test/system/015-help.bats
+++ b/test/system/015-help.bats
@@ -34,13 +34,16 @@ function check_help() {
dprint "$command_string --help"
run_podman "$@" $cmd --help
+ local full_help="$output"
# The line immediately after 'Usage:' gives us a 1-line synopsis
- usage=$(echo "$output" | grep -A1 '^Usage:' | tail -1)
+ usage=$(echo "$full_help" | grep -A1 '^Usage:' | tail -1)
[ -n "$usage" ] || die "podman $cmd: no Usage message found"
# e.g. 'podman ps' should not show 'podman container ps' in usage
- is "$usage" " $command_string .*" "Usage string matches command"
+ # Trailing space in usage handles 'podman system renumber' which
+ # has no ' [flags]'
+ is "$usage " " $command_string .*" "Usage string matches command"
# If usage ends in '[command]', recurse into subcommands
if expr "$usage" : '.*\[command\]$' >/dev/null; then
@@ -59,6 +62,17 @@ function check_help() {
die "'flags' must precede arguments in usage: $usage"
fi
+ # Cross-check: if usage includes '[flags]', there must be a
+ # longer 'Flags:' section in the full --help output; vice-versa,
+ # if 'Flags:' is in full output, usage line must have '[flags]'.
+ if expr "$usage" : '.*\[flag' >/dev/null; then
+ if ! expr "$full_help" : ".*Flags:" >/dev/null; then
+ die "$command_string: Usage includes '[flags]' but has no 'Flags:' subsection"
+ fi
+ elif expr "$full_help" : ".*Flags:" >/dev/null; then
+ die "$command_string: --help has 'Flags:' section but no '[flags]' in synopsis"
+ fi
+
# If usage lists no arguments (strings in ALL CAPS), confirm
# by running with 'invalid-arg' and expecting failure.
if ! expr "$usage" : '.*[A-Z]' >/dev/null; then
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index eeecea2e5..bc6347012 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -201,4 +201,45 @@ echo $rand | 0 | $rand
"podman will not overwrite existing cidfile"
}
+@test "podman run docker-archive" {
+ # Create an image that, when run, outputs a random magic string
+ expect=$(random_string 20)
+ run_podman run --name myc --entrypoint="[\"/bin/echo\",\"$expect\"]" $IMAGE
+ is "$output" "$expect" "podman run --entrypoint echo-randomstring"
+
+ # Save it as a tar archive
+ run_podman commit myc myi
+ archive=$PODMAN_TMPDIR/archive.tar
+ run_podman save myi -o $archive
+ is "$output" "" "podman save"
+
+ # Clean up image and container from container storage...
+ run_podman rmi myi
+ run_podman rm myc
+
+ # ... then confirm we can run from archive. This re-imports the image
+ # and runs it, producing our random string as the last line.
+ run_podman run docker-archive:$archive
+ is "${lines[0]}" "Getting image source signatures" "podman run docker-archive, first line of output"
+ is "$output" ".*Copying blob" "podman run docker-archive"
+ is "$output" ".*Copying config" "podman run docker-archive"
+ is "$output" ".*Writing manifest" "podman run docker-archive"
+ is "${lines[-1]}" "$expect" "podman run docker-archive: expected random string output"
+
+ # Clean up container as well as re-imported image
+ run_podman rm -a
+ run_podman rmi myi
+
+ # Repeat the above, with podman-create and podman-start.
+ run_podman create docker-archive:$archive
+ cid=${lines[-1]}
+
+ run_podman start --attach $cid
+ is "$output" "$expect" "'podman run' of 'podman-create docker-archive'"
+
+ # Clean up.
+ run_podman rm $cid
+ run_podman rmi myi
+}
+
# vim: filetype=sh
diff --git a/test/test_dockerpy/README.md b/test/test_dockerpy/README.md
deleted file mode 100644
index 32e426d58..000000000
--- a/test/test_dockerpy/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Dockerpy regression test
-
-Python test suite to validate Podman endpoints using dockerpy library
-
-Running tests
-=============
-To run the tests locally in your sandbox:
-
-#### Run the entire test
-
-```
-sudo PYTHONPATH=/usr/bin/python python -m dockerpy.images
-```
-
-Passing the -v option to your test script will instruct unittest.main() to enable a higher level of verbosity, and produce detailed output:
-
-```
-sudo PYTHONPATH=/usr/bin/python python -m unittest -v dockerpy.images
-```
-#### Run a specific test class
-
-```
-sudo PYTHONPATH=/usr/bin/python python -m unittest -v dockerpy.images.TestImages
-```
-
-#### Run a specific test within the test class
-
-```
-sudo PYTHONPATH=/usr/bin/python python -m unittest -v dockerpy.images.TestImages.test_list_images
-```
diff --git a/test/test_dockerpy/common.py b/test/test_dockerpy/common.py
deleted file mode 100644
index 975b13dc6..000000000
--- a/test/test_dockerpy/common.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import docker
-import subprocess
-import os
-import sys
-import time
-from docker import Client
-from . import constant
-
-alpineDict = {
- "name": "docker.io/library/alpine:latest",
- "shortName": "alpine",
- "tarballName": "alpine.tar"}
-
-def get_client():
- client = docker.Client(base_url="http://localhost:8080",timeout=15)
- return client
-
-client = get_client()
-
-def podman():
- binary = os.getenv("PODMAN_BINARY")
- if binary is None:
- binary = "bin/podman"
- return binary
-
-def restore_image_from_cache(TestClass):
- alpineImage = os.path.join(constant.ImageCacheDir , alpineDict["tarballName"])
- if not os.path.exists(alpineImage):
- os.makedirs(constant.ImageCacheDir)
- client.pull(constant.ALPINE)
- response = client.get_image(constant.ALPINE)
- image_tar = open(alpineImage,mode="wb")
- image_tar.write(response.data)
- image_tar.close()
- else :
- TestClass.podman = subprocess.run(
- [
- podman(), "load", "-i", alpineImage
- ],
- shell=False,
- stdin=subprocess.DEVNULL,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- )
-
-def run_top_container():
- c = client.create_container(image=constant.ALPINE,command='/bin/sleep 5',name=constant.TOP)
- client.start(container=c.get("Id"))
- return c.get("Id")
-
-def enable_sock(TestClass):
- TestClass.podman = subprocess.Popen(
- [
- podman(), "system", "service", "tcp:localhost:8080",
- "--log-level=debug", "--time=0"
- ],
- shell=False,
- stdin=subprocess.DEVNULL,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- )
- time.sleep(2)
-
-def terminate_connection(TestClass):
- TestClass.podman.terminate()
- stdout, stderr = TestClass.podman.communicate(timeout=0.5)
- if stdout:
- print("\nService Stdout:\n" + stdout.decode('utf-8'))
- if stderr:
- print("\nService Stderr:\n" + stderr.decode('utf-8'))
-
- if TestClass.podman.returncode > 0:
- sys.stderr.write("podman exited with error code {}\n".format(
- TestClass.podman.returncode))
- sys.exit(2)
-
-def remove_all_containers():
- containers = client.containers(quiet=True)
- for c in containers:
- client.remove_container(container=c.get("Id"), force=True)
-
-def remove_all_images():
- allImages = client.images()
- for image in allImages:
- client.remove_image(image,force=True)
diff --git a/test/test_dockerpy/constant.py b/test/test_dockerpy/constant.py
deleted file mode 100644
index 8a3f1d984..000000000
--- a/test/test_dockerpy/constant.py
+++ /dev/null
@@ -1,13 +0,0 @@
-BB = "docker.io/library/busybox:latest"
-NGINX = "docker.io/library/nginx:latest"
-ALPINE = "docker.io/library/alpine:latest"
-ALPINE_SHORTNAME = "alpine"
-ALPINELISTTAG = "docker.io/library/alpine:3.10.2"
-ALPINELISTDIGEST = "docker.io/library/alpine@sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb"
-ALPINEAMD64DIGEST = "docker.io/library/alpine@sha256:acd3ca9941a85e8ed16515bfc5328e4e2f8c128caa72959a58a127b7801ee01f"
-ALPINEAMD64ID = "961769676411f082461f9ef46626dd7a2d1e2b2a38e6a44364bcbecf51e66dd4"
-ALPINEARM64DIGEST = "docker.io/library/alpine@sha256:db7f3dcef3d586f7dd123f107c93d7911515a5991c4b9e51fa2a43e46335a43e"
-ALPINEARM64ID = "915beeae46751fc564998c79e73a1026542e945ca4f73dc841d09ccc6c2c0672"
-infra = "k8s.gcr.io/pause:3.2"
-TOP = "top"
-ImageCacheDir = "/tmp/podman/imagecachedir"
diff --git a/vendor/github.com/containers/common/pkg/apparmor/apparmor.go b/vendor/github.com/containers/common/pkg/apparmor/apparmor.go
index 8b4207efc..8046f45f5 100644
--- a/vendor/github.com/containers/common/pkg/apparmor/apparmor.go
+++ b/vendor/github.com/containers/common/pkg/apparmor/apparmor.go
@@ -2,14 +2,16 @@ package apparmor
import (
"errors"
+
+ "github.com/containers/common/version"
)
const (
// ProfilePrefix is used for version-independent presence checks.
- ProfilePrefix = "apparmor_profile"
+ ProfilePrefix = "containers-default-"
// Profile default name
- Profile = "container-default"
+ Profile = ProfilePrefix + version.Version
)
var (
diff --git a/vendor/github.com/containers/common/pkg/apparmor/apparmor_linux.go b/vendor/github.com/containers/common/pkg/apparmor/apparmor_linux.go
index f0fab4597..307249f3d 100644
--- a/vendor/github.com/containers/common/pkg/apparmor/apparmor_linux.go
+++ b/vendor/github.com/containers/common/pkg/apparmor/apparmor_linux.go
@@ -255,9 +255,11 @@ func CheckProfileAndLoadDefault(name string) (string, error) {
}
}
- // If the specified name is not empty or is not a default libpod one,
- // ignore it and return the name.
- if name != "" && !strings.HasPrefix(name, ProfilePrefix) {
+ if name == "" {
+ name = Profile
+ } else if !strings.HasPrefix(name, ProfilePrefix) {
+ // If the specified name is not a default one, ignore it and return the
+ // name.
isLoaded, err := IsLoaded(name)
if err != nil {
return "", err
@@ -268,7 +270,6 @@ func CheckProfileAndLoadDefault(name string) (string, error) {
return name, nil
}
- name = Profile
// To avoid expensive redundant loads on each invocation, check
// if it's loaded before installing it.
isLoaded, err := IsLoaded(name)
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index ce479088e..d60464739 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -822,6 +822,7 @@ func stringsEq(a, b []string) bool {
var (
configOnce sync.Once
+ configErr error
config *Config
)
@@ -837,11 +838,10 @@ var (
// The system defaults container config files can be overwritten using the
// CONTAINERS_CONF environment variable. This is usually done for testing.
func Default() (*Config, error) {
- var err error
configOnce.Do(func() {
- config, err = NewConfig("")
+ config, configErr = NewConfig("")
})
- return config, err
+ return config, configErr
}
func Path() string {
diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go
new file mode 100644
index 000000000..38a45dfb2
--- /dev/null
+++ b/vendor/github.com/containers/common/version/version.go
@@ -0,0 +1,4 @@
+package version
+
+// Version is the version of the build.
+const Version = "0.14.3"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 882ea5d25..497381b52 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -84,13 +84,14 @@ github.com/containers/buildah/pkg/secrets
github.com/containers/buildah/pkg/supplemented
github.com/containers/buildah/pkg/umask
github.com/containers/buildah/util
-# github.com/containers/common v0.14.0
+# github.com/containers/common v0.14.3
github.com/containers/common/pkg/apparmor
github.com/containers/common/pkg/auth
github.com/containers/common/pkg/capabilities
github.com/containers/common/pkg/cgroupv2
github.com/containers/common/pkg/config
github.com/containers/common/pkg/sysinfo
+github.com/containers/common/version
# github.com/containers/conmon v2.0.18+incompatible
github.com/containers/conmon/runner/config
# github.com/containers/image/v5 v5.5.1