Browse code

added docs and moved to api version 1.2

Victor Vieux authored on 2013/06/03 21:09:16
Showing 3 changed files
... ...
@@ -13,7 +13,7 @@ import (
13 13
 	"strings"
14 14
 )
15 15
 
16
-const API_VERSION = 1.1
16
+const API_VERSION = 1.2
17 17
 
18 18
 func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
19 19
 	conn, _, err := w.(http.Hijacker).Hijack()
... ...
@@ -68,15 +68,55 @@ func getBoolParam(value string) (bool, error) {
68 68
 	return false, fmt.Errorf("Bad parameter")
69 69
 }
70 70
 
71
-func postAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
72
-	authConfig := &auth.AuthConfig{}
73
-	if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil {
71
+func getAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
72
+	if version > 1.1 {
73
+		w.WriteHeader(http.StatusNotFound)
74
+		return nil
75
+	}
76
+	authConfig, err := auth.LoadConfig(srv.runtime.root)
77
+	if err != nil {
78
+		if err != auth.ErrConfigFileMissing {
79
+			return err
80
+		}
81
+		authConfig = &auth.AuthConfig{}
82
+	}
83
+	b, err := json.Marshal(&auth.AuthConfig{Username: authConfig.Username, Email: authConfig.Email})
84
+	if err != nil {
74 85
 		return err
75 86
 	}
76
-	status, err := auth.Login(authConfig)
87
+	writeJson(w, b)
88
+	return nil
89
+}
90
+
91
+func postAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
92
+	authConfig := &auth.AuthConfig{}
93
+	err := json.NewDecoder(r.Body).Decode(authConfig)
77 94
 	if err != nil {
78 95
 		return err
79 96
 	}
97
+	status := ""
98
+	if version > 1.1 {
99
+		status, err = auth.Login(authConfig, false)
100
+		if err != nil {
101
+			return err
102
+		}
103
+	} else {
104
+		localAuthConfig, err := auth.LoadConfig(srv.runtime.root)
105
+		if err != nil {
106
+			if err != auth.ErrConfigFileMissing {
107
+				return err
108
+			}
109
+		}
110
+		if authConfig.Username == localAuthConfig.Username {
111
+			authConfig.Password = localAuthConfig.Password
112
+		}
113
+
114
+		newAuthConfig := auth.NewAuthConfig(authConfig.Username, authConfig.Password, authConfig.Email, srv.runtime.root)
115
+		status, err = auth.Login(newAuthConfig, true)
116
+		if err != nil {
117
+			return err
118
+		}
119
+	}
80 120
 	if status != "" {
81 121
 		b, err := json.Marshal(&ApiAuth{Status: status})
82 122
 		if err != nil {
... ...
@@ -288,7 +328,15 @@ func postImagesCreate(srv *Server, version float64, w http.ResponseWriter, r *ht
288 288
 	if image != "" { //pull
289 289
 		registry := r.Form.Get("registry")
290 290
 		authConfig := &auth.AuthConfig{}
291
-		json.NewDecoder(r.Body).Decode(authConfig)
291
+		if version > 1.1 {
292
+			json.NewDecoder(r.Body).Decode(authConfig)
293
+		} else {
294
+			localAuthConfig, err := auth.LoadConfig(srv.runtime.root)
295
+			if err != nil && err != auth.ErrConfigFileMissing {
296
+				return err
297
+			}
298
+			authConfig = localAuthConfig
299
+		}
292 300
 		if err := srv.ImagePull(image, tag, registry, w, sf, authConfig); err != nil {
293 301
 			if sf.Used() {
294 302
 				w.Write(sf.FormatError(err))
... ...
@@ -358,8 +406,16 @@ func postImagesInsert(srv *Server, version float64, w http.ResponseWriter, r *ht
358 358
 
359 359
 func postImagesPush(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
360 360
 	authConfig := &auth.AuthConfig{}
361
-	if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil {
362
-		return err
361
+	if version > 1.1 {
362
+		if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil {
363
+			return err
364
+		}
365
+	} else {
366
+		localAuthConfig, err := auth.LoadConfig(srv.runtime.root)
367
+		if err != nil && err != auth.ErrConfigFileMissing {
368
+			return err
369
+		}
370
+		authConfig = localAuthConfig
363 371
 	}
364 372
 	if err := parseForm(r); err != nil {
365 373
 		return err
... ...
@@ -682,6 +738,7 @@ func ListenAndServe(addr string, srv *Server, logging bool) error {
682 682
 
683 683
 	m := map[string]map[string]func(*Server, float64, http.ResponseWriter, *http.Request, map[string]string) error{
684 684
 		"GET": {
685
+			"/auth":                         getAuth,
685 686
 			"/version":                      getVersion,
686 687
 			"/info":                         getInfo,
687 688
 			"/images/json":                  getImagesJson,
... ...
@@ -120,7 +120,8 @@ func SaveConfig(authConfig *AuthConfig) error {
120 120
 }
121 121
 
122 122
 // try to register/login to the registry server
123
-func Login(authConfig *AuthConfig) (string, error) {
123
+func Login(authConfig *AuthConfig, store bool) (string, error) {
124
+	storeConfig := false
124 125
 	client := &http.Client{}
125 126
 	reqStatusCode := 0
126 127
 	var status string
... ...
@@ -146,6 +147,7 @@ func Login(authConfig *AuthConfig) (string, error) {
146 146
 	if reqStatusCode == 201 {
147 147
 		status = "Account created. Please use the confirmation link we sent" +
148 148
 			" to your e-mail to activate it.\n"
149
+		storeConfig = true
149 150
 	} else if reqStatusCode == 403 {
150 151
 		return "", fmt.Errorf("Login: Your account hasn't been activated. " +
151 152
 			"Please check your e-mail for a confirmation link.")
... ...
@@ -164,7 +166,13 @@ func Login(authConfig *AuthConfig) (string, error) {
164 164
 			}
165 165
 			if resp.StatusCode == 200 {
166 166
 				status = "Login Succeeded\n"
167
+				storeConfig = true
167 168
 			} else if resp.StatusCode == 401 {
169
+				if store {
170
+					if err := SaveConfig(authConfig); err != nil {
171
+						return "", err
172
+					}
173
+				}
168 174
 				return "", fmt.Errorf("Wrong login/password, please try again")
169 175
 			} else {
170 176
 				return "", fmt.Errorf("Login: %s (Code: %d; Headers: %s)", body,
... ...
@@ -176,5 +184,10 @@ func Login(authConfig *AuthConfig) (string, error) {
176 176
 	} else {
177 177
 		return "", fmt.Errorf("Unexpected status code [%d] : %s", reqStatusCode, reqBody)
178 178
 	}
179
+	if storeConfig && store {
180
+		if err := SaveConfig(authConfig); err != nil {
181
+			return "", err
182
+		}
183
+	}
179 184
 	return status, nil
180 185
 }
... ...
@@ -14,12 +14,13 @@ Docker Remote API
14 14
 - The Remote API is replacing rcli
15 15
 - Default port in the docker deamon is 4243 
16 16
 - The API tends to be REST, but for some complex commands, like attach or pull, the HTTP connection is hijacked to transport stdout stdin and stderr
17
+- Since API version 1.2, the auth configuration is now handled client side, so the client has to send the authConfig as POST in /images/create and /images/<name>/pull
17 18
 
18 19
 2. Version
19 20
 ==========
20 21
 
21
-The current verson of the API is 1.1
22
-Calling /images/<name>/insert is the same as calling /v1.1/images/<name>/insert
22
+The current verson of the API is 1.2
23
+Calling /images/<name>/insert is the same as calling /v1.2/images/<name>/insert
23 24
 You can still call an old version of the api using /v1.0/images/<name>/insert
24 25
 
25 26
 3. Endpoints
... ...
@@ -550,11 +551,18 @@ Create an image
550 550
 
551 551
 	Create an image, either by pull it from the registry or by importing it
552 552
 
553
-	**Example request**:
553
+	**Example request v1.0**:
554
+
555
+        .. sourcecode:: http
556
+
557
+           POST /images/create?fromImage=base HTTP/1.1
558
+
559
+	**Example request v1.2**:
554 560
 
555 561
         .. sourcecode:: http
556 562
 
557 563
            POST /images/create?fromImage=base HTTP/1.1
564
+	   {{ authConfig }}
558 565
 
559 566
         **Example response v1.1**:
560 567
 
... ...
@@ -720,11 +728,18 @@ Push an image on the registry
720 720
 
721 721
 	Push the image ``name`` on the registry
722 722
 
723
-	 **Example request**:
723
+	 **Example request v1.0**:
724
+
725
+	 .. sourcecode:: http
726
+
727
+	    POST /images/test/push HTTP/1.1
728
+
729
+	 **Example request v1.2**:
724 730
 
725 731
 	 .. sourcecode:: http
726 732
 
727 733
 	    POST /images/test/push HTTP/1.1
734
+	    {{ authConfig }}
728 735
 
729 736
 	 **Example response v1.1**:
730 737
 
... ...
@@ -875,7 +890,7 @@ Build an image from Dockerfile via stdin
875 875
         :statuscode 500: server error
876 876
 
877 877
 
878
-Get default username and email
878
+Get default username and email <deprecated with 1.2>
879 879
 ******************************
880 880
 
881 881
 .. http:get:: /auth
... ...
@@ -904,8 +919,8 @@ Get default username and email
904 904
         :statuscode 500: server error
905 905
 
906 906
 
907
-Set auth configuration
908
-**********************
907
+Check auth configuration (and store if if api < 1.2)
908
+****************************************************
909 909
 
910 910
 .. http:post:: /auth
911 911