diff --git a/daemon/graphdriver/windows/windows.go b/daemon/graphdriver/windows/windows.go index 7465dc392a..77f4f1b774 100644 --- a/daemon/graphdriver/windows/windows.go +++ b/daemon/graphdriver/windows/windows.go @@ -6,7 +6,6 @@ import ( "crypto/sha512" "encoding/json" "fmt" - "io" "io/ioutil" "os" "path/filepath" @@ -501,10 +500,6 @@ func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPat if size, err = chrootarchive.ApplyLayer(tempFolder, layerData); err != nil { return } - err = copySysFiles(tempFolder, filepath.Join(d.info.HomeDir, "sysfile-backups", id)) - if err != nil { - return - } logrus.Debugf("Untar time: %vs", time.Now().UTC().Sub(start).Seconds()) if err = hcsshim.ImportLayer(d.info, id, tempFolder, parentLayerPaths); err != nil { @@ -602,69 +597,9 @@ func (d *Driver) DiffPath(id string) (path string, release func() error, err err return } - err = copySysFiles(filepath.Join(d.info.HomeDir, "sysfile-backups", id), tempFolder) - if err != nil { - return - } - return tempFolder, func() error { // TODO: activate layers and release here? _, folderName := filepath.Split(tempFolder) return hcsshim.DestroyLayer(d.info, folderName) }, nil } - -var sysFileWhiteList = []string{ - "Hives\\*", - "Files\\BOOTNXT", - "tombstones.txt", -} - -// note this only handles files -func copySysFiles(src string, dest string) error { - if err := os.MkdirAll(dest, 0700); err != nil { - return err - } - return filepath.Walk(src, func(path string, info os.FileInfo, err error) error { - rel, err := filepath.Rel(src, path) - if err != nil { - return err - } - for _, sysfile := range sysFileWhiteList { - if matches, err := filepath.Match(sysfile, rel); err != nil || !matches { - continue - } - - fi, err := os.Lstat(path) - if err != nil { - return err - } - - if !fi.Mode().IsRegular() { - continue - } - - targetPath := filepath.Join(dest, rel) - if err = os.MkdirAll(filepath.Dir(targetPath), 0700); err != nil { - return err - } - - in, err := os.Open(path) - if err != nil { - return err - } - out, err := os.Create(targetPath) - if err != nil { - in.Close() - return err - } - _, err = io.Copy(out, in) - in.Close() - out.Close() - if err != nil { - return err - } - } - return nil - }) -} diff --git a/image/tarexport/save.go b/image/tarexport/save.go index b7022ac5d8..45258e4f85 100644 --- a/image/tarexport/save.go +++ b/image/tarexport/save.go @@ -14,6 +14,7 @@ import ( "github.com/docker/docker/image/v1" "github.com/docker/docker/layer" "github.com/docker/docker/pkg/archive" + "github.com/docker/docker/pkg/system" "github.com/docker/docker/reference" ) @@ -160,7 +161,7 @@ func (s *saveSession) save(outStream io.Writer) error { if err := f.Close(); err != nil { return err } - if err := os.Chtimes(reposFile, time.Unix(0, 0), time.Unix(0, 0)); err != nil { + if err := system.Chtimes(reposFile, time.Unix(0, 0), time.Unix(0, 0)); err != nil { return err } } @@ -177,7 +178,7 @@ func (s *saveSession) save(outStream io.Writer) error { if err := f.Close(); err != nil { return err } - if err := os.Chtimes(manifestFileName, time.Unix(0, 0), time.Unix(0, 0)); err != nil { + if err := system.Chtimes(manifestFileName, time.Unix(0, 0), time.Unix(0, 0)); err != nil { return err } @@ -233,7 +234,7 @@ func (s *saveSession) saveImage(id image.ID) error { if err := ioutil.WriteFile(configFile, img.RawJSON(), 0644); err != nil { return err } - if err := os.Chtimes(configFile, img.Created, img.Created); err != nil { + if err := system.Chtimes(configFile, img.Created, img.Created); err != nil { return err } @@ -290,7 +291,7 @@ func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, creat for _, fname := range []string{"", legacyVersionFileName, legacyConfigFileName, legacyLayerFileName} { // todo: maybe save layer created timestamp? - if err := os.Chtimes(filepath.Join(outDir, fname), createdTime, createdTime); err != nil { + if err := system.Chtimes(filepath.Join(outDir, fname), createdTime, createdTime); err != nil { return err } } diff --git a/pkg/archive/changes_test.go b/pkg/archive/changes_test.go index f4316ce21e..00bd69f31e 100644 --- a/pkg/archive/changes_test.go +++ b/pkg/archive/changes_test.go @@ -8,6 +8,8 @@ import ( "sort" "testing" "time" + + "github.com/docker/docker/pkg/system" ) func max(x, y int) int { @@ -87,7 +89,7 @@ func createSampleDir(t *testing.T, root string) { if info.filetype != Symlink { // Set a consistent ctime, atime for all files and dirs - if err := os.Chtimes(p, now, now); err != nil { + if err := system.Chtimes(p, now, now); err != nil { t.Fatal(err) } } @@ -289,7 +291,7 @@ func mutateSampleDir(t *testing.T, root string) { } // Touch file - if err := os.Chtimes(path.Join(root, "file4"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { + if err := system.Chtimes(path.Join(root, "file4"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { t.Fatal(err) } @@ -333,7 +335,7 @@ func mutateSampleDir(t *testing.T, root string) { } // Touch dir - if err := os.Chtimes(path.Join(root, "dir3"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { + if err := system.Chtimes(path.Join(root, "dir3"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { t.Fatal(err) } } diff --git a/pkg/system/chtimes.go b/pkg/system/chtimes.go index acf3f566f7..7637f12e1a 100644 --- a/pkg/system/chtimes.go +++ b/pkg/system/chtimes.go @@ -43,5 +43,10 @@ func Chtimes(name string, atime time.Time, mtime time.Time) error { return err } + // Take platform specific action for setting create time. + if err := setCTime(name, mtime); err != nil { + return err + } + return nil } diff --git a/pkg/system/chtimes_unix.go b/pkg/system/chtimes_unix.go new file mode 100644 index 0000000000..09d58bcbfd --- /dev/null +++ b/pkg/system/chtimes_unix.go @@ -0,0 +1,14 @@ +// +build !windows + +package system + +import ( + "time" +) + +//setCTime will set the create time on a file. On Unix, the create +//time is updated as a side effect of setting the modified time, so +//no action is required. +func setCTime(path string, ctime time.Time) error { + return nil +} diff --git a/pkg/system/chtimes_unix_test.go b/pkg/system/chtimes_unix_test.go index fcd5940238..0aafe1d845 100644 --- a/pkg/system/chtimes_unix_test.go +++ b/pkg/system/chtimes_unix_test.go @@ -1,4 +1,4 @@ -// +build linux freebsd +// +build !windows package system diff --git a/pkg/system/chtimes_windows.go b/pkg/system/chtimes_windows.go new file mode 100644 index 0000000000..2945868465 --- /dev/null +++ b/pkg/system/chtimes_windows.go @@ -0,0 +1,27 @@ +// +build windows + +package system + +import ( + "syscall" + "time" +) + +//setCTime will set the create time on a file. On Windows, this requires +//calling SetFileTime and explicitly including the create time. +func setCTime(path string, ctime time.Time) error { + ctimespec := syscall.NsecToTimespec(ctime.UnixNano()) + pathp, e := syscall.UTF16PtrFromString(path) + if e != nil { + return e + } + h, e := syscall.CreateFile(pathp, + syscall.FILE_WRITE_ATTRIBUTES, syscall.FILE_SHARE_WRITE, nil, + syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) + if e != nil { + return e + } + defer syscall.Close(h) + c := syscall.NsecToFiletime(syscall.TimespecToNsec(ctimespec)) + return syscall.SetFileTime(h, &c, nil, nil) +}