diff options
-rw-r--r-- | cmd/podman/common/create_opts.go | 6 | ||||
-rw-r--r-- | cmd/podman/containers/kill.go | 2 | ||||
-rw-r--r-- | cmd/podman/containers/stop.go | 2 | ||||
-rw-r--r-- | cmd/podman/root.go | 2 | ||||
-rw-r--r-- | docs/source/markdown/podman-run.1.md | 2 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 28 | ||||
-rw-r--r-- | libpod/runtime_img.go | 5 | ||||
-rw-r--r-- | libpod/runtime_pod_infra_linux.go | 5 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images.go | 14 | ||||
-rw-r--r-- | pkg/bindings/connection.go | 2 | ||||
-rw-r--r-- | pkg/domain/entities/containers.go | 10 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 26 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 22 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/helpers.go | 23 | ||||
-rw-r--r-- | test/apiv2/10-images.at | 7 | ||||
-rw-r--r-- | test/e2e/common_test.go | 11 | ||||
-rw-r--r-- | test/e2e/kill_test.go | 13 | ||||
-rw-r--r-- | test/e2e/pod_create_test.go | 14 | ||||
-rw-r--r-- | test/e2e/run_working_dir_test.go | 6 | ||||
-rw-r--r-- | test/e2e/start_test.go | 17 | ||||
-rw-r--r-- | test/e2e/stop_test.go | 6 | ||||
-rw-r--r-- | test/python/docker/test_containers.py | 7 | ||||
-rw-r--r-- | test/system/030-run.bats | 6 | ||||
-rw-r--r-- | test/system/070-build.bats | 25 |
24 files changed, 206 insertions, 55 deletions
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index 430354ee9..c1523b6c1 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -223,7 +223,11 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup // publish for port, pbs := range cc.HostConfig.PortBindings { for _, pb := range pbs { - hostport, err := strconv.Atoi(pb.HostPort) + var hostport int + var err error + if pb.HostPort != "" { + hostport, err = strconv.Atoi(pb.HostPort) + } if err != nil { return nil, nil, err } diff --git a/cmd/podman/containers/kill.go b/cmd/podman/containers/kill.go index 36e3e5f59..990a6e3e7 100644 --- a/cmd/podman/containers/kill.go +++ b/cmd/podman/containers/kill.go @@ -111,7 +111,7 @@ func kill(_ *cobra.Command, args []string) error { } for _, r := range responses { if r.Err == nil { - fmt.Println(r.Id) + fmt.Println(r.RawInput) } else { errs = append(errs, r.Err) } diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go index 7338c8d98..1fe41a1bd 100644 --- a/cmd/podman/containers/stop.go +++ b/cmd/podman/containers/stop.go @@ -115,7 +115,7 @@ func stop(cmd *cobra.Command, args []string) error { } for _, r := range responses { if r.Err == nil { - fmt.Println(r.Id) + fmt.Println(r.RawInput) } else { errs = append(errs, r.Err) } diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 0ee530242..1f613a4c5 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -158,7 +158,7 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { // Prep the engines if _, err := registry.NewImageEngine(cmd, args); err != nil { - return errors.Wrapf(err, "Cannot connect to the Podman socket, make sure there is a Podman REST API service running.") + return err } if _, err := registry.NewContainerEngine(cmd, args); err != nil { return err diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 49b45f4f8..8c0b12e90 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -714,7 +714,7 @@ Override the OS, defaults to hosts, of the image to be pulled. For example, `win #### **--pid**=*mode* Set the PID namespace mode for the container. -The efault is to create a private PID namespace for the container. +The default is to create a private PID namespace for the container. - **container:**_id_: join another container's PID namespace; - **host**: use the host's PID namespace for the container. Note the host mode gives the container full access to local PID and is therefore considered insecure; diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index a3476f42e..2360d0737 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -21,6 +21,7 @@ import ( cnitypes "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/plugins/pkg/ns" + "github.com/containers/buildah/pkg/chrootuser" "github.com/containers/buildah/pkg/overlay" "github.com/containers/common/pkg/apparmor" "github.com/containers/common/pkg/config" @@ -203,10 +204,17 @@ func (c *Container) resolveWorkDir() error { } logrus.Debugf("Workdir %q resolved to host path %q", workdir, resolvedWorkdir) - // No need to create it (e.g., `--workdir=/foo`), so let's make sure - // the path exists on the container. + st, err := os.Stat(resolvedWorkdir) + if err == nil { + if !st.IsDir() { + return errors.Errorf("workdir %q exists on container %s, but is not a directory", workdir, c.ID()) + } + return nil + } if !c.config.CreateWorkingDir { - if _, err := os.Stat(resolvedWorkdir); err != nil { + // No need to create it (e.g., `--workdir=/foo`), so let's make sure + // the path exists on the container. + if err != nil { if os.IsNotExist(err) { return errors.Errorf("workdir %q does not exist on container %s", workdir, c.ID()) } @@ -216,11 +224,6 @@ func (c *Container) resolveWorkDir() error { } return nil } - - // Ensure container entrypoint is created (if required). - rootUID := c.RootUID() - rootGID := c.RootGID() - if err := os.MkdirAll(resolvedWorkdir, 0755); err != nil { if os.IsExist(err) { return nil @@ -228,7 +231,12 @@ func (c *Container) resolveWorkDir() error { return errors.Wrapf(err, "error creating container %s workdir", c.ID()) } - if err := os.Chown(resolvedWorkdir, rootUID, rootGID); err != nil { + // Ensure container entrypoint is created (if required). + uid, gid, _, err := chrootuser.GetUser(c.state.Mountpoint, c.User()) + if err != nil { + return errors.Wrapf(err, "error looking up %s inside of the container %s", c.User(), c.ID()) + } + if err := os.Chown(resolvedWorkdir, int(uid), int(gid)); err != nil { return errors.Wrapf(err, "error chowning container %s workdir to container root", c.ID()) } @@ -458,7 +466,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { break } } - if !hasHomeSet { + if !hasHomeSet && execUser.Home != "" { c.config.Spec.Process.Env = append(c.config.Spec.Process.Env, fmt.Sprintf("HOME=%s", execUser.Home)) } diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index f56fa8cce..fcc52b392 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -166,6 +166,11 @@ func (r *Runtime) newImageBuildCompleteEvent(idOrName string) { // Build adds the runtime to the imagebuildah call func (r *Runtime) Build(ctx context.Context, options imagebuildah.BuildOptions, dockerfiles ...string) (string, reference.Canonical, error) { + if options.Runtime == "" { + // Make sure that build containers use the same runtime as Podman (see #9365). + conf := util.DefaultContainerConfig() + options.Runtime = conf.Engine.OCIRuntime + } id, ref, err := imagebuildah.BuildDockerfiles(ctx, r.store, options, dockerfiles...) // Write event for build completion r.newImageBuildCompleteEvent(id) diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index bc37bdb23..c6f268182 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -225,7 +225,10 @@ func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container, if err != nil { return nil, err } - imageName := newImage.Names()[0] + imageName := "none" + if len(newImage.Names()) > 0 { + imageName = newImage.Names()[0] + } imageID := data.ID return r.makeInfraContainer(ctx, p, imageName, r.config.Engine.InfraImage, imageID, data.Config) diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 85708912b..0d75d1a94 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/containers/buildah" - "github.com/containers/common/pkg/config" "github.com/containers/image/v5/manifest" "github.com/containers/podman/v2/libpod" image2 "github.com/containers/podman/v2/libpod/image" @@ -18,6 +17,7 @@ import ( "github.com/containers/podman/v2/pkg/api/handlers/utils" "github.com/containers/podman/v2/pkg/auth" "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/containers/podman/v2/pkg/util" "github.com/gorilla/schema" "github.com/opencontainers/go-digest" "github.com/pkg/errors" @@ -236,16 +236,6 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { if sys := runtime.SystemContext(); sys != nil { registryOpts.DockerCertPath = sys.DockerCertPath } - rtc, err := runtime.GetConfig() - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) - return - } - pullPolicy, err := config.ValidatePullPolicy(rtc.Engine.PullPolicy) - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) - return - } img, err := runtime.ImageRuntime().New(r.Context(), fromImage, "", // signature policy @@ -254,7 +244,7 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { ®istryOpts, image2.SigningOptions{}, nil, // label - pullPolicy, + util.PullImageAlways, ) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go index 7b26037eb..6ff072e75 100644 --- a/pkg/bindings/connection.go +++ b/pkg/bindings/connection.go @@ -124,7 +124,7 @@ func NewConnectionWithIdentity(ctx context.Context, uri string, identity string) ctx = context.WithValue(ctx, clientKey, &connection) if err := pingNewConnection(ctx); err != nil { - return nil, err + return nil, errors.Wrap(err, "cannot connect to the Podman socket, please verify that Podman REST API service is running") } return ctx, nil } diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index 2d50d6826..116da888d 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -88,8 +88,9 @@ type StopOptions struct { } type StopReport struct { - Err error - Id string //nolint + Err error + Id string //nolint + RawInput string } type TopOptions struct { @@ -109,8 +110,9 @@ type KillOptions struct { } type KillReport struct { - Err error - Id string //nolint + Err error + Id string //nolint + RawInput string } type RestartOptions struct { diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 7a672d863..0ee4048d1 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -138,10 +138,16 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st } func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []string, options entities.StopOptions) ([]*entities.StopReport, error) { names := namesOrIds - ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod) + ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, names, ic.Libpod) if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) { return nil, err } + ctrMap := map[string]string{} + if len(rawInputs) == len(ctrs) { + for i := range ctrs { + ctrMap[ctrs[i].ID()] = rawInputs[i] + } + } errMap, err := parallelctr.ContainerOp(ctx, ctrs, func(c *libpod.Container) error { var err error if options.Timeout != nil { @@ -174,6 +180,11 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin for ctr, err := range errMap { report := new(entities.StopReport) report.Id = ctr.ID() + if options.All { + report.RawInput = ctr.ID() + } else { + report.RawInput = ctrMap[ctr.ID()] + } report.Err = err reports = append(reports, report) } @@ -197,15 +208,22 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin if err != nil { return nil, err } - ctrs, err := getContainersByContext(options.All, options.Latest, namesOrIds, ic.Libpod) + ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, namesOrIds, ic.Libpod) if err != nil { return nil, err } + ctrMap := map[string]string{} + if len(rawInputs) == len(ctrs) { + for i := range ctrs { + ctrMap[ctrs[i].ID()] = rawInputs[i] + } + } reports := make([]*entities.KillReport, 0, len(ctrs)) for _, con := range ctrs { reports = append(reports, &entities.KillReport{ - Id: con.ID(), - Err: con.Kill(uint(sig)), + Id: con.ID(), + Err: con.Kill(uint(sig)), + RawInput: ctrMap[con.ID()], }) } return reports, nil diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index c2c282ef9..b0a07cd27 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -82,16 +82,23 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []string, opts entities.StopOptions) ([]*entities.StopReport, error) { reports := []*entities.StopReport{} - ctrs, err := getContainersByContext(ic.ClientCtx, opts.All, opts.Ignore, namesOrIds) + ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, opts.All, opts.Ignore, namesOrIds) if err != nil { return nil, err } + ctrMap := map[string]string{} + for i := range ctrs { + ctrMap[ctrs[i].ID] = rawInputs[i] + } options := new(containers.StopOptions).WithIgnore(opts.Ignore) if to := opts.Timeout; to != nil { options.WithTimeout(*to) } for _, c := range ctrs { - report := entities.StopReport{Id: c.ID} + report := entities.StopReport{ + Id: c.ID, + RawInput: ctrMap[c.ID], + } if err = containers.Stop(ic.ClientCtx, c.ID, options); err != nil { // These first two are considered non-fatal under the right conditions if errors.Cause(err).Error() == define.ErrCtrStopped.Error() { @@ -117,16 +124,21 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin } func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []string, opts entities.KillOptions) ([]*entities.KillReport, error) { - ctrs, err := getContainersByContext(ic.ClientCtx, opts.All, false, namesOrIds) + ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, opts.All, false, namesOrIds) if err != nil { return nil, err } + ctrMap := map[string]string{} + for i := range ctrs { + ctrMap[ctrs[i].ID] = rawInputs[i] + } options := new(containers.KillOptions).WithSignal(opts.Signal) reports := make([]*entities.KillReport, 0, len(ctrs)) for _, c := range ctrs { reports = append(reports, &entities.KillReport{ - Id: c.ID, - Err: containers.Kill(ic.ClientCtx, c.ID, options), + Id: c.ID, + Err: containers.Kill(ic.ClientCtx, c.ID, options), + RawInput: ctrMap[c.ID], }) } return reports, nil diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go index e40e27596..5fa70bffa 100644 --- a/pkg/domain/infra/tunnel/helpers.go +++ b/pkg/domain/infra/tunnel/helpers.go @@ -14,16 +14,26 @@ import ( // FIXME: the `ignore` parameter is very likely wrong here as it should rather // be used on *errors* from operations such as remove. func getContainersByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, error) { + ctrs, _, err := getContainersAndInputByContext(contextWithConnection, all, ignore, namesOrIDs) + return ctrs, err +} + +func getContainersAndInputByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, []string, error) { if all && len(namesOrIDs) > 0 { - return nil, errors.New("cannot lookup containers and all") + return nil, nil, errors.New("cannot lookup containers and all") } options := new(containers.ListOptions).WithAll(true).WithSync(true) allContainers, err := containers.List(contextWithConnection, options) if err != nil { - return nil, err + return nil, nil, err } + rawInputs := []string{} if all { - return allContainers, err + for i := range allContainers { + rawInputs = append(rawInputs, allContainers[i].ID) + } + + return allContainers, rawInputs, err } // Note: it would be nicer if the lists endpoint would support that as @@ -42,7 +52,7 @@ func getContainersByContext(contextWithConnection context.Context, all, ignore b if ignore && errorhandling.Contains(err, define.ErrNoSuchCtr) { continue } - return nil, err + return nil, nil, err } // Now we can do a full match of the ID to find the right @@ -52,16 +62,17 @@ func getContainersByContext(contextWithConnection context.Context, all, ignore b for _, ctr := range allContainers { if ctr.ID == inspectData.ID { filtered = append(filtered, ctr) + rawInputs = append(rawInputs, nameOrID) found = true break } } if !found && !ignore { - return nil, errors.Wrapf(define.ErrNoSuchCtr, "unable to find container %q", nameOrID) + return nil, nil, errors.Wrapf(define.ErrNoSuchCtr, "unable to find container %q", nameOrID) } } - return filtered, nil + return filtered, rawInputs, nil } func getPodsByContext(contextWithConnection context.Context, all bool, namesOrIDs []string) ([]*entities.ListPodsReport, error) { diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at index 693c34ced..a650cf958 100644 --- a/test/apiv2/10-images.at +++ b/test/apiv2/10-images.at @@ -45,6 +45,13 @@ t POST "images/create?fromImage=alpine" '' 200 .error=null .status~".*Download c t POST "images/create?fromImage=alpine&tag=latest" '' 200 +# Make sure that new images are pulled +old_iid=$(podman image inspect --format "{{.ID}}" docker.io/library/alpine:latest) +podman rmi -f docker.io/library/alpine:latest +podman tag $IMAGE docker.io/library/alpine:latest +t POST "images/create?fromImage=alpine" '' 200 .error=null .status~".*$old_iid.*" +podman untag $IMAGE docker.io/library/alpine:latest + t POST "images/create?fromImage=quay.io/libpod/alpine&tag=sha256:fa93b01658e3a5a1686dc3ae55f170d8de487006fb53a28efcd12ab0710a2e5f" '' 200 # Display the image history diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index d033cc646..12b30b2c5 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -436,13 +436,20 @@ func (p *PodmanTestIntegration) RunLsContainerInPod(name, pod string) (*PodmanSe // BuildImage uses podman build and buildah to build an image // called imageName based on a string dockerfile -func (p *PodmanTestIntegration) BuildImage(dockerfile, imageName string, layers string) { +func (p *PodmanTestIntegration) BuildImage(dockerfile, imageName string, layers string) string { dockerfilePath := filepath.Join(p.TempDir, "Dockerfile") err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) Expect(err).To(BeNil()) - session := p.Podman([]string{"build", "--layers=" + layers, "-t", imageName, "--file", dockerfilePath, p.TempDir}) + cmd := []string{"build", "--layers=" + layers, "--file", dockerfilePath} + if len(imageName) > 0 { + cmd = append(cmd, []string{"-t", imageName}...) + } + cmd = append(cmd, p.TempDir) + session := p.Podman(cmd) session.Wait(240) Expect(session).Should(Exit(0), fmt.Sprintf("BuildImage session output: %q", session.OutputToString())) + output := session.OutputToStringArray() + return output[len(output)-1] } // PodmanPID execs podman and returns its PID diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go index c1c1b003e..6d6fe788b 100644 --- a/test/e2e/kill_test.go +++ b/test/e2e/kill_test.go @@ -51,6 +51,19 @@ var _ = Describe("Podman kill", func() { Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) + It("podman container kill a running container by short id", func() { + session := podmanTest.RunTopContainer("") + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + cid := session.OutputToString() + + result := podmanTest.Podman([]string{"container", "kill", cid[:5]}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(result.OutputToString()).To(Equal(cid[:5])) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + }) + It("podman kill a running container by id", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index e57712f62..0a7a5101e 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -501,4 +501,18 @@ entrypoint ["/fromimage"] Expect(session.OutputToString()).To(ContainSubstring("inet 127.0.0.1/8 scope host lo")) Expect(len(session.OutputToStringArray())).To(Equal(1)) }) + + It("podman pod create --infra-image w/untagged image", func() { + podmanTest.AddImageToRWStore(ALPINE) + dockerfile := `FROM quay.io/libpod/alpine:latest +ENTRYPOINT ["sleep","99999"] + ` + // This builds a none/none image + iid := podmanTest.BuildImage(dockerfile, "", "true") + + create := podmanTest.Podman([]string{"pod", "create", "--infra-image", iid}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(BeZero()) + }) + }) diff --git a/test/e2e/run_working_dir_test.go b/test/e2e/run_working_dir_test.go index 59538448e..948ed05e7 100644 --- a/test/e2e/run_working_dir_test.go +++ b/test/e2e/run_working_dir_test.go @@ -47,7 +47,7 @@ var _ = Describe("Podman run", func() { It("podman run a container on an image with a workdir", func() { dockerfile := `FROM alpine -RUN mkdir -p /home/foobar +RUN mkdir -p /home/foobar /etc/foobar; chown bin:bin /etc/foobar WORKDIR /etc/foobar` podmanTest.BuildImage(dockerfile, "test", "false") @@ -56,6 +56,10 @@ WORKDIR /etc/foobar` Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(Equal("/etc/foobar")) + session = podmanTest.Podman([]string{"run", "test", "ls", "-ld", "."}) + session.WaitWithDefaultTimeout() + Expect(session.LineInOutputContains("bin")).To(BeTrue()) + session = podmanTest.Podman([]string{"run", "--workdir", "/home/foobar", "test", "pwd"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index a6f22e007..74be105d8 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -95,6 +95,23 @@ var _ = Describe("Podman start", func() { Expect(session.OutputToString()).To(Equal(shortID)) }) + It("podman container start single container by short id", func() { + session := podmanTest.Podman([]string{"container", "create", ALPINE, "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + cid := session.OutputToString() + shortID := cid[0:10] + session = podmanTest.Podman([]string{"container", "start", shortID}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(Equal(shortID)) + + session = podmanTest.Podman([]string{"stop", shortID}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(Equal(shortID)) + }) + It("podman start single container by name", func() { name := "foobar99" session := podmanTest.Podman([]string{"create", "--name", name, ALPINE, "ls"}) diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go index 750d38ffb..337fd651d 100644 --- a/test/e2e/stop_test.go +++ b/test/e2e/stop_test.go @@ -149,13 +149,12 @@ var _ = Describe("Podman stop", func() { session := podmanTest.RunTopContainer("test4") session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - cid1 := session.OutputToString() session = podmanTest.Podman([]string{"stop", "--time", "1", "test4"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) output := session.OutputToString() - Expect(output).To(ContainSubstring(cid1)) + Expect(output).To(ContainSubstring("test4")) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() @@ -167,14 +166,13 @@ var _ = Describe("Podman stop", func() { session := podmanTest.Podman([]string{"run", "-d", "--name", "test5", ALPINE, "sleep", "100"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - cid1 := session.OutputToString() session = podmanTest.Podman([]string{"stop", "--timeout", "1", "test5"}) // Without timeout container stops in 10 seconds // If not stopped in 5 seconds, then --timeout did not work session.Wait(5) Expect(session.ExitCode()).To(Equal(0)) output := session.OutputToString() - Expect(output).To(ContainSubstring(cid1)) + Expect(output).To(ContainSubstring("test5")) finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) finalCtrs.WaitWithDefaultTimeout() diff --git a/test/python/docker/test_containers.py b/test/python/docker/test_containers.py index 5c2a5fef2..337cacd5c 100644 --- a/test/python/docker/test_containers.py +++ b/test/python/docker/test_containers.py @@ -86,6 +86,13 @@ class TestContainers(unittest.TestCase): containers = self.client.containers.list(all=True) self.assertEqual(len(containers), 2) + def test_start_container_with_random_port_bind(self): + container = self.client.containers.create(image=constant.ALPINE, + name="containerWithRandomBind", + ports={'1234/tcp': None}) + containers = self.client.containers.list(all=True) + self.assertTrue(container in containers) + def test_stop_container(self): top = self.client.containers.get(TestContainers.topContainerId) self.assertEqual(top.status, "running") diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 3749dcac5..93449ece9 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -662,4 +662,10 @@ json-file | f run_podman rm $cname } +@test "podman run - do not set empty HOME" { + # Regression test for #9378. + run_podman run --rm --user 100 $IMAGE printenv + is "$output" ".*HOME=/.*" +} + # vim: filetype=sh diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 7a42a4c18..c18f3f7a7 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -46,6 +46,31 @@ EOF is "$output" ".*invalidflag" "failed when passing undefined flags to the runtime" } +@test "podman build - set runtime" { + skip_if_remote "--runtime flag not supported for remote" + # Test on the CLI and via containers.conf + + tmpdir=$PODMAN_TMPDIR/build-test + run mkdir -p $tmpdir + containerfile=$tmpdir/Containerfile + cat >$containerfile <<EOF +FROM $IMAGE +RUN echo $rand_content +EOF + + run_podman 125 --runtime=idonotexist build -t build_test $tmpdir + is "$output" ".*\"idonotexist\" not found.*" "failed when passing invalid OCI runtime via CLI" + + containersconf=$tmpdir/containers.conf + cat >$containersconf <<EOF +[engine] +runtime="idonotexist" +EOF + + CONTAINERS_CONF="$containersconf" run_podman 125 build -t build_test $tmpdir + is "$output" ".*\"idonotexist\" not found.*" "failed when passing invalid OCI runtime via containers.conf" +} + # Regression from v1.5.0. This test passes fine in v1.5.0, fails in 1.6 @test "podman build - cache (#3920)" { # Make an empty test directory, with a subdirectory used for tar |