Migrate Sirupsen to sirupsen.
This commit is contained in:
parent
c134dcd6fe
commit
fb4ba7af2b
684 changed files with 92394 additions and 33943 deletions
350
vendor/github.com/docker/docker/pkg/archive/archive.go
generated
vendored
350
vendor/github.com/docker/docker/pkg/archive/archive.go
generated
vendored
|
@ -6,7 +6,6 @@ import (
|
|||
"bytes"
|
||||
"compress/bzip2"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -17,13 +16,12 @@ import (
|
|||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/pkg/fileutils"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/pools"
|
||||
"github.com/docker/docker/pkg/promise"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -31,10 +29,6 @@ type (
|
|||
Compression int
|
||||
// WhiteoutFormat is the format of whiteouts unpacked
|
||||
WhiteoutFormat int
|
||||
// TarChownOptions wraps the chown options UID and GID.
|
||||
TarChownOptions struct {
|
||||
UID, GID int
|
||||
}
|
||||
|
||||
// TarOptions wraps the tar options.
|
||||
TarOptions struct {
|
||||
|
@ -44,7 +38,7 @@ type (
|
|||
NoLchown bool
|
||||
UIDMaps []idtools.IDMap
|
||||
GIDMaps []idtools.IDMap
|
||||
ChownOpts *TarChownOptions
|
||||
ChownOpts *idtools.IDPair
|
||||
IncludeSourceDir bool
|
||||
// WhiteoutFormat is the expected on disk format for whiteout files.
|
||||
// This format will be converted to the standard format on pack
|
||||
|
@ -58,33 +52,25 @@ type (
|
|||
RebaseNames map[string]string
|
||||
InUserNS bool
|
||||
}
|
||||
|
||||
// Archiver allows the reuse of most utility functions of this package
|
||||
// with a pluggable Untar function. Also, to facilitate the passing of
|
||||
// specific id mappings for untar, an archiver can be created with maps
|
||||
// which will then be passed to Untar operations
|
||||
Archiver struct {
|
||||
Untar func(io.Reader, string, *TarOptions) error
|
||||
UIDMaps []idtools.IDMap
|
||||
GIDMaps []idtools.IDMap
|
||||
}
|
||||
|
||||
// breakoutError is used to differentiate errors related to breaking out
|
||||
// When testing archive breakout in the unit tests, this error is expected
|
||||
// in order for the test to pass.
|
||||
breakoutError error
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNotImplemented is the error message of function not implemented.
|
||||
ErrNotImplemented = errors.New("Function not implemented")
|
||||
defaultArchiver = &Archiver{Untar: Untar, UIDMaps: nil, GIDMaps: nil}
|
||||
)
|
||||
// Archiver implements the Archiver interface and allows the reuse of most utility functions of
|
||||
// this package with a pluggable Untar function. Also, to facilitate the passing of specific id
|
||||
// mappings for untar, an Archiver can be created with maps which will then be passed to Untar operations.
|
||||
type Archiver struct {
|
||||
Untar func(io.Reader, string, *TarOptions) error
|
||||
IDMappingsVar *idtools.IDMappings
|
||||
}
|
||||
|
||||
const (
|
||||
// HeaderSize is the size in bytes of a tar header
|
||||
HeaderSize = 512
|
||||
)
|
||||
// NewDefaultArchiver returns a new Archiver without any IDMappings
|
||||
func NewDefaultArchiver() *Archiver {
|
||||
return &Archiver{Untar: Untar, IDMappingsVar: &idtools.IDMappings{}}
|
||||
}
|
||||
|
||||
// breakoutError is used to differentiate errors related to breaking out
|
||||
// When testing archive breakout in the unit tests, this error is expected
|
||||
// in order for the test to pass.
|
||||
type breakoutError error
|
||||
|
||||
const (
|
||||
// Uncompressed represents the uncompressed.
|
||||
|
@ -105,17 +91,15 @@ const (
|
|||
OverlayWhiteoutFormat
|
||||
)
|
||||
|
||||
// IsArchive checks for the magic bytes of a tar or any supported compression
|
||||
// algorithm.
|
||||
func IsArchive(header []byte) bool {
|
||||
compression := DetectCompression(header)
|
||||
if compression != Uncompressed {
|
||||
return true
|
||||
}
|
||||
r := tar.NewReader(bytes.NewBuffer(header))
|
||||
_, err := r.Next()
|
||||
return err == nil
|
||||
}
|
||||
const (
|
||||
modeISDIR = 040000 // Directory
|
||||
modeISFIFO = 010000 // FIFO
|
||||
modeISREG = 0100000 // Regular file
|
||||
modeISLNK = 0120000 // Symbolic link
|
||||
modeISBLK = 060000 // Block special file
|
||||
modeISCHR = 020000 // Character special file
|
||||
modeISSOCK = 0140000 // Socket
|
||||
)
|
||||
|
||||
// IsArchivePath checks if the (possibly compressed) file at the given path
|
||||
// starts with a tar file header.
|
||||
|
@ -204,7 +188,7 @@ func DecompressStream(archive io.Reader) (io.ReadCloser, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// CompressStream compresseses the dest with specified compression algorithm.
|
||||
// CompressStream compresses the dest with specified compression algorithm.
|
||||
func CompressStream(dest io.Writer, compression Compression) (io.WriteCloser, error) {
|
||||
p := pools.BufioWriter32KPool
|
||||
buf := p.Get(dest)
|
||||
|
@ -329,20 +313,14 @@ func (compression *Compression) Extension() string {
|
|||
|
||||
// FileInfoHeader creates a populated Header from fi.
|
||||
// Compared to archive pkg this function fills in more information.
|
||||
func FileInfoHeader(path, name string, fi os.FileInfo) (*tar.Header, error) {
|
||||
var link string
|
||||
if fi.Mode()&os.ModeSymlink != 0 {
|
||||
var err error
|
||||
link, err = os.Readlink(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// Also, regardless of Go version, this function fills file type bits (e.g. hdr.Mode |= modeISDIR),
|
||||
// which have been deleted since Go 1.9 archive/tar.
|
||||
func FileInfoHeader(name string, fi os.FileInfo, link string) (*tar.Header, error) {
|
||||
hdr, err := tar.FileInfoHeader(fi, link)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
|
||||
hdr.Mode = fillGo18FileTypeBits(int64(chmodTarEntry(os.FileMode(hdr.Mode))), fi)
|
||||
name, err = canonicalTarName(name, fi.IsDir())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tar: cannot canonicalize path: %v", err)
|
||||
|
@ -351,12 +329,43 @@ func FileInfoHeader(path, name string, fi os.FileInfo) (*tar.Header, error) {
|
|||
if err := setHeaderForSpecialDevice(hdr, name, fi.Sys()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hdr, nil
|
||||
}
|
||||
|
||||
// fillGo18FileTypeBits fills type bits which have been removed on Go 1.9 archive/tar
|
||||
// https://github.com/golang/go/commit/66b5a2f
|
||||
func fillGo18FileTypeBits(mode int64, fi os.FileInfo) int64 {
|
||||
fm := fi.Mode()
|
||||
switch {
|
||||
case fm.IsRegular():
|
||||
mode |= modeISREG
|
||||
case fi.IsDir():
|
||||
mode |= modeISDIR
|
||||
case fm&os.ModeSymlink != 0:
|
||||
mode |= modeISLNK
|
||||
case fm&os.ModeDevice != 0:
|
||||
if fm&os.ModeCharDevice != 0 {
|
||||
mode |= modeISCHR
|
||||
} else {
|
||||
mode |= modeISBLK
|
||||
}
|
||||
case fm&os.ModeNamedPipe != 0:
|
||||
mode |= modeISFIFO
|
||||
case fm&os.ModeSocket != 0:
|
||||
mode |= modeISSOCK
|
||||
}
|
||||
return mode
|
||||
}
|
||||
|
||||
// ReadSecurityXattrToTarHeader reads security.capability xattr from filesystem
|
||||
// to a tar header
|
||||
func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {
|
||||
capability, _ := system.Lgetxattr(path, "security.capability")
|
||||
if capability != nil {
|
||||
hdr.Xattrs = make(map[string]string)
|
||||
hdr.Xattrs["security.capability"] = string(capability)
|
||||
}
|
||||
return hdr, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
type tarWhiteoutConverter interface {
|
||||
|
@ -369,9 +378,9 @@ 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
|
||||
ChownOpts *idtools.IDPair
|
||||
|
||||
// For packing and unpacking whiteout files in the
|
||||
// non standard format. The whiteout files defined
|
||||
|
@ -380,6 +389,16 @@ type tarAppender struct {
|
|||
WhiteoutConverter tarWhiteoutConverter
|
||||
}
|
||||
|
||||
func newTarAppender(idMapping *idtools.IDMappings, writer io.Writer, chownOpts *idtools.IDPair) *tarAppender {
|
||||
return &tarAppender{
|
||||
SeenFiles: make(map[uint64]string),
|
||||
TarWriter: tar.NewWriter(writer),
|
||||
Buffer: pools.BufioWriter32KPool.Get(nil),
|
||||
IDMappings: idMapping,
|
||||
ChownOpts: chownOpts,
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
@ -402,10 +421,22 @@ func (ta *tarAppender) addTarFile(path, name string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hdr, err := FileInfoHeader(path, name, fi)
|
||||
var link string
|
||||
if fi.Mode()&os.ModeSymlink != 0 {
|
||||
var err error
|
||||
link, err = os.Readlink(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
hdr, err := FileInfoHeader(name, fi, link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ReadSecurityXattrToTarHeader(path, hdr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if it's not a directory and has more than 1 link,
|
||||
// it's hard linked, so set the type flag accordingly
|
||||
|
@ -428,21 +459,21 @@ 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) {
|
||||
uid, gid, err := getFileUIDGID(fi.Sys())
|
||||
if !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && !ta.IDMappings.Empty() {
|
||||
fileIDPair, err := getFileUIDGID(fi.Sys())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
xUID, err := idtools.ToContainer(uid, ta.UIDMaps)
|
||||
hdr.Uid, hdr.Gid, err = ta.IDMappings.ToContainer(fileIDPair)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
xGID, err := idtools.ToContainer(gid, ta.GIDMaps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hdr.Uid = xUID
|
||||
hdr.Gid = xGID
|
||||
}
|
||||
|
||||
// explicitly override with ChownOpts
|
||||
if ta.ChownOpts != nil {
|
||||
hdr.Uid = ta.ChownOpts.UID
|
||||
hdr.Gid = ta.ChownOpts.GID
|
||||
}
|
||||
|
||||
if ta.WhiteoutConverter != nil {
|
||||
|
@ -496,7 +527,7 @@ func (ta *tarAppender) addTarFile(path, name string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool, chownOpts *TarChownOptions, inUserns bool) error {
|
||||
func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool, chownOpts *idtools.IDPair, inUserns bool) error {
|
||||
// hdr.Mode is in linux format, which we can use for sycalls,
|
||||
// but for os.Foo() calls we need the mode converted to os.FileMode,
|
||||
// so use hdrInfo.Mode() (they differ for e.g. setuid bits)
|
||||
|
@ -570,13 +601,13 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
|
|||
return nil
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Unhandled tar header type %d\n", hdr.Typeflag)
|
||||
return fmt.Errorf("unhandled tar header type %d", hdr.Typeflag)
|
||||
}
|
||||
|
||||
// Lchown is not supported on Windows.
|
||||
if Lchown && runtime.GOOS != "windows" {
|
||||
if chownOpts == nil {
|
||||
chownOpts = &TarChownOptions{UID: hdr.Uid, GID: hdr.Gid}
|
||||
chownOpts = &idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid}
|
||||
}
|
||||
if err := os.Lchown(path, chownOpts.UID, chownOpts.GID); err != nil {
|
||||
return err
|
||||
|
@ -664,14 +695,12 @@ 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,
|
||||
options.ChownOpts,
|
||||
)
|
||||
ta.WhiteoutConverter = getWhiteoutConverter(options.WhiteoutFormat)
|
||||
|
||||
defer func() {
|
||||
// Make sure to check the error on Close.
|
||||
|
@ -827,10 +856,8 @@ func Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) err
|
|||
defer pools.BufioReader32KPool.Put(trBuf)
|
||||
|
||||
var dirs []*tar.Header
|
||||
remappedRootUID, remappedRootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
idMappings := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
|
||||
rootIDs := idMappings.RootPair()
|
||||
whiteoutConverter := getWhiteoutConverter(options.WhiteoutFormat)
|
||||
|
||||
// Iterate through the files in the archive.
|
||||
|
@ -864,7 +891,7 @@ loop:
|
|||
parent := filepath.Dir(hdr.Name)
|
||||
parentPath := filepath.Join(dest, parent)
|
||||
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
|
||||
err = idtools.MkdirAllNewAs(parentPath, 0777, remappedRootUID, remappedRootGID)
|
||||
err = idtools.MkdirAllAndChownNew(parentPath, 0777, rootIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -909,26 +936,8 @@ loop:
|
|||
}
|
||||
trBuf.Reset(tr)
|
||||
|
||||
// if the options contain a uid & gid maps, convert header uid/gid
|
||||
// entries using the maps such that lchown sets the proper mapped
|
||||
// uid/gid after writing the file. We only perform this mapping if
|
||||
// the file isn't already owned by the remapped root UID or GID, as
|
||||
// that specific uid/gid has no mapping from container -> host, and
|
||||
// those files already have the proper ownership for inside the
|
||||
// container.
|
||||
if hdr.Uid != remappedRootUID {
|
||||
xUID, err := idtools.ToHost(hdr.Uid, options.UIDMaps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hdr.Uid = xUID
|
||||
}
|
||||
if hdr.Gid != remappedRootGID {
|
||||
xGID, err := idtools.ToHost(hdr.Gid, options.GIDMaps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hdr.Gid = xGID
|
||||
if err := remapIDs(idMappings, hdr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if whiteoutConverter != nil {
|
||||
|
@ -1013,23 +1022,13 @@ func (archiver *Archiver) TarUntar(src, dst string) error {
|
|||
return err
|
||||
}
|
||||
defer archive.Close()
|
||||
|
||||
var options *TarOptions
|
||||
if archiver.UIDMaps != nil || archiver.GIDMaps != nil {
|
||||
options = &TarOptions{
|
||||
UIDMaps: archiver.UIDMaps,
|
||||
GIDMaps: archiver.GIDMaps,
|
||||
}
|
||||
options := &TarOptions{
|
||||
UIDMaps: archiver.IDMappingsVar.UIDs(),
|
||||
GIDMaps: archiver.IDMappingsVar.GIDs(),
|
||||
}
|
||||
return archiver.Untar(archive, dst, options)
|
||||
}
|
||||
|
||||
// TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other.
|
||||
// If either Tar or Untar fails, TarUntar aborts and returns the error.
|
||||
func TarUntar(src, dst string) error {
|
||||
return defaultArchiver.TarUntar(src, dst)
|
||||
}
|
||||
|
||||
// UntarPath untar a file from path to a destination, src is the source tar file path.
|
||||
func (archiver *Archiver) UntarPath(src, dst string) error {
|
||||
archive, err := os.Open(src)
|
||||
|
@ -1037,22 +1036,13 @@ func (archiver *Archiver) UntarPath(src, dst string) error {
|
|||
return err
|
||||
}
|
||||
defer archive.Close()
|
||||
var options *TarOptions
|
||||
if archiver.UIDMaps != nil || archiver.GIDMaps != nil {
|
||||
options = &TarOptions{
|
||||
UIDMaps: archiver.UIDMaps,
|
||||
GIDMaps: archiver.GIDMaps,
|
||||
}
|
||||
options := &TarOptions{
|
||||
UIDMaps: archiver.IDMappingsVar.UIDs(),
|
||||
GIDMaps: archiver.IDMappingsVar.GIDs(),
|
||||
}
|
||||
return archiver.Untar(archive, dst, options)
|
||||
}
|
||||
|
||||
// UntarPath is a convenience function which looks for an archive
|
||||
// at filesystem path `src`, and unpacks it at `dst`.
|
||||
func UntarPath(src, dst string) error {
|
||||
return defaultArchiver.UntarPath(src, dst)
|
||||
}
|
||||
|
||||
// CopyWithTar creates a tar archive of filesystem path `src`, and
|
||||
// unpacks it at filesystem path `dst`.
|
||||
// The archive is streamed directly with fixed buffering and no
|
||||
|
@ -1066,30 +1056,19 @@ func (archiver *Archiver) CopyWithTar(src, dst string) error {
|
|||
return archiver.CopyFileWithTar(src, dst)
|
||||
}
|
||||
|
||||
// if this archiver is set up with ID mapping we need to create
|
||||
// if this Archiver is set up with ID mapping we need to create
|
||||
// the new destination directory with the remapped root UID/GID pair
|
||||
// as owner
|
||||
rootUID, rootGID, err := idtools.GetRootUIDGID(archiver.UIDMaps, archiver.GIDMaps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rootIDs := archiver.IDMappingsVar.RootPair()
|
||||
// Create dst, copy src's content into it
|
||||
logrus.Debugf("Creating dest directory: %s", dst)
|
||||
if err := idtools.MkdirAllNewAs(dst, 0755, rootUID, rootGID); err != nil {
|
||||
if err := idtools.MkdirAllAndChownNew(dst, 0755, rootIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
logrus.Debugf("Calling TarUntar(%s, %s)", src, dst)
|
||||
return archiver.TarUntar(src, dst)
|
||||
}
|
||||
|
||||
// CopyWithTar creates a tar archive of filesystem path `src`, and
|
||||
// unpacks it at filesystem path `dst`.
|
||||
// The archive is streamed directly with fixed buffering and no
|
||||
// intermediary disk IO.
|
||||
func CopyWithTar(src, dst string) error {
|
||||
return defaultArchiver.CopyWithTar(src, dst)
|
||||
}
|
||||
|
||||
// CopyFileWithTar emulates the behavior of the 'cp' command-line
|
||||
// for a single file. It copies a regular file from path `src` to
|
||||
// path `dst`, and preserves all its metadata.
|
||||
|
@ -1110,59 +1089,47 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
|
|||
dst = filepath.Join(dst, filepath.Base(src))
|
||||
}
|
||||
// Create the holding directory if necessary
|
||||
if err := system.MkdirAll(filepath.Dir(dst), 0700); err != nil {
|
||||
if err := system.MkdirAll(filepath.Dir(dst), 0700, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, w := io.Pipe()
|
||||
errC := promise.Go(func() error {
|
||||
defer w.Close()
|
||||
errC := make(chan error, 1)
|
||||
|
||||
srcF, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer srcF.Close()
|
||||
go func() {
|
||||
defer close(errC)
|
||||
|
||||
hdr, err := tar.FileInfoHeader(srcSt, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hdr.Name = filepath.Base(dst)
|
||||
hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
|
||||
errC <- func() error {
|
||||
defer w.Close()
|
||||
|
||||
remappedRootUID, remappedRootGID, err := idtools.GetRootUIDGID(archiver.UIDMaps, archiver.GIDMaps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// only perform mapping if the file being copied isn't already owned by the
|
||||
// uid or gid of the remapped root in the container
|
||||
if remappedRootUID != hdr.Uid {
|
||||
xUID, err := idtools.ToHost(hdr.Uid, archiver.UIDMaps)
|
||||
srcF, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hdr.Uid = xUID
|
||||
}
|
||||
if remappedRootGID != hdr.Gid {
|
||||
xGID, err := idtools.ToHost(hdr.Gid, archiver.GIDMaps)
|
||||
defer srcF.Close()
|
||||
|
||||
hdr, err := tar.FileInfoHeader(srcSt, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hdr.Gid = xGID
|
||||
}
|
||||
hdr.Name = filepath.Base(dst)
|
||||
hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
|
||||
|
||||
tw := tar.NewWriter(w)
|
||||
defer tw.Close()
|
||||
if err := tw.WriteHeader(hdr); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(tw, srcF); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err := remapIDs(archiver.IDMappingsVar, hdr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tw := tar.NewWriter(w)
|
||||
defer tw.Close()
|
||||
if err := tw.WriteHeader(hdr); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(tw, srcF); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
}()
|
||||
defer func() {
|
||||
if er := <-errC; err == nil && er != nil {
|
||||
err = er
|
||||
|
@ -1176,16 +1143,15 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
// CopyFileWithTar emulates the behavior of the 'cp' command-line
|
||||
// for a single file. It copies a regular file from path `src` to
|
||||
// path `dst`, and preserves all its metadata.
|
||||
//
|
||||
// Destination handling is in an operating specific manner depending
|
||||
// where the daemon is running. If `dst` ends with a trailing slash
|
||||
// the final destination path will be `dst/base(src)` (Linux) or
|
||||
// `dst\base(src)` (Windows).
|
||||
func CopyFileWithTar(src, dst string) (err error) {
|
||||
return defaultArchiver.CopyFileWithTar(src, dst)
|
||||
// IDMappings returns the IDMappings of the archiver.
|
||||
func (archiver *Archiver) IDMappings() *idtools.IDMappings {
|
||||
return archiver.IDMappingsVar
|
||||
}
|
||||
|
||||
func remapIDs(idMappings *idtools.IDMappings, hdr *tar.Header) error {
|
||||
ids, err := idMappings.ToHost(idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid})
|
||||
hdr.Uid, hdr.Gid = ids.UID, ids.GID
|
||||
return err
|
||||
}
|
||||
|
||||
// cmdStream executes a command, and returns its stdout as a stream.
|
||||
|
|
6
vendor/github.com/docker/docker/pkg/archive/archive_linux.go
generated
vendored
6
vendor/github.com/docker/docker/pkg/archive/archive_linux.go
generated
vendored
|
@ -5,9 +5,9 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func getWhiteoutConverter(format WhiteoutFormat) tarWhiteoutConverter {
|
||||
|
@ -67,7 +67,7 @@ func (overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool,
|
|||
|
||||
// if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay
|
||||
if base == WhiteoutOpaqueDir {
|
||||
err := syscall.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0)
|
||||
err := unix.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0)
|
||||
// don't write the file itself
|
||||
return false, err
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ func (overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool,
|
|||
originalBase := base[len(WhiteoutPrefix):]
|
||||
originalPath := filepath.Join(dir, originalBase)
|
||||
|
||||
if err := syscall.Mknod(originalPath, syscall.S_IFCHR, 0); err != nil {
|
||||
if err := unix.Mknod(originalPath, unix.S_IFCHR, 0); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := os.Chown(originalPath, hdr.Uid, hdr.Gid); err != nil {
|
||||
|
|
46
vendor/github.com/docker/docker/pkg/archive/archive_unix.go
generated
vendored
46
vendor/github.com/docker/docker/pkg/archive/archive_unix.go
generated
vendored
|
@ -9,8 +9,10 @@ import (
|
|||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
rsystem "github.com/opencontainers/runc/libcontainer/system"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// fixVolumePathPrefix does platform specific processing to ensure that if
|
||||
|
@ -44,16 +46,13 @@ func chmodTarEntry(perm os.FileMode) os.FileMode {
|
|||
func setHeaderForSpecialDevice(hdr *tar.Header, name string, stat interface{}) (err error) {
|
||||
s, ok := stat.(*syscall.Stat_t)
|
||||
|
||||
if !ok {
|
||||
err = errors.New("cannot convert stat value to syscall.Stat_t")
|
||||
return
|
||||
}
|
||||
|
||||
// Currently go does not fill in the major/minors
|
||||
if s.Mode&syscall.S_IFBLK != 0 ||
|
||||
s.Mode&syscall.S_IFCHR != 0 {
|
||||
hdr.Devmajor = int64(major(uint64(s.Rdev)))
|
||||
hdr.Devminor = int64(minor(uint64(s.Rdev)))
|
||||
if ok {
|
||||
// Currently go does not fill in the major/minors
|
||||
if s.Mode&unix.S_IFBLK != 0 ||
|
||||
s.Mode&unix.S_IFCHR != 0 {
|
||||
hdr.Devmajor = int64(unix.Major(uint64(s.Rdev))) // nolint: unconvert
|
||||
hdr.Devminor = int64(unix.Minor(uint64(s.Rdev))) // nolint: unconvert
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -62,31 +61,20 @@ func setHeaderForSpecialDevice(hdr *tar.Header, name string, stat interface{}) (
|
|||
func getInodeFromStat(stat interface{}) (inode uint64, err error) {
|
||||
s, ok := stat.(*syscall.Stat_t)
|
||||
|
||||
if !ok {
|
||||
err = errors.New("cannot convert stat value to syscall.Stat_t")
|
||||
return
|
||||
if ok {
|
||||
inode = s.Ino
|
||||
}
|
||||
|
||||
inode = uint64(s.Ino)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getFileUIDGID(stat interface{}) (int, int, error) {
|
||||
func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
|
||||
s, ok := stat.(*syscall.Stat_t)
|
||||
|
||||
if !ok {
|
||||
return -1, -1, errors.New("cannot convert stat value to syscall.Stat_t")
|
||||
return idtools.IDPair{}, errors.New("cannot convert stat value to syscall.Stat_t")
|
||||
}
|
||||
return int(s.Uid), int(s.Gid), nil
|
||||
}
|
||||
|
||||
func major(device uint64) uint64 {
|
||||
return (device >> 8) & 0xfff
|
||||
}
|
||||
|
||||
func minor(device uint64) uint64 {
|
||||
return (device & 0xff) | ((device >> 12) & 0xfff00)
|
||||
return idtools.IDPair{UID: int(s.Uid), GID: int(s.Gid)}, nil
|
||||
}
|
||||
|
||||
// handleTarTypeBlockCharFifo is an OS-specific helper function used by
|
||||
|
@ -100,11 +88,11 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
|
|||
mode := uint32(hdr.Mode & 07777)
|
||||
switch hdr.Typeflag {
|
||||
case tar.TypeBlock:
|
||||
mode |= syscall.S_IFBLK
|
||||
mode |= unix.S_IFBLK
|
||||
case tar.TypeChar:
|
||||
mode |= syscall.S_IFCHR
|
||||
mode |= unix.S_IFCHR
|
||||
case tar.TypeFifo:
|
||||
mode |= syscall.S_IFIFO
|
||||
mode |= unix.S_IFIFO
|
||||
}
|
||||
|
||||
return system.Mknod(path, mode, int(system.Mkdev(hdr.Devmajor, hdr.Devminor)))
|
||||
|
|
5
vendor/github.com/docker/docker/pkg/archive/archive_windows.go
generated
vendored
5
vendor/github.com/docker/docker/pkg/archive/archive_windows.go
generated
vendored
|
@ -9,6 +9,7 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/longpath"
|
||||
)
|
||||
|
||||
|
@ -72,7 +73,7 @@ func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getFileUIDGID(stat interface{}) (int, int, error) {
|
||||
func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
|
||||
// no notion of file ownership mapping yet on Windows
|
||||
return 0, 0, nil
|
||||
return idtools.IDPair{0, 0}, nil
|
||||
}
|
||||
|
|
11
vendor/github.com/docker/docker/pkg/archive/changes.go
generated
vendored
11
vendor/github.com/docker/docker/pkg/archive/changes.go
generated
vendored
|
@ -13,10 +13,10 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/pools"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ChangeType represents the change type.
|
||||
|
@ -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, nil)
|
||||
|
||||
// this buffer is needed for the duration of this piped stream
|
||||
defer pools.BufioWriter32KPool.Put(ta.Buffer)
|
||||
|
||||
|
|
9
vendor/github.com/docker/docker/pkg/archive/changes_linux.go
generated
vendored
9
vendor/github.com/docker/docker/pkg/archive/changes_linux.go
generated
vendored
|
@ -10,6 +10,7 @@ import (
|
|||
"unsafe"
|
||||
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// walker is used to implement collectFileInfoForChanges on linux. Where this
|
||||
|
@ -233,7 +234,7 @@ func readdirnames(dirname string) (names []nameIno, err error) {
|
|||
// Refill the buffer if necessary
|
||||
if bufp >= nbuf {
|
||||
bufp = 0
|
||||
nbuf, err = syscall.ReadDirent(int(f.Fd()), buf) // getdents on linux
|
||||
nbuf, err = unix.ReadDirent(int(f.Fd()), buf) // getdents on linux
|
||||
if nbuf < 0 {
|
||||
nbuf = 0
|
||||
}
|
||||
|
@ -255,12 +256,12 @@ func readdirnames(dirname string) (names []nameIno, err error) {
|
|||
return sl, nil
|
||||
}
|
||||
|
||||
// parseDirent is a minor modification of syscall.ParseDirent (linux version)
|
||||
// parseDirent is a minor modification of unix.ParseDirent (linux version)
|
||||
// which returns {name,inode} pairs instead of just names.
|
||||
func parseDirent(buf []byte, names []nameIno) (consumed int, newnames []nameIno) {
|
||||
origlen := len(buf)
|
||||
for len(buf) > 0 {
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&buf[0]))
|
||||
dirent := (*unix.Dirent)(unsafe.Pointer(&buf[0]))
|
||||
buf = buf[dirent.Reclen:]
|
||||
if dirent.Ino == 0 { // File absent in directory.
|
||||
continue
|
||||
|
@ -293,7 +294,7 @@ func OverlayChanges(layers []string, rw string) ([]Change, error) {
|
|||
func overlayDeletedFile(root, path string, fi os.FileInfo) (string, error) {
|
||||
if fi.Mode()&os.ModeCharDevice != 0 {
|
||||
s := fi.Sys().(*syscall.Stat_t)
|
||||
if major(uint64(s.Rdev)) == 0 && minor(uint64(s.Rdev)) == 0 {
|
||||
if unix.Major(uint64(s.Rdev)) == 0 && unix.Minor(uint64(s.Rdev)) == 0 { // nolint: unconvert
|
||||
return path, nil
|
||||
}
|
||||
}
|
||||
|
|
7
vendor/github.com/docker/docker/pkg/archive/changes_unix.go
generated
vendored
7
vendor/github.com/docker/docker/pkg/archive/changes_unix.go
generated
vendored
|
@ -7,6 +7,7 @@ import (
|
|||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func statDifferent(oldStat *system.StatT, newStat *system.StatT) bool {
|
||||
|
@ -16,7 +17,7 @@ func statDifferent(oldStat *system.StatT, newStat *system.StatT) bool {
|
|||
oldStat.GID() != newStat.GID() ||
|
||||
oldStat.Rdev() != newStat.Rdev() ||
|
||||
// Don't look at size for dirs, its not a good measure of change
|
||||
(oldStat.Mode()&syscall.S_IFDIR != syscall.S_IFDIR &&
|
||||
(oldStat.Mode()&unix.S_IFDIR != unix.S_IFDIR &&
|
||||
(!sameFsTimeSpec(oldStat.Mtim(), newStat.Mtim()) || (oldStat.Size() != newStat.Size()))) {
|
||||
return true
|
||||
}
|
||||
|
@ -24,11 +25,11 @@ func statDifferent(oldStat *system.StatT, newStat *system.StatT) bool {
|
|||
}
|
||||
|
||||
func (info *FileInfo) isDir() bool {
|
||||
return info.parent == nil || info.stat.Mode()&syscall.S_IFDIR != 0
|
||||
return info.parent == nil || info.stat.Mode()&unix.S_IFDIR != 0
|
||||
}
|
||||
|
||||
func getIno(fi os.FileInfo) uint64 {
|
||||
return uint64(fi.Sys().(*syscall.Stat_t).Ino)
|
||||
return fi.Sys().(*syscall.Stat_t).Ino
|
||||
}
|
||||
|
||||
func hasHardlinks(fi os.FileInfo) bool {
|
||||
|
|
66
vendor/github.com/docker/docker/pkg/archive/copy.go
generated
vendored
66
vendor/github.com/docker/docker/pkg/archive/copy.go
generated
vendored
|
@ -9,8 +9,8 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Errors used or returned by this file.
|
||||
|
@ -27,23 +27,23 @@ var (
|
|||
// path (from before being processed by utility functions from the path or
|
||||
// filepath stdlib packages) ends with a trailing `/.` or `/`. If the cleaned
|
||||
// path already ends in a `.` path segment, then another is not added. If the
|
||||
// clean path already ends in a path separator, then another is not added.
|
||||
func PreserveTrailingDotOrSeparator(cleanedPath, originalPath string) string {
|
||||
// clean path already ends in the separator, then another is not added.
|
||||
func PreserveTrailingDotOrSeparator(cleanedPath string, originalPath string, sep byte) string {
|
||||
// Ensure paths are in platform semantics
|
||||
cleanedPath = normalizePath(cleanedPath)
|
||||
originalPath = normalizePath(originalPath)
|
||||
cleanedPath = strings.Replace(cleanedPath, "/", string(sep), -1)
|
||||
originalPath = strings.Replace(originalPath, "/", string(sep), -1)
|
||||
|
||||
if !specifiesCurrentDir(cleanedPath) && specifiesCurrentDir(originalPath) {
|
||||
if !hasTrailingPathSeparator(cleanedPath) {
|
||||
if !hasTrailingPathSeparator(cleanedPath, sep) {
|
||||
// Add a separator if it doesn't already end with one (a cleaned
|
||||
// path would only end in a separator if it is the root).
|
||||
cleanedPath += string(filepath.Separator)
|
||||
cleanedPath += string(sep)
|
||||
}
|
||||
cleanedPath += "."
|
||||
}
|
||||
|
||||
if !hasTrailingPathSeparator(cleanedPath) && hasTrailingPathSeparator(originalPath) {
|
||||
cleanedPath += string(filepath.Separator)
|
||||
if !hasTrailingPathSeparator(cleanedPath, sep) && hasTrailingPathSeparator(originalPath, sep) {
|
||||
cleanedPath += string(sep)
|
||||
}
|
||||
|
||||
return cleanedPath
|
||||
|
@ -52,14 +52,14 @@ func PreserveTrailingDotOrSeparator(cleanedPath, originalPath string) string {
|
|||
// assertsDirectory returns whether the given path is
|
||||
// asserted to be a directory, i.e., the path ends with
|
||||
// a trailing '/' or `/.`, assuming a path separator of `/`.
|
||||
func assertsDirectory(path string) bool {
|
||||
return hasTrailingPathSeparator(path) || specifiesCurrentDir(path)
|
||||
func assertsDirectory(path string, sep byte) bool {
|
||||
return hasTrailingPathSeparator(path, sep) || specifiesCurrentDir(path)
|
||||
}
|
||||
|
||||
// hasTrailingPathSeparator returns whether the given
|
||||
// path ends with the system's path separator character.
|
||||
func hasTrailingPathSeparator(path string) bool {
|
||||
return len(path) > 0 && os.IsPathSeparator(path[len(path)-1])
|
||||
func hasTrailingPathSeparator(path string, sep byte) bool {
|
||||
return len(path) > 0 && path[len(path)-1] == sep
|
||||
}
|
||||
|
||||
// specifiesCurrentDir returns whether the given path specifies
|
||||
|
@ -72,10 +72,10 @@ func specifiesCurrentDir(path string) bool {
|
|||
// basename by first cleaning the path but preserves a trailing "." if the
|
||||
// original path specified the current directory.
|
||||
func SplitPathDirEntry(path string) (dir, base string) {
|
||||
cleanedPath := filepath.Clean(normalizePath(path))
|
||||
cleanedPath := filepath.Clean(filepath.FromSlash(path))
|
||||
|
||||
if specifiesCurrentDir(path) {
|
||||
cleanedPath += string(filepath.Separator) + "."
|
||||
cleanedPath += string(os.PathSeparator) + "."
|
||||
}
|
||||
|
||||
return filepath.Dir(cleanedPath), filepath.Base(cleanedPath)
|
||||
|
@ -106,19 +106,24 @@ func TarResourceRebase(sourcePath, rebaseName string) (content io.ReadCloser, er
|
|||
// Separate the source path between its directory and
|
||||
// the entry in that directory which we are archiving.
|
||||
sourceDir, sourceBase := SplitPathDirEntry(sourcePath)
|
||||
|
||||
filter := []string{sourceBase}
|
||||
opts := TarResourceRebaseOpts(sourceBase, rebaseName)
|
||||
|
||||
logrus.Debugf("copying %q from %q", sourceBase, sourceDir)
|
||||
return TarWithOptions(sourceDir, opts)
|
||||
}
|
||||
|
||||
return TarWithOptions(sourceDir, &TarOptions{
|
||||
// TarResourceRebaseOpts does not preform the Tar, but instead just creates the rebase
|
||||
// parameters to be sent to TarWithOptions (the TarOptions struct)
|
||||
func TarResourceRebaseOpts(sourceBase string, rebaseName string) *TarOptions {
|
||||
filter := []string{sourceBase}
|
||||
return &TarOptions{
|
||||
Compression: Uncompressed,
|
||||
IncludeFiles: filter,
|
||||
IncludeSourceDir: true,
|
||||
RebaseNames: map[string]string{
|
||||
sourceBase: rebaseName,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// CopyInfo holds basic info about the source
|
||||
|
@ -218,7 +223,7 @@ func CopyInfoDestinationPath(path string) (info CopyInfo, err error) {
|
|||
// Ensure destination parent dir exists.
|
||||
dstParent, _ := SplitPathDirEntry(path)
|
||||
|
||||
parentDirStat, err := os.Lstat(dstParent)
|
||||
parentDirStat, err := os.Stat(dstParent)
|
||||
if err != nil {
|
||||
return CopyInfo{}, err
|
||||
}
|
||||
|
@ -281,7 +286,7 @@ func PrepareArchiveCopy(srcContent io.Reader, srcInfo, dstInfo CopyInfo) (dstDir
|
|||
srcBase = srcInfo.RebaseName
|
||||
}
|
||||
return dstDir, RebaseArchiveEntries(srcContent, srcBase, dstBase), nil
|
||||
case assertsDirectory(dstInfo.Path):
|
||||
case assertsDirectory(dstInfo.Path, os.PathSeparator):
|
||||
// The destination does not exist and is asserted to be created as a
|
||||
// directory, but the source content is not a directory. This is an
|
||||
// error condition since you cannot create a directory from a file
|
||||
|
@ -332,6 +337,9 @@ func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.Read
|
|||
}
|
||||
|
||||
hdr.Name = strings.Replace(hdr.Name, oldBase, newBase, 1)
|
||||
if hdr.Typeflag == tar.TypeLink {
|
||||
hdr.Linkname = strings.Replace(hdr.Linkname, oldBase, newBase, 1)
|
||||
}
|
||||
|
||||
if err = rebasedTar.WriteHeader(hdr); err != nil {
|
||||
w.CloseWithError(err)
|
||||
|
@ -348,6 +356,9 @@ func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.Read
|
|||
return rebased
|
||||
}
|
||||
|
||||
// TODO @gupta-ak. These might have to be changed in the future to be
|
||||
// continuity driver aware as well to support LCOW.
|
||||
|
||||
// CopyResource performs an archive copy from the given source path to the
|
||||
// given destination path. The source path MUST exist and the destination
|
||||
// path's parent directory must exist.
|
||||
|
@ -362,8 +373,8 @@ func CopyResource(srcPath, dstPath string, followLink bool) error {
|
|||
dstPath = normalizePath(dstPath)
|
||||
|
||||
// Clean the source and destination paths.
|
||||
srcPath = PreserveTrailingDotOrSeparator(filepath.Clean(srcPath), srcPath)
|
||||
dstPath = PreserveTrailingDotOrSeparator(filepath.Clean(dstPath), dstPath)
|
||||
srcPath = PreserveTrailingDotOrSeparator(filepath.Clean(srcPath), srcPath, os.PathSeparator)
|
||||
dstPath = PreserveTrailingDotOrSeparator(filepath.Clean(dstPath), dstPath, os.PathSeparator)
|
||||
|
||||
if srcInfo, err = CopyInfoSourcePath(srcPath, followLink); err != nil {
|
||||
return err
|
||||
|
@ -426,7 +437,8 @@ func ResolveHostSourcePath(path string, followLink bool) (resolvedPath, rebaseNa
|
|||
// resolvedDirPath will have been cleaned (no trailing path separators) so
|
||||
// we can manually join it with the base path element.
|
||||
resolvedPath = resolvedDirPath + string(filepath.Separator) + basePath
|
||||
if hasTrailingPathSeparator(path) && filepath.Base(path) != filepath.Base(resolvedPath) {
|
||||
if hasTrailingPathSeparator(path, os.PathSeparator) &&
|
||||
filepath.Base(path) != filepath.Base(resolvedPath) {
|
||||
rebaseName = filepath.Base(path)
|
||||
}
|
||||
}
|
||||
|
@ -439,11 +451,13 @@ func GetRebaseName(path, resolvedPath string) (string, string) {
|
|||
// linkTarget will have been cleaned (no trailing path separators and dot) so
|
||||
// we can manually join it with them
|
||||
var rebaseName string
|
||||
if specifiesCurrentDir(path) && !specifiesCurrentDir(resolvedPath) {
|
||||
if specifiesCurrentDir(path) &&
|
||||
!specifiesCurrentDir(resolvedPath) {
|
||||
resolvedPath += string(filepath.Separator) + "."
|
||||
}
|
||||
|
||||
if hasTrailingPathSeparator(path) && !hasTrailingPathSeparator(resolvedPath) {
|
||||
if hasTrailingPathSeparator(path, os.PathSeparator) &&
|
||||
!hasTrailingPathSeparator(resolvedPath, os.PathSeparator) {
|
||||
resolvedPath += string(filepath.Separator)
|
||||
}
|
||||
|
||||
|
|
32
vendor/github.com/docker/docker/pkg/archive/diff.go
generated
vendored
32
vendor/github.com/docker/docker/pkg/archive/diff.go
generated
vendored
|
@ -10,10 +10,10 @@ import (
|
|||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/pools"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// UnpackLayer unpack `layer` to a `dest`. The stream `layer` can be
|
||||
|
@ -33,10 +33,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
|
|||
if options.ExcludePatterns == nil {
|
||||
options.ExcludePatterns = []string{}
|
||||
}
|
||||
remappedRootUID, remappedRootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
idMappings := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
|
||||
|
||||
aufsTempdir := ""
|
||||
aufsHardlinks := make(map[string]*tar.Header)
|
||||
|
@ -87,7 +84,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
|
|||
parentPath := filepath.Join(dest, parent)
|
||||
|
||||
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
|
||||
err = system.MkdirAll(parentPath, 0600)
|
||||
err = system.MkdirAll(parentPath, 0600, "")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -195,27 +192,10 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
|
|||
srcData = tmpFile
|
||||
}
|
||||
|
||||
// if the options contain a uid & gid maps, convert header uid/gid
|
||||
// entries using the maps such that lchown sets the proper mapped
|
||||
// uid/gid after writing the file. We only perform this mapping if
|
||||
// the file isn't already owned by the remapped root UID or GID, as
|
||||
// that specific uid/gid has no mapping from container -> host, and
|
||||
// those files already have the proper ownership for inside the
|
||||
// container.
|
||||
if srcHdr.Uid != remappedRootUID {
|
||||
xUID, err := idtools.ToHost(srcHdr.Uid, options.UIDMaps)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
srcHdr.Uid = xUID
|
||||
}
|
||||
if srcHdr.Gid != remappedRootGID {
|
||||
xGID, err := idtools.ToHost(srcHdr.Gid, options.GIDMaps)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
srcHdr.Gid = xGID
|
||||
if err := remapIDs(idMappings, srcHdr); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err := createTarFile(path, dest, srcHdr, srcData, true, nil, options.InUserNS); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
2
vendor/github.com/docker/docker/pkg/archive/example_changes.go
generated
vendored
2
vendor/github.com/docker/docker/pkg/archive/example_changes.go
generated
vendored
|
@ -13,8 +13,8 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue