Skip to content

Commit

Permalink
registries.conf.d: add stances for the registries.conf
Browse files Browse the repository at this point in the history
When loading the registries.conf, allow for loading additional files
from `/etc/containers/registries.conf.d`.  The files are loaded in
alpha-numerical order and specified fields will overwrite the previous
config.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
  • Loading branch information
vrothberg committed Mar 2, 2020
1 parent 143904c commit eee0de5
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 19 deletions.
33 changes: 33 additions & 0 deletions docs/containers-registries.conf.d.5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
% CONTAINERS-REGISTRIES.CONF.D(5)
% Valentin Rothberg
% Mar 2020

# NAME
containers-registries.conf.d - directory for drop-in registries.conf files

# DESCRIPTION
CONTAINERS-REGISTRIES.CONF.D is a systemd-wide directory for drop-in
configuration files in the `containers-registries.conf(5)` format.

By default, the directory is located at `/etc/containers/registries.conf.d`.

# CONFIGURATION PRECEDENCE

Once the main configuration at `/etc/containers/registries.conf` is loaded, the
files in `/etc/containers/registries.conf.d` are loaded in alpha-numerical order.
Specified fields in a config will overwrite any previous setting.

For instance, setting the `unqualified-search-registries` in
`/etc/containers/registries.conf.d/myregistries.conf` will overwrite previous
settings in `/etc/containers/registries.conf`.

Note that all files must be specified in the same version of the
`containers-registries.conf(5)` format. The entire `[[registry]]` table will
always be overridden if set.

# SEE ALSO
`containers-registries.conf(5)`

# HISTORY

Mar 2020, Originally compiled by Valentin Rothberg <rothberg@redhat.com>
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b // indirect
github.com/xeipuuv/gojsonschema v0.0.0-20190816131739-be0936907f66
go.etcd.io/bbolt v1.3.3 // indirect
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6
golang.org/x/net v0.0.0-20190628185345-da137c7871d7
golang.org/x/sync v0.0.0-20190423024810-112230192c58
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2
golang.org/x/sys v0.0.0-20200217220822-9197077df867
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
k8s.io/client-go v0.0.0-20170217214107-bcde30fb7eae
)
68 changes: 51 additions & 17 deletions pkg/sysregistriesv2/system_registries_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package sysregistriesv2

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
Expand All @@ -26,6 +25,16 @@ var systemRegistriesConfPath = builtinRegistriesConfPath
// DO NOT change this, instead see systemRegistriesConfPath above.
const builtinRegistriesConfPath = "/etc/containers/registries.conf"

// systemRegistriesConfDirPath is the path to the system-wide registry
// configuration directory and is used to add/subtract potential registries for
// obtaining images. You can override this at build time with
// -ldflags '-X github.com/containers/image/sysregistries.systemRegistriesConfDirecotyPath=$your_path'
var systemRegistriesConfDirPath = builtinRegistriesConfDirPath

// builtinRegistriesConfDirPath is the path to the registry configuration directory.
// DO NOT change this, instead see systemRegistriesConfDirectoryPath above.
const builtinRegistriesConfDirPath = "/etc/containers/registries.conf.d"

// Endpoint describes a remote location of a registry.
type Endpoint struct {
// The endpoint's remote location.
Expand Down Expand Up @@ -360,16 +369,45 @@ func TryUpdatingCache(ctx *types.SystemContext) (*V2RegistriesConf, error) {
defer configMutex.Unlock()

// load the config
config, err := loadRegistryConf(configPath)
if err != nil {
config := &tomlConfig{}
if err := config.loadConfig(configPath); err != nil {
// Return an empty []Registry if we use the default config,
// which implies that the config path of the SystemContext
// isn't set. Note: if ctx.SystemRegistriesConfPath points to
// the default config, we will still return an error.
if os.IsNotExist(err) && (ctx == nil || ctx.SystemRegistriesConfPath == "") {
return &V2RegistriesConf{Registries: []Registry{}}, nil
config = &tomlConfig{}
config.V2RegistriesConf = V2RegistriesConf{Registries: []Registry{}}
} else {
return nil, err
}
return nil, err
}

// Load the configs from the conf directory path.
confDir := systemRegistriesConfDirPath
if ctx != nil && ctx.SystemRegistriesConfDirPath != "" {
confDir = ctx.SystemRegistriesConfDirPath
}
err := filepath.Walk(confDir,
// WalkFunc to read additional
func(path string, info os.FileInfo, err error) error {
switch {
case info == nil:
// registries.conf.d doesn't exist
return nil
case info.IsDir():
// ignore directories
return nil
default:
// expect all files to be a config
return config.loadConfig(path)
}
},
)
if err != nil && !os.IsNotExist(err) {
// Ignore IsNotExist errors: most systems won't have a
// registries.conf.d directory.
return nil, errors.Wrapf(err, "error reading registries.conf.d")
}

v2Config := &config.V2RegistriesConf
Expand Down Expand Up @@ -470,16 +508,12 @@ func FindRegistry(ctx *types.SystemContext, ref string) (*Registry, error) {
return nil, nil
}

// Loads the registry configuration file from the filesystem and then unmarshals
// it. Returns the unmarshalled object.
func loadRegistryConf(configPath string) (*tomlConfig, error) {
config := &tomlConfig{}

configBytes, err := ioutil.ReadFile(configPath)
if err != nil {
return nil, err
}

err = toml.Unmarshal(configBytes, &config)
return config, err
// tomlConfig loads the unmarshals the configuration at the specified path.
// Note that the tomlConfig's fields will be overridden if they are set in
// specified path. This behavior is necessary for registries.conf.d stances
// behavior.
func (t *tomlConfig) loadConfig(path string) error {
logrus.Debugf("Loading registries.conf %q", path)
_, err := toml.DecodeFile(path, t)
return err
}
15 changes: 15 additions & 0 deletions pkg/sysregistriesv2/system_registries_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,3 +463,18 @@ func TestTryUpdatingCache(t *testing.T) {
assert.Nil(t, registries)
assert.Equal(t, 1, len(configCache))
}

func TestRegistriesConfDirectory(t *testing.T) {
ctx := &types.SystemContext{
SystemRegistriesConfPath: "testdata/base-for-registries.d.conf",
SystemRegistriesConfDirPath: "testdata/registries.conf.d",
}
configCache = make(map[string]*V2RegistriesConf)
registries, err := TryUpdatingCache(ctx)
assert.Nil(t, err)
assert.NotNil(t, registries)

assert.Equal(t, registries.UnqualifiedSearchRegistries, []string{"example-overwrite.com"})
assert.Equal(t, len(registries.Registries), 1)
assert.Equal(t, registries.Registries[0].Location, "2.com")
}
5 changes: 5 additions & 0 deletions pkg/sysregistriesv2/testdata/base-for-registries.d.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
unqualified-search-registries = ["example.com"]

[[registry]]
location = "base.com"
insecure = true
4 changes: 4 additions & 0 deletions pkg/sysregistriesv2/testdata/registries.conf.d/config-1.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
unqualified-search-registries = ["example-overwrite.com"]

[[registry]]
location = "1.com"
2 changes: 2 additions & 0 deletions pkg/sysregistriesv2/testdata/registries.conf.d/config-2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[[registry]]
location = "2.com"
2 changes: 2 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,8 @@ type SystemContext struct {
RegistriesDirPath string
// Path to the system-wide registries configuration file
SystemRegistriesConfPath string
// Path to the system-wide registries configuration directory
SystemRegistriesConfDirPath string
// If not "", overrides the default path for the authentication file, but only new format files
AuthFilePath string
// if not "", overrides the default path for the authentication file, but with the legacy format;
Expand Down

0 comments on commit eee0de5

Please sign in to comment.