From 6d3f523c5723082e5745ef473cf4f4073fb6ea6d Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Tue, 6 Jun 2017 13:22:58 +0200 Subject: [PATCH] fail early when image os doesn't match host os Signed-off-by: Antonio Murdaca --- integration/copy_test.go | 5 +++ vendor.conf | 2 +- .../github.com/containers/image/copy/copy.go | 21 +++++++++++ .../image/directory/directory_dest.go | 5 +++ .../image/docker/daemon/daemon_dest.go | 5 +++ .../image/docker/docker_image_dest.go | 5 +++ .../containers/image/docker/tarfile/dest.go | 5 +++ .../containers/image/oci/layout/oci_dest.go | 5 +++ .../containers/image/openshift/openshift.go | 5 +++ .../containers/image/ostree/ostree_dest.go | 5 +++ .../containers/image/storage/storage_image.go | 14 +++++++- .../containers/image/types/types.go | 4 +-- .../github.com/containers/image/vendor.conf | 36 +++++++++++++++++++ 13 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 vendor/github.com/containers/image/vendor.conf diff --git a/integration/copy_test.go b/integration/copy_test.go index 43a4d4aa..e42908e2 100644 --- a/integration/copy_test.go +++ b/integration/copy_test.go @@ -91,6 +91,11 @@ func (s *CopySuite) TestCopyFailsWithManifestList(c *check.C) { assertSkopeoFails(c, ".*can not copy docker://estesp/busybox:latest: manifest contains multiple images.*", "copy", "docker://estesp/busybox:latest", "dir:somedir") } +func (s *CopySuite) TestCopyFailsWhenImageOSDoesntMatchRuntimeOS(c *check.C) { + c.Skip("can't run this on Travis") + assertSkopeoFails(c, `.*image operating system "windows" cannot be used on "linux".*`, "copy", "docker://microsoft/windowsservercore", "containers-storage:test") +} + func (s *CopySuite) TestCopySimpleAtomicRegistry(c *check.C) { dir1, err := ioutil.TempDir("", "copy-1") c.Assert(err, check.IsNil) diff --git a/vendor.conf b/vendor.conf index 490c037b..ac61d19c 100644 --- a/vendor.conf +++ b/vendor.conf @@ -43,6 +43,6 @@ github.com/imdario/mergo 6633656539c1639d9d78127b7d47c622b5d7b6dc github.com/mistifyio/go-zfs 22c9b32c84eb0d0c6f4043b6e90fc94073de92fa github.com/pborman/uuid v1.0 github.com/opencontainers/selinux master -golang.org/x/sys/unix master +golang.org/x/sys master github.com/tchap/go-patricia v2.2.6 github.com/BurntSushi/toml master diff --git a/vendor/github.com/containers/image/copy/copy.go b/vendor/github.com/containers/image/copy/copy.go index fd131765..a8afcc9e 100644 --- a/vendor/github.com/containers/image/copy/copy.go +++ b/vendor/github.com/containers/image/copy/copy.go @@ -7,6 +7,7 @@ import ( "io" "io/ioutil" "reflect" + "runtime" "strings" "time" @@ -157,6 +158,10 @@ func Image(policyContext *signature.PolicyContext, destRef, srcRef types.ImageRe } }() + if err := checkImageDestinationForCurrentRuntimeOS(src, dest); err != nil { + return err + } + if src.IsMultiImage() { return errors.Errorf("can not copy %s: manifest contains multiple images", transports.ImageName(srcRef)) } @@ -277,6 +282,22 @@ func Image(policyContext *signature.PolicyContext, destRef, srcRef types.ImageRe return nil } +func checkImageDestinationForCurrentRuntimeOS(src types.Image, dest types.ImageDestination) error { + if dest.MustMatchRuntimeOS() { + c, err := src.OCIConfig() + if err != nil { + return errors.Wrapf(err, "Error parsing image configuration") + } + osErr := fmt.Errorf("image operating system %q cannot be used on %q", c.OS, runtime.GOOS) + if runtime.GOOS == "windows" && c.OS == "linux" { + return osErr + } else if runtime.GOOS != "windows" && c.OS == "windows" { + return osErr + } + } + return nil +} + // updateEmbeddedDockerReference handles the Docker reference embedded in Docker schema1 manifests. func updateEmbeddedDockerReference(manifestUpdates *types.ManifestUpdateOptions, dest types.ImageDestination, src types.Image, canModifyManifest bool) error { destRef := dest.Reference().DockerReference() diff --git a/vendor/github.com/containers/image/directory/directory_dest.go b/vendor/github.com/containers/image/directory/directory_dest.go index c0f5d977..ea46a27e 100644 --- a/vendor/github.com/containers/image/directory/directory_dest.go +++ b/vendor/github.com/containers/image/directory/directory_dest.go @@ -51,6 +51,11 @@ 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. +func (d *dirImageDestination) MustMatchRuntimeOS() bool { + return false +} + // PutBlob writes contents of stream and returns data representing the result (with all data filled in). // inputInfo.Digest can be optionally provided if known; it is not mandatory for the implementation to verify it. // inputInfo.Size is the expected length of stream, if known. diff --git a/vendor/github.com/containers/image/docker/daemon/daemon_dest.go b/vendor/github.com/containers/image/docker/daemon/daemon_dest.go index 3c20acba..31cb2eac 100644 --- a/vendor/github.com/containers/image/docker/daemon/daemon_dest.go +++ b/vendor/github.com/containers/image/docker/daemon/daemon_dest.go @@ -78,6 +78,11 @@ func imageLoadGoroutine(ctx context.Context, c *client.Client, reader *io.PipeRe defer resp.Body.Close() } +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +func (d *daemonImageDestination) MustMatchRuntimeOS() bool { + return true +} + // Close removes resources associated with an initialized ImageDestination, if any. func (d *daemonImageDestination) Close() error { if !d.committed { diff --git a/vendor/github.com/containers/image/docker/docker_image_dest.go b/vendor/github.com/containers/image/docker/docker_image_dest.go index 155aa14f..a3a4ca39 100644 --- a/vendor/github.com/containers/image/docker/docker_image_dest.go +++ b/vendor/github.com/containers/image/docker/docker_image_dest.go @@ -99,6 +99,11 @@ 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. +func (d *dockerImageDestination) MustMatchRuntimeOS() bool { + return false +} + // sizeCounter is an io.Writer which only counts the total size of its input. type sizeCounter struct{ size int64 } diff --git a/vendor/github.com/containers/image/docker/tarfile/dest.go b/vendor/github.com/containers/image/docker/tarfile/dest.go index 6a8ff2fe..537450fe 100644 --- a/vendor/github.com/containers/image/docker/tarfile/dest.go +++ b/vendor/github.com/containers/image/docker/tarfile/dest.go @@ -81,6 +81,11 @@ 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. +func (d *Destination) MustMatchRuntimeOS() bool { + return false +} + // PutBlob writes contents of stream and returns data representing the result (with all data filled in). // inputInfo.Digest can be optionally provided if known; it is not mandatory for the implementation to verify it. // inputInfo.Size is the expected length of stream, if known. diff --git a/vendor/github.com/containers/image/oci/layout/oci_dest.go b/vendor/github.com/containers/image/oci/layout/oci_dest.go index 0c571531..05367309 100644 --- a/vendor/github.com/containers/image/oci/layout/oci_dest.go +++ b/vendor/github.com/containers/image/oci/layout/oci_dest.go @@ -66,6 +66,11 @@ func (d *ociImageDestination) AcceptsForeignLayerURLs() bool { return false } +// MustMatchRuntimeOS returns true iff the destination can store only images targeted for the current runtime OS. False otherwise. +func (d *ociImageDestination) MustMatchRuntimeOS() bool { + return false +} + // PutBlob writes contents of stream and returns data representing the result (with all data filled in). // inputInfo.Digest can be optionally provided if known; it is not mandatory for the implementation to verify it. // inputInfo.Size is the expected length of stream, if known. diff --git a/vendor/github.com/containers/image/openshift/openshift.go b/vendor/github.com/containers/image/openshift/openshift.go index 93802f4d..88659212 100644 --- a/vendor/github.com/containers/image/openshift/openshift.go +++ b/vendor/github.com/containers/image/openshift/openshift.go @@ -358,6 +358,11 @@ 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. +func (d *openshiftImageDestination) MustMatchRuntimeOS() bool { + return false +} + // PutBlob writes contents of stream and returns data representing the result (with all data filled in). // inputInfo.Digest can be optionally provided if known; it is not mandatory for the implementation to verify it. // inputInfo.Size is the expected length of stream, if known. diff --git a/vendor/github.com/containers/image/ostree/ostree_dest.go b/vendor/github.com/containers/image/ostree/ostree_dest.go index 8a247370..80be2241 100644 --- a/vendor/github.com/containers/image/ostree/ostree_dest.go +++ b/vendor/github.com/containers/image/ostree/ostree_dest.go @@ -86,6 +86,11 @@ 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. +func (d *ostreeImageDestination) MustMatchRuntimeOS() bool { + return true +} + func (d *ostreeImageDestination) PutBlob(stream io.Reader, inputInfo types.BlobInfo) (types.BlobInfo, error) { tmpDir, err := ioutil.TempDir(d.tmpDirPath, "blob") if err != nil { diff --git a/vendor/github.com/containers/image/storage/storage_image.go b/vendor/github.com/containers/image/storage/storage_image.go index 1d7bc164..6ad12b21 100644 --- a/vendor/github.com/containers/image/storage/storage_image.go +++ b/vendor/github.com/containers/image/storage/storage_image.go @@ -416,8 +416,15 @@ func (s *storageImageDestination) Commit() error { return nil } +var manifestMIMETypes = []string{ + // TODO(runcom): we'll add OCI as part of another PR here + manifest.DockerV2Schema2MediaType, + manifest.DockerV2Schema1SignedMediaType, + manifest.DockerV2Schema1MediaType, +} + func (s *storageImageDestination) SupportedManifestMIMETypes() []string { - return nil + return manifestMIMETypes } // PutManifest writes manifest to the destination. @@ -442,6 +449,11 @@ 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. +func (s *storageImageDestination) MustMatchRuntimeOS() bool { + return true +} + func (s *storageImageDestination) PutSignatures(signatures [][]byte) error { sizes := []int{} sigblob := []byte{} diff --git a/vendor/github.com/containers/image/types/types.go b/vendor/github.com/containers/image/types/types.go index 6d571c17..0788904c 100644 --- a/vendor/github.com/containers/image/types/types.go +++ b/vendor/github.com/containers/image/types/types.go @@ -148,11 +148,11 @@ type ImageDestination interface { SupportsSignatures() error // ShouldCompressLayers returns true iff it is desirable to compress layer blobs written to this destination. ShouldCompressLayers() bool - // 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() bool // PutBlob writes contents of stream and returns data representing the result (with all data filled in). // inputInfo.Digest can be optionally provided if known; it is not mandatory for the implementation to verify it. // inputInfo.Size is the expected length of stream, if known. diff --git a/vendor/github.com/containers/image/vendor.conf b/vendor/github.com/containers/image/vendor.conf new file mode 100644 index 00000000..6568715f --- /dev/null +++ b/vendor/github.com/containers/image/vendor.conf @@ -0,0 +1,36 @@ +github.com/Sirupsen/logrus 7f4b1adc791766938c29457bed0703fb9134421a +github.com/containers/storage 29d2c86eadb88a0cbfbbedec8762126a3987d4c3 +github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 +github.com/docker/distribution df5327f76fb6468b84a87771e361762b8be23fdb +github.com/docker/docker 75843d36aa5c3eaade50da005f9e0ff2602f3d5e +github.com/docker/go-connections 7da10c8c50cad14494ec818dcdfb6506265c0086 +github.com/docker/go-units 0dadbb0345b35ec7ef35e228dabb8de89a65bf52 +github.com/docker/libtrust aabc10ec26b754e797f9028f4589c5b7bd90dc20 +github.com/ghodss/yaml 04f313413ffd65ce25f2541bfd2b2ceec5c0908c +github.com/gorilla/context 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 +github.com/gorilla/mux 94e7d24fd285520f3d12ae998f7fdd6b5393d453 +github.com/imdario/mergo 50d4dbd4eb0e84778abe37cefef140271d96fade +github.com/mattn/go-runewidth 14207d285c6c197daabb5c9793d63e7af9ab2d50 +github.com/mattn/go-shellwords 005a0944d84452842197c2108bd9168ced206f78 +github.com/mistifyio/go-zfs c0224de804d438efd11ea6e52ada8014537d6062 +github.com/mtrmac/gpgme b2432428689ca58c2b8e8dea9449d3295cf96fc9 +github.com/opencontainers/go-digest aa2ec055abd10d26d539eb630a92241b781ce4bc +github.com/opencontainers/image-spec v1.0.0-rc6 +github.com/opencontainers/runc 6b1d0e76f239ffb435445e5ae316d2676c07c6e3 +github.com/pborman/uuid 1b00554d822231195d1babd97ff4a781231955c9 +github.com/pkg/errors 248dadf4e9068a0b3e79f02ed0a610d935de5302 +github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2 +github.com/stretchr/testify 4d4bfba8f1d1027c4fdbe371823030df51419987 +github.com/vbatts/tar-split bd4c5d64c3e9297f410025a3b1bd0c58f659e721 +golang.org/x/crypto 453249f01cfeb54c3d549ddb75ff152ca243f9d8 +golang.org/x/net 6b27048ae5e6ad1ef927e72e437531493de612fe +golang.org/x/sys 075e574b89e4c2d22f2286a7e2b919519c6f3547 +gopkg.in/cheggaaa/pb.v1 d7e6ca3010b6f084d8056847f55d7f572f180678 +gopkg.in/yaml.v2 a3f3340b5840cee44f372bddb5880fcbc419b46a +k8s.io/client-go bcde30fb7eaed76fd98a36b4120321b94995ffb6 +github.com/xeipuuv/gojsonschema master +github.com/xeipuuv/gojsonreference master +github.com/xeipuuv/gojsonpointer master +github.com/tchap/go-patricia v2.2.6 +github.com/opencontainers/selinux ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d +github.com/BurntSushi/toml b26d9c308763d68093482582cea63d69be07a0f0