|
@@ -13,6 +13,8 @@ import (
|
|
"strings"
|
|
"strings"
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+const API_VERSION = 1.1
|
|
|
|
+
|
|
func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
|
|
func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
|
|
conn, _, err := w.(http.Hijacker).Hijack()
|
|
conn, _, err := w.(http.Hijacker).Hijack()
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -31,6 +33,13 @@ func parseForm(r *http.Request) error {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func parseMultipartForm(r *http.Request) error {
|
|
|
|
+ if err := r.ParseMultipartForm(4096); err != nil && !strings.HasPrefix(err.Error(), "mime:") {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
func httpError(w http.ResponseWriter, err error) {
|
|
func httpError(w http.ResponseWriter, err error) {
|
|
if strings.HasPrefix(err.Error(), "No such") {
|
|
if strings.HasPrefix(err.Error(), "No such") {
|
|
http.Error(w, err.Error(), http.StatusNotFound)
|
|
http.Error(w, err.Error(), http.StatusNotFound)
|
|
@@ -46,6 +55,7 @@ func writeJson(w http.ResponseWriter, b []byte) {
|
|
w.Write(b)
|
|
w.Write(b)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// FIXME: Use stvconv.ParseBool() instead?
|
|
func getBoolParam(value string) (bool, error) {
|
|
func getBoolParam(value string) (bool, error) {
|
|
if value == "1" || strings.ToLower(value) == "true" {
|
|
if value == "1" || strings.ToLower(value) == "true" {
|
|
return true, nil
|
|
return true, nil
|
|
@@ -56,8 +66,17 @@ func getBoolParam(value string) (bool, error) {
|
|
return false, fmt.Errorf("Bad parameter")
|
|
return false, fmt.Errorf("Bad parameter")
|
|
}
|
|
}
|
|
|
|
|
|
-func getAuth(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
- b, err := json.Marshal(srv.registry.GetAuthConfig())
|
|
|
|
|
|
+func getAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
+ // FIXME: Handle multiple login at once
|
|
|
|
+ // FIXME: return specific error code if config file missing?
|
|
|
|
+ authConfig, err := auth.LoadConfig(srv.runtime.root)
|
|
|
|
+ if err != nil {
|
|
|
|
+ if err != auth.ErrConfigFileMissing {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ authConfig = &auth.AuthConfig{}
|
|
|
|
+ }
|
|
|
|
+ b, err := json.Marshal(&auth.AuthConfig{Username: authConfig.Username, Email: authConfig.Email})
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -65,14 +84,22 @@ func getAuth(srv *Server, w http.ResponseWriter, r *http.Request, vars map[strin
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postAuth(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
+ // FIXME: Handle multiple login at once
|
|
config := &auth.AuthConfig{}
|
|
config := &auth.AuthConfig{}
|
|
if err := json.NewDecoder(r.Body).Decode(config); err != nil {
|
|
if err := json.NewDecoder(r.Body).Decode(config); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
- if config.Username == srv.registry.GetAuthConfig().Username {
|
|
|
|
- config.Password = srv.registry.GetAuthConfig().Password
|
|
|
|
|
|
+ authConfig, err := auth.LoadConfig(srv.runtime.root)
|
|
|
|
+ if err != nil {
|
|
|
|
+ if err != auth.ErrConfigFileMissing {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ authConfig = &auth.AuthConfig{}
|
|
|
|
+ }
|
|
|
|
+ if config.Username == authConfig.Username {
|
|
|
|
+ config.Password = authConfig.Password
|
|
}
|
|
}
|
|
|
|
|
|
newAuthConfig := auth.NewAuthConfig(config.Username, config.Password, config.Email, srv.runtime.root)
|
|
newAuthConfig := auth.NewAuthConfig(config.Username, config.Password, config.Email, srv.runtime.root)
|
|
@@ -80,7 +107,6 @@ func postAuth(srv *Server, w http.ResponseWriter, r *http.Request, vars map[stri
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
- srv.registry.ResetClient(newAuthConfig)
|
|
|
|
|
|
|
|
if status != "" {
|
|
if status != "" {
|
|
b, err := json.Marshal(&ApiAuth{Status: status})
|
|
b, err := json.Marshal(&ApiAuth{Status: status})
|
|
@@ -94,7 +120,7 @@ func postAuth(srv *Server, w http.ResponseWriter, r *http.Request, vars map[stri
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getVersion(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getVersion(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
m := srv.DockerVersion()
|
|
m := srv.DockerVersion()
|
|
b, err := json.Marshal(m)
|
|
b, err := json.Marshal(m)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -104,7 +130,7 @@ func getVersion(srv *Server, w http.ResponseWriter, r *http.Request, vars map[st
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersKill(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postContainersKill(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -116,7 +142,7 @@ func postContainersKill(srv *Server, w http.ResponseWriter, r *http.Request, var
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersExport(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getContainersExport(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -129,7 +155,7 @@ func getContainersExport(srv *Server, w http.ResponseWriter, r *http.Request, va
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesJson(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getImagesJson(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -152,14 +178,14 @@ func getImagesJson(srv *Server, w http.ResponseWriter, r *http.Request, vars map
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesViz(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getImagesViz(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := srv.ImagesViz(w); err != nil {
|
|
if err := srv.ImagesViz(w); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getInfo(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getInfo(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
out := srv.DockerInfo()
|
|
out := srv.DockerInfo()
|
|
b, err := json.Marshal(out)
|
|
b, err := json.Marshal(out)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -169,7 +195,7 @@ func getInfo(srv *Server, w http.ResponseWriter, r *http.Request, vars map[strin
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesHistory(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getImagesHistory(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -186,7 +212,7 @@ func getImagesHistory(srv *Server, w http.ResponseWriter, r *http.Request, vars
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersChanges(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getContainersChanges(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -203,7 +229,7 @@ func getContainersChanges(srv *Server, w http.ResponseWriter, r *http.Request, v
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersPs(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getContainersJson(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -227,7 +253,7 @@ func getContainersPs(srv *Server, w http.ResponseWriter, r *http.Request, vars m
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postImagesTag(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postImagesTag(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -249,7 +275,7 @@ func postImagesTag(srv *Server, w http.ResponseWriter, r *http.Request, vars map
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postCommit(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postCommit(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -276,7 +302,7 @@ func postCommit(srv *Server, w http.ResponseWriter, r *http.Request, vars map[st
|
|
}
|
|
}
|
|
|
|
|
|
// Creates an image from Pull or from Import
|
|
// Creates an image from Pull or from Import
|
|
-func postImagesCreate(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postImagesCreate(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -288,7 +314,10 @@ func postImagesCreate(srv *Server, w http.ResponseWriter, r *http.Request, vars
|
|
|
|
|
|
if image != "" { //pull
|
|
if image != "" { //pull
|
|
registry := r.Form.Get("registry")
|
|
registry := r.Form.Get("registry")
|
|
- if err := srv.ImagePull(image, tag, registry, w); err != nil {
|
|
|
|
|
|
+ if version > 1.0 {
|
|
|
|
+ w.Header().Set("Content-Type", "application/json")
|
|
|
|
+ }
|
|
|
|
+ if err := srv.ImagePull(image, tag, registry, w, version > 1.0); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
} else { //import
|
|
} else { //import
|
|
@@ -299,7 +328,7 @@ func postImagesCreate(srv *Server, w http.ResponseWriter, r *http.Request, vars
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesSearch(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getImagesSearch(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -317,7 +346,7 @@ func getImagesSearch(srv *Server, w http.ResponseWriter, r *http.Request, vars m
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postImagesInsert(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postImagesInsert(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -329,13 +358,19 @@ func postImagesInsert(srv *Server, w http.ResponseWriter, r *http.Request, vars
|
|
}
|
|
}
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
|
|
|
|
- if err := srv.ImageInsert(name, url, path, w); err != nil {
|
|
|
|
|
|
+ imgId, err := srv.ImageInsert(name, url, path, w)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ b, err := json.Marshal(&ApiId{Id: imgId})
|
|
|
|
+ if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
+ writeJson(w, b)
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postImagesPush(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postImagesPush(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -352,7 +387,7 @@ func postImagesPush(srv *Server, w http.ResponseWriter, r *http.Request, vars ma
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersCreate(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
config := &Config{}
|
|
config := &Config{}
|
|
if err := json.NewDecoder(r.Body).Decode(config); err != nil {
|
|
if err := json.NewDecoder(r.Body).Decode(config); err != nil {
|
|
return err
|
|
return err
|
|
@@ -382,7 +417,7 @@ func postContainersCreate(srv *Server, w http.ResponseWriter, r *http.Request, v
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersRestart(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postContainersRestart(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -401,7 +436,7 @@ func postContainersRestart(srv *Server, w http.ResponseWriter, r *http.Request,
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func deleteContainers(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func deleteContainers(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -421,7 +456,7 @@ func deleteContainers(srv *Server, w http.ResponseWriter, r *http.Request, vars
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func deleteImages(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func deleteImages(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -433,7 +468,7 @@ func deleteImages(srv *Server, w http.ResponseWriter, r *http.Request, vars map[
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersStart(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postContainersStart(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -445,7 +480,7 @@ func postContainersStart(srv *Server, w http.ResponseWriter, r *http.Request, va
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersStop(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postContainersStop(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -466,7 +501,7 @@ func postContainersStop(srv *Server, w http.ResponseWriter, r *http.Request, var
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersWait(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postContainersWait(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -483,7 +518,29 @@ func postContainersWait(srv *Server, w http.ResponseWriter, r *http.Request, var
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersAttach(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postContainersResize(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
+ if err := parseForm(r); err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ height, err := strconv.Atoi(r.Form.Get("h"))
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ width, err := strconv.Atoi(r.Form.Get("w"))
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ if vars == nil {
|
|
|
|
+ return fmt.Errorf("Missing parameter")
|
|
|
|
+ }
|
|
|
|
+ name := vars["name"]
|
|
|
|
+ if err := srv.ContainerResize(name, height, width); err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func postContainersAttach(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -513,6 +570,10 @@ func postContainersAttach(srv *Server, w http.ResponseWriter, r *http.Request, v
|
|
}
|
|
}
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
|
|
|
|
|
|
+ if _, err := srv.ContainerInspect(name); err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
in, out, err := hijackServer(w)
|
|
in, out, err := hijackServer(w)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
@@ -526,7 +587,7 @@ func postContainersAttach(srv *Server, w http.ResponseWriter, r *http.Request, v
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersByName(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getContainersByName(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -544,7 +605,7 @@ func getContainersByName(srv *Server, w http.ResponseWriter, r *http.Request, va
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesByName(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func getImagesByName(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -562,7 +623,7 @@ func getImagesByName(srv *Server, w http.ResponseWriter, r *http.Request, vars m
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postImagesGetCache(srv *Server, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func postImagesGetCache(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
apiConfig := &ApiImageConfig{}
|
|
apiConfig := &ApiImageConfig{}
|
|
if err := json.NewDecoder(r.Body).Decode(apiConfig); err != nil {
|
|
if err := json.NewDecoder(r.Body).Decode(apiConfig); err != nil {
|
|
return err
|
|
return err
|
|
@@ -585,11 +646,35 @@ func postImagesGetCache(srv *Server, w http.ResponseWriter, r *http.Request, var
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
+ if err := r.ParseMultipartForm(4096); err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dockerfile, _, err := r.FormFile("Dockerfile")
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ context, _, err := r.FormFile("Context")
|
|
|
|
+ if err != nil {
|
|
|
|
+ if err != http.ErrMissingFile {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ b := NewBuildFile(srv, utils.NewWriteFlusher(w))
|
|
|
|
+ if _, err := b.Build(dockerfile, context); err != nil {
|
|
|
|
+ fmt.Fprintf(w, "Error build: %s\n", err)
|
|
|
|
+ }
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
func ListenAndServe(addr string, srv *Server, logging bool) error {
|
|
func ListenAndServe(addr string, srv *Server, logging bool) error {
|
|
r := mux.NewRouter()
|
|
r := mux.NewRouter()
|
|
log.Printf("Listening for HTTP on %s\n", addr)
|
|
log.Printf("Listening for HTTP on %s\n", addr)
|
|
|
|
|
|
- m := map[string]map[string]func(*Server, http.ResponseWriter, *http.Request, map[string]string) error{
|
|
|
|
|
|
+ m := map[string]map[string]func(*Server, float64, http.ResponseWriter, *http.Request, map[string]string) error{
|
|
"GET": {
|
|
"GET": {
|
|
"/auth": getAuth,
|
|
"/auth": getAuth,
|
|
"/version": getVersion,
|
|
"/version": getVersion,
|
|
@@ -599,7 +684,8 @@ func ListenAndServe(addr string, srv *Server, logging bool) error {
|
|
"/images/search": getImagesSearch,
|
|
"/images/search": getImagesSearch,
|
|
"/images/{name:.*}/history": getImagesHistory,
|
|
"/images/{name:.*}/history": getImagesHistory,
|
|
"/images/{name:.*}/json": getImagesByName,
|
|
"/images/{name:.*}/json": getImagesByName,
|
|
- "/containers/ps": getContainersPs,
|
|
|
|
|
|
+ "/containers/ps": getContainersJson,
|
|
|
|
+ "/containers/json": getContainersJson,
|
|
"/containers/{name:.*}/export": getContainersExport,
|
|
"/containers/{name:.*}/export": getContainersExport,
|
|
"/containers/{name:.*}/changes": getContainersChanges,
|
|
"/containers/{name:.*}/changes": getContainersChanges,
|
|
"/containers/{name:.*}/json": getContainersByName,
|
|
"/containers/{name:.*}/json": getContainersByName,
|
|
@@ -607,6 +693,7 @@ func ListenAndServe(addr string, srv *Server, logging bool) error {
|
|
"POST": {
|
|
"POST": {
|
|
"/auth": postAuth,
|
|
"/auth": postAuth,
|
|
"/commit": postCommit,
|
|
"/commit": postCommit,
|
|
|
|
+ "/build": postBuild,
|
|
"/images/create": postImagesCreate,
|
|
"/images/create": postImagesCreate,
|
|
"/images/{name:.*}/insert": postImagesInsert,
|
|
"/images/{name:.*}/insert": postImagesInsert,
|
|
"/images/{name:.*}/push": postImagesPush,
|
|
"/images/{name:.*}/push": postImagesPush,
|
|
@@ -618,6 +705,7 @@ func ListenAndServe(addr string, srv *Server, logging bool) error {
|
|
"/containers/{name:.*}/start": postContainersStart,
|
|
"/containers/{name:.*}/start": postContainersStart,
|
|
"/containers/{name:.*}/stop": postContainersStop,
|
|
"/containers/{name:.*}/stop": postContainersStop,
|
|
"/containers/{name:.*}/wait": postContainersWait,
|
|
"/containers/{name:.*}/wait": postContainersWait,
|
|
|
|
+ "/containers/{name:.*}/resize": postContainersResize,
|
|
"/containers/{name:.*}/attach": postContainersAttach,
|
|
"/containers/{name:.*}/attach": postContainersAttach,
|
|
},
|
|
},
|
|
"DELETE": {
|
|
"DELETE": {
|
|
@@ -633,7 +721,7 @@ func ListenAndServe(addr string, srv *Server, logging bool) error {
|
|
localRoute := route
|
|
localRoute := route
|
|
localMethod := method
|
|
localMethod := method
|
|
localFct := fct
|
|
localFct := fct
|
|
- r.Path(localRoute).Methods(localMethod).HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
+ f := func(w http.ResponseWriter, r *http.Request) {
|
|
utils.Debugf("Calling %s %s", localMethod, localRoute)
|
|
utils.Debugf("Calling %s %s", localMethod, localRoute)
|
|
if logging {
|
|
if logging {
|
|
log.Println(r.Method, r.RequestURI)
|
|
log.Println(r.Method, r.RequestURI)
|
|
@@ -644,12 +732,21 @@ func ListenAndServe(addr string, srv *Server, logging bool) error {
|
|
utils.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], VERSION)
|
|
utils.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], VERSION)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if err := localFct(srv, w, r, mux.Vars(r)); err != nil {
|
|
|
|
|
|
+ version, err := strconv.ParseFloat(mux.Vars(r)["version"], 64)
|
|
|
|
+ if err != nil {
|
|
|
|
+ version = API_VERSION
|
|
|
|
+ }
|
|
|
|
+ if version == 0 || version > API_VERSION {
|
|
|
|
+ w.WriteHeader(http.StatusNotFound)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if err := localFct(srv, version, w, r, mux.Vars(r)); err != nil {
|
|
httpError(w, err)
|
|
httpError(w, err)
|
|
}
|
|
}
|
|
- })
|
|
|
|
|
|
+ }
|
|
|
|
+ r.Path("/v{version:[0-9.]+}" + localRoute).Methods(localMethod).HandlerFunc(f)
|
|
|
|
+ r.Path(localRoute).Methods(localMethod).HandlerFunc(f)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
return http.ListenAndServe(addr, r)
|
|
return http.ListenAndServe(addr, r)
|
|
}
|
|
}
|