mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
27801b9ef8
This switches the hcsshim dependency back to tagged releases, instead of the special "moby" branch. This makes the dependency align with both BuildKit and containerd, which use these versions. The switch to the "moby" branch was done in2865478487
, to bring in a fix for image import, without having to bring in additional changes; > We changed to the moby branch for a couple of reasons: > > - Allows us to take this important change without needing to also pull in all > of the other work that has been going on in the repo. > - moby uses an older set of APIs exposed from hcsshim, based on the HCS v1 > functionality. Going forwards, we have discussed deprecating/removing these > APIs from the mainline branch in hcsshim, so our thinking was we could keep > this moby branch around to ensure we don't break compatibility there. > > (...) Long term, the best path here is to get moby using containerd as the > backend on Windows, which should alleviate these issues. full diff:9dcb42f100
..v0.8.10 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
182 lines
3.9 KiB
Go
182 lines
3.9 KiB
Go
package wclayer
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"syscall"
|
|
|
|
"github.com/Microsoft/go-winio"
|
|
"github.com/Microsoft/hcsshim/internal/hcserror"
|
|
"github.com/Microsoft/hcsshim/internal/oc"
|
|
"github.com/Microsoft/hcsshim/internal/safefile"
|
|
"github.com/Microsoft/hcsshim/internal/winapi"
|
|
"go.opencensus.io/trace"
|
|
)
|
|
|
|
type baseLayerWriter struct {
|
|
ctx context.Context
|
|
s *trace.Span
|
|
|
|
root *os.File
|
|
f *os.File
|
|
bw *winio.BackupFileWriter
|
|
err error
|
|
hasUtilityVM bool
|
|
dirInfo []dirInfo
|
|
}
|
|
|
|
type dirInfo struct {
|
|
path string
|
|
fileInfo winio.FileBasicInfo
|
|
}
|
|
|
|
// reapplyDirectoryTimes reapplies directory modification, creation, etc. times
|
|
// after processing of the directory tree has completed. The times are expected
|
|
// to be ordered such that parent directories come before child directories.
|
|
func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error {
|
|
for i := range dis {
|
|
di := &dis[len(dis)-i-1] // reverse order: process child directories first
|
|
f, err := safefile.OpenRelative(di.path, root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, winapi.FILE_OPEN, winapi.FILE_DIRECTORY_FILE|syscall.FILE_FLAG_OPEN_REPARSE_POINT)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = winio.SetFileBasicInfo(f, &di.fileInfo)
|
|
f.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (w *baseLayerWriter) closeCurrentFile() error {
|
|
if w.f != nil {
|
|
err := w.bw.Close()
|
|
err2 := w.f.Close()
|
|
w.f = nil
|
|
w.bw = nil
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err2 != nil {
|
|
return err2
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (w *baseLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) (err error) {
|
|
defer func() {
|
|
if err != nil {
|
|
w.err = err
|
|
}
|
|
}()
|
|
|
|
err = w.closeCurrentFile()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if filepath.ToSlash(name) == `UtilityVM/Files` {
|
|
w.hasUtilityVM = true
|
|
}
|
|
|
|
var f *os.File
|
|
defer func() {
|
|
if f != nil {
|
|
f.Close()
|
|
}
|
|
}()
|
|
|
|
extraFlags := uint32(0)
|
|
if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
|
|
extraFlags |= winapi.FILE_DIRECTORY_FILE
|
|
w.dirInfo = append(w.dirInfo, dirInfo{name, *fileInfo})
|
|
}
|
|
|
|
mode := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | winio.WRITE_DAC | winio.WRITE_OWNER | winio.ACCESS_SYSTEM_SECURITY)
|
|
f, err = safefile.OpenRelative(name, w.root, mode, syscall.FILE_SHARE_READ, winapi.FILE_CREATE, extraFlags)
|
|
if err != nil {
|
|
return hcserror.New(err, "Failed to safefile.OpenRelative", name)
|
|
}
|
|
|
|
err = winio.SetFileBasicInfo(f, fileInfo)
|
|
if err != nil {
|
|
return hcserror.New(err, "Failed to SetFileBasicInfo", name)
|
|
}
|
|
|
|
w.f = f
|
|
w.bw = winio.NewBackupFileWriter(f, true)
|
|
f = nil
|
|
return nil
|
|
}
|
|
|
|
func (w *baseLayerWriter) AddLink(name string, target string) (err error) {
|
|
defer func() {
|
|
if err != nil {
|
|
w.err = err
|
|
}
|
|
}()
|
|
|
|
err = w.closeCurrentFile()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return safefile.LinkRelative(target, w.root, name, w.root)
|
|
}
|
|
|
|
func (w *baseLayerWriter) Remove(name string) error {
|
|
return errors.New("base layer cannot have tombstones")
|
|
}
|
|
|
|
func (w *baseLayerWriter) Write(b []byte) (int, error) {
|
|
n, err := w.bw.Write(b)
|
|
if err != nil {
|
|
w.err = err
|
|
}
|
|
return n, err
|
|
}
|
|
|
|
func (w *baseLayerWriter) Close() (err error) {
|
|
defer w.s.End()
|
|
defer func() { oc.SetSpanStatus(w.s, err) }()
|
|
defer func() {
|
|
w.root.Close()
|
|
w.root = nil
|
|
}()
|
|
|
|
err = w.closeCurrentFile()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if w.err == nil {
|
|
// Restore the file times of all the directories, since they may have
|
|
// been modified by creating child directories.
|
|
err = reapplyDirectoryTimes(w.root, w.dirInfo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = ProcessBaseLayer(w.ctx, w.root.Name())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if w.hasUtilityVM {
|
|
err := safefile.EnsureNotReparsePointRelative("UtilityVM", w.root)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = ProcessUtilityVMImage(w.ctx, filepath.Join(w.root.Name(), "UtilityVM"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return w.err
|
|
}
|