From 779635a3b20dd8f44f05c30991554dad52f5fd00 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Wed, 15 Apr 2015 14:05:49 +0200 Subject: [PATCH 1/9] rkt: Remove useless parameter --- rkt/config/auth.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rkt/config/auth.go b/rkt/config/auth.go index 2910db9..bd893a0 100644 --- a/rkt/config/auth.go +++ b/rkt/config/auth.go @@ -89,9 +89,9 @@ func (p *authV1JsonParser) parse(config *Config, raw []byte) error { ) switch auth.Type { case "basic": - headerer, err = p.getBasicV1Headerer(config, auth.Credentials) + headerer, err = p.getBasicV1Headerer(auth.Credentials) case "oauth": - headerer, err = p.getOAuthV1Headerer(config, auth.Credentials) + headerer, err = p.getOAuthV1Headerer(auth.Credentials) default: err = fmt.Errorf("unknown auth type: %q", auth.Type) } @@ -107,7 +107,7 @@ func (p *authV1JsonParser) parse(config *Config, raw []byte) error { return nil } -func (p *authV1JsonParser) getBasicV1Headerer(config *Config, raw json.RawMessage) (Headerer, error) { +func (p *authV1JsonParser) getBasicV1Headerer(raw json.RawMessage) (Headerer, error) { var basic basicV1 if err := json.Unmarshal(raw, &basic); err != nil { return nil, err @@ -124,7 +124,7 @@ func (p *authV1JsonParser) getBasicV1Headerer(config *Config, raw json.RawMessag }, nil } -func (p *authV1JsonParser) getOAuthV1Headerer(config *Config, raw json.RawMessage) (Headerer, error) { +func (p *authV1JsonParser) getOAuthV1Headerer(raw json.RawMessage) (Headerer, error) { var oauth oauthV1 if err := json.Unmarshal(raw, &oauth); err != nil { return nil, err From 20e09287bb4940f9fc1b9118f17b7cf1cf56ad30 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Wed, 15 Apr 2015 14:06:39 +0200 Subject: [PATCH 2/9] rkt: Add JSON config parser for docker auth The dockerAuth config files can be placed in both "auth.d" and "docker.d" directory and their format is: ``` { "rktKind": "dockerAuth", "rktVersion": "v1", "indices": [ "index.docker.io", "quay.io" ], "credentials": { "user": "foo", "password": "bar" } } ``` --- rkt/config/auth.go | 55 +++++++++++++++++++++++++++++++++++++++----- rkt/config/config.go | 14 +++++++++-- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/rkt/config/auth.go b/rkt/config/auth.go index bd893a0..31d6b0a 100644 --- a/rkt/config/auth.go +++ b/rkt/config/auth.go @@ -42,9 +42,18 @@ type oauthV1 struct { Token string `json:"token"` } +type dockerAuthV1JsonParser struct{} + +type dockerAuthV1 struct { + Indices []string `json:"indices"` + Credentials basicV1 `json:"credentials"` +} + func init() { addParser("auth", "v1", &authV1JsonParser{}) - registerSubDir("auth.d", []string{"auth"}) + addParser("dockerAuth", "v1", &dockerAuthV1JsonParser{}) + registerSubDir("auth.d", []string{"auth", "dockerAuth"}) + registerSubDir("docker.d", []string{"dockerAuth"}) } type basicAuthHeaderer struct { @@ -112,11 +121,8 @@ func (p *authV1JsonParser) getBasicV1Headerer(raw json.RawMessage) (Headerer, er if err := json.Unmarshal(raw, &basic); err != nil { return nil, err } - if len(basic.User) == 0 { - return nil, fmt.Errorf("user not specified") - } - if len(basic.Password) == 0 { - return nil, fmt.Errorf("password not specified") + if err := validateBasicV1(&basic); err != nil { + return nil, err } return &basicAuthHeaderer{ user: basic.User, @@ -136,3 +142,40 @@ func (p *authV1JsonParser) getOAuthV1Headerer(raw json.RawMessage) (Headerer, er token: oauth.Token, }, nil } + +func (p *dockerAuthV1JsonParser) parse(config *Config, raw []byte) error { + var auth dockerAuthV1 + if err := json.Unmarshal(raw, &auth); err != nil { + return err + } + if len(auth.Indices) == 0 { + return fmt.Errorf("no indices specified") + } + if err := validateBasicV1(&auth.Credentials); err != nil { + return err + } + basic := BasicCredentials{ + User: auth.Credentials.User, + Password: auth.Credentials.Password, + } + for _, index := range auth.Indices { + if _, ok := config.DockerCredentialsPerIndex[index]; ok { + return fmt.Errorf("credentials for docker index %q are already specified", index) + } + config.DockerCredentialsPerIndex[index] = basic + } + return nil +} + +func validateBasicV1(basic *basicV1) error { + if basic == nil { + return fmt.Errorf("no credentials") + } + if len(basic.User) == 0 { + return fmt.Errorf("user not specified") + } + if len(basic.Password) == 0 { + return fmt.Errorf("password not specified") + } + return nil +} diff --git a/rkt/config/config.go b/rkt/config/config.go index f66a321..66e3c4d 100644 --- a/rkt/config/config.go +++ b/rkt/config/config.go @@ -31,10 +31,16 @@ type Headerer interface { Header() http.Header } +type BasicCredentials struct { + User string + Password string +} + // Config is a single place where configuration for rkt frontend needs // resides. type Config struct { - AuthPerHost map[string]Headerer + AuthPerHost map[string]Headerer + DockerCredentialsPerIndex map[string]BasicCredentials } type configParser interface { @@ -140,7 +146,8 @@ func GetConfigFromDir(dir string) (*Config, error) { func newConfig() *Config { return &Config{ - AuthPerHost: make(map[string]Headerer), + AuthPerHost: make(map[string]Headerer), + DockerCredentialsPerIndex: make(map[string]BasicCredentials), } } @@ -272,4 +279,7 @@ func mergeConfigs(config *Config, subconfig *Config) { for host, headerer := range subconfig.AuthPerHost { config.AuthPerHost[host] = headerer } + for index, creds := range subconfig.DockerCredentialsPerIndex { + config.DockerCredentialsPerIndex[index] = creds + } } From 3f73d07402cdf1565f4004a71977457c9738d695 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Wed, 15 Apr 2015 15:37:09 +0200 Subject: [PATCH 3/9] rkt: Split some code in test to separate functions Will be used by docker auth unit tests. --- rkt/config/config_test.go | 53 ++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/rkt/config/config_test.go b/rkt/config/config_test.go index 9f43a0e..905c94b 100644 --- a/rkt/config/config_test.go +++ b/rkt/config/config_test.go @@ -73,26 +73,10 @@ func TestAuthConfigFormat(t *testing.T) { {`{"rktKind": "auth", "rktVersion": "v1", "domains": ["coreos.com"], "type": "oauth", "credentials": {"token": "sometoken"}}`, map[string]http.Header{"coreos.com": {"Authorization": []string{"Bearer sometoken"}}}, false}, } for _, tt := range tests { - f, err := tmpConfigFile(tstprefix) - if err != nil { - panic(fmt.Sprintf("Failed to create tmp config file: %v", err)) - } - defer f.Close() - if _, err := f.Write([]byte(tt.contents)); err != nil { - panic(fmt.Sprintf("Writing config to file failed: %v", err)) - } - fi, err := f.Stat() - if err != nil { - panic(fmt.Sprintf("Stating a tmp config file failed: %v", err)) - } - cfg := newConfig() - if err := readFile(cfg, fi, f.Name(), []string{"auth"}); err != nil { - if !tt.fail { - t.Errorf("Expected test to succeed, failed unexpectedly (contents: `%s`)", tt.contents) - } - } else if tt.fail { - t.Errorf("Expected test to fail, succeeded unexpectedly (contents: `%s`)", tt.contents) - } else { + cfg, err := getConfigFromContents(tt.contents, "auth") + if vErr := verifyFailure(tt.fail, tt.contents, err); vErr != nil { + t.Errorf("%v", vErr) + } else if !tt.fail { result := make(map[string]http.Header) for k, v := range cfg.AuthPerHost { result[k] = v.Header() @@ -104,6 +88,35 @@ func TestAuthConfigFormat(t *testing.T) { } } +func verifyFailure(shouldFail bool, contents string, err error) error { + var vErr error = nil + if err != nil { + if !shouldFail { + vErr = fmt.Errorf("Expected test to succeed, failed unexpectedly (contents: `%s`): %v", contents, err) + } + } else if shouldFail { + vErr = fmt.Errorf("Expected test to fail, succeeded unexpectedly (contents: `%s`)", contents) + } + return vErr +} + +func getConfigFromContents(contents, kind string) (*Config, error) { + f, err := tmpConfigFile(tstprefix) + if err != nil { + panic(fmt.Sprintf("Failed to create tmp config file: %v", err)) + } + defer f.Close() + if _, err := f.Write([]byte(contents)); err != nil { + panic(fmt.Sprintf("Writing config to file failed: %v", err)) + } + fi, err := f.Stat() + if err != nil { + panic(fmt.Sprintf("Stating a tmp config file failed: %v", err)) + } + cfg := newConfig() + return cfg, readFile(cfg, fi, f.Name(), []string{kind}) +} + func TestConfigLoading(t *testing.T) { dir, err := ioutil.TempDir("", tstprefix) if err != nil { From 4fca9b70a9b29ffca9ff92d6c4a2076e1da53237 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Wed, 15 Apr 2015 15:38:05 +0200 Subject: [PATCH 4/9] rkt: Test dockerAuth configuration --- rkt/config/config_test.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/rkt/config/config_test.go b/rkt/config/config_test.go index 905c94b..a501ded 100644 --- a/rkt/config/config_test.go +++ b/rkt/config/config_test.go @@ -88,6 +88,39 @@ func TestAuthConfigFormat(t *testing.T) { } } +func TestDockerAuthConfigFormat(t *testing.T) { + tests := []struct { + contents string + expected map[string]BasicCredentials + fail bool + }{ + {"bogus contents", nil, true}, + {`{"bogus": {"foo": "bar"}}`, nil, true}, + {`{"rktKind": "foo"}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "foo"}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1"}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": "foo"}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": []}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"]}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {}}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {"user": ""}}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {"user": "bar"}}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {"user": "bar", "password": ""}}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {"user": "bar", "password": "baz"}}`, map[string]BasicCredentials{"coreos.com": BasicCredentials{User: "bar", Password: "baz"}}, false}, + } + for _, tt := range tests { + cfg, err := getConfigFromContents(tt.contents, "dockerAuth") + if vErr := verifyFailure(tt.fail, tt.contents, err); vErr != nil { + t.Errorf("%v", vErr) + } else if !tt.fail { + result := cfg.DockerCredentialsPerIndex + if !reflect.DeepEqual(result, tt.expected) { + t.Error("Got unexpected results\nResult:\n", result, "\n\nExpected:\n", tt.expected) + } + } + } +} + func verifyFailure(shouldFail bool, contents string, err error) error { var vErr error = nil if err != nil { From 1a97b97226420400c1a2707964643675faa461b5 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Wed, 15 Apr 2015 15:39:34 +0200 Subject: [PATCH 5/9] rkt: Use docker auth when necessary --- rkt/fetch.go | 1 + rkt/images.go | 10 +++++++++- rkt/prepare.go | 1 + rkt/run.go | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/rkt/fetch.go b/rkt/fetch.go index caf66c4..d00bd68 100644 --- a/rkt/fetch.go +++ b/rkt/fetch.go @@ -76,6 +76,7 @@ func runFetch(args []string) (exit int) { ds: ds, ks: ks, headers: config.AuthPerHost, + dockerAuth: config.DockerCredentialsPerIndex, insecureSkipVerify: globalFlags.InsecureSkipVerify, debug: globalFlags.Debug, }, diff --git a/rkt/images.go b/rkt/images.go index f914232..6b5b1ff 100644 --- a/rkt/images.go +++ b/rkt/images.go @@ -43,6 +43,7 @@ type imageActionData struct { ds *store.Store ks *keystore.Keystore headers map[string]config.Headerer + dockerAuth map[string]config.BasicCredentials insecureSkipVerify bool debug bool } @@ -267,7 +268,14 @@ func (f *fetcher) fetch(aciURL, ascURL string, ascFile *os.File) (*openpgp.Entit return nil, nil, fmt.Errorf("error creating temporary dir for docker to ACI conversion: %v", err) } - acis, err := docker2aci.Convert(registryURL, true, tmpDir, "", "") + indexName := docker2aci.GetIndexName(registryURL) + user := "" + password := "" + if creds, ok := f.dockerAuth[indexName]; ok { + user = creds.User + password = creds.Password + } + acis, err := docker2aci.Convert(registryURL, true, tmpDir, user, password) if err != nil { return nil, nil, fmt.Errorf("error converting docker image to ACI: %v", err) } diff --git a/rkt/prepare.go b/rkt/prepare.go index a51c77b..b8056c7 100644 --- a/rkt/prepare.go +++ b/rkt/prepare.go @@ -103,6 +103,7 @@ func runPrepare(args []string) (exit int) { imageActionData: imageActionData{ ds: ds, headers: config.AuthPerHost, + dockerAuth: config.DockerCredentialsPerIndex, insecureSkipVerify: globalFlags.InsecureSkipVerify, debug: globalFlags.Debug, }, diff --git a/rkt/run.go b/rkt/run.go index dd38c03..b228bf9 100644 --- a/rkt/run.go +++ b/rkt/run.go @@ -134,6 +134,7 @@ func runRun(args []string) (exit int) { imageActionData: imageActionData{ ds: ds, headers: config.AuthPerHost, + dockerAuth: config.DockerCredentialsPerIndex, insecureSkipVerify: globalFlags.InsecureSkipVerify, debug: globalFlags.Debug, }, From b67bc3b567c4b49fb828919c85594b18b09b5c4f Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Wed, 15 Apr 2015 18:58:46 +0200 Subject: [PATCH 6/9] documentation: Minor corrections for auth configuration --- Documentation/configuration.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Documentation/configuration.md b/Documentation/configuration.md index e066bf5..ee68ff9 100644 --- a/Documentation/configuration.md +++ b/Documentation/configuration.md @@ -44,7 +44,7 @@ be placed inside `auth.d` subdirectory (that is - in ##### Description and examples -This version if `auth` configuration specifies three additional +This version of `auth` configuration specifies three additional fields: `domains`, `type` and `credentials`. The `domains` field is an array of strings describing hosts for which @@ -149,7 +149,8 @@ In `/etc/rkt/auth.d/specific-tectonic.json`: } ``` -The result is that when downloading data from `kubernetes.io` we still -send `Authorization: Bearer common-token`, but when downloading from -`coreos.com` - `Authorization: Basic Zm9vOmJhcg==`. And for -`tectonic.com` - `Authorization: Bearer tectonic-token`. +The result is that when downloading data from `kubernetes.io` `rkt` +still sends `Authorization: Bearer common-token`, but when downloading +from `coreos.com` - `Authorization: Basic Zm9vOmJhcg==` (`foo:bar` +encoded in base64). And for `tectonic.com` - `Authorization: Bearer +tectonic-token`. From 4fe77eead8108d6ff0eb2722688b2c2cf077c8fd Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Wed, 15 Apr 2015 19:02:57 +0200 Subject: [PATCH 7/9] documentation: Add informations about dockerAuth kind --- Documentation/configuration.md | 102 +++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/Documentation/configuration.md b/Documentation/configuration.md index ee68ff9..766b1a1 100644 --- a/Documentation/configuration.md +++ b/Documentation/configuration.md @@ -154,3 +154,105 @@ still sends `Authorization: Bearer common-token`, but when downloading from `coreos.com` - `Authorization: Basic Zm9vOmJhcg==` (`foo:bar` encoded in base64). And for `tectonic.com` - `Authorization: Bearer tectonic-token`. + +### rktKind: `dockerAuth` + +This kind of configuration is used to set up necessary credentials +when downloading data from docker indices. The configuration files +should be placed inside either `auth.d` or `docker.d` subdirectories +(that is - in `/usr/lib/rkt/{auth.d,docker.d}` or in +`/etc/rkt/{auth.d,docker.d}`). + +#### rktVersion: `v1` + +##### Description and examples + +This version of `dockerAuth` configuration specifies two additional +fields: `indices` and `credentials`. + +The `indices` field is an array of strings describing docker indices +for which following credentials should be used. A short list of +popular docker indices is below. This field has to be specified and +cannot be empty. + +`credentials` field holds the necessary data to authenticate against +docker index. This field has to be specified and cannot be empty. + +Currently docker indices only support basic HTTP authentication, so +`credentials` field has two subfields - `user` and `password`. These +fields have to be specified and cannot be empty. + +Some popular docker indices: +* index.docker.io (this is is used when no docker index is specified + in URL, like in `docker://redis`) +* quay.io +* gcr.io + +Example of dockerAuth config: +``` +{ + "rktKind": "dockerAuth", + "rktVersion": "v1", + "indices": ["index.docker.io", "quay.io"], + "credentials": { + "user": "foo", + "password": "bar" + } +} +``` + +##### Overriding semantics + +Overriding is done for each index. That means that the user can +override credentials used for each index. Example of vendor +configuration: + +In `/usr/lib/rkt/docker.d/docker.json`: +``` +{ + "rktKind": "dockerAuth", + "rktVersion": "v1", + "indices": ["index.docker.io", "gcr.io", "quay.io"], + "credentials": { + "user": "foo", + "password": "bar" + } +} +``` + +If only this configuration file were available to `rkt` then when +downloading images from either `index.docker.io`, `gcr.io` or +`quay.io`, `rkt` would use user `foo` and password `bar`. + +But with additional configuration like follows situation +changes. Example of custom configuration: + +In `/etc/rkt/auth.d/specific-quay.json`: +``` +{ + "rktKind": "dockerAuth", + "rktVersion": "v1", + "indices": ["quay.io"], + "credentials": { + "user": "baz", + "password": "quux" + } +} +``` +In `/etc/rkt/auth.d/specific-gcr.json`: +``` +{ + "rktKind": "dockerAuth", + "rktVersion": "v1", + "domains": ["gcr.io"], + "credentials": { + "user": "goo", + "password": "gle" + } +} +``` + +The result is that when downloading images from `index.docker.io` `rkt` +still sends user `foo` and password `bar`, but when downloading +from `quay.io` - user `baz` and password `quux`. And for +`gcr.io` - user `goo` and password `gle`. From 71f87b164fe1c5de5d500dd46ec1a4fdb3cc250a Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Mon, 20 Apr 2015 15:14:09 +0200 Subject: [PATCH 8/9] rkt, documentation: Do not mention docker.d config subdirectory Initially docker.d was meant for configuration related to docker. But currently we only have dockerAuth kind that is related to it. If some other configuration kind relevant to docker appears in future then we can think about bringing docker.d directory back. --- Documentation/configuration.md | 7 +++---- rkt/config/auth.go | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Documentation/configuration.md b/Documentation/configuration.md index 766b1a1..63d4525 100644 --- a/Documentation/configuration.md +++ b/Documentation/configuration.md @@ -159,9 +159,8 @@ tectonic-token`. This kind of configuration is used to set up necessary credentials when downloading data from docker indices. The configuration files -should be placed inside either `auth.d` or `docker.d` subdirectories -(that is - in `/usr/lib/rkt/{auth.d,docker.d}` or in -`/etc/rkt/{auth.d,docker.d}`). +should be placed inside `auth.d` subdirectory (that is - in +`/usr/lib/rkt/auth.d` or in `/etc/rkt/auth.d`). #### rktVersion: `v1` @@ -207,7 +206,7 @@ Overriding is done for each index. That means that the user can override credentials used for each index. Example of vendor configuration: -In `/usr/lib/rkt/docker.d/docker.json`: +In `/usr/lib/rkt/auth.d/docker.json`: ``` { "rktKind": "dockerAuth", diff --git a/rkt/config/auth.go b/rkt/config/auth.go index 31d6b0a..9b9dd76 100644 --- a/rkt/config/auth.go +++ b/rkt/config/auth.go @@ -53,7 +53,6 @@ func init() { addParser("auth", "v1", &authV1JsonParser{}) addParser("dockerAuth", "v1", &dockerAuthV1JsonParser{}) registerSubDir("auth.d", []string{"auth", "dockerAuth"}) - registerSubDir("docker.d", []string{"dockerAuth"}) } type basicAuthHeaderer struct { From a88d79bbf3260ec6070e03944018be82ae8d9fcf Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Mon, 20 Apr 2015 16:38:54 +0200 Subject: [PATCH 9/9] rkt, documentation: Rename indices to registries Looks like registry more correct term than index, despite what index.docker.io might hint. This is all confusing, so let's stick with more popular term. --- Documentation/configuration.md | 32 ++++++++++++++++---------------- rkt/config/auth.go | 14 +++++++------- rkt/config/config.go | 12 ++++++------ rkt/config/config_test.go | 18 +++++++++--------- rkt/fetch.go | 2 +- rkt/prepare.go | 2 +- rkt/run.go | 2 +- 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Documentation/configuration.md b/Documentation/configuration.md index 63d4525..a52b0bd 100644 --- a/Documentation/configuration.md +++ b/Documentation/configuration.md @@ -158,7 +158,7 @@ tectonic-token`. ### rktKind: `dockerAuth` This kind of configuration is used to set up necessary credentials -when downloading data from docker indices. The configuration files +when downloading data from docker registries. The configuration files should be placed inside `auth.d` subdirectory (that is - in `/usr/lib/rkt/auth.d` or in `/etc/rkt/auth.d`). @@ -167,23 +167,23 @@ should be placed inside `auth.d` subdirectory (that is - in ##### Description and examples This version of `dockerAuth` configuration specifies two additional -fields: `indices` and `credentials`. +fields: `registries` and `credentials`. -The `indices` field is an array of strings describing docker indices -for which following credentials should be used. A short list of -popular docker indices is below. This field has to be specified and -cannot be empty. +The `registries` field is an array of strings describing docker +registries for which following credentials should be used. A short +list of popular docker registries is below. This field has to be +specified and cannot be empty. `credentials` field holds the necessary data to authenticate against -docker index. This field has to be specified and cannot be empty. +docker registry. This field has to be specified and cannot be empty. -Currently docker indices only support basic HTTP authentication, so +Currently docker registries only support basic HTTP authentication, so `credentials` field has two subfields - `user` and `password`. These fields have to be specified and cannot be empty. -Some popular docker indices: -* index.docker.io (this is is used when no docker index is specified - in URL, like in `docker://redis`) +Some popular docker registries: +* index.docker.io (this is is used when no docker registry is + specified in URL, like in `docker://redis`) * quay.io * gcr.io @@ -192,7 +192,7 @@ Example of dockerAuth config: { "rktKind": "dockerAuth", "rktVersion": "v1", - "indices": ["index.docker.io", "quay.io"], + "registries": ["index.docker.io", "quay.io"], "credentials": { "user": "foo", "password": "bar" @@ -202,8 +202,8 @@ Example of dockerAuth config: ##### Overriding semantics -Overriding is done for each index. That means that the user can -override credentials used for each index. Example of vendor +Overriding is done for each registry. That means that the user can +override credentials used for each registry. Example of vendor configuration: In `/usr/lib/rkt/auth.d/docker.json`: @@ -211,7 +211,7 @@ In `/usr/lib/rkt/auth.d/docker.json`: { "rktKind": "dockerAuth", "rktVersion": "v1", - "indices": ["index.docker.io", "gcr.io", "quay.io"], + "registries": ["index.docker.io", "gcr.io", "quay.io"], "credentials": { "user": "foo", "password": "bar" @@ -231,7 +231,7 @@ In `/etc/rkt/auth.d/specific-quay.json`: { "rktKind": "dockerAuth", "rktVersion": "v1", - "indices": ["quay.io"], + "registries": ["quay.io"], "credentials": { "user": "baz", "password": "quux" diff --git a/rkt/config/auth.go b/rkt/config/auth.go index 9b9dd76..e7e09ad 100644 --- a/rkt/config/auth.go +++ b/rkt/config/auth.go @@ -45,7 +45,7 @@ type oauthV1 struct { type dockerAuthV1JsonParser struct{} type dockerAuthV1 struct { - Indices []string `json:"indices"` + Registries []string `json:"registries"` Credentials basicV1 `json:"credentials"` } @@ -147,8 +147,8 @@ func (p *dockerAuthV1JsonParser) parse(config *Config, raw []byte) error { if err := json.Unmarshal(raw, &auth); err != nil { return err } - if len(auth.Indices) == 0 { - return fmt.Errorf("no indices specified") + if len(auth.Registries) == 0 { + return fmt.Errorf("no registries specified") } if err := validateBasicV1(&auth.Credentials); err != nil { return err @@ -157,11 +157,11 @@ func (p *dockerAuthV1JsonParser) parse(config *Config, raw []byte) error { User: auth.Credentials.User, Password: auth.Credentials.Password, } - for _, index := range auth.Indices { - if _, ok := config.DockerCredentialsPerIndex[index]; ok { - return fmt.Errorf("credentials for docker index %q are already specified", index) + for _, registry := range auth.Registries { + if _, ok := config.DockerCredentialsPerRegistry[registry]; ok { + return fmt.Errorf("credentials for docker registry %q are already specified", registry) } - config.DockerCredentialsPerIndex[index] = basic + config.DockerCredentialsPerRegistry[registry] = basic } return nil } diff --git a/rkt/config/config.go b/rkt/config/config.go index 66e3c4d..95a5860 100644 --- a/rkt/config/config.go +++ b/rkt/config/config.go @@ -39,8 +39,8 @@ type BasicCredentials struct { // Config is a single place where configuration for rkt frontend needs // resides. type Config struct { - AuthPerHost map[string]Headerer - DockerCredentialsPerIndex map[string]BasicCredentials + AuthPerHost map[string]Headerer + DockerCredentialsPerRegistry map[string]BasicCredentials } type configParser interface { @@ -146,8 +146,8 @@ func GetConfigFromDir(dir string) (*Config, error) { func newConfig() *Config { return &Config{ - AuthPerHost: make(map[string]Headerer), - DockerCredentialsPerIndex: make(map[string]BasicCredentials), + AuthPerHost: make(map[string]Headerer), + DockerCredentialsPerRegistry: make(map[string]BasicCredentials), } } @@ -279,7 +279,7 @@ func mergeConfigs(config *Config, subconfig *Config) { for host, headerer := range subconfig.AuthPerHost { config.AuthPerHost[host] = headerer } - for index, creds := range subconfig.DockerCredentialsPerIndex { - config.DockerCredentialsPerIndex[index] = creds + for registry, creds := range subconfig.DockerCredentialsPerRegistry { + config.DockerCredentialsPerRegistry[registry] = creds } } diff --git a/rkt/config/config_test.go b/rkt/config/config_test.go index a501ded..e55af02 100644 --- a/rkt/config/config_test.go +++ b/rkt/config/config_test.go @@ -99,21 +99,21 @@ func TestDockerAuthConfigFormat(t *testing.T) { {`{"rktKind": "foo"}`, nil, true}, {`{"rktKind": "dockerAuth", "rktVersion": "foo"}`, nil, true}, {`{"rktKind": "dockerAuth", "rktVersion": "v1"}`, nil, true}, - {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": "foo"}`, nil, true}, - {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": []}`, nil, true}, - {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"]}`, nil, true}, - {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {}}`, nil, true}, - {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {"user": ""}}`, nil, true}, - {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {"user": "bar"}}`, nil, true}, - {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {"user": "bar", "password": ""}}`, nil, true}, - {`{"rktKind": "dockerAuth", "rktVersion": "v1", "indices": ["coreos.com"], "credentials": {"user": "bar", "password": "baz"}}`, map[string]BasicCredentials{"coreos.com": BasicCredentials{User: "bar", Password: "baz"}}, false}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "registries": "foo"}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "registries": []}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "registries": ["coreos.com"]}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "registries": ["coreos.com"], "credentials": {}}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "registries": ["coreos.com"], "credentials": {"user": ""}}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "registries": ["coreos.com"], "credentials": {"user": "bar"}}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "registries": ["coreos.com"], "credentials": {"user": "bar", "password": ""}}`, nil, true}, + {`{"rktKind": "dockerAuth", "rktVersion": "v1", "registries": ["coreos.com"], "credentials": {"user": "bar", "password": "baz"}}`, map[string]BasicCredentials{"coreos.com": BasicCredentials{User: "bar", Password: "baz"}}, false}, } for _, tt := range tests { cfg, err := getConfigFromContents(tt.contents, "dockerAuth") if vErr := verifyFailure(tt.fail, tt.contents, err); vErr != nil { t.Errorf("%v", vErr) } else if !tt.fail { - result := cfg.DockerCredentialsPerIndex + result := cfg.DockerCredentialsPerRegistry if !reflect.DeepEqual(result, tt.expected) { t.Error("Got unexpected results\nResult:\n", result, "\n\nExpected:\n", tt.expected) } diff --git a/rkt/fetch.go b/rkt/fetch.go index d00bd68..a5071d0 100644 --- a/rkt/fetch.go +++ b/rkt/fetch.go @@ -76,7 +76,7 @@ func runFetch(args []string) (exit int) { ds: ds, ks: ks, headers: config.AuthPerHost, - dockerAuth: config.DockerCredentialsPerIndex, + dockerAuth: config.DockerCredentialsPerRegistry, insecureSkipVerify: globalFlags.InsecureSkipVerify, debug: globalFlags.Debug, }, diff --git a/rkt/prepare.go b/rkt/prepare.go index b8056c7..65211e0 100644 --- a/rkt/prepare.go +++ b/rkt/prepare.go @@ -103,7 +103,7 @@ func runPrepare(args []string) (exit int) { imageActionData: imageActionData{ ds: ds, headers: config.AuthPerHost, - dockerAuth: config.DockerCredentialsPerIndex, + dockerAuth: config.DockerCredentialsPerRegistry, insecureSkipVerify: globalFlags.InsecureSkipVerify, debug: globalFlags.Debug, }, diff --git a/rkt/run.go b/rkt/run.go index b228bf9..a17c688 100644 --- a/rkt/run.go +++ b/rkt/run.go @@ -134,7 +134,7 @@ func runRun(args []string) (exit int) { imageActionData: imageActionData{ ds: ds, headers: config.AuthPerHost, - dockerAuth: config.DockerCredentialsPerIndex, + dockerAuth: config.DockerCredentialsPerRegistry, insecureSkipVerify: globalFlags.InsecureSkipVerify, debug: globalFlags.Debug, },