store: drop remap-[ug]ids

drop the possibility to configure a remapping for all the layers in
the storage.

The feature dates back to the initial fork from Docker, that supported
a single user namespace where all the images were pulled. It was never
used by the container tools since we have a finer control of the user
namespaces.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2024-06-19 12:16:57 +02:00
parent 9a0bef07c7
commit 2d959dd4bf
No known key found for this signature in database
GPG Key ID: 67E38F7A8BA21772
14 changed files with 15 additions and 261 deletions

View File

@ -111,24 +111,6 @@ containers/storage supports four keys
partial pulls in order to take advantage of local deduplication and hardlinking. It is an
expensive operation so it is not enabled by default.
**remap-uids=**""
**remap-gids=**""
Remap-UIDs/GIDs is the mapping from UIDs/GIDs as they should appear inside of a container, to the UIDs/GIDs outside of the container, and the length of the range of UIDs/GIDs. Additional mapped sets can be listed and will be heeded by libraries, but there are limits to the number of mappings which the kernel will allow when you later attempt to run a container.
Example
remap-uids = "0:1668442479:65536"
remap-gids = "0:1668442479:65536"
These mappings tell the container engines to map UID 0 inside of the container to UID 1668442479 outside. UID 1 will be mapped to 1668442480. UID 2 will be mapped to 1668442481, etc, for the next 65533 UIDs in succession.
**remap-user**=""
**remap-group**=""
Remap-User/Group is a user name which can be used to look up one or more UID/GID ranges in the /etc/subuid or /etc/subgid file. Mappings are set up starting with an in-container ID of 0 and then a host-level ID taken from the lowest range that matches the specified name, and using the length of that range. Additional ranges are then assigned, using the ranges which specify the lowest host-level IDs first, to the lowest not-yet-mapped in-container ID, until all of the entries have been used for maps. This setting overrides the Remap-UIDs/GIDs setting.
Example
remap-user = "containers"
remap-group = "containers"
**root-auto-userns-user**=""
Root-auto-userns-user is a user name which can be used to look up one or more UID/GID ranges in the /etc/subuid and /etc/subgid file. These ranges will be partitioned to containers configured to create automatically a user namespace. Containers configured to automatically create a user namespace can still overlap with containers having an explicit mapping set. This setting is ignored when running as rootless.

View File

@ -75,8 +75,6 @@ func init() {
type Driver struct {
sync.Mutex
root string
uidMaps []idtools.IDMap
gidMaps []idtools.IDMap
ctr *graphdriver.RefCounter
pathCacheLock sync.Mutex
pathCache map[string]string
@ -129,22 +127,16 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
a := &Driver{
root: home,
uidMaps: options.UIDMaps,
gidMaps: options.GIDMaps,
pathCache: make(map[string]string),
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicAufs)),
locker: locker.New(),
mountOptions: mountOptions,
}
rootUID, rootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
if err != nil {
return nil, err
}
// Create the root aufs driver dir and return
// if it already exists
// If not populate the dir structure
if err := idtools.MkdirAllAs(home, 0o700, rootUID, rootGID); err != nil {
if err := os.MkdirAll(home, 0o700); err != nil {
if os.IsExist(err) {
return a, nil
}
@ -157,7 +149,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
// Populate the dir structure
for _, p := range paths {
if err := idtools.MkdirAllAs(path.Join(home, p), 0o700, rootUID, rootGID); err != nil {
if err := os.MkdirAll(path.Join(home, p), 0o700); err != nil {
return nil, err
}
}
@ -334,7 +326,7 @@ func (a *Driver) createDirsFor(id, parent string) error {
// The path of directories are <aufs_root_path>/mnt/<image_id>
// and <aufs_root_path>/diff/<image_id>
for _, p := range paths {
rootPair := idtools.NewIDMappingsFromMaps(a.uidMaps, a.gidMaps).RootPair()
rootPair := idtools.IDPair{UID: 0, GID: 0}
rootPerms := defaultPerms
if parent != "" {
st, err := system.Stat(path.Join(a.rootPath(), p, parent))

View File

@ -66,11 +66,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
return nil, fmt.Errorf("%q is not on a btrfs filesystem: %w", home, graphdriver.ErrPrerequisites)
}
rootUID, rootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
if err != nil {
return nil, err
}
if err := idtools.MkdirAllAs(filepath.Join(home, "subvolumes"), 0o700, rootUID, rootGID); err != nil {
if err := os.MkdirAll(filepath.Join(home, "subvolumes"), 0o700); err != nil {
return nil, err
}
@ -85,8 +81,6 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
driver := &Driver{
home: home,
uidMaps: options.UIDMaps,
gidMaps: options.GIDMaps,
options: opt,
}
@ -129,8 +123,6 @@ func parseOptions(opt []string) (btrfsOptions, bool, error) {
type Driver struct {
// root of the file system
home string
uidMaps []idtools.IDMap
gidMaps []idtools.IDMap
options btrfsOptions
quotaEnabled bool
once sync.Once
@ -481,11 +473,7 @@ func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts
func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
quotas := d.quotasDir()
subvolumes := d.subvolumesDir()
rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
if err != nil {
return err
}
if err := idtools.MkdirAllAs(subvolumes, 0o700, rootUID, rootGID); err != nil {
if err := os.MkdirAll(subvolumes, 0o700); err != nil {
return err
}
if parent == "" {
@ -523,7 +511,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
if err := d.setStorageSize(path.Join(subvolumes, id), driver); err != nil {
return err
}
if err := idtools.MkdirAllAs(quotas, 0o700, rootUID, rootGID); err != nil {
if err := os.MkdirAll(quotas, 0o700); err != nil {
return err
}
if err := os.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(driver.options.size)), 0o644); err != nil {
@ -531,14 +519,6 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
}
}
// if we have a remapped root (user namespaces enabled), change the created snapshot
// dir ownership to match
if rootUID != 0 || rootGID != 0 {
if err := os.Chown(path.Join(subvolumes, id), rootUID, rootGID); err != nil {
return err
}
}
mountLabel := ""
if opts != nil {
mountLabel = opts.MountLabel

View File

@ -382,8 +382,6 @@ type Options struct {
ImageStore string
DriverPriority []string
DriverOptions []string
UIDMaps []idtools.IDMap
GIDMaps []idtools.IDMap
ExperimentalEnabled bool
}

View File

@ -120,8 +120,6 @@ type Driver struct {
home string
runhome string
imageStore string
uidMaps []idtools.IDMap
gidMaps []idtools.IDMap
ctr *graphdriver.RefCounter
quotaCtl *quota.Control
options overlayOptions
@ -333,13 +331,9 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
backingFs = fsName
runhome := filepath.Join(options.RunRoot, filepath.Base(home))
rootUID, rootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
if err != nil {
return nil, err
}
// Create the driver home dir
if err := idtools.MkdirAllAs(path.Join(home, linkDir), 0o755, 0, 0); err != nil {
if err := os.MkdirAll(path.Join(home, linkDir), 0o755); err != nil {
return nil, err
}
@ -349,7 +343,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
}
}
if err := idtools.MkdirAllAs(runhome, 0o700, rootUID, rootGID); err != nil {
if err := os.MkdirAll(runhome, 0o700); err != nil {
return nil, err
}
@ -455,8 +449,6 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
home: home,
imageStore: options.ImageStore,
runhome: runhome,
uidMaps: options.UIDMaps,
gidMaps: options.GIDMaps,
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(fileSystemType)),
supportsDType: supportsDType,
usingMetacopy: usingMetacopy,
@ -1023,8 +1015,8 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnl
disableQuota := readOnly
uidMaps := d.uidMaps
gidMaps := d.gidMaps
var uidMaps []idtools.IDMap
var gidMaps []idtools.IDMap
if opts != nil && opts.IDMappings != nil {
uidMaps = opts.IDMappings.UIDs()
@ -1293,12 +1285,6 @@ func (d *Driver) getLowerDirs(id string) ([]string, error) {
}
func (d *Driver) optsAppendMappings(opts string, uidMaps, gidMaps []idtools.IDMap) string {
if uidMaps == nil {
uidMaps = d.uidMaps
}
if gidMaps == nil {
gidMaps = d.gidMaps
}
if uidMaps != nil {
var uids, gids bytes.Buffer
if len(uidMaps) == 1 && uidMaps[0].Size == 1 {

View File

@ -33,12 +33,10 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
d := &Driver{
name: "vfs",
home: home,
idMappings: idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps),
imageStore: options.ImageStore,
}
rootIDs := d.idMappings.RootPair()
if err := idtools.MkdirAllAndChown(filepath.Join(home, "dir"), 0o700, rootIDs); err != nil {
if err := os.MkdirAll(filepath.Join(home, "dir"), 0o700); err != nil {
return nil, err
}
for _, option := range options.DriverOptions {
@ -79,7 +77,6 @@ type Driver struct {
name string
home string
additionalHomes []string
idMappings *idtools.IDMappings
ignoreChownErrors bool
naiveDiff graphdriver.DiffDriver
updater graphdriver.LayerIDMapUpdater
@ -152,14 +149,8 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, ro bool
return fmt.Errorf("--storage-opt is not supported for vfs")
}
idMappings := d.idMappings
if opts != nil && opts.IDMappings != nil {
idMappings = opts.IDMappings
}
dir := d.dir2(id, ro)
rootIDs := idMappings.RootPair()
if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0o700, rootIDs); err != nil {
if err := os.MkdirAll(filepath.Dir(dir), 0o700); err != nil {
return err
}
@ -174,6 +165,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, ro bool
rootPerms = os.FileMode(0o700)
}
rootIDs := idtools.IDPair{UID: 0, GID: 0}
if parent != "" {
st, err := system.Stat(d.dir(parent))
if err != nil {

View File

@ -106,11 +106,7 @@ func Init(base string, opt graphdriver.Options) (graphdriver.Driver, error) {
return nil, fmt.Errorf("zfs get all -t filesystem -rHp '%s' should contain '%s'", options.fsName, options.fsName)
}
rootUID, rootGID, err := idtools.GetRootUIDGID(opt.UIDMaps, opt.GIDMaps)
if err != nil {
return nil, fmt.Errorf("failed to get root uid/gid: %w", err)
}
if err := idtools.MkdirAllAs(base, 0o700, rootUID, rootGID); err != nil {
if err := os.MkdirAll(base, 0o700); err != nil {
return nil, fmt.Errorf("failed to create '%s': %w", base, err)
}
@ -118,8 +114,6 @@ func Init(base string, opt graphdriver.Options) (graphdriver.Driver, error) {
dataset: rootDataset,
options: options,
filesystemsCache: filesystemsCache,
uidMaps: opt.UIDMaps,
gidMaps: opt.GIDMaps,
ctr: graphdriver.NewRefCounter(graphdriver.NewDefaultChecker()),
}
return graphdriver.NewNaiveDiffDriver(d, graphdriver.NewNaiveLayerIDMapUpdater(d)), nil
@ -177,8 +171,6 @@ type Driver struct {
options zfsOptions
sync.Mutex // protects filesystem cache against concurrent access
filesystemsCache map[string]bool
uidMaps []idtools.IDMap
gidMaps []idtools.IDMap
ctr *graphdriver.RefCounter
}
@ -448,12 +440,8 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr
opts := label.FormatMountLabel(mountOptions, options.MountLabel)
logrus.WithField("storage-driver", "zfs").Debugf(`mount("%s", "%s", "%s")`, filesystem, mountpoint, opts)
rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
if err != nil {
return "", err
}
// Create the target directories if they don't exist
if err := idtools.MkdirAllAs(mountpoint, 0o755, rootUID, rootGID); err != nil {
if err := os.MkdirAll(mountpoint, 0o755); err != nil {
return "", err
}

View File

@ -75,10 +75,6 @@ type OptionsConfig struct {
// Size
Size string `toml:"size,omitempty"`
// RemapUIDs is a list of default UID mappings to use for layers.
RemapUIDs string `toml:"remap-uids,omitempty"`
// RemapGIDs is a list of default GID mappings to use for layers.
RemapGIDs string `toml:"remap-gids,omitempty"`
// IgnoreChownErrors is a flag for whether chown errors should be
// ignored when building an image.
IgnoreChownErrors string `toml:"ignore_chown_errors,omitempty"`
@ -90,13 +86,6 @@ type OptionsConfig struct {
// files and directories.
ForceMask os.FileMode `toml:"force_mask,omitempty"`
// RemapUser is the name of one or more entries in /etc/subuid which
// should be used to set up default UID mappings.
RemapUser string `toml:"remap-user,omitempty"`
// 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,omitempty"`
// RootAutoUsernsUser is the name of one or more entries in /etc/subuid and
// /etc/subgid which should be used to set up automatically a userns.
RootAutoUsernsUser string `toml:"root-auto-userns-user,omitempty"`

View File

@ -77,28 +77,6 @@ additionalimagestores = [
# operation so it is not enabled by default.
pull_options = {enable_partial_images = "true", use_hard_links = "false", ostree_repos=""}
# 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
# listed and will be heeded by libraries, but there are limits to the number of
# mappings which the kernel will allow when you later attempt to run a
# container.
#
# remap-uids = "0:1668442479:65536"
# remap-gids = "0:1668442479:65536"
# Remap-User/Group is a user name which can be used to look up one or more UID/GID
# ranges in the /etc/subuid or /etc/subgid file. Mappings are set up starting
# with an in-container ID of 0 and then a host-level ID taken from the lowest
# range that matches the specified name, and using the length of that range.
# Additional ranges are then assigned, using the ranges which specify the
# lowest host-level IDs first, to the lowest not-yet-mapped in-container ID,
# until all of the entries have been used for maps. This setting overrides the
# Remap-UIDs/GIDs setting.
#
# remap-user = "containers"
# remap-group = "containers"
# Root-auto-userns-user is a user name which can be used to look up one or more UID/GID
# ranges in the /etc/subuid and /etc/subgid file. These ranges will be partitioned
# to containers configured to create automatically a user namespace. Containers

View File

@ -39,27 +39,6 @@ graphroot = "/var/db/containers/storage"
additionalimagestores = [
]
# 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
# listed and will be heeded by libraries, but there are limits to the number of
# mappings which the kernel will allow when you later attempt to run a
# container.
#
# remap-uids = 0:1668442479:65536
# remap-gids = 0:1668442479:65536
# Remap-User/Group is a user name which can be used to look up one or more UID/GID
# ranges in the /etc/subuid or /etc/subgid file. Mappings are set up starting
# with an in-container ID of 0 and then a host-level ID taken from the lowest
# range that matches the specified name, and using the length of that range.
# Additional ranges are then assigned, using the ranges which specify the
# lowest host-level IDs first, to the lowest not-yet-mapped in-container ID,
# until all of the entries have been used for maps.
#
# remap-user = "containers"
# remap-group = "containers"
# Root-auto-userns-user is a user name which can be used to look up one or more UID/GID
# ranges in the /etc/subuid and /etc/subgid file. These ranges will be partitioned
# to containers configured to create automatically a user namespace. Containers

View File

@ -1088,8 +1088,6 @@ func (s *store) createGraphDriverLocked() (drivers.Driver, error) {
RunRoot: s.runRoot,
DriverPriority: s.graphDriverPriority,
DriverOptions: s.graphOptions,
UIDMaps: s.uidMap,
GIDMaps: s.gidMap,
}
return drivers.New(s.graphDriverName, config)
}

View File

@ -481,33 +481,6 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) erro
if config.Storage.Options.MountOpt != "" {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.mountopt=%s", config.Storage.Driver, config.Storage.Options.MountOpt))
}
uidmap, err := idtools.ParseIDMap([]string{config.Storage.Options.RemapUIDs}, "remap-uids")
if err != nil {
return err
}
gidmap, err := idtools.ParseIDMap([]string{config.Storage.Options.RemapGIDs}, "remap-gids")
if err != nil {
return err
}
if config.Storage.Options.RemapUser != "" && config.Storage.Options.RemapGroup == "" {
config.Storage.Options.RemapGroup = config.Storage.Options.RemapUser
}
if config.Storage.Options.RemapGroup != "" && config.Storage.Options.RemapUser == "" {
config.Storage.Options.RemapUser = config.Storage.Options.RemapGroup
}
if config.Storage.Options.RemapUser != "" && config.Storage.Options.RemapGroup != "" {
mappings, err := idtools.NewIDMappings(config.Storage.Options.RemapUser, config.Storage.Options.RemapGroup)
if err != nil {
logrus.Warningf("Error initializing ID mappings for %s:%s %v\n", config.Storage.Options.RemapUser, config.Storage.Options.RemapGroup, err)
return err
}
uidmap = mappings.UIDs()
gidmap = mappings.GIDs()
}
storeOptions.UIDMap = uidmap
storeOptions.GIDMap = gidmap
storeOptions.RootAutoNsUser = config.Storage.Options.RootAutoUsernsUser
if config.Storage.Options.AutoUsernsMinSize > 0 {
storeOptions.AutoNsMinSize = config.Storage.Options.AutoUsernsMinSize

View File

@ -5,11 +5,9 @@ import (
"fmt"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
@ -126,75 +124,6 @@ func TestGetRootlessStorageOpts2(t *testing.T) {
assert.Equal(t, storageOpts.GraphRoot, expectedPath)
}
func TestSetRemapUIDsGIDsOpts(t *testing.T) {
var remapOpts StoreOptions
uidmap := []idtools.IDMap{
{
ContainerID: 0,
HostID: 1000000000,
Size: 30000,
},
}
gidmap := []idtools.IDMap{
{
ContainerID: 0,
HostID: 1500000000,
Size: 60000,
},
}
err := ReloadConfigurationFile("./storage_test.conf", &remapOpts)
require.NoError(t, err)
if !reflect.DeepEqual(uidmap, remapOpts.UIDMap) {
t.Errorf("Failed to set UIDMap: Expected %v Actual %v", uidmap, remapOpts.UIDMap)
}
if !reflect.DeepEqual(gidmap, remapOpts.GIDMap) {
t.Errorf("Failed to set GIDMap: Expected %v Actual %v", gidmap, remapOpts.GIDMap)
}
}
func TestSetRemapUserGroupOpts(t *testing.T) {
var remapOpts StoreOptions
user := os.Getenv("USER")
if user == "root" {
t.Skip("This test is enabled only rootless user")
}
configPath := "./remap_user_test.conf"
config := fmt.Sprintf(`
[storage]
driver = ""
[storage.options]
remap-uids = "0:1000000000:30000"
remap-gids = "0:1500000000:60000"
remap-user = "%s"
remap-group = "%s"
`, user, user)
f, err := os.Create(configPath)
require.NoError(t, err)
defer func() {
f.Close()
os.Remove(configPath)
}()
_, err = f.Write([]byte(config))
require.NoError(t, err)
mappings, err := idtools.NewIDMappings(user, user)
require.NoError(t, err)
err = ReloadConfigurationFile(configPath, &remapOpts)
require.NoError(t, err)
if !reflect.DeepEqual(mappings.UIDs(), remapOpts.UIDMap) {
t.Errorf("Failed to set UIDMap: Expected %v Actual %v", mappings.UIDs(), remapOpts.UIDMap)
}
if !reflect.DeepEqual(mappings.GIDs(), remapOpts.GIDMap) {
t.Errorf("Failed to set GIDMap: Expected %v Actual %v", mappings.GIDs(), remapOpts.GIDMap)
}
}
func TestReloadConfigurationFile(t *testing.T) {
content := bytes.NewBufferString("")
logrus.SetOutput(content)

View File

@ -25,16 +25,6 @@ rootless_storage_path = "$HOME/$UID/containers/storage"
additionalimagestores = [
]
# 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
# listed and will be heeded by libraries, but there are limits to the number of
# mappings which the kernel will allow when you later attempt to run a
# container.
#
remap-uids = "0:1000000000:30000"
remap-gids = "0:1500000000:60000"
[storage.options.overlay]
# mountopt specifies comma separated list of extra mount options