Integrate Auth in runtime and make the config file relative to runtime root
This commit is contained in:
parent
5e561a9d52
commit
c72ff318d3
6 changed files with 55 additions and 51 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,3 +7,4 @@ build_src
|
|||
command-line-arguments.test
|
||||
.flymake*
|
||||
docker.test
|
||||
auth/auth.test
|
||||
|
|
62
auth/auth.go
62
auth/auth.go
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
25
commands.go
25
commands.go
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue