瀏覽代碼

Convert tarAppender to the newIDMappings.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Daniel Nephin 8 年之前
父節點
當前提交
5672eeb5e0
共有 3 個文件被更改,包括 44 次插入25 次删除
  1. 19 16
      pkg/archive/archive.go
  2. 2 7
      pkg/archive/changes.go
  3. 23 2
      pkg/idtools/idtools.go

+ 19 - 16
pkg/archive/archive.go

@@ -345,9 +345,8 @@ type tarAppender struct {
 	Buffer    *bufio.Writer
 
 	// for hardlink mapping
-	SeenFiles map[uint64]string
-	UIDMaps   []idtools.IDMap
-	GIDMaps   []idtools.IDMap
+	SeenFiles  map[uint64]string
+	IDMappings *idtools.IDMappings
 
 	// For packing and unpacking whiteout files in the
 	// non standard format. The whiteout files defined
@@ -356,6 +355,15 @@ type tarAppender struct {
 	WhiteoutConverter tarWhiteoutConverter
 }
 
+func newTarAppender(idMapping *idtools.IDMappings, writer io.Writer) *tarAppender {
+	return &tarAppender{
+		SeenFiles:  make(map[uint64]string),
+		TarWriter:  tar.NewWriter(writer),
+		Buffer:     pools.BufioWriter32KPool.Get(nil),
+		IDMappings: idMapping,
+	}
+}
+
 // canonicalTarName provides a platform-independent and consistent posix-style
 //path for files and directories to be archived regardless of the platform.
 func canonicalTarName(name string, isDir bool) (string, error) {
@@ -404,21 +412,19 @@ func (ta *tarAppender) addTarFile(path, name string) error {
 	//handle re-mapping container ID mappings back to host ID mappings before
 	//writing tar headers/files. We skip whiteout files because they were written
 	//by the kernel and already have proper ownership relative to the host
-	if !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && (ta.UIDMaps != nil || ta.GIDMaps != nil) {
+	if !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && !ta.IDMappings.Empty() {
 		uid, gid, err := getFileUIDGID(fi.Sys())
 		if err != nil {
 			return err
 		}
-		xUID, err := idtools.ToContainer(uid, ta.UIDMaps)
+		hdr.Uid, err = ta.IDMappings.UIDToContainer(uid)
 		if err != nil {
 			return err
 		}
-		xGID, err := idtools.ToContainer(gid, ta.GIDMaps)
+		hdr.Gid, err = ta.IDMappings.GIDToContainer(gid)
 		if err != nil {
 			return err
 		}
-		hdr.Uid = xUID
-		hdr.Gid = xGID
 	}
 
 	if ta.WhiteoutConverter != nil {
@@ -640,14 +646,11 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
 	}
 
 	go func() {
-		ta := &tarAppender{
-			TarWriter:         tar.NewWriter(compressWriter),
-			Buffer:            pools.BufioWriter32KPool.Get(nil),
-			SeenFiles:         make(map[uint64]string),
-			UIDMaps:           options.UIDMaps,
-			GIDMaps:           options.GIDMaps,
-			WhiteoutConverter: getWhiteoutConverter(options.WhiteoutFormat),
-		}
+		ta := newTarAppender(
+			idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps),
+			compressWriter,
+		)
+		ta.WhiteoutConverter = getWhiteoutConverter(options.WhiteoutFormat)
 
 		defer func() {
 			// Make sure to check the error on Close.

+ 2 - 7
pkg/archive/changes.go

@@ -394,13 +394,8 @@ func ChangesSize(newDir string, changes []Change) int64 {
 func ExportChanges(dir string, changes []Change, uidMaps, gidMaps []idtools.IDMap) (io.ReadCloser, error) {
 	reader, writer := io.Pipe()
 	go func() {
-		ta := &tarAppender{
-			TarWriter: tar.NewWriter(writer),
-			Buffer:    pools.BufioWriter32KPool.Get(nil),
-			SeenFiles: make(map[uint64]string),
-			UIDMaps:   uidMaps,
-			GIDMaps:   gidMaps,
-		}
+		ta := newTarAppender(idtools.NewIDMappingsFromMaps(uidMaps, gidMaps), writer)
+
 		// this buffer is needed for the duration of this piped stream
 		defer pools.BufioWriter32KPool.Put(ta.Buffer)
 

+ 23 - 2
pkg/idtools/idtools.go

@@ -99,10 +99,10 @@ func GetRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) {
 	return uid, gid, nil
 }
 
-// ToContainer takes an id mapping, and uses it to translate a
+// toContainer takes an id mapping, and uses it to translate a
 // host ID to the remapped ID. If no map is provided, then the translation
 // assumes a 1-to-1 mapping and returns the passed in id
-func ToContainer(hostID int, idMap []IDMap) (int, error) {
+func toContainer(hostID int, idMap []IDMap) (int, error) {
 	if idMap == nil {
 		return hostID, nil
 	}
@@ -169,6 +169,12 @@ func NewIDMappings(username, groupname string) (*IDMappings, error) {
 	}, nil
 }
 
+// NewIDMappingsFromMaps creates a new mapping from two slices
+// Deprecated: this is a temporary shim while transitioning to IDMapping
+func NewIDMappingsFromMaps(uids []IDMap, gids []IDMap) *IDMappings {
+	return &IDMappings{uids: uids, gids: gids}
+}
+
 // RootPair returns a uid and gid pair for the root user
 func (i *IDMappings) RootPair() (IDPair, error) {
 	uid, gid, err := GetRootUIDGID(i.uids, i.gids)
@@ -185,6 +191,21 @@ func (i *IDMappings) GIDToHost(gid int) (int, error) {
 	return ToHost(gid, i.gids)
 }
 
+// UIDToContainer returns the container UID for the host uid
+func (i *IDMappings) UIDToContainer(uid int) (int, error) {
+	return toContainer(uid, i.uids)
+}
+
+// GIDToContainer returns the container GID for the host gid
+func (i *IDMappings) GIDToContainer(gid int) (int, error) {
+	return toContainer(gid, i.gids)
+}
+
+// Empty returns true if there are no id mappings
+func (i *IDMappings) Empty() bool {
+	return len(i.uids) == 0 && len(i.gids) == 0
+}
+
 // UIDs return the UID mapping
 // TODO: remove this once everything has been refactored to use pairs
 func (i *IDMappings) UIDs() []IDMap {