summaryrefslogtreecommitdiffstats
path: root/types
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 16:28:11 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 16:28:11 +0000
commit496cd77eb2f01b34629ee1dfecef1b9bd745a3c5 (patch)
tree9c5bce932c85822cbd4e88252493173775ab051a /types
parentReleasing progress-linux version 1.51.0+ds1-2~progress7.99u1. (diff)
downloadgolang-github-containers-storage-496cd77eb2f01b34629ee1dfecef1b9bd745a3c5.tar.xz
golang-github-containers-storage-496cd77eb2f01b34629ee1dfecef1b9bd745a3c5.zip
Merging upstream version 1.52.0+ds1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'types')
-rw-r--r--types/options.go86
-rw-r--r--types/options_test.go25
-rw-r--r--types/utils.go151
-rw-r--r--types/utils_test.go271
4 files changed, 76 insertions, 457 deletions
diff --git a/types/options.go b/types/options.go
index 5ae667a..ad0bfa4 100644
--- a/types/options.go
+++ b/types/options.go
@@ -11,7 +11,9 @@ import (
"github.com/BurntSushi/toml"
cfg "github.com/containers/storage/pkg/config"
+ "github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/idtools"
+ "github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus"
)
@@ -87,7 +89,7 @@ func loadDefaultStoreOptions() {
_, err := os.Stat(defaultOverrideConfigFile)
if err == nil {
- // The DefaultConfigFile(rootless) function returns the path
+ // The DefaultConfigFile() function returns the path
// of the used storage.conf file, by returning defaultConfigFile
// If override exists containers/storage uses it by default.
defaultConfigFile = defaultOverrideConfigFile
@@ -109,21 +111,41 @@ func loadDefaultStoreOptions() {
setDefaults()
}
-// defaultStoreOptionsIsolated is an internal implementation detail of DefaultStoreOptions to allow testing.
-// Everyone but the tests this is intended for should only call DefaultStoreOptions, never this function.
-func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf string) (StoreOptions, error) {
+// loadStoreOptions returns the default storage ops for containers
+func loadStoreOptions() (StoreOptions, error) {
+ storageConf, err := DefaultConfigFile()
+ if err != nil {
+ return defaultStoreOptions, err
+ }
+ return loadStoreOptionsFromConfFile(storageConf)
+}
+
+// usePerUserStorage returns whether the user private storage must be used.
+// We cannot simply use the unshare.IsRootless() condition, because
+// that checks only if the current process needs a user namespace to
+// work and it would break cases where the process is already created
+// in a user namespace (e.g. nested Podman/Buildah) and the desired
+// behavior is to use system paths instead of user private paths.
+func usePerUserStorage() bool {
+ return unshare.IsRootless() && unshare.GetRootlessUID() != 0
+}
+
+// loadStoreOptionsFromConfFile is an internal implementation detail of DefaultStoreOptions to allow testing.
+// Everyone but the tests this is intended for should only call loadStoreOptions, never this function.
+func loadStoreOptionsFromConfFile(storageConf string) (StoreOptions, error) {
var (
defaultRootlessRunRoot string
defaultRootlessGraphRoot string
err error
)
+
defaultStoreOptionsOnce.Do(loadDefaultStoreOptions)
if loadDefaultStoreOptionsErr != nil {
return StoreOptions{}, loadDefaultStoreOptionsErr
}
storageOpts := defaultStoreOptions
- if rootless && rootlessUID != 0 {
- storageOpts, err = getRootlessStorageOpts(rootlessUID, storageOpts)
+ if usePerUserStorage() {
+ storageOpts, err = getRootlessStorageOpts(storageOpts)
if err != nil {
return storageOpts, err
}
@@ -137,7 +159,7 @@ func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf str
defaultRootlessGraphRoot = storageOpts.GraphRoot
storageOpts = StoreOptions{}
reloadConfigurationFileIfNeeded(storageConf, &storageOpts)
- if rootless && rootlessUID != 0 {
+ if usePerUserStorage() {
// If the file did not specify a graphroot or runroot,
// set sane defaults so we don't try and use root-owned
// directories
@@ -156,6 +178,7 @@ func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf str
if storageOpts.RunRoot == "" {
return storageOpts, fmt.Errorf("runroot must be set")
}
+ rootlessUID := unshare.GetRootlessUID()
runRoot, err := expandEnvPath(storageOpts.RunRoot, rootlessUID)
if err != nil {
return storageOpts, err
@@ -186,26 +209,17 @@ func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf str
return storageOpts, nil
}
-// loadStoreOptions returns the default storage ops for containers
-func loadStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) {
- storageConf, err := DefaultConfigFile(rootless && rootlessUID != 0)
- if err != nil {
- return defaultStoreOptions, err
- }
- return defaultStoreOptionsIsolated(rootless, rootlessUID, storageConf)
-}
-
// UpdateOptions should be called iff container engine received a SIGHUP,
// otherwise use DefaultStoreOptions
-func UpdateStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) {
- storeOptions, storeError = loadStoreOptions(rootless, rootlessUID)
+func UpdateStoreOptions() (StoreOptions, error) {
+ storeOptions, storeError = loadStoreOptions()
return storeOptions, storeError
}
// DefaultStoreOptions returns the default storage ops for containers
-func DefaultStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) {
+func DefaultStoreOptions() (StoreOptions, error) {
once.Do(func() {
- storeOptions, storeError = loadStoreOptions(rootless, rootlessUID)
+ storeOptions, storeError = loadStoreOptions()
})
return storeOptions, storeError
}
@@ -270,14 +284,26 @@ func isRootlessDriver(driver string) bool {
}
// getRootlessStorageOpts returns the storage opts for containers running as non root
-func getRootlessStorageOpts(rootlessUID int, systemOpts StoreOptions) (StoreOptions, error) {
+func getRootlessStorageOpts(systemOpts StoreOptions) (StoreOptions, error) {
var opts StoreOptions
- dataDir, rootlessRuntime, err := getRootlessDirInfo(rootlessUID)
+ rootlessUID := unshare.GetRootlessUID()
+
+ dataDir, err := homedir.GetDataHome()
+ if err != nil {
+ return opts, err
+ }
+
+ rootlessRuntime, err := homedir.GetRuntimeDir()
if err != nil {
return opts, err
}
- opts.RunRoot = rootlessRuntime
+
+ opts.RunRoot = filepath.Join(rootlessRuntime, "containers")
+ if err := os.MkdirAll(opts.RunRoot, 0o700); err != nil {
+ return opts, fmt.Errorf("unable to make rootless runtime: %w", err)
+ }
+
opts.PullOptions = systemOpts.PullOptions
if systemOpts.RootlessStoragePath != "" {
opts.GraphRoot, err = expandEnvPath(systemOpts.RootlessStoragePath, rootlessUID)
@@ -343,12 +369,6 @@ func getRootlessStorageOpts(rootlessUID int, systemOpts StoreOptions) (StoreOpti
return opts, nil
}
-// DefaultStoreOptionsAutoDetectUID returns the default storage ops for containers
-func DefaultStoreOptionsAutoDetectUID() (StoreOptions, error) {
- uid := getRootlessUID()
- return DefaultStoreOptions(uid != 0, uid)
-}
-
var prevReloadConfig = struct {
storeOptions *StoreOptions
mod time.Time
@@ -518,8 +538,8 @@ func Options() (StoreOptions, error) {
}
// Save overwrites the tomlConfig in storage.conf with the given conf
-func Save(conf TomlConfig, rootless bool) error {
- configFile, err := DefaultConfigFile(rootless)
+func Save(conf TomlConfig) error {
+ configFile, err := DefaultConfigFile()
if err != nil {
return err
}
@@ -537,10 +557,10 @@ func Save(conf TomlConfig, rootless bool) error {
}
// StorageConfig is used to retrieve the storage.conf toml in order to overwrite it
-func StorageConfig(rootless bool) (*TomlConfig, error) {
+func StorageConfig() (*TomlConfig, error) {
config := new(TomlConfig)
- configFile, err := DefaultConfigFile(rootless)
+ configFile, err := DefaultConfigFile()
if err != nil {
return nil, err
}
diff --git a/types/options_test.go b/types/options_test.go
index 5201936..bd2d265 100644
--- a/types/options_test.go
+++ b/types/options_test.go
@@ -10,6 +10,7 @@ import (
"testing"
"github.com/containers/storage/pkg/idtools"
+ "github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"gotest.tools/assert"
@@ -32,7 +33,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
systemOpts.GraphRoot = home
systemOpts.RunRoot = runhome
- storageOpts, err := getRootlessStorageOpts(os.Geteuid(), systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
expectedDriver := vfsDriver
@@ -45,7 +46,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
t.Run("systemDriver=btrfs", func(t *testing.T) {
systemOpts := StoreOptions{}
systemOpts.GraphDriverName = "btrfs"
- storageOpts, err := getRootlessStorageOpts(1000, systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
assert.Equal(t, storageOpts.GraphDriverName, "btrfs")
})
@@ -53,7 +54,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
t.Run("systemDriver=overlay", func(t *testing.T) {
systemOpts := StoreOptions{}
systemOpts.GraphDriverName = overlayDriver
- storageOpts, err := getRootlessStorageOpts(1000, systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
assert.Equal(t, storageOpts.GraphDriverName, overlayDriver)
})
@@ -61,7 +62,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
t.Run("systemDriver=overlay2", func(t *testing.T) {
systemOpts := StoreOptions{}
systemOpts.GraphDriverName = "overlay2"
- storageOpts, err := getRootlessStorageOpts(1000, systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
assert.Equal(t, storageOpts.GraphDriverName, overlayDriver)
})
@@ -69,7 +70,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
t.Run("systemDriver=vfs", func(t *testing.T) {
systemOpts := StoreOptions{}
systemOpts.GraphDriverName = vfsDriver
- storageOpts, err := getRootlessStorageOpts(1000, systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
assert.Equal(t, storageOpts.GraphDriverName, vfsDriver)
})
@@ -77,7 +78,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
t.Run("systemDriver=aufs", func(t *testing.T) {
systemOpts := StoreOptions{}
systemOpts.GraphDriverName = "aufs"
- storageOpts, err := getRootlessStorageOpts(1000, systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
assert.Assert(t, storageOpts.GraphDriverName == overlayDriver || storageOpts.GraphDriverName == vfsDriver, fmt.Sprintf("The rootless driver should be set to 'overlay' or 'vfs' not '%v'", storageOpts.GraphDriverName))
})
@@ -85,7 +86,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
t.Run("systemDriver=devmapper", func(t *testing.T) {
systemOpts := StoreOptions{}
systemOpts.GraphDriverName = "devmapper"
- storageOpts, err := getRootlessStorageOpts(1000, systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
assert.Assert(t, storageOpts.GraphDriverName == overlayDriver || storageOpts.GraphDriverName == vfsDriver, fmt.Sprintf("The rootless driver should be set to 'overlay' or 'vfs' not '%v'", storageOpts.GraphDriverName))
})
@@ -93,7 +94,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
t.Run("systemDriver=zfs", func(t *testing.T) {
systemOpts := StoreOptions{}
systemOpts.GraphDriverName = "zfs"
- storageOpts, err := getRootlessStorageOpts(1000, systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
assert.Assert(t, storageOpts.GraphDriverName == overlayDriver || storageOpts.GraphDriverName == vfsDriver, fmt.Sprintf("The rootless driver should be set to 'overlay' or 'vfs' not '%v'", storageOpts.GraphDriverName))
})
@@ -102,7 +103,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
t.Setenv("STORAGE_DRIVER", "btrfs")
systemOpts := StoreOptions{}
systemOpts.GraphDriverName = vfsDriver
- storageOpts, err := getRootlessStorageOpts(1000, systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
assert.Equal(t, storageOpts.GraphDriverName, "btrfs")
})
@@ -111,7 +112,7 @@ func TestGetRootlessStorageOpts(t *testing.T) {
t.Setenv("STORAGE_DRIVER", "zfs")
systemOpts := StoreOptions{}
systemOpts.GraphDriverName = vfsDriver
- storageOpts, err := getRootlessStorageOpts(1000, systemOpts)
+ storageOpts, err := getRootlessStorageOpts(systemOpts)
assert.NilError(t, err)
assert.Equal(t, storageOpts.GraphDriverName, "zfs")
})
@@ -127,8 +128,8 @@ func TestGetRootlessStorageOpts2(t *testing.T) {
opts := StoreOptions{
RootlessStoragePath: "/$HOME/$UID/containers/storage",
}
- expectedPath := filepath.Join(os.Getenv("HOME"), "2000", "containers/storage")
- storageOpts, err := getRootlessStorageOpts(2000, opts)
+ expectedPath := filepath.Join(os.Getenv("HOME"), fmt.Sprintf("%d", unshare.GetRootlessUID()), "containers/storage")
+ storageOpts, err := getRootlessStorageOpts(opts)
assert.NilError(t, err)
assert.Equal(t, storageOpts.GraphRoot, expectedPath)
}
diff --git a/types/utils.go b/types/utils.go
index 73134f8..5b4b31b 100644
--- a/types/utils.go
+++ b/types/utils.go
@@ -2,162 +2,15 @@ package types
import (
"errors"
- "fmt"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/containers/storage/pkg/homedir"
- "github.com/containers/storage/pkg/system"
"github.com/sirupsen/logrus"
)
-// GetRootlessRuntimeDir returns the runtime directory when running as non root
-func GetRootlessRuntimeDir(rootlessUID int) (string, error) {
- path, err := getRootlessRuntimeDir(rootlessUID)
- if err != nil {
- return "", err
- }
- path = filepath.Join(path, "containers")
- if err := os.MkdirAll(path, 0o700); err != nil {
- return "", fmt.Errorf("unable to make rootless runtime: %w", err)
- }
- return path, nil
-}
-
-type rootlessRuntimeDirEnvironment interface {
- getProcCommandFile() string
- getRunUserDir() string
- getTmpPerUserDir() string
-
- homeDirGetRuntimeDir() (string, error)
- systemLstat(string) (*system.StatT, error)
- homedirGet() string
-}
-
-type rootlessRuntimeDirEnvironmentImplementation struct {
- procCommandFile string
- runUserDir string
- tmpPerUserDir string
-}
-
-func (env rootlessRuntimeDirEnvironmentImplementation) getProcCommandFile() string {
- return env.procCommandFile
-}
-
-func (env rootlessRuntimeDirEnvironmentImplementation) getRunUserDir() string {
- return env.runUserDir
-}
-
-func (env rootlessRuntimeDirEnvironmentImplementation) getTmpPerUserDir() string {
- return env.tmpPerUserDir
-}
-
-func (rootlessRuntimeDirEnvironmentImplementation) homeDirGetRuntimeDir() (string, error) {
- return homedir.GetRuntimeDir()
-}
-
-func (rootlessRuntimeDirEnvironmentImplementation) systemLstat(path string) (*system.StatT, error) {
- return system.Lstat(path)
-}
-
-func (rootlessRuntimeDirEnvironmentImplementation) homedirGet() string {
- return homedir.Get()
-}
-
-func isRootlessRuntimeDirOwner(dir string, env rootlessRuntimeDirEnvironment) bool {
- st, err := env.systemLstat(dir)
- return err == nil && int(st.UID()) == os.Getuid() && st.Mode()&0o700 == 0o700 && st.Mode()&0o066 == 0o000
-}
-
-// getRootlessRuntimeDirIsolated is an internal implementation detail of getRootlessRuntimeDir to allow testing.
-// Everyone but the tests this is intended for should only call getRootlessRuntimeDir, never this function.
-func getRootlessRuntimeDirIsolated(env rootlessRuntimeDirEnvironment) (string, error) {
- runtimeDir, err := env.homeDirGetRuntimeDir()
- if err == nil {
- return runtimeDir, nil
- }
-
- initCommand, err := os.ReadFile(env.getProcCommandFile())
- if err != nil || string(initCommand) == "systemd" {
- runUserDir := env.getRunUserDir()
- if isRootlessRuntimeDirOwner(runUserDir, env) {
- return runUserDir, nil
- }
- }
-
- tmpPerUserDir := env.getTmpPerUserDir()
- if tmpPerUserDir != "" {
- if _, err := env.systemLstat(tmpPerUserDir); os.IsNotExist(err) {
- if err := os.Mkdir(tmpPerUserDir, 0o700); err != nil {
- logrus.Errorf("Failed to create temp directory for user: %v", err)
- } else {
- return tmpPerUserDir, nil
- }
- } else if isRootlessRuntimeDirOwner(tmpPerUserDir, env) {
- return tmpPerUserDir, nil
- }
- }
-
- homeDir := env.homedirGet()
- if homeDir == "" {
- return "", errors.New("neither XDG_RUNTIME_DIR nor temp dir nor HOME was set non-empty")
- }
- resolvedHomeDir, err := filepath.EvalSymlinks(homeDir)
- if err != nil {
- return "", err
- }
- return filepath.Join(resolvedHomeDir, "rundir"), nil
-}
-
-func getRootlessRuntimeDir(rootlessUID int) (string, error) {
- return getRootlessRuntimeDirIsolated(
- rootlessRuntimeDirEnvironmentImplementation{
- "/proc/1/comm",
- fmt.Sprintf("/run/user/%d", rootlessUID),
- fmt.Sprintf("%s/containers-user-%d", os.TempDir(), rootlessUID),
- },
- )
-}
-
-// getRootlessDirInfo returns the parent path of where the storage for containers and
-// volumes will be in rootless mode
-func getRootlessDirInfo(rootlessUID int) (string, string, error) {
- rootlessRuntime, err := GetRootlessRuntimeDir(rootlessUID)
- if err != nil {
- return "", "", err
- }
-
- dataDir, err := homedir.GetDataHome()
- if err == nil {
- return dataDir, rootlessRuntime, nil
- }
-
- home := homedir.Get()
- if home == "" {
- return "", "", fmt.Errorf("neither XDG_DATA_HOME nor HOME was set non-empty: %w", err)
- }
- // runc doesn't like symlinks in the rootfs path, and at least
- // on CoreOS /home is a symlink to /var/home, so resolve any symlink.
- resolvedHome, err := filepath.EvalSymlinks(home)
- if err != nil {
- return "", "", err
- }
- dataDir = filepath.Join(resolvedHome, ".local", "share")
-
- return dataDir, rootlessRuntime, nil
-}
-
-func getRootlessUID() int {
- uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
- if uidEnv != "" {
- u, _ := strconv.Atoi(uidEnv)
- return u
- }
- return os.Geteuid()
-}
-
func expandEnvPath(path string, rootlessUID int) (string, error) {
var err error
path = strings.Replace(path, "$UID", strconv.Itoa(rootlessUID), -1)
@@ -169,7 +22,7 @@ func expandEnvPath(path string, rootlessUID int) (string, error) {
return newpath, nil
}
-func DefaultConfigFile(rootless bool) (string, error) {
+func DefaultConfigFile() (string, error) {
if defaultConfigFileSet {
return defaultConfigFile, nil
}
@@ -177,7 +30,7 @@ func DefaultConfigFile(rootless bool) (string, error) {
if path, ok := os.LookupEnv(storageConfEnv); ok {
return path, nil
}
- if !rootless {
+ if !usePerUserStorage() {
if _, err := os.Stat(defaultOverrideConfigFile); err == nil {
return defaultOverrideConfigFile, nil
}
diff --git a/types/utils_test.go b/types/utils_test.go
index a6c8d50..124ad87 100644
--- a/types/utils_test.go
+++ b/types/utils_test.go
@@ -1,276 +1,21 @@
package types
import (
- "errors"
"fmt"
"os"
"path/filepath"
"testing"
- "github.com/containers/storage/pkg/homedir"
- "github.com/containers/storage/pkg/system"
+ "github.com/containers/storage/pkg/unshare"
"gotest.tools/assert"
)
-type homeRuntimeData struct {
- dir string
- err error
-}
-
-type rootlessRuntimeDirEnvironmentTest struct {
- homeRuntime homeRuntimeData
- procCommandFile string
- runUserDir string
- tmpPerUserDir string
- homeDir string
- result string
-}
-
-func (env rootlessRuntimeDirEnvironmentTest) getProcCommandFile() string {
- return env.procCommandFile
-}
-
-func (env rootlessRuntimeDirEnvironmentTest) getRunUserDir() string {
- return env.runUserDir
-}
-
-func (env rootlessRuntimeDirEnvironmentTest) getTmpPerUserDir() string {
- return env.tmpPerUserDir
-}
-
-func (env rootlessRuntimeDirEnvironmentTest) homeDirGetRuntimeDir() (string, error) {
- return env.homeRuntime.dir, env.homeRuntime.err
-}
-
-func (env rootlessRuntimeDirEnvironmentTest) systemLstat(path string) (*system.StatT, error) {
- return system.Lstat(path)
-}
-
-func (env rootlessRuntimeDirEnvironmentTest) homedirGet() string {
- return env.homeDir
-}
-
-func TestRootlessRuntimeDir(t *testing.T) {
- testDir := t.TempDir()
-
- homeRuntimeDir := filepath.Join(testDir, "home-rundir")
- err := os.Mkdir(homeRuntimeDir, 0o700)
- assert.NilError(t, err)
-
- homeRuntimeDisabled := homeRuntimeData{err: errors.New("homedirGetRuntimeDir is disabled")}
-
- systemdCommandFile := filepath.Join(testDir, "systemd-command")
- err = os.WriteFile(systemdCommandFile, []byte("systemd"), 0o644)
- assert.NilError(t, err)
-
- initCommandFile := filepath.Join(testDir, "init-command")
- err = os.WriteFile(initCommandFile, []byte("init"), 0o644)
- assert.NilError(t, err)
-
- dirForOwner := filepath.Join(testDir, "dir-for-owner")
- err = os.Mkdir(dirForOwner, 0o700)
- assert.NilError(t, err)
-
- dirForAll := filepath.Join(testDir, "dir-for-all")
- err = os.Mkdir(dirForAll, 0o777)
- assert.NilError(t, err)
-
- dirToBeCreated := filepath.Join(testDir, "dir-to-be-created")
-
- envs := []rootlessRuntimeDirEnvironmentTest{
- {
- homeRuntime: homeRuntimeData{dir: homeRuntimeDir},
- result: homeRuntimeDir,
- },
-
- // Reading proc command file fails
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: "",
- runUserDir: dirForOwner,
- result: dirForOwner,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: "",
- runUserDir: "", // Accessing run user dir fails
- tmpPerUserDir: dirForOwner,
- result: dirForOwner,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: "",
- runUserDir: dirForAll,
- tmpPerUserDir: dirForOwner,
- result: dirForOwner,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: "",
- runUserDir: "", // Accessing run user dir fails
- tmpPerUserDir: dirToBeCreated,
- result: dirToBeCreated,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: "",
- runUserDir: "", // Accessing run user dir fails
- tmpPerUserDir: "", // Accessing tmp per user dir fails
- homeDir: dirForOwner,
- result: filepath.Join(dirForOwner, "rundir"),
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: "",
- runUserDir: "", // Accessing run user dir fails
- tmpPerUserDir: dirForAll,
- homeDir: dirForOwner,
- result: filepath.Join(dirForOwner, "rundir"),
- },
-
- // systemd
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: systemdCommandFile,
- runUserDir: dirForOwner,
- result: dirForOwner,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: systemdCommandFile,
- runUserDir: "", // Accessing run user dir fails
- tmpPerUserDir: dirForOwner,
- result: dirForOwner,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: systemdCommandFile,
- runUserDir: dirForAll,
- tmpPerUserDir: dirForOwner,
- result: dirForOwner,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: systemdCommandFile,
- runUserDir: "", // Accessing run user dir fails
- tmpPerUserDir: dirToBeCreated,
- result: dirToBeCreated,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: systemdCommandFile,
- runUserDir: "", // Accessing run user dir fails
- tmpPerUserDir: "", // Accessing tmp per user dir fails
- homeDir: dirForOwner,
- result: filepath.Join(dirForOwner, "rundir"),
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: systemdCommandFile,
- runUserDir: "", // Accessing run user dir fails
- tmpPerUserDir: dirForAll,
- homeDir: dirForOwner,
- result: filepath.Join(dirForOwner, "rundir"),
- },
-
- // init
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: initCommandFile,
- tmpPerUserDir: dirForOwner,
- result: dirForOwner,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: initCommandFile,
- tmpPerUserDir: dirToBeCreated,
- result: dirToBeCreated,
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: initCommandFile,
- tmpPerUserDir: "", // Accessing tmp per user dir fails
- homeDir: dirForOwner,
- result: filepath.Join(dirForOwner, "rundir"),
- },
- {
- homeRuntime: homeRuntimeDisabled,
- procCommandFile: initCommandFile,
- tmpPerUserDir: dirForAll,
- homeDir: dirForOwner,
- result: filepath.Join(dirForOwner, "rundir"),
- },
- }
-
- for i, env := range envs {
- t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
- os.Remove(dirToBeCreated)
-
- resultDir, err := getRootlessRuntimeDirIsolated(env)
- assert.NilError(t, err)
- assert.Assert(t, resultDir == env.result)
- })
- }
-}
-
-type rootlessRuntimeDirEnvironmentRace struct {
- procCommandFile string
- tmpPerUserDir string
-}
-
-func (env rootlessRuntimeDirEnvironmentRace) getProcCommandFile() string {
- return env.procCommandFile
-}
-
-func (rootlessRuntimeDirEnvironmentRace) getRunUserDir() string {
- return ""
-}
-
-func (env rootlessRuntimeDirEnvironmentRace) getTmpPerUserDir() string {
- return env.tmpPerUserDir
-}
-
-func (rootlessRuntimeDirEnvironmentRace) homeDirGetRuntimeDir() (string, error) {
- return "", errors.New("homedirGetRuntimeDir is disabled")
-}
-
-func (env rootlessRuntimeDirEnvironmentRace) systemLstat(path string) (*system.StatT, error) {
- if path == env.tmpPerUserDir {
- st, err := system.Lstat(path)
- // We can simulate that race directory was created immediately after system.Lstat call.
- if err := os.Mkdir(path, 0o700); err != nil {
- return nil, err
- }
- return st, err
- }
- return system.Lstat(path)
-}
-
-func (rootlessRuntimeDirEnvironmentRace) homedirGet() string {
- return homedir.Get()
-}
-
-func TestRootlessRuntimeDirRace(t *testing.T) {
- raceDir := t.TempDir()
-
- procCommandFile := filepath.Join(raceDir, "command")
- err := os.WriteFile(procCommandFile, []byte("init"), 0o644)
- assert.NilError(t, err)
-
- tmpPerUserDir := filepath.Join(raceDir, "tmp")
-
- resultDir, err := getRootlessRuntimeDirIsolated(rootlessRuntimeDirEnvironmentRace{
- procCommandFile,
- tmpPerUserDir,
- })
- assert.NilError(t, err)
- assert.Assert(t, resultDir != tmpPerUserDir, "Rootless runtime dir shouldn't follow race dir.")
-}
-
func TestDefaultStoreOpts(t *testing.T) {
- storageOpts, err := defaultStoreOptionsIsolated(true, 1000, "./storage_test.conf")
-
- expectedPath := filepath.Join(os.Getenv("HOME"), "1000", "containers/storage")
+ if !usePerUserStorage() {
+ t.Skip()
+ }
+ storageOpts, err := loadStoreOptionsFromConfFile("./storage_test.conf")
+ expectedPath := filepath.Join(os.Getenv("HOME"), fmt.Sprintf("%d", unshare.GetRootlessUID()), "containers/storage")
assert.NilError(t, err)
assert.Equal(t, storageOpts.RunRoot, expectedPath)
@@ -280,7 +25,7 @@ func TestDefaultStoreOpts(t *testing.T) {
func TestStorageConfOverrideEnvironmentDefaultConfigFileRootless(t *testing.T) {
t.Setenv("CONTAINERS_STORAGE_CONF", "default_override_test.conf")
- defaultFile, err := DefaultConfigFile(true)
+ defaultFile, err := DefaultConfigFile()
expectedPath := "default_override_test.conf"
@@ -290,7 +35,7 @@ func TestStorageConfOverrideEnvironmentDefaultConfigFileRootless(t *testing.T) {
func TestStorageConfOverrideEnvironmentDefaultConfigFileRoot(t *testing.T) {
t.Setenv("CONTAINERS_STORAGE_CONF", "default_override_test.conf")
- defaultFile, err := DefaultConfigFile(false)
+ defaultFile, err := DefaultConfigFile()
expectedPath := "default_override_test.conf"