summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2018-04-23 20:42:53 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2018-05-04 17:15:55 +0000
commitb51d7379987581da82902027fe91cdf298047bc0 (patch)
treef9d7fbebf3b946caea5eb5e2c626a19413c795c8 /pkg
parent1f5debd43806cc3bd07f562ff00ef4c426540f98 (diff)
downloadpodman-b51d7379987581da82902027fe91cdf298047bc0.tar.gz
podman-b51d7379987581da82902027fe91cdf298047bc0.tar.bz2
podman-b51d7379987581da82902027fe91cdf298047bc0.zip
Begin wiring in USERNS Support into podman
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Closes: #690 Approved by: mheon
Diffstat (limited to 'pkg')
-rw-r--r--pkg/secrets/secrets.go23
-rw-r--r--pkg/util/utils.go76
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
+}