Browse code

Remove ToHost and replace it with IDMappings.ToHost

Signed-off-by: Daniel Nephin <dnephin@docker.com>

Daniel Nephin authored on 2017/06/01 06:18:04
Showing 5 changed files
... ...
@@ -413,15 +413,11 @@ func (ta *tarAppender) addTarFile(path, name string) error {
413 413
 	//writing tar headers/files. We skip whiteout files because they were written
414 414
 	//by the kernel and already have proper ownership relative to the host
415 415
 	if !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && !ta.IDMappings.Empty() {
416
-		uid, gid, err := getFileUIDGID(fi.Sys())
416
+		fileIDPair, err := getFileUIDGID(fi.Sys())
417 417
 		if err != nil {
418 418
 			return err
419 419
 		}
420
-		hdr.Uid, err = ta.IDMappings.UIDToContainer(uid)
421
-		if err != nil {
422
-			return err
423
-		}
424
-		hdr.Gid, err = ta.IDMappings.GIDToContainer(gid)
420
+		hdr.Uid, hdr.Gid, err = ta.IDMappings.ToContainer(fileIDPair)
425 421
 		if err != nil {
426 422
 			return err
427 423
 		}
... ...
@@ -806,7 +802,8 @@ func Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) err
806 806
 	defer pools.BufioReader32KPool.Put(trBuf)
807 807
 
808 808
 	var dirs []*tar.Header
809
-	remappedRootUID, remappedRootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
809
+	idMappings := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
810
+	rootIDs, err := idMappings.RootPair()
810 811
 	if err != nil {
811 812
 		return err
812 813
 	}
... ...
@@ -843,7 +840,7 @@ loop:
843 843
 			parent := filepath.Dir(hdr.Name)
844 844
 			parentPath := filepath.Join(dest, parent)
845 845
 			if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
846
-				err = idtools.MkdirAllNewAs(parentPath, 0777, remappedRootUID, remappedRootGID)
846
+				err = idtools.MkdirAllAndChownNew(parentPath, 0777, rootIDs)
847 847
 				if err != nil {
848 848
 					return err
849 849
 				}
... ...
@@ -888,26 +885,8 @@ loop:
888 888
 		}
889 889
 		trBuf.Reset(tr)
890 890
 
891
-		// if the options contain a uid & gid maps, convert header uid/gid
892
-		// entries using the maps such that lchown sets the proper mapped
893
-		// uid/gid after writing the file. We only perform this mapping if
894
-		// the file isn't already owned by the remapped root UID or GID, as
895
-		// that specific uid/gid has no mapping from container -> host, and
896
-		// those files already have the proper ownership for inside the
897
-		// container.
898
-		if hdr.Uid != remappedRootUID {
899
-			xUID, err := idtools.ToHost(hdr.Uid, options.UIDMaps)
900
-			if err != nil {
901
-				return err
902
-			}
903
-			hdr.Uid = xUID
904
-		}
905
-		if hdr.Gid != remappedRootGID {
906
-			xGID, err := idtools.ToHost(hdr.Gid, options.GIDMaps)
907
-			if err != nil {
908
-				return err
909
-			}
910
-			hdr.Gid = xGID
891
+		if err := remapIDs(idMappings, hdr); err != nil {
892
+			return err
911 893
 		}
912 894
 
913 895
 		if whiteoutConverter != nil {
... ...
@@ -1083,26 +1062,10 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
1083 1083
 		hdr.Name = filepath.Base(dst)
1084 1084
 		hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
1085 1085
 
1086
-		remappedRootIDs, err := archiver.IDMappings.RootPair()
1087
-		if err != nil {
1086
+		if err := remapIDs(archiver.IDMappings, hdr); err != nil {
1088 1087
 			return err
1089 1088
 		}
1090 1089
 
1091
-		// only perform mapping if the file being copied isn't already owned by the
1092
-		// uid or gid of the remapped root in the container
1093
-		if remappedRootIDs.UID != hdr.Uid {
1094
-			hdr.Uid, err = archiver.IDMappings.UIDToHost(hdr.Uid)
1095
-			if err != nil {
1096
-				return err
1097
-			}
1098
-		}
1099
-		if remappedRootIDs.GID != hdr.Gid {
1100
-			hdr.Gid, err = archiver.IDMappings.GIDToHost(hdr.Gid)
1101
-			if err != nil {
1102
-				return err
1103
-			}
1104
-		}
1105
-
1106 1090
 		tw := tar.NewWriter(w)
1107 1091
 		defer tw.Close()
1108 1092
 		if err := tw.WriteHeader(hdr); err != nil {
... ...
@@ -1126,6 +1089,12 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
1126 1126
 	return err
1127 1127
 }
1128 1128
 
1129
+func remapIDs(idMappings *idtools.IDMappings, hdr *tar.Header) error {
1130
+	ids, err := idMappings.ToHost(idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid})
1131
+	hdr.Uid, hdr.Gid = ids.UID, ids.GID
1132
+	return err
1133
+}
1134
+
1129 1135
 // cmdStream executes a command, and returns its stdout as a stream.
1130 1136
 // If the command fails to run or doesn't complete successfully, an error
1131 1137
 // will be returned, including anything written on stderr.
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"path/filepath"
10 10
 	"syscall"
11 11
 
12
+	"github.com/docker/docker/pkg/idtools"
12 13
 	"github.com/docker/docker/pkg/system"
13 14
 	rsystem "github.com/opencontainers/runc/libcontainer/system"
14 15
 )
... ...
@@ -72,13 +73,13 @@ func getInodeFromStat(stat interface{}) (inode uint64, err error) {
72 72
 	return
73 73
 }
74 74
 
75
-func getFileUIDGID(stat interface{}) (int, int, error) {
75
+func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
76 76
 	s, ok := stat.(*syscall.Stat_t)
77 77
 
78 78
 	if !ok {
79
-		return -1, -1, errors.New("cannot convert stat value to syscall.Stat_t")
79
+		return idtools.IDPair{}, errors.New("cannot convert stat value to syscall.Stat_t")
80 80
 	}
81
-	return int(s.Uid), int(s.Gid), nil
81
+	return idtools.IDPair{UID: int(s.Uid), GID: int(s.Gid)}, nil
82 82
 }
83 83
 
84 84
 func major(device uint64) uint64 {
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"path/filepath"
10 10
 	"strings"
11 11
 
12
+	"github.com/docker/docker/pkg/idtools"
12 13
 	"github.com/docker/docker/pkg/longpath"
13 14
 )
14 15
 
... ...
@@ -72,7 +73,7 @@ func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
72 72
 	return nil
73 73
 }
74 74
 
75
-func getFileUIDGID(stat interface{}) (int, int, error) {
75
+func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
76 76
 	// no notion of file ownership mapping yet on Windows
77
-	return 0, 0, nil
77
+	return idtools.IDPair{0, 0}, nil
78 78
 }
... ...
@@ -33,10 +33,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
33 33
 	if options.ExcludePatterns == nil {
34 34
 		options.ExcludePatterns = []string{}
35 35
 	}
36
-	remappedRootUID, remappedRootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
37
-	if err != nil {
38
-		return 0, err
39
-	}
36
+	idMappings := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
40 37
 
41 38
 	aufsTempdir := ""
42 39
 	aufsHardlinks := make(map[string]*tar.Header)
... ...
@@ -195,27 +192,10 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
195 195
 				srcData = tmpFile
196 196
 			}
197 197
 
198
-			// if the options contain a uid & gid maps, convert header uid/gid
199
-			// entries using the maps such that lchown sets the proper mapped
200
-			// uid/gid after writing the file. We only perform this mapping if
201
-			// the file isn't already owned by the remapped root UID or GID, as
202
-			// that specific uid/gid has no mapping from container -> host, and
203
-			// those files already have the proper ownership for inside the
204
-			// container.
205
-			if srcHdr.Uid != remappedRootUID {
206
-				xUID, err := idtools.ToHost(srcHdr.Uid, options.UIDMaps)
207
-				if err != nil {
208
-					return 0, err
209
-				}
210
-				srcHdr.Uid = xUID
211
-			}
212
-			if srcHdr.Gid != remappedRootGID {
213
-				xGID, err := idtools.ToHost(srcHdr.Gid, options.GIDMaps)
214
-				if err != nil {
215
-					return 0, err
216
-				}
217
-				srcHdr.Gid = xGID
198
+			if err := remapIDs(idMappings, srcHdr); err != nil {
199
+				return 0, err
218 200
 			}
201
+
219 202
 			if err := createTarFile(path, dest, srcHdr, srcData, true, nil, options.InUserNS); err != nil {
220 203
 				return 0, err
221 204
 			}
... ...
@@ -80,21 +80,13 @@ func MkdirAllAndChownNew(path string, mode os.FileMode, ids IDPair) error {
80 80
 // GetRootUIDGID retrieves the remapped root uid/gid pair from the set of maps.
81 81
 // If the maps are empty, then the root uid/gid will default to "real" 0/0
82 82
 func GetRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) {
83
-	var uid, gid int
84
-
85
-	if uidMap != nil {
86
-		xUID, err := ToHost(0, uidMap)
87
-		if err != nil {
88
-			return -1, -1, err
89
-		}
90
-		uid = xUID
83
+	uid, err := toHost(0, uidMap)
84
+	if err != nil {
85
+		return -1, -1, err
91 86
 	}
92
-	if gidMap != nil {
93
-		xGID, err := ToHost(0, gidMap)
94
-		if err != nil {
95
-			return -1, -1, err
96
-		}
97
-		gid = xGID
87
+	gid, err := toHost(0, gidMap)
88
+	if err != nil {
89
+		return -1, -1, err
98 90
 	}
99 91
 	return uid, gid, nil
100 92
 }
... ...
@@ -115,11 +107,10 @@ func toContainer(hostID int, idMap []IDMap) (int, error) {
115 115
 	return -1, fmt.Errorf("Host ID %d cannot be mapped to a container ID", hostID)
116 116
 }
117 117
 
118
-// ToHost takes an id mapping and a remapped ID, and translates the
118
+// toHost takes an id mapping and a remapped ID, and translates the
119 119
 // ID to the mapped host ID. If no map is provided, then the translation
120 120
 // assumes a 1-to-1 mapping and returns the passed in id #
121
-// Depercated: use IDMappings.UIDToHost and IDMappings.GIDToHost
122
-func ToHost(contID int, idMap []IDMap) (int, error) {
121
+func toHost(contID int, idMap []IDMap) (int, error) {
123 122
 	if idMap == nil {
124 123
 		return contID, nil
125 124
 	}
... ...
@@ -181,24 +172,35 @@ func (i *IDMappings) RootPair() (IDPair, error) {
181 181
 	return IDPair{UID: uid, GID: gid}, err
182 182
 }
183 183
 
184
-// UIDToHost returns the host UID for the container uid
185
-func (i *IDMappings) UIDToHost(uid int) (int, error) {
186
-	return ToHost(uid, i.uids)
187
-}
184
+// ToHost returns the host UID and GID for the container uid, gid.
185
+// Remapping is only performed if the ids aren't already the remapped root ids
186
+func (i *IDMappings) ToHost(pair IDPair) (IDPair, error) {
187
+	target, err := i.RootPair()
188
+	if err != nil {
189
+		return IDPair{}, err
190
+	}
188 191
 
189
-// GIDToHost returns the host GID for the container gid
190
-func (i *IDMappings) GIDToHost(gid int) (int, error) {
191
-	return ToHost(gid, i.gids)
192
-}
192
+	if pair.UID != target.UID {
193
+		target.UID, err = toHost(pair.UID, i.uids)
194
+		if err != nil {
195
+			return target, err
196
+		}
197
+	}
193 198
 
194
-// UIDToContainer returns the container UID for the host uid
195
-func (i *IDMappings) UIDToContainer(uid int) (int, error) {
196
-	return toContainer(uid, i.uids)
199
+	if pair.GID != target.GID {
200
+		target.GID, err = toHost(pair.GID, i.gids)
201
+	}
202
+	return target, err
197 203
 }
198 204
 
199
-// GIDToContainer returns the container GID for the host gid
200
-func (i *IDMappings) GIDToContainer(gid int) (int, error) {
201
-	return toContainer(gid, i.gids)
205
+// ToContainer returns the container UID and GID for the host uid and gid
206
+func (i *IDMappings) ToContainer(pair IDPair) (int, int, error) {
207
+	uid, err := toContainer(pair.UID, i.uids)
208
+	if err != nil {
209
+		return -1, -1, err
210
+	}
211
+	gid, err := toContainer(pair.GID, i.gids)
212
+	return uid, gid, err
202 213
 }
203 214
 
204 215
 // Empty returns true if there are no id mappings