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