moby--moby/graph/export.go

181 lines
4.5 KiB
Go
Raw Normal View History

package graph
import (
"encoding/json"
graph: exported images times matching creation the image export, that is used in `docker save` previous has just had the layers times (atimes, mtimes) be when the save was done. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 2015-09-03 22:22 repositories ``` With this change, the layer's directory and artifact will have times matching the image layer's created time. The "repositories" file is set to epoch. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 1969-12-31 19:00 repositories ``` Side effect of this is that the tar stream from `docker save` is now more deterministic. ```bash vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - ``` Signed-off-by: Vincent Batts <vbatts@redhat.com>
2015-09-04 02:19:10 +00:00
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
graph: exported images times matching creation the image export, that is used in `docker save` previous has just had the layers times (atimes, mtimes) be when the save was done. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 2015-09-03 22:22 repositories ``` With this change, the layer's directory and artifact will have times matching the image layer's created time. The "repositories" file is set to epoch. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 1969-12-31 19:00 repositories ``` Side effect of this is that the tar stream from `docker save` is now more deterministic. ```bash vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - ``` Signed-off-by: Vincent Batts <vbatts@redhat.com>
2015-09-04 02:19:10 +00:00
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/digest"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/parsers"
Deprecating ResolveRepositoryName Passing RepositoryInfo to ResolveAuthConfig, pullRepository, and pushRepository Moving --registry-mirror configuration to registry config Created resolve_repository job Repo names with 'index.docker.io' or 'docker.io' are now synonymous with omitting an index name. Adding test for RepositoryInfo Adding tests for opts.StringSetOpts and registry.ValidateMirror Fixing search term use of repoInfo Adding integration tests for registry mirror configuration Normalizing LookupImage image name to match LocalName parsing rules Normalizing repository LocalName to avoid multiple references to an official image Removing errorOut use in tests Removing TODO comment gofmt changes golint comments cleanup. renaming RegistryOptions => registry.Options, and RegistryServiceConfig => registry.ServiceConfig Splitting out builtins.Registry and registry.NewService calls Stray whitespace cleanup Moving integration tests for Mirrors and InsecureRegistries into TestNewIndexInfo unit test Factoring out ValidateRepositoryName from NewRepositoryInfo Removing unused IndexServerURL Allowing json marshaling of ServiceConfig. Exposing ServiceConfig in /info Switching to CamelCase for json marshaling PR cleanup; removing 'Is' prefix from boolean members. Removing unneeded json tags. Removing non-cleanup related fix for 'localhost:[port]' in splitReposName Merge fixes for gh9735 Fixing integration test Reapplying #9754 Adding comment on config.IndexConfigs use from isSecureIndex Remove unused error return value from isSecureIndex Signed-off-by: Don Kjer <don.kjer@gmail.com> Adding back comment in isSecureIndex Signed-off-by: Don Kjer <don.kjer@gmail.com>
2014-10-07 01:54:52 +00:00
"github.com/docker/docker/registry"
)
// ImageExport exports list of images to a output stream specified in the
// config. The exported images are archived into a tar when written to the
// output stream. All images with the given tag and all versions containing the
// same tag are exported. names is the set of tags to export, and outStream
// is the writer which the images are written to.
func (s *TagStore) ImageExport(names []string, outStream io.Writer) error {
// get image json
tempdir, err := ioutil.TempDir("", "docker-export-")
if err != nil {
return err
}
defer os.RemoveAll(tempdir)
rootRepoMap := map[string]Repository{}
addKey := func(name string, tag string, id string) {
logrus.Debugf("add key [%s:%s]", name, tag)
if repo, ok := rootRepoMap[name]; !ok {
rootRepoMap[name] = Repository{tag: id}
} else {
repo[tag] = id
}
}
for _, name := range names {
Deprecating ResolveRepositoryName Passing RepositoryInfo to ResolveAuthConfig, pullRepository, and pushRepository Moving --registry-mirror configuration to registry config Created resolve_repository job Repo names with 'index.docker.io' or 'docker.io' are now synonymous with omitting an index name. Adding test for RepositoryInfo Adding tests for opts.StringSetOpts and registry.ValidateMirror Fixing search term use of repoInfo Adding integration tests for registry mirror configuration Normalizing LookupImage image name to match LocalName parsing rules Normalizing repository LocalName to avoid multiple references to an official image Removing errorOut use in tests Removing TODO comment gofmt changes golint comments cleanup. renaming RegistryOptions => registry.Options, and RegistryServiceConfig => registry.ServiceConfig Splitting out builtins.Registry and registry.NewService calls Stray whitespace cleanup Moving integration tests for Mirrors and InsecureRegistries into TestNewIndexInfo unit test Factoring out ValidateRepositoryName from NewRepositoryInfo Removing unused IndexServerURL Allowing json marshaling of ServiceConfig. Exposing ServiceConfig in /info Switching to CamelCase for json marshaling PR cleanup; removing 'Is' prefix from boolean members. Removing unneeded json tags. Removing non-cleanup related fix for 'localhost:[port]' in splitReposName Merge fixes for gh9735 Fixing integration test Reapplying #9754 Adding comment on config.IndexConfigs use from isSecureIndex Remove unused error return value from isSecureIndex Signed-off-by: Don Kjer <don.kjer@gmail.com> Adding back comment in isSecureIndex Signed-off-by: Don Kjer <don.kjer@gmail.com>
2014-10-07 01:54:52 +00:00
name = registry.NormalizeLocalName(name)
logrus.Debugf("Serializing %s", name)
rootRepo := s.Repositories[name]
if rootRepo != nil {
// this is a base repo name, like 'busybox'
for tag, id := range rootRepo {
addKey(name, tag, id)
if err := s.exportImage(id, tempdir); err != nil {
return err
}
}
} else {
img, err := s.LookupImage(name)
if err != nil {
return err
}
if img != nil {
// This is a named image like 'busybox:latest'
repoName, repoTag := parsers.ParseRepositoryTag(name)
// Skip digests on save
if _, err := digest.ParseDigest(repoTag); err == nil {
repoTag = ""
}
// check this length, because a lookup of a truncated has will not have a tag
// and will not need to be added to this map
if len(repoTag) > 0 {
addKey(repoName, repoTag, img.ID)
}
if err := s.exportImage(img.ID, tempdir); err != nil {
return err
}
} else {
// this must be an ID that didn't get looked up just right?
if err := s.exportImage(name, tempdir); err != nil {
return err
}
}
}
logrus.Debugf("End Serializing %s", name)
}
// write repositories, if there is something to write
if len(rootRepoMap) > 0 {
f, err := os.OpenFile(filepath.Join(tempdir, "repositories"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
f.Close()
return err
}
if err := json.NewEncoder(f).Encode(rootRepoMap); err != nil {
return err
}
if err := f.Close(); err != nil {
return err
}
graph: exported images times matching creation the image export, that is used in `docker save` previous has just had the layers times (atimes, mtimes) be when the save was done. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 2015-09-03 22:22 repositories ``` With this change, the layer's directory and artifact will have times matching the image layer's created time. The "repositories" file is set to epoch. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 1969-12-31 19:00 repositories ``` Side effect of this is that the tar stream from `docker save` is now more deterministic. ```bash vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - ``` Signed-off-by: Vincent Batts <vbatts@redhat.com>
2015-09-04 02:19:10 +00:00
if err := os.Chtimes(filepath.Join(tempdir, "repositories"), time.Unix(0, 0), time.Unix(0, 0)); err != nil {
return err
}
} else {
logrus.Debugf("There were no repositories to write")
}
fs, err := archive.Tar(tempdir, archive.Uncompressed)
if err != nil {
return err
}
defer fs.Close()
if _, err := io.Copy(outStream, fs); err != nil {
return err
}
logrus.Debugf("End export image")
return nil
}
func (s *TagStore) exportImage(name, tempdir string) error {
for n := name; n != ""; {
img, err := s.LookupImage(n)
if err != nil || img == nil {
return fmt.Errorf("No such image %s", n)
}
// temporary directory
tmpImageDir := filepath.Join(tempdir, n)
if err := os.Mkdir(tmpImageDir, os.FileMode(0755)); err != nil {
if os.IsExist(err) {
return nil
}
return err
}
var version = "1.0"
var versionBuf = []byte(version)
if err := ioutil.WriteFile(filepath.Join(tmpImageDir, "VERSION"), versionBuf, os.FileMode(0644)); err != nil {
return err
}
imageInspectRaw, err := json.Marshal(img)
if err != nil {
return err
}
// serialize json
json, err := os.Create(filepath.Join(tmpImageDir, "json"))
if err != nil {
return err
}
written, err := json.Write(imageInspectRaw)
if err != nil {
return err
}
if written != len(imageInspectRaw) {
logrus.Warnf("%d byes should have been written instead %d have been written", written, len(imageInspectRaw))
}
// serialize filesystem
fsTar, err := os.Create(filepath.Join(tmpImageDir, "layer.tar"))
if err != nil {
return err
}
if err := s.ImageTarLayer(n, fsTar); err != nil {
return err
}
graph: exported images times matching creation the image export, that is used in `docker save` previous has just had the layers times (atimes, mtimes) be when the save was done. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 2015-09-03 22:22 repositories ``` With this change, the layer's directory and artifact will have times matching the image layer's created time. The "repositories" file is set to epoch. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 1969-12-31 19:00 repositories ``` Side effect of this is that the tar stream from `docker save` is now more deterministic. ```bash vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - ``` Signed-off-by: Vincent Batts <vbatts@redhat.com>
2015-09-04 02:19:10 +00:00
for _, fname := range []string{"", "VERSION", "json", "layer.tar"} {
if err := os.Chtimes(filepath.Join(tmpImageDir, fname), img.Created, img.Created); err != nil {
return err
}
}
graph: exported images times matching creation the image export, that is used in `docker save` previous has just had the layers times (atimes, mtimes) be when the save was done. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-09-03 22:22 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-09-03 22:22 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 2015-09-03 22:22 repositories ``` With this change, the layer's directory and artifact will have times matching the image layer's created time. The "repositories" file is set to epoch. ```bash vbatts@valse ~ (master) $ docker save busybox | tar tv drwxr-xr-x 0/0 0 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/ -rw-r--r-- 0/0 3 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/VERSION -rw-r--r-- 0/0 1405 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/json -rw-r--r-- 0/0 2643968 2015-04-17 18:01 6ce2e90b0bc7224de3db1f0d646fe8e2c4dd37f1793928287f6074bc451a57ea/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/ -rw-r--r-- 0/0 3 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/VERSION -rw-r--r-- 0/0 1346 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 8c2e06607696bd4afb3d03b687e361cc43cf8ec1a4a725bc96e39f05ba97dd55/layer.tar drwxr-xr-x 0/0 0 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/ -rw-r--r-- 0/0 3 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/VERSION -rw-r--r-- 0/0 1181 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/json -rw-r--r-- 0/0 1024 2015-04-17 18:01 cf2616975b4a3cba083ca99bc3f0bf25f5f528c3c52be1596b30f60b0b1c37ff/layer.tar -rw-r--r-- 0/0 90 1969-12-31 19:00 repositories ``` Side effect of this is that the tar stream from `docker save` is now more deterministic. ```bash vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - vbatts@valse ~ (master) $ docker save busybox | sha1sum baf03e30ef79ca4d9c5e512d3a1b873880f404ca - ``` Signed-off-by: Vincent Batts <vbatts@redhat.com>
2015-09-04 02:19:10 +00:00
// try again with parent
n = img.Parent
}
return nil
}