From a713ac4a7ea09a4c8809b906d47555488ef13097 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Wed, 18 Sep 2019 17:10:45 -0400 Subject: [PATCH] Move storage options to driver specific entries Storage options are really driver specific and it is when distributions set defaults, they should not effect the user if he changes the default driver. By moving the storage options to be driver specific, we can make sure all drivers only document and support their options. Signed-off-by: Daniel J Walsh --- docs/containers-storage.conf.5.md | 90 +++++++++++++++----- pkg/config/config.go | 43 ++++++++++ pkg/parsers/kernel/kernel_windows.go | 2 +- storage.conf | 31 +++---- store.go | 121 +++++++++++++++++---------- 5 files changed, 208 insertions(+), 79 deletions(-) diff --git a/docs/containers-storage.conf.5.md b/docs/containers-storage.conf.5.md index 1fa66e7f9a..ebcb7b3955 100644 --- a/docs/containers-storage.conf.5.md +++ b/docs/containers-storage.conf.5.md @@ -49,28 +49,9 @@ The `storage.options` table supports the following options: **additionalimagestores**=[] Paths to additional container image stores. Usually these are read/only and stored on remote network shares. -**ignore_chown_errors** = "true|False" - ignore_chown_errors can be set to allow a non privileged user running with a single UID within a user namespace to run containers. The user can pull and use any image even those with multiple uids. Note multiple UIDs will be squasheddown to the default uid in the container. These images will have no separation between the users in the container. Only supported for the overlay and vfs drivers. - -**mount_program**="" - Specifies the path to a custom program to use instead of using kernel defaults for mounting the file system. - - mount_program = "/usr/bin/fuse-overlayfs" - -**mountopt**="" - - Comma separated list of default options to be used to mount container images. Suggested value "nodev". - **ostree_repo** = "" If specified, use OSTree to deduplicate files with the overlay or vfs backends. -**size**="" - Maximum size of a container image. This flag can be used to set quota on the size of container images. (default: 10GB) - -**skip_mount_home** = "false" - Set to skip a PRIVATE bind mount on the storage home directory. -Only supported by certain container storage drivers (overlay). - **remap-uids=**"" **remap-gids=**"" @@ -103,6 +84,24 @@ until all of the entries have been used for maps. remap-user = "storage" remap-group = "storage" +**size**="" + Maximum size of a container image. This flag can be used to set quota on the size of container images. (default: 10GB) + +### STORAGE OPTIONS FOR AUFS TABLE + +The `storage.options.aufs` table supports the following options: + +**mountopt**="" + + Comma separated list of default options to be used to mount container images. Suggested value "nodev". + +### STORAGE OPTIONS FOR BTRFS TABLE + +The `storage.options.btrfs` table supports the following options: + +**min_space**="" +Specifies the min space in a btrfs volume. + ### STORAGE OPTIONS FOR THINPOOL TABLE The `storage.options.thinpool` table supports the following options: @@ -155,6 +154,10 @@ Specifies the min free space percent in a thin pool required for new device crea Specifies extra mkfs arguments to be used when creating the base device. +**mountopt**="" + + Comma separated list of default options to be used to mount container images. Suggested value "nodev". + **use_deferred_deletion**="" Marks thinpool device for deferred deletion. If the thinpool is in use when the driver attempts to delete it, the driver will attempt to delete device every 30 seconds until successful, or when it restarts. Deferred deletion permanently deletes the device and all data stored in the device will be lost. (default: true). @@ -167,6 +170,55 @@ Marks devicemapper block device for deferred removal. If the device is in use w Specifies the maximum number of retries XFS should attempt to complete IO when ENOSPC (no space) error is returned by underlying storage device. (default: 0, which means to try continuously.) +### STORAGE OPTIONS FOR OVERLAY TABLE + +The `storage.options.overlay` table supports the following options: + +**ignore_chown_errors** = "true|False" + ignore_chown_errors can be set to allow a non privileged user running with a single UID within a user namespace to run containers. The user can pull and use any image even those with multiple uids. Note multiple UIDs will be squasheddown to the default uid in the container. These images will have no separation between the users in the container. Only supported for the overlay and vfs drivers. + +**mount_program**="" + Specifies the path to a custom program to use instead of using kernel defaults for mounting the file system. + + mount_program = "/usr/bin/fuse-overlayfs" + +**mountopt**="" + + Comma separated list of default options to be used to mount container images. Suggested value "nodev". + +**skip_mount_home** = "false" + Set to skip a PRIVATE bind mount on the storage home directory. +Only supported by certain container storage drivers (overlay). + +### STORAGE OPTIONS FOR ZFS TABLE + +The `storage.options.zfs` table supports the following options: + +**mountopt**="" + + Comma separated list of default options to be used to mount container images. Suggested value "nodev". + +**name**="" +Specifies the name of the ZFS File System + +### STORAGE OPTIONS FOR ZFS TABLE + +The `storage.options.zfs` table supports the following options: + +**fsname**="" + File System name for the zfs driver + +**mountopt**="" + + Comma separated list of default options to be used to mount container images. Suggested value "nodev". + +### STORAGE OPTIONS FOR BTRFS TABLE + +The `storage.options.btrfs` table supports the following options: + +**min_space**="" +Specifies the min space in a btrfs volume. + ## SELINUX LABELING When running on an SELinux system, if you move the containers storage graphroot directory, you must make sure the labeling is correct. diff --git a/pkg/config/config.go b/pkg/config/config.go index c53f704219..becfacb357 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -59,6 +59,35 @@ type ThinpoolOptionsConfig struct { XfsNoSpaceMaxRetries string `toml:"xfs_nospace_max_retries"` } +type AufsOptionsConfig struct { + // MountOpt specifies extra mount options used when mounting + MountOpt string `toml:"mountopt"` +} + +type BtrfsOptionsConfig struct { + // MinSpace is the minimal spaces allocated to the device + MinSpace string `toml:"min_space"` +} + +type OverlayOptionsConfig struct { + // IgnoreChownErrors is a flag for whether chown errors should be + // ignored when building an image. + IgnoreChownErrors string `toml:"ignore_chown_errors"` + // MountOpt specifies extra mount options used when mounting + MountOpt string `toml:"mountopt"` + // Alternative program to use for the mount of the file system + MountProgram string `toml:"mount_program"` + // Do not create a bind mount on the storage home + SkipMountHome string `toml:"skip_mount_home"` +} + +type ZfsOptionsConfig struct { + // MountOpt specifies extra mount options used when mounting + MountOpt string `toml:"mountopt"` + // Name of the ZFS File system + Name string `toml:"name"` +} + // OptionsConfig represents the "storage.options" TOML config table. type OptionsConfig struct { // AdditionalImagesStores is the location of additional read/only @@ -83,8 +112,22 @@ type OptionsConfig struct { // RemapGroup is the name of one or more entries in /etc/subgid which // should be used to set up default GID mappings. RemapGroup string `toml:"remap-group"` + + // Aufs container options to be handed to aufs drivers + Aufs struct{ AufsOptionsConfig } `toml:"aufs"` + + // Btrfs container options to be handed to btrfs drivers + Btrfs struct{ BtrfsOptionsConfig } `toml:"btrfs"` + // Thinpool container options to be handed to thinpool drivers Thinpool struct{ ThinpoolOptionsConfig } `toml:"thinpool"` + + // Overlay container options to be handed to overlay drivers + Overlay struct{ OverlayOptionsConfig } `toml:"overlay"` + + // Zfs container options to be handed to ZFS drivers + Zfs struct{ ZfsOptionsConfig } `toml:"zfs"` + // OSTree repository OstreeRepo string `toml:"ostree_repo"` diff --git a/pkg/parsers/kernel/kernel_windows.go b/pkg/parsers/kernel/kernel_windows.go index e598672776..3d38292368 100644 --- a/pkg/parsers/kernel/kernel_windows.go +++ b/pkg/parsers/kernel/kernel_windows.go @@ -63,7 +63,7 @@ func GetKernelVersion() (*VersionInfo, error) { } KVI.major = int(dwVersion & 0xFF) - KVI.minor = int((dwVersion & 0XFF00) >> 8) + KVI.minor = int((dwVersion & 0xFF00) >> 8) KVI.build = int((dwVersion & 0xFFFF0000) >> 16) return KVI, nil diff --git a/storage.conf b/storage.conf index 3e7bf62f06..4e049f8bfd 100644 --- a/storage.conf +++ b/storage.conf @@ -25,21 +25,6 @@ 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" - -# mountopt specifies comma separated list of extra mount options -mountopt = "nodev" - -# ignore_chown_errors can be set to allow a non privileged user running with -# a single UID within a user namespace to run containers. The user can pull -# and use any image even those with multiple uids. Note multiple UIDs will be -# squasheddown to the default uid in the container. These images will have no -# separation between the users in the container. Only supported for the overlay -# and vfs drivers. -#ignore_chown_errors = false - # Remap-UIDs/GIDs is the mapping from UIDs/GIDs as they should appear inside of # a container, to the UIDs/GIDs as they should appear outside of the container, # and the length of the range of UIDs/GIDs. Additional mapped sets can be @@ -68,6 +53,22 @@ ostree_repo = "" # certain container storage drivers (overlay). skip_mount_home = "false" +[storage.options.overlay] +# ignore_chown_errors can be set to allow a non privileged user running with +# a single UID within a user namespace to run containers. The user can pull +# and use any image even those with multiple uids. Note multiple UIDs will be +# squasheddown to the default uid in the container. These images will have no +# separation between the users in the container. Only supported for the overlay +# and vfs drivers. +#ignore_chown_errors = false + +# Path to an helper program to use for mounting the file system instead of mounting it +# directly. +#mount_program = "/usr/bin/fuse-overlayfs" + +# mountopt specifies comma separated list of extra mount options +mountopt = "nodev" + [storage.options.thinpool] # Storage Options for thinpool diff --git a/store.go b/store.go index dd34052121..4d27f0329d 100644 --- a/store.go +++ b/store.go @@ -3298,50 +3298,6 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) { if config.Storage.GraphRoot != "" { storeOptions.GraphRoot = config.Storage.GraphRoot } - if 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 != "" { - storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.thinp_autoextend_threshold=%s", config.Storage.Options.Thinpool.AutoExtendThreshold)) - } - - if 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 != "" { - storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.blocksize=%s", config.Storage.Options.Thinpool.BlockSize)) - } - if 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 != "" { - storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.directlvm_device_force=%s", config.Storage.Options.Thinpool.DirectLvmDeviceForce)) - } - if 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 != "" { - storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.libdm_log_level=%s", config.Storage.Options.Thinpool.LogLevel)) - } - if 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 != "" { - storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.mkfsarg=%s", config.Storage.Options.Thinpool.MkfsArg)) - } - if config.Storage.Options.Thinpool.MountOpt != "" { - storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mountopt=%s", config.Storage.Driver, config.Storage.Options.Thinpool.MountOpt)) - } - if 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 != "" { - storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.use_deferred_removal=%s", config.Storage.Options.Thinpool.UseDeferredRemoval)) - } - if 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 { storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.imagestore=%s", config.Storage.Driver, s)) } @@ -3394,6 +3350,83 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) { if os.Getenv("STORAGE_DRIVER") != "" { storeOptions.GraphDriverName = os.Getenv("STORAGE_DRIVER") } + switch storeOptions.GraphDriverName { + case "aufs": + if config.Storage.Options.Aufs.MountOpt != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mountopt=%s", config.Storage.Driver, config.Storage.Options.Aufs.MountOpt)) + } + + case "btrfs": + if config.Storage.Options.Btrfs.MinSpace != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.min_space=%s", config.Storage.Driver, config.Storage.Options.Btrfs.MinSpace)) + } + + case "devicemapper": + if 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 != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.thinp_autoextend_threshold=%s", config.Storage.Options.Thinpool.AutoExtendThreshold)) + } + + if 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 != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.blocksize=%s", config.Storage.Options.Thinpool.BlockSize)) + } + if 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 != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.directlvm_device_force=%s", config.Storage.Options.Thinpool.DirectLvmDeviceForce)) + } + if 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 != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.libdm_log_level=%s", config.Storage.Options.Thinpool.LogLevel)) + } + if 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 != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.mkfsarg=%s", config.Storage.Options.Thinpool.MkfsArg)) + } + if config.Storage.Options.Thinpool.MountOpt != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mountopt=%s", config.Storage.Driver, config.Storage.Options.Thinpool.MountOpt)) + } + if 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 != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.use_deferred_removal=%s", config.Storage.Options.Thinpool.UseDeferredRemoval)) + } + if config.Storage.Options.Thinpool.XfsNoSpaceMaxRetries != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("dm.xfs_nospace_max_retries=%s", config.Storage.Options.Thinpool.XfsNoSpaceMaxRetries)) + } + case "overlay": + if config.Storage.Options.Overlay.IgnoreChownErrors != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.ignore_chown_errors=%s", config.Storage.Driver, config.Storage.Options.Overlay.IgnoreChownErrors)) + } + if config.Storage.Options.Overlay.MountProgram != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mount_program=%s", config.Storage.Driver, config.Storage.Options.Overlay.MountProgram)) + } + if config.Storage.Options.Overlay.MountOpt != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mountopt=%s", config.Storage.Driver, config.Storage.Options.Overlay.MountOpt)) + } + if config.Storage.Options.Overlay.SkipMountHome != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.skip_mount_home=%s", config.Storage.Driver, config.Storage.Options.Overlay.SkipMountHome)) + } + case "zfs": + if config.Storage.Options.Zfs.Name != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.fsname=%s", config.Storage.Driver, config.Storage.Options.Zfs.Name)) + } + if config.Storage.Options.Zfs.MountOpt != "" { + storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mountopt=%s", config.Storage.Driver, config.Storage.Options.Zfs.MountOpt)) + } + } if os.Getenv("STORAGE_OPTS") != "" { storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, strings.Split(os.Getenv("STORAGE_OPTS"), ",")...) }