diff options
-rw-r--r-- | libpod/oci.go | 6 | ||||
-rw-r--r-- | libpod/runtime.go | 12 | ||||
-rw-r--r-- | pkg/util/utils.go | 69 |
3 files changed, 57 insertions, 30 deletions
diff --git a/libpod/oci.go b/libpod/oci.go index b25175b9d..62331b879 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -473,7 +473,7 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, res // If useRunc is false, we will not directly hit runc to see the container's // status, but will instead only check for the existence of the conmon exit file // and update state to stopped if it exists. -func (r *OCIRuntime) updateContainerStatus(ctr *Container, useRunc bool) error { +func (r *OCIRuntime) updateContainerStatus(ctr *Container, useRuntime bool) error { exitFile := ctr.exitFilePath() runtimeDir, err := util.GetRootlessRuntimeDir() @@ -481,8 +481,8 @@ func (r *OCIRuntime) updateContainerStatus(ctr *Container, useRunc bool) error { return err } - // If not using runc, we don't need to do most of this. - if !useRunc { + // If not using the OCI runtime, we don't need to do most of this. + if !useRuntime { // If the container's not running, nothing to do. if ctr.state.State != ContainerStateRunning && ctr.state.State != ContainerStatePaused { return nil diff --git a/libpod/runtime.go b/libpod/runtime.go index f7b166513..6e54de558 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -309,7 +309,17 @@ func getDefaultTmpDir() (string, error) { if err != nil { return "", err } - return filepath.Join(rootlessRuntimeDir, "libpod", "tmp"), nil + libpodRuntimeDir := filepath.Join(rootlessRuntimeDir, "libpod") + + if err := os.Mkdir(libpodRuntimeDir, 0700|os.ModeSticky); err != nil { + if !os.IsExist(err) { + return "", errors.Wrapf(err, "cannot mkdir %s", libpodRuntimeDir) + } else if err := os.Chmod(libpodRuntimeDir, 0700|os.ModeSticky); err != nil { + // The directory already exist, just set the sticky bit + return "", errors.Wrapf(err, "could not set sticky bit on %s", libpodRuntimeDir) + } + } + return filepath.Join(libpodRuntimeDir, "tmp"), nil } // SetXdgRuntimeDir ensures the XDG_RUNTIME_DIR env variable is set diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 19b2c44be..136f8fadd 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "strings" + "sync" "syscall" "time" @@ -181,38 +182,54 @@ func ParseIDMapping(UIDMapSlice, GIDMapSlice []string, subUIDMap, subGIDMap stri return &options, nil } +var ( + rootlessRuntimeDirOnce sync.Once + rootlessRuntimeDir string +) + // GetRootlessRuntimeDir returns the runtime directory when running as non root func GetRootlessRuntimeDir() (string, error) { - runtimeDir := os.Getenv("XDG_RUNTIME_DIR") - uid := fmt.Sprintf("%d", rootless.GetRootlessUID()) - if runtimeDir == "" { - tmpDir := filepath.Join("/run", "user", uid) - os.MkdirAll(tmpDir, 0700) - st, err := os.Stat(tmpDir) - if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { - runtimeDir = tmpDir - } - } - if runtimeDir == "" { - tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid)) - os.MkdirAll(tmpDir, 0700) - st, err := os.Stat(tmpDir) - if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { - runtimeDir = tmpDir + var rootlessRuntimeDirError error + + rootlessRuntimeDirOnce.Do(func() { + runtimeDir := os.Getenv("XDG_RUNTIME_DIR") + uid := fmt.Sprintf("%d", rootless.GetRootlessUID()) + if runtimeDir == "" { + tmpDir := filepath.Join("/run", "user", uid) + os.MkdirAll(tmpDir, 0700) + st, err := os.Stat(tmpDir) + if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { + runtimeDir = tmpDir + } } - } - if runtimeDir == "" { - home := os.Getenv("HOME") - if home == "" { - return "", fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty") + if runtimeDir == "" { + tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid)) + os.MkdirAll(tmpDir, 0700) + st, err := os.Stat(tmpDir) + if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { + runtimeDir = tmpDir + } } - resolvedHome, err := filepath.EvalSymlinks(home) - if err != nil { - return "", errors.Wrapf(err, "cannot resolve %s", home) + if runtimeDir == "" { + home := os.Getenv("HOME") + if home == "" { + rootlessRuntimeDirError = fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty") + return + } + resolvedHome, err := filepath.EvalSymlinks(home) + if err != nil { + rootlessRuntimeDirError = errors.Wrapf(err, "cannot resolve %s", home) + return + } + runtimeDir = filepath.Join(resolvedHome, "rundir") } - runtimeDir = filepath.Join(resolvedHome, "rundir") + rootlessRuntimeDir = runtimeDir + }) + + if rootlessRuntimeDirError != nil { + return "", rootlessRuntimeDirError } - return runtimeDir, nil + return rootlessRuntimeDir, nil } // GetRootlessDirInfo returns the parent path of where the storage for containers and |