diff --git a/errors.go b/errors.go index 63cb9ab74d..d81206e432 100644 --- a/errors.go +++ b/errors.go @@ -53,4 +53,6 @@ var ( ErrDigestUnknown = errors.New("could not compute digest of item") // ErrLayerNotMounted is returned when the requested information can only be computed for a mounted layer, and the layer is not mounted. ErrLayerNotMounted = errors.New("layer is not mounted") + // ErrTargetNotVolatile is returned when a path must be on volatile storage. + ErrTargetNotVolatile = errors.New("the target is not on tmpfs") ) diff --git a/store.go b/store.go index 27b00f6fe7..2a640f853a 100644 --- a/store.go +++ b/store.go @@ -148,6 +148,9 @@ type StoreOptions struct { // for use inside of a user namespace where UID mapping is being used. UIDMap []idtools.IDMap `json:"uidmap,omitempty"` GIDMap []idtools.IDMap `json:"gidmap,omitempty"` + // SkipRunRootCheck disables the check for the RunRoot to be on a volatile + // storage. + SkipRunRootCheck bool } // Store wraps up the various types of file-based stores that we use into a @@ -600,6 +603,12 @@ func GetStore(options StoreOptions) (Store, error) { } } + if !options.SkipRunRootCheck { + if err := validateRunRoot(options.RunRoot); err != nil { + return nil, err + } + } + graphLock, err := GetLockfile(filepath.Join(options.GraphRoot, "storage.lock")) if err != nil { return nil, err @@ -3282,6 +3291,12 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) { storeOptions.GraphDriverName = config.Storage.Driver } if config.Storage.RunRoot != "" { + if !storeOptions.SkipRunRootCheck { + if err := validateRunRoot(config.Storage.RunRoot); err != nil { + fmt.Printf("Failed to set runroot to %s %v\n", config.Storage.RunRoot, err.Error()) + return + } + } storeOptions.RunRoot = config.Storage.RunRoot } if config.Storage.GraphRoot != "" { diff --git a/store_linux.go b/store_linux.go new file mode 100644 index 0000000000..6c4f7d37f5 --- /dev/null +++ b/store_linux.go @@ -0,0 +1,29 @@ +package storage + +import ( + "os" + + "github.com/containers/storage/drivers" + "github.com/pkg/errors" +) + +func isOnVolatileStorage(target string) (bool, error) { + magic, err := graphdriver.GetFSMagic(target) + if err != nil { + if os.IsNotExist(err) { + return true, nil + } + return false, err + } + return magic == graphdriver.FsMagicTmpFs, nil +} + +func validateRunRoot(runRoot string) error { + if onTmpfs, err := isOnVolatileStorage(runRoot); err != nil || !onTmpfs { + if err != nil { + return errors.Wrapf(err, "cannot check if %s is on tmpfs", runRoot) + } + return errors.Wrapf(ErrTargetNotVolatile, "%s must be on tmpfs", runRoot) + } + return nil +} diff --git a/store_unsupported.go b/store_unsupported.go new file mode 100644 index 0000000000..774ff1dba5 --- /dev/null +++ b/store_unsupported.go @@ -0,0 +1,7 @@ +// +build !linux + +package storage + +func validateRunRoot(runRoot string) error { + return nil +}