1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
package types
import (
"fmt"
"os"
"github.com/containers/storage/pkg/idtools"
)
// AutoUserNsOptions defines how to automatically create a user namespace.
type AutoUserNsOptions struct {
// Size defines the size for the user namespace. If it is set to a
// value bigger than 0, the user namespace will have exactly this size.
// If it is not set, some heuristics will be used to find its size.
Size uint32
// InitialSize defines the minimum size for the user namespace.
// The created user namespace will have at least this size.
InitialSize uint32
// PasswdFile to use if the container uses a volume.
PasswdFile string
// GroupFile to use if the container uses a volume.
GroupFile string
// AdditionalUIDMappings specified additional UID mappings to include in
// the generated user namespace.
AdditionalUIDMappings []idtools.IDMap
// AdditionalGIDMappings specified additional GID mappings to include in
// the generated user namespace.
AdditionalGIDMappings []idtools.IDMap
}
// IDMappingOptions are used for specifying how ID mapping should be set up for
// a layer or container.
type IDMappingOptions struct {
// UIDMap and GIDMap are used for setting up a layer's root filesystem
// for use inside of a user namespace where ID mapping is being used.
// If HostUIDMapping/HostGIDMapping is true, no mapping of the
// respective type will be used. Otherwise, if UIDMap and/or GIDMap
// contain at least one mapping, one or both will be used. By default,
// if neither of those conditions apply, if the layer has a parent
// layer, the parent layer's mapping will be used, and if it does not
// have a parent layer, the mapping which was passed to the Store
// object when it was initialized will be used.
HostUIDMapping bool
HostGIDMapping bool
UIDMap []idtools.IDMap
GIDMap []idtools.IDMap
AutoUserNs bool
AutoUserNsOpts AutoUserNsOptions
}
// ParseIDMapping takes idmappings and subuid and subgid maps and returns a storage mapping
func ParseIDMapping(UIDMapSlice, GIDMapSlice []string, subUIDMap, subGIDMap string) (*IDMappingOptions, error) {
options := IDMappingOptions{
HostUIDMapping: true,
HostGIDMapping: true,
}
if subGIDMap == "" && subUIDMap != "" {
subGIDMap = subUIDMap
}
if subUIDMap == "" && subGIDMap != "" {
subUIDMap = subGIDMap
}
if len(GIDMapSlice) == 0 && len(UIDMapSlice) != 0 {
GIDMapSlice = UIDMapSlice
}
if len(UIDMapSlice) == 0 && len(GIDMapSlice) != 0 {
UIDMapSlice = GIDMapSlice
}
if len(UIDMapSlice) == 0 && subUIDMap == "" && os.Getuid() != 0 {
UIDMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getuid())}
}
if len(GIDMapSlice) == 0 && subGIDMap == "" && os.Getuid() != 0 {
GIDMapSlice = []string{fmt.Sprintf("0:%d:1", os.Getgid())}
}
if subUIDMap != "" && subGIDMap != "" {
mappings, err := idtools.NewIDMappings(subUIDMap, subGIDMap)
if err != nil {
return nil, fmt.Errorf("failed to create NewIDMappings for uidmap=%s gidmap=%s: %w", subUIDMap, subGIDMap, err)
}
options.UIDMap = mappings.UIDs()
options.GIDMap = mappings.GIDs()
}
parsedUIDMap, err := idtools.ParseIDMap(UIDMapSlice, "UID")
if err != nil {
return nil, fmt.Errorf("failed to create ParseUIDMap UID=%s: %w", UIDMapSlice, err)
}
parsedGIDMap, err := idtools.ParseIDMap(GIDMapSlice, "GID")
if err != nil {
return nil, fmt.Errorf("failed to create ParseGIDMap GID=%s: %w", UIDMapSlice, err)
}
options.UIDMap = append(options.UIDMap, parsedUIDMap...)
options.GIDMap = append(options.GIDMap, parsedGIDMap...)
if len(options.UIDMap) > 0 {
options.HostUIDMapping = false
}
if len(options.GIDMap) > 0 {
options.HostGIDMapping = false
}
return &options, nil
}
|