mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
add version pkg
Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
This commit is contained in:
parent
10faefac3b
commit
8dad771daa
6 changed files with 140 additions and 105 deletions
123
api/server.go
123
api/server.go
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/dotcloud/docker/pkg/listenbuffer"
|
"github.com/dotcloud/docker/pkg/listenbuffer"
|
||||||
"github.com/dotcloud/docker/pkg/systemd"
|
"github.com/dotcloud/docker/pkg/systemd"
|
||||||
"github.com/dotcloud/docker/pkg/user"
|
"github.com/dotcloud/docker/pkg/user"
|
||||||
|
"github.com/dotcloud/docker/pkg/version"
|
||||||
"github.com/dotcloud/docker/utils"
|
"github.com/dotcloud/docker/utils"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"io"
|
"io"
|
||||||
|
@ -32,7 +33,7 @@ var (
|
||||||
activationLock chan struct{}
|
activationLock chan struct{}
|
||||||
)
|
)
|
||||||
|
|
||||||
type HttpApiFunc func(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error
|
type HttpApiFunc func(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error
|
||||||
|
|
||||||
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()
|
||||||
|
@ -113,7 +114,7 @@ func getBoolParam(value string) (bool, error) {
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postAuth(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postAuth(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
var (
|
var (
|
||||||
authConfig, err = ioutil.ReadAll(r.Body)
|
authConfig, err = ioutil.ReadAll(r.Body)
|
||||||
job = eng.Job("auth")
|
job = eng.Job("auth")
|
||||||
|
@ -136,13 +137,13 @@ func postAuth(eng *engine.Engine, version string, w http.ResponseWriter, r *http
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getVersion(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getVersion(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
eng.ServeHTTP(w, r)
|
eng.ServeHTTP(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersKill(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersKill(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -160,7 +161,7 @@ func postContainersKill(eng *engine.Engine, version string, w http.ResponseWrite
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainersExport(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getContainersExport(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -172,7 +173,7 @@ func getContainersExport(eng *engine.Engine, version string, w http.ResponseWrit
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImagesJSON(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getImagesJSON(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -186,7 +187,7 @@ func getImagesJSON(eng *engine.Engine, version string, w http.ResponseWriter, r
|
||||||
job.Setenv("filter", r.Form.Get("filter"))
|
job.Setenv("filter", r.Form.Get("filter"))
|
||||||
job.Setenv("all", r.Form.Get("all"))
|
job.Setenv("all", r.Form.Get("all"))
|
||||||
|
|
||||||
if utils.CompareVersion(version, "1.7") >= 0 {
|
if version.GreaterThanOrEqualTo("1.7") {
|
||||||
streamJSON(job, w, false)
|
streamJSON(job, w, false)
|
||||||
} else if outs, err = job.Stdout.AddListTable(); err != nil {
|
} else if outs, err = job.Stdout.AddListTable(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -196,7 +197,7 @@ func getImagesJSON(eng *engine.Engine, version string, w http.ResponseWriter, r
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if utils.CompareVersion(version, "1.7") < 0 && outs != nil { // Convert to legacy format
|
if version.LessThan("1.7") && outs != nil { // Convert to legacy format
|
||||||
outsLegacy := engine.NewTable("Created", 0)
|
outsLegacy := engine.NewTable("Created", 0)
|
||||||
for _, out := range outs.Data {
|
for _, out := range outs.Data {
|
||||||
for _, repoTag := range out.GetList("RepoTags") {
|
for _, repoTag := range out.GetList("RepoTags") {
|
||||||
|
@ -219,8 +220,8 @@ func getImagesJSON(eng *engine.Engine, version string, w http.ResponseWriter, r
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImagesViz(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getImagesViz(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
if utils.CompareVersion(version, "1.6") > 0 {
|
if version.GreaterThan("1.6") {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return fmt.Errorf("This is now implemented in the client.")
|
return fmt.Errorf("This is now implemented in the client.")
|
||||||
}
|
}
|
||||||
|
@ -228,13 +229,13 @@ func getImagesViz(eng *engine.Engine, version string, w http.ResponseWriter, r *
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getInfo(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getInfo(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
eng.ServeHTTP(w, r)
|
eng.ServeHTTP(w, r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEvents(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getEvents(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -245,7 +246,7 @@ func getEvents(eng *engine.Engine, version string, w http.ResponseWriter, r *htt
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImagesHistory(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getImagesHistory(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -259,7 +260,7 @@ func getImagesHistory(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainersChanges(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getContainersChanges(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -269,8 +270,8 @@ func getContainersChanges(eng *engine.Engine, version string, w http.ResponseWri
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainersTop(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getContainersTop(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
if utils.CompareVersion(version, "1.4") < 0 {
|
if version.LessThan("1.4") {
|
||||||
return fmt.Errorf("top was improved a lot since 1.3, Please upgrade your docker client.")
|
return fmt.Errorf("top was improved a lot since 1.3, Please upgrade your docker client.")
|
||||||
}
|
}
|
||||||
if vars == nil {
|
if vars == nil {
|
||||||
|
@ -285,7 +286,7 @@ func getContainersTop(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainersJSON(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getContainersJSON(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -301,7 +302,7 @@ func getContainersJSON(eng *engine.Engine, version string, w http.ResponseWriter
|
||||||
job.Setenv("before", r.Form.Get("before"))
|
job.Setenv("before", r.Form.Get("before"))
|
||||||
job.Setenv("limit", r.Form.Get("limit"))
|
job.Setenv("limit", r.Form.Get("limit"))
|
||||||
|
|
||||||
if utils.CompareVersion(version, "1.5") >= 0 {
|
if version.GreaterThanOrEqualTo("1.5") {
|
||||||
streamJSON(job, w, false)
|
streamJSON(job, w, false)
|
||||||
} else if outs, err = job.Stdout.AddTable(); err != nil {
|
} else if outs, err = job.Stdout.AddTable(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -309,7 +310,7 @@ func getContainersJSON(eng *engine.Engine, version string, w http.ResponseWriter
|
||||||
if err = job.Run(); err != nil {
|
if err = job.Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if utils.CompareVersion(version, "1.5") < 0 { // Convert to legacy format
|
if version.LessThan("1.5") { // Convert to legacy format
|
||||||
for _, out := range outs.Data {
|
for _, out := range outs.Data {
|
||||||
ports := engine.NewTable("", 0)
|
ports := engine.NewTable("", 0)
|
||||||
ports.ReadListFrom([]byte(out.Get("Ports")))
|
ports.ReadListFrom([]byte(out.Get("Ports")))
|
||||||
|
@ -323,7 +324,7 @@ func getContainersJSON(eng *engine.Engine, version string, w http.ResponseWriter
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postImagesTag(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postImagesTag(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -340,7 +341,7 @@ func postImagesTag(eng *engine.Engine, version string, w http.ResponseWriter, r
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postCommit(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postCommit(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -369,7 +370,7 @@ func postCommit(eng *engine.Engine, version string, w http.ResponseWriter, r *ht
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an image from Pull or from Import
|
// Creates an image from Pull or from Import
|
||||||
func postImagesCreate(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postImagesCreate(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -397,7 +398,7 @@ func postImagesCreate(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
job = eng.Job("pull", r.Form.Get("fromImage"), tag)
|
job = eng.Job("pull", r.Form.Get("fromImage"), tag)
|
||||||
job.SetenvBool("parallel", utils.CompareVersion(version, "1.3") > 0)
|
job.SetenvBool("parallel", version.GreaterThan("1.3"))
|
||||||
job.SetenvJson("metaHeaders", metaHeaders)
|
job.SetenvJson("metaHeaders", metaHeaders)
|
||||||
job.SetenvJson("authConfig", authConfig)
|
job.SetenvJson("authConfig", authConfig)
|
||||||
} else { //import
|
} else { //import
|
||||||
|
@ -405,7 +406,7 @@ func postImagesCreate(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
job.Stdin.Add(r.Body)
|
job.Stdin.Add(r.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
if utils.CompareVersion(version, "1.0") > 0 {
|
if version.GreaterThan("1.0") {
|
||||||
job.SetenvBool("json", true)
|
job.SetenvBool("json", true)
|
||||||
streamJSON(job, w, true)
|
streamJSON(job, w, true)
|
||||||
} else {
|
} else {
|
||||||
|
@ -415,14 +416,14 @@ func postImagesCreate(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
if !job.Stdout.Used() {
|
if !job.Stdout.Used() {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sf := utils.NewStreamFormatter(utils.CompareVersion(version, "1.0") > 0)
|
sf := utils.NewStreamFormatter(version.GreaterThan("1.0"))
|
||||||
w.Write(sf.FormatError(err))
|
w.Write(sf.FormatError(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImagesSearch(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getImagesSearch(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -454,7 +455,7 @@ func getImagesSearch(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func postImagesInsert(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postImagesInsert(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -462,7 +463,7 @@ func postImagesInsert(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
return fmt.Errorf("Missing parameter")
|
return fmt.Errorf("Missing parameter")
|
||||||
}
|
}
|
||||||
job := eng.Job("insert", vars["name"], r.Form.Get("url"), r.Form.Get("path"))
|
job := eng.Job("insert", vars["name"], r.Form.Get("url"), r.Form.Get("path"))
|
||||||
if utils.CompareVersion(version, "1.0") > 0 {
|
if version.GreaterThan("1.0") {
|
||||||
job.SetenvBool("json", true)
|
job.SetenvBool("json", true)
|
||||||
streamJSON(job, w, false)
|
streamJSON(job, w, false)
|
||||||
} else {
|
} else {
|
||||||
|
@ -472,14 +473,14 @@ func postImagesInsert(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
if !job.Stdout.Used() {
|
if !job.Stdout.Used() {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sf := utils.NewStreamFormatter(utils.CompareVersion(version, "1.0") > 0)
|
sf := utils.NewStreamFormatter(version.GreaterThan("1.0"))
|
||||||
w.Write(sf.FormatError(err))
|
w.Write(sf.FormatError(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postImagesPush(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postImagesPush(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -513,7 +514,7 @@ func postImagesPush(eng *engine.Engine, version string, w http.ResponseWriter, r
|
||||||
job := eng.Job("push", vars["name"])
|
job := eng.Job("push", vars["name"])
|
||||||
job.SetenvJson("metaHeaders", metaHeaders)
|
job.SetenvJson("metaHeaders", metaHeaders)
|
||||||
job.SetenvJson("authConfig", authConfig)
|
job.SetenvJson("authConfig", authConfig)
|
||||||
if utils.CompareVersion(version, "1.0") > 0 {
|
if version.GreaterThan("1.0") {
|
||||||
job.SetenvBool("json", true)
|
job.SetenvBool("json", true)
|
||||||
streamJSON(job, w, true)
|
streamJSON(job, w, true)
|
||||||
} else {
|
} else {
|
||||||
|
@ -524,17 +525,17 @@ func postImagesPush(eng *engine.Engine, version string, w http.ResponseWriter, r
|
||||||
if !job.Stdout.Used() {
|
if !job.Stdout.Used() {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sf := utils.NewStreamFormatter(utils.CompareVersion(version, "1.0") > 0)
|
sf := utils.NewStreamFormatter(version.GreaterThan("1.0"))
|
||||||
w.Write(sf.FormatError(err))
|
w.Write(sf.FormatError(err))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImagesGet(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getImagesGet(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
if utils.CompareVersion(version, "1.0") > 0 {
|
if version.GreaterThan("1.0") {
|
||||||
w.Header().Set("Content-Type", "application/x-tar")
|
w.Header().Set("Content-Type", "application/x-tar")
|
||||||
}
|
}
|
||||||
job := eng.Job("image_export", vars["name"])
|
job := eng.Job("image_export", vars["name"])
|
||||||
|
@ -542,13 +543,13 @@ func getImagesGet(eng *engine.Engine, version string, w http.ResponseWriter, r *
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func postImagesLoad(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postImagesLoad(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
job := eng.Job("load")
|
job := eng.Job("load")
|
||||||
job.Stdin.Add(r.Body)
|
job.Stdin.Add(r.Body)
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersCreate(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
if err := parseForm(r); err != nil {
|
if err := parseForm(r); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -579,7 +580,7 @@ func postContainersCreate(eng *engine.Engine, version string, w http.ResponseWri
|
||||||
return writeJSON(w, http.StatusCreated, out)
|
return writeJSON(w, http.StatusCreated, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersRestart(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersRestart(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -595,7 +596,7 @@ func postContainersRestart(eng *engine.Engine, version string, w http.ResponseWr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteContainers(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func deleteContainers(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -612,7 +613,7 @@ func deleteContainers(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteImages(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func deleteImages(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -626,7 +627,7 @@ func deleteImages(eng *engine.Engine, version string, w http.ResponseWriter, r *
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersStart(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersStart(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -647,7 +648,7 @@ func postContainersStart(eng *engine.Engine, version string, w http.ResponseWrit
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersStop(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersStop(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -663,7 +664,7 @@ func postContainersStop(eng *engine.Engine, version string, w http.ResponseWrite
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersWait(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersWait(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -685,7 +686,7 @@ func postContainersWait(eng *engine.Engine, version string, w http.ResponseWrite
|
||||||
return writeJSON(w, http.StatusOK, env)
|
return writeJSON(w, http.StatusOK, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersResize(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersResize(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -698,7 +699,7 @@ func postContainersResize(eng *engine.Engine, version string, w http.ResponseWri
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersAttach(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersAttach(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -740,7 +741,7 @@ func postContainersAttach(eng *engine.Engine, version string, w http.ResponseWri
|
||||||
|
|
||||||
fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
|
fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
|
||||||
|
|
||||||
if c.GetSubEnv("Config") != nil && !c.GetSubEnv("Config").GetBool("Tty") && utils.CompareVersion(version, "1.6") >= 0 {
|
if c.GetSubEnv("Config") != nil && !c.GetSubEnv("Config").GetBool("Tty") && version.GreaterThanOrEqualTo("1.6") {
|
||||||
errStream = utils.NewStdWriter(outStream, utils.Stderr)
|
errStream = utils.NewStdWriter(outStream, utils.Stderr)
|
||||||
outStream = utils.NewStdWriter(outStream, utils.Stdout)
|
outStream = utils.NewStdWriter(outStream, utils.Stdout)
|
||||||
} else {
|
} else {
|
||||||
|
@ -763,7 +764,7 @@ func postContainersAttach(eng *engine.Engine, version string, w http.ResponseWri
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func wsContainersAttach(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func wsContainersAttach(eng *engine.Engine, version version.Version, 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
|
||||||
}
|
}
|
||||||
|
@ -795,7 +796,7 @@ func wsContainersAttach(eng *engine.Engine, version string, w http.ResponseWrite
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainersByName(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getContainersByName(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -805,7 +806,7 @@ func getContainersByName(eng *engine.Engine, version string, w http.ResponseWrit
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImagesByName(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func getImagesByName(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -815,8 +816,8 @@ func getImagesByName(eng *engine.Engine, version string, w http.ResponseWriter,
|
||||||
return job.Run()
|
return job.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func postBuild(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postBuild(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
if utils.CompareVersion(version, "1.3") < 0 {
|
if version.LessThan("1.3") {
|
||||||
return fmt.Errorf("Multipart upload for build is no longer supported. Please upgrade your docker client.")
|
return fmt.Errorf("Multipart upload for build is no longer supported. Please upgrade your docker client.")
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
|
@ -831,7 +832,7 @@ func postBuild(eng *engine.Engine, version string, w http.ResponseWriter, r *htt
|
||||||
// Both headers will be parsed and sent along to the daemon, but if a non-empty
|
// Both headers will be parsed and sent along to the daemon, but if a non-empty
|
||||||
// ConfigFile is present, any value provided as an AuthConfig directly will
|
// ConfigFile is present, any value provided as an AuthConfig directly will
|
||||||
// be overridden. See BuildFile::CmdFrom for details.
|
// be overridden. See BuildFile::CmdFrom for details.
|
||||||
if utils.CompareVersion(version, "1.9") < 0 && authEncoded != "" {
|
if version.LessThan("1.9") && authEncoded != "" {
|
||||||
authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
|
authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
|
||||||
if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
|
if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
|
||||||
// for a pull it is not an error if no auth was given
|
// for a pull it is not an error if no auth was given
|
||||||
|
@ -849,7 +850,7 @@ func postBuild(eng *engine.Engine, version string, w http.ResponseWriter, r *htt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if utils.CompareVersion(version, "1.8") >= 0 {
|
if version.GreaterThanOrEqualTo("1.8") {
|
||||||
job.SetenvBool("json", true)
|
job.SetenvBool("json", true)
|
||||||
streamJSON(job, w, true)
|
streamJSON(job, w, true)
|
||||||
} else {
|
} else {
|
||||||
|
@ -868,13 +869,13 @@ func postBuild(eng *engine.Engine, version string, w http.ResponseWriter, r *htt
|
||||||
if !job.Stdout.Used() {
|
if !job.Stdout.Used() {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sf := utils.NewStreamFormatter(utils.CompareVersion(version, "1.8") >= 0)
|
sf := utils.NewStreamFormatter(version.GreaterThanOrEqualTo("1.8"))
|
||||||
w.Write(sf.FormatError(err))
|
w.Write(sf.FormatError(err))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postContainersCopy(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func postContainersCopy(eng *engine.Engine, version version.Version, 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")
|
||||||
}
|
}
|
||||||
|
@ -907,7 +908,7 @@ func postContainersCopy(eng *engine.Engine, version string, w http.ResponseWrite
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func optionsHandler(eng *engine.Engine, version string, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func optionsHandler(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -917,7 +918,7 @@ func writeCorsHeaders(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
|
w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, localRoute string, handlerFunc HttpApiFunc, enableCors bool, dockerVersion string) http.HandlerFunc {
|
func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, localRoute string, handlerFunc HttpApiFunc, enableCors bool, dockerVersion version.Version) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
// log the request
|
// log the request
|
||||||
utils.Debugf("Calling %s %s", localMethod, localRoute)
|
utils.Debugf("Calling %s %s", localMethod, localRoute)
|
||||||
|
@ -928,11 +929,11 @@ func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, local
|
||||||
|
|
||||||
if strings.Contains(r.Header.Get("User-Agent"), "Docker-Client/") {
|
if strings.Contains(r.Header.Get("User-Agent"), "Docker-Client/") {
|
||||||
userAgent := strings.Split(r.Header.Get("User-Agent"), "/")
|
userAgent := strings.Split(r.Header.Get("User-Agent"), "/")
|
||||||
if len(userAgent) == 2 && userAgent[1] != dockerVersion {
|
if len(userAgent) == 2 && !dockerVersion.Equal(userAgent[1]) {
|
||||||
utils.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], dockerVersion)
|
utils.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], dockerVersion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
version := mux.Vars(r)["version"]
|
version := version.Version(mux.Vars(r)["version"])
|
||||||
if version == "" {
|
if version == "" {
|
||||||
version = APIVERSION
|
version = APIVERSION
|
||||||
}
|
}
|
||||||
|
@ -940,7 +941,7 @@ func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, local
|
||||||
writeCorsHeaders(w, r)
|
writeCorsHeaders(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if utils.CompareVersion(version, APIVERSION) == 1 {
|
if version.GreaterThan(APIVERSION) {
|
||||||
http.Error(w, fmt.Errorf("client and server don't have same version (client : %s, server: %s)", version, APIVERSION).Error(), http.StatusNotFound)
|
http.Error(w, fmt.Errorf("client and server don't have same version (client : %s, server: %s)", version, APIVERSION).Error(), http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1039,7 +1040,7 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, dockerVersion st
|
||||||
localMethod := method
|
localMethod := method
|
||||||
|
|
||||||
// build the handler function
|
// build the handler function
|
||||||
f := makeHttpHandler(eng, logging, localMethod, localRoute, localFct, enableCors, dockerVersion)
|
f := makeHttpHandler(eng, logging, localMethod, localRoute, localFct, enableCors, version.Version(dockerVersion))
|
||||||
|
|
||||||
// add the new route
|
// add the new route
|
||||||
if localRoute == "" {
|
if localRoute == "" {
|
||||||
|
@ -1057,7 +1058,7 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, dockerVersion st
|
||||||
// ServeRequest processes a single http request to the docker remote api.
|
// ServeRequest processes a single http request to the docker remote api.
|
||||||
// FIXME: refactor this to be part of Server and not require re-creating a new
|
// FIXME: refactor this to be part of Server and not require re-creating a new
|
||||||
// router each time. This requires first moving ListenAndServe into Server.
|
// router each time. This requires first moving ListenAndServe into Server.
|
||||||
func ServeRequest(eng *engine.Engine, apiversion string, w http.ResponseWriter, req *http.Request) error {
|
func ServeRequest(eng *engine.Engine, apiversion version.Version, w http.ResponseWriter, req *http.Request) error {
|
||||||
router, err := createRouter(eng, false, true, "")
|
router, err := createRouter(eng, false, true, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -2,6 +2,7 @@ package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/dotcloud/docker"
|
"github.com/dotcloud/docker"
|
||||||
|
"github.com/dotcloud/docker/engine"
|
||||||
"github.com/dotcloud/docker/runconfig"
|
"github.com/dotcloud/docker/runconfig"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
52
pkg/version/version.go
Normal file
52
pkg/version/version.go
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Version string
|
||||||
|
|
||||||
|
func (me Version) compareTo(other string) int {
|
||||||
|
var (
|
||||||
|
meTab = strings.Split(string(me), ".")
|
||||||
|
otherTab = strings.Split(other, ".")
|
||||||
|
)
|
||||||
|
for i, s := range meTab {
|
||||||
|
var meInt, otherInt int
|
||||||
|
meInt, _ = strconv.Atoi(s)
|
||||||
|
if len(otherTab) > i {
|
||||||
|
otherInt, _ = strconv.Atoi(otherTab[i])
|
||||||
|
}
|
||||||
|
if meInt > otherInt {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if otherInt > meInt {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(otherTab) > len(meTab) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me Version) LessThan(other string) bool {
|
||||||
|
return me.compareTo(other) == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me Version) LessThanOrEqualTo(other string) bool {
|
||||||
|
return me.compareTo(other) <= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me Version) GreaterThan(other string) bool {
|
||||||
|
return me.compareTo(other) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me Version) GreaterThanOrEqualTo(other string) bool {
|
||||||
|
return me.compareTo(other) >= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me Version) Equal(other string) bool {
|
||||||
|
return me.compareTo(other) == 0
|
||||||
|
}
|
25
pkg/version/version_test.go
Normal file
25
pkg/version/version_test.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func assertVersion(t *testing.T, a, b string, result int) {
|
||||||
|
if r := Version(a).compareTo(b); r != result {
|
||||||
|
t.Fatalf("Unexpected version comparison result. Found %d, expected %d", r, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompareVersion(t *testing.T) {
|
||||||
|
assertVersion(t, "1.12", "1.12", 0)
|
||||||
|
assertVersion(t, "1.05.00.0156", "1.0.221.9289", 1)
|
||||||
|
assertVersion(t, "1", "1.0.1", -1)
|
||||||
|
assertVersion(t, "1.0.1", "1", 1)
|
||||||
|
assertVersion(t, "1.0.1", "1.0.2", -1)
|
||||||
|
assertVersion(t, "1.0.2", "1.0.3", -1)
|
||||||
|
assertVersion(t, "1.0.3", "1.1", -1)
|
||||||
|
assertVersion(t, "1.1", "1.1.1", -1)
|
||||||
|
assertVersion(t, "1.1.1", "1.1.2", -1)
|
||||||
|
assertVersion(t, "1.1.2", "1.2", -1)
|
||||||
|
|
||||||
|
}
|
|
@ -972,27 +972,3 @@ func NewReadCloserWrapper(r io.Reader, closer func() error) io.ReadCloser {
|
||||||
closer: closer,
|
closer: closer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CompareVersion(a, b string) int {
|
|
||||||
var (
|
|
||||||
aa = strings.Split(a, ".")
|
|
||||||
bb = strings.Split(b, ".")
|
|
||||||
)
|
|
||||||
for i, s := range aa {
|
|
||||||
var ai, bi int
|
|
||||||
ai, _ = strconv.Atoi(s)
|
|
||||||
if len(bb) > i {
|
|
||||||
bi, _ = strconv.Atoi(bb[i])
|
|
||||||
}
|
|
||||||
if ai > bi {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
if bi > ai {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(bb) > len(aa) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
|
@ -479,23 +479,3 @@ func StrSlicesEqual(a, b []string) bool {
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func asserVersion(t *testing.T, a, b string, result int) {
|
|
||||||
if r := CompareVersion(a, b); r != result {
|
|
||||||
t.Fatalf("Unexpected version comparison result. Found %d, expected %d", r, result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCompareVersion(t *testing.T) {
|
|
||||||
asserVersion(t, "1.12", "1.12", 0)
|
|
||||||
asserVersion(t, "1.05.00.0156", "1.0.221.9289", 1)
|
|
||||||
asserVersion(t, "1", "1.0.1", -1)
|
|
||||||
asserVersion(t, "1.0.1", "1", 1)
|
|
||||||
asserVersion(t, "1.0.1", "1.0.2", -1)
|
|
||||||
asserVersion(t, "1.0.2", "1.0.3", -1)
|
|
||||||
asserVersion(t, "1.0.3", "1.1", -1)
|
|
||||||
asserVersion(t, "1.1", "1.1.1", -1)
|
|
||||||
asserVersion(t, "1.1.1", "1.1.2", -1)
|
|
||||||
asserVersion(t, "1.1.2", "1.2", -1)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue