github.com/AliyunContainerService/cli@v0.0.0-20181009023821-814ced4b30d0/cli/manifest/types/types.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 6 "github.com/docker/distribution" 7 "github.com/docker/distribution/manifest/manifestlist" 8 "github.com/docker/distribution/manifest/schema2" 9 "github.com/docker/distribution/reference" 10 "github.com/opencontainers/go-digest" 11 ocispec "github.com/opencontainers/image-spec/specs-go/v1" 12 "github.com/pkg/errors" 13 ) 14 15 // ImageManifest contains info to output for a manifest object. 16 type ImageManifest struct { 17 Ref *SerializableNamed 18 Descriptor ocispec.Descriptor 19 20 // SchemaV2Manifest is used for inspection 21 // TODO: Deprecate this and store manifest blobs 22 SchemaV2Manifest *schema2.DeserializedManifest `json:",omitempty"` 23 } 24 25 // OCIPlatform creates an OCI platform from a manifest list platform spec 26 func OCIPlatform(ps *manifestlist.PlatformSpec) *ocispec.Platform { 27 if ps == nil { 28 return nil 29 } 30 return &ocispec.Platform{ 31 Architecture: ps.Architecture, 32 OS: ps.OS, 33 OSVersion: ps.OSVersion, 34 OSFeatures: ps.OSFeatures, 35 Variant: ps.Variant, 36 } 37 } 38 39 // PlatformSpecFromOCI creates a platform spec from OCI platform 40 func PlatformSpecFromOCI(p *ocispec.Platform) *manifestlist.PlatformSpec { 41 if p == nil { 42 return nil 43 } 44 return &manifestlist.PlatformSpec{ 45 Architecture: p.Architecture, 46 OS: p.OS, 47 OSVersion: p.OSVersion, 48 OSFeatures: p.OSFeatures, 49 Variant: p.Variant, 50 } 51 } 52 53 // Blobs returns the digests for all the blobs referenced by this manifest 54 func (i ImageManifest) Blobs() []digest.Digest { 55 digests := []digest.Digest{} 56 for _, descriptor := range i.SchemaV2Manifest.References() { 57 digests = append(digests, descriptor.Digest) 58 } 59 return digests 60 } 61 62 // Payload returns the media type and bytes for the manifest 63 func (i ImageManifest) Payload() (string, []byte, error) { 64 // TODO: If available, read content from a content store by digest 65 switch { 66 case i.SchemaV2Manifest != nil: 67 return i.SchemaV2Manifest.Payload() 68 default: 69 return "", nil, errors.Errorf("%s has no payload", i.Ref) 70 } 71 } 72 73 // References implements the distribution.Manifest interface. It delegates to 74 // the underlying manifest. 75 func (i ImageManifest) References() []distribution.Descriptor { 76 switch { 77 case i.SchemaV2Manifest != nil: 78 return i.SchemaV2Manifest.References() 79 default: 80 return nil 81 } 82 } 83 84 // NewImageManifest returns a new ImageManifest object. The values for Platform 85 // are initialized from those in the image 86 func NewImageManifest(ref reference.Named, desc ocispec.Descriptor, manifest *schema2.DeserializedManifest) ImageManifest { 87 return ImageManifest{ 88 Ref: &SerializableNamed{Named: ref}, 89 Descriptor: desc, 90 SchemaV2Manifest: manifest, 91 } 92 } 93 94 // SerializableNamed is a reference.Named that can be serialzied and deserialized 95 // from JSON 96 type SerializableNamed struct { 97 reference.Named 98 } 99 100 // UnmarshalJSON loads the Named reference from JSON bytes 101 func (s *SerializableNamed) UnmarshalJSON(b []byte) error { 102 var raw string 103 if err := json.Unmarshal(b, &raw); err != nil { 104 return errors.Wrapf(err, "invalid named reference bytes: %s", b) 105 } 106 var err error 107 s.Named, err = reference.ParseNamed(raw) 108 return err 109 } 110 111 // MarshalJSON returns the JSON bytes representation 112 func (s *SerializableNamed) MarshalJSON() ([]byte, error) { 113 return json.Marshal(s.String()) 114 }