Quellcode durchsuchen

Merge pull request #21307 from Microsoft/jstarks/fix_long_paths

Windows: revendor Microsoft/hcsshim to v0.1.0
Brian Goff vor 9 Jahren
Ursprung
Commit
6dd69afd37

+ 1 - 1
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

+ 18 - 2
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 {

+ 61 - 12
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
+}
 
-ErrorLoop:
-	for {
-		r.result <- &fileEntry{err: err}
-		if !<-r.proceed {
-			break
+func (r *LegacyLayerReader) walk() {
+	defer close(r.result)
+	if !<-r.proceed {
+		return
+	}
+
+	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