mirror of https://github.com/containers/image.git
registries.conf.d: add stances for the registries.conf
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>
This commit is contained in:
parent
143904cdaa
commit
eee0de5d00
|
|
@ -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
go.mod
4
go.mod
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package sysregistriesv2
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
unqualified-search-registries = ["example.com"]
|
||||
|
||||
[[registry]]
|
||||
location = "base.com"
|
||||
insecure = true
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
unqualified-search-registries = ["example-overwrite.com"]
|
||||
|
||||
[[registry]]
|
||||
location = "1.com"
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[[registry]]
|
||||
location = "2.com"
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue