diff options
50 files changed, 323 insertions, 127 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index cd122d39f..1458e2cc6 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -59,7 +59,7 @@ env: #### Default to NOT operating in any special-case testing mode #### SPECIALMODE: "none" # don't do anything special - TEST_REMOTE_CLIENT: 'false' # don't test remote client by default + RCLI: 'false' # don't test remote client by default ADD_SECOND_PARTITION: 'false' # will certainly fail inside containers MOD_CONTAINERS_CONF: 'true' # Update containers.conf runtime if required by OS environment @@ -422,8 +422,8 @@ testing_task: env: ADD_SECOND_PARTITION: 'true' matrix: - - TEST_REMOTE_CLIENT: 'true' - - TEST_REMOTE_CLIENT: 'false' + - RCLI: 'true' + - RCLI: 'false' networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh' setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}' @@ -470,8 +470,8 @@ special_testing_rootless_task: ADD_SECOND_PARTITION: 'true' SPECIALMODE: 'rootless' # See docs matrix: - - TEST_REMOTE_CLIENT: 'true' - - TEST_REMOTE_CLIENT: 'false' + - RCLI: 'true' + - RCLI: 'false' timeout_in: 60m @@ -674,8 +674,8 @@ verify_test_built_images_task: env: ADD_SECOND_PARTITION: 'true' matrix: - - TEST_REMOTE_CLIENT: 'true' - - TEST_REMOTE_CLIENT: 'false' + - RCLI: 'true' + - RCLI: 'false' matrix: PACKER_BUILDER_NAME: "${FEDORA_NAME}" PACKER_BUILDER_NAME: "${PRIOR_FEDORA_NAME}" diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go index 0b6897d3a..5c6c47e8d 100644 --- a/cmd/podman/common/specgen.go +++ b/cmd/podman/common/specgen.go @@ -387,8 +387,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string s.Annotations = annotations s.WorkDir = c.Workdir - userCommand := []string{} - var command []string if c.Entrypoint != nil { entrypoint := []string{} if ep := *c.Entrypoint; len(ep) > 0 { @@ -398,27 +396,13 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string } } s.Entrypoint = entrypoint - // Build the command - // If we have an entry point, it goes first - command = entrypoint } // Include the command used to create the container. s.ContainerCreateCommand = os.Args if len(inputCommand) > 0 { - // User command overrides data CMD - command = append(command, inputCommand...) - userCommand = append(userCommand, inputCommand...) - } - - switch { - case len(inputCommand) > 0: - s.Command = userCommand - case c.Entrypoint != nil: - s.Command = []string{} - default: - s.Command = command + s.Command = inputCommand } // SHM Size diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go index 64271031d..ebb6ed98f 100644 --- a/cmd/podman/containers/ps.go +++ b/cmd/podman/containers/ps.go @@ -109,6 +109,7 @@ func jsonOut(responses []entities.ListContainer) error { r := make([]entities.ListContainer, 0) for _, con := range responses { con.CreatedAt = units.HumanDuration(time.Since(time.Unix(con.Created, 0))) + " ago" + con.Status = psReporter{con}.Status() r = append(r, con) } b, err := json.MarshalIndent(r, "", " ") diff --git a/cmd/podman/images/list.go b/cmd/podman/images/list.go index ee0f64d99..043871a8c 100644 --- a/cmd/podman/images/list.go +++ b/cmd/podman/images/list.go @@ -195,6 +195,7 @@ func sortImages(imageS []*entities.ImageSummary) ([]imageReporter, error) { } else { h.ImageSummary = *e h.Repository = "<none>" + h.Tag = "<none>" imgs = append(imgs, h) } listFlag.readOnly = e.IsReadOnly() @@ -205,27 +206,34 @@ func sortImages(imageS []*entities.ImageSummary) ([]imageReporter, error) { } func tokenRepoTag(ref string) (string, string, error) { - if ref == "<none>:<none>" { return "<none>", "<none>", nil } repo, err := reference.Parse(ref) if err != nil { - return "", "", err + return "<none>", "<none>", err } named, ok := repo.(reference.Named) if !ok { - return ref, "", nil + return ref, "<none>", nil + } + name := named.Name() + if name == "" { + name = "<none>" } tagged, ok := repo.(reference.Tagged) if !ok { - return named.Name(), "", nil + return name, "<none>", nil + } + tag := tagged.Tag() + if tag == "" { + tag = "<none>" } - return named.Name(), tagged.Tag(), nil + return name, tag, nil } diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 9e9011dc9..2aa7267c2 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -6,7 +6,6 @@ import ( "path" "runtime" "runtime/pprof" - "strconv" "strings" "github.com/containers/common/pkg/config" @@ -112,15 +111,6 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { cfg := registry.PodmanConfig() - // Validate --remote and --latest not given on same command - latest := cmd.Flags().Lookup("latest") - if latest != nil { - value, _ := strconv.ParseBool(latest.Value.String()) - if cfg.Remote && value { - return errors.Errorf("For %s \"--remote\" and \"--latest\", are mutually exclusive flags", cmd.CommandPath()) - } - } - // Prep the engines if _, err := registry.NewImageEngine(cmd, args); err != nil { return err diff --git a/cmd/podman/validate/args.go b/cmd/podman/validate/args.go index a33f47959..aacb41e69 100644 --- a/cmd/podman/validate/args.go +++ b/cmd/podman/validate/args.go @@ -4,6 +4,7 @@ import ( "fmt" "strconv" + "github.com/containers/podman/v2/cmd/podman/registry" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -47,17 +48,20 @@ func IDOrLatestArgs(cmd *cobra.Command, args []string) error { // CheckAllLatestAndCIDFile checks that --all and --latest are used correctly. // If cidfile is set, also check for the --cidfile flag. func CheckAllLatestAndCIDFile(c *cobra.Command, args []string, ignoreArgLen bool, cidfile bool) error { + var specifiedLatest bool argLen := len(args) - if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil { - if !cidfile { - return errors.New("unable to lookup values for 'latest' or 'all'") - } else if c.Flags().Lookup("cidfile") == nil { - return errors.New("unable to lookup values for 'latest', 'all' or 'cidfile'") + if !registry.IsRemote() { + specifiedLatest, _ = c.Flags().GetBool("latest") + if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil { + if !cidfile { + return errors.New("unable to lookup values for 'latest' or 'all'") + } else if c.Flags().Lookup("cidfile") == nil { + return errors.New("unable to lookup values for 'latest', 'all' or 'cidfile'") + } } } specifiedAll, _ := c.Flags().GetBool("all") - specifiedLatest, _ := c.Flags().GetBool("latest") specifiedCIDFile := false if cid, _ := c.Flags().GetStringArray("cidfile"); len(cid) > 0 { specifiedCIDFile = true @@ -98,17 +102,21 @@ func CheckAllLatestAndCIDFile(c *cobra.Command, args []string, ignoreArgLen bool // CheckAllLatestAndPodIDFile checks that --all and --latest are used correctly. // If withIDFile is set, also check for the --pod-id-file flag. func CheckAllLatestAndPodIDFile(c *cobra.Command, args []string, ignoreArgLen bool, withIDFile bool) error { + var specifiedLatest bool argLen := len(args) - if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil { - if !withIDFile { - return errors.New("unable to lookup values for 'latest' or 'all'") - } else if c.Flags().Lookup("pod-id-file") == nil { - return errors.New("unable to lookup values for 'latest', 'all' or 'pod-id-file'") + if !registry.IsRemote() { + // remote clients have no latest flag + specifiedLatest, _ = c.Flags().GetBool("latest") + if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil { + if !withIDFile { + return errors.New("unable to lookup values for 'latest' or 'all'") + } else if c.Flags().Lookup("pod-id-file") == nil { + return errors.New("unable to lookup values for 'latest', 'all' or 'pod-id-file'") + } } } specifiedAll, _ := c.Flags().GetBool("all") - specifiedLatest, _ := c.Flags().GetBool("latest") specifiedPodIDFile := false if pid, _ := c.Flags().GetStringArray("pod-id-file"); len(pid) > 0 { specifiedPodIDFile = true diff --git a/cmd/podman/validate/latest.go b/cmd/podman/validate/latest.go index 5c76fe847..c9bff798a 100644 --- a/cmd/podman/validate/latest.go +++ b/cmd/podman/validate/latest.go @@ -7,9 +7,8 @@ import ( func AddLatestFlag(cmd *cobra.Command, b *bool) { // Initialization flag verification - cmd.Flags().BoolVarP(b, "latest", "l", false, - "Act on the latest container podman is aware of\nNot supported with the \"--remote\" flag") - if registry.IsRemote() { - _ = cmd.Flags().MarkHidden("latest") + if !registry.IsRemote() { + cmd.Flags().BoolVarP(b, "latest", "l", false, + "Act on the latest container podman is aware of\nNot supported with the \"--remote\" flag") } } diff --git a/commands-demo.md b/commands-demo.md index 555f83af9..74879842f 100644 --- a/commands-demo.md +++ b/commands-demo.md @@ -27,11 +27,11 @@ | [podman-generate-systemd(1)](https://podman.readthedocs.io/en/latest/markdown/podman-generate-systemd.1.html) | Generate systemd unit file(s) for a container or pod. Not supported for the remote client | | [podman-history(1)](https://podman.readthedocs.io/en/latest/markdown/podman-history.1.html) | Shows the history of an image | | [podman-image(1)](https://podman.readthedocs.io/en/latest/image.html) | Manage Images | -| [podman-image-exists(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-exists.1.html) | Check if an image exists in local storage | | [podman-image-diff(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-diff.html) | Inspect changes on an image's filesystem. | +| [podman-image-exists(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-exists.1.html) | Check if an image exists in local storage | | [podman-image-prune(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-prune.1.html) | Remove all unused images from the local store | -| [podman-image-sign(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-sign.1.html) | Create a signature for an image | | [podman-image-search(1)](https://podman.readthedocs.io/en/latest/markdown/podman-search.1.html) | Search a registry for an image. | +| [podman-image-sign(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-sign.1.html) | Create a signature for an image | | [podman-image-tree(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-tree.1.html) | Prints layer hierarchy of an image in a tree format | | [podman-image-trust(1)](https://podman.readthedocs.io/en/latest/markdown/podman-image-trust.1.html) | Manage container registry image trust policy | | [podman-images(1)](https://podman.readthedocs.io/en/latest/markdown/podman-images.1.html) | List images in local storage | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/images/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_images.sh) | @@ -58,9 +58,9 @@ | [podman-pod-exists(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-exists.1.html) | Check if a pod exists in local storage | | [podman-pod-inspect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-inspect.1.html) | Displays information describing a pod | | [podman-pod-kill(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-kill.1.html) | Kill the main process of each container in one or more pods | -| [podman-pod-ps(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-ps.1.html) | Prints out information about pods | | [podman-pod-pause(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pause.1.html) | Pause one or more containers | | [podman-pod-prune(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-prune.1.html) | Remove all stopped pods and their containers | +| [podman-pod-ps(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-ps.1.html) | Prints out information about pods | | [podman-pod-restart](https://podman.readthedocs.io/en/latest/markdown/podman-pod-restart.1.html) | Restart one or more pods | | [podman-pod-rm(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-rm.1.html) | Remove one or more stopped pods and containers | | [podman-pod-start(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pod-start.1.html) | Start one or more pods | diff --git a/contrib/cirrus/apiv2_test.sh b/contrib/cirrus/apiv2_test.sh index 33e9fbc6b..546fe8e30 100755 --- a/contrib/cirrus/apiv2_test.sh +++ b/contrib/cirrus/apiv2_test.sh @@ -7,7 +7,7 @@ source $(dirname $0)/lib.sh req_env_var GOSRC SCRIPT_BASE OS_RELEASE_ID OS_RELEASE_VER CONTAINER_RUNTIME VARLINK_LOG LOCAL_OR_REMOTE=local -if [[ "$TEST_REMOTE_CLIENT" = "true" ]]; then +if [[ "$RCLI" = "true" ]]; then LOCAL_OR_REMOTE=remote fi diff --git a/contrib/cirrus/build_release.sh b/contrib/cirrus/build_release.sh index 07db88f81..45634f368 100755 --- a/contrib/cirrus/build_release.sh +++ b/contrib/cirrus/build_release.sh @@ -4,11 +4,11 @@ set -e source $(dirname $0)/lib.sh -req_env_var TEST_REMOTE_CLIENT OS_RELEASE_ID GOSRC +req_env_var RCLI OS_RELEASE_ID GOSRC cd $GOSRC -if [[ "$TEST_REMOTE_CLIENT" == "true" ]] && [[ -z "$CROSS_PLATFORM" ]] +if [[ "$RCLI" == "true" ]] && [[ -z "$CROSS_PLATFORM" ]] then CROSS_PLATFORM=linux fi diff --git a/contrib/cirrus/check_image.sh b/contrib/cirrus/check_image.sh index 39c2be3f8..13172fe1c 100755 --- a/contrib/cirrus/check_image.sh +++ b/contrib/cirrus/check_image.sh @@ -6,7 +6,7 @@ source $(dirname $0)/lib.sh EVIL_UNITS="$($CIRRUS_WORKING_DIR/$PACKER_BASE/systemd_banish.sh --list)" -req_env_var PACKER_BUILDER_NAME TEST_REMOTE_CLIENT EVIL_UNITS OS_RELEASE_ID CG_FS_TYPE +req_env_var PACKER_BUILDER_NAME RCLI EVIL_UNITS OS_RELEASE_ID CG_FS_TYPE NFAILS=0 echo "Validating VM image" diff --git a/contrib/cirrus/container_test.sh b/contrib/cirrus/container_test.sh index 8a4ed9492..b56a12232 100644 --- a/contrib/cirrus/container_test.sh +++ b/contrib/cirrus/container_test.sh @@ -18,7 +18,7 @@ if [ "${ID}" != "fedora" ] || [ "${CONTAINER_RUNTIME}" != "" ]; then INTEGRATION_TEST_ENVS="SKIP_USERNS=1" fi -echo "$(date --rfc-3339=seconds) $(basename $0) started with '$*' and TEST_REMOTE_CLIENT='${TEST_REMOTE_CLIENT}'" +echo "$(date --rfc-3339=seconds) $(basename $0) started with '$*' and RCLI='${RCLI}'" pwd @@ -57,9 +57,9 @@ while getopts "bituv" opt; do esac done -# The TEST_REMOTE_CLIENT environment variable decides whether +# The RCLI environment variable decides whether # to test varlinke -if [[ "$TEST_REMOTE_CLIENT" == "true" ]]; then +if [[ "$RCLI" == "true" ]]; then remote=1 fi diff --git a/contrib/cirrus/integration_test.sh b/contrib/cirrus/integration_test.sh index 692d5a236..c65f5e25f 100755 --- a/contrib/cirrus/integration_test.sh +++ b/contrib/cirrus/integration_test.sh @@ -7,7 +7,7 @@ source $(dirname $0)/lib.sh req_env_var GOSRC SCRIPT_BASE OS_RELEASE_ID OS_RELEASE_VER CONTAINER_RUNTIME VARLINK_LOG LOCAL_OR_REMOTE=local -if [[ "$TEST_REMOTE_CLIENT" = "true" ]]; then +if [[ "$RCLI" = "true" ]]; then LOCAL_OR_REMOTE=remote fi diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index d2af4d883..968b2de39 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -96,12 +96,12 @@ LILTO="timeout_attempt_delay_command 120s 5 30s" BIGTO="timeout_attempt_delay_command 300s 5 60s" # Safe env. vars. to transfer from root -> $ROOTLESS_USER (go env handled separately) -ROOTLESS_ENV_RE='(CIRRUS_.+)|(ROOTLESS_.+)|(.+_IMAGE.*)|(.+_BASE)|(.*DIRPATH)|(.*FILEPATH)|(SOURCE.*)|(DEPEND.*)|(.+_DEPS_.+)|(OS_REL.*)|(.+_ENV_RE)|(TRAVIS)|(CI.+)|(TEST_REMOTE.*)' +ROOTLESS_ENV_RE='(CIRRUS_.+)|(ROOTLESS_.+)|(.+_IMAGE.*)|(.+_BASE)|(.*DIRPATH)|(.*FILEPATH)|(SOURCE.*)|(DEPEND.*)|(.+_DEPS_.+)|(OS_REL.*)|(.+_ENV_RE)|(TRAVIS)|(CI.+)|(REMOTE.*)' # Unsafe env. vars for display SECRET_ENV_RE='(IRCID)|(ACCOUNT)|(GC[EP]..+)|(SSH)' SPECIALMODE="${SPECIALMODE:-none}" -TEST_REMOTE_CLIENT="${TEST_REMOTE_CLIENT:-false}" +RCLI="${RCLI:-false}" export CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-podman} # When running as root, this may be empty or not, as a user, it MUST be set. diff --git a/contrib/cirrus/logcollector.sh b/contrib/cirrus/logcollector.sh index 0b179591a..859da2966 100755 --- a/contrib/cirrus/logcollector.sh +++ b/contrib/cirrus/logcollector.sh @@ -4,7 +4,7 @@ set -e source $(dirname $0)/lib.sh -req_env_var CIRRUS_WORKING_DIR OS_RELEASE_ID TEST_REMOTE_CLIENT +req_env_var CIRRUS_WORKING_DIR OS_RELEASE_ID RCLI # Assume there are other log collection commands to follow - Don't # let one break another that may be useful, but also keep any @@ -34,12 +34,12 @@ case $1 in journal) showrun journalctl -b ;; podman) showrun ./bin/podman system info ;; varlink) - if [[ "$TEST_REMOTE_CLIENT" == "true" ]] + if [[ "$RCLI" == "true" ]] then echo "(Trailing 100 lines of $VARLINK_LOG)" showrun tail -100 $VARLINK_LOG else - die 0 "\$TEST_REMOTE_CLIENT is not 'true': $TEST_REMOTE_CLIENT" + die 0 "\$RCLI is not 'true': $RCLI" fi ;; packages) diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index 94169442b..0b9d686d3 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -103,7 +103,7 @@ case "$SPECIALMODE" in tee -a /etc/environment) && eval "$X" && echo "$X" X=$(echo "export SPECIALMODE='${SPECIALMODE}'" | \ tee -a /etc/environment) && eval "$X" && echo "$X" - X=$(echo "export TEST_REMOTE_CLIENT='${TEST_REMOTE_CLIENT}'" | \ + X=$(echo "export RCLI='${RCLI}'" | \ tee -a /etc/environment) && eval "$X" && echo "$X" setup_rootless fi diff --git a/contrib/cirrus/system_test.sh b/contrib/cirrus/system_test.sh index 33e9fbc6b..546fe8e30 100755 --- a/contrib/cirrus/system_test.sh +++ b/contrib/cirrus/system_test.sh @@ -7,7 +7,7 @@ source $(dirname $0)/lib.sh req_env_var GOSRC SCRIPT_BASE OS_RELEASE_ID OS_RELEASE_VER CONTAINER_RUNTIME VARLINK_LOG LOCAL_OR_REMOTE=local -if [[ "$TEST_REMOTE_CLIENT" = "true" ]]; then +if [[ "$RCLI" = "true" ]]; then LOCAL_OR_REMOTE=remote fi diff --git a/contrib/podmanimage/stable/Dockerfile b/contrib/podmanimage/stable/Dockerfile index fdf461f72..bcd3a5d3d 100644 --- a/contrib/podmanimage/stable/Dockerfile +++ b/contrib/podmanimage/stable/Dockerfile @@ -16,7 +16,7 @@ RUN useradd podman; yum -y update; yum -y reinstall shadow-utils; yum -y install ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/ # chmod containers.conf and adjust storage.conf to enable Fuse storage. -RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf -RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock +RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf +RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/stable/manual/Containerfile b/contrib/podmanimage/stable/manual/Containerfile index 79ff95956..f9ae57dbf 100644 --- a/contrib/podmanimage/stable/manual/Containerfile +++ b/contrib/podmanimage/stable/manual/Containerfile @@ -29,8 +29,8 @@ RUN yum -y install /tmp/podman-1.7.0-3.fc30.x86_64.rpm fuse-overlayfs --exclude ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/ # chmod containers.conf and adjust storage.conf to enable Fuse storage. -RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf -RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock +RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf +RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/testing/Dockerfile b/contrib/podmanimage/testing/Dockerfile index 0124879e0..97690360d 100644 --- a/contrib/podmanimage/testing/Dockerfile +++ b/contrib/podmanimage/testing/Dockerfile @@ -18,7 +18,7 @@ RUN useradd podman; yum -y update; yum -y reinstall shadow-utils; yum -y install ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/ # chmod containers.conf and adjust storage.conf to enable Fuse storage. -RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf -RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock +RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf +RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/contrib/podmanimage/upstream/Dockerfile b/contrib/podmanimage/upstream/Dockerfile index 52b3e1d4d..ca7370de9 100644 --- a/contrib/podmanimage/upstream/Dockerfile +++ b/contrib/podmanimage/upstream/Dockerfile @@ -66,7 +66,7 @@ RUN useradd podman; yum -y update; yum -y reinstall shadow-utils; yum -y install ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/ # chmod containers.conf and adjust storage.conf to enable Fuse storage. -RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf -RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock +RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf +RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock ENV _CONTAINERS_USERNS_CONFIGURED="" diff --git a/docs/source/Commands.rst b/docs/source/Commands.rst index aba29bd82..a3ff24e89 100644 --- a/docs/source/Commands.rst +++ b/docs/source/Commands.rst @@ -6,11 +6,13 @@ Commands :doc:`attach <markdown/podman-attach.1>` Attach to a running container +:doc:`auto-update <markdown/podman-auto-update.1>` Auto update containers according to their auto-update policy + :doc:`build <markdown/podman-build.1>` Build an image using instructions from Containerfiles :doc:`commit <markdown/podman-commit.1>` Create new image based on the changed container -:doc:`containers <managecontainers>` Manage Containers +:doc:`container <managecontainers>` Manage Containers :doc:`cp <markdown/podman-cp.1>` Copy files/folders between a container and the local filesystem @@ -52,6 +54,8 @@ Commands :doc:`logs <markdown/podman-logs.1>` Fetch the logs of a container +:doc:`manifest <manifest>` Create and manipulate manifest lists and image indexes + :doc:`mount <markdown/podman-mount.1>` Mount a working container's root filesystem :doc:`network <network>` Manage Networks @@ -100,6 +104,8 @@ Commands :doc:`unshare <markdown/podman-unshare.1>` Run a command in a modified user namespace +:doc:`untag <markdown/podman-untag.1>` Removes one or more names from a locally-stored image + :doc:`version <markdown/podman-version.1>` Display the Podman Version Information :doc:`volume <volume>` Manage volumes diff --git a/docs/source/connection.rst b/docs/source/connection.rst new file mode 100644 index 000000000..64eb18c57 --- /dev/null +++ b/docs/source/connection.rst @@ -0,0 +1,12 @@ +Manage the destination(s) for Podman service(s) +================= + +:doc:`add <markdown/podman-system-connection-add.1>` Record destination for the Podman service + +:doc:`default <markdown/podman-system-connection-default.1>` Set named destination as default for the Podman service + +:doc:`list <markdown/podman-system-connection-list.1>` List the destination for the Podman service(s) + +:doc:`remove <markdown/podman-system-connection-remove.1>` Delete named destination + +:doc:`rename <markdown/podman-system-connection-rename.1>` Rename the destination for Podman service diff --git a/docs/source/image.rst b/docs/source/image.rst index a8c6171e1..fe3a7aa3b 100644 --- a/docs/source/image.rst +++ b/docs/source/image.rst @@ -4,6 +4,8 @@ Image :doc:`build <markdown/podman-build.1>` Build an image using instructions from Containerfiles +:doc:`diff <markdown/podman-image-diff.1>` Inspect changes on an image's filesystem + :doc:`exists <markdown/podman-image-exists.1>` Check if an image exists in local storage :doc:`history <markdown/podman-history.1>` Show history of a specified image @@ -16,6 +18,8 @@ Image :doc:`load <markdown/podman-load.1>` Load an image from container archive +:doc:`mount <markdown/podman-images-mount.1>` Mount an image's root filesystem. + :doc:`prune <markdown/podman-image-prune.1>` Remove unused images :doc:`pull <markdown/podman-pull.1>` Pull an image from a registry @@ -26,6 +30,8 @@ Image :doc:`save <markdown/podman-save.1>` Save image to an archive +:doc:`search <markdown/podman-search.1>` Search a registry for an image + :doc:`sign <markdown/podman-image-sign.1>` Sign an image :doc:`tag <markdown/podman-tag.1>` Add an additional name to a local image @@ -33,3 +39,7 @@ Image :doc:`tree <markdown/podman-image-tree.1>` Prints layer hierarchy of an image in a tree format :doc:`trust <markdown/podman-image-trust.1>` Manage container image trust policy + +:doc:`untag <markdown/podman-untag.1>` Removes one or more names from a locally-stored image + +:doc:`unmount <markdown/podman-unmount.1>` Unmount an image's root filesystem diff --git a/docs/source/index.rst b/docs/source/index.rst index 715ca2744..9a1381080 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -15,6 +15,7 @@ If you are completely new to containers, we recommend that you check out the :do :caption: Contents: Introduction + :doc:`<markdown/podman.1>` Simple management tool for pods, containers and images Commands Reference Tutorials diff --git a/docs/source/managecontainers.rst b/docs/source/managecontainers.rst index 5c5a83a82..2e787c9e9 100644 --- a/docs/source/managecontainers.rst +++ b/docs/source/managecontainers.rst @@ -57,7 +57,7 @@ Manage Containers :doc:`top <markdown/podman-top.1>` Display the running processes of a container -:doc:`umount <markdown/podman-umount.1>` Unmounts working container's root filesystem +:doc:`unmount <markdown/podman-unmount.1>` Unmounts working container's root filesystem :doc:`unpause <markdown/podman-unpause.1>` Unpause the processes in one or more containers diff --git a/docs/source/manifest.rst b/docs/source/manifest.rst new file mode 100644 index 000000000..c63c28502 --- /dev/null +++ b/docs/source/manifest.rst @@ -0,0 +1,14 @@ +Create and manipulate manifest lists and image indexes +================= + +:doc:`add <markdown/podman-manifest-add.1>` Add an image to a manifest list or image index + +:doc:`annotate <markdown/podman-manifest-annotate.1>` Add or update information about an entry in a manifest list or image index + +:doc:`create <markdown/podman-manifest-create.1>` Create a manifest list or image index + +:doc:`inspect <markdown/podman-manifest-inspect.1>` Display a manifest list or image index + +:doc:`push <markdown/podman-manifest-push.1>` Push a manifest list or image index to a registry + +:doc:`remove <markdown/podman-manifest-remove.1>` Remove an image from a manifest list or image index diff --git a/docs/source/markdown/podman-image.1.md b/docs/source/markdown/podman-image.1.md index 55e95d032..bbf5f6d84 100644 --- a/docs/source/markdown/podman-image.1.md +++ b/docs/source/markdown/podman-image.1.md @@ -20,8 +20,8 @@ The image command allows you to manage images | 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. | | list | [podman-images(1)](podman-images.1.md) | List the container images on the system.(alias ls) | -| mount | [podman-image-mount(1)](podman-image-mount.1.md) | Mount an image's root filesystem. | | load | [podman-load(1)](podman-load.1.md) | Load an image from the docker archive. | +| mount | [podman-image-mount(1)](podman-image-mount.1.md) | Mount an image's root filesystem. | | prune | [podman-image-prune(1)](podman-image-prune.1.md) | Remove all unused images from the local store. | | pull | [podman-pull(1)](podman-pull.1.md) | Pull an image from a registry. | | push | [podman-push(1)](podman-push.1.md) | Push an image from local storage to elsewhere. | @@ -30,10 +30,10 @@ The image command allows you to manage images | search | [podman-search(1)](podman-search.1.md) | Search a registry for an image. | | sign | [podman-image-sign(1)](podman-image-sign.1.md) | Create a signature for an image. | | tag | [podman-tag(1)](podman-tag.1.md) | Add an additional name to a local image. | -| untag | [podman-untag(1)](podman-untag.1.md) | Removes one or more names from a locally-stored image. | -| unmount | [podman-image-unmount(1)](podman-image-unmount.1.md) | Unmount an image's root filesystem. | | tree | [podman-image-tree(1)](podman-image-tree.1.md) | Prints layer hierarchy of an image in a tree format. | | trust | [podman-image-trust(1)](podman-image-trust.1.md) | Manage container registry image trust policy. | +| unmount | [podman-image-unmount(1)](podman-image-unmount.1.md) | Unmount an image's root filesystem. | +| untag | [podman-untag(1)](podman-untag.1.md) | Removes one or more names from a locally-stored image. | ## SEE ALSO podman diff --git a/docs/source/markdown/podman-system-connection.1.md b/docs/source/markdown/podman-system-connection.1.md index 86199c6b9..0673aaee1 100644 --- a/docs/source/markdown/podman-system-connection.1.md +++ b/docs/source/markdown/podman-system-connection.1.md @@ -13,13 +13,13 @@ The user will be prompted for the ssh login password or key file pass phrase as ## COMMANDS -| Command | Man Page | Description | -| ------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------- | -| add | [podman-system-connection-add(1)](podman-system-connection-add.1.md) | Record destination for the Podman service | -| default | [podman-system-connection-default(1)](podman-system-connection-default.1.md) | Set named destination as default for the Podman service | -| list | [podman-system-connection-list(1)](podman-system-connection-list.1.md) | List the destination for the Podman service(s) | -| remove | [podman-system-connection-remove(1)](podman-system-connection-remove.1.md) | Delete named destination | -| rename | [podman-system-connection-rename(1)](podman-system-connection-rename.1.md) | Rename the destination for Podman service | +| Command | Man Page | Description | +| -------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------- | +| add | [podman-system-connection\-add(1)](podman-system-connection-add.1.md) | Record destination for the Podman service | +| default | [podman-system-connection\-default(1)](podman-system-connection-default.1.md) | Set named destination as default for the Podman service | +| list | [podman-system-connection\-list(1)](podman-system-connection-list.1.md) | List the destination for the Podman service(s) | +| remove | [podman-system-connection\-remove(1)](podman-system-connection-remove.1.md) | Delete named destination | +| rename | [podman-system-connection\-rename(1)](podman-system-connection-rename.1.md) | Rename the destination for Podman service | ## EXAMPLE ``` diff --git a/docs/source/system.rst b/docs/source/system.rst index 2d93a1d6d..e3dfa9d01 100644 --- a/docs/source/system.rst +++ b/docs/source/system.rst @@ -1,6 +1,8 @@ System ====== +:doc:`connection <markdown/podman-system-conection.1>` Manage the destination(s) for Podman service(s) + :doc:`df <markdown/podman-system-df.1>` Show podman disk usage :doc:`info <markdown/podman-info.1>` Display podman system information @@ -12,3 +14,5 @@ System :doc:`renumber <markdown/podman-system-renumber.1>` Migrate lock numbers :doc:`reset <markdown/podman-system-reset.1>` Reset podman storage + +:doc:`service <markdown/podman-system-service.1>` Run an API service diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index 2575f0e86..9dd5ca465 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -424,6 +424,61 @@ func (s *BoltState) SetNamespace(ns string) error { return nil } +// GetName returns the name associated with a given ID. Since IDs are globally +// unique, it works for both containers and pods. +// Returns ErrNoSuchCtr if the ID does not exist. +func (s *BoltState) GetName(id string) (string, error) { + if id == "" { + return "", define.ErrEmptyID + } + + if !s.valid { + return "", define.ErrDBClosed + } + + idBytes := []byte(id) + + db, err := s.getDBCon() + if err != nil { + return "", err + } + defer s.deferredCloseDBCon(db) + + name := "" + + err = db.View(func(tx *bolt.Tx) error { + idBkt, err := getIDBucket(tx) + if err != nil { + return err + } + + nameBytes := idBkt.Get(idBytes) + if nameBytes == nil { + return define.ErrNoSuchCtr + } + + if s.namespaceBytes != nil { + nsBkt, err := getNSBucket(tx) + if err != nil { + return err + } + + idNs := nsBkt.Get(idBytes) + if !bytes.Equal(idNs, s.namespaceBytes) { + return define.ErrNoSuchCtr + } + } + + name = string(nameBytes) + return nil + }) + if err != nil { + return "", err + } + + return name, nil +} + // Container retrieves a single container from the state by its full ID func (s *BoltState) Container(id string) (*Container, error) { if id == "" { diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go index 2ac05e88d..0de25a6ef 100644 --- a/libpod/in_memory_state.go +++ b/libpod/in_memory_state.go @@ -106,6 +106,36 @@ func (s *InMemoryState) SetNamespace(ns string) error { return nil } +// GetName retrieves the name associated with a given ID. +// Works with both Container and Pod IDs. +func (s *InMemoryState) GetName(id string) (string, error) { + if id == "" { + return "", define.ErrEmptyID + } + + var idIndex *truncindex.TruncIndex + if s.namespace != "" { + nsIndex, ok := s.namespaceIndexes[s.namespace] + if !ok { + // We have no containers in the namespace + // Return false + return "", define.ErrNoSuchCtr + } + idIndex = nsIndex.idIndex + } else { + idIndex = s.idIndex + } + + fullID, err := idIndex.Get(id) + if err != nil { + if err == truncindex.ErrNotExist { + return "", define.ErrNoSuchCtr + } + return "", errors.Wrapf(err, "error performing truncindex lookup for ID %s", id) + } + return fullID, nil +} + // Container retrieves a container from its full ID func (s *InMemoryState) Container(id string) (*Container, error) { if id == "" { diff --git a/libpod/runtime.go b/libpod/runtime.go index 3021ef3f4..8a7053e33 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -732,6 +732,22 @@ func (r *Runtime) GetStore() storage.Store { return r.store } +// GetName retrieves the name associated with a given full ID. +// This works for both containers and pods, and does not distinguish between the +// two. +// If the given ID does not correspond to any existing Pod or Container, +// ErrNoSuchCtr is returned. +func (r *Runtime) GetName(id string) (string, error) { + r.lock.RLock() + defer r.lock.RUnlock() + + if !r.valid { + return "", define.ErrRuntimeStopped + } + + return r.state.GetName(id) +} + // DBConfig is a set of Libpod runtime configuration settings that are saved in // a State when it is first created, and can subsequently be retrieved. type DBConfig struct { diff --git a/libpod/state.go b/libpod/state.go index 6206a2994..44632b02f 100644 --- a/libpod/state.go +++ b/libpod/state.go @@ -43,6 +43,12 @@ type State interface { // containers and pods in all namespaces will be returned. SetNamespace(ns string) error + // Resolve an ID into a Name. Since Podman names and IDs are globally + // unique between Pods and Containers, the ID may belong to either a pod + // or container. Despite this, we will always return ErrNoSuchCtr if the + // ID does not exist. + GetName(id string) (string, error) + // Return a container from the database from its full ID. // If the container is not in the set namespace, an error will be // returned. diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go index 47ea6c40d..e343a9e0c 100644 --- a/pkg/api/handlers/libpod/containers.go +++ b/pkg/api/handlers/libpod/containers.go @@ -41,7 +41,6 @@ func ListContainers(w http.ResponseWriter, r *http.Request) { Last int `schema:"last"` // alias for limit Limit int `schema:"limit"` Namespace bool `schema:"namespace"` - Pod bool `schema:"pod"` Size bool `schema:"size"` Sync bool `schema:"sync"` }{ @@ -72,7 +71,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) { Size: query.Size, Sort: "", Namespace: query.Namespace, - Pod: query.Pod, + Pod: true, Sync: query.Sync, } pss, err := ps.GetContainerLists(runtime, opts) diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index edc1ee3c8..0ad5d29ea 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -661,11 +661,10 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // type: boolean // description: Include namespace information // default: false - // - in: query // name: pod // type: boolean // default: false - // description: Include Pod ID and Name if applicable + // description: Ignored. Previously included details on pod name and ID that are currently included by default. // - in: query // name: size // type: boolean diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go index 9913b773b..c1eb23233 100644 --- a/pkg/bindings/containers/containers.go +++ b/pkg/bindings/containers/containers.go @@ -24,7 +24,7 @@ var ( // the most recent number of containers. The pod and size booleans indicate that pod information and rootfs // size information should also be included. Finally, the sync bool synchronizes the OCI runtime and // container state. -func List(ctx context.Context, filters map[string][]string, all *bool, last *int, pod, size, sync *bool) ([]entities.ListContainer, error) { // nolint:typecheck +func List(ctx context.Context, filters map[string][]string, all *bool, last *int, size, sync *bool) ([]entities.ListContainer, error) { // nolint:typecheck conn, err := bindings.GetClient(ctx) if err != nil { return nil, err @@ -37,9 +37,6 @@ func List(ctx context.Context, filters map[string][]string, all *bool, last *int if last != nil { params.Set("limit", strconv.Itoa(*last)) } - if pod != nil { - params.Set("pod", strconv.FormatBool(*pod)) - } if size != nil { params.Set("size", strconv.FormatBool(*size)) } diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go index 9a188e5da..db5be4909 100644 --- a/pkg/bindings/test/containers_test.go +++ b/pkg/bindings/test/containers_test.go @@ -510,7 +510,7 @@ var _ = Describe("Podman containers ", func() { Expect(err).To(BeNil()) _, err = bt.RunTopContainer(&name2, bindings.PFalse, nil) Expect(err).To(BeNil()) - containerLatestList, err := containers.List(bt.conn, nil, nil, &latestContainers, nil, nil, nil) + containerLatestList, err := containers.List(bt.conn, nil, nil, &latestContainers, nil, nil) Expect(err).To(BeNil()) err = containers.Kill(bt.conn, containerLatestList[0].Names[0], "SIGTERM") Expect(err).To(BeNil()) @@ -755,8 +755,23 @@ var _ = Describe("Podman containers ", func() { // Validate list container with id filter filters := make(map[string][]string) filters["id"] = []string{cid} - c, err := containers.List(bt.conn, filters, bindings.PTrue, nil, nil, nil, nil) + c, err := containers.List(bt.conn, filters, bindings.PTrue, nil, nil, nil) Expect(err).To(BeNil()) Expect(len(c)).To(Equal(1)) }) + + It("List containers always includes pod information", func() { + podName := "testpod" + ctrName := "testctr" + bt.Podcreate(&podName) + _, err := bt.RunTopContainer(&ctrName, bindings.PTrue, &podName) + Expect(err).To(BeNil()) + + lastNum := 1 + + c, err := containers.List(bt.conn, nil, bindings.PTrue, &lastNum, nil, nil) + Expect(err).To(BeNil()) + Expect(len(c)).To(Equal(1)) + Expect(c[0].PodName).To(Equal(podName)) + }) }) diff --git a/pkg/domain/entities/container_ps.go b/pkg/domain/entities/container_ps.go index 50dd4933b..ed40a37ab 100644 --- a/pkg/domain/entities/container_ps.go +++ b/pkg/domain/entities/container_ps.go @@ -56,6 +56,8 @@ type ListContainer struct { StartedAt int64 // State of container State string + // Status is a human-readable approximation of a duration for json output + Status string } // ListContainer Namespaces contains the identifiers of the container's Linux namespaces diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go index 93c4ede49..0b73ddd7e 100644 --- a/pkg/domain/infra/abi/generate.go +++ b/pkg/domain/infra/abi/generate.go @@ -20,9 +20,10 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string, if ctrErr == nil { // Generate the unit for the container. s, err := generate.ContainerUnit(ctr, options) - if err == nil { - return &entities.GenerateSystemdReport{Output: s}, nil + if err != nil { + return nil, err } + return &entities.GenerateSystemdReport{Output: s}, nil } // If it's not a container, we either have a pod or garbage. diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 35675e1f3..70d740bb5 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -226,7 +226,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti if err != nil { imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, rawImage)) if err != nil { - return nil, errors.Errorf("invalid image reference %q", rawImage) + return nil, errors.Wrapf(err, "invalid image reference %q", rawImage) } } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index d2221ab7b..cc919561f 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -496,7 +496,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri } func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) { - return containers.List(ic.ClientCxt, options.Filters, &options.All, &options.Last, &options.Pod, &options.Size, &options.Sync) + return containers.List(ic.ClientCxt, options.Filters, &options.All, &options.Last, &options.Size, &options.Sync) } func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) { diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go index 91a49cd02..0c38a3326 100644 --- a/pkg/domain/infra/tunnel/helpers.go +++ b/pkg/domain/infra/tunnel/helpers.go @@ -20,7 +20,7 @@ func getContainersByContext(contextWithConnection context.Context, all bool, nam if all && len(namesOrIDs) > 0 { return nil, errors.New("cannot lookup containers and all") } - c, err := containers.List(contextWithConnection, nil, bindings.PTrue, nil, nil, nil, bindings.PTrue) + c, err := containers.List(contextWithConnection, nil, bindings.PTrue, nil, nil, bindings.PTrue) if err != nil { return nil, err } diff --git a/pkg/ps/ps.go b/pkg/ps/ps.go index 8163d7247..4c5f60844 100644 --- a/pkg/ps/ps.go +++ b/pkg/ps/ps.go @@ -175,11 +175,14 @@ func ListContainerBatch(rt *libpod.Runtime, ctr *libpod.Container, opts entities State: conState.String(), } if opts.Pod && len(conConfig.Pod) > 0 { - pod, err := rt.GetPod(conConfig.Pod) + podName, err := rt.GetName(conConfig.Pod) if err != nil { + if errors.Cause(err) == define.ErrNoSuchCtr { + return entities.ListContainer{}, errors.Wrapf(define.ErrNoSuchPod, "could not find container %s pod (id %s) in state", conConfig.ID, conConfig.Pod) + } return entities.ListContainer{}, err } - ps.PodName = pod.Name() + ps.PodName = podName } if opts.Namespace { diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index 78cd32253..ee9f63680 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -96,8 +96,10 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image finalCommand = append(finalCommand, entrypoint...) + // Only use image command if the user did not manually set an + // entrypoint. command := s.Command - if command == nil && img != nil { + if command == nil && img != nil && s.Entrypoint == nil { newCmd, err := img.Cmd(ctx) if err != nil { return nil, err diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index d114744c4..60d9162d1 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -53,6 +53,18 @@ var _ = Describe("Podman generate systemd", func() { Expect(session).To(ExitWithError()) }) + It("podman generate systemd bad restart-policy value", func() { + session := podmanTest.Podman([]string{"create", "--name", "foobar", "alpine", "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"generate", "systemd", "--restart-policy", "bogus", "foobar"}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + found, _ := session.ErrorGrepString("Error: bogus is not a valid restart policy") + Expect(found).Should(BeTrue()) + }) + It("podman generate systemd good timeout value", func() { session := podmanTest.Podman([]string{"create", "--name", "foobar", "alpine", "top"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index f10ef5c99..a734d399d 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -188,6 +188,21 @@ var _ = Describe("Podman ps", func() { Expect(result.IsJSONOutputValid()).To(BeTrue()) }) + It("podman ps print a human-readable `Status` with json format", func() { + _, ec, _ := podmanTest.RunLsContainer("test1") + Expect(ec).To(Equal(0)) + + result := podmanTest.Podman([]string{"ps", "-a", "--format", "json"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(result.IsJSONOutputValid()).To(BeTrue()) + // must contain "Status" + match, StatusLine := result.GrepString(`Status`) + Expect(match).To(BeTrue()) + // container is running or exit, so it must contain `ago` + Expect(StatusLine[0]).To(ContainSubstring("ago")) + }) + It("podman ps namespace flag with go template format", func() { Skip(v2fail) _, ec, _ := podmanTest.RunLsContainer("test1") diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 9cb76d1f6..dc44d3b3f 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -1143,7 +1143,7 @@ USER mail` Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask")) }) - It("podman run makes entrypoint from image", func() { + It("podman run makes workdir from image", func() { // BuildImage does not seem to work remote SkipIfRemote() dockerfile := `FROM busybox @@ -1154,4 +1154,13 @@ WORKDIR /madethis` Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("/madethis")) }) + + It("podman run --entrypoint does not use image command", func() { + session := podmanTest.Podman([]string{"run", "--entrypoint", "/bin/echo", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + // We can't guarantee the output is completely empty, some + // nonprintables seem to work their way in. + Expect(session.OutputToString()).To(Not(ContainSubstring("/bin/sh"))) + }) }) diff --git a/test/system/120-load.bats b/test/system/120-load.bats index 4825eed07..2fcabcd8a 100644 --- a/test/system/120-load.bats +++ b/test/system/120-load.bats @@ -28,8 +28,6 @@ verify_iid_and_name() { @test "podman load - by image ID" { - skip_if_remote "FIXME: pending #7123" - # FIXME: how to build a simple archive instead? get_iid_and_name diff --git a/transfer.md b/transfer.md index 9aa271c37..49ff687e6 100644 --- a/transfer.md +++ b/transfer.md @@ -38,10 +38,10 @@ There are other equivalents for these tools | Existing Step | `Podman` (and friends) | | :--- | :--- | | `docker attach` | [`podman attach`](./docs/source/markdown/podman-attach.1.md) | -| `docker cp` | [`podman cp`](./docs/source/markdown/podman-cp.1.md) | | `docker build` | [`podman build`](./docs/source/markdown/podman-build.1.md) | | `docker commit` | [`podman commit`](./docs/source/markdown/podman-commit.1.md) | | `docker container`|[`podman container`](./docs/source/markdown/podman-container.1.md) | +| `docker cp` | [`podman cp`](./docs/source/markdown/podman-cp.1.md) | | `docker create` | [`podman create`](./docs/source/markdown/podman-create.1.md) | | `docker diff` | [`podman diff`](./docs/source/markdown/podman-diff.1.md) | | `docker events` | [`podman events`](./docs/source/markdown/podman-events.1.md) | @@ -59,10 +59,10 @@ There are other equivalents for these tools | `docker network ls` | [`podman network ls`](./docs/source/markdown/podman-network-ls.1.md) | | `docker network rm` | [`podman network rm`](./docs.source/markdown/podman-network-rm.1.md) | | `docker pause` | [`podman pause`](./docs/source/markdown/podman-pause.1.md) | +| `docker port` | [`podman port`](./docs/source/markdown/podman-port.1.md) | | `docker ps` | [`podman ps`](./docs/source/markdown/podman-ps.1.md) | | `docker pull` | [`podman pull`](./docs/source/markdown/podman-pull.1.md) | | `docker push` | [`podman push`](./docs/source/markdown/podman-push.1.md) | -| `docker port` | [`podman port`](./docs/source/markdown/podman-port.1.md) | | `docker restart` | [`podman restart`](./docs/source/markdown/podman-restart.1.md) | | `docker rm` | [`podman rm`](./docs/source/markdown/podman-rm.1.md) | | `docker rmi` | [`podman rmi`](./docs/source/markdown/podman-rmi.1.md) | @@ -71,20 +71,20 @@ There are other equivalents for these tools | `docker search` | [`podman search`](./docs/source/markdown/podman-search.1.md) | | `docker start` | [`podman start`](./docs/source/markdown/podman-start.1.md) | | `docker stop` | [`podman stop`](./docs/source/markdown/podman-stop.1.md) | +| `docker system df` | [`podman system df`](./docs/source/markdown/podman-system-df.1.md) | +| `docker system info` | [`podman system info`](./docs/source/markdown/podman-system-info.1.md) | +| `docker system prune` | [`podman system prune`](./docs/source/markdown/podman-system-prune.1.md) | +| `docker system` | [`podman system`](./docs/source/markdown/podman-system.1.md) | | `docker tag` | [`podman tag`](./docs/source/markdown/podman-tag.1.md) | | `docker top` | [`podman top`](./docs/source/markdown/podman-top.1.md) | | `docker unpause` | [`podman unpause`](./docs/source/markdown/podman-unpause.1.md) | | `docker version` | [`podman version`](./docs/source/markdown/podman-version.1.md) | -| `docker volume` | [`podman volume`](./docs/source/markdown/podman-volume.1.md) | | `docker volume create` | [`podman volume create`](./docs/source/markdown/podman-volume-create.1.md) | | `docker volume inspect`| [`podman volume inspect`](./docs/source/markdown/podman-volume-inspect.1.md)| | `docker volume ls` | [`podman volume ls`](./docs/source/markdown/podman-volume-ls.1.md) | | `docker volume prune` | [`podman volume prune`](./docs/source/markdown/podman-volume-prune.1.md) | | `docker volume rm` | [`podman volume rm`](./docs/source/markdown/podman-volume-rm.1.md) | -| `docker system` | [`podman system`](./docs/source/markdown/podman-system.1.md) | -| `docker system df` | [`podman system df`](./docs/source/markdown/podman-system-df.1.md) | -| `docker system prune` | [`podman system prune`](./docs/source/markdown/podman-system-prune.1.md) | -| `docker system info` | [`podman system info`](./docs/source/markdown/podman-system-info.1.md) | +| `docker volume` | [`podman volume`](./docs/source/markdown/podman-volume.1.md) | | `docker wait` | [`podman wait`](./docs/source/markdown/podman-wait.1.md) | **** Use mount to take advantage of the entire linux tool chain rather then just cp. Read [`here`](./docs/podman-cp.1.md) for more information. @@ -95,8 +95,8 @@ Those Docker commands currently do not have equivalents in `podman`: | Missing command | Description| | :--- | :--- | -| `docker container update` | podman does not support altering running containers. We recommend recreating containers with the correct arguments.| | `docker container rename` | podman does not support `container rename` - or the `rename` shorthand. We recommend using `podman rm` and `podman create` to create a container with a specific name.| +| `docker container update` | podman does not support altering running containers. We recommend recreating containers with the correct arguments.| | `docker node` || | `docker plugin` | podman does not support plugins. We recommend you use alternative OCI Runtimes or OCI Runtime Hooks to alter behavior of podman.| | `docker secret` || @@ -108,22 +108,21 @@ Those Docker commands currently do not have equivalents in `podman`: The following podman commands do not have a Docker equivalent: -* [`podman generate`](./docs/source/markdown/podman-generate.1.md) -* [`podman generate kube`](./docs/source/markdown/podman-generate-kube.1.md) * [`podman container checkpoint`](/docs/source/markdown/podman-container-checkpoint.1.md) * [`podman container cleanup`](/docs/source/markdown/podman-container-cleanup.1.md) * [`podman container exists`](/docs/source/markdown/podman-container-exists.1.md) * [`podman container refresh`](/docs/source/markdown/podman-container-refresh.1.md) -* [`podman container runlabel`](/docs/source/markdown/podman-container-runlabel.1.md) * [`podman container restore`](/docs/source/markdown/podman-container-restore.1.md) +* [`podman container runlabel`](/docs/source/markdown/podman-container-runlabel.1.md) +* [`podman generate kube`](./docs/source/markdown/podman-generate-kube.1.md) +* [`podman generate`](./docs/source/markdown/podman-generate.1.md) * [`podman healthcheck run`](/docs/source/markdown/podman-healthcheck-run.1.md) * [`podman image exists`](./docs/source/markdown/podman-image-exists.1.md) * [`podman image sign`](./docs/source/markdown/podman-image-sign.1.md) * [`podman image trust`](./docs/source/markdown/podman-image-trust.1.md) * [`podman mount`](./docs/source/markdown/podman-mount.1.md) -* [`podman play`](./docs/source/markdown/podman-play.1.md) * [`podman play kube`](./docs/source/markdown/podman-play-kube.1.md) -* [`podman pod`](./docs/source/markdown/podman-pod.1.md) +* [`podman play`](./docs/source/markdown/podman-play.1.md) * [`podman pod create`](./docs/source/markdown/podman-pod-create.1.md) * [`podman pod exists`](./docs/source/markdown/podman-pod-exists.1.md) * [`podman pod inspect`](./docs/source/markdown/podman-pod-inspect.1.md) @@ -136,4 +135,5 @@ The following podman commands do not have a Docker equivalent: * [`podman pod stop`](./docs/source/markdown/podman-pod-stop.1.md) * [`podman pod top`](./docs/source/markdown/podman-pod-top.1.md) * [`podman pod unpause`](./docs/source/markdown/podman-pod-unpause.1.md) +* [`podman pod`](./docs/source/markdown/podman-pod.1.md) * [`podman umount`](./docs/source/markdown/podman-umount.1.md) |