summaryrefslogtreecommitdiff
path: root/pkg/domain/infra
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain/infra')
-rw-r--r--pkg/domain/infra/abi/manifest.go71
-rw-r--r--pkg/domain/infra/abi/trust.go171
-rw-r--r--pkg/domain/infra/tunnel/manifest.go15
-rw-r--r--pkg/domain/infra/tunnel/trust.go16
4 files changed, 273 insertions, 0 deletions
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go
index 812507f0a..fca34dda2 100644
--- a/pkg/domain/infra/abi/manifest.go
+++ b/pkg/domain/infra/abi/manifest.go
@@ -6,15 +6,21 @@ import (
"context"
"encoding/json"
"fmt"
+ "io/ioutil"
+ "os"
"strings"
+ "github.com/containers/buildah/manifests"
buildahUtil "github.com/containers/buildah/util"
+ cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/docker"
+ "github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/transports/alltransports"
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"
+ imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@@ -137,3 +143,68 @@ func (ir *ImageEngine) ManifestAnnotate(ctx context.Context, names []string, opt
}
return "", err
}
+
+// ManifestRemove removes specified digest from the specified manifest list
+func (ir *ImageEngine) ManifestRemove(ctx context.Context, names []string) (string, error) {
+ instanceDigest, err := digest.Parse(names[1])
+ if err != nil {
+ return "", errors.Errorf(`invalid image digest "%s": %v`, names[1], err)
+ }
+ listImage, err := ir.Libpod.ImageRuntime().NewFromLocal(names[0])
+ if err != nil {
+ return "", errors.Wrapf(err, "error retriving local image from image name %s", names[0])
+ }
+ updatedListID, err := listImage.RemoveManifest(instanceDigest)
+ if err == nil {
+ return fmt.Sprintf("%s :%s\n", updatedListID, instanceDigest.String()), nil
+ }
+ return "", err
+}
+
+// ManifestPush pushes a manifest list or image index to the destination
+func (ir *ImageEngine) ManifestPush(ctx context.Context, names []string, opts entities.ManifestPushOptions) error {
+ listImage, err := ir.Libpod.ImageRuntime().NewFromLocal(names[0])
+ if err != nil {
+ return errors.Wrapf(err, "error retriving local image from image name %s", names[0])
+ }
+ dest, err := alltransports.ParseImageName(names[1])
+ if err != nil {
+ return err
+ }
+ var manifestType string
+ if opts.Format != "" {
+ switch opts.Format {
+ case "oci":
+ manifestType = imgspecv1.MediaTypeImageManifest
+ case "v2s2", "docker":
+ manifestType = manifest.DockerV2Schema2MediaType
+ default:
+ return errors.Errorf("unknown format %q. Choose on of the supported formats: 'oci' or 'v2s2'", opts.Format)
+ }
+ }
+ options := manifests.PushOptions{
+ Store: ir.Libpod.GetStore(),
+ SystemContext: ir.Libpod.SystemContext(),
+ ImageListSelection: cp.CopySpecificImages,
+ Instances: nil,
+ RemoveSignatures: opts.RemoveSignatures,
+ SignBy: opts.SignBy,
+ ManifestType: manifestType,
+ }
+ if opts.All {
+ options.ImageListSelection = cp.CopyAllImages
+ }
+ if !opts.Quiet {
+ options.ReportWriter = os.Stderr
+ }
+ digest, err := listImage.PushManifest(dest, options)
+ if err == nil && opts.Purge {
+ _, err = ir.Libpod.GetStore().DeleteImage(listImage.ID(), true)
+ }
+ if opts.DigestFile != "" {
+ if err = ioutil.WriteFile(opts.DigestFile, []byte(digest.String()), 0644); err != nil {
+ return buildahUtil.GetFailureCause(err, errors.Wrapf(err, "failed to write digest to file %q", opts.DigestFile))
+ }
+ }
+ return err
+}
diff --git a/pkg/domain/infra/abi/trust.go b/pkg/domain/infra/abi/trust.go
new file mode 100644
index 000000000..5b89c91d9
--- /dev/null
+++ b/pkg/domain/infra/abi/trust.go
@@ -0,0 +1,171 @@
+package abi
+
+import (
+ "context"
+ "encoding/json"
+ "io/ioutil"
+ "os"
+ "strings"
+
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/trust"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+func (ir *ImageEngine) ShowTrust(ctx context.Context, args []string, options entities.ShowTrustOptions) (*entities.ShowTrustReport, error) {
+ var (
+ err error
+ report entities.ShowTrustReport
+ )
+ policyPath := trust.DefaultPolicyPath(ir.Libpod.SystemContext())
+ if len(options.PolicyPath) > 0 {
+ policyPath = options.PolicyPath
+ }
+ report.Raw, err = ioutil.ReadFile(policyPath)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to read %s", policyPath)
+ }
+ if options.Raw {
+ return &report, nil
+ }
+ report.SystemRegistriesDirPath = trust.RegistriesDirPath(ir.Libpod.SystemContext())
+ if len(options.RegistryPath) > 0 {
+ report.SystemRegistriesDirPath = options.RegistryPath
+ }
+ policyContentStruct, err := trust.GetPolicy(policyPath)
+ if err != nil {
+ return nil, errors.Wrapf(err, "could not read trust policies")
+ }
+ report.Policies, err = getPolicyShowOutput(policyContentStruct, report.SystemRegistriesDirPath)
+ if err != nil {
+ return nil, errors.Wrapf(err, "could not show trust policies")
+ }
+ return &report, nil
+}
+
+func (ir *ImageEngine) SetTrust(ctx context.Context, args []string, options entities.SetTrustOptions) error {
+ var (
+ policyContentStruct trust.PolicyContent
+ newReposContent []trust.RepoContent
+ )
+ trustType := options.Type
+ if trustType == "accept" {
+ trustType = "insecureAcceptAnything"
+ }
+
+ pubkeysfile := options.PubKeysFile
+ if len(pubkeysfile) == 0 && trustType == "signedBy" {
+ return errors.Errorf("At least one public key must be defined for type 'signedBy'")
+ }
+
+ policyPath := trust.DefaultPolicyPath(ir.Libpod.SystemContext())
+ if len(options.PolicyPath) > 0 {
+ policyPath = options.PolicyPath
+ }
+ _, err := os.Stat(policyPath)
+ if !os.IsNotExist(err) {
+ policyContent, err := ioutil.ReadFile(policyPath)
+ if err != nil {
+ return errors.Wrapf(err, "unable to read %s", policyPath)
+ }
+ if err := json.Unmarshal(policyContent, &policyContentStruct); err != nil {
+ return errors.Errorf("could not read trust policies")
+ }
+ }
+ if len(pubkeysfile) != 0 {
+ for _, filepath := range pubkeysfile {
+ newReposContent = append(newReposContent, trust.RepoContent{Type: trustType, KeyType: "GPGKeys", KeyPath: filepath})
+ }
+ } else {
+ newReposContent = append(newReposContent, trust.RepoContent{Type: trustType})
+ }
+ if args[0] == "default" {
+ policyContentStruct.Default = newReposContent
+ } else {
+ if len(policyContentStruct.Default) == 0 {
+ return errors.Errorf("Default trust policy must be set.")
+ }
+ registryExists := false
+ for transport, transportval := range policyContentStruct.Transports {
+ _, registryExists = transportval[args[0]]
+ if registryExists {
+ policyContentStruct.Transports[transport][args[0]] = newReposContent
+ break
+ }
+ }
+ if !registryExists {
+ if policyContentStruct.Transports == nil {
+ policyContentStruct.Transports = make(map[string]trust.RepoMap)
+ }
+ if policyContentStruct.Transports["docker"] == nil {
+ policyContentStruct.Transports["docker"] = make(map[string][]trust.RepoContent)
+ }
+ policyContentStruct.Transports["docker"][args[0]] = append(policyContentStruct.Transports["docker"][args[0]], newReposContent...)
+ }
+ }
+
+ data, err := json.MarshalIndent(policyContentStruct, "", " ")
+ if err != nil {
+ return errors.Wrapf(err, "error setting trust policy")
+ }
+ return ioutil.WriteFile(policyPath, data, 0644)
+}
+
+func getPolicyShowOutput(policyContentStruct trust.PolicyContent, systemRegistriesDirPath string) ([]*trust.TrustPolicy, error) {
+ var output []*trust.TrustPolicy
+
+ registryConfigs, err := trust.LoadAndMergeConfig(systemRegistriesDirPath)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(policyContentStruct.Default) > 0 {
+ defaultPolicyStruct := trust.TrustPolicy{
+ Name: "* (default)",
+ RepoName: "default",
+ Type: trustTypeDescription(policyContentStruct.Default[0].Type),
+ }
+ output = append(output, &defaultPolicyStruct)
+ }
+ for _, transval := range policyContentStruct.Transports {
+ for repo, repoval := range transval {
+ tempTrustShowOutput := trust.TrustPolicy{
+ Name: repo,
+ RepoName: repo,
+ Type: repoval[0].Type,
+ }
+ // TODO - keyarr is not used and I don't know its intent; commenting out for now for someone to fix later
+ //keyarr := []string{}
+ uids := []string{}
+ for _, repoele := range repoval {
+ if len(repoele.KeyPath) > 0 {
+ //keyarr = append(keyarr, repoele.KeyPath)
+ uids = append(uids, trust.GetGPGIdFromKeyPath(repoele.KeyPath)...)
+ }
+ if len(repoele.KeyData) > 0 {
+ //keyarr = append(keyarr, string(repoele.KeyData))
+ uids = append(uids, trust.GetGPGIdFromKeyData(repoele.KeyData)...)
+ }
+ }
+ tempTrustShowOutput.GPGId = strings.Join(uids, ", ")
+
+ registryNamespace := trust.HaveMatchRegistry(repo, registryConfigs)
+ if registryNamespace != nil {
+ tempTrustShowOutput.SignatureStore = registryNamespace.SigStore
+ }
+ output = append(output, &tempTrustShowOutput)
+ }
+ }
+ return output, nil
+}
+
+var typeDescription = map[string]string{"insecureAcceptAnything": "accept", "signedBy": "signed", "reject": "reject"}
+
+func trustTypeDescription(trustType string) string {
+ trustDescription, exist := typeDescription[trustType]
+ if !exist {
+ logrus.Warnf("invalid trust type %s", trustType)
+ }
+ return trustDescription
+}
diff --git a/pkg/domain/infra/tunnel/manifest.go b/pkg/domain/infra/tunnel/manifest.go
index 3d3196019..7d9a0fce1 100644
--- a/pkg/domain/infra/tunnel/manifest.go
+++ b/pkg/domain/infra/tunnel/manifest.go
@@ -91,3 +91,18 @@ func (ir *ImageEngine) ManifestAnnotate(ctx context.Context, names []string, opt
}
return fmt.Sprintf("%s :%s", updatedListID, names[1]), nil
}
+
+// ManifestRemove removes the digest from manifest list
+func (ir *ImageEngine) ManifestRemove(ctx context.Context, names []string) (string, error) {
+ updatedListID, err := manifests.Remove(ctx, names[0], names[1])
+ if err != nil {
+ return updatedListID, errors.Wrapf(err, "error removing from manifest %s", names[0])
+ }
+ return fmt.Sprintf("%s :%s\n", updatedListID, names[1]), nil
+}
+
+// ManifestPush pushes a manifest list or image index to the destination
+func (ir *ImageEngine) ManifestPush(ctx context.Context, names []string, opts entities.ManifestPushOptions) error {
+ _, err := manifests.Push(ctx, names[0], &names[1], &opts.All)
+ return err
+}
diff --git a/pkg/domain/infra/tunnel/trust.go b/pkg/domain/infra/tunnel/trust.go
new file mode 100644
index 000000000..a976bfdc2
--- /dev/null
+++ b/pkg/domain/infra/tunnel/trust.go
@@ -0,0 +1,16 @@
+package tunnel
+
+import (
+ "context"
+ "errors"
+
+ "github.com/containers/libpod/pkg/domain/entities"
+)
+
+func (ir *ImageEngine) ShowTrust(ctx context.Context, args []string, options entities.ShowTrustOptions) (*entities.ShowTrustReport, error) {
+ return nil, errors.New("not implemented")
+}
+
+func (ir *ImageEngine) SetTrust(ctx context.Context, args []string, options entities.SetTrustOptions) error {
+ return errors.New("not implemented")
+}