summaryrefslogtreecommitdiff
path: root/libpod/container_path_resolution.go
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2021-01-21 15:41:14 +0100
committerValentin Rothberg <rothberg@redhat.com>2021-01-26 09:02:21 +0100
commit0f668aa0857815f388ef1bb880efa4b2e889edaf (patch)
tree8a2a7301b5c43429fd95369a24022584ca211433 /libpod/container_path_resolution.go
parent7b186dcb9e79c15a4d5506db8922281cd8034a58 (diff)
downloadpodman-0f668aa0857815f388ef1bb880efa4b2e889edaf.tar.gz
podman-0f668aa0857815f388ef1bb880efa4b2e889edaf.tar.bz2
podman-0f668aa0857815f388ef1bb880efa4b2e889edaf.zip
workdir presence checks
A container's workdir can be specified via the CLI via `--workdir` and via an image config with the CLI having precedence. Since images have a tendency to specify workdirs without necessarily shipping the paths with the root FS, make sure that Podman creates the workdir. When specified via the CLI, do not create the path, but check for its existence and return a human-friendly error. NOTE: `crun` is performing a similar check that would yield exit code 127. With this change, however, Podman performs the check and yields exit code 126. Since this is specific to `crun`, I do not consider it to be a breaking change of Podman. Fixes: #9040 Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'libpod/container_path_resolution.go')
-rw-r--r--libpod/container_path_resolution.go47
1 files changed, 43 insertions, 4 deletions
diff --git a/libpod/container_path_resolution.go b/libpod/container_path_resolution.go
index 68f174278..805b3b947 100644
--- a/libpod/container_path_resolution.go
+++ b/libpod/container_path_resolution.go
@@ -13,6 +13,11 @@ import (
// resolveContainerPaths resolves the container's mount point and the container
// path as specified by the user. Both may resolve to paths outside of the
// container's mount point when the container path hits a volume or bind mount.
+//
+// It returns a bool, indicating whether containerPath resolves outside of
+// mountPoint (e.g., via a mount or volume), the resolved root (e.g., container
+// mount, bind mount or volume) and the resolved path on the root (absolute to
+// the host).
func (container *Container) resolvePath(mountPoint string, containerPath string) (string, string, error) {
// Let's first make sure we have a path relative to the mount point.
pathRelativeToContainerMountPoint := containerPath
@@ -97,8 +102,8 @@ func (container *Container) resolvePath(mountPoint string, containerPath string)
return mountPoint, resolvedPathOnTheContainerMountPoint, nil
}
-// findVolume checks if the specified container path matches a volume inside
-// the container. It returns a matching volume or nil.
+// findVolume checks if the specified containerPath matches the destination
+// path of a Volume. Returns a matching Volume or nil.
func findVolume(c *Container, containerPath string) (*Volume, error) {
runtime := c.Runtime()
cleanedContainerPath := filepath.Clean(containerPath)
@@ -110,8 +115,25 @@ func findVolume(c *Container, containerPath string) (*Volume, error) {
return nil, nil
}
-// findBindMount checks if the specified container path matches a bind mount
-// inside the container. It returns a matching mount or nil.
+// isPathOnVolume returns true if the specified containerPath is a subdir of any
+// Volume's destination.
+func isPathOnVolume(c *Container, containerPath string) bool {
+ cleanedContainerPath := filepath.Clean(containerPath)
+ for _, vol := range c.Config().NamedVolumes {
+ if cleanedContainerPath == filepath.Clean(vol.Dest) {
+ return true
+ }
+ for dest := vol.Dest; dest != "/"; dest = filepath.Dir(dest) {
+ if cleanedContainerPath == dest {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// findBindMounts checks if the specified containerPath matches the destination
+// path of a Mount. Returns a matching Mount or nil.
func findBindMount(c *Container, containerPath string) *specs.Mount {
cleanedPath := filepath.Clean(containerPath)
for _, m := range c.Config().Spec.Mounts {
@@ -125,3 +147,20 @@ func findBindMount(c *Container, containerPath string) *specs.Mount {
}
return nil
}
+
+/// isPathOnBindMount returns true if the specified containerPath is a subdir of any
+// Mount's destination.
+func isPathOnBindMount(c *Container, containerPath string) bool {
+ cleanedContainerPath := filepath.Clean(containerPath)
+ for _, m := range c.Config().Spec.Mounts {
+ if cleanedContainerPath == filepath.Clean(m.Destination) {
+ return true
+ }
+ for dest := m.Destination; dest != "/"; dest = filepath.Dir(dest) {
+ if cleanedContainerPath == dest {
+ return true
+ }
+ }
+ }
+ return false
+}