Windows: revendor Microsoft/hcsshim to v0.1.0

This (the first tagged hcsshim release) fixes long-path bugs on
Windows TP5 that affect commit and save. These bugs were blocking
commit of Windows containers that had node.js installed.

Signed-off-by: John Starks <jostarks@microsoft.com>
This commit is contained in:
John Starks 2016-03-17 21:08:07 +00:00
parent 41c1c6501e
commit b54058bafe
3 changed files with 80 additions and 15 deletions

View File

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

View File

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

View File

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