Add an option to specify a Create date for images
Add CommitOption option that to allow a caller to specify a creation timestamp to use in images. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com> Closes: #141 Approved by: rhatdan
This commit is contained in:
parent
af5512ab74
commit
4a05d8643d
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/storage"
|
||||
"github.com/containers/image/transports/alltransports"
|
||||
|
@ -15,7 +16,7 @@ import (
|
|||
var (
|
||||
commitFlags = []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "disable-compression",
|
||||
Name: "disable-compression, D",
|
||||
Usage: "don't compress layers",
|
||||
},
|
||||
cli.StringFlag{
|
||||
|
@ -26,6 +27,11 @@ var (
|
|||
Name: "format, f",
|
||||
Usage: "`format` of the image manifest and metadata",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "reference-time",
|
||||
Usage: "set the timestamp on the image to match the named `file`",
|
||||
Hidden: true,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "quiet, q",
|
||||
Usage: "don't output progress information when writing images",
|
||||
|
@ -73,6 +79,15 @@ func commitCmd(c *cli.Context) error {
|
|||
if c.IsSet("format") {
|
||||
format = c.String("format")
|
||||
}
|
||||
timestamp := time.Now().UTC()
|
||||
if c.IsSet("reference-time") {
|
||||
referenceFile := c.String("reference-time")
|
||||
finfo, err := os.Stat(referenceFile)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error reading timestamp of file %q", referenceFile)
|
||||
}
|
||||
timestamp = finfo.ModTime().UTC()
|
||||
}
|
||||
if strings.HasPrefix(strings.ToLower(format), "oci") {
|
||||
format = buildah.OCIv1ImageManifest
|
||||
} else if strings.HasPrefix(strings.ToLower(format), "docker") {
|
||||
|
@ -103,6 +118,7 @@ func commitCmd(c *cli.Context) error {
|
|||
PreferredManifestType: format,
|
||||
Compression: compress,
|
||||
SignaturePolicyPath: signaturePolicy,
|
||||
HistoryTimestamp: ×tamp,
|
||||
}
|
||||
if !quiet {
|
||||
options.ReportWriter = os.Stderr
|
||||
|
|
|
@ -3,6 +3,7 @@ package buildah
|
|||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
cp "github.com/containers/image/copy"
|
||||
|
@ -50,6 +51,9 @@ type CommitOptions struct {
|
|||
// ReportWriter is an io.Writer which will be used to log the writing
|
||||
// of the new image.
|
||||
ReportWriter io.Writer
|
||||
// HistoryTimestamp is the timestamp used when creating new items in the
|
||||
// image's history. If unset, the current time will be used.
|
||||
HistoryTimestamp *time.Time
|
||||
}
|
||||
|
||||
// shallowCopy copies the most recent layer, the configuration, and the manifest from one image to another.
|
||||
|
@ -220,7 +224,7 @@ func (b *Builder) Commit(dest types.ImageReference, options CommitOptions) error
|
|||
// Check if we're keeping everything in local storage. If so, we can take certain shortcuts.
|
||||
_, destIsStorage := dest.Transport().(storage.StoreTransport)
|
||||
exporting := !destIsStorage
|
||||
src, err := b.makeContainerImageRef(options.PreferredManifestType, exporting, options.Compression)
|
||||
src, err := b.makeContainerImageRef(options.PreferredManifestType, exporting, options.Compression, options.HistoryTimestamp)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error recomputing layer digests and building metadata")
|
||||
}
|
||||
|
|
|
@ -227,9 +227,16 @@ func (b *Builder) fixupConfig() {
|
|||
b.Docker.Parent = docker.ID(digest.NewDigestFromHex(digest.Canonical.String(), b.FromImageID))
|
||||
}
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
if b.Docker.Created.IsZero() {
|
||||
b.Docker.Created = now
|
||||
}
|
||||
if b.FromImage != "" {
|
||||
b.Docker.Config.Image = b.FromImage
|
||||
}
|
||||
if b.OCIv1.Created.IsZero() {
|
||||
b.OCIv1.Created = now
|
||||
}
|
||||
if b.OS() == "" {
|
||||
b.SetOS(runtime.GOOS)
|
||||
}
|
||||
|
|
|
@ -295,6 +295,7 @@ return 1
|
|||
--signature-policy
|
||||
--format
|
||||
-f
|
||||
--reference-time
|
||||
"
|
||||
|
||||
local all_options="$options_with_args $boolean_options"
|
||||
|
|
|
@ -33,6 +33,11 @@ Control the format for the image manifest and configuration data. Recognized
|
|||
formats include *oci* (OCI image-spec v1.0, the default) and *docker* (version
|
||||
2, using schema format 2 for the manifest).
|
||||
|
||||
**--reference-time**
|
||||
|
||||
Sets the creation date in the image to match the last-modified time of the
|
||||
specified file. This option is mainly present for use in buildah's self-tests.
|
||||
|
||||
## EXAMPLE
|
||||
|
||||
buildah commit containerID
|
||||
|
|
16
image.go
16
image.go
|
@ -460,7 +460,7 @@ func (i *containerImageSource) GetBlob(blob types.BlobInfo) (reader io.ReadClose
|
|||
return ioutils.NewReadCloserWrapper(layerFile, closer), size, nil
|
||||
}
|
||||
|
||||
func (b *Builder) makeImageRef(manifestType string, exporting, addHistory bool, compress archive.Compression, names []string, layerID string) (types.ImageReference, error) {
|
||||
func (b *Builder) makeImageRef(manifestType string, exporting, addHistory bool, compress archive.Compression, names []string, layerID string, historyTimestamp *time.Time) (types.ImageReference, error) {
|
||||
var name reference.Named
|
||||
if len(names) > 0 {
|
||||
if parsed, err := reference.ParseNamed(names[0]); err == nil {
|
||||
|
@ -478,6 +478,10 @@ func (b *Builder) makeImageRef(manifestType string, exporting, addHistory bool,
|
|||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error encoding docker-format image configuration")
|
||||
}
|
||||
created := time.Now().UTC()
|
||||
if historyTimestamp != nil {
|
||||
created = historyTimestamp.UTC()
|
||||
}
|
||||
ref := &containerImageRef{
|
||||
store: b.store,
|
||||
compression: compress,
|
||||
|
@ -487,7 +491,7 @@ func (b *Builder) makeImageRef(manifestType string, exporting, addHistory bool,
|
|||
addHistory: addHistory,
|
||||
oconfig: oconfig,
|
||||
dconfig: dconfig,
|
||||
created: time.Now().UTC(),
|
||||
created: created,
|
||||
createdBy: b.CreatedBy(),
|
||||
annotations: b.Annotations(),
|
||||
preferredManifestType: manifestType,
|
||||
|
@ -496,7 +500,7 @@ func (b *Builder) makeImageRef(manifestType string, exporting, addHistory bool,
|
|||
return ref, nil
|
||||
}
|
||||
|
||||
func (b *Builder) makeContainerImageRef(manifestType string, exporting bool, compress archive.Compression) (types.ImageReference, error) {
|
||||
func (b *Builder) makeContainerImageRef(manifestType string, exporting bool, compress archive.Compression, historyTimestamp *time.Time) (types.ImageReference, error) {
|
||||
if manifestType == "" {
|
||||
manifestType = OCIv1ImageManifest
|
||||
}
|
||||
|
@ -504,9 +508,9 @@ func (b *Builder) makeContainerImageRef(manifestType string, exporting bool, com
|
|||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error locating container %q", b.ContainerID)
|
||||
}
|
||||
return b.makeImageRef(manifestType, exporting, true, compress, container.Names, container.LayerID)
|
||||
return b.makeImageRef(manifestType, exporting, true, compress, container.Names, container.LayerID, historyTimestamp)
|
||||
}
|
||||
|
||||
func (b *Builder) makeImageImageRef(compress archive.Compression, names []string, layerID string) (types.ImageReference, error) {
|
||||
return b.makeImageRef(manifest.GuessMIMEType(b.Manifest), true, false, compress, names, layerID)
|
||||
func (b *Builder) makeImageImageRef(compress archive.Compression, names []string, layerID string, historyTimestamp *time.Time) (types.ImageReference, error) {
|
||||
return b.makeImageRef(manifest.GuessMIMEType(b.Manifest), true, false, compress, names, layerID, historyTimestamp)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue