mirror of
https://github.com/containers/podman.git
synced 2025-05-20 08:36:23 +08:00
artifact: only allow single manifest
Allowing for multiple manifest per artifact just makes the code and cli design harder to work with it. It is not clear how mounting, extracting or edit on a multi manifest artifact should have worked. A single manifest should make the code much easier to work with. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:

committed by
Matt Heon

parent
d5989990d5
commit
141eae99b8
@ -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