summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/bindings/manifests/manifests.go21
-rw-r--r--pkg/bindings/test/manifests_test.go20
-rw-r--r--pkg/domain/entities/engine_image.go1
-rw-r--r--pkg/domain/entities/manifest.go10
-rw-r--r--pkg/domain/infra/abi/manifest.go39
-rw-r--r--pkg/domain/infra/tunnel/manifest.go29
6 files changed, 119 insertions, 1 deletions
diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go
index a8d1e6ca3..b85169410 100644
--- a/pkg/bindings/manifests/manifests.go
+++ b/pkg/bindings/manifests/manifests.go
@@ -124,3 +124,24 @@ func Push(ctx context.Context, name string, destination *string, all *bool) (str
}
return idr.ID, response.Process(&idr)
}
+
+// Annotate updates the image configuration of a given manifest list
+func Annotate(ctx context.Context, name, digest string, options image.ManifestAnnotateOpts) (string, error) {
+ var idr handlers.IDResponse
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return "", err
+ }
+ params := url.Values{}
+ params.Set("digest", digest)
+ optionsString, err := jsoniter.MarshalToString(options)
+ if err != nil {
+ return "", err
+ }
+ stringReader := strings.NewReader(optionsString)
+ response, err := conn.DoRequest(stringReader, http.MethodPost, "/manifests/%s/annotate", params, name)
+ if err != nil {
+ return "", err
+ }
+ return idr.ID, response.Process(&idr)
+}
diff --git a/pkg/bindings/test/manifests_test.go b/pkg/bindings/test/manifests_test.go
index 4987dfe5b..ddb75865c 100644
--- a/pkg/bindings/test/manifests_test.go
+++ b/pkg/bindings/test/manifests_test.go
@@ -118,6 +118,26 @@ var _ = Describe("Podman containers ", func() {
Expect(len(data.Manifests)).To(BeZero())
})
+ It("annotate manifest", func() {
+ id, err := manifests.Create(bt.conn, []string{"quay.io/libpod/foobar:latest"}, []string{}, nil)
+ Expect(err).To(BeNil())
+ opts := image.ManifestAddOpts{Images: []string{"docker.io/library/alpine:latest"}}
+
+ _, err = manifests.Add(bt.conn, id, opts)
+ Expect(err).To(BeNil())
+ data, err := manifests.Inspect(bt.conn, id)
+ Expect(err).To(BeNil())
+ Expect(len(data.Manifests)).To(BeNumerically("==", 1))
+ digest := data.Manifests[0].Digest.String()
+ annoOpts := image.ManifestAnnotateOpts{OS: "foo"}
+ _, err = manifests.Annotate(bt.conn, id, digest, annoOpts)
+ Expect(err).To(BeNil())
+ list, err := manifests.Inspect(bt.conn, id)
+ Expect(err).To(BeNil())
+ Expect(len(list.Manifests)).To(BeNumerically("==", 1))
+ Expect(list.Manifests[0].Platform.OS).To(Equal("foo"))
+ })
+
It("push manifest", func() {
Skip("TODO")
})
diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go
index 45686ec79..c46ba815a 100644
--- a/pkg/domain/entities/engine_image.go
+++ b/pkg/domain/entities/engine_image.go
@@ -29,4 +29,5 @@ type ImageEngine interface {
ManifestCreate(ctx context.Context, names, images []string, opts ManifestCreateOptions) (string, error)
ManifestInspect(ctx context.Context, name string) ([]byte, error)
ManifestAdd(ctx context.Context, opts ManifestAddOptions) (string, error)
+ ManifestAnnotate(ctx context.Context, names []string, opts ManifestAnnotateOptions) (string, error)
}
diff --git a/pkg/domain/entities/manifest.go b/pkg/domain/entities/manifest.go
index 7316735b0..d92b1dc9b 100644
--- a/pkg/domain/entities/manifest.go
+++ b/pkg/domain/entities/manifest.go
@@ -14,3 +14,13 @@ type ManifestAddOptions struct {
OSVersion string `json:"os_version" schema:"os_version"`
Variant string `json:"variant" schema:"variant"`
}
+
+type ManifestAnnotateOptions struct {
+ Annotation []string `json:"annotation"`
+ Arch string `json:"arch" schema:"arch"`
+ Features []string `json:"features" schema:"features"`
+ OS string `json:"os" schema:"os"`
+ OSFeatures []string `json:"os_features" schema:"os_features"`
+ OSVersion string `json:"os_version" schema:"os_version"`
+ Variant string `json:"variant" schema:"variant"`
+}
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go
index 88331f96c..812507f0a 100644
--- a/pkg/domain/infra/abi/manifest.go
+++ b/pkg/domain/infra/abi/manifest.go
@@ -14,6 +14,7 @@ import (
libpodImage "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/util"
+ "github.com/opencontainers/go-digest"
"github.com/pkg/errors"
)
@@ -71,7 +72,7 @@ func (ir *ImageEngine) ManifestAdd(ctx context.Context, opts entities.ManifestAd
}
listImage, err := ir.Libpod.ImageRuntime().NewFromLocal(listImageSpec)
if err != nil {
- return "", errors.Wrapf(err, "error retriving local image from image name %s", listImageSpec)
+ return "", errors.Wrapf(err, "error retrieving local image from image name %s", listImageSpec)
}
manifestAddOpts := libpodImage.ManifestAddOpts{
@@ -100,3 +101,39 @@ func (ir *ImageEngine) ManifestAdd(ctx context.Context, opts entities.ManifestAd
}
return listID, nil
}
+
+// ManifestAnnotate updates an entry of the manifest list
+func (ir *ImageEngine) ManifestAnnotate(ctx context.Context, names []string, opts entities.ManifestAnnotateOptions) (string, error) {
+ listImage, err := ir.Libpod.ImageRuntime().NewFromLocal(names[0])
+ if err != nil {
+ return "", errors.Wrapf(err, "error retreiving local image from image name %s", names[0])
+ }
+ digest, err := digest.Parse(names[1])
+ if err != nil {
+ return "", errors.Errorf(`invalid image digest "%s": %v`, names[1], err)
+ }
+ manifestAnnotateOpts := libpodImage.ManifestAnnotateOpts{
+ Arch: opts.Arch,
+ Features: opts.Features,
+ OS: opts.OS,
+ OSFeatures: opts.OSFeatures,
+ OSVersion: opts.OSVersion,
+ Variant: opts.Variant,
+ }
+ if len(opts.Annotation) > 0 {
+ annotations := make(map[string]string)
+ for _, annotationSpec := range opts.Annotation {
+ spec := strings.SplitN(annotationSpec, "=", 2)
+ if len(spec) != 2 {
+ return "", errors.Errorf("no value given for annotation %q", spec[0])
+ }
+ annotations[spec[0]] = spec[1]
+ }
+ manifestAnnotateOpts.Annotation = annotations
+ }
+ updatedListID, err := listImage.AnnotateManifest(*ir.Libpod.SystemContext(), digest, manifestAnnotateOpts)
+ if err == nil {
+ return fmt.Sprintf("%s: %s", updatedListID, digest.String()), nil
+ }
+ return "", err
+}
diff --git a/pkg/domain/infra/tunnel/manifest.go b/pkg/domain/infra/tunnel/manifest.go
index 18b400533..3d3196019 100644
--- a/pkg/domain/infra/tunnel/manifest.go
+++ b/pkg/domain/infra/tunnel/manifest.go
@@ -3,6 +3,7 @@ package tunnel
import (
"context"
"encoding/json"
+ "fmt"
"strings"
"github.com/containers/libpod/libpod/image"
@@ -62,3 +63,31 @@ func (ir *ImageEngine) ManifestAdd(ctx context.Context, opts entities.ManifestAd
}
return listID, nil
}
+
+// ManifestAnnotate updates an entry of the manifest list
+func (ir *ImageEngine) ManifestAnnotate(ctx context.Context, names []string, opts entities.ManifestAnnotateOptions) (string, error) {
+ manifestAnnotateOpts := image.ManifestAnnotateOpts{
+ Arch: opts.Arch,
+ Features: opts.Features,
+ OS: opts.OS,
+ OSFeatures: opts.OSFeatures,
+ OSVersion: opts.OSVersion,
+ Variant: opts.Variant,
+ }
+ if len(opts.Annotation) > 0 {
+ annotations := make(map[string]string)
+ for _, annotationSpec := range opts.Annotation {
+ spec := strings.SplitN(annotationSpec, "=", 2)
+ if len(spec) != 2 {
+ return "", errors.Errorf("no value given for annotation %q", spec[0])
+ }
+ annotations[spec[0]] = spec[1]
+ }
+ manifestAnnotateOpts.Annotation = annotations
+ }
+ updatedListID, err := manifests.Annotate(ctx, names[0], names[1], manifestAnnotateOpts)
+ if err != nil {
+ return updatedListID, errors.Wrapf(err, "error annotating %s of manifest list %s", names[1], names[0])
+ }
+ return fmt.Sprintf("%s :%s", updatedListID, names[1]), nil
+}