Convert tarAppender to the newIDMappings.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2017-05-24 14:10:15 -04:00
parent 967ef7e6d2
commit 5672eeb5e0
3 changed files with 44 additions and 25 deletions

View file

@ -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.

View file

@ -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)

View file

@ -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 {