2017-02-11 00:48:15 +08:00
|
|
|
package buildah
|
|
|
|
|
|
|
|
import (
|
2017-09-29 23:07:32 +08:00
|
|
|
"fmt"
|
2017-05-09 23:56:44 +08:00
|
|
|
"io"
|
2017-06-07 02:11:46 +08:00
|
|
|
"time"
|
2017-04-11 02:25:07 +08:00
|
|
|
|
2017-06-05 21:42:30 +08:00
|
|
|
cp "github.com/containers/image/copy"
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
"github.com/containers/image/manifest"
|
2017-02-11 00:48:15 +08:00
|
|
|
"github.com/containers/image/signature"
|
2017-06-02 00:11:14 +08:00
|
|
|
is "github.com/containers/image/storage"
|
2017-05-18 04:56:14 +08:00
|
|
|
"github.com/containers/image/transports"
|
2017-02-11 00:48:15 +08:00
|
|
|
"github.com/containers/image/types"
|
2017-06-02 00:11:14 +08:00
|
|
|
"github.com/containers/storage"
|
2017-02-11 00:48:15 +08:00
|
|
|
"github.com/containers/storage/pkg/archive"
|
2017-06-02 03:23:02 +08:00
|
|
|
"github.com/pkg/errors"
|
2017-05-20 02:13:15 +08:00
|
|
|
"github.com/projectatomic/buildah/util"
|
2017-10-10 03:05:56 +08:00
|
|
|
"github.com/sirupsen/logrus"
|
2017-02-11 00:48:15 +08:00
|
|
|
)
|
|
|
|
|
2017-02-11 03:45:06 +08:00
|
|
|
// CommitOptions can be used to alter how an image is committed.
|
2017-02-11 00:48:15 +08:00
|
|
|
type CommitOptions struct {
|
2017-05-18 05:02:40 +08:00
|
|
|
// PreferredManifestType is the preferred type of image manifest. The
|
|
|
|
// image configuration format will be of a compatible type.
|
|
|
|
PreferredManifestType string
|
2017-02-11 03:45:06 +08:00
|
|
|
// Compression specifies the type of compression which is applied to
|
|
|
|
// layer blobs. The default is to not use compression, but
|
|
|
|
// archive.Gzip is recommended.
|
|
|
|
Compression archive.Compression
|
|
|
|
// SignaturePolicyPath specifies an override location for the signature
|
|
|
|
// policy which should be used for verifying the new image as it is
|
|
|
|
// being written. Except in specific circumstances, no value should be
|
|
|
|
// specified, indicating that the shared, system-wide default policy
|
|
|
|
// should be used.
|
2017-02-11 00:48:15 +08:00
|
|
|
SignaturePolicyPath string
|
2017-04-11 02:25:07 +08:00
|
|
|
// AdditionalTags is a list of additional names to add to the image, if
|
|
|
|
// the transport to which we're writing the image gives us a way to add
|
|
|
|
// them.
|
|
|
|
AdditionalTags []string
|
2017-05-09 23:56:44 +08:00
|
|
|
// ReportWriter is an io.Writer which will be used to log the writing
|
|
|
|
// of the new image.
|
|
|
|
ReportWriter io.Writer
|
2017-06-07 02:11:46 +08:00
|
|
|
// 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
|
2017-08-25 05:44:32 +08:00
|
|
|
// github.com/containers/image/types SystemContext to hold credentials
|
|
|
|
// and other authentication/authorization information.
|
|
|
|
SystemContext *types.SystemContext
|
2017-04-11 02:25:07 +08:00
|
|
|
}
|
|
|
|
|
2017-06-02 00:11:14 +08:00
|
|
|
// PushOptions can be used to alter how an image is copied somewhere.
|
|
|
|
type PushOptions struct {
|
|
|
|
// Compression specifies the type of compression which is applied to
|
|
|
|
// layer blobs. The default is to not use compression, but
|
|
|
|
// archive.Gzip is recommended.
|
|
|
|
Compression archive.Compression
|
|
|
|
// SignaturePolicyPath specifies an override location for the signature
|
|
|
|
// policy which should be used for verifying the new image as it is
|
|
|
|
// being written. Except in specific circumstances, no value should be
|
|
|
|
// specified, indicating that the shared, system-wide default policy
|
|
|
|
// should be used.
|
|
|
|
SignaturePolicyPath string
|
|
|
|
// ReportWriter is an io.Writer which will be used to log the writing
|
|
|
|
// of the new image.
|
|
|
|
ReportWriter io.Writer
|
|
|
|
// Store is the local storage store which holds the source image.
|
|
|
|
Store storage.Store
|
2017-08-25 05:44:32 +08:00
|
|
|
// github.com/containers/image/types SystemContext to hold credentials
|
|
|
|
// and other authentication/authorization information.
|
|
|
|
SystemContext *types.SystemContext
|
2017-11-10 01:52:50 +08:00
|
|
|
// ManifestType is the format to use when saving the imge using the 'dir' transport
|
|
|
|
// possible options are oci, v2s1, and v2s2
|
|
|
|
ManifestType string
|
2017-06-02 00:11:14 +08:00
|
|
|
}
|
|
|
|
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
// shallowCopy copies the most recent layer, the configuration, and the manifest from one image to another.
|
|
|
|
// For local storage, which doesn't care about histories and the manifest's contents, that's sufficient, but
|
|
|
|
// almost any other destination has higher expectations.
|
|
|
|
// We assume that "dest" is a reference to a local image (specifically, a containers/image/storage.storageReference),
|
|
|
|
// and will fail if it isn't.
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
func (b *Builder) shallowCopy(dest types.ImageReference, src types.ImageReference, systemContext *types.SystemContext) error {
|
2017-06-16 05:36:27 +08:00
|
|
|
var names []string
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
var layerDiff, config io.ReadCloser
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
// Read the target image name.
|
2017-06-16 05:36:27 +08:00
|
|
|
if dest.DockerReference() != nil {
|
|
|
|
names = []string{dest.DockerReference().String()}
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
}
|
2017-06-16 05:36:27 +08:00
|
|
|
// Open the source for reading and the new image for writing.
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
srcImage, err := src.NewImageSource(systemContext)
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error reading configuration to write to image %q", transports.ImageName(dest))
|
|
|
|
}
|
|
|
|
defer srcImage.Close()
|
2017-06-16 05:36:27 +08:00
|
|
|
destImage, err := dest.NewImageDestination(systemContext)
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
2017-06-16 05:36:27 +08:00
|
|
|
return errors.Wrapf(err, "error opening image %q for writing", transports.ImageName(dest))
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
}
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
// Read the newly-generated manifest, which already contains a layer entry for the read-write layer.
|
|
|
|
manifestBlob, manifestType, err := srcImage.GetManifest(nil)
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
return errors.Wrapf(err, "error reading the manifest we just generated")
|
|
|
|
}
|
|
|
|
m, err := manifest.FromBlob(manifestBlob, manifestType)
|
2017-06-29 05:07:58 +08:00
|
|
|
if err != nil {
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
return errors.Wrapf(err, "error parsing the manifest we just generated")
|
|
|
|
}
|
|
|
|
// Read the read-write layer blob.
|
|
|
|
layerInfos := m.LayerInfos()
|
|
|
|
if len(layerInfos) > 0 {
|
|
|
|
layerDiff, _, err = srcImage.GetBlob(layerInfos[len(layerInfos)-1])
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error reading the container's layer")
|
|
|
|
}
|
|
|
|
defer layerDiff.Close()
|
2017-06-29 05:07:58 +08:00
|
|
|
}
|
|
|
|
// Write a copy of the layer as a blob, for the new image to reference.
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
if layerDiff != nil {
|
|
|
|
if _, err = destImage.PutBlob(layerDiff, types.BlobInfo{Digest: "", Size: -1}); err != nil {
|
|
|
|
return errors.Wrapf(err, "error creating new read-only layer from container %q", b.ContainerID)
|
|
|
|
}
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
}
|
|
|
|
// Read the newly-generated configuration blob.
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
configInfo := m.ConfigInfo()
|
|
|
|
if configInfo.Size == 0 {
|
|
|
|
return errors.Wrapf(err, "error reading new configuration info for image %q", transports.ImageName(dest))
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
}
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
config, _, err = srcImage.GetBlob(configInfo)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error reading the new configuration info for image %q", transports.ImageName(dest))
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
}
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
defer config.Close()
|
|
|
|
logrus.Debugf("read configuration blob %q", configInfo.Digest)
|
2017-06-16 05:36:27 +08:00
|
|
|
// Write the configuration to the new image.
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
if _, err = destImage.PutBlob(config, configInfo); err != nil {
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
return errors.Wrapf(err, "error writing image configuration for temporary copy of %q", transports.ImageName(dest))
|
|
|
|
}
|
2017-06-16 05:36:27 +08:00
|
|
|
// Write the manifest to the new image.
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
err = destImage.PutManifest(manifestBlob)
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
2017-06-16 05:36:27 +08:00
|
|
|
return errors.Wrapf(err, "error writing new manifest to image %q", transports.ImageName(dest))
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
}
|
2017-06-16 05:36:27 +08:00
|
|
|
// Save the new image.
|
|
|
|
err = destImage.Commit()
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error committing new image %q", transports.ImageName(dest))
|
|
|
|
}
|
2017-06-16 05:36:27 +08:00
|
|
|
err = destImage.Close()
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
2017-06-16 05:36:27 +08:00
|
|
|
return errors.Wrapf(err, "error closing new image %q", transports.ImageName(dest))
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
}
|
2017-06-29 05:07:58 +08:00
|
|
|
image, err := is.Transport.GetStoreImage(b.store, dest)
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
2017-06-29 05:07:58 +08:00
|
|
|
return errors.Wrapf(err, "error locating just-written image %q", transports.ImageName(dest))
|
2017-06-16 05:36:27 +08:00
|
|
|
}
|
|
|
|
// Add the target name(s) to the new image.
|
|
|
|
if len(names) > 0 {
|
|
|
|
err = util.AddImageNames(b.store, image, names)
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
2017-06-16 05:36:27 +08:00
|
|
|
return errors.Wrapf(err, "error assigning names %v to new image", names)
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
}
|
2017-06-16 05:36:27 +08:00
|
|
|
logrus.Debugf("assigned names %v to image %q", names, image.ID)
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-02-11 03:45:06 +08:00
|
|
|
// Commit writes the contents of the container, along with its updated
|
2017-04-11 02:25:07 +08:00
|
|
|
// configuration, to a new image in the specified location, and if we know how,
|
|
|
|
// add any additional tags that were specified.
|
2017-02-11 00:48:15 +08:00
|
|
|
func (b *Builder) Commit(dest types.ImageReference, options CommitOptions) error {
|
2017-06-29 05:07:58 +08:00
|
|
|
policy, err := signature.DefaultPolicy(getSystemContext(options.SystemContext, options.SignaturePolicyPath))
|
2017-02-11 00:48:15 +08:00
|
|
|
if err != nil {
|
2017-07-29 00:58:29 +08:00
|
|
|
return errors.Wrapf(err, "error obtaining default signature policy")
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|
|
|
|
policyContext, err := signature.NewPolicyContext(policy)
|
|
|
|
if err != nil {
|
2017-07-29 00:58:29 +08:00
|
|
|
return errors.Wrapf(err, "error creating new signature policy context")
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|
2017-07-29 00:58:29 +08:00
|
|
|
defer func() {
|
|
|
|
if err2 := policyContext.Destroy(); err2 != nil {
|
2017-06-29 05:07:58 +08:00
|
|
|
logrus.Debugf("error destroying signature policy context: %v", err2)
|
2017-07-29 00:58:29 +08:00
|
|
|
}
|
|
|
|
}()
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
// Check if we're keeping everything in local storage. If so, we can take certain shortcuts.
|
2017-06-02 00:11:14 +08:00
|
|
|
_, destIsStorage := dest.Transport().(is.StoreTransport)
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
exporting := !destIsStorage
|
2017-06-29 05:07:58 +08:00
|
|
|
src, err := b.makeImageRef(options.PreferredManifestType, exporting, options.Compression, options.HistoryTimestamp)
|
2017-02-11 00:48:15 +08:00
|
|
|
if err != nil {
|
2017-06-02 00:11:14 +08:00
|
|
|
return errors.Wrapf(err, "error computing layer digests and building metadata")
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if exporting {
|
|
|
|
// Copy everything.
|
2017-11-10 01:52:50 +08:00
|
|
|
err = cp.Image(policyContext, dest, src, getCopyOptions(options.ReportWriter, nil, options.SystemContext, ""))
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error copying layers and metadata")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Copy only the most recent layer, the configuration, and the manifest.
|
shallowCopy: avoid a second read of the container's layer
Avoid reading the container's layer a second time in shallowCopy (after
the first time it's read, in NewImageSource()).
Our second copy of the diff isn't going to match the first one if it's
of any serious size, because when NaiveDiff is used to generate the
diff, whiteout entries have their times set to "now", rather than a
fixed value, which causes both the uncompressed and compressed digests
to differ from what NewImageSource() records in the manifest.
Instead, use the generic manifest-reading API that the image library
now provides to read the layer info list and the config blob info, and
use their values to PutBlob() them to the destination image.
We can probably drop shallowCopy() completely, since the newer version
of the image library has a more reliable HasBlob(), which should save us
the time that shallowCopy() was originally meant to save, but we should
probably consider the use of compression for this code path as part of
that, too.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #506
Approved by: rhatdan
2018-03-03 06:30:47 +08:00
|
|
|
err = b.shallowCopy(dest, src, getSystemContext(options.SystemContext, options.SignaturePolicyPath))
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error copying layer and metadata")
|
|
|
|
}
|
2017-05-20 02:13:15 +08:00
|
|
|
}
|
|
|
|
if len(options.AdditionalTags) > 0 {
|
|
|
|
switch dest.Transport().Name() {
|
2017-06-02 00:11:14 +08:00
|
|
|
case is.Transport.Name():
|
|
|
|
img, err := is.Transport.GetStoreImage(b.store, dest)
|
2017-05-20 02:13:15 +08:00
|
|
|
if err != nil {
|
2017-06-02 03:23:02 +08:00
|
|
|
return errors.Wrapf(err, "error locating just-written image %q", transports.ImageName(dest))
|
2017-05-20 02:13:15 +08:00
|
|
|
}
|
|
|
|
err = util.AddImageNames(b.store, img, options.AdditionalTags)
|
|
|
|
if err != nil {
|
2017-06-02 03:23:02 +08:00
|
|
|
return errors.Wrapf(err, "error setting image names to %v", append(img.Names, options.AdditionalTags...))
|
2017-05-20 02:13:15 +08:00
|
|
|
}
|
Take a shortcut when writing to local storage
When writing to local storage, take a couple of shortcuts: instead of
recompressing layers to ensure that the values we store in the image
manifest will be correct for content-addressibility, just pretend that
the layer ID is a blob hash value, and that it's a valid layer diffID.
Local storage doesn't generally care if these values are correct, and we
already have to recompute these values when exporting an image, but this
saves us quite a bit of time.
The image library's Copy() routine actually cares about and
sanity-checks these things, so if we're going to take advantage of the
shortcuts, we need to use its higher-level APIs to write a layer, write
the configuration, and write the manifest, then move those items that it
writes to an image with the right set of layers.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #141
Approved by: rhatdan
2017-06-01 01:56:25 +08:00
|
|
|
logrus.Debugf("assigned names %v to image %q", img.Names, img.ID)
|
2017-05-20 02:13:15 +08:00
|
|
|
default:
|
|
|
|
logrus.Warnf("don't know how to add tags to images stored in %q transport", dest.Transport().Name())
|
2017-04-11 02:25:07 +08:00
|
|
|
}
|
|
|
|
}
|
2017-05-20 02:13:15 +08:00
|
|
|
return nil
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|
2017-06-02 00:11:14 +08:00
|
|
|
|
|
|
|
// Push copies the contents of the image to a new location.
|
|
|
|
func Push(image string, dest types.ImageReference, options PushOptions) error {
|
2017-06-29 05:07:58 +08:00
|
|
|
systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath)
|
2017-06-02 00:11:14 +08:00
|
|
|
policy, err := signature.DefaultPolicy(systemContext)
|
|
|
|
if err != nil {
|
2017-07-29 00:58:29 +08:00
|
|
|
return errors.Wrapf(err, "error obtaining default signature policy")
|
2017-06-02 00:11:14 +08:00
|
|
|
}
|
|
|
|
policyContext, err := signature.NewPolicyContext(policy)
|
|
|
|
if err != nil {
|
2017-07-29 00:58:29 +08:00
|
|
|
return errors.Wrapf(err, "error creating new signature policy context")
|
2017-06-02 00:11:14 +08:00
|
|
|
}
|
2017-06-29 05:07:58 +08:00
|
|
|
// Look up the image.
|
|
|
|
src, err := is.Transport.ParseStoreReference(options.Store, image)
|
2017-06-02 00:11:14 +08:00
|
|
|
if err != nil {
|
2017-06-29 05:07:58 +08:00
|
|
|
return errors.Wrapf(err, "error parsing reference to image %q", image)
|
2017-06-02 00:11:14 +08:00
|
|
|
}
|
|
|
|
// Copy everything.
|
2017-11-10 01:52:50 +08:00
|
|
|
err = cp.Image(policyContext, dest, src, getCopyOptions(options.ReportWriter, nil, options.SystemContext, options.ManifestType))
|
2017-06-02 00:11:14 +08:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error copying layers and metadata")
|
|
|
|
}
|
2017-09-29 23:07:32 +08:00
|
|
|
if options.ReportWriter != nil {
|
|
|
|
fmt.Fprintf(options.ReportWriter, "\n")
|
|
|
|
}
|
2017-06-02 00:11:14 +08:00
|
|
|
return nil
|
|
|
|
}
|