diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/secrets/secrets.go | 23 | ||||
-rw-r--r-- | pkg/util/utils.go | 76 |
2 files changed, 95 insertions, 4 deletions
diff --git a/pkg/secrets/secrets.go b/pkg/secrets/secrets.go index 04890c06a..29ccd4592 100644 --- a/pkg/secrets/secrets.go +++ b/pkg/secrets/secrets.go @@ -127,7 +127,12 @@ func getMountsMap(path string) (string, string, error) { } // SecretMounts copies, adds, and mounts the secrets to the container root filesystem -func SecretMounts(mountLabel, containerWorkingDir string, mountFile string) []rspec.Mount { +func SecretMounts(mountLabel, containerWorkingDir, mountFile string) []rspec.Mount { + return SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, 0, 0) +} + +// SecretMountsWithUIDGID specifies the uid/gid of the owner +func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile string, uid, gid int) []rspec.Mount { var ( secretMounts []rspec.Mount mountFiles []string @@ -141,7 +146,7 @@ func SecretMounts(mountLabel, containerWorkingDir string, mountFile string) []rs mountFiles = append(mountFiles, mountFile) } for _, file := range mountFiles { - mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir) + mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir, uid, gid) if err != nil { logrus.Warnf("error mounting secrets, skipping: %v", err) } @@ -162,9 +167,15 @@ func SecretMounts(mountLabel, containerWorkingDir string, mountFile string) []rs return secretMounts } +func rchown(chowndir string, uid, gid int) error { + return filepath.Walk(chowndir, func(filePath string, f os.FileInfo, err error) error { + return os.Lchown(filePath, uid, gid) + }) +} + // addSecretsFromMountsFile copies the contents of host directory to container directory // and returns a list of mounts -func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string) ([]rspec.Mount, error) { +func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string, uid, gid int) ([]rspec.Mount, error) { var mounts []rspec.Mount defaultMountsPaths := getMounts(filePath) for _, path := range defaultMountsPaths { @@ -186,7 +197,6 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string) if err = os.MkdirAll(ctrDirOnHost, 0755); err != nil { return nil, errors.Wrapf(err, "making container directory failed") } - hostDir, err = resolveSymbolicLink(hostDir) if err != nil { return nil, err @@ -206,6 +216,11 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir string) if err != nil { return nil, errors.Wrap(err, "error applying correct labels") } + if uid != 0 || gid != 0 { + if err := rchown(ctrDirOnHost, uid, gid); err != nil { + return nil, err + } + } } else if err != nil { return nil, errors.Wrapf(err, "error getting status of %q", ctrDirOnHost) } diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 1bbfe30d3..a29a1ee60 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -2,9 +2,12 @@ package util import ( "fmt" + "strconv" "strings" "github.com/containers/image/types" + "github.com/containers/storage" + "github.com/containers/storage/pkg/idtools" "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "golang.org/x/crypto/ssh/terminal" @@ -120,3 +123,76 @@ func GetImageConfig(changes []string) (v1.ImageConfig, error) { StopSignal: stopSignal, }, nil } + +// ParseIDMapping takes idmappings and subuid and subgid maps and returns a storage mapping +func ParseIDMapping(UIDMapSlice, GIDMapSlice []string, subUIDMap, subGIDMap string) (*storage.IDMappingOptions, error) { + options := storage.IDMappingOptions{ + HostUIDMapping: true, + HostGIDMapping: true, + } + if subGIDMap == "" && subUIDMap != "" { + subGIDMap = subUIDMap + } + if subUIDMap == "" && subGIDMap != "" { + subUIDMap = subGIDMap + } + parseTriple := func(spec []string) (container, host, size int, err error) { + cid, err := strconv.ParseUint(spec[0], 10, 32) + if err != nil { + return 0, 0, 0, fmt.Errorf("error parsing id map value %q: %v", spec[0], err) + } + hid, err := strconv.ParseUint(spec[1], 10, 32) + if err != nil { + return 0, 0, 0, fmt.Errorf("error parsing id map value %q: %v", spec[1], err) + } + sz, err := strconv.ParseUint(spec[2], 10, 32) + if err != nil { + return 0, 0, 0, fmt.Errorf("error parsing id map value %q: %v", spec[2], err) + } + return int(cid), int(hid), int(sz), nil + } + parseIDMap := func(spec []string) (idmap []idtools.IDMap, err error) { + for _, uid := range spec { + splitmap := strings.SplitN(uid, ":", 3) + if len(splitmap) < 3 { + return nil, fmt.Errorf("invalid mapping requires 3 fields: %q", uid) + } + cid, hid, size, err := parseTriple(splitmap) + if err != nil { + return nil, err + } + pmap := idtools.IDMap{ + ContainerID: cid, + HostID: hid, + Size: size, + } + idmap = append(idmap, pmap) + } + return idmap, nil + } + if subUIDMap != "" && subGIDMap != "" { + mappings, err := idtools.NewIDMappings(subUIDMap, subGIDMap) + if err != nil { + return nil, err + } + options.UIDMap = mappings.UIDs() + options.GIDMap = mappings.GIDs() + } + parsedUIDMap, err := parseIDMap(UIDMapSlice) + if err != nil { + return nil, err + } + parsedGIDMap, err := parseIDMap(GIDMapSlice) + if err != nil { + return nil, 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 +} |