Victor Vieux před 12 roky
rodič
revize
faae7220c0
3 změnil soubory, kde provedl 75 přidání a 63 odebrání
  1. 44 32
      api.go
  2. 26 26
      api_test.go
  3. 5 5
      commands.go

+ 44 - 32
api.go

@@ -13,6 +13,8 @@ import (
 	"strings"
 	"strings"
 )
 )
 
 
+const API_VERSION = 1.0
+
 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 {
@@ -56,7 +58,7 @@ 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 {
+func getAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	b, err := json.Marshal(srv.registry.GetAuthConfig())
 	b, err := json.Marshal(srv.registry.GetAuthConfig())
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -65,7 +67,7 @@ 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 {
 	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
@@ -94,7 +96,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 +106,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 +118,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 +131,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 +154,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 +171,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 +188,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 +205,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 getContainersPs(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 +229,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 +251,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 +278,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
 	}
 	}
@@ -299,7 +301,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 +319,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
 	}
 	}
@@ -335,7 +337,7 @@ func postImagesInsert(srv *Server, w http.ResponseWriter, r *http.Request, vars
 	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 +354,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 +384,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 +403,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 +423,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 +435,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 +447,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 +468,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 +485,7 @@ 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 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
 	}
 	}
@@ -526,7 +528,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 +546,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 +564,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
@@ -589,7 +591,7 @@ 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,
@@ -633,7 +635,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,10 +646,20 @@ 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)
 		}
 		}
 	}
 	}
 
 

+ 26 - 26
api_test.go

@@ -48,7 +48,7 @@ func TestGetAuth(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := postAuth(srv, r, req, nil); err != nil {
+	if err := postAuth(srv, API_VERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -74,7 +74,7 @@ func TestGetVersion(t *testing.T) {
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
 
 
-	if err := getVersion(srv, r, nil, nil); err != nil {
+	if err := getVersion(srv, API_VERSION, r, nil, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -98,7 +98,7 @@ func TestGetInfo(t *testing.T) {
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
 
 
-	if err := getInfo(srv, r, nil, nil); err != nil {
+	if err := getInfo(srv, API_VERSION, r, nil, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -129,7 +129,7 @@ func TestGetImagesJson(t *testing.T) {
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
 
 
-	if err := getImagesJson(srv, r, req, nil); err != nil {
+	if err := getImagesJson(srv, API_VERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -154,7 +154,7 @@ func TestGetImagesJson(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := getImagesJson(srv, r2, req2, nil); err != nil {
+	if err := getImagesJson(srv, API_VERSION, r2, req2, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -179,7 +179,7 @@ func TestGetImagesJson(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := getImagesJson(srv, r3, req3, nil); err != nil {
+	if err := getImagesJson(srv, API_VERSION, r3, req3, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -200,7 +200,7 @@ func TestGetImagesJson(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	err = getImagesJson(srv, r4, req4, nil)
+	err = getImagesJson(srv, API_VERSION, r4, req4, nil)
 	if err == nil {
 	if err == nil {
 		t.Fatalf("Error expected, received none")
 		t.Fatalf("Error expected, received none")
 	}
 	}
@@ -221,7 +221,7 @@ func TestGetImagesViz(t *testing.T) {
 	srv := &Server{runtime: runtime}
 	srv := &Server{runtime: runtime}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getImagesViz(srv, r, nil, nil); err != nil {
+	if err := getImagesViz(srv, API_VERSION, r, nil, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -258,7 +258,7 @@ func TestGetImagesSearch(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := getImagesSearch(srv, r, req, nil); err != nil {
+	if err := getImagesSearch(srv, API_VERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -282,7 +282,7 @@ func TestGetImagesHistory(t *testing.T) {
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
 
 
-	if err := getImagesHistory(srv, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
+	if err := getImagesHistory(srv, API_VERSION, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -305,7 +305,7 @@ func TestGetImagesByName(t *testing.T) {
 	srv := &Server{runtime: runtime}
 	srv := &Server{runtime: runtime}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getImagesByName(srv, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
+	if err := getImagesByName(srv, API_VERSION, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -342,7 +342,7 @@ func TestGetContainersPs(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getContainersPs(srv, r, req, nil); err != nil {
+	if err := getContainersPs(srv, API_VERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	containers := []ApiContainers{}
 	containers := []ApiContainers{}
@@ -385,7 +385,7 @@ func TestGetContainersExport(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err = getContainersExport(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err = getContainersExport(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -440,7 +440,7 @@ func TestGetContainersChanges(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getContainersChanges(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err := getContainersChanges(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	changes := []Change{}
 	changes := []Change{}
@@ -484,7 +484,7 @@ func TestGetContainersByName(t *testing.T) {
 	defer runtime.Destroy(container)
 	defer runtime.Destroy(container)
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getContainersByName(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err := getContainersByName(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	outContainer := &Container{}
 	outContainer := &Container{}
@@ -515,7 +515,7 @@ func TestPostAuth(t *testing.T) {
 	srv.registry.ResetClient(authConfigOrig)
 	srv.registry.ResetClient(authConfigOrig)
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getAuth(srv, r, nil, nil); err != nil {
+	if err := getAuth(srv, API_VERSION, r, nil, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -562,7 +562,7 @@ func TestPostCommit(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postCommit(srv, r, req, nil); err != nil {
+	if err := postCommit(srv, API_VERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusCreated {
 	if r.Code != http.StatusCreated {
@@ -840,7 +840,7 @@ func TestPostContainersCreate(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersCreate(srv, r, req, nil); err != nil {
+	if err := postContainersCreate(srv, API_VERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusCreated {
 	if r.Code != http.StatusCreated {
@@ -903,7 +903,7 @@ func TestPostContainersKill(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersKill(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err := postContainersKill(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusNoContent {
 	if r.Code != http.StatusNoContent {
@@ -951,7 +951,7 @@ func TestPostContainersRestart(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersRestart(srv, r, req, map[string]string{"name": container.Id}); err != nil {
+	if err := postContainersRestart(srv, API_VERSION, r, req, map[string]string{"name": container.Id}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusNoContent {
 	if r.Code != http.StatusNoContent {
@@ -992,7 +992,7 @@ func TestPostContainersStart(t *testing.T) {
 	defer runtime.Destroy(container)
 	defer runtime.Destroy(container)
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersStart(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err := postContainersStart(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusNoContent {
 	if r.Code != http.StatusNoContent {
@@ -1007,7 +1007,7 @@ func TestPostContainersStart(t *testing.T) {
 	}
 	}
 
 
 	r = httptest.NewRecorder()
 	r = httptest.NewRecorder()
-	if err = postContainersStart(srv, r, nil, map[string]string{"name": container.Id}); err == nil {
+	if err = postContainersStart(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err == nil {
 		t.Fatalf("A running containter should be able to be started")
 		t.Fatalf("A running containter should be able to be started")
 	}
 	}
 
 
@@ -1054,7 +1054,7 @@ func TestPostContainersStop(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersStop(srv, r, req, map[string]string{"name": container.Id}); err != nil {
+	if err := postContainersStop(srv, API_VERSION, r, req, map[string]string{"name": container.Id}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusNoContent {
 	if r.Code != http.StatusNoContent {
@@ -1092,7 +1092,7 @@ func TestPostContainersWait(t *testing.T) {
 
 
 	setTimeout(t, "Wait timed out", 3*time.Second, func() {
 	setTimeout(t, "Wait timed out", 3*time.Second, func() {
 		r := httptest.NewRecorder()
 		r := httptest.NewRecorder()
-		if err := postContainersWait(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
+		if err := postContainersWait(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
 			t.Fatal(err)
 			t.Fatal(err)
 		}
 		}
 		apiWait := &ApiWait{}
 		apiWait := &ApiWait{}
@@ -1154,7 +1154,7 @@ func TestPostContainersAttach(t *testing.T) {
 			t.Fatal(err)
 			t.Fatal(err)
 		}
 		}
 
 
-		if err := postContainersAttach(srv, r, req, map[string]string{"name": container.Id}); err != nil {
+		if err := postContainersAttach(srv, API_VERSION, r, req, map[string]string{"name": container.Id}); err != nil {
 			t.Fatal(err)
 			t.Fatal(err)
 		}
 		}
 	}()
 	}()
@@ -1224,7 +1224,7 @@ func TestDeleteContainers(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := deleteContainers(srv, r, req, map[string]string{"name": container.Id}); err != nil {
+	if err := deleteContainers(srv, API_VERSION, r, req, map[string]string{"name": container.Id}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusNoContent {
 	if r.Code != http.StatusNoContent {

+ 5 - 5
commands.go

@@ -1167,7 +1167,7 @@ func (cli *DockerCli) call(method, path string, data interface{}) ([]byte, int,
 		params = bytes.NewBuffer(buf)
 		params = bytes.NewBuffer(buf)
 	}
 	}
 
 
-	req, err := http.NewRequest(method, fmt.Sprintf("http://%s:%d", cli.host, cli.port)+path, params)
+	req, err := http.NewRequest(method, fmt.Sprintf("http://%s:%d/v%f", cli.host, cli.port, API_VERSION)+path, params)
 	if err != nil {
 	if err != nil {
 		return nil, -1, err
 		return nil, -1, err
 	}
 	}
@@ -1199,7 +1199,7 @@ func (cli *DockerCli) stream(method, path string, in io.Reader, out io.Writer) e
 	if (method == "POST" || method == "PUT") && in == nil {
 	if (method == "POST" || method == "PUT") && in == nil {
 		in = bytes.NewReader([]byte{})
 		in = bytes.NewReader([]byte{})
 	}
 	}
-	req, err := http.NewRequest(method, fmt.Sprintf("http://%s:%d%s", cli.host, cli.port, path), in)
+	req, err := http.NewRequest(method, fmt.Sprintf("http://%s:%d/v%f%s", cli.host, cli.port, API_VERSION, path), in)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -1230,7 +1230,7 @@ func (cli *DockerCli) stream(method, path string, in io.Reader, out io.Writer) e
 }
 }
 
 
 func (cli *DockerCli) hijack(method, path string, setRawTerminal bool) error {
 func (cli *DockerCli) hijack(method, path string, setRawTerminal bool) error {
-	req, err := http.NewRequest(method, path, nil)
+	req, err := http.NewRequest(method, fmt.Sprintf("/v%f%s", API_VERSION, path), nil)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -1294,6 +1294,6 @@ func NewDockerCli(host string, port int) *DockerCli {
 }
 }
 
 
 type DockerCli struct {
 type DockerCli struct {
-	host string
-	port int
+	host       string
+	port       int
 }
 }