aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQi Wang <qiwan@redhat.com>2020-10-27 17:25:20 -0400
committerQi Wang <qiwan@redhat.com>2020-12-07 09:58:38 -0500
commitcf8f2342a1cdbd821fec217af75c2438c00a9b4d (patch)
treee446ee5ccd991e299d865b9e83e1fdeabf32e411
parentdc5da90523f35146f5368a31be7edf39be13beb4 (diff)
downloadpodman-cf8f2342a1cdbd821fec217af75c2438c00a9b4d.tar.gz
podman-cf8f2342a1cdbd821fec217af75c2438c00a9b4d.tar.bz2
podman-cf8f2342a1cdbd821fec217af75c2438c00a9b4d.zip
image sign using per user registries.d
Support per user ~/.config/containers/registries.d to allow rootless image sign configurations. Signed-off-by: Qi Wang <qiwan@redhat.com>
-rw-r--r--docs/source/markdown/podman-image-sign.1.md10
-rw-r--r--pkg/domain/infra/abi/images.go61
-rw-r--r--pkg/trust/trust.go25
3 files changed, 42 insertions, 54 deletions
diff --git a/docs/source/markdown/podman-image-sign.1.md b/docs/source/markdown/podman-image-sign.1.md
index 1bd6e5b9d..7a924b80b 100644
--- a/docs/source/markdown/podman-image-sign.1.md
+++ b/docs/source/markdown/podman-image-sign.1.md
@@ -9,7 +9,9 @@ podman-image-sign - Create a signature for an image
## DESCRIPTION
**podman image sign** will create a local signature for one or more local images that have
been pulled from a registry. The signature will be written to a directory
-derived from the registry configuration files in /etc/containers/registries.d. By default, the signature will be written into /var/lib/containers/sigstore directory.
+derived from the registry configuration files in `$HOME/.config/containers/registries.d` if it exists,
+otherwise `/etc/containers/registries.d` (unless overridden at compile-time), see **containers-registries.d(5)** for more information.
+By default, the signature will be written into `/var/lib/containers/sigstore` for root and `$HOME/.local/share/containers/sigstore` for non-root users
## OPTIONS
@@ -38,7 +40,8 @@ Sign the busybox image with the identify of foo@bar.com with a user's keyring an
## RELATED CONFIGURATION
The write (and read) location for signatures is defined in YAML-based
-configuration files in /etc/containers/registries.d/. When you sign
+configuration files in /etc/containers/registries.d/ for root,
+or $HOME/.config/containers/registries.d for non-root users. When you sign
an image, Podman will use those configuration files to determine
where to write the signature based on the the name of the originating
registry or a default storage value unless overridden with the --directory
@@ -53,5 +56,8 @@ the signature will be written into sub-directories of
/var/lib/containers/sigstore/privateregistry.example.com. The use of 'sigstore' also means
the signature will be 'read' from that same location on a pull-related function.
+## SEE ALSO
+containers-registries.d(5)
+
## HISTORY
November 2018, Originally compiled by Qi Wang (qiwan at redhat dot com)
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index ff2f2e7ae..57a2bc4cf 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -26,7 +26,6 @@ import (
"github.com/containers/podman/v2/pkg/domain/entities"
domainUtils "github.com/containers/podman/v2/pkg/domain/utils"
"github.com/containers/podman/v2/pkg/rootless"
- "github.com/containers/podman/v2/pkg/trust"
"github.com/containers/podman/v2/pkg/util"
"github.com/containers/storage"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
@@ -34,9 +33,6 @@ import (
"github.com/sirupsen/logrus"
)
-// SignatureStoreDir defines default directory to store signatures
-const SignatureStoreDir = "/var/lib/containers/sigstore"
-
func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.BoolReport, error) {
_, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrID)
if err != nil {
@@ -707,12 +703,6 @@ func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entitie
sc := ir.Libpod.SystemContext()
sc.DockerCertPath = options.CertDir
- systemRegistriesDirPath := trust.RegistriesDirPath(sc)
- registryConfigs, err := trust.LoadAndMergeConfig(systemRegistriesDirPath)
- if err != nil {
- return nil, errors.Wrapf(err, "error reading registry configuration")
- }
-
for _, signimage := range names {
err = func() error {
srcRef, err := alltransports.ParseImageName(signimage)
@@ -738,37 +728,25 @@ func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entitie
}
var sigStoreDir string
if options.Directory != "" {
- sigStoreDir = options.Directory
- }
- if sigStoreDir == "" {
- if rootless.IsRootless() {
- sigStoreDir = filepath.Join(filepath.Dir(ir.Libpod.StorageConfig().GraphRoot), "sigstore")
- } else {
- var sigStoreURI string
- registryInfo := trust.HaveMatchRegistry(rawSource.Reference().DockerReference().String(), registryConfigs)
- if registryInfo != nil {
- if sigStoreURI = registryInfo.SigStoreStaging; sigStoreURI == "" {
- sigStoreURI = registryInfo.SigStore
- }
- }
- if sigStoreURI == "" {
- return errors.Errorf("no signature storage configuration found for %s", rawSource.Reference().DockerReference().String())
-
- }
- sigStoreDir, err = localPathFromURI(sigStoreURI)
- if err != nil {
- return errors.Wrapf(err, "invalid signature storage %s", sigStoreURI)
- }
+ repo := reference.Path(dockerReference)
+ if path.Clean(repo) != repo { // Coverage: This should not be reachable because /./ and /../ components are not valid in docker references
+ return errors.Errorf("Unexpected path elements in Docker reference %s for signature storage", dockerReference.String())
+ }
+ sigStoreDir = filepath.Join(options.Directory, repo)
+ } else {
+ signatureURL, err := docker.SignatureStorageBaseURL(sc, rawSource.Reference(), true)
+ if err != nil {
+ return err
+ }
+ sigStoreDir, err = localPathFromURI(signatureURL)
+ if err != nil {
+ return err
}
}
manifestDigest, err := manifest.Digest(getManifest)
if err != nil {
return err
}
- repo := reference.Path(dockerReference)
- if path.Clean(repo) != repo { // Coverage: This should not be reachable because /./ and /../ components are not valid in docker references
- return errors.Errorf("Unexpected path elements in Docker reference %s for signature storage", dockerReference.String())
- }
// create signature
newSig, err := signature.SignDockerManifest(getManifest, dockerReference.String(), mech, options.SignBy)
@@ -776,7 +754,7 @@ func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entitie
return errors.Wrapf(err, "error creating new signature")
}
// create the signstore file
- signatureDir := fmt.Sprintf("%s@%s=%s", filepath.Join(sigStoreDir, repo), manifestDigest.Algorithm(), manifestDigest.Hex())
+ signatureDir := fmt.Sprintf("%s@%s=%s", sigStoreDir, manifestDigest.Algorithm(), manifestDigest.Hex())
if err := os.MkdirAll(signatureDir, 0751); err != nil {
// The directory is allowed to exist
if !os.IsExist(err) {
@@ -822,14 +800,9 @@ func getSigFilename(sigStoreDirPath string) (string, error) {
}
}
-func localPathFromURI(sigStoreDir string) (string, error) {
- url, err := url.Parse(sigStoreDir)
- if err != nil {
- return sigStoreDir, errors.Wrapf(err, "invalid directory %s", sigStoreDir)
- }
+func localPathFromURI(url *url.URL) (string, error) {
if url.Scheme != "file" {
- return sigStoreDir, errors.Errorf("writing to %s is not supported. Use a supported scheme", sigStoreDir)
+ return "", errors.Errorf("writing to %s is not supported. Use a supported scheme", url.String())
}
- sigStoreDir = url.Path
- return sigStoreDir, nil
+ return url.Path, nil
}
diff --git a/pkg/trust/trust.go b/pkg/trust/trust.go
index a61e0ef10..a30611b74 100644
--- a/pkg/trust/trust.go
+++ b/pkg/trust/trust.go
@@ -12,6 +12,7 @@ import (
"strings"
"github.com/containers/image/v5/types"
+ "github.com/docker/docker/pkg/homedir"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -60,6 +61,12 @@ type ShowOutput struct {
Sigstore string
}
+// systemRegistriesDirPath is the path to registries.d.
+const systemRegistriesDirPath = "/etc/containers/registries.d"
+
+// userRegistriesDir is the path to the per user registries.d.
+var userRegistriesDir = filepath.FromSlash(".config/containers/registries.d")
+
// DefaultPolicyPath returns a path to the default policy of the system.
func DefaultPolicyPath(sys *types.SystemContext) string {
systemDefaultPolicyPath := "/etc/containers/policy.json"
@@ -76,15 +83,17 @@ func DefaultPolicyPath(sys *types.SystemContext) string {
// RegistriesDirPath returns a path to registries.d
func RegistriesDirPath(sys *types.SystemContext) string {
- systemRegistriesDirPath := "/etc/containers/registries.d"
- if sys != nil {
- if sys.RegistriesDirPath != "" {
- return sys.RegistriesDirPath
- }
- if sys.RootForImplicitAbsolutePaths != "" {
- return filepath.Join(sys.RootForImplicitAbsolutePaths, systemRegistriesDirPath)
- }
+ if sys != nil && sys.RegistriesDirPath != "" {
+ return sys.RegistriesDirPath
+ }
+ userRegistriesDirPath := filepath.Join(homedir.Get(), userRegistriesDir)
+ if _, err := os.Stat(userRegistriesDirPath); err == nil {
+ return userRegistriesDirPath
}
+ if sys != nil && sys.RootForImplicitAbsolutePaths != "" {
+ return filepath.Join(sys.RootForImplicitAbsolutePaths, systemRegistriesDirPath)
+ }
+
return systemRegistriesDirPath
}