diff --git a/hack/vendor.sh b/hack/vendor.sh index 9d950eda2d..054525a4c5 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -7,7 +7,7 @@ source 'hack/.vendor-helpers.sh' # the following lines are in sorted order, FYI clone git github.com/Azure/go-ansiterm 70b2c90b260171e829f1ebd7c17f600c11858dbe -clone git github.com/Microsoft/hcsshim 116e0e9f5ced0cec94ae46d0aa1b3002a325f532 +clone git github.com/Microsoft/hcsshim v0.1.0 clone git github.com/Microsoft/go-winio v0.1.0 clone git github.com/Sirupsen/logrus v0.9.0 # logrus is a common dependency among multiple deps clone git github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a diff --git a/vendor/src/github.com/Microsoft/hcsshim/importlayer.go b/vendor/src/github.com/Microsoft/hcsshim/importlayer.go index 800b300b3a..fc9a6e2e4f 100644 --- a/vendor/src/github.com/Microsoft/hcsshim/importlayer.go +++ b/vendor/src/github.com/Microsoft/hcsshim/importlayer.go @@ -3,6 +3,7 @@ package hcsshim import ( "io/ioutil" "os" + "path/filepath" "runtime" "github.com/Microsoft/go-winio" @@ -110,13 +111,22 @@ type legacyLayerWriterWrapper struct { *LegacyLayerWriter info DriverInfo layerId string + path string parentLayerPaths []string } func (r *legacyLayerWriterWrapper) Close() error { err := r.LegacyLayerWriter.Close() if err == nil { - err = ImportLayer(r.info, r.layerId, r.root, r.parentLayerPaths) + // Use the original path here because ImportLayer does not support long paths for the source in TP5. + // But do use a long path for the destination to work around another bug with directories + // with MAX_PATH - 12 < length < MAX_PATH. + info := r.info + fullPath, err := makeLongAbsPath(filepath.Join(info.HomeDir, r.layerId)) + if err == nil { + info.HomeDir = "" + err = ImportLayer(info, fullPath, r.path, r.parentLayerPaths) + } } os.RemoveAll(r.root) return err @@ -131,7 +141,13 @@ func NewLayerWriter(info DriverInfo, layerId string, parentLayerPaths []string) if err != nil { return nil, err } - return &legacyLayerWriterWrapper{NewLegacyLayerWriter(path), info, layerId, parentLayerPaths}, nil + return &legacyLayerWriterWrapper{ + LegacyLayerWriter: NewLegacyLayerWriter(path), + info: info, + layerId: layerId, + path: path, + parentLayerPaths: parentLayerPaths, + }, nil } layers, err := layerPathsToDescriptors(parentLayerPaths) if err != nil { diff --git a/vendor/src/github.com/Microsoft/hcsshim/legacy.go b/vendor/src/github.com/Microsoft/hcsshim/legacy.go index bc31f23656..863c2a6446 100644 --- a/vendor/src/github.com/Microsoft/hcsshim/legacy.go +++ b/vendor/src/github.com/Microsoft/hcsshim/legacy.go @@ -29,6 +29,23 @@ func openFileOrDir(path string, mode uint32, createDisposition uint32) (file *os return } +func makeLongAbsPath(path string) (string, error) { + if strings.HasPrefix(path, `\\?\`) || strings.HasPrefix(path, `\\.\`) { + return path, nil + } + if !filepath.IsAbs(path) { + absPath, err := filepath.Abs(path) + if err != nil { + return "", err + } + path = absPath + } + if strings.HasPrefix(path, `\\`) { + return `\\?\UNC\` + path[2:], nil + } + return `\\?\` + path, nil +} + type fileEntry struct { path string fi os.FileInfo @@ -81,15 +98,16 @@ func readTombstones(path string) (map[string]([]string), error) { return ts, nil } -func (r *LegacyLayerReader) walk() { - defer close(r.result) - if !<-r.proceed { - return +func (r *LegacyLayerReader) walkUntilCancelled() error { + root, err := makeLongAbsPath(r.root) + if err != nil { + return err } + r.root = root ts, err := readTombstones(r.root) if err != nil { - goto ErrorLoop + return err } err = filepath.Walk(r.root, func(path string, info os.FileInfo, err error) error { @@ -122,17 +140,27 @@ func (r *LegacyLayerReader) walk() { return nil }) if err == errorIterationCanceled { - return + return nil } if err == nil { - err = io.EOF + return io.EOF + } + return err +} + +func (r *LegacyLayerReader) walk() { + defer close(r.result) + if !<-r.proceed { + return } -ErrorLoop: - for { - r.result <- &fileEntry{err: err} - if !<-r.proceed { - break + err := r.walkUntilCancelled() + if err != nil { + for { + r.result <- &fileEntry{err: err} + if !<-r.proceed { + return + } } } } @@ -287,6 +315,7 @@ type LegacyLayerWriter struct { backupWriter *winio.BackupFileWriter tombstones []string isTP4Format bool + pathFixed bool } // NewLegacyLayerWriter returns a LayerWriter that can write the TP4 transport format @@ -298,6 +327,18 @@ func NewLegacyLayerWriter(root string) *LegacyLayerWriter { } } +func (w *LegacyLayerWriter) init() error { + if !w.pathFixed { + path, err := makeLongAbsPath(w.root) + if err != nil { + return err + } + w.root = path + w.pathFixed = true + } + return nil +} + func (w *LegacyLayerWriter) reset() { if w.backupWriter != nil { w.backupWriter.Close() @@ -311,6 +352,10 @@ func (w *LegacyLayerWriter) reset() { func (w *LegacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) error { w.reset() + err := w.init() + if err != nil { + return err + } path := filepath.Join(w.root, name) createDisposition := uint32(syscall.CREATE_NEW) @@ -374,6 +419,10 @@ func (w *LegacyLayerWriter) Write(b []byte) (int, error) { func (w *LegacyLayerWriter) Close() error { w.reset() + err := w.init() + if err != nil { + return err + } tf, err := os.Create(filepath.Join(w.root, "tombstones.txt")) if err != nil { return err