aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/container.go4
-rw-r--r--libpod/container_internal_linux.go27
-rw-r--r--libpod/options.go13
-rw-r--r--pkg/specgen/generate/container_create.go11
-rw-r--r--test/e2e/run_test.go10
5 files changed, 64 insertions, 1 deletions
diff --git a/libpod/container.go b/libpod/container.go
index 9ad938a5c..644647bc9 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -261,6 +261,10 @@ type ContainerConfig struct {
Mounts []string `json:"mounts,omitempty"`
// NamedVolumes lists the named volumes to mount into the container.
NamedVolumes []*ContainerNamedVolume `json:"namedVolumes,omitempty"`
+ // CreateWorkingDir indicates that Libpod should create the container's
+ // working directory if it does not exist. Some OCI runtimes do this by
+ // default, but others do not.
+ CreateWorkingDir bool `json:"createWorkingDir,omitempty"`
// Security Config
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index b9e4f9a93..0d9a1c824 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -157,7 +157,32 @@ func (c *Container) prepare() error {
}
// Save changes to container state
- return c.save()
+ if err := c.save(); err != nil {
+ return err
+ }
+
+ // Ensure container entrypoint is created (if required)
+ if c.config.CreateWorkingDir {
+ workdir, err := securejoin.SecureJoin(c.state.Mountpoint, c.WorkingDir())
+ if err != nil {
+ return errors.Wrapf(err, "error creating path to container %s working dir", c.ID())
+ }
+ rootUID := c.RootUID()
+ rootGID := c.RootGID()
+
+ if err := os.MkdirAll(workdir, 0755); err != nil {
+ if os.IsExist(err) {
+ return nil
+ }
+ return errors.Wrapf(err, "error creating container %s working dir", c.ID())
+ }
+
+ if err := os.Chown(workdir, rootUID, rootGID); err != nil {
+ return errors.Wrapf(err, "error chowning container %s working directory to container root", c.ID())
+ }
+ }
+
+ return nil
}
// cleanupNetwork unmounts and cleans up the container's network
diff --git a/libpod/options.go b/libpod/options.go
index 560b406e2..a4e4b99e9 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1395,6 +1395,19 @@ func WithCreateCommand(cmd []string) CtrCreateOption {
}
}
+// WithCreateWorkingDir tells Podman to create the container's working directory
+// if it does not exist.
+func WithCreateWorkingDir() CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+
+ ctr.config.CreateWorkingDir = true
+ return nil
+ }
+}
+
// Volume Creation Options
// WithVolumeName sets the name of the volume.
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index b31bc91e0..42be5e812 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -215,6 +215,17 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if s.Entrypoint != nil {
options = append(options, libpod.WithEntrypoint(s.Entrypoint))
}
+ // If the user did not set an workdir but the image did, ensure it is
+ // created.
+ if s.WorkDir == "" && img != nil {
+ newWD, err := img.WorkingDir(ctx)
+ if err != nil {
+ return nil, err
+ }
+ if newWD != "" {
+ options = append(options, libpod.WithCreateWorkingDir())
+ }
+ }
if s.StopSignal != nil {
options = append(options, libpod.WithStopSignal(*s.StopSignal))
}
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 13f0db550..ef275b32e 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -1060,4 +1060,14 @@ USER mail`
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring(limit))
})
+
+ It("podman run makes entrypoint from image", func() {
+ dockerfile := `FROM busybox
+WORKDIR /madethis`
+ podmanTest.BuildImage(dockerfile, "test", "false")
+ session := podmanTest.Podman([]string{"run", "--rm", "test", "pwd"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("/madethis"))
+ })
})