Skip to content

Commit

Permalink
Support per user registries.d
Browse files Browse the repository at this point in the history
Support per user  ~/.config/containers/registries.d to allow rootless podman push image sign.

Signed-off-by: Qi Wang <qiwan@redhat.com>
  • Loading branch information
QiWang19 committed Aug 24, 2020
1 parent 8ad4121 commit e5c4679
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 15 deletions.
21 changes: 14 additions & 7 deletions docker/lookaside.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/types"
"github.com/containers/storage/pkg/homedir"
"github.com/ghodss/yaml"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
Expand All @@ -26,6 +27,9 @@ var systemRegistriesDirPath = builtinRegistriesDirPath
// DO NOT change this, instead see systemRegistriesDirPath above.
const builtinRegistriesDirPath = "/etc/containers/registries.d"

// userRegistriesDirPath is the path to the per user registries.d.
var userRegistriesDir = filepath.FromSlash(".config/containers/registries.d")

// registryConfiguration is one of the files in registriesDirPath configuring lookaside locations, or the result of merging them all.
// NOTE: Keep this in sync with docs/registries.d.md!
type registryConfiguration struct {
Expand Down Expand Up @@ -75,14 +79,17 @@ func configuredSignatureStorageBase(sys *types.SystemContext, ref dockerReferenc

// registriesDirPath returns a path to registries.d
func registriesDirPath(sys *types.SystemContext) string {
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
}

Expand Down
51 changes: 44 additions & 7 deletions docker/lookaside_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,36 @@ func TestRegistriesDirPath(t *testing.T) {
const nondefaultPath = "/this/is/not/the/default/registries.d"
const variableReference = "$HOME"
const rootPrefix = "/root/prefix"

oldHomeEnv, hasHomeEnv := os.LookupEnv("HOME")
tempHome, err := ioutil.TempDir("", "tempHome")
require.NoError(t, err)
err = os.Setenv("HOME", tempHome)
require.NoError(t, err)
defer func() {
os.RemoveAll(tempHome)
if hasHomeEnv {
os.Setenv("HOME", oldHomeEnv)
} else {
os.Unsetenv("HOME")
}
}()
var userRegistriesDir = filepath.FromSlash(".config/containers/registries.d")
userRegistriesDirPath := filepath.Join(tempHome, userRegistriesDir)
for _, c := range []struct {
sys *types.SystemContext
expected string
sys *types.SystemContext
userFilePresent bool
expected string
}{
// The common case
{nil, systemRegistriesDirPath},
{nil, false, systemRegistriesDirPath},
// There is a context, but it does not override the path.
{&types.SystemContext{}, systemRegistriesDirPath},
{&types.SystemContext{}, false, systemRegistriesDirPath},
// Path overridden
{&types.SystemContext{RegistriesDirPath: nondefaultPath}, nondefaultPath},
{&types.SystemContext{RegistriesDirPath: nondefaultPath}, false, nondefaultPath},
// Root overridden
{
&types.SystemContext{RootForImplicitAbsolutePaths: rootPrefix},
false,
filepath.Join(rootPrefix, systemRegistriesDirPath),
},
// Root and path overrides present simultaneously,
Expand All @@ -75,11 +91,32 @@ func TestRegistriesDirPath(t *testing.T) {
RootForImplicitAbsolutePaths: rootPrefix,
RegistriesDirPath: nondefaultPath,
},
false,
nondefaultPath,
},
// User registries.d present, not overridden
{&types.SystemContext{}, true, userRegistriesDirPath},
// Context and user User registries.d preset simultaneously
{&types.SystemContext{RegistriesDirPath: nondefaultPath}, true, nondefaultPath},
// Root and user registries.d overrides present simultaneously,
{
&types.SystemContext{
RootForImplicitAbsolutePaths: rootPrefix,
RegistriesDirPath: nondefaultPath,
},
true,
nondefaultPath,
},
// No environment expansion happens in the overridden paths
{&types.SystemContext{RegistriesDirPath: variableReference}, variableReference},
{&types.SystemContext{RegistriesDirPath: variableReference}, false, variableReference},
} {
if c.userFilePresent {
err := os.MkdirAll(userRegistriesDirPath, 0700)
require.NoError(t, err)
} else {
err := os.RemoveAll(userRegistriesDirPath)
require.NoError(t, err)
}
path := registriesDirPath(c.sys)
assert.Equal(t, c.expected, path)
}
Expand Down
2 changes: 1 addition & 1 deletion docs/containers-registries.d.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The registries configuration directory contains configuration for various regist
so that the configuration does not have to be provided in command-line options over and over for every command,
and so that it can be shared by all users of containers/image.

By default (unless overridden at compile-time), the registries configuration directory is `/etc/containers/registries.d`;
By default, the registries configuration directory is `$HOME/.config/containers/registries.d` if it exists, otherwise `/etc/containers/registries.d` (unless overridden at compile-time);
applications may allow using a different directory instead.

## Directory Structure
Expand Down

0 comments on commit e5c4679

Please sign in to comment.