diff --git a/copy/copy.go b/copy/copy.go index f0982b36bc..b560a9b2e4 100644 --- a/copy/copy.go +++ b/copy/copy.go @@ -524,7 +524,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli } } - if err := checkImageDestinationForCurrentRuntimeOS(ctx, options.DestinationCtx, src, c.dest); err != nil { + if err := checkImageDestinationForCurrentRuntime(ctx, options.DestinationCtx, src, c.dest); err != nil { return nil, "", "", err } @@ -651,21 +651,28 @@ func (c *copier) Printf(format string, a ...interface{}) { fmt.Fprintf(c.reportWriter, format, a...) } -func checkImageDestinationForCurrentRuntimeOS(ctx context.Context, sys *types.SystemContext, src types.Image, dest types.ImageDestination) error { +// checkImageDestinationForCurrentRuntime enforces dest.MustMatchRuntimeOS, if necessary. +func checkImageDestinationForCurrentRuntime(ctx context.Context, sys *types.SystemContext, src types.Image, dest types.ImageDestination) error { if dest.MustMatchRuntimeOS() { + c, err := src.OCIConfig(ctx) + if err != nil { + return errors.Wrapf(err, "Error parsing image configuration") + } + wantedOS := runtime.GOOS if sys != nil && sys.OSChoice != "" { wantedOS = sys.OSChoice } - c, err := src.OCIConfig(ctx) - if err != nil { - return errors.Wrapf(err, "Error parsing image configuration") + if wantedOS != c.OS { + return fmt.Errorf("Image operating system mismatch: image uses %q, expecting %q", c.OS, wantedOS) + } + + wantedArch := runtime.GOARCH + if sys != nil && sys.ArchitectureChoice != "" { + wantedArch = sys.ArchitectureChoice } - osErr := fmt.Errorf("image operating system %q cannot be used on %q", c.OS, wantedOS) - if wantedOS == "windows" && c.OS == "linux" { - return osErr - } else if wantedOS != "windows" && c.OS == "windows" { - return osErr + if wantedArch != c.Architecture { + return fmt.Errorf("Image architecture mismatch: image uses %q, expecting %q", c.Architecture, wantedArch) } } return nil diff --git a/directory/directory_dest.go b/directory/directory_dest.go index 2d6650de71..caa7a207fe 100644 --- a/directory/directory_dest.go +++ b/directory/directory_dest.go @@ -112,7 +112,7 @@ func (d *dirImageDestination) AcceptsForeignLayerURLs() bool { return false } -// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise. func (d *dirImageDestination) MustMatchRuntimeOS() bool { return false } diff --git a/docker/daemon/daemon_dest.go b/docker/daemon/daemon_dest.go index 0f27ca5dab..af7418fd11 100644 --- a/docker/daemon/daemon_dest.go +++ b/docker/daemon/daemon_dest.go @@ -90,7 +90,7 @@ func (d *daemonImageDestination) DesiredLayerCompression() types.LayerCompressio return types.PreserveOriginal } -// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise. func (d *daemonImageDestination) MustMatchRuntimeOS() bool { return d.mustMatchRuntimeOS } diff --git a/docker/docker_image_dest.go b/docker/docker_image_dest.go index 417d97aec9..47a73d8686 100644 --- a/docker/docker_image_dest.go +++ b/docker/docker_image_dest.go @@ -94,7 +94,7 @@ func (d *dockerImageDestination) AcceptsForeignLayerURLs() bool { return true } -// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise. func (d *dockerImageDestination) MustMatchRuntimeOS() bool { return false } diff --git a/docker/tarfile/dest.go b/docker/tarfile/dest.go index b8e474dfc4..fa7fad1592 100644 --- a/docker/tarfile/dest.go +++ b/docker/tarfile/dest.go @@ -78,7 +78,7 @@ func (d *Destination) AcceptsForeignLayerURLs() bool { return false } -// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise. func (d *Destination) MustMatchRuntimeOS() bool { return false } diff --git a/oci/archive/oci_dest.go b/oci/archive/oci_dest.go index 6918f7fb0f..33bd731024 100644 --- a/oci/archive/oci_dest.go +++ b/oci/archive/oci_dest.go @@ -66,7 +66,7 @@ func (d *ociArchiveImageDestination) AcceptsForeignLayerURLs() bool { return d.unpackedDest.AcceptsForeignLayerURLs() } -// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise func (d *ociArchiveImageDestination) MustMatchRuntimeOS() bool { return d.unpackedDest.MustMatchRuntimeOS() } diff --git a/oci/layout/oci_dest.go b/oci/layout/oci_dest.go index 370e8d2cd2..fb0449ca52 100644 --- a/oci/layout/oci_dest.go +++ b/oci/layout/oci_dest.go @@ -97,7 +97,7 @@ func (d *ociImageDestination) AcceptsForeignLayerURLs() bool { return true } -// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise. func (d *ociImageDestination) MustMatchRuntimeOS() bool { return false } diff --git a/openshift/openshift.go b/openshift/openshift.go index 016de48034..2fdcc81ab0 100644 --- a/openshift/openshift.go +++ b/openshift/openshift.go @@ -378,7 +378,7 @@ func (d *openshiftImageDestination) AcceptsForeignLayerURLs() bool { return true } -// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise. func (d *openshiftImageDestination) MustMatchRuntimeOS() bool { return false } diff --git a/ostree/ostree_dest.go b/ostree/ostree_dest.go index c442b4d2ee..1150970559 100644 --- a/ostree/ostree_dest.go +++ b/ostree/ostree_dest.go @@ -120,7 +120,7 @@ func (d *ostreeImageDestination) AcceptsForeignLayerURLs() bool { return false } -// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise. func (d *ostreeImageDestination) MustMatchRuntimeOS() bool { return true } diff --git a/storage/storage_image.go b/storage/storage_image.go index 409619b210..35cdfa3bdc 100644 --- a/storage/storage_image.go +++ b/storage/storage_image.go @@ -930,7 +930,7 @@ func (s *storageImageDestination) AcceptsForeignLayerURLs() bool { return false } -// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise. func (s *storageImageDestination) MustMatchRuntimeOS() bool { return true } diff --git a/types/types.go b/types/types.go index 13a8ef78d6..7efcb12928 100644 --- a/types/types.go +++ b/types/types.go @@ -264,7 +264,7 @@ type ImageDestination interface { // AcceptsForeignLayerURLs returns false iff foreign layers in manifest should be actually // uploaded to the image destination, true otherwise. AcceptsForeignLayerURLs() bool - // MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. + // MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime architecture and OS. False otherwise. MustMatchRuntimeOS() bool // IgnoresEmbeddedDockerReference() returns true iff the destination does not care about Image.EmbeddedDockerReferenceConflicts(), // and would prefer to receive an unmodified manifest instead of one modified for the destination.