Integrate Auth in runtime and make the config file relative to runtime root

This commit is contained in:
creack 2013-03-22 02:19:39 -07:00
parent 5e561a9d52
commit c72ff318d3
6 changed files with 55 additions and 51 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ build_src
command-line-arguments.test
.flymake*
docker.test
auth/auth.test

View File

@ -8,11 +8,12 @@ import (
"io/ioutil"
"net/http"
"os"
"path"
"strings"
)
// Where we store the config file
const CONFIGFILE = "/var/lib/docker/.dockercfg"
const CONFIGFILE = ".dockercfg"
// the registry server we want to login against
//const REGISTRY_SERVER = "https://registry.docker.io"
@ -22,10 +23,11 @@ type AuthConfig struct {
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
rootPath string `json:-`
}
// create a base64 encoded auth string to store in config
func EncodeAuth(authConfig AuthConfig) string {
func EncodeAuth(authConfig *AuthConfig) string {
authStr := authConfig.Username + ":" + authConfig.Password
msg := []byte(authStr)
encoded := make([]byte, base64.StdEncoding.EncodedLen(len(msg)))
@ -34,50 +36,54 @@ func EncodeAuth(authConfig AuthConfig) string {
}
// decode the auth string
func DecodeAuth(authStr string) (AuthConfig, error) {
func DecodeAuth(authStr string) (*AuthConfig, error) {
decLen := base64.StdEncoding.DecodedLen(len(authStr))
decoded := make([]byte, decLen)
authByte := []byte(authStr)
n, err := base64.StdEncoding.Decode(decoded, authByte)
if err != nil {
return AuthConfig{}, err
return nil, err
}
if n > decLen {
return AuthConfig{}, errors.New("something went wrong decoding auth config")
return nil, fmt.Errorf("Something went wrong decoding auth config")
}
arr := strings.Split(string(decoded), ":")
if len(arr) != 2 {
return nil, fmt.Errorf("Invalid auth configuration file")
}
password := strings.Trim(arr[1], "\x00")
return AuthConfig{Username: arr[0], Password: password}, nil
return &AuthConfig{Username: arr[0], Password: password}, nil
}
// load up the auth config information and return values
func LoadConfig() (AuthConfig, error) {
if _, err := os.Stat(CONFIGFILE); err == nil {
b, err := ioutil.ReadFile(CONFIGFILE)
if err != nil {
return AuthConfig{}, err
}
arr := strings.Split(string(b), "\n")
orig_auth := strings.Split(arr[0], " = ")
orig_email := strings.Split(arr[1], " = ")
authConfig, err := DecodeAuth(orig_auth[1])
if err != nil {
return AuthConfig{}, err
}
authConfig.Email = orig_email[1]
return authConfig, nil
} else {
return AuthConfig{}, nil
// FIXME: use the internal golang config parser
func LoadConfig(rootPath string) (*AuthConfig, error) {
confFile := path.Join(rootPath, CONFIGFILE)
if _, err := os.Stat(confFile); err != nil {
return &AuthConfig{}, fmt.Errorf("The Auth config file is missing")
}
return AuthConfig{}, nil
b, err := ioutil.ReadFile(confFile)
if err != nil {
return nil, err
}
arr := strings.Split(string(b), "\n")
orig_auth := strings.Split(arr[0], " = ")
orig_email := strings.Split(arr[1], " = ")
authConfig, err := DecodeAuth(orig_auth[1])
if err != nil {
return nil, err
}
authConfig.Email = orig_email[1]
authConfig.rootPath = rootPath
return authConfig, nil
}
// save the auth config
func saveConfig(authStr string, email string) error {
func saveConfig(rootPath, authStr string, email string) error {
lines := "auth = " + authStr + "\n" + "email = " + email + "\n"
b := []byte(lines)
err := ioutil.WriteFile(CONFIGFILE, b, 0600)
err := ioutil.WriteFile(path.Join(rootPath, CONFIGFILE), b, 0600)
if err != nil {
return err
}
@ -85,7 +91,7 @@ func saveConfig(authStr string, email string) error {
}
// try to register/login to the registry server
func Login(authConfig AuthConfig) (string, error) {
func Login(authConfig *AuthConfig) (string, error) {
storeConfig := false
reqStatusCode := 0
var status string
@ -146,7 +152,7 @@ func Login(authConfig AuthConfig) (string, error) {
}
if storeConfig {
authStr := EncodeAuth(authConfig)
saveConfig(authStr, authConfig.Email)
saveConfig(authConfig.rootPath, authStr, authConfig.Email)
}
return status, nil
}

View File

@ -5,7 +5,7 @@ import (
)
func TestEncodeAuth(t *testing.T) {
newAuthConfig := AuthConfig{Username: "ken", Password: "test", Email: "test@example.com"}
newAuthConfig := &AuthConfig{Username: "ken", Password: "test", Email: "test@example.com"}
authStr := EncodeAuth(newAuthConfig)
decAuthConfig, err := DecodeAuth(authStr)
if err != nil {

View File

@ -69,17 +69,13 @@ func (srv *Server) CmdLogin(stdin io.ReadCloser, stdout io.Writer, args ...strin
var username string
var password string
var email string
authConfig, err := auth.LoadConfig()
if err != nil {
fmt.Fprintf(stdout, "Error : %s\n", err)
}
fmt.Fprint(stdout, "Username (", authConfig.Username, "): ")
fmt.Fprint(stdout, "Username (", srv.runtime.authConfig.Username, "): ")
fmt.Fscanf(stdin, "%s", &username)
if username == "" {
username = authConfig.Username
username = srv.runtime.authConfig.Username
}
if username != authConfig.Username {
if username != srv.runtime.authConfig.Username {
fmt.Fprint(stdout, "Password: ")
fmt.Fscanf(stdin, "%s", &password)
@ -87,16 +83,16 @@ func (srv *Server) CmdLogin(stdin io.ReadCloser, stdout io.Writer, args ...strin
return errors.New("Error : Password Required\n")
}
fmt.Fprint(stdout, "Email (", authConfig.Email, "): ")
fmt.Fprint(stdout, "Email (", srv.runtime.authConfig.Email, "): ")
fmt.Fscanf(stdin, "%s", &email)
if email == "" {
email = authConfig.Email
email = srv.runtime.authConfig.Email
}
} else {
password = authConfig.Password
email = authConfig.Email
password = srv.runtime.authConfig.Password
email = srv.runtime.authConfig.Email
}
newAuthConfig := auth.AuthConfig{Username: username, Password: password, Email: email}
newAuthConfig := &auth.AuthConfig{Username: username, Password: password, Email: email}
status, err := auth.Login(newAuthConfig)
if err != nil {
fmt.Fprintf(stdout, "Error : %s\n", err)
@ -473,7 +469,7 @@ func (srv *Server) CmdPull(stdin io.ReadCloser, stdout io.Writer, args ...string
return fmt.Errorf("Not loggin and no user specified\n")
}
// FIXME: Allow pull repo:tag
return srv.runtime.graph.PullRepository(*user, cmd.Arg(0), "", srv.runtime.repositories)
return srv.runtime.graph.PullRepository(*user, cmd.Arg(0), "", srv.runtime.repositories, srv.runtime.authConfig)
}
func (srv *Server) CmdImages(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
@ -867,9 +863,6 @@ func NewServer() (*Server, error) {
if runtime.GOARCH != "amd64" {
log.Fatalf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH)
}
// if err != nil {
// return nil, err
// }
runtime, err := NewRuntime()
if err != nil {
return nil, err

View File

@ -129,19 +129,15 @@ func (graph *Graph) PullImage(imgId string) error {
}
// FIXME: Handle the askedTag parameter
func (graph *Graph) PullRepository(user, repoName, askedTag string, repositories *TagStore) error {
func (graph *Graph) PullRepository(user, repoName, askedTag string, repositories *TagStore, authConfig *auth.AuthConfig) error {
client := &http.Client{}
req, err := http.NewRequest("GET", REGISTRY_ENDPOINT+"/users/"+user+"/"+repoName, nil)
if err != nil {
return err
}
authStruct, err := auth.LoadConfig()
if err != nil {
return err
}
req.SetBasicAuth(authStruct.Username, authStruct.Password)
req.SetBasicAuth(authConfig.Username, authConfig.Password)
res, err := client.Do(req)
if err != nil {
return err

View File

@ -3,6 +3,7 @@ package docker
import (
"container/list"
"fmt"
"github.com/dotcloud/docker/auth"
"io"
"io/ioutil"
"log"
@ -20,6 +21,7 @@ type Runtime struct {
networkManager *NetworkManager
graph *Graph
repositories *TagStore
authConfig *auth.AuthConfig
}
var sysInitPath string
@ -246,6 +248,11 @@ func NewRuntimeFromDirectory(root string) (*Runtime, error) {
if err != nil {
return nil, err
}
authConfig, err := auth.LoadConfig(root)
if err != nil && authConfig == nil {
// If the auth file does not exist, keep going
return nil, err
}
runtime := &Runtime{
root: root,
@ -254,6 +261,7 @@ func NewRuntimeFromDirectory(root string) (*Runtime, error) {
networkManager: netManager,
graph: g,
repositories: repositories,
authConfig: authConfig,
}
if err := runtime.restore(); err != nil {