Browse code

Convert tarAppender to the newIDMappings.

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

Daniel Nephin authored on 2017/05/25 03:10:15
Showing 3 changed files
... ...
@@ -345,9 +345,8 @@ type tarAppender struct {
345 345
 	Buffer    *bufio.Writer
346 346
 
347 347
 	// for hardlink mapping
348
-	SeenFiles map[uint64]string
349
-	UIDMaps   []idtools.IDMap
350
-	GIDMaps   []idtools.IDMap
348
+	SeenFiles  map[uint64]string
349
+	IDMappings *idtools.IDMappings
351 350
 
352 351
 	// For packing and unpacking whiteout files in the
353 352
 	// non standard format. The whiteout files defined
... ...
@@ -356,6 +355,15 @@ type tarAppender struct {
356 356
 	WhiteoutConverter tarWhiteoutConverter
357 357
 }
358 358
 
359
+func newTarAppender(idMapping *idtools.IDMappings, writer io.Writer) *tarAppender {
360
+	return &tarAppender{
361
+		SeenFiles:  make(map[uint64]string),
362
+		TarWriter:  tar.NewWriter(writer),
363
+		Buffer:     pools.BufioWriter32KPool.Get(nil),
364
+		IDMappings: idMapping,
365
+	}
366
+}
367
+
359 368
 // canonicalTarName provides a platform-independent and consistent posix-style
360 369
 //path for files and directories to be archived regardless of the platform.
361 370
 func canonicalTarName(name string, isDir bool) (string, error) {
... ...
@@ -404,21 +412,19 @@ func (ta *tarAppender) addTarFile(path, name string) error {
404 404
 	//handle re-mapping container ID mappings back to host ID mappings before
405 405
 	//writing tar headers/files. We skip whiteout files because they were written
406 406
 	//by the kernel and already have proper ownership relative to the host
407
-	if !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && (ta.UIDMaps != nil || ta.GIDMaps != nil) {
407
+	if !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && !ta.IDMappings.Empty() {
408 408
 		uid, gid, err := getFileUIDGID(fi.Sys())
409 409
 		if err != nil {
410 410
 			return err
411 411
 		}
412
-		xUID, err := idtools.ToContainer(uid, ta.UIDMaps)
412
+		hdr.Uid, err = ta.IDMappings.UIDToContainer(uid)
413 413
 		if err != nil {
414 414
 			return err
415 415
 		}
416
-		xGID, err := idtools.ToContainer(gid, ta.GIDMaps)
416
+		hdr.Gid, err = ta.IDMappings.GIDToContainer(gid)
417 417
 		if err != nil {
418 418
 			return err
419 419
 		}
420
-		hdr.Uid = xUID
421
-		hdr.Gid = xGID
422 420
 	}
423 421
 
424 422
 	if ta.WhiteoutConverter != nil {
... ...
@@ -640,14 +646,11 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
640 640
 	}
641 641
 
642 642
 	go func() {
643
-		ta := &tarAppender{
644
-			TarWriter:         tar.NewWriter(compressWriter),
645
-			Buffer:            pools.BufioWriter32KPool.Get(nil),
646
-			SeenFiles:         make(map[uint64]string),
647
-			UIDMaps:           options.UIDMaps,
648
-			GIDMaps:           options.GIDMaps,
649
-			WhiteoutConverter: getWhiteoutConverter(options.WhiteoutFormat),
650
-		}
643
+		ta := newTarAppender(
644
+			idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps),
645
+			compressWriter,
646
+		)
647
+		ta.WhiteoutConverter = getWhiteoutConverter(options.WhiteoutFormat)
651 648
 
652 649
 		defer func() {
653 650
 			// Make sure to check the error on Close.
... ...
@@ -394,13 +394,8 @@ func ChangesSize(newDir string, changes []Change) int64 {
394 394
 func ExportChanges(dir string, changes []Change, uidMaps, gidMaps []idtools.IDMap) (io.ReadCloser, error) {
395 395
 	reader, writer := io.Pipe()
396 396
 	go func() {
397
-		ta := &tarAppender{
398
-			TarWriter: tar.NewWriter(writer),
399
-			Buffer:    pools.BufioWriter32KPool.Get(nil),
400
-			SeenFiles: make(map[uint64]string),
401
-			UIDMaps:   uidMaps,
402
-			GIDMaps:   gidMaps,
403
-		}
397
+		ta := newTarAppender(idtools.NewIDMappingsFromMaps(uidMaps, gidMaps), writer)
398
+
404 399
 		// this buffer is needed for the duration of this piped stream
405 400
 		defer pools.BufioWriter32KPool.Put(ta.Buffer)
406 401
 
... ...
@@ -99,10 +99,10 @@ func GetRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) {
99 99
 	return uid, gid, nil
100 100
 }
101 101
 
102
-// ToContainer takes an id mapping, and uses it to translate a
102
+// toContainer takes an id mapping, and uses it to translate a
103 103
 // host ID to the remapped ID. If no map is provided, then the translation
104 104
 // assumes a 1-to-1 mapping and returns the passed in id
105
-func ToContainer(hostID int, idMap []IDMap) (int, error) {
105
+func toContainer(hostID int, idMap []IDMap) (int, error) {
106 106
 	if idMap == nil {
107 107
 		return hostID, nil
108 108
 	}
... ...
@@ -169,6 +169,12 @@ func NewIDMappings(username, groupname string) (*IDMappings, error) {
169 169
 	}, nil
170 170
 }
171 171
 
172
+// NewIDMappingsFromMaps creates a new mapping from two slices
173
+// Deprecated: this is a temporary shim while transitioning to IDMapping
174
+func NewIDMappingsFromMaps(uids []IDMap, gids []IDMap) *IDMappings {
175
+	return &IDMappings{uids: uids, gids: gids}
176
+}
177
+
172 178
 // RootPair returns a uid and gid pair for the root user
173 179
 func (i *IDMappings) RootPair() (IDPair, error) {
174 180
 	uid, gid, err := GetRootUIDGID(i.uids, i.gids)
... ...
@@ -185,6 +191,21 @@ func (i *IDMappings) GIDToHost(gid int) (int, error) {
185 185
 	return ToHost(gid, i.gids)
186 186
 }
187 187
 
188
+// UIDToContainer returns the container UID for the host uid
189
+func (i *IDMappings) UIDToContainer(uid int) (int, error) {
190
+	return toContainer(uid, i.uids)
191
+}
192
+
193
+// GIDToContainer returns the container GID for the host gid
194
+func (i *IDMappings) GIDToContainer(gid int) (int, error) {
195
+	return toContainer(gid, i.gids)
196
+}
197
+
198
+// Empty returns true if there are no id mappings
199
+func (i *IDMappings) Empty() bool {
200
+	return len(i.uids) == 0 && len(i.gids) == 0
201
+}
202
+
188 203
 // UIDs return the UID mapping
189 204
 // TODO: remove this once everything has been refactored to use pairs
190 205
 func (i *IDMappings) UIDs() []IDMap {