diff options
Diffstat (limited to 'pkg/util/utils.go')
-rw-r--r-- | pkg/util/utils.go | 133 |
1 files changed, 43 insertions, 90 deletions
diff --git a/pkg/util/utils.go b/pkg/util/utils.go index a408ad34b..136f8fadd 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -3,9 +3,9 @@ package util import ( "fmt" "os" - "os/exec" "path/filepath" "strings" + "sync" "syscall" "time" @@ -182,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 @@ -241,25 +257,6 @@ func GetRootlessDirInfo() (string, string, error) { return dataDir, rootlessRuntime, nil } -// GetRootlessStorageOpts returns the storage opts for containers running as non root -func GetRootlessStorageOpts() (storage.StoreOptions, error) { - var opts storage.StoreOptions - - dataDir, rootlessRuntime, err := GetRootlessDirInfo() - if err != nil { - return opts, err - } - opts.RunRoot = rootlessRuntime - opts.GraphRoot = filepath.Join(dataDir, "containers", "storage") - if path, err := exec.LookPath("fuse-overlayfs"); err == nil { - opts.GraphDriverName = "overlay" - opts.GraphDriverOptions = []string{fmt.Sprintf("overlay.mount_program=%s", path)} - } else { - opts.GraphDriverName = "vfs" - } - return opts, nil -} - type tomlOptionsConfig struct { MountProgram string `toml:"mount_program"` } @@ -289,42 +286,6 @@ func getTomlStorage(storeOptions *storage.StoreOptions) *tomlConfig { return config } -// GetDefaultStoreOptions returns the default storage ops for containers -func GetDefaultStoreOptions() (storage.StoreOptions, error) { - var ( - defaultRootlessRunRoot string - defaultRootlessGraphRoot string - err error - ) - storageOpts := storage.DefaultStoreOptions - if rootless.IsRootless() { - storageOpts, err = GetRootlessStorageOpts() - if err != nil { - return storageOpts, err - } - } - - storageConf := StorageConfigFile() - if _, err = os.Stat(storageConf); err == nil { - defaultRootlessRunRoot = storageOpts.RunRoot - defaultRootlessGraphRoot = storageOpts.GraphRoot - storageOpts = storage.StoreOptions{} - storage.ReloadConfigurationFile(storageConf, &storageOpts) - } - if rootless.IsRootless() && err == nil { - // If the file did not specify a graphroot or runroot, - // set sane defaults so we don't try and use root-owned - // directories - if storageOpts.RunRoot == "" { - storageOpts.RunRoot = defaultRootlessRunRoot - } - if storageOpts.GraphRoot == "" { - storageOpts.GraphRoot = defaultRootlessGraphRoot - } - } - return storageOpts, nil -} - // WriteStorageConfigFile writes the configuration to a file func WriteStorageConfigFile(storageOpts *storage.StoreOptions, storageConf string) error { os.MkdirAll(filepath.Dir(storageConf), 0755) @@ -342,14 +303,6 @@ func WriteStorageConfigFile(storageOpts *storage.StoreOptions, storageConf strin return nil } -// StorageConfigFile returns the path to the storage config file used -func StorageConfigFile() string { - if rootless.IsRootless() { - return filepath.Join(os.Getenv("HOME"), ".config/containers/storage.conf") - } - return storage.DefaultConfigFile -} - // ParseInputTime takes the users input and to determine if it is valid and // returns a time format and error. The input is compared to known time formats // or a duration which implies no-duration |