aboutsummaryrefslogtreecommitdiff
path: root/pkg/util/utils.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/util/utils.go')
-rw-r--r--pkg/util/utils.go133
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