diff --git a/docs/containers-storage.conf.5.md b/docs/containers-storage.conf.5.md index 3b898e731d..cf12f31dda 100644 --- a/docs/containers-storage.conf.5.md +++ b/docs/containers-storage.conf.5.md @@ -55,6 +55,9 @@ The `storage.options` table supports the following options: old, the driver is not supported. But for kernels that have had the drivers backported, this flag allows users to override the checks +**mount_program**="" + Specifies the path to a custom program to use instead for mounting the file system. + [storage.options.thinpool] Storage Options for thinpool @@ -89,10 +92,6 @@ Tells driver to wipe device (directlvm_device) even if device already has a file Specifies the filesystem type to use for the base device. (default: xfs) -**fuse_program**="" - -Specifies the path to a custom FUSE program to use instead for mounting the file system. - **log_level**="" Sets the log level of devicemapper. diff --git a/drivers/overlay/overlay.go b/drivers/overlay/overlay.go index 5d5d61d9c8..fbe36f4a46 100644 --- a/drivers/overlay/overlay.go +++ b/drivers/overlay/overlay.go @@ -85,7 +85,7 @@ type overlayOptions struct { overrideKernelCheck bool imageStores []string quota quota.Quota - fuseProgram string + mountProgram string ostreeRepo string skipMountHome bool } @@ -153,7 +153,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap } var supportsDType bool - if opts.fuseProgram != "" { + if opts.mountProgram != "" { supportsDType = true } else { supportsDType, err = supportsOverlay(home, fsMagic, rootUID, rootGID) @@ -246,13 +246,13 @@ func parseOptions(options []string) (*overlayOptions, error) { } o.imageStores = append(o.imageStores, store) } - case ".fuse_program", "overlay.fuse_program", "overlay2.fuse_program": - logrus.Debugf("overlay: fuse_program=%s", val) + case ".mount_program", "overlay.mount_program", "overlay2.mount_program": + logrus.Debugf("overlay: mount_program=%s", val) _, err := os.Stat(val) if err != nil { - return nil, fmt.Errorf("overlay: can't stat FUSE program %s: %v", val, err) + return nil, fmt.Errorf("overlay: can't stat program %s: %v", val, err) } - o.fuseProgram = val + o.mountProgram = val case "overlay2.ostree_repo", "overlay.ostree_repo", ".ostree_repo": logrus.Debugf("overlay: ostree_repo=%s", val) if !ostree.OstreeSupport() { @@ -713,7 +713,7 @@ func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) { // the page size. The mount syscall fails if the mount data cannot // fit within a page and relative links make the mount data much // smaller at the expense of requiring a fork exec to chroot. - if len(mountData) > pageSize || d.options.fuseProgram != "" { + if len(mountData) > pageSize || d.options.mountProgram != "" { //FIXME: We need to figure out to get this to work with additional stores opts = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", strings.Join(relLowers, ":"), path.Join(id, "diff"), path.Join(id, "work")) mountData = label.FormatMountLabel(opts, mountLabel) @@ -721,11 +721,11 @@ func (d *Driver) Get(id, mountLabel string) (_ string, retErr error) { return "", fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData)) } - if d.options.fuseProgram != "" { + if d.options.mountProgram != "" { mount = func(source string, target string, mType string, flags uintptr, label string) error { - cmdRootless := exec.Command(d.options.fuseProgram, "-o", label, target) - cmdRootless.Dir = d.home - return cmdRootless.Run() + mountProgram := exec.Command(d.options.mountProgram, "-o", label, target) + mountProgram.Dir = d.home + return mountProgram.Run() } } else { mount = func(source string, target string, mType string, flags uintptr, label string) error { diff --git a/storage.conf b/storage.conf index e1c0d2c449..636fe72c8d 100644 --- a/storage.conf +++ b/storage.conf @@ -25,6 +25,10 @@ additionalimagestores = [ # certain container storage drivers. size = "" +# Path to an helper program to use for mounting the file system instead of mounting it +# directly. +#mount_program = "/usr/bin/fuse-overlayfs" + # OverrideKernelCheck tells the driver to ignore kernel checks based on kernel version override_kernel_check = "false" diff --git a/store.go b/store.go index 870ccf7b0a..bafe011bf4 100644 --- a/store.go +++ b/store.go @@ -2900,7 +2900,7 @@ func copyStringInterfaceMap(m map[string]interface{}) map[string]interface{} { return ret } -const configFile = "/etc/containers/storage.conf" +const defaultConfigFile = "/etc/containers/storage.conf" // ThinpoolOptionsConfig represents the "storage.options.thinpool" // TOML config table. @@ -2992,6 +2992,9 @@ type OptionsConfig struct { // Do not create a bind mount on the storage home SkipMountHome string `toml:"skip_mount_home"` + + // Alternative program to use for the mount of the file system + MountProgram string `toml:"mount_program"` } // TOML-friendly explicit tables used for conversions. @@ -3004,11 +3007,9 @@ type tomlConfig struct { } `toml:"storage"` } -func init() { - DefaultStoreOptions.RunRoot = "/var/run/containers/storage" - DefaultStoreOptions.GraphRoot = "/var/lib/containers/storage" - DefaultStoreOptions.GraphDriverName = "" - +// ReloadConfigurationFile parses the specified configuration file and overrides +// the configuration in storeOptions. +func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) { data, err := ioutil.ReadFile(configFile) if err != nil { if !os.IsNotExist(err) { @@ -3024,72 +3025,75 @@ func init() { return } if config.Storage.Driver != "" { - DefaultStoreOptions.GraphDriverName = config.Storage.Driver + storeOptions.GraphDriverName = config.Storage.Driver } if config.Storage.RunRoot != "" { - DefaultStoreOptions.RunRoot = config.Storage.RunRoot + storeOptions.RunRoot = config.Storage.RunRoot } if config.Storage.GraphRoot != "" { - DefaultStoreOptions.GraphRoot = config.Storage.GraphRoot + storeOptions.GraphRoot = config.Storage.GraphRoot } if config.Storage.Options.Thinpool.AutoExtendPercent != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.thinp_autoextend_percent=%s", config.Storage.Options.Thinpool.AutoExtendPercent)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.thinp_autoextend_percent=%s", config.Storage.Options.Thinpool.AutoExtendPercent)) } if config.Storage.Options.Thinpool.AutoExtendThreshold != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.thinp_autoextend_threshold=%s", config.Storage.Options.Thinpool.AutoExtendThreshold)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.thinp_autoextend_threshold=%s", config.Storage.Options.Thinpool.AutoExtendThreshold)) } if config.Storage.Options.Thinpool.BaseSize != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.basesize=%s", config.Storage.Options.Thinpool.BaseSize)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.basesize=%s", config.Storage.Options.Thinpool.BaseSize)) } if config.Storage.Options.Thinpool.BlockSize != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.blocksize=%s", config.Storage.Options.Thinpool.BlockSize)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.blocksize=%s", config.Storage.Options.Thinpool.BlockSize)) } if config.Storage.Options.Thinpool.DirectLvmDevice != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.directlvm_device=%s", config.Storage.Options.Thinpool.DirectLvmDevice)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.directlvm_device=%s", config.Storage.Options.Thinpool.DirectLvmDevice)) } if config.Storage.Options.Thinpool.DirectLvmDeviceForce != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.directlvm_device_force=%s", config.Storage.Options.Thinpool.DirectLvmDeviceForce)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.directlvm_device_force=%s", config.Storage.Options.Thinpool.DirectLvmDeviceForce)) } if config.Storage.Options.Thinpool.Fs != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.fs=%s", config.Storage.Options.Thinpool.Fs)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.fs=%s", config.Storage.Options.Thinpool.Fs)) } if config.Storage.Options.Thinpool.LogLevel != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.libdm_log_level=%s", config.Storage.Options.Thinpool.LogLevel)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.libdm_log_level=%s", config.Storage.Options.Thinpool.LogLevel)) } if config.Storage.Options.Thinpool.MinFreeSpace != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.min_free_space=%s", config.Storage.Options.Thinpool.MinFreeSpace)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.min_free_space=%s", config.Storage.Options.Thinpool.MinFreeSpace)) } if config.Storage.Options.Thinpool.MkfsArg != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.mkfsarg=%s", config.Storage.Options.Thinpool.MkfsArg)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.mkfsarg=%s", config.Storage.Options.Thinpool.MkfsArg)) } if config.Storage.Options.Thinpool.MountOpt != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.mountopt=%s", config.Storage.Options.Thinpool.MountOpt)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.mountopt=%s", config.Storage.Options.Thinpool.MountOpt)) } if config.Storage.Options.Thinpool.UseDeferredDeletion != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.use_deferred_deletion=%s", config.Storage.Options.Thinpool.UseDeferredDeletion)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.use_deferred_deletion=%s", config.Storage.Options.Thinpool.UseDeferredDeletion)) } if config.Storage.Options.Thinpool.UseDeferredRemoval != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.use_deferred_removal=%s", config.Storage.Options.Thinpool.UseDeferredRemoval)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.use_deferred_removal=%s", config.Storage.Options.Thinpool.UseDeferredRemoval)) } if config.Storage.Options.Thinpool.XfsNoSpaceMaxRetries != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("dm.xfs_nospace_max_retries=%s", config.Storage.Options.Thinpool.XfsNoSpaceMaxRetries)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.xfs_nospace_max_retries=%s", config.Storage.Options.Thinpool.XfsNoSpaceMaxRetries)) } for _, s := range config.Storage.Options.AdditionalImageStores { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("%s.imagestore=%s", config.Storage.Driver, s)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.imagestore=%s", config.Storage.Driver, s)) } if config.Storage.Options.Size != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("%s.size=%s", config.Storage.Driver, config.Storage.Options.Size)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.size=%s", config.Storage.Driver, config.Storage.Options.Size)) } if config.Storage.Options.OstreeRepo != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("%s.ostree_repo=%s", config.Storage.Driver, config.Storage.Options.OstreeRepo)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.ostree_repo=%s", config.Storage.Driver, config.Storage.Options.OstreeRepo)) } if config.Storage.Options.SkipMountHome != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("%s.skip_mount_home=%s", config.Storage.Driver, config.Storage.Options.SkipMountHome)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.skip_mount_home=%s", config.Storage.Driver, config.Storage.Options.SkipMountHome)) + } + if config.Storage.Options.MountProgram != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mount_program=%s", config.Storage.Driver, config.Storage.Options.MountProgram)) } if config.Storage.Options.OverrideKernelCheck != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, fmt.Sprintf("%s.override_kernel_check=%s", config.Storage.Driver, config.Storage.Options.OverrideKernelCheck)) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.override_kernel_check=%s", config.Storage.Driver, config.Storage.Options.OverrideKernelCheck)) } if config.Storage.Options.RemapUser != "" && config.Storage.Options.RemapGroup == "" { config.Storage.Options.RemapGroup = config.Storage.Options.RemapUser @@ -3103,8 +3107,8 @@ func init() { fmt.Printf("Error initializing ID mappings for %s:%s %v\n", config.Storage.Options.RemapUser, config.Storage.Options.RemapGroup, err) return } - DefaultStoreOptions.UIDMap = mappings.UIDs() - DefaultStoreOptions.GIDMap = mappings.GIDs() + storeOptions.UIDMap = mappings.UIDs() + storeOptions.GIDMap = mappings.GIDs() } nonDigitsToWhitespace := func(r rune) rune { if strings.IndexRune("0123456789", r) == -1 { @@ -3154,15 +3158,23 @@ func init() { } return idmap } - DefaultStoreOptions.UIDMap = append(DefaultStoreOptions.UIDMap, parseIDMap(config.Storage.Options.RemapUIDs, "remap-uids")...) - DefaultStoreOptions.GIDMap = append(DefaultStoreOptions.GIDMap, parseIDMap(config.Storage.Options.RemapGIDs, "remap-gids")...) + storeOptions.UIDMap = append(storeOptions.UIDMap, parseIDMap(config.Storage.Options.RemapUIDs, "remap-uids")...) + storeOptions.GIDMap = append(storeOptions.GIDMap, parseIDMap(config.Storage.Options.RemapGIDs, "remap-gids")...) if os.Getenv("STORAGE_DRIVER") != "" { - DefaultStoreOptions.GraphDriverName = os.Getenv("STORAGE_DRIVER") + storeOptions.GraphDriverName = os.Getenv("STORAGE_DRIVER") } if os.Getenv("STORAGE_OPTS") != "" { - DefaultStoreOptions.GraphDriverOptions = append(DefaultStoreOptions.GraphDriverOptions, strings.Split(os.Getenv("STORAGE_OPTS"), ",")...) + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, strings.Split(os.Getenv("STORAGE_OPTS"), ",")...) } - if len(DefaultStoreOptions.GraphDriverOptions) == 1 && DefaultStoreOptions.GraphDriverOptions[0] == "" { - DefaultStoreOptions.GraphDriverOptions = nil + if len(storeOptions.GraphDriverOptions) == 1 && storeOptions.GraphDriverOptions[0] == "" { + storeOptions.GraphDriverOptions = nil } } + +func init() { + DefaultStoreOptions.RunRoot = "/var/run/containers/storage" + DefaultStoreOptions.GraphRoot = "/var/lib/containers/storage" + DefaultStoreOptions.GraphDriverName = "" + + ReloadConfigurationFile(defaultConfigFile, &DefaultStoreOptions) +}