mirror of
https://github.com/containers/podman.git
synced 2025-10-20 20:54:45 +08:00
Merge pull request #25200 from Luap99/artifact-single-manifest
artifact: only allow single manifest
This commit is contained in:
@ -11,17 +11,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Artifact struct {
|
type Artifact struct {
|
||||||
Manifests []manifest.OCI1
|
// Manifest is the OCI manifest for the artifact with the name.
|
||||||
Name string
|
// In a valid artifact the Manifest is guaranteed to not be nil.
|
||||||
|
Manifest *manifest.OCI1
|
||||||
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// TotalSizeBytes returns the total bytes of the all the artifact layers
|
// TotalSizeBytes returns the total bytes of the all the artifact layers
|
||||||
func (a *Artifact) TotalSizeBytes() int64 {
|
func (a *Artifact) TotalSizeBytes() int64 {
|
||||||
var s int64
|
var s int64
|
||||||
for _, artifact := range a.Manifests {
|
for _, layer := range a.Manifest.Layers {
|
||||||
for _, layer := range artifact.Layers {
|
s += layer.Size
|
||||||
s += layer.Size
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@ -45,13 +45,7 @@ func (a *Artifact) SetName(name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Artifact) GetDigest() (*digest.Digest, error) {
|
func (a *Artifact) GetDigest() (*digest.Digest, error) {
|
||||||
if len(a.Manifests) > 1 {
|
b, err := json.Marshal(a.Manifest)
|
||||||
return nil, fmt.Errorf("not supported: multiple manifests found in artifact")
|
|
||||||
}
|
|
||||||
if len(a.Manifests) < 1 {
|
|
||||||
return nil, fmt.Errorf("not supported: no manifests found in artifact")
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(a.Manifests[0])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -72,17 +66,13 @@ func (al ArtifactList) GetByNameOrDigest(nameOrDigest string) (*Artifact, bool,
|
|||||||
}
|
}
|
||||||
// Before giving up, check by digest
|
// Before giving up, check by digest
|
||||||
for _, artifact := range al {
|
for _, artifact := range al {
|
||||||
// TODO Here we have to assume only a single manifest for the artifact; this will
|
artifactDigest, err := artifact.GetDigest()
|
||||||
// need to evolve
|
if err != nil {
|
||||||
if len(artifact.Manifests) > 0 {
|
return nil, false, err
|
||||||
artifactDigest, err := artifact.GetDigest()
|
}
|
||||||
if err != nil {
|
// If the artifact's digest matches or is a prefix of ...
|
||||||
return nil, false, err
|
if artifactDigest.Encoded() == nameOrDigest || strings.HasPrefix(artifactDigest.Encoded(), nameOrDigest) {
|
||||||
}
|
return artifact, true, nil
|
||||||
// If the artifact's digest matches or is a prefix of ...
|
|
||||||
if artifactDigest.Encoded() == nameOrDigest || strings.HasPrefix(artifactDigest.Encoded(), nameOrDigest) {
|
|
||||||
return artifact, true, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, false, fmt.Errorf("no artifact found with name or digest of %s", nameOrDigest)
|
return nil, false, fmt.Errorf("no artifact found with name or digest of %s", nameOrDigest)
|
||||||
|
@ -299,13 +299,13 @@ func (as ArtifactStore) getArtifacts(ctx context.Context, _ *libartTypes.GetArti
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
manifests, err := getManifests(ctx, imgSrc, nil)
|
manifest, err := getManifest(ctx, imgSrc)
|
||||||
imgSrc.Close()
|
imgSrc.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
artifact := libartifact.Artifact{
|
artifact := libartifact.Artifact{
|
||||||
Manifests: manifests,
|
Manifest: manifest,
|
||||||
}
|
}
|
||||||
if val, ok := l.ManifestDescriptor.Annotations[specV1.AnnotationRefName]; ok {
|
if val, ok := l.ManifestDescriptor.Annotations[specV1.AnnotationRefName]; ok {
|
||||||
artifact.SetName(val)
|
artifact.SetName(val)
|
||||||
@ -316,41 +316,25 @@ func (as ArtifactStore) getArtifacts(ctx context.Context, _ *libartTypes.GetArti
|
|||||||
return al, nil
|
return al, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getManifests takes an imgSrc and starting digest (nil means "top") and collects all the manifests "under"
|
// getManifest takes an imgSrc and returns the manifest for the imgSrc.
|
||||||
// it. this func calls itself recursively with a new startingDigest assuming that we are dealing with
|
// A OCI index list is not supported and will return an error.
|
||||||
// an index list
|
func getManifest(ctx context.Context, imgSrc types.ImageSource) (*manifest.OCI1, error) {
|
||||||
func getManifests(ctx context.Context, imgSrc types.ImageSource, startingDigest *digest.Digest) ([]manifest.OCI1, error) {
|
b, manifestType, err := imgSrc.GetManifest(ctx, nil)
|
||||||
var (
|
|
||||||
manifests []manifest.OCI1
|
|
||||||
)
|
|
||||||
b, manifestType, err := imgSrc.GetManifest(ctx, startingDigest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// this assumes that there are only single, and multi-images
|
// We only support a single flat manifest and not an oci index list
|
||||||
if !manifest.MIMETypeIsMultiImage(manifestType) {
|
if manifest.MIMETypeIsMultiImage(manifestType) {
|
||||||
// these are the keepers
|
return nil, fmt.Errorf("manifest %q is index list", imgSrc.Reference().StringWithinTransport())
|
||||||
mani, err := manifest.OCI1FromManifest(b)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
manifests = append(manifests, *mani)
|
|
||||||
return manifests, nil
|
|
||||||
}
|
}
|
||||||
// We are dealing with an oci index list
|
|
||||||
maniList, err := manifest.OCI1IndexFromManifest(b)
|
// parse the single manifest
|
||||||
|
mani, err := manifest.OCI1FromManifest(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, m := range maniList.Manifests {
|
return mani, nil
|
||||||
iterManifests, err := getManifests(ctx, imgSrc, &m.Digest)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
manifests = append(manifests, iterManifests...)
|
|
||||||
}
|
|
||||||
return manifests, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createEmptyStanza(path string) error {
|
func createEmptyStanza(path string) error {
|
||||||
|
@ -100,9 +100,9 @@ var _ = Describe("Podman artifact", func() {
|
|||||||
err = json.Unmarshal([]byte(inspectSingleSession.OutputToString()), &a)
|
err = json.Unmarshal([]byte(inspectSingleSession.OutputToString()), &a)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(a.Name).To(Equal(artifact1Name))
|
Expect(a.Name).To(Equal(artifact1Name))
|
||||||
Expect(a.Manifests[0].ArtifactType).To(Equal(artifactType))
|
Expect(a.Manifest.ArtifactType).To(Equal(artifactType))
|
||||||
Expect(a.Manifests[0].Layers[0].Annotations["color"]).To(Equal("blue"))
|
Expect(a.Manifest.Layers[0].Annotations["color"]).To(Equal("blue"))
|
||||||
Expect(a.Manifests[0].Layers[0].Annotations["flavor"]).To(Equal("lemon"))
|
Expect(a.Manifest.Layers[0].Annotations["flavor"]).To(Equal("lemon"))
|
||||||
|
|
||||||
failSession := podmanTest.Podman([]string{"artifact", "add", "--annotation", "org.opencontainers.image.title=foobar", "foobar", artifact1File})
|
failSession := podmanTest.Podman([]string{"artifact", "add", "--annotation", "org.opencontainers.image.title=foobar", "foobar", artifact1File})
|
||||||
failSession.WaitWithDefaultTimeout()
|
failSession.WaitWithDefaultTimeout()
|
||||||
@ -128,11 +128,7 @@ var _ = Describe("Podman artifact", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(a.Name).To(Equal(artifact1Name))
|
Expect(a.Name).To(Equal(artifact1Name))
|
||||||
|
|
||||||
var layerCount int
|
Expect(a.Manifest.Layers).To(HaveLen(2))
|
||||||
for _, layer := range a.Manifests {
|
|
||||||
layerCount += len(layer.Layers)
|
|
||||||
}
|
|
||||||
Expect(layerCount).To(Equal(2))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman artifact push and pull", func() {
|
It("podman artifact push and pull", func() {
|
||||||
|
Reference in New Issue
Block a user