github.com/moby/docker@v26.1.3+incompatible/internal/testutils/specialimage/twoplatform.go (about) 1 package specialimage 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "github.com/containerd/containerd/platforms" 8 "github.com/distribution/reference" 9 "github.com/opencontainers/go-digest" 10 "github.com/opencontainers/image-spec/specs-go" 11 ocispec "github.com/opencontainers/image-spec/specs-go/v1" 12 ) 13 14 func TwoPlatform(dir string) (*ocispec.Index, error) { 15 const imageRef = "twoplatform:latest" 16 17 layer1Desc, err := writeLayerWithOneFile(dir, "bash", []byte("layer1")) 18 if err != nil { 19 return nil, err 20 } 21 layer2Desc, err := writeLayerWithOneFile(dir, "bash", []byte("layer2")) 22 if err != nil { 23 return nil, err 24 } 25 26 config1Desc, err := writeJsonBlob(dir, ocispec.MediaTypeImageConfig, ocispec.Image{ 27 Platform: platforms.MustParse("linux/amd64"), 28 Config: ocispec.ImageConfig{ 29 Env: []string{"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}, 30 }, 31 RootFS: ocispec.RootFS{ 32 Type: "layers", 33 DiffIDs: []digest.Digest{layer1Desc.Digest}, 34 }, 35 }) 36 if err != nil { 37 return nil, err 38 } 39 40 manifest1Desc, err := writeJsonBlob(dir, ocispec.MediaTypeImageManifest, ocispec.Manifest{ 41 MediaType: ocispec.MediaTypeImageManifest, 42 Config: config1Desc, 43 Layers: []ocispec.Descriptor{layer1Desc}, 44 }) 45 if err != nil { 46 return nil, err 47 } 48 49 config2Desc, err := writeJsonBlob(dir, ocispec.MediaTypeImageConfig, ocispec.Image{ 50 Platform: platforms.MustParse("linux/arm64"), 51 Config: ocispec.ImageConfig{ 52 Env: []string{"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}, 53 }, 54 RootFS: ocispec.RootFS{ 55 Type: "layers", 56 DiffIDs: []digest.Digest{layer1Desc.Digest}, 57 }, 58 }) 59 if err != nil { 60 return nil, err 61 } 62 63 manifest2Desc, err := writeJsonBlob(dir, ocispec.MediaTypeImageManifest, ocispec.Manifest{ 64 MediaType: ocispec.MediaTypeImageManifest, 65 Config: config2Desc, 66 Layers: []ocispec.Descriptor{layer2Desc}, 67 }) 68 if err != nil { 69 return nil, err 70 } 71 72 index := ocispec.Index{ 73 Versioned: specs.Versioned{SchemaVersion: 2}, 74 MediaType: ocispec.MediaTypeImageIndex, 75 Manifests: []ocispec.Descriptor{manifest1Desc, manifest2Desc}, 76 } 77 78 ref, err := reference.ParseNormalizedNamed(imageRef) 79 if err != nil { 80 return nil, err 81 } 82 return multiPlatformImage(dir, ref, index) 83 } 84 85 func multiPlatformImage(dir string, ref reference.Named, target ocispec.Index) (*ocispec.Index, error) { 86 targetDesc, err := writeJsonBlob(dir, ocispec.MediaTypeImageIndex, target) 87 if err != nil { 88 return nil, err 89 } 90 91 if ref != nil { 92 targetDesc.Annotations = map[string]string{ 93 "io.containerd.image.name": ref.String(), 94 } 95 96 if tagged, ok := ref.(reference.Tagged); ok { 97 targetDesc.Annotations[ocispec.AnnotationRefName] = tagged.Tag() 98 } 99 } 100 101 index := ocispec.Index{ 102 Versioned: specs.Versioned{SchemaVersion: 2}, 103 MediaType: ocispec.MediaTypeImageIndex, 104 Manifests: []ocispec.Descriptor{targetDesc}, 105 } 106 107 if err := writeJson(index, filepath.Join(dir, "index.json")); err != nil { 108 return nil, err 109 } 110 111 err = os.WriteFile(filepath.Join(dir, "oci-layout"), []byte(`{"imageLayoutVersion": "1.0.0"}`), 0o644) 112 if err != nil { 113 return nil, err 114 } 115 116 return &index, nil 117 }