aee260d4eb
This removes the email prompt when you use docker login, and also removes the ability to register via the docker cli. Docker login, will strictly be used for logging into a registry server. Signed-off-by: Ken Cochrane <kencochrane@gmail.com>
558 lines
14 KiB
Go
558 lines
14 KiB
Go
package cliconfig
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/docker/docker/pkg/homedir"
|
|
"github.com/docker/engine-api/types"
|
|
)
|
|
|
|
func TestEmptyConfigDir(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
SetConfigDir(tmpHome)
|
|
|
|
config, err := Load("")
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on empty config dir: %q", err)
|
|
}
|
|
|
|
expectedConfigFilename := filepath.Join(tmpHome, ConfigFileName)
|
|
if config.Filename() != expectedConfigFilename {
|
|
t.Fatalf("Expected config filename %s, got %s", expectedConfigFilename, config.Filename())
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
}
|
|
|
|
func TestMissingFile(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
config, err := Load(tmpHome)
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on missing file: %q", err)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
}
|
|
|
|
func TestSaveFileToDirs(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
tmpHome += "/.docker"
|
|
|
|
config, err := Load(tmpHome)
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on missing file: %q", err)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
}
|
|
|
|
func TestEmptyFile(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
if err := ioutil.WriteFile(fn, []byte(""), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err = Load(tmpHome)
|
|
if err == nil {
|
|
t.Fatalf("Was supposed to fail")
|
|
}
|
|
}
|
|
|
|
func TestEmptyJson(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
if err := ioutil.WriteFile(fn, []byte("{}"), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on empty json file: %q", err)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
}
|
|
|
|
func TestOldInvalidsAuth(t *testing.T) {
|
|
invalids := map[string]string{
|
|
`username = test`: "The Auth config file is empty",
|
|
`username
|
|
password`: "Invalid Auth config file",
|
|
`username = test
|
|
email`: "Invalid auth configuration file",
|
|
}
|
|
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
homeKey := homedir.Key()
|
|
homeVal := homedir.Get()
|
|
|
|
defer func() { os.Setenv(homeKey, homeVal) }()
|
|
os.Setenv(homeKey, tmpHome)
|
|
|
|
for content, expectedError := range invalids {
|
|
fn := filepath.Join(tmpHome, oldConfigfile)
|
|
if err := ioutil.WriteFile(fn, []byte(content), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
// Use Contains instead of == since the file name will change each time
|
|
if err == nil || !strings.Contains(err.Error(), expectedError) {
|
|
t.Fatalf("Should have failed\nConfig: %v\nGot: %v\nExpected: %v", config, err, expectedError)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
func TestOldValidAuth(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
homeKey := homedir.Key()
|
|
homeVal := homedir.Get()
|
|
|
|
defer func() { os.Setenv(homeKey, homeVal) }()
|
|
os.Setenv(homeKey, tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, oldConfigfile)
|
|
js := `username = am9lam9lOmhlbGxv
|
|
email = user@example.com`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// defaultIndexserver is https://index.docker.io/v1/
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
if ac.Username != "joejoe" || ac.Password != "hello" {
|
|
t.Fatalf("Missing data from parsing:\n%q", config)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv"
|
|
}
|
|
}
|
|
}`
|
|
|
|
if configStr != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n%s\n not \n%s", configStr, expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestOldJsonInvalid(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
homeKey := homedir.Key()
|
|
homeVal := homedir.Get()
|
|
|
|
defer func() { os.Setenv(homeKey, homeVal) }()
|
|
os.Setenv(homeKey, tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, oldConfigfile)
|
|
js := `{"https://index.docker.io/v1/":{"auth":"test","email":"user@example.com"}}`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
// Use Contains instead of == since the file name will change each time
|
|
if err == nil || !strings.Contains(err.Error(), "Invalid auth configuration file") {
|
|
t.Fatalf("Expected an error got : %v, %v", config, err)
|
|
}
|
|
}
|
|
|
|
func TestOldJson(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
homeKey := homedir.Key()
|
|
homeVal := homedir.Get()
|
|
|
|
defer func() { os.Setenv(homeKey, homeVal) }()
|
|
os.Setenv(homeKey, tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, oldConfigfile)
|
|
js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on empty json file: %q", err)
|
|
}
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
if ac.Username != "joejoe" || ac.Password != "hello" {
|
|
t.Fatalf("Missing data from parsing:\n%q", config)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv",
|
|
"email": "user@example.com"
|
|
}
|
|
}
|
|
}`
|
|
|
|
if configStr != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n'%s'\n not \n'%s'\n", configStr, expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestNewJson(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } } }`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on empty json file: %q", err)
|
|
}
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
if ac.Username != "joejoe" || ac.Password != "hello" {
|
|
t.Fatalf("Missing data from parsing:\n%q", config)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv"
|
|
}
|
|
}
|
|
}`
|
|
|
|
if configStr != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n%s\n not \n%s", configStr, expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestNewJsonNoEmail(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } } }`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on empty json file: %q", err)
|
|
}
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
if ac.Username != "joejoe" || ac.Password != "hello" {
|
|
t.Fatalf("Missing data from parsing:\n%q", config)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv"
|
|
}
|
|
}
|
|
}`
|
|
|
|
if configStr != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n%s\n not \n%s", configStr, expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestJsonWithPsFormat(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
js := `{
|
|
"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } },
|
|
"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
|
|
}`
|
|
if err := ioutil.WriteFile(fn, []byte(js), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
config, err := Load(tmpHome)
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on empty json file: %q", err)
|
|
}
|
|
|
|
if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` {
|
|
t.Fatalf("Unknown ps format: %s\n", config.PsFormat)
|
|
}
|
|
|
|
// Now save it and make sure it shows up in new form
|
|
configStr := saveConfigAndValidateNewFormat(t, config, tmpHome)
|
|
if !strings.Contains(configStr, `"psFormat":`) ||
|
|
!strings.Contains(configStr, "{{.ID}}") {
|
|
t.Fatalf("Should have save in new form: %s", configStr)
|
|
}
|
|
}
|
|
|
|
// Save it and make sure it shows up in new form
|
|
func saveConfigAndValidateNewFormat(t *testing.T, config *ConfigFile, homeFolder string) string {
|
|
err := config.Save()
|
|
if err != nil {
|
|
t.Fatalf("Failed to save: %q", err)
|
|
}
|
|
|
|
buf, err := ioutil.ReadFile(filepath.Join(homeFolder, ConfigFileName))
|
|
if !strings.Contains(string(buf), `"auths":`) {
|
|
t.Fatalf("Should have save in new form: %s", string(buf))
|
|
}
|
|
return string(buf)
|
|
}
|
|
|
|
func TestConfigDir(t *testing.T) {
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
if ConfigDir() == tmpHome {
|
|
t.Fatalf("Expected ConfigDir to be different than %s by default, but was the same", tmpHome)
|
|
}
|
|
|
|
// Update configDir
|
|
SetConfigDir(tmpHome)
|
|
|
|
if ConfigDir() != tmpHome {
|
|
t.Fatalf("Expected ConfigDir to %s, but was %s", tmpHome, ConfigDir())
|
|
}
|
|
}
|
|
|
|
func TestConfigFile(t *testing.T) {
|
|
configFilename := "configFilename"
|
|
configFile := NewConfigFile(configFilename)
|
|
|
|
if configFile.Filename() != configFilename {
|
|
t.Fatalf("Expected %s, got %s", configFilename, configFile.Filename())
|
|
}
|
|
}
|
|
|
|
func TestJsonReaderNoFile(t *testing.T) {
|
|
js := ` { "auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } } }`
|
|
|
|
config, err := LoadFromReader(strings.NewReader(js))
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on empty json file: %q", err)
|
|
}
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
if ac.Username != "joejoe" || ac.Password != "hello" {
|
|
t.Fatalf("Missing data from parsing:\n%q", config)
|
|
}
|
|
|
|
}
|
|
|
|
func TestOldJsonReaderNoFile(t *testing.T) {
|
|
js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
|
|
|
|
config, err := LegacyLoadFromReader(strings.NewReader(js))
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on empty json file: %q", err)
|
|
}
|
|
|
|
ac := config.AuthConfigs["https://index.docker.io/v1/"]
|
|
if ac.Username != "joejoe" || ac.Password != "hello" {
|
|
t.Fatalf("Missing data from parsing:\n%q", config)
|
|
}
|
|
}
|
|
|
|
func TestJsonWithPsFormatNoFile(t *testing.T) {
|
|
js := `{
|
|
"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv", "email": "user@example.com" } },
|
|
"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
|
|
}`
|
|
config, err := LoadFromReader(strings.NewReader(js))
|
|
if err != nil {
|
|
t.Fatalf("Failed loading on empty json file: %q", err)
|
|
}
|
|
|
|
if config.PsFormat != `table {{.ID}}\t{{.Label "com.docker.label.cpu"}}` {
|
|
t.Fatalf("Unknown ps format: %s\n", config.PsFormat)
|
|
}
|
|
|
|
}
|
|
|
|
func TestJsonSaveWithNoFile(t *testing.T) {
|
|
js := `{
|
|
"auths": { "https://index.docker.io/v1/": { "auth": "am9lam9lOmhlbGxv" } },
|
|
"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
|
|
}`
|
|
config, err := LoadFromReader(strings.NewReader(js))
|
|
err = config.Save()
|
|
if err == nil {
|
|
t.Fatalf("Expected error. File should not have been able to save with no file name.")
|
|
}
|
|
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create a temp dir: %q", err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
err = config.SaveToWriter(f)
|
|
if err != nil {
|
|
t.Fatalf("Failed saving to file: %q", err)
|
|
}
|
|
buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName))
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv"
|
|
}
|
|
},
|
|
"psFormat": "table {{.ID}}\\t{{.Label \"com.docker.label.cpu\"}}"
|
|
}`
|
|
if string(buf) != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n%s\nnot \n%s", string(buf), expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestLegacyJsonSaveWithNoFile(t *testing.T) {
|
|
|
|
js := `{"https://index.docker.io/v1/":{"auth":"am9lam9lOmhlbGxv","email":"user@example.com"}}`
|
|
config, err := LegacyLoadFromReader(strings.NewReader(js))
|
|
err = config.Save()
|
|
if err == nil {
|
|
t.Fatalf("Expected error. File should not have been able to save with no file name.")
|
|
}
|
|
|
|
tmpHome, err := ioutil.TempDir("", "config-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create a temp dir: %q", err)
|
|
}
|
|
defer os.RemoveAll(tmpHome)
|
|
|
|
fn := filepath.Join(tmpHome, ConfigFileName)
|
|
f, _ := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
err = config.SaveToWriter(f)
|
|
if err != nil {
|
|
t.Fatalf("Failed saving to file: %q", err)
|
|
}
|
|
buf, err := ioutil.ReadFile(filepath.Join(tmpHome, ConfigFileName))
|
|
|
|
expConfStr := `{
|
|
"auths": {
|
|
"https://index.docker.io/v1/": {
|
|
"auth": "am9lam9lOmhlbGxv",
|
|
"email": "user@example.com"
|
|
}
|
|
}
|
|
}`
|
|
|
|
if string(buf) != expConfStr {
|
|
t.Fatalf("Should have save in new form: \n%s\n not \n%s", string(buf), expConfStr)
|
|
}
|
|
}
|
|
|
|
func TestEncodeAuth(t *testing.T) {
|
|
newAuthConfig := &types.AuthConfig{Username: "ken", Password: "test"}
|
|
authStr := encodeAuth(newAuthConfig)
|
|
decAuthConfig := &types.AuthConfig{}
|
|
var err error
|
|
decAuthConfig.Username, decAuthConfig.Password, err = decodeAuth(authStr)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if newAuthConfig.Username != decAuthConfig.Username {
|
|
t.Fatal("Encode Username doesn't match decoded Username")
|
|
}
|
|
if newAuthConfig.Password != decAuthConfig.Password {
|
|
t.Fatal("Encode Password doesn't match decoded Password")
|
|
}
|
|
if authStr != "a2VuOnRlc3Q=" {
|
|
t.Fatal("AuthString encoding isn't correct.")
|
|
}
|
|
}
|