Victor Vieux 12 年之前
父节点
当前提交
66d9a73362
共有 54 个文件被更改,包括 1039 次插入1050 次删除
  1. 5 0
      CHANGELOG.md
  2. 4 1
      README.md
  3. 37 37
      api.go
  4. 29 30
      api_params.go
  5. 77 77
      api_test.go
  6. 4 4
      auth/auth.go
  7. 5 5
      builder.go
  8. 20 20
      builder_client.go
  9. 10 10
      buildfile.go
  10. 3 3
      buildfile_test.go
  11. 1 1
      changes.go
  12. 74 73
      commands.go
  13. 46 45
      container.go
  14. 64 33
      container_test.go
  15. 3 3
      contrib/crashTest.go
  16. 0 1
      contrib/docker-build/MAINTAINERS
  17. 0 68
      contrib/docker-build/README
  18. 0 142
      contrib/docker-build/docker-build
  19. 0 13
      contrib/docker-build/example.changefile
  20. 0 3
      contrib/docker-build/myscript
  21. 2 2
      docker/docker.go
  22. 1 1
      docs/Makefile
  23. 10 9
      docs/sources/api/docker_remote_api.rst
  24. 1 1
      docs/sources/contributing/contributing.rst
  25. 26 2
      docs/sources/contributing/devenvironment.rst
  26. 7 5
      docs/sources/faq.rst
  27. 10 0
      docs/sources/installation/ubuntulinux.rst
  28. 1 0
      docs/sources/installation/windows.rst
  29. 1 1
      docs/sources/use/builder.rst
  30. 21 9
      docs/theme/docker/layout.html
  31. 40 1
      docs/theme/docker/static/css/main.css
  32. 38 3
      docs/theme/docker/static/css/main.less
  33. 25 18
      docs/website/gettingstarted/index.html
  34. 29 29
      docs/website/index.html
  35. 21 21
      graph.go
  36. 11 11
      graph_test.go
  37. 15 0
      hack/PRINCIPLES.md
  38. 88 0
      hack/ROADMAP.md
  39. 1 0
      hack/dockerbuilder/MAITAINERS
  40. 17 18
      image.go
  41. 1 1
      lxc_template.go
  42. 7 8
      network.go
  43. 1 1
      network_test.go
  44. 7 0
      packaging/ubuntu/changelog
  45. 41 27
      registry/registry.go
  46. 31 31
      runtime.go
  47. 25 25
      runtime_test.go
  48. 100 88
      server.go
  49. 2 2
      server_test.go
  50. 14 14
      tags.go
  51. 7 105
      term/term.go
  52. 27 5
      term/termios_darwin.go
  53. 22 36
      term/termios_linux.go
  54. 7 7
      utils/utils.go

+ 5 - 0
CHANGELOG.md

@@ -1,5 +1,10 @@
 # Changelog
 # Changelog
 
 
+## 0.4.0 (2013-06-03)
+ + Introducing Builder: 'docker build' builds a container, layer by layer, from a source repository containing a Dockerfile
+ + Introducing Remote API: control Docker programmatically using a simple HTTP/json API
+ * Runtime: various reliability and usability improvements
+
 ## 0.3.4 (2013-05-30)
 ## 0.3.4 (2013-05-30)
  + Builder: 'docker build' builds a container, layer by layer, from a source repository containing a Dockerfile
  + Builder: 'docker build' builds a container, layer by layer, from a source repository containing a Dockerfile
  + Builder: 'docker build -t FOO' applies the tag FOO to the newly built container.
  + Builder: 'docker build -t FOO' applies the tag FOO to the newly built container.

+ 4 - 1
README.md

@@ -251,7 +251,7 @@ Note
 ----
 ----
 
 
 We also keep the documentation in this repository. The website documentation is generated using sphinx using these sources.
 We also keep the documentation in this repository. The website documentation is generated using sphinx using these sources.
-Please find it under docs/sources/ and read more about it https://github.com/dotcloud/docker/master/docs/README.md
+Please find it under docs/sources/ and read more about it https://github.com/dotcloud/docker/tree/master/docs/README.md
 
 
 Please feel free to fix / update the documentation and send us pull requests. More tutorials are also welcome.
 Please feel free to fix / update the documentation and send us pull requests. More tutorials are also welcome.
 
 
@@ -371,4 +371,7 @@ Standard Container Specification
 
 
 #### Security
 #### Security
 
 
+### Legal
+
+Transfers Docker shall be in accordance with any applicable export control or other legal requirements.
 
 

+ 37 - 37
api.go

@@ -13,7 +13,7 @@ import (
 	"strings"
 	"strings"
 )
 )
 
 
-const API_VERSION = 1.1
+const APIVERSION = 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()
@@ -54,7 +54,7 @@ func httpError(w http.ResponseWriter, err error) {
 	}
 	}
 }
 }
 
 
-func writeJson(w http.ResponseWriter, b []byte) {
+func writeJSON(w http.ResponseWriter, b []byte) {
 	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Content-Type", "application/json")
 	w.Write(b)
 	w.Write(b)
 }
 }
@@ -84,7 +84,7 @@ func getAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Reques
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -113,11 +113,11 @@ func postAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Reque
 	}
 	}
 
 
 	if status != "" {
 	if status != "" {
-		b, err := json.Marshal(&ApiAuth{Status: status})
+		b, err := json.Marshal(&APIAuth{Status: status})
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		writeJson(w, b)
+		writeJSON(w, b)
 		return nil
 		return nil
 	}
 	}
 	w.WriteHeader(http.StatusNoContent)
 	w.WriteHeader(http.StatusNoContent)
@@ -130,7 +130,7 @@ func getVersion(srv *Server, version float64, w http.ResponseWriter, r *http.Req
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -159,7 +159,7 @@ func getContainersExport(srv *Server, version float64, w http.ResponseWriter, r
 	return nil
 	return nil
 }
 }
 
 
-func getImagesJson(srv *Server, version float64, 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
 	}
 	}
@@ -178,7 +178,7 @@ func getImagesJson(srv *Server, version float64, w http.ResponseWriter, r *http.
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -195,7 +195,7 @@ func getInfo(srv *Server, version float64, w http.ResponseWriter, r *http.Reques
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -212,7 +212,7 @@ func getImagesHistory(srv *Server, version float64, w http.ResponseWriter, r *ht
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -229,11 +229,11 @@ func getContainersChanges(srv *Server, version float64, w http.ResponseWriter, r
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
-func getContainersJson(srv *Server, version float64, 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
 	}
 	}
@@ -253,7 +253,7 @@ func getContainersJson(srv *Server, version float64, w http.ResponseWriter, r *h
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -296,12 +296,12 @@ func postCommit(srv *Server, version float64, w http.ResponseWriter, r *http.Req
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	b, err := json.Marshal(&ApiId{id})
+	b, err := json.Marshal(&APIID{id})
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 	w.WriteHeader(http.StatusCreated)
 	w.WriteHeader(http.StatusCreated)
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -355,7 +355,7 @@ func getImagesSearch(srv *Server, version float64, w http.ResponseWriter, r *htt
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -374,18 +374,18 @@ func postImagesInsert(srv *Server, version float64, w http.ResponseWriter, r *ht
 		w.Header().Set("Content-Type", "application/json")
 		w.Header().Set("Content-Type", "application/json")
 	}
 	}
 	sf := utils.NewStreamFormatter(version > 1.0)
 	sf := utils.NewStreamFormatter(version > 1.0)
-	imgId, err := srv.ImageInsert(name, url, path, w, sf)
+	imgID, err := srv.ImageInsert(name, url, path, w, sf)
 	if err != nil {
 	if err != nil {
 		if sf.Used() {
 		if sf.Used() {
 			w.Write(sf.FormatError(err))
 			w.Write(sf.FormatError(err))
 			return nil
 			return nil
 		}
 		}
 	}
 	}
-	b, err := json.Marshal(&ApiId{Id: imgId})
+	b, err := json.Marshal(&APIID{ID: imgID})
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -423,8 +423,8 @@ func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r
 		return err
 		return err
 	}
 	}
 
 
-	out := &ApiRun{
-		Id: id,
+	out := &APIRun{
+		ID: id,
 	}
 	}
 	if config.Memory > 0 && !srv.runtime.capabilities.MemoryLimit {
 	if config.Memory > 0 && !srv.runtime.capabilities.MemoryLimit {
 		log.Println("WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.")
 		log.Println("WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.")
@@ -439,7 +439,7 @@ func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r
 		return err
 		return err
 	}
 	}
 	w.WriteHeader(http.StatusCreated)
 	w.WriteHeader(http.StatusCreated)
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -500,7 +500,7 @@ func deleteImages(srv *Server, version float64, w http.ResponseWriter, r *http.R
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
-			writeJson(w, b)
+			writeJSON(w, b)
 		} else {
 		} else {
 			return fmt.Errorf("Conflict, %s wasn't deleted", name)
 			return fmt.Errorf("Conflict, %s wasn't deleted", name)
 		}
 		}
@@ -552,11 +552,11 @@ func postContainersWait(srv *Server, version float64, w http.ResponseWriter, r *
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	b, err := json.Marshal(&ApiWait{StatusCode: status})
+	b, err := json.Marshal(&APIWait{StatusCode: status})
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -643,7 +643,7 @@ func getContainersByName(srv *Server, version float64, w http.ResponseWriter, r
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -661,17 +661,17 @@ func getImagesByName(srv *Server, version float64, w http.ResponseWriter, r *htt
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
 func postImagesGetCache(srv *Server, version float64, 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
 	}
 	}
 
 
-	image, err := srv.ImageGetCached(apiConfig.Id, apiConfig.Config)
+	image, err := srv.ImageGetCached(apiConfig.ID, apiConfig.Config)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -679,12 +679,12 @@ func postImagesGetCache(srv *Server, version float64, w http.ResponseWriter, r *
 		w.WriteHeader(http.StatusNotFound)
 		w.WriteHeader(http.StatusNotFound)
 		return nil
 		return nil
 	}
 	}
-	apiId := &ApiId{Id: image.Id}
-	b, err := json.Marshal(apiId)
+	apiID := &APIID{ID: image.ID}
+	b, err := json.Marshal(apiID)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	writeJson(w, b)
+	writeJSON(w, b)
 	return nil
 	return nil
 }
 }
 
 
@@ -730,13 +730,13 @@ func ListenAndServe(addr string, srv *Server, logging bool) error {
 			"/auth":                         getAuth,
 			"/auth":                         getAuth,
 			"/version":                      getVersion,
 			"/version":                      getVersion,
 			"/info":                         getInfo,
 			"/info":                         getInfo,
-			"/images/json":                  getImagesJson,
+			"/images/json":                  getImagesJSON,
 			"/images/viz":                   getImagesViz,
 			"/images/viz":                   getImagesViz,
 			"/images/search":                getImagesSearch,
 			"/images/search":                getImagesSearch,
 			"/images/{name:.*}/history":     getImagesHistory,
 			"/images/{name:.*}/history":     getImagesHistory,
 			"/images/{name:.*}/json":        getImagesByName,
 			"/images/{name:.*}/json":        getImagesByName,
-			"/containers/ps":                getContainersJson,
-			"/containers/json":              getContainersJson,
+			"/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,
@@ -785,9 +785,9 @@ func ListenAndServe(addr string, srv *Server, logging bool) error {
 				}
 				}
 				version, err := strconv.ParseFloat(mux.Vars(r)["version"], 64)
 				version, err := strconv.ParseFloat(mux.Vars(r)["version"], 64)
 				if err != nil {
 				if err != nil {
-					version = API_VERSION
+					version = APIVERSION
 				}
 				}
-				if version == 0 || version > API_VERSION {
+				if version == 0 || version > APIVERSION {
 					w.WriteHeader(http.StatusNotFound)
 					w.WriteHeader(http.StatusNotFound)
 					return
 					return
 				}
 				}

+ 29 - 30
api_params.go

@@ -1,35 +1,35 @@
 package docker
 package docker
 
 
-type ApiHistory struct {
-	Id        string
+type APIHistory struct {
+	ID        string `json:"Id"`
 	Created   int64
 	Created   int64
-	CreatedBy string
+	CreatedBy string `json:",omitempty"`
 }
 }
 
 
-type ApiImages struct {
+type APIImages struct {
 	Repository string `json:",omitempty"`
 	Repository string `json:",omitempty"`
 	Tag        string `json:",omitempty"`
 	Tag        string `json:",omitempty"`
-	Id         string
+	ID         string `json:"Id"`
 	Created    int64
 	Created    int64
 }
 }
 
 
-type ApiInfo struct {
+type APIInfo struct {
+	Debug       bool
 	Containers  int
 	Containers  int
-	Version     string
 	Images      int
 	Images      int
-	Debug       bool
-	GoVersion   string
-	NFd         int `json:",omitempty"`
-	NGoroutines int `json:",omitempty"`
+	NFd         int  `json:",omitempty"`
+	NGoroutines int  `json:",omitempty"`
+	MemoryLimit bool `json:",omitempty"`
+	SwapLimit   bool `json:",omitempty"`
 }
 }
 
 
-type ApiRmi struct {
+type APIRmi struct {
 	Deleted  string `json:",omitempty"`
 	Deleted  string `json:",omitempty"`
 	Untagged string `json:",omitempty"`
 	Untagged string `json:",omitempty"`
 }
 }
 
 
-type ApiContainers struct {
-	Id      string
+type APIContainers struct {
+	ID      string `json:"Id"`
 	Image   string
 	Image   string
 	Command string
 	Command string
 	Created int64
 	Created int64
@@ -37,40 +37,39 @@ type ApiContainers struct {
 	Ports   string
 	Ports   string
 }
 }
 
 
-type ApiSearch struct {
+type APISearch struct {
 	Name        string
 	Name        string
 	Description string
 	Description string
 }
 }
 
 
-type ApiId struct {
-	Id string
+type APIID struct {
+	ID string `json:"Id"`
 }
 }
 
 
-type ApiRun struct {
-	Id       string
-	Warnings []string
+type APIRun struct {
+	ID       string   `json:"Id"`
+	Warnings []string `json:",omitempty"`
 }
 }
 
 
-type ApiPort struct {
+type APIPort struct {
 	Port string
 	Port string
 }
 }
 
 
-type ApiVersion struct {
-	Version     string
-	GitCommit   string
-	MemoryLimit bool
-	SwapLimit   bool
+type APIVersion struct {
+	Version   string
+	GitCommit string `json:",omitempty"`
+	GoVersion string `json:",omitempty"`
 }
 }
 
 
-type ApiWait struct {
+type APIWait struct {
 	StatusCode int
 	StatusCode int
 }
 }
 
 
-type ApiAuth struct {
+type APIAuth struct {
 	Status string
 	Status string
 }
 }
 
 
-type ApiImageConfig struct {
-	Id string
+type APIImageConfig struct {
+	ID string `json:"Id"`
 	*Config
 	*Config
 }
 }

+ 77 - 77
api_test.go

@@ -37,17 +37,17 @@ func TestGetAuth(t *testing.T) {
 		Email:    "utest@yopmail.com",
 		Email:    "utest@yopmail.com",
 	}
 	}
 
 
-	authConfigJson, err := json.Marshal(authConfig)
+	authConfigJSON, err := json.Marshal(authConfig)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	req, err := http.NewRequest("POST", "/auth", bytes.NewReader(authConfigJson))
+	req, err := http.NewRequest("POST", "/auth", bytes.NewReader(authConfigJSON))
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := postAuth(srv, API_VERSION, r, req, nil); err != nil {
+	if err := postAuth(srv, APIVERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -73,11 +73,11 @@ func TestGetVersion(t *testing.T) {
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
 
 
-	if err := getVersion(srv, API_VERSION, r, nil, nil); err != nil {
+	if err := getVersion(srv, APIVERSION, r, nil, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	v := &ApiVersion{}
+	v := &APIVersion{}
 	if err = json.Unmarshal(r.Body.Bytes(), v); err != nil {
 	if err = json.Unmarshal(r.Body.Bytes(), v); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -97,21 +97,21 @@ func TestGetInfo(t *testing.T) {
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
 
 
-	if err := getInfo(srv, API_VERSION, r, nil, nil); err != nil {
+	if err := getInfo(srv, APIVERSION, r, nil, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	infos := &ApiInfo{}
+	infos := &APIInfo{}
 	err = json.Unmarshal(r.Body.Bytes(), infos)
 	err = json.Unmarshal(r.Body.Bytes(), infos)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	if infos.Version != VERSION {
-		t.Errorf("Excepted version %s, %s found", VERSION, infos.Version)
+	if infos.Images != 1 {
+		t.Errorf("Excepted images: %d, %d found", 1, infos.Images)
 	}
 	}
 }
 }
 
 
-func TestGetImagesJson(t *testing.T) {
+func TestGetImagesJSON(t *testing.T) {
 	runtime, err := newTestRuntime()
 	runtime, err := newTestRuntime()
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -128,11 +128,11 @@ func TestGetImagesJson(t *testing.T) {
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
 
 
-	if err := getImagesJson(srv, API_VERSION, r, req, nil); err != nil {
+	if err := getImagesJSON(srv, APIVERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	images := []ApiImages{}
+	images := []APIImages{}
 	if err := json.Unmarshal(r.Body.Bytes(), &images); err != nil {
 	if err := json.Unmarshal(r.Body.Bytes(), &images); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -153,11 +153,11 @@ func TestGetImagesJson(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := getImagesJson(srv, API_VERSION, r2, req2, nil); err != nil {
+	if err := getImagesJSON(srv, APIVERSION, r2, req2, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	images2 := []ApiImages{}
+	images2 := []APIImages{}
 	if err := json.Unmarshal(r2.Body.Bytes(), &images2); err != nil {
 	if err := json.Unmarshal(r2.Body.Bytes(), &images2); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -166,8 +166,8 @@ func TestGetImagesJson(t *testing.T) {
 		t.Errorf("Excepted 1 image, %d found", len(images2))
 		t.Errorf("Excepted 1 image, %d found", len(images2))
 	}
 	}
 
 
-	if images2[0].Id != GetTestImage(runtime).Id {
-		t.Errorf("Retrieved image Id differs, expected %s, received %s", GetTestImage(runtime).Id, images2[0].Id)
+	if images2[0].ID != GetTestImage(runtime).ID {
+		t.Errorf("Retrieved image Id differs, expected %s, received %s", GetTestImage(runtime).ID, images2[0].ID)
 	}
 	}
 
 
 	r3 := httptest.NewRecorder()
 	r3 := httptest.NewRecorder()
@@ -178,11 +178,11 @@ func TestGetImagesJson(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := getImagesJson(srv, API_VERSION, r3, req3, nil); err != nil {
+	if err := getImagesJSON(srv, APIVERSION, r3, req3, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	images3 := []ApiImages{}
+	images3 := []APIImages{}
 	if err := json.Unmarshal(r3.Body.Bytes(), &images3); err != nil {
 	if err := json.Unmarshal(r3.Body.Bytes(), &images3); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -199,7 +199,7 @@ func TestGetImagesJson(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	err = getImagesJson(srv, API_VERSION, r4, req4, nil)
+	err = getImagesJSON(srv, APIVERSION, r4, req4, nil)
 	if err == nil {
 	if err == nil {
 		t.Fatalf("Error expected, received none")
 		t.Fatalf("Error expected, received none")
 	}
 	}
@@ -220,7 +220,7 @@ func TestGetImagesViz(t *testing.T) {
 	srv := &Server{runtime: runtime}
 	srv := &Server{runtime: runtime}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getImagesViz(srv, API_VERSION, r, nil, nil); err != nil {
+	if err := getImagesViz(srv, APIVERSION, r, nil, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -256,11 +256,11 @@ func TestGetImagesSearch(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	if err := getImagesSearch(srv, API_VERSION, r, req, nil); err != nil {
+	if err := getImagesSearch(srv, APIVERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	results := []ApiSearch{}
+	results := []APISearch{}
 	if err := json.Unmarshal(r.Body.Bytes(), &results); err != nil {
 	if err := json.Unmarshal(r.Body.Bytes(), &results); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -280,11 +280,11 @@ func TestGetImagesHistory(t *testing.T) {
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
 
 
-	if err := getImagesHistory(srv, API_VERSION, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
+	if err := getImagesHistory(srv, APIVERSION, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	history := []ApiHistory{}
+	history := []APIHistory{}
 	if err := json.Unmarshal(r.Body.Bytes(), &history); err != nil {
 	if err := json.Unmarshal(r.Body.Bytes(), &history); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -303,7 +303,7 @@ func TestGetImagesByName(t *testing.T) {
 	srv := &Server{runtime: runtime}
 	srv := &Server{runtime: runtime}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getImagesByName(srv, API_VERSION, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
+	if err := getImagesByName(srv, APIVERSION, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -311,12 +311,12 @@ func TestGetImagesByName(t *testing.T) {
 	if err := json.Unmarshal(r.Body.Bytes(), img); err != nil {
 	if err := json.Unmarshal(r.Body.Bytes(), img); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	if img.Id != GetTestImage(runtime).Id || img.Comment != "Imported from http://get.docker.io/images/busybox" {
+	if img.ID != GetTestImage(runtime).ID || img.Comment != "Imported from http://get.docker.io/images/busybox" {
 		t.Errorf("Error inspecting image")
 		t.Errorf("Error inspecting image")
 	}
 	}
 }
 }
 
 
-func TestGetContainersJson(t *testing.T) {
+func TestGetContainersJSON(t *testing.T) {
 	runtime, err := newTestRuntime()
 	runtime, err := newTestRuntime()
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -326,7 +326,7 @@ func TestGetContainersJson(t *testing.T) {
 	srv := &Server{runtime: runtime}
 	srv := &Server{runtime: runtime}
 
 
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"echo", "test"},
 		Cmd:   []string{"echo", "test"},
 	})
 	})
 	if err != nil {
 	if err != nil {
@@ -340,18 +340,18 @@ func TestGetContainersJson(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getContainersJson(srv, API_VERSION, r, req, nil); err != nil {
+	if err := getContainersJSON(srv, APIVERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	containers := []ApiContainers{}
+	containers := []APIContainers{}
 	if err := json.Unmarshal(r.Body.Bytes(), &containers); err != nil {
 	if err := json.Unmarshal(r.Body.Bytes(), &containers); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if len(containers) != 1 {
 	if len(containers) != 1 {
 		t.Fatalf("Excepted %d container, %d found", 1, len(containers))
 		t.Fatalf("Excepted %d container, %d found", 1, len(containers))
 	}
 	}
-	if containers[0].Id != container.Id {
-		t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", container.Id, containers[0].Id)
+	if containers[0].ID != container.ID {
+		t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", container.ID, containers[0].ID)
 	}
 	}
 }
 }
 
 
@@ -369,7 +369,7 @@ func TestGetContainersExport(t *testing.T) {
 	// Create a container and remove a file
 	// Create a container and remove a file
 	container, err := builder.Create(
 	container, err := builder.Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"touch", "/test"},
 			Cmd:   []string{"touch", "/test"},
 		},
 		},
 	)
 	)
@@ -383,7 +383,7 @@ func TestGetContainersExport(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err = getContainersExport(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err = getContainersExport(srv, APIVERSION, r, nil, map[string]string{"name": container.ID}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -424,7 +424,7 @@ func TestGetContainersChanges(t *testing.T) {
 	// Create a container and remove a file
 	// Create a container and remove a file
 	container, err := builder.Create(
 	container, err := builder.Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"/bin/rm", "/etc/passwd"},
 			Cmd:   []string{"/bin/rm", "/etc/passwd"},
 		},
 		},
 	)
 	)
@@ -438,7 +438,7 @@ func TestGetContainersChanges(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getContainersChanges(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err := getContainersChanges(srv, APIVERSION, r, nil, map[string]string{"name": container.ID}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	changes := []Change{}
 	changes := []Change{}
@@ -472,7 +472,7 @@ func TestGetContainersByName(t *testing.T) {
 	// Create a container and remove a file
 	// Create a container and remove a file
 	container, err := builder.Create(
 	container, err := builder.Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"echo", "test"},
 			Cmd:   []string{"echo", "test"},
 		},
 		},
 	)
 	)
@@ -482,15 +482,15 @@ func TestGetContainersByName(t *testing.T) {
 	defer runtime.Destroy(container)
 	defer runtime.Destroy(container)
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getContainersByName(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err := getContainersByName(srv, APIVERSION, r, nil, map[string]string{"name": container.ID}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	outContainer := &Container{}
 	outContainer := &Container{}
 	if err := json.Unmarshal(r.Body.Bytes(), outContainer); err != nil {
 	if err := json.Unmarshal(r.Body.Bytes(), outContainer); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	if outContainer.Id != container.Id {
-		t.Fatalf("Wrong containers retrieved. Expected %s, recieved %s", container.Id, outContainer.Id)
+	if outContainer.ID != container.ID {
+		t.Fatalf("Wrong containers retrieved. Expected %s, recieved %s", container.ID, outContainer.ID)
 	}
 	}
 }
 }
 
 
@@ -514,7 +514,7 @@ func TestPostAuth(t *testing.T) {
 	auth.SaveConfig(runtime.root, authStr, config.Email)
 	auth.SaveConfig(runtime.root, authStr, config.Email)
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := getAuth(srv, API_VERSION, r, nil, nil); err != nil {
+	if err := getAuth(srv, APIVERSION, r, nil, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
@@ -542,7 +542,7 @@ func TestPostCommit(t *testing.T) {
 	// Create a container and remove a file
 	// Create a container and remove a file
 	container, err := builder.Create(
 	container, err := builder.Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"touch", "/test"},
 			Cmd:   []string{"touch", "/test"},
 		},
 		},
 	)
 	)
@@ -555,24 +555,24 @@ func TestPostCommit(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	req, err := http.NewRequest("POST", "/commit?repo=testrepo&testtag=tag&container="+container.Id, bytes.NewReader([]byte{}))
+	req, err := http.NewRequest("POST", "/commit?repo=testrepo&testtag=tag&container="+container.ID, bytes.NewReader([]byte{}))
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postCommit(srv, API_VERSION, r, req, nil); err != nil {
+	if err := postCommit(srv, APIVERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusCreated {
 	if r.Code != http.StatusCreated {
 		t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
 		t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
 	}
 	}
 
 
-	apiId := &ApiId{}
-	if err := json.Unmarshal(r.Body.Bytes(), apiId); err != nil {
+	apiID := &APIID{}
+	if err := json.Unmarshal(r.Body.Bytes(), apiID); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	if _, err := runtime.graph.Get(apiId.Id); err != nil {
+	if _, err := runtime.graph.Get(apiID.ID); err != nil {
 		t.Fatalf("The image has not been commited")
 		t.Fatalf("The image has not been commited")
 	}
 	}
 }
 }
@@ -715,7 +715,7 @@ func TestPostImagesInsert(t *testing.T) {
 	// 	t.Fatalf("The test file has not been found")
 	// 	t.Fatalf("The test file has not been found")
 	// }
 	// }
 
 
-	// if err := srv.runtime.graph.Delete(img.Id); err != nil {
+	// if err := srv.runtime.graph.Delete(img.ID); err != nil {
 	// 	t.Fatal(err)
 	// 	t.Fatal(err)
 	// }
 	// }
 }
 }
@@ -824,8 +824,8 @@ func TestPostContainersCreate(t *testing.T) {
 
 
 	srv := &Server{runtime: runtime}
 	srv := &Server{runtime: runtime}
 
 
-	configJson, err := json.Marshal(&Config{
-		Image:  GetTestImage(runtime).Id,
+	configJSON, err := json.Marshal(&Config{
+		Image:  GetTestImage(runtime).ID,
 		Memory: 33554432,
 		Memory: 33554432,
 		Cmd:    []string{"touch", "/test"},
 		Cmd:    []string{"touch", "/test"},
 	})
 	})
@@ -833,25 +833,25 @@ func TestPostContainersCreate(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	req, err := http.NewRequest("POST", "/containers/create", bytes.NewReader(configJson))
+	req, err := http.NewRequest("POST", "/containers/create", bytes.NewReader(configJSON))
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersCreate(srv, API_VERSION, r, req, nil); err != nil {
+	if err := postContainersCreate(srv, APIVERSION, r, req, nil); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusCreated {
 	if r.Code != http.StatusCreated {
 		t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
 		t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
 	}
 	}
 
 
-	apiRun := &ApiRun{}
+	apiRun := &APIRun{}
 	if err := json.Unmarshal(r.Body.Bytes(), apiRun); err != nil {
 	if err := json.Unmarshal(r.Body.Bytes(), apiRun); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	container := srv.runtime.Get(apiRun.Id)
+	container := srv.runtime.Get(apiRun.ID)
 	if container == nil {
 	if container == nil {
 		t.Fatalf("Container not created")
 		t.Fatalf("Container not created")
 	}
 	}
@@ -880,7 +880,7 @@ func TestPostContainersKill(t *testing.T) {
 
 
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image:     GetTestImage(runtime).Id,
+			Image:     GetTestImage(runtime).ID,
 			Cmd:       []string{"/bin/cat"},
 			Cmd:       []string{"/bin/cat"},
 			OpenStdin: true,
 			OpenStdin: true,
 		},
 		},
@@ -902,7 +902,7 @@ func TestPostContainersKill(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersKill(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err := postContainersKill(srv, APIVERSION, 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 {
@@ -924,7 +924,7 @@ func TestPostContainersRestart(t *testing.T) {
 
 
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image:     GetTestImage(runtime).Id,
+			Image:     GetTestImage(runtime).ID,
 			Cmd:       []string{"/bin/cat"},
 			Cmd:       []string{"/bin/cat"},
 			OpenStdin: true,
 			OpenStdin: true,
 		},
 		},
@@ -945,12 +945,12 @@ func TestPostContainersRestart(t *testing.T) {
 		t.Errorf("Container should be running")
 		t.Errorf("Container should be running")
 	}
 	}
 
 
-	req, err := http.NewRequest("POST", "/containers/"+container.Id+"/restart?t=1", bytes.NewReader([]byte{}))
+	req, err := http.NewRequest("POST", "/containers/"+container.ID+"/restart?t=1", bytes.NewReader([]byte{}))
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersRestart(srv, API_VERSION, r, req, map[string]string{"name": container.Id}); err != nil {
+	if err := postContainersRestart(srv, APIVERSION, 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 {
@@ -980,7 +980,7 @@ func TestPostContainersStart(t *testing.T) {
 
 
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image:     GetTestImage(runtime).Id,
+			Image:     GetTestImage(runtime).ID,
 			Cmd:       []string{"/bin/cat"},
 			Cmd:       []string{"/bin/cat"},
 			OpenStdin: true,
 			OpenStdin: true,
 		},
 		},
@@ -991,7 +991,7 @@ func TestPostContainersStart(t *testing.T) {
 	defer runtime.Destroy(container)
 	defer runtime.Destroy(container)
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersStart(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
+	if err := postContainersStart(srv, APIVERSION, 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 {
@@ -1006,7 +1006,7 @@ func TestPostContainersStart(t *testing.T) {
 	}
 	}
 
 
 	r = httptest.NewRecorder()
 	r = httptest.NewRecorder()
-	if err = postContainersStart(srv, API_VERSION, r, nil, map[string]string{"name": container.Id}); err == nil {
+	if err = postContainersStart(srv, APIVERSION, 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")
 	}
 	}
 
 
@@ -1026,7 +1026,7 @@ func TestPostContainersStop(t *testing.T) {
 
 
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image:     GetTestImage(runtime).Id,
+			Image:     GetTestImage(runtime).ID,
 			Cmd:       []string{"/bin/cat"},
 			Cmd:       []string{"/bin/cat"},
 			OpenStdin: true,
 			OpenStdin: true,
 		},
 		},
@@ -1048,12 +1048,12 @@ func TestPostContainersStop(t *testing.T) {
 	}
 	}
 
 
 	// Note: as it is a POST request, it requires a body.
 	// Note: as it is a POST request, it requires a body.
-	req, err := http.NewRequest("POST", "/containers/"+container.Id+"/stop?t=1", bytes.NewReader([]byte{}))
+	req, err := http.NewRequest("POST", "/containers/"+container.ID+"/stop?t=1", bytes.NewReader([]byte{}))
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := postContainersStop(srv, API_VERSION, r, req, map[string]string{"name": container.Id}); err != nil {
+	if err := postContainersStop(srv, APIVERSION, 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 {
@@ -1075,7 +1075,7 @@ func TestPostContainersWait(t *testing.T) {
 
 
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image:     GetTestImage(runtime).Id,
+			Image:     GetTestImage(runtime).ID,
 			Cmd:       []string{"/bin/sleep", "1"},
 			Cmd:       []string{"/bin/sleep", "1"},
 			OpenStdin: true,
 			OpenStdin: true,
 		},
 		},
@@ -1091,10 +1091,10 @@ 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, API_VERSION, r, nil, map[string]string{"name": container.Id}); err != nil {
+		if err := postContainersWait(srv, APIVERSION, r, nil, map[string]string{"name": container.ID}); err != nil {
 			t.Fatal(err)
 			t.Fatal(err)
 		}
 		}
-		apiWait := &ApiWait{}
+		apiWait := &APIWait{}
 		if err := json.Unmarshal(r.Body.Bytes(), apiWait); err != nil {
 		if err := json.Unmarshal(r.Body.Bytes(), apiWait); err != nil {
 			t.Fatal(err)
 			t.Fatal(err)
 		}
 		}
@@ -1119,7 +1119,7 @@ func TestPostContainersAttach(t *testing.T) {
 
 
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image:     GetTestImage(runtime).Id,
+			Image:     GetTestImage(runtime).ID,
 			Cmd:       []string{"/bin/cat"},
 			Cmd:       []string{"/bin/cat"},
 			OpenStdin: true,
 			OpenStdin: true,
 		},
 		},
@@ -1148,12 +1148,12 @@ func TestPostContainersAttach(t *testing.T) {
 			out:              stdoutPipe,
 			out:              stdoutPipe,
 		}
 		}
 
 
-		req, err := http.NewRequest("POST", "/containers/"+container.Id+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
+		req, err := http.NewRequest("POST", "/containers/"+container.ID+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
 		if err != nil {
 		if err != nil {
 			t.Fatal(err)
 			t.Fatal(err)
 		}
 		}
 
 
-		if err := postContainersAttach(srv, API_VERSION, r, req, map[string]string{"name": container.Id}); err != nil {
+		if err := postContainersAttach(srv, APIVERSION, r, req, map[string]string{"name": container.ID}); err != nil {
 			t.Fatal(err)
 			t.Fatal(err)
 		}
 		}
 	}()
 	}()
@@ -1206,7 +1206,7 @@ func TestDeleteContainers(t *testing.T) {
 	srv := &Server{runtime: runtime}
 	srv := &Server{runtime: runtime}
 
 
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"touch", "/test"},
 		Cmd:   []string{"touch", "/test"},
 	})
 	})
 	if err != nil {
 	if err != nil {
@@ -1218,19 +1218,19 @@ func TestDeleteContainers(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 
-	req, err := http.NewRequest("DELETE", "/containers/"+container.Id, nil)
+	req, err := http.NewRequest("DELETE", "/containers/"+container.ID, nil)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := deleteContainers(srv, API_VERSION, r, req, map[string]string{"name": container.Id}); err != nil {
+	if err := deleteContainers(srv, APIVERSION, 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 {
 		t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
 		t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
 	}
 	}
 
 
-	if c := runtime.Get(container.Id); c != nil {
+	if c := runtime.Get(container.ID); c != nil {
 		t.Fatalf("The container as not been deleted")
 		t.Fatalf("The container as not been deleted")
 	}
 	}
 
 
@@ -1267,14 +1267,14 @@ func TestDeleteImages(t *testing.T) {
 	}
 	}
 
 
 	r := httptest.NewRecorder()
 	r := httptest.NewRecorder()
-	if err := deleteImages(srv, API_VERSION, r, req, map[string]string{"name": "test:test"}); err != nil {
+	if err := deleteImages(srv, APIVERSION, r, req, map[string]string{"name": "test:test"}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if r.Code != http.StatusOK {
 	if r.Code != http.StatusOK {
 		t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
 		t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
 	}
 	}
 
 
-	var outs []ApiRmi
+	var outs []APIRmi
 	if err := json.Unmarshal(r.Body.Bytes(), &outs); err != nil {
 	if err := json.Unmarshal(r.Body.Bytes(), &outs); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}

+ 4 - 4
auth/auth.go

@@ -16,12 +16,12 @@ import (
 const CONFIGFILE = ".dockercfg"
 const CONFIGFILE = ".dockercfg"
 
 
 // the registry server we want to login against
 // the registry server we want to login against
-const INDEX_SERVER = "https://index.docker.io/v1"
+const INDEXSERVER = "https://index.docker.io/v1"
 
 
-//const INDEX_SERVER = "http://indexstaging-docker.dotcloud.com/"
+//const INDEXSERVER = "http://indexstaging-docker.dotcloud.com/"
 
 
 var (
 var (
-	ErrConfigFileMissing error = errors.New("The Auth config file is missing")
+	ErrConfigFileMissing = errors.New("The Auth config file is missing")
 )
 )
 
 
 type AuthConfig struct {
 type AuthConfig struct {
@@ -44,7 +44,7 @@ func IndexServerAddress() string {
 	if os.Getenv("DOCKER_INDEX_URL") != "" {
 	if os.Getenv("DOCKER_INDEX_URL") != "" {
 		return os.Getenv("DOCKER_INDEX_URL") + "/v1"
 		return os.Getenv("DOCKER_INDEX_URL") + "/v1"
 	}
 	}
-	return INDEX_SERVER
+	return INDEXSERVER
 }
 }
 
 
 // create a base64 encoded auth string to store in config
 // create a base64 encoded auth string to store in config

+ 5 - 5
builder.go

@@ -40,7 +40,7 @@ func (builder *Builder) Create(config *Config) (*Container, error) {
 	}
 	}
 
 
 	// Generate id
 	// Generate id
-	id := GenerateId()
+	id := GenerateID()
 	// Generate default hostname
 	// Generate default hostname
 	// FIXME: the lxc template no longer needs to set a default hostname
 	// FIXME: the lxc template no longer needs to set a default hostname
 	if config.Hostname == "" {
 	if config.Hostname == "" {
@@ -49,17 +49,17 @@ func (builder *Builder) Create(config *Config) (*Container, error) {
 
 
 	container := &Container{
 	container := &Container{
 		// FIXME: we should generate the ID here instead of receiving it as an argument
 		// FIXME: we should generate the ID here instead of receiving it as an argument
-		Id:              id,
+		ID:              id,
 		Created:         time.Now(),
 		Created:         time.Now(),
 		Path:            config.Cmd[0],
 		Path:            config.Cmd[0],
 		Args:            config.Cmd[1:], //FIXME: de-duplicate from config
 		Args:            config.Cmd[1:], //FIXME: de-duplicate from config
 		Config:          config,
 		Config:          config,
-		Image:           img.Id, // Always use the resolved image id
+		Image:           img.ID, // Always use the resolved image id
 		NetworkSettings: &NetworkSettings{},
 		NetworkSettings: &NetworkSettings{},
 		// FIXME: do we need to store this in the container?
 		// FIXME: do we need to store this in the container?
 		SysInitPath: sysInitPath,
 		SysInitPath: sysInitPath,
 	}
 	}
-	container.root = builder.runtime.containerRoot(container.Id)
+	container.root = builder.runtime.containerRoot(container.ID)
 	// Step 1: create the container directory.
 	// Step 1: create the container directory.
 	// This doubles as a barrier to avoid race conditions.
 	// This doubles as a barrier to avoid race conditions.
 	if err := os.Mkdir(container.root, 0700); err != nil {
 	if err := os.Mkdir(container.root, 0700); err != nil {
@@ -110,7 +110,7 @@ func (builder *Builder) Commit(container *Container, repository, tag, comment, a
 	}
 	}
 	// Register the image if needed
 	// Register the image if needed
 	if repository != "" {
 	if repository != "" {
-		if err := builder.repositories.Set(repository, tag, img.Id, true); err != nil {
+		if err := builder.repositories.Set(repository, tag, img.ID, true); err != nil {
 			return img, err
 			return img, err
 		}
 		}
 	}
 	}

+ 20 - 20
builder_client.go

@@ -63,11 +63,11 @@ func (b *builderClient) CmdFrom(name string) error {
 		return err
 		return err
 	}
 	}
 
 
-	img := &ApiId{}
+	img := &APIID{}
 	if err := json.Unmarshal(obj, img); err != nil {
 	if err := json.Unmarshal(obj, img); err != nil {
 		return err
 		return err
 	}
 	}
-	b.image = img.Id
+	b.image = img.ID
 	utils.Debugf("Using image %s", b.image)
 	utils.Debugf("Using image %s", b.image)
 	return nil
 	return nil
 }
 }
@@ -91,19 +91,19 @@ func (b *builderClient) CmdRun(args string) error {
 	b.config.Cmd = nil
 	b.config.Cmd = nil
 	MergeConfig(b.config, config)
 	MergeConfig(b.config, config)
 
 
-	body, statusCode, err := b.cli.call("POST", "/images/getCache", &ApiImageConfig{Id: b.image, Config: b.config})
+	body, statusCode, err := b.cli.call("POST", "/images/getCache", &APIImageConfig{ID: b.image, Config: b.config})
 	if err != nil {
 	if err != nil {
 		if statusCode != 404 {
 		if statusCode != 404 {
 			return err
 			return err
 		}
 		}
 	}
 	}
 	if statusCode != 404 {
 	if statusCode != 404 {
-		apiId := &ApiId{}
-		if err := json.Unmarshal(body, apiId); err != nil {
+		apiID := &APIID{}
+		if err := json.Unmarshal(body, apiID); err != nil {
 			return err
 			return err
 		}
 		}
 		utils.Debugf("Use cached version")
 		utils.Debugf("Use cached version")
-		b.image = apiId.Id
+		b.image = apiID.ID
 		return nil
 		return nil
 	}
 	}
 	cid, err := b.run()
 	cid, err := b.run()
@@ -163,7 +163,7 @@ func (b *builderClient) CmdInsert(args string) error {
 	// 	return err
 	// 	return err
 	// }
 	// }
 
 
-	// apiId := &ApiId{}
+	// apiId := &APIId{}
 	// if err := json.Unmarshal(body, apiId); err != nil {
 	// if err := json.Unmarshal(body, apiId); err != nil {
 	// 	return err
 	// 	return err
 	// }
 	// }
@@ -182,7 +182,7 @@ func (b *builderClient) run() (string, error) {
 		return "", err
 		return "", err
 	}
 	}
 
 
-	apiRun := &ApiRun{}
+	apiRun := &APIRun{}
 	if err := json.Unmarshal(body, apiRun); err != nil {
 	if err := json.Unmarshal(body, apiRun); err != nil {
 		return "", err
 		return "", err
 	}
 	}
@@ -191,18 +191,18 @@ func (b *builderClient) run() (string, error) {
 	}
 	}
 
 
 	//start the container
 	//start the container
-	_, _, err = b.cli.call("POST", "/containers/"+apiRun.Id+"/start", nil)
+	_, _, err = b.cli.call("POST", "/containers/"+apiRun.ID+"/start", nil)
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
-	b.tmpContainers[apiRun.Id] = struct{}{}
+	b.tmpContainers[apiRun.ID] = struct{}{}
 
 
 	// Wait for it to finish
 	// Wait for it to finish
-	body, _, err = b.cli.call("POST", "/containers/"+apiRun.Id+"/wait", nil)
+	body, _, err = b.cli.call("POST", "/containers/"+apiRun.ID+"/wait", nil)
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
-	apiWait := &ApiWait{}
+	apiWait := &APIWait{}
 	if err := json.Unmarshal(body, apiWait); err != nil {
 	if err := json.Unmarshal(body, apiWait); err != nil {
 		return "", err
 		return "", err
 	}
 	}
@@ -210,7 +210,7 @@ func (b *builderClient) run() (string, error) {
 		return "", fmt.Errorf("The command %v returned a non-zero code: %d", b.config.Cmd, apiWait.StatusCode)
 		return "", fmt.Errorf("The command %v returned a non-zero code: %d", b.config.Cmd, apiWait.StatusCode)
 	}
 	}
 
 
-	return apiRun.Id, nil
+	return apiRun.ID, nil
 }
 }
 
 
 func (b *builderClient) commit(id string) error {
 func (b *builderClient) commit(id string) error {
@@ -222,11 +222,11 @@ func (b *builderClient) commit(id string) error {
 	if id == "" {
 	if id == "" {
 		cmd := b.config.Cmd
 		cmd := b.config.Cmd
 		b.config.Cmd = []string{"true"}
 		b.config.Cmd = []string{"true"}
-		if cid, err := b.run(); err != nil {
+		cid, err := b.run()
+		if err != nil {
 			return err
 			return err
-		} else {
-			id = cid
 		}
 		}
+		id = cid
 		b.config.Cmd = cmd
 		b.config.Cmd = cmd
 	}
 	}
 
 
@@ -239,12 +239,12 @@ func (b *builderClient) commit(id string) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	apiId := &ApiId{}
-	if err := json.Unmarshal(body, apiId); err != nil {
+	apiID := &APIID{}
+	if err := json.Unmarshal(body, apiID); err != nil {
 		return err
 		return err
 	}
 	}
-	b.tmpImages[apiId.Id] = struct{}{}
-	b.image = apiId.Id
+	b.tmpImages[apiID.ID] = struct{}{}
+	b.image = apiID.ID
 	b.needCommit = false
 	b.needCommit = false
 	return nil
 	return nil
 }
 }

+ 10 - 10
buildfile.go

@@ -73,7 +73,7 @@ func (b *buildFile) CmdFrom(name string) error {
 			return err
 			return err
 		}
 		}
 	}
 	}
-	b.image = image.Id
+	b.image = image.ID
 	b.config = &Config{}
 	b.config = &Config{}
 	return nil
 	return nil
 }
 }
@@ -102,7 +102,7 @@ func (b *buildFile) CmdRun(args string) error {
 		return err
 		return err
 	} else if cache != nil {
 	} else if cache != nil {
 		utils.Debugf("[BUILDER] Use cached version")
 		utils.Debugf("[BUILDER] Use cached version")
-		b.image = cache.Id
+		b.image = cache.ID
 		return nil
 		return nil
 	} else {
 	} else {
 		utils.Debugf("[BUILDER] Cache miss")
 		utils.Debugf("[BUILDER] Cache miss")
@@ -238,7 +238,7 @@ func (b *buildFile) run() (string, error) {
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
-	b.tmpContainers[c.Id] = struct{}{}
+	b.tmpContainers[c.ID] = struct{}{}
 
 
 	//start the container
 	//start the container
 	if err := c.Start(); err != nil {
 	if err := c.Start(); err != nil {
@@ -250,7 +250,7 @@ func (b *buildFile) run() (string, error) {
 		return "", fmt.Errorf("The command %v returned a non-zero code: %d", b.config.Cmd, ret)
 		return "", fmt.Errorf("The command %v returned a non-zero code: %d", b.config.Cmd, ret)
 	}
 	}
 
 
-	return c.Id, nil
+	return c.ID, nil
 }
 }
 
 
 // Commit the container <id> with the autorun command <autoCmd>
 // Commit the container <id> with the autorun command <autoCmd>
@@ -266,17 +266,17 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
 			return err
 			return err
 		} else if cache != nil {
 		} else if cache != nil {
 			utils.Debugf("[BUILDER] Use cached version")
 			utils.Debugf("[BUILDER] Use cached version")
-			b.image = cache.Id
+			b.image = cache.ID
 			return nil
 			return nil
 		} else {
 		} else {
 			utils.Debugf("[BUILDER] Cache miss")
 			utils.Debugf("[BUILDER] Cache miss")
 		}
 		}
 
 
-		if cid, err := b.run(); err != nil {
+		cid, err := b.run()
+		if err != nil {
 			return err
 			return err
-		} else {
-			id = cid
 		}
 		}
+		id = cid
 	}
 	}
 
 
 	container := b.runtime.Get(id)
 	container := b.runtime.Get(id)
@@ -292,8 +292,8 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	b.tmpImages[image.Id] = struct{}{}
-	b.image = image.Id
+	b.tmpImages[image.ID] = struct{}{}
+	b.image = image.ID
 	return nil
 	return nil
 }
 }
 
 

+ 3 - 3
buildfile_test.go

@@ -26,7 +26,7 @@ func TestBuild(t *testing.T) {
 
 
 	buildfile := NewBuildFile(srv, &utils.NopWriter{})
 	buildfile := NewBuildFile(srv, &utils.NopWriter{})
 
 
-	imgId, err := buildfile.Build(strings.NewReader(Dockerfile), nil)
+	imgID, err := buildfile.Build(strings.NewReader(Dockerfile), nil)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -34,7 +34,7 @@ func TestBuild(t *testing.T) {
 	builder := NewBuilder(runtime)
 	builder := NewBuilder(runtime)
 	container, err := builder.Create(
 	container, err := builder.Create(
 		&Config{
 		&Config{
-			Image: imgId,
+			Image: imgID,
 			Cmd:   []string{"cat", "/tmp/passwd"},
 			Cmd:   []string{"cat", "/tmp/passwd"},
 		},
 		},
 	)
 	)
@@ -53,7 +53,7 @@ func TestBuild(t *testing.T) {
 
 
 	container2, err := builder.Create(
 	container2, err := builder.Create(
 		&Config{
 		&Config{
-			Image: imgId,
+			Image: imgID,
 			Cmd:   []string{"ls", "-d", "/var/run/sshd"},
 			Cmd:   []string{"ls", "-d", "/var/run/sshd"},
 		},
 		},
 	)
 	)

+ 1 - 1
changes.go

@@ -65,7 +65,7 @@ func Changes(layers []string, rw string) ([]Change, error) {
 		file := filepath.Base(path)
 		file := filepath.Base(path)
 		// If there is a whiteout, then the file was removed
 		// If there is a whiteout, then the file was removed
 		if strings.HasPrefix(file, ".wh.") {
 		if strings.HasPrefix(file, ".wh.") {
-			originalFile := strings.TrimLeft(file, ".wh.")
+			originalFile := file[len(".wh."):]
 			change.Path = filepath.Join(filepath.Dir(path), originalFile)
 			change.Path = filepath.Join(filepath.Dir(path), originalFile)
 			change.Kind = ChangeDelete
 			change.Kind = ChangeDelete
 		} else {
 		} else {

+ 74 - 73
commands.go

@@ -28,10 +28,10 @@ import (
 	"unicode"
 	"unicode"
 )
 )
 
 
-const VERSION = "0.3.4"
+const VERSION = "0.4.0"
 
 
 var (
 var (
-	GIT_COMMIT string
+	GITCOMMIT string
 )
 )
 
 
 func (cli *DockerCli) getMethod(name string) (reflect.Method, bool) {
 func (cli *DockerCli) getMethod(name string) (reflect.Method, bool) {
@@ -159,11 +159,11 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 		file = os.Stdin
 		file = os.Stdin
 	} else {
 	} else {
 		// Send Dockerfile from arg/Dockerfile (deprecate later)
 		// Send Dockerfile from arg/Dockerfile (deprecate later)
-		if f, err := os.Open(path.Join(cmd.Arg(0), "Dockerfile")); err != nil {
+		f, err := os.Open(path.Join(cmd.Arg(0), "Dockerfile"))
+		if err != nil {
 			return err
 			return err
-		} else {
-			file = f
 		}
 		}
+		file = f
 		// Send context from arg
 		// Send context from arg
 		// Create a FormFile multipart for the context if needed
 		// Create a FormFile multipart for the context if needed
 		// FIXME: Use NewTempArchive in order to have the size and avoid too much memory usage?
 		// FIXME: Use NewTempArchive in order to have the size and avoid too much memory usage?
@@ -176,21 +176,21 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		if wField, err := w.CreateFormFile("Context", filepath.Base(absPath)+"."+compression.Extension()); err != nil {
+		wField, err := w.CreateFormFile("Context", filepath.Base(absPath)+"."+compression.Extension())
+		if err != nil {
 			return err
 			return err
-		} else {
-			// FIXME: Find a way to have a progressbar for the upload too
-			sf := utils.NewStreamFormatter(false)
-			io.Copy(wField, utils.ProgressReader(ioutil.NopCloser(context), -1, os.Stdout, sf.FormatProgress("Caching Context", "%v/%v (%v)"), sf))
 		}
 		}
+		// FIXME: Find a way to have a progressbar for the upload too
+		sf := utils.NewStreamFormatter(false)
+		io.Copy(wField, utils.ProgressReader(ioutil.NopCloser(context), -1, os.Stdout, sf.FormatProgress("Caching Context", "%v/%v (%v)"), sf))
 		multipartBody = io.MultiReader(multipartBody, boundary)
 		multipartBody = io.MultiReader(multipartBody, boundary)
 	}
 	}
 	// Create a FormFile multipart for the Dockerfile
 	// Create a FormFile multipart for the Dockerfile
-	if wField, err := w.CreateFormFile("Dockerfile", "Dockerfile"); err != nil {
+	wField, err := w.CreateFormFile("Dockerfile", "Dockerfile")
+	if err != nil {
 		return err
 		return err
-	} else {
-		io.Copy(wField, file)
 	}
 	}
+	io.Copy(wField, file)
 	multipartBody = io.MultiReader(multipartBody, boundary)
 	multipartBody = io.MultiReader(multipartBody, boundary)
 
 
 	v := &url.Values{}
 	v := &url.Values{}
@@ -276,9 +276,8 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
 	oldState, err := term.SetRawTerminal()
 	oldState, err := term.SetRawTerminal()
 	if err != nil {
 	if err != nil {
 		return err
 		return err
-	} else {
-		defer term.RestoreTerminal(oldState)
 	}
 	}
+	defer term.RestoreTerminal(oldState)
 
 
 	cmd := Subcmd("login", "", "Register or Login to the docker registry server")
 	cmd := Subcmd("login", "", "Register or Login to the docker registry server")
 	if err := cmd.Parse(args); err != nil {
 	if err := cmd.Parse(args); err != nil {
@@ -331,7 +330,7 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
 		return err
 		return err
 	}
 	}
 
 
-	var out2 ApiAuth
+	var out2 APIAuth
 	err = json.Unmarshal(body, &out2)
 	err = json.Unmarshal(body, &out2)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -358,7 +357,7 @@ func (cli *DockerCli) CmdWait(args ...string) error {
 		if err != nil {
 		if err != nil {
 			fmt.Printf("%s", err)
 			fmt.Printf("%s", err)
 		} else {
 		} else {
-			var out ApiWait
+			var out APIWait
 			err = json.Unmarshal(body, &out)
 			err = json.Unmarshal(body, &out)
 			if err != nil {
 			if err != nil {
 				return err
 				return err
@@ -386,21 +385,20 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
 		return err
 		return err
 	}
 	}
 
 
-	var out ApiVersion
+	var out APIVersion
 	err = json.Unmarshal(body, &out)
 	err = json.Unmarshal(body, &out)
 	if err != nil {
 	if err != nil {
 		utils.Debugf("Error unmarshal: body: %s, err: %s\n", body, err)
 		utils.Debugf("Error unmarshal: body: %s, err: %s\n", body, err)
 		return err
 		return err
 	}
 	}
-	fmt.Println("Version:", out.Version)
-	fmt.Println("Git Commit:", out.GitCommit)
-	if !out.MemoryLimit {
-		fmt.Println("WARNING: No memory limit support")
+	fmt.Println("Client version:", VERSION)
+	fmt.Println("Server version:", out.Version)
+	if out.GitCommit != "" {
+		fmt.Println("Git commit:", out.GitCommit)
 	}
 	}
-	if !out.SwapLimit {
-		fmt.Println("WARNING: No swap limit support")
+	if out.GoVersion != "" {
+		fmt.Println("Go version:", out.GoVersion)
 	}
 	}
-
 	return nil
 	return nil
 }
 }
 
 
@@ -420,15 +418,24 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
 		return err
 		return err
 	}
 	}
 
 
-	var out ApiInfo
-	err = json.Unmarshal(body, &out)
-	if err != nil {
+	var out APIInfo
+	if err := json.Unmarshal(body, &out); err != nil {
 		return err
 		return err
 	}
 	}
-	fmt.Printf("containers: %d\nversion: %s\nimages: %d\nGo version: %s\n", out.Containers, out.Version, out.Images, out.GoVersion)
-	if out.Debug {
-		fmt.Println("debug mode enabled")
-		fmt.Printf("fds: %d\ngoroutines: %d\n", out.NFd, out.NGoroutines)
+
+	fmt.Printf("Containers: %d\n", out.Containers)
+	fmt.Printf("Images: %d\n", out.Images)
+	if out.Debug || os.Getenv("DEBUG") != "" {
+		fmt.Printf("Debug mode (server): %v\n", out.Debug)
+		fmt.Printf("Debug mode (client): %v\n", os.Getenv("DEBUG") != "")
+		fmt.Printf("Fds: %d\n", out.NFd)
+		fmt.Printf("Goroutines: %d\n", out.NGoroutines)
+	}
+	if !out.MemoryLimit {
+		fmt.Println("WARNING: No memory limit support")
+	}
+	if !out.SwapLimit {
+		fmt.Println("WARNING: No swap limit support")
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -575,7 +582,7 @@ func (cli *DockerCli) CmdRmi(args ...string) error {
 		if err != nil {
 		if err != nil {
 			fmt.Fprintf(os.Stderr, "%s", err)
 			fmt.Fprintf(os.Stderr, "%s", err)
 		} else {
 		} else {
-			var outs []ApiRmi
+			var outs []APIRmi
 			err = json.Unmarshal(body, &outs)
 			err = json.Unmarshal(body, &outs)
 			if err != nil {
 			if err != nil {
 				return err
 				return err
@@ -607,7 +614,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
 		return err
 		return err
 	}
 	}
 
 
-	var outs []ApiHistory
+	var outs []APIHistory
 	err = json.Unmarshal(body, &outs)
 	err = json.Unmarshal(body, &outs)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -616,7 +623,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
 	fmt.Fprintln(w, "ID\tCREATED\tCREATED BY")
 	fmt.Fprintln(w, "ID\tCREATED\tCREATED BY")
 
 
 	for _, out := range outs {
 	for _, out := range outs {
-		fmt.Fprintf(w, "%s\t%s ago\t%s\n", out.Id, utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.CreatedBy)
+		fmt.Fprintf(w, "%s\t%s ago\t%s\n", out.ID, utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.CreatedBy)
 	}
 	}
 	w.Flush()
 	w.Flush()
 	return nil
 	return nil
@@ -742,12 +749,6 @@ func (cli *DockerCli) CmdPull(args ...string) error {
 		remote = remoteParts[0]
 		remote = remoteParts[0]
 	}
 	}
 
 
-	if strings.Contains(remote, "/") {
-		if _, err := cli.checkIfLogged(true, "pull"); err != nil {
-			return err
-		}
-	}
-
 	v := url.Values{}
 	v := url.Values{}
 	v.Set("fromImage", remote)
 	v.Set("fromImage", remote)
 	v.Set("tag", *tag)
 	v.Set("tag", *tag)
@@ -795,7 +796,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
 			return err
 			return err
 		}
 		}
 
 
-		var outs []ApiImages
+		var outs []APIImages
 		err = json.Unmarshal(body, &outs)
 		err = json.Unmarshal(body, &outs)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
@@ -817,16 +818,16 @@ func (cli *DockerCli) CmdImages(args ...string) error {
 			if !*quiet {
 			if !*quiet {
 				fmt.Fprintf(w, "%s\t%s\t", out.Repository, out.Tag)
 				fmt.Fprintf(w, "%s\t%s\t", out.Repository, out.Tag)
 				if *noTrunc {
 				if *noTrunc {
-					fmt.Fprintf(w, "%s\t", out.Id)
+					fmt.Fprintf(w, "%s\t", out.ID)
 				} else {
 				} else {
-					fmt.Fprintf(w, "%s\t", utils.TruncateId(out.Id))
+					fmt.Fprintf(w, "%s\t", utils.TruncateID(out.ID))
 				}
 				}
 				fmt.Fprintf(w, "%s ago\n", utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))))
 				fmt.Fprintf(w, "%s ago\n", utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))))
 			} else {
 			} else {
 				if *noTrunc {
 				if *noTrunc {
-					fmt.Fprintln(w, out.Id)
+					fmt.Fprintln(w, out.ID)
 				} else {
 				} else {
-					fmt.Fprintln(w, utils.TruncateId(out.Id))
+					fmt.Fprintln(w, utils.TruncateID(out.ID))
 				}
 				}
 			}
 			}
 		}
 		}
@@ -873,7 +874,7 @@ func (cli *DockerCli) CmdPs(args ...string) error {
 		return err
 		return err
 	}
 	}
 
 
-	var outs []ApiContainers
+	var outs []APIContainers
 	err = json.Unmarshal(body, &outs)
 	err = json.Unmarshal(body, &outs)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -886,15 +887,15 @@ func (cli *DockerCli) CmdPs(args ...string) error {
 	for _, out := range outs {
 	for _, out := range outs {
 		if !*quiet {
 		if !*quiet {
 			if *noTrunc {
 			if *noTrunc {
-				fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\n", out.Id, out.Image, out.Command, utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Status, out.Ports)
+				fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\n", out.ID, out.Image, out.Command, utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Status, out.Ports)
 			} else {
 			} else {
-				fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\n", utils.TruncateId(out.Id), out.Image, utils.Trunc(out.Command, 20), utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Status, out.Ports)
+				fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\n", utils.TruncateID(out.ID), out.Image, utils.Trunc(out.Command, 20), utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Status, out.Ports)
 			}
 			}
 		} else {
 		} else {
 			if *noTrunc {
 			if *noTrunc {
-				fmt.Fprintln(w, out.Id)
+				fmt.Fprintln(w, out.ID)
 			} else {
 			} else {
-				fmt.Fprintln(w, utils.TruncateId(out.Id))
+				fmt.Fprintln(w, utils.TruncateID(out.ID))
 			}
 			}
 		}
 		}
 	}
 	}
@@ -937,13 +938,13 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
 		return err
 		return err
 	}
 	}
 
 
-	apiId := &ApiId{}
-	err = json.Unmarshal(body, apiId)
+	apiID := &APIID{}
+	err = json.Unmarshal(body, apiID)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	fmt.Println(apiId.Id)
+	fmt.Println(apiID.ID)
 	return nil
 	return nil
 }
 }
 
 
@@ -1080,7 +1081,7 @@ func (cli *DockerCli) CmdSearch(args ...string) error {
 		return err
 		return err
 	}
 	}
 
 
-	outs := []ApiSearch{}
+	outs := []APISearch{}
 	err = json.Unmarshal(body, &outs)
 	err = json.Unmarshal(body, &outs)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -1212,7 +1213,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 		return err
 		return err
 	}
 	}
 
 
-	out := &ApiRun{}
+	out := &APIRun{}
 	err = json.Unmarshal(body, out)
 	err = json.Unmarshal(body, out)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -1233,18 +1234,21 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 	}
 	}
 
 
 	//start the container
 	//start the container
-	_, _, err = cli.call("POST", "/containers/"+out.Id+"/start", nil)
+	_, _, err = cli.call("POST", "/containers/"+out.ID+"/start", nil)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
+	if !config.AttachStdout && !config.AttachStderr {
+		fmt.Println(out.ID)
+	}
 	if connections > 0 {
 	if connections > 0 {
 		chErrors := make(chan error, connections)
 		chErrors := make(chan error, connections)
-		cli.monitorTtySize(out.Id)
+		cli.monitorTtySize(out.ID)
 
 
 		if splitStderr && config.AttachStderr {
 		if splitStderr && config.AttachStderr {
 			go func() {
 			go func() {
-				chErrors <- cli.hijack("POST", "/containers/"+out.Id+"/attach?logs=1&stream=1&stderr=1", config.Tty, nil, os.Stderr)
+				chErrors <- cli.hijack("POST", "/containers/"+out.ID+"/attach?logs=1&stream=1&stderr=1", config.Tty, nil, os.Stderr)
 			}()
 			}()
 		}
 		}
 
 
@@ -1262,7 +1266,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 			v.Set("stderr", "1")
 			v.Set("stderr", "1")
 		}
 		}
 		go func() {
 		go func() {
-			chErrors <- cli.hijack("POST", "/containers/"+out.Id+"/attach?"+v.Encode(), config.Tty, os.Stdin, os.Stdout)
+			chErrors <- cli.hijack("POST", "/containers/"+out.ID+"/attach?"+v.Encode(), config.Tty, os.Stdin, os.Stdout)
 		}()
 		}()
 		for connections > 0 {
 		for connections > 0 {
 			err := <-chErrors
 			err := <-chErrors
@@ -1272,9 +1276,6 @@ func (cli *DockerCli) CmdRun(args ...string) error {
 			connections -= 1
 			connections -= 1
 		}
 		}
 	}
 	}
-	if !config.AttachStdout && !config.AttachStderr {
-		fmt.Println(out.Id)
-	}
 	return nil
 	return nil
 }
 }
 
 
@@ -1322,7 +1323,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/v%g%s", cli.host, cli.port, API_VERSION, path), params)
+	req, err := http.NewRequest(method, fmt.Sprintf("http://%s:%d/v%g%s", cli.host, cli.port, APIVERSION, path), params)
 	if err != nil {
 	if err != nil {
 		return nil, -1, err
 		return nil, -1, err
 	}
 	}
@@ -1354,7 +1355,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/v%g%s", cli.host, cli.port, API_VERSION, path), in)
+	req, err := http.NewRequest(method, fmt.Sprintf("http://%s:%d/v%g%s", cli.host, cli.port, APIVERSION, path), in)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -1381,14 +1382,14 @@ func (cli *DockerCli) stream(method, path string, in io.Reader, out io.Writer) e
 	if resp.Header.Get("Content-Type") == "application/json" {
 	if resp.Header.Get("Content-Type") == "application/json" {
 		dec := json.NewDecoder(resp.Body)
 		dec := json.NewDecoder(resp.Body)
 		for {
 		for {
-			var m utils.JsonMessage
+			var m utils.JSONMessage
 			if err := dec.Decode(&m); err == io.EOF {
 			if err := dec.Decode(&m); err == io.EOF {
 				break
 				break
 			} else if err != nil {
 			} else if err != nil {
 				return err
 				return err
 			}
 			}
 			if m.Progress != "" {
 			if m.Progress != "" {
-				fmt.Fprintf(out, "Downloading %s\r", m.Progress)
+				fmt.Fprintf(out, "%s %s\r", m.Status, m.Progress)
 			} else if m.Error != "" {
 			} else if m.Error != "" {
 				return fmt.Errorf(m.Error)
 				return fmt.Errorf(m.Error)
 			} else {
 			} else {
@@ -1404,7 +1405,7 @@ func (cli *DockerCli) stream(method, path string, in io.Reader, out io.Writer) e
 }
 }
 
 
 func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in *os.File, out io.Writer) error {
 func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in *os.File, out io.Writer) error {
-	req, err := http.NewRequest(method, fmt.Sprintf("/v%g%s", API_VERSION, path), nil)
+	req, err := http.NewRequest(method, fmt.Sprintf("/v%g%s", APIVERSION, path), nil)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -1425,12 +1426,12 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in *os.Fi
 		return err
 		return err
 	})
 	})
 
 
-	if in != nil && setRawTerminal && term.IsTerminal(int(in.Fd())) && os.Getenv("NORAW") == "" {
-		if oldState, err := term.SetRawTerminal(); err != nil {
+	if in != nil && setRawTerminal && term.IsTerminal(in.Fd()) && os.Getenv("NORAW") == "" {
+		oldState, err := term.SetRawTerminal()
+		if err != nil {
 			return err
 			return err
-		} else {
-			defer term.RestoreTerminal(oldState)
 		}
 		}
+		defer term.RestoreTerminal(oldState)
 	}
 	}
 	sendStdin := utils.Go(func() error {
 	sendStdin := utils.Go(func() error {
 		_, err := io.Copy(rwc, in)
 		_, err := io.Copy(rwc, in)
@@ -1444,7 +1445,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in *os.Fi
 		return err
 		return err
 	}
 	}
 
 
-	if !term.IsTerminal(int(os.Stdin.Fd())) {
+	if !term.IsTerminal(os.Stdin.Fd()) {
 		if err := <-sendStdin; err != nil {
 		if err := <-sendStdin; err != nil {
 			return err
 			return err
 		}
 		}

+ 46 - 45
container.go

@@ -23,7 +23,7 @@ import (
 type Container struct {
 type Container struct {
 	root string
 	root string
 
 
-	Id string
+	ID string
 
 
 	Created time.Time
 	Created time.Time
 
 
@@ -167,8 +167,8 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *flag.FlagSet
 }
 }
 
 
 type NetworkSettings struct {
 type NetworkSettings struct {
-	IpAddress   string
-	IpPrefixLen int
+	IPAddress   string
+	IPPrefixLen int
 	Gateway     string
 	Gateway     string
 	Bridge      string
 	Bridge      string
 	PortMapping map[string]string
 	PortMapping map[string]string
@@ -409,7 +409,7 @@ func (container *Container) Start() error {
 	defer container.State.unlock()
 	defer container.State.unlock()
 
 
 	if container.State.Running {
 	if container.State.Running {
-		return fmt.Errorf("The container %s is already running.", container.Id)
+		return fmt.Errorf("The container %s is already running.", container.ID)
 	}
 	}
 	if err := container.EnsureMounted(); err != nil {
 	if err := container.EnsureMounted(); err != nil {
 		return err
 		return err
@@ -431,24 +431,24 @@ func (container *Container) Start() error {
 
 
 	// Create the requested volumes volumes
 	// Create the requested volumes volumes
 	for volPath := range container.Config.Volumes {
 	for volPath := range container.Config.Volumes {
-		if c, err := container.runtime.volumes.Create(nil, container, "", "", nil); err != nil {
+		c, err := container.runtime.volumes.Create(nil, container, "", "", nil)
+		if err != nil {
 			return err
 			return err
-		} else {
-			if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil {
-				return nil
-			}
-			container.Volumes[volPath] = c.Id
 		}
 		}
+		if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil {
+			return nil
+		}
+		container.Volumes[volPath] = c.ID
 	}
 	}
 
 
 	if container.Config.VolumesFrom != "" {
 	if container.Config.VolumesFrom != "" {
 		c := container.runtime.Get(container.Config.VolumesFrom)
 		c := container.runtime.Get(container.Config.VolumesFrom)
 		if c == nil {
 		if c == nil {
-			return fmt.Errorf("Container %s not found. Impossible to mount its volumes", container.Id)
+			return fmt.Errorf("Container %s not found. Impossible to mount its volumes", container.ID)
 		}
 		}
 		for volPath, id := range c.Volumes {
 		for volPath, id := range c.Volumes {
 			if _, exists := container.Volumes[volPath]; exists {
 			if _, exists := container.Volumes[volPath]; exists {
-				return fmt.Errorf("The requested volume %s overlap one of the volume of the container %s", volPath, c.Id)
+				return fmt.Errorf("The requested volume %s overlap one of the volume of the container %s", volPath, c.ID)
 			}
 			}
 			if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil {
 			if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil {
 				return nil
 				return nil
@@ -462,7 +462,7 @@ func (container *Container) Start() error {
 	}
 	}
 
 
 	params := []string{
 	params := []string{
-		"-n", container.Id,
+		"-n", container.ID,
 		"-f", container.lxcConfigPath(),
 		"-f", container.lxcConfigPath(),
 		"--",
 		"--",
 		"/sbin/init",
 		"/sbin/init",
@@ -573,17 +573,17 @@ func (container *Container) allocateNetwork() error {
 	}
 	}
 	container.NetworkSettings.PortMapping = make(map[string]string)
 	container.NetworkSettings.PortMapping = make(map[string]string)
 	for _, spec := range container.Config.PortSpecs {
 	for _, spec := range container.Config.PortSpecs {
-		if nat, err := iface.AllocatePort(spec); err != nil {
+		nat, err := iface.AllocatePort(spec)
+		if err != nil {
 			iface.Release()
 			iface.Release()
 			return err
 			return err
-		} else {
-			container.NetworkSettings.PortMapping[strconv.Itoa(nat.Backend)] = strconv.Itoa(nat.Frontend)
 		}
 		}
+		container.NetworkSettings.PortMapping[strconv.Itoa(nat.Backend)] = strconv.Itoa(nat.Frontend)
 	}
 	}
 	container.network = iface
 	container.network = iface
 	container.NetworkSettings.Bridge = container.runtime.networkManager.bridgeIface
 	container.NetworkSettings.Bridge = container.runtime.networkManager.bridgeIface
-	container.NetworkSettings.IpAddress = iface.IPNet.IP.String()
-	container.NetworkSettings.IpPrefixLen, _ = iface.IPNet.Mask.Size()
+	container.NetworkSettings.IPAddress = iface.IPNet.IP.String()
+	container.NetworkSettings.IPPrefixLen, _ = iface.IPNet.Mask.Size()
 	container.NetworkSettings.Gateway = iface.Gateway.String()
 	container.NetworkSettings.Gateway = iface.Gateway.String()
 	return nil
 	return nil
 }
 }
@@ -597,16 +597,16 @@ func (container *Container) releaseNetwork() {
 // FIXME: replace this with a control socket within docker-init
 // FIXME: replace this with a control socket within docker-init
 func (container *Container) waitLxc() error {
 func (container *Container) waitLxc() error {
 	for {
 	for {
-		if output, err := exec.Command("lxc-info", "-n", container.Id).CombinedOutput(); err != nil {
+		output, err := exec.Command("lxc-info", "-n", container.ID).CombinedOutput()
+		if err != nil {
 			return err
 			return err
-		} else {
-			if !strings.Contains(string(output), "RUNNING") {
-				return nil
-			}
+		}
+		if !strings.Contains(string(output), "RUNNING") {
+			return nil
 		}
 		}
 		time.Sleep(500 * time.Millisecond)
 		time.Sleep(500 * time.Millisecond)
 	}
 	}
-	return nil
+	panic("Unreachable")
 }
 }
 
 
 func (container *Container) monitor() {
 func (container *Container) monitor() {
@@ -616,17 +616,17 @@ func (container *Container) monitor() {
 	// If the command does not exists, try to wait via lxc
 	// If the command does not exists, try to wait via lxc
 	if container.cmd == nil {
 	if container.cmd == nil {
 		if err := container.waitLxc(); err != nil {
 		if err := container.waitLxc(); err != nil {
-			utils.Debugf("%s: Process: %s", container.Id, err)
+			utils.Debugf("%s: Process: %s", container.ID, err)
 		}
 		}
 	} else {
 	} else {
 		if err := container.cmd.Wait(); err != nil {
 		if err := container.cmd.Wait(); err != nil {
 			// Discard the error as any signals or non 0 returns will generate an error
 			// Discard the error as any signals or non 0 returns will generate an error
-			utils.Debugf("%s: Process: %s", container.Id, err)
+			utils.Debugf("%s: Process: %s", container.ID, err)
 		}
 		}
 	}
 	}
 	utils.Debugf("Process finished")
 	utils.Debugf("Process finished")
 
 
-	var exitCode int = -1
+	exitCode := -1
 	if container.cmd != nil {
 	if container.cmd != nil {
 		exitCode = container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
 		exitCode = container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
 	}
 	}
@@ -635,24 +635,24 @@ func (container *Container) monitor() {
 	container.releaseNetwork()
 	container.releaseNetwork()
 	if container.Config.OpenStdin {
 	if container.Config.OpenStdin {
 		if err := container.stdin.Close(); err != nil {
 		if err := container.stdin.Close(); err != nil {
-			utils.Debugf("%s: Error close stdin: %s", container.Id, err)
+			utils.Debugf("%s: Error close stdin: %s", container.ID, err)
 		}
 		}
 	}
 	}
 	if err := container.stdout.CloseWriters(); err != nil {
 	if err := container.stdout.CloseWriters(); err != nil {
-		utils.Debugf("%s: Error close stdout: %s", container.Id, err)
+		utils.Debugf("%s: Error close stdout: %s", container.ID, err)
 	}
 	}
 	if err := container.stderr.CloseWriters(); err != nil {
 	if err := container.stderr.CloseWriters(); err != nil {
-		utils.Debugf("%s: Error close stderr: %s", container.Id, err)
+		utils.Debugf("%s: Error close stderr: %s", container.ID, err)
 	}
 	}
 
 
 	if container.ptyMaster != nil {
 	if container.ptyMaster != nil {
 		if err := container.ptyMaster.Close(); err != nil {
 		if err := container.ptyMaster.Close(); err != nil {
-			utils.Debugf("%s: Error closing Pty master: %s", container.Id, err)
+			utils.Debugf("%s: Error closing Pty master: %s", container.ID, err)
 		}
 		}
 	}
 	}
 
 
 	if err := container.Unmount(); err != nil {
 	if err := container.Unmount(); err != nil {
-		log.Printf("%v: Failed to umount filesystem: %v", container.Id, err)
+		log.Printf("%v: Failed to umount filesystem: %v", container.ID, err)
 	}
 	}
 
 
 	// Re-create a brand new stdin pipe once the container exited
 	// Re-create a brand new stdin pipe once the container exited
@@ -673,7 +673,7 @@ func (container *Container) monitor() {
 		// This is because State.setStopped() has already been called, and has caused Wait()
 		// This is because State.setStopped() has already been called, and has caused Wait()
 		// to return.
 		// to return.
 		// FIXME: why are we serializing running state to disk in the first place?
 		// FIXME: why are we serializing running state to disk in the first place?
-		//log.Printf("%s: Failed to dump configuration to the disk: %s", container.Id, err)
+		//log.Printf("%s: Failed to dump configuration to the disk: %s", container.ID, err)
 	}
 	}
 }
 }
 
 
@@ -683,17 +683,17 @@ func (container *Container) kill() error {
 	}
 	}
 
 
 	// Sending SIGKILL to the process via lxc
 	// Sending SIGKILL to the process via lxc
-	output, err := exec.Command("lxc-kill", "-n", container.Id, "9").CombinedOutput()
+	output, err := exec.Command("lxc-kill", "-n", container.ID, "9").CombinedOutput()
 	if err != nil {
 	if err != nil {
-		log.Printf("error killing container %s (%s, %s)", container.Id, output, err)
+		log.Printf("error killing container %s (%s, %s)", container.ID, output, err)
 	}
 	}
 
 
 	// 2. Wait for the process to die, in last resort, try to kill the process directly
 	// 2. Wait for the process to die, in last resort, try to kill the process directly
 	if err := container.WaitTimeout(10 * time.Second); err != nil {
 	if err := container.WaitTimeout(10 * time.Second); err != nil {
 		if container.cmd == nil {
 		if container.cmd == nil {
-			return fmt.Errorf("lxc-kill failed, impossible to kill the container %s", container.Id)
+			return fmt.Errorf("lxc-kill failed, impossible to kill the container %s", container.ID)
 		}
 		}
-		log.Printf("Container %s failed to exit within 10 seconds of lxc SIGKILL - trying direct SIGKILL", container.Id)
+		log.Printf("Container %s failed to exit within 10 seconds of lxc SIGKILL - trying direct SIGKILL", container.ID)
 		if err := container.cmd.Process.Kill(); err != nil {
 		if err := container.cmd.Process.Kill(); err != nil {
 			return err
 			return err
 		}
 		}
@@ -721,7 +721,7 @@ func (container *Container) Stop(seconds int) error {
 	}
 	}
 
 
 	// 1. Send a SIGTERM
 	// 1. Send a SIGTERM
-	if output, err := exec.Command("lxc-kill", "-n", container.Id, "15").CombinedOutput(); err != nil {
+	if output, err := exec.Command("lxc-kill", "-n", container.ID, "15").CombinedOutput(); err != nil {
 		log.Print(string(output))
 		log.Print(string(output))
 		log.Print("Failed to send SIGTERM to the process, force killing")
 		log.Print("Failed to send SIGTERM to the process, force killing")
 		if err := container.kill(); err != nil {
 		if err := container.kill(); err != nil {
@@ -731,7 +731,7 @@ func (container *Container) Stop(seconds int) error {
 
 
 	// 2. Wait for the process to exit on its own
 	// 2. Wait for the process to exit on its own
 	if err := container.WaitTimeout(time.Duration(seconds) * time.Second); err != nil {
 	if err := container.WaitTimeout(time.Duration(seconds) * time.Second); err != nil {
-		log.Printf("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.Id, seconds)
+		log.Printf("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.ID, seconds)
 		if err := container.kill(); err != nil {
 		if err := container.kill(); err != nil {
 			return err
 			return err
 		}
 		}
@@ -795,7 +795,8 @@ func (container *Container) WaitTimeout(timeout time.Duration) error {
 	case <-done:
 	case <-done:
 		return nil
 		return nil
 	}
 	}
-	panic("unreachable")
+
+	panic("Unreachable")
 }
 }
 
 
 func (container *Container) EnsureMounted() error {
 func (container *Container) EnsureMounted() error {
@@ -838,16 +839,16 @@ func (container *Container) Unmount() error {
 	return Unmount(container.RootfsPath())
 	return Unmount(container.RootfsPath())
 }
 }
 
 
-// ShortId returns a shorthand version of the container's id for convenience.
+// ShortID returns a shorthand version of the container's id for convenience.
 // A collision with other container shorthands is very unlikely, but possible.
 // A collision with other container shorthands is very unlikely, but possible.
 // In case of a collision a lookup with Runtime.Get() will fail, and the caller
 // In case of a collision a lookup with Runtime.Get() will fail, and the caller
 // will need to use a langer prefix, or the full-length container Id.
 // will need to use a langer prefix, or the full-length container Id.
-func (container *Container) ShortId() string {
-	return utils.TruncateId(container.Id)
+func (container *Container) ShortID() string {
+	return utils.TruncateID(container.ID)
 }
 }
 
 
 func (container *Container) logPath(name string) string {
 func (container *Container) logPath(name string) string {
-	return path.Join(container.root, fmt.Sprintf("%s-%s.log", container.Id, name))
+	return path.Join(container.root, fmt.Sprintf("%s-%s.log", container.ID, name))
 }
 }
 
 
 func (container *Container) ReadLog(name string) (io.Reader, error) {
 func (container *Container) ReadLog(name string) (io.Reader, error) {
@@ -887,7 +888,7 @@ func (container *Container) rwPath() string {
 	return path.Join(container.root, "rw")
 	return path.Join(container.root, "rw")
 }
 }
 
 
-func validateId(id string) error {
+func validateID(id string) error {
 	if id == "" {
 	if id == "" {
 		return fmt.Errorf("Invalid empty id")
 		return fmt.Errorf("Invalid empty id")
 	}
 	}

+ 64 - 33
container_test.go

@@ -14,7 +14,7 @@ import (
 	"time"
 	"time"
 )
 )
 
 
-func TestIdFormat(t *testing.T) {
+func TestIDFormat(t *testing.T) {
 	runtime, err := newTestRuntime()
 	runtime, err := newTestRuntime()
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -22,19 +22,19 @@ func TestIdFormat(t *testing.T) {
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container1, err := NewBuilder(runtime).Create(
 	container1, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"/bin/sh", "-c", "echo hello world"},
 			Cmd:   []string{"/bin/sh", "-c", "echo hello world"},
 		},
 		},
 	)
 	)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	match, err := regexp.Match("^[0-9a-f]{64}$", []byte(container1.Id))
+	match, err := regexp.Match("^[0-9a-f]{64}$", []byte(container1.ID))
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if !match {
 	if !match {
-		t.Fatalf("Invalid container ID: %s", container1.Id)
+		t.Fatalf("Invalid container ID: %s", container1.ID)
 	}
 	}
 }
 }
 
 
@@ -46,7 +46,7 @@ func TestMultipleAttachRestart(t *testing.T) {
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd: []string{"/bin/sh", "-c",
 			Cmd: []string{"/bin/sh", "-c",
 				"i=1; while [ $i -le 5 ]; do i=`expr $i + 1`;  echo hello; done"},
 				"i=1; while [ $i -le 5 ]; do i=`expr $i + 1`;  echo hello; done"},
 		},
 		},
@@ -153,7 +153,7 @@ func TestDiff(t *testing.T) {
 	// Create a container and remove a file
 	// Create a container and remove a file
 	container1, err := builder.Create(
 	container1, err := builder.Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"/bin/rm", "/etc/passwd"},
 			Cmd:   []string{"/bin/rm", "/etc/passwd"},
 		},
 		},
 	)
 	)
@@ -194,7 +194,7 @@ func TestDiff(t *testing.T) {
 	// Create a new container from the commited image
 	// Create a new container from the commited image
 	container2, err := builder.Create(
 	container2, err := builder.Create(
 		&Config{
 		&Config{
-			Image: img.Id,
+			Image: img.ID,
 			Cmd:   []string{"cat", "/etc/passwd"},
 			Cmd:   []string{"cat", "/etc/passwd"},
 		},
 		},
 	)
 	)
@@ -217,6 +217,37 @@ func TestDiff(t *testing.T) {
 			t.Fatalf("/etc/passwd should not be present in the diff after commit.")
 			t.Fatalf("/etc/passwd should not be present in the diff after commit.")
 		}
 		}
 	}
 	}
+
+	// Create a new containere
+	container3, err := builder.Create(
+		&Config{
+			Image: GetTestImage(runtime).ID,
+			Cmd:   []string{"rm", "/bin/httpd"},
+		},
+	)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer runtime.Destroy(container3)
+
+	if err := container3.Run(); err != nil {
+		t.Fatal(err)
+	}
+
+	// Check the changelog
+	c, err = container3.Changes()
+	if err != nil {
+		t.Fatal(err)
+	}
+	success = false
+	for _, elem := range c {
+		if elem.Path == "/bin/httpd" && elem.Kind == 2 {
+			success = true
+		}
+	}
+	if !success {
+		t.Fatalf("/bin/httpd should be present in the diff after commit.")
+	}
 }
 }
 
 
 func TestCommitAutoRun(t *testing.T) {
 func TestCommitAutoRun(t *testing.T) {
@@ -229,7 +260,7 @@ func TestCommitAutoRun(t *testing.T) {
 	builder := NewBuilder(runtime)
 	builder := NewBuilder(runtime)
 	container1, err := builder.Create(
 	container1, err := builder.Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"/bin/sh", "-c", "echo hello > /world"},
 			Cmd:   []string{"/bin/sh", "-c", "echo hello > /world"},
 		},
 		},
 	)
 	)
@@ -260,7 +291,7 @@ func TestCommitAutoRun(t *testing.T) {
 	// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
 	// FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
 	container2, err := builder.Create(
 	container2, err := builder.Create(
 		&Config{
 		&Config{
-			Image: img.Id,
+			Image: img.ID,
 		},
 		},
 	)
 	)
 	if err != nil {
 	if err != nil {
@@ -309,7 +340,7 @@ func TestCommitRun(t *testing.T) {
 
 
 	container1, err := builder.Create(
 	container1, err := builder.Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"/bin/sh", "-c", "echo hello > /world"},
 			Cmd:   []string{"/bin/sh", "-c", "echo hello > /world"},
 		},
 		},
 	)
 	)
@@ -341,7 +372,7 @@ func TestCommitRun(t *testing.T) {
 
 
 	container2, err := builder.Create(
 	container2, err := builder.Create(
 		&Config{
 		&Config{
-			Image: img.Id,
+			Image: img.ID,
 			Cmd:   []string{"cat", "/world"},
 			Cmd:   []string{"cat", "/world"},
 		},
 		},
 	)
 	)
@@ -388,7 +419,7 @@ func TestStart(t *testing.T) {
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image:     GetTestImage(runtime).Id,
+			Image:     GetTestImage(runtime).ID,
 			Memory:    33554432,
 			Memory:    33554432,
 			CpuShares: 1000,
 			CpuShares: 1000,
 			Cmd:       []string{"/bin/cat"},
 			Cmd:       []string{"/bin/cat"},
@@ -432,7 +463,7 @@ func TestRun(t *testing.T) {
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"ls", "-al"},
 			Cmd:   []string{"ls", "-al"},
 		},
 		},
 	)
 	)
@@ -460,7 +491,7 @@ func TestOutput(t *testing.T) {
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(
 	container, err := NewBuilder(runtime).Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"echo", "-n", "foobar"},
 			Cmd:   []string{"echo", "-n", "foobar"},
 		},
 		},
 	)
 	)
@@ -484,7 +515,7 @@ func TestKillDifferentUser(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"tail", "-f", "/etc/resolv.conf"},
 		Cmd:   []string{"tail", "-f", "/etc/resolv.conf"},
 		User:  "daemon",
 		User:  "daemon",
 	},
 	},
@@ -532,7 +563,7 @@ func TestKill(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"cat", "/dev/zero"},
 		Cmd:   []string{"cat", "/dev/zero"},
 	},
 	},
 	)
 	)
@@ -580,7 +611,7 @@ func TestExitCode(t *testing.T) {
 	builder := NewBuilder(runtime)
 	builder := NewBuilder(runtime)
 
 
 	trueContainer, err := builder.Create(&Config{
 	trueContainer, err := builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"/bin/true", ""},
 		Cmd:   []string{"/bin/true", ""},
 	})
 	})
 	if err != nil {
 	if err != nil {
@@ -595,7 +626,7 @@ func TestExitCode(t *testing.T) {
 	}
 	}
 
 
 	falseContainer, err := builder.Create(&Config{
 	falseContainer, err := builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"/bin/false", ""},
 		Cmd:   []string{"/bin/false", ""},
 	})
 	})
 	if err != nil {
 	if err != nil {
@@ -617,7 +648,7 @@ func TestRestart(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"echo", "-n", "foobar"},
 		Cmd:   []string{"echo", "-n", "foobar"},
 	},
 	},
 	)
 	)
@@ -650,7 +681,7 @@ func TestRestartStdin(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"cat"},
 		Cmd:   []string{"cat"},
 
 
 		OpenStdin: true,
 		OpenStdin: true,
@@ -732,7 +763,7 @@ func TestUser(t *testing.T) {
 
 
 	// Default user must be root
 	// Default user must be root
 	container, err := builder.Create(&Config{
 	container, err := builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"id"},
 		Cmd:   []string{"id"},
 	},
 	},
 	)
 	)
@@ -750,7 +781,7 @@ func TestUser(t *testing.T) {
 
 
 	// Set a username
 	// Set a username
 	container, err = builder.Create(&Config{
 	container, err = builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"id"},
 		Cmd:   []string{"id"},
 
 
 		User: "root",
 		User: "root",
@@ -770,7 +801,7 @@ func TestUser(t *testing.T) {
 
 
 	// Set a UID
 	// Set a UID
 	container, err = builder.Create(&Config{
 	container, err = builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"id"},
 		Cmd:   []string{"id"},
 
 
 		User: "0",
 		User: "0",
@@ -790,7 +821,7 @@ func TestUser(t *testing.T) {
 
 
 	// Set a different user by uid
 	// Set a different user by uid
 	container, err = builder.Create(&Config{
 	container, err = builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"id"},
 		Cmd:   []string{"id"},
 
 
 		User: "1",
 		User: "1",
@@ -812,7 +843,7 @@ func TestUser(t *testing.T) {
 
 
 	// Set a different user by username
 	// Set a different user by username
 	container, err = builder.Create(&Config{
 	container, err = builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"id"},
 		Cmd:   []string{"id"},
 
 
 		User: "daemon",
 		User: "daemon",
@@ -841,7 +872,7 @@ func TestMultipleContainers(t *testing.T) {
 	builder := NewBuilder(runtime)
 	builder := NewBuilder(runtime)
 
 
 	container1, err := builder.Create(&Config{
 	container1, err := builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"cat", "/dev/zero"},
 		Cmd:   []string{"cat", "/dev/zero"},
 	},
 	},
 	)
 	)
@@ -851,7 +882,7 @@ func TestMultipleContainers(t *testing.T) {
 	defer runtime.Destroy(container1)
 	defer runtime.Destroy(container1)
 
 
 	container2, err := builder.Create(&Config{
 	container2, err := builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"cat", "/dev/zero"},
 		Cmd:   []string{"cat", "/dev/zero"},
 	},
 	},
 	)
 	)
@@ -897,7 +928,7 @@ func TestStdin(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"cat"},
 		Cmd:   []string{"cat"},
 
 
 		OpenStdin: true,
 		OpenStdin: true,
@@ -944,7 +975,7 @@ func TestTty(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"cat"},
 		Cmd:   []string{"cat"},
 
 
 		OpenStdin: true,
 		OpenStdin: true,
@@ -991,7 +1022,7 @@ func TestEnv(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"/usr/bin/env"},
 		Cmd:   []string{"/usr/bin/env"},
 	},
 	},
 	)
 	)
@@ -1069,7 +1100,7 @@ func TestLXCConfig(t *testing.T) {
 	cpuMax := 10000
 	cpuMax := 10000
 	cpu := cpuMin + rand.Intn(cpuMax-cpuMin)
 	cpu := cpuMin + rand.Intn(cpuMax-cpuMin)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"/bin/true"},
 		Cmd:   []string{"/bin/true"},
 
 
 		Hostname:  "foobar",
 		Hostname:  "foobar",
@@ -1097,7 +1128,7 @@ func BenchmarkRunSequencial(b *testing.B) {
 	defer nuke(runtime)
 	defer nuke(runtime)
 	for i := 0; i < b.N; i++ {
 	for i := 0; i < b.N; i++ {
 		container, err := NewBuilder(runtime).Create(&Config{
 		container, err := NewBuilder(runtime).Create(&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{"echo", "-n", "foo"},
 			Cmd:   []string{"echo", "-n", "foo"},
 		},
 		},
 		)
 		)
@@ -1132,7 +1163,7 @@ func BenchmarkRunParallel(b *testing.B) {
 		tasks = append(tasks, complete)
 		tasks = append(tasks, complete)
 		go func(i int, complete chan error) {
 		go func(i int, complete chan error) {
 			container, err := NewBuilder(runtime).Create(&Config{
 			container, err := NewBuilder(runtime).Create(&Config{
-				Image: GetTestImage(runtime).Id,
+				Image: GetTestImage(runtime).ID,
 				Cmd:   []string{"echo", "-n", "foo"},
 				Cmd:   []string{"echo", "-n", "foo"},
 			},
 			},
 			)
 			)

+ 3 - 3
contrib/crashTest.go

@@ -11,13 +11,13 @@ import (
 	"time"
 	"time"
 )
 )
 
 
-var DOCKER_PATH string = path.Join(os.Getenv("DOCKERPATH"), "docker")
+var DOCKERPATH = path.Join(os.Getenv("DOCKERPATH"), "docker")
 
 
 // WARNING: this crashTest will 1) crash your host, 2) remove all containers
 // WARNING: this crashTest will 1) crash your host, 2) remove all containers
 func runDaemon() (*exec.Cmd, error) {
 func runDaemon() (*exec.Cmd, error) {
 	os.Remove("/var/run/docker.pid")
 	os.Remove("/var/run/docker.pid")
 	exec.Command("rm", "-rf", "/var/lib/docker/containers").Run()
 	exec.Command("rm", "-rf", "/var/lib/docker/containers").Run()
-	cmd := exec.Command(DOCKER_PATH, "-d")
+	cmd := exec.Command(DOCKERPATH, "-d")
 	outPipe, err := cmd.StdoutPipe()
 	outPipe, err := cmd.StdoutPipe()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -77,7 +77,7 @@ func crashTest() error {
 			stop = false
 			stop = false
 			for i := 0; i < 100 && !stop; {
 			for i := 0; i < 100 && !stop; {
 				func() error {
 				func() error {
-					cmd := exec.Command(DOCKER_PATH, "run", "base", "echo", fmt.Sprintf("%d", totalTestCount))
+					cmd := exec.Command(DOCKERPATH, "run", "base", "echo", fmt.Sprintf("%d", totalTestCount))
 					i++
 					i++
 					totalTestCount++
 					totalTestCount++
 					outPipe, err := cmd.StdoutPipe()
 					outPipe, err := cmd.StdoutPipe()

+ 0 - 1
contrib/docker-build/MAINTAINERS

@@ -1 +0,0 @@
-Solomon Hykes <solomon@dotcloud.com>

+ 0 - 68
contrib/docker-build/README

@@ -1,68 +0,0 @@
-# docker-build: build your software with docker
-
-## Description
-
-docker-build is a script to build docker images from source. It will be deprecated once the 'build' feature is incorporated into docker itself (See https://github.com/dotcloud/docker/issues/278)
-
-Author: Solomon Hykes <solomon@dotcloud.com>
-
-
-## Install
-
-docker-builder requires:
-
-1) A reasonably recent Python setup (tested on 2.7.2).
-
-2) A running docker daemon at version 0.1.4 or more recent (http://www.docker.io/gettingstarted)
-
-
-## Usage
-
-First create a valid Changefile, which defines a sequence of changes to apply to a base image.
-
-    $ cat Changefile
-    # Start build from a know base image
-    from	base:ubuntu-12.10
-    # Update ubuntu sources
-    run	echo 'deb http://archive.ubuntu.com/ubuntu quantal main universe multiverse' > /etc/apt/sources.list
-    run	apt-get update
-    # Install system packages
-    run	DEBIAN_FRONTEND=noninteractive apt-get install -y -q git
-    run DEBIAN_FRONTEND=noninteractive apt-get install -y -q curl
-    run DEBIAN_FRONTEND=noninteractive apt-get install -y -q golang
-    # Insert files from the host (./myscript must be present in the current directory)
-    copy	myscript /usr/local/bin/myscript
-
-
-Run docker-build, and pass the contents of your Changefile as standard input.
-
-    $ IMG=$(./docker-build < Changefile)
-
-This will take a while: for each line of the changefile, docker-build will:
-
-1. Create a new container to execute the given command or insert the given file
-2. Wait for the container to complete execution
-3. Commit the resulting changes as a new image
-4. Use the resulting image as the input of the next step
-
-
-If all the steps succeed, the result will be an image containing the combined results of each build step.
-You can trace back those build steps by inspecting the image's history:
-
-    $ docker history $IMG
-    ID                  CREATED             CREATED BY
-    1e9e2045de86        A few seconds ago   /bin/sh -c cat > /usr/local/bin/myscript; chmod +x /usr/local/bin/git
-    77db140aa62a        A few seconds ago   /bin/sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -q golang
-    77db140aa62a        A few seconds ago   /bin/sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -q curl
-    77db140aa62a        A few seconds ago   /bin/sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -q git 
-    83e85d155451        A few seconds ago   /bin/sh -c apt-get update
-    bfd53b36d9d3        A few seconds ago   /bin/sh -c echo 'deb http://archive.ubuntu.com/ubuntu quantal main universe multiverse' > /etc/apt/sources.list
-    base		2 weeks ago         /bin/bash
-    27cf78414709        2 weeks ago
-
-
-Note that your build started from 'base', as instructed by your Changefile. But that base image itself seems to have been built in 2 steps - hence the extra step in the history.
-
-
-You can use this build technique to create any image you want: a database, a web application, or anything else that can be build by a sequence of unix commands - in other words, anything else.
-

+ 0 - 142
contrib/docker-build/docker-build

@@ -1,142 +0,0 @@
-#!/usr/bin/env python
-
-# docker-build is a script to build docker images from source.
-# It will be deprecated once the 'build' feature is incorporated into docker itself.
-# (See https://github.com/dotcloud/docker/issues/278)
-#
-# Author: Solomon Hykes <solomon@dotcloud.com>
-
-
-
-# First create a valid Changefile, which defines a sequence of changes to apply to a base image.
-# 
-#     $ cat Changefile
-#     # Start build from a know base image
-#     from	base:ubuntu-12.10
-#     # Update ubuntu sources
-#     run	echo 'deb http://archive.ubuntu.com/ubuntu quantal main universe multiverse' > /etc/apt/sources.list
-#     run	apt-get update
-#     # Install system packages
-#     run	DEBIAN_FRONTEND=noninteractive apt-get install -y -q git
-#     run DEBIAN_FRONTEND=noninteractive apt-get install -y -q curl
-#     run DEBIAN_FRONTEND=noninteractive apt-get install -y -q golang
-#     # Insert files from the host (./myscript must be present in the current directory)
-#     copy	myscript /usr/local/bin/myscript
-# 
-# 
-# Run docker-build, and pass the contents of your Changefile as standard input.
-# 
-#     $ IMG=$(./docker-build < Changefile)
-# 
-# This will take a while: for each line of the changefile, docker-build will:
-# 
-# 1. Create a new container to execute the given command or insert the given file
-# 2. Wait for the container to complete execution
-# 3. Commit the resulting changes as a new image
-# 4. Use the resulting image as the input of the next step
-
-
-import sys
-import subprocess
-import json
-import hashlib
-
-def docker(args, stdin=None):
-	print "# docker " + " ".join(args)
-	p = subprocess.Popen(["docker"] + list(args), stdin=stdin, stdout=subprocess.PIPE)
-	return p.stdout
-
-def image_exists(img):
-	return docker(["inspect", img]).read().strip() != ""
-
-def image_config(img):
-	return json.loads(docker(["inspect", img]).read()).get("config", {})
-
-def run_and_commit(img_in, cmd, stdin=None, author=None, run=None):
-	run_id = docker(["run"] + (["-i", "-a", "stdin"] if stdin else ["-d"]) + [img_in, "/bin/sh", "-c", cmd], stdin=stdin).read().rstrip()
-	print "---> Waiting for " + run_id
-	result=int(docker(["wait", run_id]).read().rstrip())
-	if result != 0:
-		print "!!! '{}' return non-zero exit code '{}'. Aborting.".format(cmd, result)
-		sys.exit(1)
-	return docker(["commit"] + (["-author", author] if author else []) + (["-run", json.dumps(run)] if run is not None else []) + [run_id]).read().rstrip()
-
-def insert(base, src, dst, author=None):
-	print "COPY {} to {} in {}".format(src, dst, base)
-	if dst == "":
-		raise Exception("Missing destination path")
-	stdin = file(src)
-	stdin.seek(0)
-	return run_and_commit(base, "cat > {0}; chmod +x {0}".format(dst), stdin=stdin, author=author)
-
-def add(base, src, dst, author=None):
-	print "PUSH to {} in {}".format(dst, base)
-	if src == ".":
-		tar = subprocess.Popen(["tar", "-c", "."], stdout=subprocess.PIPE).stdout
-	else:
-		tar = subprocess.Popen(["curl", src], stdout=subprocess.PIPE).stdout
-	if dst == "":
-		raise Exception("Missing argument to push")
-	return run_and_commit(base, "mkdir -p '{0}' && tar -C '{0}' -x".format(dst), stdin=tar, author=author)
-
-def main():
-	base=""
-	maintainer=""
-	steps = []
-	try:
-		for line in sys.stdin.readlines():
-			line = line.strip()
-			# Skip comments and empty lines
-			if line == "" or line[0] == "#":
-				continue
-			op, param = line.split(None, 1)
-			print op.upper() + " " + param
-			if op == "from":
-				base = param
-				steps.append(base)
-			elif op == "maintainer":
-				maintainer = param
-			elif op == "run":
-				result = run_and_commit(base, param, author=maintainer)
-				steps.append(result)
-				base = result
-				print "===> " + base
-			elif op == "copy":
-				src, dst = param.split("	", 1)
-				result = insert(base, src, dst, author=maintainer)
-				steps.append(result)
-				base = result
-				print "===> " + base
-			elif op == "add":
-				src, dst = param.split("	", 1)
-				result = add(base, src, dst, author=maintainer)
-				steps.append(result)
-				base=result
-				print "===> " + base
-			elif op == "expose":
-				config = image_config(base)
-				if config.get("PortSpecs") is None:
-					config["PortSpecs"] = []
-				portspec = param.strip()
-				config["PortSpecs"].append(portspec)
-				result = run_and_commit(base, "# (nop) expose port {}".format(portspec), author=maintainer, run=config)
-				steps.append(result)
-				base=result
-				print "===> " + base
-			elif op == "cmd":
-				config  = image_config(base)
-				cmd = list(json.loads(param))
-				config["Cmd"] = cmd
-				result = run_and_commit(base, "# (nop) set default command to '{}'".format(" ".join(cmd)), author=maintainer, run=config)
-				steps.append(result)
-				base=result
-				print "===> " + base
-			else:
-				print "Skipping uknown op " + op
-	except:
-		docker(["rmi"] + steps[1:])
-		raise
-	print base
-
-if __name__ == "__main__":
-	main()

+ 0 - 13
contrib/docker-build/example.changefile

@@ -1,13 +0,0 @@
-# Start build from a know base image
-maintainer	Solomon Hykes <solomon@dotcloud.com>
-from	base:ubuntu-12.10
-# Update ubuntu sources
-run	echo 'deb http://archive.ubuntu.com/ubuntu quantal main universe multiverse' > /etc/apt/sources.list
-run	apt-get update
-# Install system packages
-run	DEBIAN_FRONTEND=noninteractive apt-get install -y -q git
-run	DEBIAN_FRONTEND=noninteractive apt-get install -y -q curl
-run	DEBIAN_FRONTEND=noninteractive apt-get install -y -q golang
-# Insert files from the host (./myscript must be present in the current directory)
-copy	myscript	/usr/local/bin/myscript
-push	/src

+ 0 - 3
contrib/docker-build/myscript

@@ -1,3 +0,0 @@
-#!/bin/sh
-
-echo hello, world!

+ 2 - 2
docker/docker.go

@@ -15,7 +15,7 @@ import (
 )
 )
 
 
 var (
 var (
-	GIT_COMMIT string
+	GITCOMMIT string
 )
 )
 
 
 func main() {
 func main() {
@@ -59,7 +59,7 @@ func main() {
 	if *flDebug {
 	if *flDebug {
 		os.Setenv("DEBUG", "1")
 		os.Setenv("DEBUG", "1")
 	}
 	}
-	docker.GIT_COMMIT = GIT_COMMIT
+	docker.GITCOMMIT = GITCOMMIT
 	if *flDaemon {
 	if *flDaemon {
 		if flag.NArg() != 0 {
 		if flag.NArg() != 0 {
 			flag.Usage()
 			flag.Usage()

+ 1 - 1
docs/Makefile

@@ -63,7 +63,7 @@ site:
 connect:
 connect:
 	@echo connecting dotcloud to www.docker.io website, make sure to use user 1
 	@echo connecting dotcloud to www.docker.io website, make sure to use user 1
 	@cd _build/website/ ; \
 	@cd _build/website/ ; \
-	dotcloud connect dockerwebsite ;
+	dotcloud connect dockerwebsite ; \
 	dotcloud list
 	dotcloud list
 
 
 push:
 push:

+ 10 - 9
docs/sources/api/docker_remote_api.rst

@@ -564,7 +564,7 @@ Create an image
 	   Content-Type: application/json
 	   Content-Type: application/json
 
 
 	   {"status":"Pulling..."}
 	   {"status":"Pulling..."}
-	   {"progress":"1/? (n/a)"}
+	   {"status":"Pulling", "progress":"1/? (n/a)"}
 	   {"error":"Invalid..."}
 	   {"error":"Invalid..."}
 	   ...
 	   ...
 
 
@@ -607,7 +607,7 @@ Insert a file in a image
 	   Content-Type: application/json
 	   Content-Type: application/json
 
 
 	   {"status":"Inserting..."}
 	   {"status":"Inserting..."}
-	   {"progress":"1/? (n/a)"}
+	   {"status":"Inserting", "progress":"1/? (n/a)"}
 	   {"error":"Invalid..."}
 	   {"error":"Invalid..."}
 	   ...
 	   ...
 
 
@@ -734,7 +734,7 @@ Push an image on the registry
 	   Content-Type: application/json
 	   Content-Type: application/json
 
 
 	   {"status":"Pushing..."}
 	   {"status":"Pushing..."}
-	   {"progress":"1/? (n/a)"}
+	   {"status":"Pushing", "progress":"1/? (n/a)"}
 	   {"error":"Invalid..."}
 	   {"error":"Invalid..."}
 	   ...
 	   ...
 
 
@@ -974,10 +974,12 @@ Display system-wide information
 
 
 	   {
 	   {
 		"Containers":11,
 		"Containers":11,
-		"Version":"0.2.2",
 		"Images":16,
 		"Images":16,
-		"GoVersion":"go1.0.3",
-		"Debug":false
+		"Debug":false,
+		"NFd": 11,
+		"NGoroutines":21,
+		"MemoryLimit":true,
+		"SwapLimit":false
 	   }
 	   }
 
 
         :statuscode 200: no error
         :statuscode 200: no error
@@ -1003,12 +1005,11 @@ Show the docker version information
 
 
            HTTP/1.1 200 OK
            HTTP/1.1 200 OK
 	   Content-Type: application/json
 	   Content-Type: application/json
-	   
+
 	   {
 	   {
 		"Version":"0.2.2",
 		"Version":"0.2.2",
 		"GitCommit":"5a2a5cc+CHANGES",
 		"GitCommit":"5a2a5cc+CHANGES",
-		"MemoryLimit":true,
-		"SwapLimit":false
+		"GoVersion":"go1.0.3"
 	   }
 	   }
 
 
         :statuscode 200: no error
         :statuscode 200: no error

+ 1 - 1
docs/sources/contributing/contributing.rst

@@ -5,5 +5,5 @@
 Contributing to Docker
 Contributing to Docker
 ======================
 ======================
 
 
-Want to hack on Docker? Awesome! The repository includes `all the instructions you need to get started <https://github.com/dotcloud/docker/blob/master/CONTRIBUTING.md>`.
+Want to hack on Docker? Awesome! The repository includes `all the instructions you need to get started <https://github.com/dotcloud/docker/blob/master/CONTRIBUTING.md>`_.
 
 

+ 26 - 2
docs/sources/contributing/devenvironment.rst

@@ -5,11 +5,35 @@
 Setting Up a Dev Environment
 Setting Up a Dev Environment
 ============================
 ============================
 
 
-Instructions that have been verified to work on Ubuntu 12.10,
+Instructions that have been verified to work on Ubuntu Precise 12.04 (LTS) (64-bit),
+
+
+Dependencies
+------------
+
+**Linux kernel 3.8**
+
+Due to a bug in LXC docker works best on the 3.8 kernel. Precise comes with a 3.2 kernel, so we need to upgrade it. The kernel we install comes with AUFS built in.
+
 
 
 .. code-block:: bash
 .. code-block:: bash
 
 
-    sudo apt-get -y install lxc wget bsdtar curl golang git
+   # install the backported kernel
+   sudo apt-get update && sudo apt-get install linux-image-generic-lts-raring
+
+   # reboot
+   sudo reboot
+
+
+Installation
+------------
+
+.. code-block:: bash
+		
+    sudo apt-get install python-software-properties
+    sudo add-apt-repository ppa:gophers/go
+    sudo apt-get update
+    sudo apt-get -y install lxc wget bsdtar curl golang-stable git
 
 
     export GOPATH=~/go/
     export GOPATH=~/go/
     export PATH=$GOPATH/bin:$PATH
     export PATH=$GOPATH/bin:$PATH

+ 7 - 5
docs/sources/faq.rst

@@ -19,7 +19,8 @@ Most frequently asked questions.
 
 
 3. **Does Docker run on Mac OS X or Windows?**
 3. **Does Docker run on Mac OS X or Windows?**
 
 
-   Not at this time, Docker currently only runs on Linux, but you can use VirtualBox to run Docker in a virtual machine on your box, and get the best of both worlds. Check out the MacOSX_ and Windows_ installation guides.
+   Not at this time, Docker currently only runs on Linux, but you can use VirtualBox to run Docker in a
+   virtual machine on your box, and get the best of both worlds. Check out the :ref:`install_using_vagrant` and :ref:`windows` installation guides.
 
 
 4. **How do containers compare to virtual machines?**
 4. **How do containers compare to virtual machines?**
 
 
@@ -34,15 +35,16 @@ Most frequently asked questions.
 
 
     You can find more answers on:
     You can find more answers on:
 
 
-    * `IRC: docker on freenode`_
+    * `Docker club mailinglist`_
+    * `IRC, docker on freenode`_
     * `Github`_
     * `Github`_
     * `Ask questions on Stackoverflow`_
     * `Ask questions on Stackoverflow`_
     * `Join the conversation on Twitter`_
     * `Join the conversation on Twitter`_
 
 
-    .. _Windows: ../installation/windows/
-    .. _MacOSX: ../installation/vagrant/
+
+    .. _Docker club mailinglist: https://groups.google.com/d/forum/docker-club
     .. _the repo: http://www.github.com/dotcloud/docker
     .. _the repo: http://www.github.com/dotcloud/docker
-    .. _IRC\: docker on freenode: irc://chat.freenode.net#docker
+    .. _IRC, docker on freenode: irc://chat.freenode.net#docker
     .. _Github: http://www.github.com/dotcloud/docker
     .. _Github: http://www.github.com/dotcloud/docker
     .. _Ask questions on Stackoverflow: http://stackoverflow.com/search?q=docker
     .. _Ask questions on Stackoverflow: http://stackoverflow.com/search?q=docker
     .. _Join the conversation on Twitter: http://twitter.com/getdocker
     .. _Join the conversation on Twitter: http://twitter.com/getdocker

+ 10 - 0
docs/sources/installation/ubuntulinux.rst

@@ -92,6 +92,16 @@ have AUFS filesystem support enabled, so we need to install it.
    sudo apt-get update
    sudo apt-get update
    sudo apt-get install linux-image-extra-`uname -r`
    sudo apt-get install linux-image-extra-`uname -r`
 
 
+**add-apt-repository support**
+
+Some installations of Ubuntu 13.04 require ``software-properties-common`` to be
+installed before being able to use add-apt-repository.
+
+.. code-block:: bash
+
+  sudo apt-get install software-properties-common
+
+
 Installation
 Installation
 ------------
 ------------
 
 

+ 1 - 0
docs/sources/installation/windows.rst

@@ -2,6 +2,7 @@
 :description: Docker's tutorial to run docker on Windows
 :description: Docker's tutorial to run docker on Windows
 :keywords: Docker, Docker documentation, Windows, requirements, virtualbox, vagrant, git, ssh, putty, cygwin
 :keywords: Docker, Docker documentation, Windows, requirements, virtualbox, vagrant, git, ssh, putty, cygwin
 
 
+.. _windows:
 
 
 Using Vagrant (Windows)
 Using Vagrant (Windows)
 =======================
 =======================

+ 1 - 1
docs/sources/use/builder.rst

@@ -18,7 +18,7 @@ steps and commit them along the way, giving you a final image.
 To use Docker Builder, assemble the steps into a text file (commonly referred to
 To use Docker Builder, assemble the steps into a text file (commonly referred to
 as a Dockerfile) and supply this to `docker build` on STDIN, like so:
 as a Dockerfile) and supply this to `docker build` on STDIN, like so:
 
 
-    ``docker build < Dockerfile``
+    ``docker build - < Dockerfile``
 
 
 Docker will run your steps one-by-one, committing the result if necessary, 
 Docker will run your steps one-by-one, committing the result if necessary, 
 before finally outputting the ID of your new image.
 before finally outputting the ID of your new image.

+ 21 - 9
docs/theme/docker/layout.html

@@ -64,14 +64,15 @@
 
 
             <div style="float: right" class="pull-right">
             <div style="float: right" class="pull-right">
                 <ul class="nav">
                 <ul class="nav">
-                    <li><a href="http://www.docker.io/">Introduction</a></li>
-                    <li><a href="http://www.docker.io/gettingstarted/">Getting started</a></li>
-                    <li class="active"><a href="http://docs.docker.io/en/latest/">Documentation</a></li>
+                    <li id="nav-introduction"><a href="http://www.docker.io/">Introduction</a></li>
+                    <li id="nav-gettingstarted"><a href="http://www.docker.io/gettingstarted/">Getting started</a></li>
+                    <li id="nav-documentation" class="active"><a href="http://docs.docker.io/en/latest/">Documentation</a></li>
+                    <li id="nav-blog"><a href="http://blog.docker.io/">Blog</a></li>
                 </ul>
                 </ul>
-                <div class="social links" style="float: right; margin-top: 14px; margin-left: 12px">
-                    <a class="twitter" href="http://twitter.com/getdocker">Twitter</a>
-                    <a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
-                </div>
+                <!--<div class="social links" style="float: right; margin-top: 14px; margin-left: 12px">-->
+                    <!--<a class="twitter" href="http://twitter.com/getdocker">Twitter</a>-->
+                    <!--<a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>-->
+                <!--</div>-->
             </div>
             </div>
 
 
             <div style="margin-left: -12px; float: left;">
             <div style="margin-left: -12px; float: left;">
@@ -86,8 +87,13 @@
 
 
 <div class="container">
 <div class="container">
     <div class="row">
     <div class="row">
-        <div class="span12 titlebar"><h1 class="pageheader">DOCUMENTATION</h1>
+        <div class="span12 titlebar">
             <!--<span class="pull-right" style="margin-left: 20px; font-size: 20px">{{version}}</span>-->
             <!--<span class="pull-right" style="margin-left: 20px; font-size: 20px">{{version}}</span>-->
+            <div class="pull-right" id="fork-us" style="margin-top: 16px; margin-right: 16px;">
+                <a  href="http://github.com/dotcloud/docker/"><img src="{{ pathto('_static/img/fork-us.png', 1) }}"> Fork us on Github</a>
+            </div>
+            <h1 class="pageheader">DOCUMENTATION</h1>
+
         </div>
         </div>
     </div>
     </div>
 
 
@@ -123,8 +129,14 @@
     <div class="row">
     <div class="row">
 
 
         <div class="span12 footer">
         <div class="span12 footer">
+            <div class="tbox textright forceleftmargin social links pull-right">
+                <a class="twitter" href="http://twitter.com/getdocker">Twitter</a>
+                <a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
+            </div>
 
 
             Docker is a project by <a href="http://www.dotcloud.com">dotCloud</a>
             Docker is a project by <a href="http://www.dotcloud.com">dotCloud</a>
+
+
 {#            {%- if show_source and has_source and sourcename %}#}
 {#            {%- if show_source and has_source and sourcename %}#}
 {#            ·#}
 {#            ·#}
 {#            <a href="{{ pathto('_sources/' + sourcename, true)|e }}"#}
 {#            <a href="{{ pathto('_sources/' + sourcename, true)|e }}"#}
@@ -157,7 +169,7 @@
   <!-- script which should be loaded after everything else -->
   <!-- script which should be loaded after everything else -->
 <script type="text/javascript">
 <script type="text/javascript">
 
 
-
+    // Function to make the sticky header possible
     var shiftWindow = function() {
     var shiftWindow = function() {
         scrollBy(0, -70);
         scrollBy(0, -70);
         console.log("window shifted")
         console.log("window shifted")

+ 40 - 1
docs/theme/docker/static/css/main.css

@@ -285,6 +285,40 @@ section.header {
 .social .github {
 .social .github {
   background-position: -59px 2px;
   background-position: -59px 2px;
 }
 }
+#fork-us {
+  /*font-family: 'Maven Pro';*/
+
+  /*font-weight: bold;*/
+
+  font-size: 12px;
+  /*text-transform: uppercase;*/
+
+  display: block;
+  padding: 0px 1em;
+  height: 28px;
+  line-height: 28px;
+  background-color: #43484c;
+  filter: progid:dximagetransform.microsoft.gradient(gradientType=0, startColorstr='#FFFF6E56', endColorstr='#FFED4F35');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #747474), color-stop(100%, #43484c));
+  background-image: -webkit-linear-gradient(top, #747474 0%, #43484c 100%);
+  background-image: -moz-linear-gradient(top, #747474 0%, #43484c 100%);
+  background-image: -o-linear-gradient(top, #747474 0%, #43484c 100%);
+  background-image: linear-gradient(top, #747474 0%, #43484c 100%);
+  border: 1px solid #43484c;
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  -ms-border-radius: 4px;
+  -o-border-radius: 4px;
+  border-radius: 4px;
+  -webkit-box-shadow: inset rgba(255, 255, 255, 0.17) 0 1px 1px;
+  -moz-box-shadow: inset rgba(255, 255, 255, 0.17) 0 1px 1px;
+  box-shadow: inset rgba(255, 255, 255, 0.17) 0 1px 1px;
+  margin: 8px;
+}
+#fork-us a {
+  color: #faf2ee;
+  text-shadow: rgba(0, 0, 0, 0.3) 0px 1px 0px;
+}
 /* =======================
 /* =======================
    Media size overrides
    Media size overrides
 ======================= */
 ======================= */
@@ -325,10 +359,15 @@ section.header {
   
   
     padding-top: 600px;
     padding-top: 600px;
   }
   }
+  #fork-us {
+    display: none;
+  }
 }
 }
 /* Landscape phones and down */
 /* Landscape phones and down */
 @media (max-width: 480px) {
 @media (max-width: 480px) {
-  
+  #nav-gettingstarted {
+    display: none;
+  }
 }
 }
 /* Misc fixes */
 /* Misc fixes */
 table th {
 table th {

+ 38 - 3
docs/theme/docker/static/css/main.less

@@ -391,6 +391,38 @@ section.header {
 }
 }
 
 
 
 
+#fork-us {
+  /*font-family: 'Maven Pro';*/
+  /*font-weight: bold;*/
+  font-size: 12px;
+  /*text-transform: uppercase;*/
+  display: block;
+  padding: 0px 1em;
+  height: 28px;
+  line-height: 28px;
+  background-color: #43484c;
+  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FFFF6E56', endColorstr='#FFED4F35');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #747474), color-stop(100%, #43484c));
+  background-image: -webkit-linear-gradient(top, #747474 0%, #43484c 100%);
+  background-image: -moz-linear-gradient(top, #747474 0%, #43484c 100%);
+  background-image: -o-linear-gradient(top, #747474 0%, #43484c 100%);
+  background-image: linear-gradient(top, #747474 0%, #43484c 100%);
+  border: 1px solid #43484c;
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  -ms-border-radius: 4px;
+  -o-border-radius: 4px;
+  border-radius: 4px;
+  -webkit-box-shadow: inset rgba(255, 255, 255, 0.17) 0 1px 1px;
+  -moz-box-shadow: inset rgba(255, 255, 255, 0.17) 0 1px 1px;
+  box-shadow: inset rgba(255, 255, 255, 0.17) 0 1px 1px;
+  margin: 8px;
+
+  a {
+    color: #faf2ee;
+    text-shadow: rgba(0, 0, 0, 0.3) 0px 1px 0px;
+  }
+}
 /* =======================
 /* =======================
    Media size overrides
    Media size overrides
 ======================= */
 ======================= */
@@ -441,14 +473,17 @@ section.header {
   /* TODO: Fix this to be relative to the navigation size */
   /* TODO: Fix this to be relative to the navigation size */
     padding-top: 600px;
     padding-top: 600px;
   }
   }
-
+  #fork-us {
+    display: none;
+  }
 }
 }
 
 
 
 
 /* Landscape phones and down */
 /* Landscape phones and down */
 @media (max-width: 480px) {
 @media (max-width: 480px) {
-
-
+  #nav-gettingstarted {
+    display: none;
+  }
 }
 }
 
 
 /* Misc fixes */
 /* Misc fixes */

+ 25 - 18
docs/website/gettingstarted/index.html

@@ -34,15 +34,11 @@
 
 
             <div style="float: right" class="pull-right">
             <div style="float: right" class="pull-right">
                 <ul class="nav">
                 <ul class="nav">
-                    <li><a href="../">Introduction</a></li>
-                    <li class="active"><a href="">Getting started</a></li>
-                    <li class=""><a href="http://docs.docker.io/en/latest/">Documentation</a></li>
+                    <li id="nav-introduction"><a href="../">Introduction</a></li>
+                    <li id="nav-gettingstarted" class="active"><a href="">Getting started</a></li>
+                    <li id="nav-documentation" class=""><a href="http://docs.docker.io/en/latest/">Documentation</a></li>
+                    <li id="nav-blog"><a href="http://blog.docker.io/">Blog</a></li>
                 </ul>
                 </ul>
-
-                <div class="social links" style="float: right; margin-top: 14px; margin-left: 12px">
-                    <a class="twitter" href="http://twitter.com/getdocker">Twitter</a>
-                    <a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
-                </div>
             </div>
             </div>
 
 
             <div style="margin-left: -12px; float: left;">
             <div style="margin-left: -12px; float: left;">
@@ -55,14 +51,22 @@
 
 
 <div class="container">
 <div class="container">
     <div class="row">
     <div class="row">
-        <div class="span12 titlebar"><h1 class="pageheader">GETTING STARTED</h1>
+
+        <div class="span12 titlebar">
+
+            <div class="pull-right" id="fork-us" style="margin-top: 16px; margin-right: 16px;">
+                <a  href="http://github.com/dotcloud/docker/"><img src="../static/img/fork-us.png"> Fork us on Github</a>
+            </div>
+
+            <h1 class="pageheader"> GETTING STARTED</h1>
         </div>
         </div>
+
     </div>
     </div>
 
 
 </div>
 </div>
 
 
 <div class="container">
 <div class="container">
-    <div class="alert alert-info">
+    <div class="alert alert-info" style="margin-bottom: 0;">
         <strong>Docker is still under heavy development.</strong> It should not yet be used in production. Check <a href="http://github.com/dotcloud/docker">the repo</a> for recent progress.
         <strong>Docker is still under heavy development.</strong> It should not yet be used in production. Check <a href="http://github.com/dotcloud/docker">the repo</a> for recent progress.
     </div>
     </div>
     <div class="row">
     <div class="row">
@@ -133,13 +137,13 @@
             </section>
             </section>
 
 
             <section class="contentblock">
             <section class="contentblock">
-                <h2>More resources</h2>
-                <ul>
-                    <li><a href="irc://chat.freenode.net#docker">IRC: docker on freenode</a></li>
-                    <li><a href="http://www.github.com/dotcloud/docker">Github</a></li>
-                    <li><a href="http://stackoverflow.com/tags/docker/">Ask questions on Stackoverflow</a></li>
-                    <li><a href="http://twitter.com/getdocker/">Join the conversation on Twitter</a></li>
-                </ul>
+                <h2>Questions? Want to get in touch?</h2>
+                <p>There are several ways to get in touch:</p>
+                <p><strong>Join the discussion on IRC.</strong> We can be found in the <a href="irc://chat.freenode.net#docker">#docker</a> channel on chat.freenode.net</p>
+                <p><strong>Discussions</strong> happen on our google group: <a href="https://groups.google.com/d/forum/docker-club">docker-club at googlegroups.com</a></p>
+                <p>All our <strong>development and decisions</strong> are made out in the open on Github <a href="http://www.github.com/dotcloud/docker">github.com/dotcloud/docker</a></p>
+                <p><strong>Get help on using Docker</strong> by asking on <a href="http://stackoverflow.com/tags/docker/">Stackoverflow</a></p>
+                <p>And of course, <strong>tweet</strong> your tweets to <a href="http://twitter.com/getdocker/">twitter.com/getdocker</a></p>
             </section>
             </section>
 
 
 
 
@@ -172,7 +176,10 @@
     <footer id="footer" class="footer">
     <footer id="footer" class="footer">
         <div class="row">
         <div class="row">
             <div class="span12 social">
             <div class="span12 social">
-
+                <div class="tbox textright forceleftmargin social links pull-right">
+                    <a class="twitter" href="http://twitter.com/getdocker">Twitter</a>
+                    <a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
+                </div>
                 Docker is a project by <a href="http://www.dotcloud.com">dotCloud</a>
                 Docker is a project by <a href="http://www.dotcloud.com">dotCloud</a>
 
 
             </div>
             </div>

+ 29 - 29
docs/website/index.html

@@ -44,9 +44,18 @@
         .debug {
         .debug {
             border: 1px red dotted;
             border: 1px red dotted;
         }
         }
+        .twitterblock {
+            min-height: 75px;
+        }
+
+        .twitterblock img {
+            float: left;
+            margin-right: 10px;
+        }
 
 
     </style>
     </style>
 
 
+
 </head>
 </head>
 
 
 
 
@@ -56,17 +65,18 @@
     <div class="navbar-dotcloud">
     <div class="navbar-dotcloud">
         <div class="container" style="text-align: center;">
         <div class="container" style="text-align: center;">
 
 
+
+            <div class="pull-left" id="fork-us" style="margin-top: 16px;">
+                <a  href="http://github.com/dotcloud/docker/"><img src="static/img/fork-us.png" alt="fork-icon"> Fork us on Github</a>
+            </div>
+
             <div class="pull-right" >
             <div class="pull-right" >
                 <ul class="nav">
                 <ul class="nav">
-                    <li class="active"><a href="/">Introduction</a></li>
-                    <li ><a href="gettingstarted">Getting started</a></li>
-                    <li class=""><a href="http://docs.docker.io/en/latest/">Documentation</a></li>
+                    <li id="nav-introduction" class="active"><a href="/">Introduction</a></li>
+                    <li id="nav-gettingstarted"><a href="gettingstarted">Getting started</a></li>
+                    <li id="nav-documentation" class=""><a href="http://docs.docker.io/en/latest/">Documentation</a></li>
+                    <li id="nav-blog"><a href="http://blog.docker.io/">Blog</a></li>
                 </ul>
                 </ul>
-
-                <div class="social links" style="float: right; margin-top: 14px; margin-left: 12px">
-                    <a class="twitter" href="http://twitter.com/getdocker">Twitter</a>
-                    <a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
-                </div>
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>
@@ -81,7 +91,7 @@
 
 
                 <div class="span5" style="margin-bottom: 15px;">
                 <div class="span5" style="margin-bottom: 15px;">
                     <div style="text-align: center;" >
                     <div style="text-align: center;" >
-                        <img src="static/img/docker_letters_500px.png">
+                        <img src="static/img/docker_letters_500px.png" alt="docker letters">
 
 
                         <h2>The Linux container engine</h2>
                         <h2>The Linux container engine</h2>
                     </div>
                     </div>
@@ -130,7 +140,7 @@
             <section class="contentblock">
             <section class="contentblock">
                 <div class="container">
                 <div class="container">
                 <div class="span2" style="margin-left: 0" >
                 <div class="span2" style="margin-left: 0" >
-                    <a href="http://dotcloud.theresumator.com/apply/mWjkD4/Software-Engineer.html" title="Job description"><img src="static/img/hiring_graphic.png" width="140px" style="margin-top: 25px"></a>
+                    <a href="http://dotcloud.theresumator.com/apply/mWjkD4/Software-Engineer.html" title="Job description"><img src="static/img/hiring_graphic.png" alt="we're hiring" width="140" style="margin-top: 25px"></a>
                 </div>
                 </div>
                 <div class="span4" style="margin-left: 0">
                 <div class="span4" style="margin-left: 0">
                     <h4>Do you think it is cool to hack on docker? Join us!</h4>
                     <h4>Do you think it is cool to hack on docker? Join us!</h4>
@@ -156,7 +166,7 @@
                     </div>
                     </div>
                 </a>
                 </a>
                 &nbsp;
                 &nbsp;
-                <input type="button" class="searchbutton" type="submit" value="Search images"
+                <input type="button" class="searchbutton" value="Search images"
                        onClick="window.open('https://index.docker.io')" />
                        onClick="window.open('https://index.docker.io')" />
 
 
             </section>
             </section>
@@ -184,32 +194,19 @@
 
 
 </div>
 </div>
 
 
-<style>
-    .twitterblock {
-        min-height: 75px;
-    }
-
-    .twitterblock img {
-        float: left;
-        margin-right: 10px;
-    }
-
-</style>
-
-
 <div class="container">
 <div class="container">
 
 
     <div class="row">
     <div class="row">
         <div class="span6">
         <div class="span6">
             <section class="contentblock twitterblock">
             <section class="contentblock twitterblock">
                 <img src="https://si0.twimg.com/profile_images/2707460527/252a64411a339184ff375a96fb68dcb0_bigger.png">
                 <img src="https://si0.twimg.com/profile_images/2707460527/252a64411a339184ff375a96fb68dcb0_bigger.png">
-                <em>Mitchell Hashimoto‏@mitchellh:</em> Docker launched today. It is incredible. They’re also working RIGHT NOW on a Vagrant provider. LXC is COMING!!
+                <em>Mitchell Hashimoto ‏@mitchellh:</em> Docker launched today. It is incredible. They’re also working RIGHT NOW on a Vagrant provider. LXC is COMING!!
             </section>
             </section>
         </div>
         </div>
         <div class="span6">
         <div class="span6">
             <section class="contentblock twitterblock">
             <section class="contentblock twitterblock">
                 <img src="https://si0.twimg.com/profile_images/1108290260/Adam_Jacob-114x150_original_bigger.jpg">
                 <img src="https://si0.twimg.com/profile_images/1108290260/Adam_Jacob-114x150_original_bigger.jpg">
-                <em>Adam Jacob‏@adamhjk:</em> Docker is clearly the right idea. @solomonstre absolutely killed it. Containerized app deployment is the future, I think.
+                <em>Adam Jacob ‏@adamhjk:</em> Docker is clearly the right idea. @solomonstre absolutely killed it. Containerized app deployment is the future, I think.
             </section>
             </section>
         </div>
         </div>
     </div>
     </div>
@@ -217,13 +214,13 @@
         <div class="span6">
         <div class="span6">
             <section class="contentblock twitterblock">
             <section class="contentblock twitterblock">
                 <img src="https://si0.twimg.com/profile_images/14872832/twitter_pic_bigger.jpg">
                 <img src="https://si0.twimg.com/profile_images/14872832/twitter_pic_bigger.jpg">
-                <em>Matt Townsend‏@mtownsend:</em> I have a serious code crush on docker.io - it's Lego for PaaS. Motherfucking awesome Lego.
+                <em>Matt Townsend ‏@mtownsend:</em> I have a serious code crush on docker.io - it's Lego for PaaS. Motherfucking awesome Lego.
             </section>
             </section>
         </div>
         </div>
         <div class="span6">
         <div class="span6">
             <section class="contentblock twitterblock">
             <section class="contentblock twitterblock">
                 <img src="https://si0.twimg.com/profile_images/1312352395/rupert-259x300_bigger.jpg">
                 <img src="https://si0.twimg.com/profile_images/1312352395/rupert-259x300_bigger.jpg">
-                <em>Rob Harrop‏@robertharrop:</em> Impressed by @getdocker - it's all kinds of magic. Serious rethink of AWS architecture happening @skillsmatter.
+                <em>Rob Harrop ‏@robertharrop:</em> Impressed by @getdocker - it's all kinds of magic. Serious rethink of AWS architecture happening @skillsmatter.
             </section>
             </section>
         </div>
         </div>
     </div>
     </div>
@@ -317,7 +314,10 @@
     <footer id="footer" class="footer">
     <footer id="footer" class="footer">
         <div class="row">
         <div class="row">
             <div class="span12">
             <div class="span12">
-
+                <div class="tbox textright forceleftmargin social links pull-right">
+                    <a class="twitter" href="http://twitter.com/getdocker">Twitter</a>
+                    <a class="github" href="https://github.com/dotcloud/docker/">GitHub</a>
+                </div>
                 Docker is a project by <a href="http://www.dotcloud.com">dotCloud</a>
                 Docker is a project by <a href="http://www.dotcloud.com">dotCloud</a>
 
 
             </div>
             </div>

+ 21 - 21
graph.go

@@ -86,14 +86,14 @@ func (graph *Graph) Get(name string) (*Image, error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	if img.Id != id {
-		return nil, fmt.Errorf("Image stored at '%s' has wrong id '%s'", id, img.Id)
+	if img.ID != id {
+		return nil, fmt.Errorf("Image stored at '%s' has wrong id '%s'", id, img.ID)
 	}
 	}
 	img.graph = graph
 	img.graph = graph
 	graph.lockSumMap.Lock()
 	graph.lockSumMap.Lock()
 	defer graph.lockSumMap.Unlock()
 	defer graph.lockSumMap.Unlock()
-	if _, exists := graph.checksumLock[img.Id]; !exists {
-		graph.checksumLock[img.Id] = &sync.Mutex{}
+	if _, exists := graph.checksumLock[img.ID]; !exists {
+		graph.checksumLock[img.ID] = &sync.Mutex{}
 	}
 	}
 	return img, nil
 	return img, nil
 }
 }
@@ -101,7 +101,7 @@ func (graph *Graph) Get(name string) (*Image, error) {
 // Create creates a new image and registers it in the graph.
 // Create creates a new image and registers it in the graph.
 func (graph *Graph) Create(layerData Archive, container *Container, comment, author string, config *Config) (*Image, error) {
 func (graph *Graph) Create(layerData Archive, container *Container, comment, author string, config *Config) (*Image, error) {
 	img := &Image{
 	img := &Image{
-		Id:            GenerateId(),
+		ID:            GenerateID(),
 		Comment:       comment,
 		Comment:       comment,
 		Created:       time.Now(),
 		Created:       time.Now(),
 		DockerVersion: VERSION,
 		DockerVersion: VERSION,
@@ -111,7 +111,7 @@ func (graph *Graph) Create(layerData Archive, container *Container, comment, aut
 	}
 	}
 	if container != nil {
 	if container != nil {
 		img.Parent = container.Image
 		img.Parent = container.Image
-		img.Container = container.Id
+		img.Container = container.ID
 		img.ContainerConfig = *container.Config
 		img.ContainerConfig = *container.Config
 	}
 	}
 	if err := graph.Register(layerData, layerData != nil, img); err != nil {
 	if err := graph.Register(layerData, layerData != nil, img); err != nil {
@@ -124,12 +124,12 @@ func (graph *Graph) Create(layerData Archive, container *Container, comment, aut
 // Register imports a pre-existing image into the graph.
 // Register imports a pre-existing image into the graph.
 // FIXME: pass img as first argument
 // FIXME: pass img as first argument
 func (graph *Graph) Register(layerData Archive, store bool, img *Image) error {
 func (graph *Graph) Register(layerData Archive, store bool, img *Image) error {
-	if err := ValidateId(img.Id); err != nil {
+	if err := ValidateID(img.ID); err != nil {
 		return err
 		return err
 	}
 	}
 	// (This is a convenience to save time. Race conditions are taken care of by os.Rename)
 	// (This is a convenience to save time. Race conditions are taken care of by os.Rename)
-	if graph.Exists(img.Id) {
-		return fmt.Errorf("Image %s already exists", img.Id)
+	if graph.Exists(img.ID) {
+		return fmt.Errorf("Image %s already exists", img.ID)
 	}
 	}
 	tmp, err := graph.Mktemp("")
 	tmp, err := graph.Mktemp("")
 	defer os.RemoveAll(tmp)
 	defer os.RemoveAll(tmp)
@@ -140,12 +140,12 @@ func (graph *Graph) Register(layerData Archive, store bool, img *Image) error {
 		return err
 		return err
 	}
 	}
 	// Commit
 	// Commit
-	if err := os.Rename(tmp, graph.imageRoot(img.Id)); err != nil {
+	if err := os.Rename(tmp, graph.imageRoot(img.ID)); err != nil {
 		return err
 		return err
 	}
 	}
 	img.graph = graph
 	img.graph = graph
-	graph.idIndex.Add(img.Id)
-	graph.checksumLock[img.Id] = &sync.Mutex{}
+	graph.idIndex.Add(img.ID)
+	graph.checksumLock[img.ID] = &sync.Mutex{}
 	return nil
 	return nil
 }
 }
 
 
@@ -173,7 +173,7 @@ func (graph *Graph) TempLayerArchive(id string, compression Compression, output
 // Mktemp creates a temporary sub-directory inside the graph's filesystem.
 // Mktemp creates a temporary sub-directory inside the graph's filesystem.
 func (graph *Graph) Mktemp(id string) (string, error) {
 func (graph *Graph) Mktemp(id string) (string, error) {
 	if id == "" {
 	if id == "" {
-		id = GenerateId()
+		id = GenerateID()
 	}
 	}
 	tmp, err := graph.tmp()
 	tmp, err := graph.tmp()
 	if err != nil {
 	if err != nil {
@@ -230,7 +230,7 @@ func (graph *Graph) Map() (map[string]*Image, error) {
 	}
 	}
 	images := make(map[string]*Image, len(all))
 	images := make(map[string]*Image, len(all))
 	for _, image := range all {
 	for _, image := range all {
-		images[image.Id] = image
+		images[image.ID] = image
 	}
 	}
 	return images, nil
 	return images, nil
 }
 }
@@ -273,10 +273,10 @@ func (graph *Graph) ByParent() (map[string][]*Image, error) {
 		if err != nil {
 		if err != nil {
 			return
 			return
 		}
 		}
-		if children, exists := byParent[parent.Id]; exists {
-			byParent[parent.Id] = []*Image{image}
+		if children, exists := byParent[parent.ID]; exists {
+			byParent[parent.ID] = []*Image{image}
 		} else {
 		} else {
-			byParent[parent.Id] = append(children, image)
+			byParent[parent.ID] = append(children, image)
 		}
 		}
 	})
 	})
 	return byParent, err
 	return byParent, err
@@ -293,8 +293,8 @@ func (graph *Graph) Heads() (map[string]*Image, error) {
 	err = graph.WalkAll(func(image *Image) {
 	err = graph.WalkAll(func(image *Image) {
 		// If it's not in the byParent lookup table, then
 		// If it's not in the byParent lookup table, then
 		// it's not a parent -> so it's a head!
 		// it's not a parent -> so it's a head!
-		if _, exists := byParent[image.Id]; !exists {
-			heads[image.Id] = image
+		if _, exists := byParent[image.ID]; !exists {
+			heads[image.ID] = image
 		}
 		}
 	})
 	})
 	return heads, err
 	return heads, err
@@ -317,11 +317,11 @@ func (graph *Graph) getStoredChecksums() (map[string]string, error) {
 }
 }
 
 
 func (graph *Graph) storeChecksums(checksums map[string]string) error {
 func (graph *Graph) storeChecksums(checksums map[string]string) error {
-	checksumJson, err := json.Marshal(checksums)
+	checksumJSON, err := json.Marshal(checksums)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	if err := ioutil.WriteFile(path.Join(graph.Root, "checksums"), checksumJson, 0600); err != nil {
+	if err := ioutil.WriteFile(path.Join(graph.Root, "checksums"), checksumJSON, 0600); err != nil {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil

+ 11 - 11
graph_test.go

@@ -34,14 +34,14 @@ func TestInterruptedRegister(t *testing.T) {
 	defer os.RemoveAll(graph.Root)
 	defer os.RemoveAll(graph.Root)
 	badArchive, w := io.Pipe() // Use a pipe reader as a fake archive which never yields data
 	badArchive, w := io.Pipe() // Use a pipe reader as a fake archive which never yields data
 	image := &Image{
 	image := &Image{
-		Id:      GenerateId(),
+		ID:      GenerateID(),
 		Comment: "testing",
 		Comment: "testing",
 		Created: time.Now(),
 		Created: time.Now(),
 	}
 	}
 	go graph.Register(badArchive, false, image)
 	go graph.Register(badArchive, false, image)
 	time.Sleep(200 * time.Millisecond)
 	time.Sleep(200 * time.Millisecond)
 	w.CloseWithError(errors.New("But I'm not a tarball!")) // (Nobody's perfect, darling)
 	w.CloseWithError(errors.New("But I'm not a tarball!")) // (Nobody's perfect, darling)
-	if _, err := graph.Get(image.Id); err == nil {
+	if _, err := graph.Get(image.ID); err == nil {
 		t.Fatal("Image should not exist after Register is interrupted")
 		t.Fatal("Image should not exist after Register is interrupted")
 	}
 	}
 	// Registering the same image again should succeed if the first register was interrupted
 	// Registering the same image again should succeed if the first register was interrupted
@@ -67,7 +67,7 @@ func TestGraphCreate(t *testing.T) {
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	if err := ValidateId(image.Id); err != nil {
+	if err := ValidateID(image.ID); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	if image.Comment != "Testing" {
 	if image.Comment != "Testing" {
@@ -91,7 +91,7 @@ func TestRegister(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	image := &Image{
 	image := &Image{
-		Id:      GenerateId(),
+		ID:      GenerateID(),
 		Comment: "testing",
 		Comment: "testing",
 		Created: time.Now(),
 		Created: time.Now(),
 	}
 	}
@@ -104,11 +104,11 @@ func TestRegister(t *testing.T) {
 	} else if l := len(images); l != 1 {
 	} else if l := len(images); l != 1 {
 		t.Fatalf("Wrong number of images. Should be %d, not %d", 1, l)
 		t.Fatalf("Wrong number of images. Should be %d, not %d", 1, l)
 	}
 	}
-	if resultImg, err := graph.Get(image.Id); err != nil {
+	if resultImg, err := graph.Get(image.ID); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	} else {
 	} else {
-		if resultImg.Id != image.Id {
-			t.Fatalf("Wrong image ID. Should be '%s', not '%s'", image.Id, resultImg.Id)
+		if resultImg.ID != image.ID {
+			t.Fatalf("Wrong image ID. Should be '%s', not '%s'", image.ID, resultImg.ID)
 		}
 		}
 		if resultImg.Comment != image.Comment {
 		if resultImg.Comment != image.Comment {
 			t.Fatalf("Wrong image comment. Should be '%s', not '%s'", image.Comment, resultImg.Comment)
 			t.Fatalf("Wrong image comment. Should be '%s', not '%s'", image.Comment, resultImg.Comment)
@@ -156,7 +156,7 @@ func TestDeletePrefix(t *testing.T) {
 	graph := tempGraph(t)
 	graph := tempGraph(t)
 	defer os.RemoveAll(graph.Root)
 	defer os.RemoveAll(graph.Root)
 	img := createTestImage(graph, t)
 	img := createTestImage(graph, t)
-	if err := graph.Delete(utils.TruncateId(img.Id)); err != nil {
+	if err := graph.Delete(utils.TruncateID(img.ID)); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	assertNImages(graph, t, 0)
 	assertNImages(graph, t, 0)
@@ -187,7 +187,7 @@ func TestDelete(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	assertNImages(graph, t, 1)
 	assertNImages(graph, t, 1)
-	if err := graph.Delete(img.Id); err != nil {
+	if err := graph.Delete(img.ID); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	assertNImages(graph, t, 0)
 	assertNImages(graph, t, 0)
@@ -201,7 +201,7 @@ func TestDelete(t *testing.T) {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	assertNImages(graph, t, 2)
 	assertNImages(graph, t, 2)
-	if err := graph.Delete(img1.Id); err != nil {
+	if err := graph.Delete(img1.ID); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	assertNImages(graph, t, 1)
 	assertNImages(graph, t, 1)
@@ -216,7 +216,7 @@ func TestDelete(t *testing.T) {
 	if err := graph.Register(archive, false, img1); err != nil {
 	if err := graph.Register(archive, false, img1); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	if err := graph.Delete(img1.Id); err != nil {
+	if err := graph.Delete(img1.ID); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 	assertNImages(graph, t, 1)
 	assertNImages(graph, t, 1)

+ 15 - 0
hack/PRINCIPLES.md

@@ -0,0 +1,15 @@
+# Docker principles
+
+In the design and development of Docker we try to follow these principles:
+
+(Work in progress)
+
+* Don't try to replace every tool. Instead, be an ingredient to improve them.
+* When hesitating between 2 options, choose the one that is easier to reverse.
+* No is temporary, Yes is forever. If you're not sure about a new feature, say no. You can change your mind later.
+* Containers must be portable to the greatest possible number of machines. Be suspicious of any change which makes machines less interchangeable.
+* The less moving parts in a container, the better.
+* Don't merge it unless you document it.
+* Don't document it unless you can keep it up-to-date.
+* Don't merge it unless you test it!
+* Everyone's problem is slightly different. Focus on the part that is the same for everyone, and solve that.

+ 88 - 0
hack/ROADMAP.md

@@ -0,0 +1,88 @@
+# Docker: what's next?
+
+This document is a high-level overview of where we want to take Docker next.
+It is a curated selection of planned improvements which are either important, difficult, or both.
+
+For a more complete view of planned and requested improvements, see [the Github issues](https://github.com/dotcloud/docker/issues).
+
+Tu suggest changes to the roadmap, including additions, please write the change as if it were already in effect, and make a pull request.
+
+Broader kernel support
+----------------------
+
+Our goal is to make Docker run everywhere, but currently Docker requires [Linux version 3.8 or higher with lxc and aufs support](http://docs.docker.io/en/latest/installation/kernel.html). If you're deploying new machines for the purpose of running Docker, this is a fairly easy requirement to meet.
+However, if you're adding Docker to an existing deployment, you may not have the flexibility to update and patch the kernel.
+
+Expanding Docker's kernel support is a priority. This includes running on older kernel versions,
+but also on kernels with no AUFS support, or with incomplete lxc capabilities.
+
+
+Cross-architecture support
+--------------------------
+
+Our goal is to make Docker run everywhere. However currently Docker only runs on x86_64 systems.
+We plan on expanding architecture support, so that Docker containers can be created and used on more architectures.
+
+
+Even more integrations
+----------------------
+
+We want Docker to be the secret ingredient that makes your existing tools more awesome.
+Thanks to this philosophy, Docker has already been integrated with
+[Puppet](http://forge.puppetlabs.com/garethr/docker),  [Chef](http://www.opscode.com/chef),
+[Openstack Nova](https://github.com/dotcloud/openstack-docker), [Jenkins](https://github.com/georgebashi/jenkins-docker-plugin),
+[DotCloud sandbox](http://github.com/dotcloud/sandbox), [Pallet](https://github.com/pallet/pallet-docker),
+[Strider CI](http://blog.frozenridge.co/next-generation-continuous-integration-deployment-with-dotclouds-docker-and-strider/)
+and even [Heroku buildpacks](https://github.com/progrium/buildstep).
+
+Expect Docker to integrate with even more of your favorite tools going forward, including:
+
+* Alternative storage backends such as ZFS, LVM or [BTRFS](github.com/dotcloud/docker/issues/443)
+* Alternative containerization backends such as [OpenVZ](http://openvz.org), Solaris Zones, BSD Jails and even plain Chroot.
+* Process managers like [Supervisord](http://supervisord.org/), [Runit](http://smarden.org/runit/), [Gaffer](https://gaffer.readthedocs.org/en/latest/#gaffer) and [Systemd](http://www.freedesktop.org/wiki/Software/systemd/)
+* Build and integration tools like Make, Maven, Scons, Jenkins, Buildbot and Cruise Control.
+* Configuration management tools like [Puppet](http://puppetlabs.com), [Chef](http://www.opscode.com/chef/) and [Salt](http://saltstack.org)
+* Personal development environments like [Vagrant](http://vagrantup.com), [Boxen](http://boxen.github.com/), [Koding](http://koding.com) and [Cloud9](http://c9.io).
+* Orchestration tools like [Zookeeper](http://zookeeper.apache.org/), [Mesos](http://incubator.apache.org/mesos/) and [Galaxy](https://github.com/ning/galaxy)
+* Infrastructure deployment tools like [Openstack](http://openstack.org), [Apache Cloudstack](http://apache.cloudstack.org), [Ganeti](https://code.google.com/p/ganeti/)
+
+
+Plugin API
+----------
+
+We want Docker to run everywhere, and to integrate with every devops tool.
+Those are ambitious goals, and the only way to reach them is with the Docker community.
+For the community to participate fully, we need an API which allows Docker to be deeply and easily customized.
+
+We are working on a plugin API which will make Docker very, very customization-friendly.
+We believe it will facilitate the integrations listed above - and many more we didn't even think about.
+
+Let us know if you want to start playing with the API before it's generally available.
+
+
+Externally mounted volumes
+--------------------------
+
+In 0.3 we [introduced data volumes](https://github.com/dotcloud/docker/wiki/Docker-0.3.0-release-note%2C-May-6-2013#data-volumes),
+a great mechanism for manipulating persistent data such as database files, log files, etc.
+
+Data volumes can be shared between containers, a powerful capability [which allows many advanced use cases](http://docs.docker.io/en/latest/examples/couchdb_data_volumes.html). In the future it will also be possible to share volumes between a container and the underlying host. This will make certain scenarios much easier, such as using a high-performance storage backend for your production database,
+making live development changes available to a container, etc.
+
+
+Better documentation
+--------------------
+
+We believe that great documentation is worth 10 features. We are often told that "Docker's documentation is great for a 2-month old project".
+Our goal is to make it great, period.
+
+If you have feedback on how to improve our documentation, please get in touch by replying to this email,
+or by [filing an issue](https://github.com/dotcloud/docker/issues). We always appreciate it!
+
+
+Production-ready
+----------------
+
+Docker is still alpha software, and not suited for production.
+We are working hard to get there, and we are confident that it will be possible within a few months.
+

+ 1 - 0
hack/dockerbuilder/MAITAINERS

@@ -0,0 +1 @@
+Daniel Mizyrycki <daniel@dotcloud.com>

+ 17 - 18
image.go

@@ -18,7 +18,7 @@ import (
 )
 )
 
 
 type Image struct {
 type Image struct {
-	Id              string    `json:"id"`
+	ID              string    `json:"id"`
 	Parent          string    `json:"parent,omitempty"`
 	Parent          string    `json:"parent,omitempty"`
 	Comment         string    `json:"comment,omitempty"`
 	Comment         string    `json:"comment,omitempty"`
 	Created         time.Time `json:"created"`
 	Created         time.Time `json:"created"`
@@ -42,18 +42,17 @@ func LoadImage(root string) (*Image, error) {
 	if err := json.Unmarshal(jsonData, img); err != nil {
 	if err := json.Unmarshal(jsonData, img); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	if err := ValidateId(img.Id); err != nil {
+	if err := ValidateID(img.ID); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 	// Check that the filesystem layer exists
 	// Check that the filesystem layer exists
 	if stat, err := os.Stat(layerPath(root)); err != nil {
 	if stat, err := os.Stat(layerPath(root)); err != nil {
 		if os.IsNotExist(err) {
 		if os.IsNotExist(err) {
-			return nil, fmt.Errorf("Couldn't load image %s: no filesystem layer", img.Id)
-		} else {
-			return nil, err
+			return nil, fmt.Errorf("Couldn't load image %s: no filesystem layer", img.ID)
 		}
 		}
+		return nil, err
 	} else if !stat.IsDir() {
 	} else if !stat.IsDir() {
-		return nil, fmt.Errorf("Couldn't load image %s: %s is not a directory", img.Id, layerPath(root))
+		return nil, fmt.Errorf("Couldn't load image %s: %s is not a directory", img.ID, layerPath(root))
 	}
 	}
 	return img, nil
 	return img, nil
 }
 }
@@ -61,7 +60,7 @@ func LoadImage(root string) (*Image, error) {
 func StoreImage(img *Image, layerData Archive, root string, store bool) error {
 func StoreImage(img *Image, layerData Archive, root string, store bool) error {
 	// Check that root doesn't already exist
 	// Check that root doesn't already exist
 	if _, err := os.Stat(root); err == nil {
 	if _, err := os.Stat(root); err == nil {
-		return fmt.Errorf("Image %s already exists", img.Id)
+		return fmt.Errorf("Image %s already exists", img.ID)
 	} else if !os.IsNotExist(err) {
 	} else if !os.IsNotExist(err) {
 		return err
 		return err
 	}
 	}
@@ -181,11 +180,11 @@ func (image *Image) Changes(rw string) ([]Change, error) {
 	return Changes(layers, rw)
 	return Changes(layers, rw)
 }
 }
 
 
-func (image *Image) ShortId() string {
-	return utils.TruncateId(image.Id)
+func (image *Image) ShortID() string {
+	return utils.TruncateID(image.ID)
 }
 }
 
 
-func ValidateId(id string) error {
+func ValidateID(id string) error {
 	if id == "" {
 	if id == "" {
 		return fmt.Errorf("Image id can't be empty")
 		return fmt.Errorf("Image id can't be empty")
 	}
 	}
@@ -195,7 +194,7 @@ func ValidateId(id string) error {
 	return nil
 	return nil
 }
 }
 
 
-func GenerateId() string {
+func GenerateID() string {
 	id := make([]byte, 32)
 	id := make([]byte, 32)
 	_, err := io.ReadFull(rand.Reader, id)
 	_, err := io.ReadFull(rand.Reader, id)
 	if err != nil {
 	if err != nil {
@@ -241,7 +240,7 @@ func (img *Image) layers() ([]string, error) {
 		return nil, e
 		return nil, e
 	}
 	}
 	if len(list) == 0 {
 	if len(list) == 0 {
-		return nil, fmt.Errorf("No layer found for image %s\n", img.Id)
+		return nil, fmt.Errorf("No layer found for image %s\n", img.ID)
 	}
 	}
 	return list, nil
 	return list, nil
 }
 }
@@ -276,7 +275,7 @@ func (img *Image) root() (string, error) {
 	if img.graph == nil {
 	if img.graph == nil {
 		return "", fmt.Errorf("Can't lookup root of unregistered image")
 		return "", fmt.Errorf("Can't lookup root of unregistered image")
 	}
 	}
-	return img.graph.imageRoot(img.Id), nil
+	return img.graph.imageRoot(img.ID), nil
 }
 }
 
 
 // Return the path of an image's layer
 // Return the path of an image's layer
@@ -289,8 +288,8 @@ func (img *Image) layer() (string, error) {
 }
 }
 
 
 func (img *Image) Checksum() (string, error) {
 func (img *Image) Checksum() (string, error) {
-	img.graph.checksumLock[img.Id].Lock()
-	defer img.graph.checksumLock[img.Id].Unlock()
+	img.graph.checksumLock[img.ID].Lock()
+	defer img.graph.checksumLock[img.ID].Unlock()
 
 
 	root, err := img.root()
 	root, err := img.root()
 	if err != nil {
 	if err != nil {
@@ -301,7 +300,7 @@ func (img *Image) Checksum() (string, error) {
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
-	if checksum, ok := checksums[img.Id]; ok {
+	if checksum, ok := checksums[img.ID]; ok {
 		return checksum, nil
 		return checksum, nil
 	}
 	}
 
 
@@ -352,7 +351,7 @@ func (img *Image) Checksum() (string, error) {
 		return "", err
 		return "", err
 	}
 	}
 
 
-	checksums[img.Id] = hash
+	checksums[img.ID] = hash
 
 
 	// Dump the checksums to disc
 	// Dump the checksums to disc
 	if err := img.graph.storeChecksums(checksums); err != nil {
 	if err := img.graph.storeChecksums(checksums); err != nil {
@@ -363,7 +362,7 @@ func (img *Image) Checksum() (string, error) {
 }
 }
 
 
 // Build an Image object from raw json data
 // Build an Image object from raw json data
-func NewImgJson(src []byte) (*Image, error) {
+func NewImgJSON(src []byte) (*Image, error) {
 	ret := &Image{}
 	ret := &Image{}
 
 
 	utils.Debugf("Json string: {%s}\n", src)
 	utils.Debugf("Json string: {%s}\n", src)

+ 1 - 1
lxc_template.go

@@ -19,7 +19,7 @@ lxc.network.flags = up
 lxc.network.link = {{.NetworkSettings.Bridge}}
 lxc.network.link = {{.NetworkSettings.Bridge}}
 lxc.network.name = eth0
 lxc.network.name = eth0
 lxc.network.mtu = 1500
 lxc.network.mtu = 1500
-lxc.network.ipv4 = {{.NetworkSettings.IpAddress}}/{{.NetworkSettings.IpPrefixLen}}
+lxc.network.ipv4 = {{.NetworkSettings.IPAddress}}/{{.NetworkSettings.IPPrefixLen}}
 
 
 # root filesystem
 # root filesystem
 {{$ROOTFS := .RootfsPath}}
 {{$ROOTFS := .RootfsPath}}

+ 7 - 8
network.go

@@ -52,7 +52,7 @@ func ipToInt(ip net.IP) int32 {
 }
 }
 
 
 // Converts 32 bit integer into a 4 bytes IP address
 // Converts 32 bit integer into a 4 bytes IP address
-func intToIp(n int32) net.IP {
+func intToIP(n int32) net.IP {
 	b := make([]byte, 4)
 	b := make([]byte, 4)
 	binary.BigEndian.PutUint32(b, uint32(n))
 	binary.BigEndian.PutUint32(b, uint32(n))
 	return net.IP(b)
 	return net.IP(b)
@@ -132,9 +132,8 @@ func CreateBridgeIface(ifaceName string) error {
 	}
 	}
 	if ifaceAddr == "" {
 	if ifaceAddr == "" {
 		return fmt.Errorf("Could not find a free IP address range for interface '%s'. Please configure its address manually and run 'docker -b %s'", ifaceName, ifaceName)
 		return fmt.Errorf("Could not find a free IP address range for interface '%s'. Please configure its address manually and run 'docker -b %s'", ifaceName, ifaceName)
-	} else {
-		utils.Debugf("Creating bridge %s with network %s", ifaceName, ifaceAddr)
 	}
 	}
+	utils.Debugf("Creating bridge %s with network %s", ifaceName, ifaceAddr)
 
 
 	if output, err := ip("link", "add", ifaceName, "type", "bridge"); err != nil {
 	if output, err := ip("link", "add", ifaceName, "type", "bridge"); err != nil {
 		return fmt.Errorf("Error creating bridge: %s (output: %s)", err, output)
 		return fmt.Errorf("Error creating bridge: %s (output: %s)", err, output)
@@ -258,7 +257,7 @@ func proxy(listener net.Listener, proto, address string) error {
 		utils.Debugf("Connected to backend, splicing")
 		utils.Debugf("Connected to backend, splicing")
 		splice(src, dst)
 		splice(src, dst)
 	}
 	}
-	return nil
+	panic("Unreachable")
 }
 }
 
 
 func halfSplice(dst, src net.Conn) error {
 func halfSplice(dst, src net.Conn) error {
@@ -398,7 +397,7 @@ func (alloc *IPAllocator) run() {
 			}
 			}
 		}
 		}
 
 
-		ip := allocatedIP{ip: intToIp(newNum)}
+		ip := allocatedIP{ip: intToIP(newNum)}
 		if inUse {
 		if inUse {
 			ip.err = errors.New("No unallocated IP available")
 			ip.err = errors.New("No unallocated IP available")
 		}
 		}
@@ -465,11 +464,11 @@ func (iface *NetworkInterface) AllocatePort(spec string) (*Nat, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 	// Allocate a random port if Frontend==0
 	// Allocate a random port if Frontend==0
-	if extPort, err := iface.manager.portAllocator.Acquire(nat.Frontend); err != nil {
+	extPort, err := iface.manager.portAllocator.Acquire(nat.Frontend)
+	if err != nil {
 		return nil, err
 		return nil, err
-	} else {
-		nat.Frontend = extPort
 	}
 	}
+	nat.Frontend = extPort
 	if err := iface.manager.portMapper.Map(nat.Frontend, net.TCPAddr{IP: iface.IPNet.IP, Port: nat.Backend}); err != nil {
 	if err := iface.manager.portMapper.Map(nat.Frontend, net.TCPAddr{IP: iface.IPNet.IP, Port: nat.Backend}); err != nil {
 		iface.manager.portAllocator.Release(nat.Frontend)
 		iface.manager.portAllocator.Release(nat.Frontend)
 		return nil, err
 		return nil, err

+ 1 - 1
network_test.go

@@ -137,7 +137,7 @@ func TestConversion(t *testing.T) {
 	if i == 0 {
 	if i == 0 {
 		t.Fatal("converted to zero")
 		t.Fatal("converted to zero")
 	}
 	}
-	conv := intToIp(i)
+	conv := intToIP(i)
 	if !ip.Equal(conv) {
 	if !ip.Equal(conv) {
 		t.Error(conv.String())
 		t.Error(conv.String())
 	}
 	}

+ 7 - 0
packaging/ubuntu/changelog

@@ -1,3 +1,10 @@
+lxc-docker (0.4.0-1) precise; urgency=low
+  - Introducing Builder: 'docker build' builds a container, layer by layer, from a source repository containing a Dockerfile
+  - Introducing Remote API: control Docker programmatically using a simple HTTP/json API
+  - Runtime: various reliability and usability improvements
+
+ -- dotCloud <ops@dotcloud.com>  Mon, 03 Jun 2013 00:00:00 -0700
+
 lxc-docker (0.3.4-1) precise; urgency=low
 lxc-docker (0.3.4-1) precise; urgency=low
   - Builder: 'docker build' builds a container, layer by layer, from a source repository containing a Dockerfile
   - Builder: 'docker build' builds a container, layer by layer, from a source repository containing a Dockerfile
   - Builder: 'docker build -t FOO' applies the tag FOO to the newly built container.
   - Builder: 'docker build -t FOO' applies the tag FOO to the newly built container.

+ 41 - 27
registry/registry.go

@@ -15,7 +15,7 @@ import (
 	"strings"
 	"strings"
 )
 )
 
 
-var ErrAlreadyExists error = errors.New("Image already exists")
+var ErrAlreadyExists = errors.New("Image already exists")
 
 
 func doWithCookies(c *http.Client, req *http.Request) (*http.Response, error) {
 func doWithCookies(c *http.Client, req *http.Request) (*http.Response, error) {
 	for _, cookie := range c.Jar.Cookies(req.URL) {
 	for _, cookie := range c.Jar.Cookies(req.URL) {
@@ -64,7 +64,11 @@ func (r *Registry) LookupRemoteImage(imgId, registry string, authConfig *auth.Au
 	}
 	}
 	req.SetBasicAuth(authConfig.Username, authConfig.Password)
 	req.SetBasicAuth(authConfig.Username, authConfig.Password)
 	res, err := rt.RoundTrip(req)
 	res, err := rt.RoundTrip(req)
-	return err == nil && res.StatusCode == 307
+	if err != nil {
+		return false
+	}
+	res.Body.Close()
+	return res.StatusCode == 307
 }
 }
 
 
 func (r *Registry) getImagesInRepository(repository string, authConfig *auth.AuthConfig) ([]map[string]string, error) {
 func (r *Registry) getImagesInRepository(repository string, authConfig *auth.AuthConfig) ([]map[string]string, error) {
@@ -103,8 +107,8 @@ func (r *Registry) getImagesInRepository(repository string, authConfig *auth.Aut
 
 
 // Retrieve an image from the Registry.
 // Retrieve an image from the Registry.
 // Returns the Image object as well as the layer as an Archive (io.Reader)
 // Returns the Image object as well as the layer as an Archive (io.Reader)
-func (r *Registry) GetRemoteImageJson(imgId, registry string, token []string) ([]byte, error) {
-	// Get the Json
+func (r *Registry) GetRemoteImageJSON(imgId, registry string, token []string) ([]byte, error) {
+	// Get the JSON
 	req, err := http.NewRequest("GET", registry+"/images/"+imgId+"/json", nil)
 	req, err := http.NewRequest("GET", registry+"/images/"+imgId+"/json", nil)
 	if err != nil {
 	if err != nil {
 		return nil, fmt.Errorf("Failed to download json: %s", err)
 		return nil, fmt.Errorf("Failed to download json: %s", err)
@@ -152,21 +156,24 @@ func (r *Registry) GetRemoteTags(registries []string, repository string, token [
 		}
 		}
 		req.Header.Set("Authorization", "Token "+strings.Join(token, ", "))
 		req.Header.Set("Authorization", "Token "+strings.Join(token, ", "))
 		res, err := r.client.Do(req)
 		res, err := r.client.Do(req)
-		defer res.Body.Close()
 		utils.Debugf("Got status code %d from %s", res.StatusCode, endpoint)
 		utils.Debugf("Got status code %d from %s", res.StatusCode, endpoint)
-		if err != nil || (res.StatusCode != 200 && res.StatusCode != 404) {
+		if err != nil {
+			return nil, err
+		}
+		defer res.Body.Close()
+
+		if res.StatusCode != 200 && res.StatusCode != 404 {
 			continue
 			continue
 		} else if res.StatusCode == 404 {
 		} else if res.StatusCode == 404 {
 			return nil, fmt.Errorf("Repository not found")
 			return nil, fmt.Errorf("Repository not found")
 		}
 		}
 
 
 		result := make(map[string]string)
 		result := make(map[string]string)
-
-		rawJson, err := ioutil.ReadAll(res.Body)
+		rawJSON, err := ioutil.ReadAll(res.Body)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
-		if err := json.Unmarshal(rawJson, &result); err != nil {
+		if err := json.Unmarshal(rawJSON, &result); err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 		return result, nil
 		return result, nil
@@ -212,19 +219,19 @@ func (r *Registry) GetRepositoryData(remote string) (*RepositoryData, error) {
 		return nil, fmt.Errorf("Index response didn't contain any endpoints")
 		return nil, fmt.Errorf("Index response didn't contain any endpoints")
 	}
 	}
 
 
-	checksumsJson, err := ioutil.ReadAll(res.Body)
+	checksumsJSON, err := ioutil.ReadAll(res.Body)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 	remoteChecksums := []*ImgData{}
 	remoteChecksums := []*ImgData{}
-	if err := json.Unmarshal(checksumsJson, &remoteChecksums); err != nil {
+	if err := json.Unmarshal(checksumsJSON, &remoteChecksums); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
 	// Forge a better object from the retrieved data
 	// Forge a better object from the retrieved data
 	imgsData := make(map[string]*ImgData)
 	imgsData := make(map[string]*ImgData)
 	for _, elem := range remoteChecksums {
 	for _, elem := range remoteChecksums {
-		imgsData[elem.Id] = elem
+		imgsData[elem.ID] = elem
 	}
 	}
 
 
 	return &RepositoryData{
 	return &RepositoryData{
@@ -235,10 +242,10 @@ func (r *Registry) GetRepositoryData(remote string) (*RepositoryData, error) {
 }
 }
 
 
 // Push a local image to the registry
 // Push a local image to the registry
-func (r *Registry) PushImageJsonRegistry(imgData *ImgData, jsonRaw []byte, registry string, token []string) error {
+func (r *Registry) PushImageJSONRegistry(imgData *ImgData, jsonRaw []byte, registry string, token []string) error {
 	registry = "https://" + registry + "/v1"
 	registry = "https://" + registry + "/v1"
 	// FIXME: try json with UTF8
 	// FIXME: try json with UTF8
-	req, err := http.NewRequest("PUT", registry+"/images/"+imgData.Id+"/json", strings.NewReader(string(jsonRaw)))
+	req, err := http.NewRequest("PUT", registry+"/images/"+imgData.ID+"/json", strings.NewReader(string(jsonRaw)))
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -246,7 +253,7 @@ func (r *Registry) PushImageJsonRegistry(imgData *ImgData, jsonRaw []byte, regis
 	req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
 	req.Header.Set("Authorization", "Token "+strings.Join(token, ","))
 	req.Header.Set("X-Docker-Checksum", imgData.Checksum)
 	req.Header.Set("X-Docker-Checksum", imgData.Checksum)
 
 
-	utils.Debugf("Setting checksum for %s: %s", imgData.Id, imgData.Checksum)
+	utils.Debugf("Setting checksum for %s: %s", imgData.ID, imgData.Checksum)
 	res, err := doWithCookies(r.client, req)
 	res, err := doWithCookies(r.client, req)
 	if err != nil {
 	if err != nil {
 		return fmt.Errorf("Failed to upload metadata: %s", err)
 		return fmt.Errorf("Failed to upload metadata: %s", err)
@@ -321,8 +328,8 @@ func (r *Registry) PushRegistryTag(remote, revision, tag, registry string, token
 	return nil
 	return nil
 }
 }
 
 
-func (r *Registry) PushImageJsonIndex(remote string, imgList []*ImgData, validate bool) (*RepositoryData, error) {
-	imgListJson, err := json.Marshal(imgList)
+func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validate bool) (*RepositoryData, error) {
+	imgListJSON, err := json.Marshal(imgList)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -331,14 +338,14 @@ func (r *Registry) PushImageJsonIndex(remote string, imgList []*ImgData, validat
 		suffix = "images"
 		suffix = "images"
 	}
 	}
 
 
-	utils.Debugf("Image list pushed to index:\n%s\n", imgListJson)
+	utils.Debugf("Image list pushed to index:\n%s\n", imgListJSON)
 
 
-	req, err := http.NewRequest("PUT", auth.IndexServerAddress()+"/repositories/"+remote+"/"+suffix, bytes.NewReader(imgListJson))
+	req, err := http.NewRequest("PUT", auth.IndexServerAddress()+"/repositories/"+remote+"/"+suffix, bytes.NewReader(imgListJSON))
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 	req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password)
 	req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password)
-	req.ContentLength = int64(len(imgListJson))
+	req.ContentLength = int64(len(imgListJSON))
 	req.Header.Set("X-Docker-Token", "true")
 	req.Header.Set("X-Docker-Token", "true")
 
 
 	res, err := r.client.Do(req)
 	res, err := r.client.Do(req)
@@ -350,12 +357,12 @@ func (r *Registry) PushImageJsonIndex(remote string, imgList []*ImgData, validat
 	// Redirect if necessary
 	// Redirect if necessary
 	for res.StatusCode >= 300 && res.StatusCode < 400 {
 	for res.StatusCode >= 300 && res.StatusCode < 400 {
 		utils.Debugf("Redirected to %s\n", res.Header.Get("Location"))
 		utils.Debugf("Redirected to %s\n", res.Header.Get("Location"))
-		req, err = http.NewRequest("PUT", res.Header.Get("Location"), bytes.NewReader(imgListJson))
+		req, err = http.NewRequest("PUT", res.Header.Get("Location"), bytes.NewReader(imgListJSON))
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 		req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password)
 		req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password)
-		req.ContentLength = int64(len(imgListJson))
+		req.ContentLength = int64(len(imgListJSON))
 		req.Header.Set("X-Docker-Token", "true")
 		req.Header.Set("X-Docker-Token", "true")
 
 
 		res, err = r.client.Do(req)
 		res, err = r.client.Do(req)
@@ -389,11 +396,11 @@ func (r *Registry) PushImageJsonIndex(remote string, imgList []*ImgData, validat
 	}
 	}
 	if validate {
 	if validate {
 		if res.StatusCode != 204 {
 		if res.StatusCode != 204 {
-			if errBody, err := ioutil.ReadAll(res.Body); err != nil {
+			errBody, err := ioutil.ReadAll(res.Body)
+			if err != nil {
 				return nil, err
 				return nil, err
-			} else {
-				return nil, fmt.Errorf("Error: Status %d trying to push checksums %s: %s", res.StatusCode, remote, errBody)
 			}
 			}
+			return nil, fmt.Errorf("Error: Status %d trying to push checksums %s: %s", res.StatusCode, remote, errBody)
 		}
 		}
 	}
 	}
 
 
@@ -456,7 +463,7 @@ type RepositoryData struct {
 }
 }
 
 
 type ImgData struct {
 type ImgData struct {
-	Id       string `json:"id"`
+	ID       string `json:"id"`
 	Checksum string `json:"checksum,omitempty"`
 	Checksum string `json:"checksum,omitempty"`
 	Tag      string `json:",omitempty"`
 	Tag      string `json:",omitempty"`
 }
 }
@@ -470,9 +477,16 @@ func NewRegistry(root string) *Registry {
 	// If the auth file does not exist, keep going
 	// If the auth file does not exist, keep going
 	authConfig, _ := auth.LoadConfig(root)
 	authConfig, _ := auth.LoadConfig(root)
 
 
+	httpTransport := &http.Transport{
+		DisableKeepAlives: true,
+		Proxy: http.ProxyFromEnvironment,
+	}
+
 	r := &Registry{
 	r := &Registry{
 		authConfig: authConfig,
 		authConfig: authConfig,
-		client:     &http.Client{},
+		client: &http.Client{
+			Transport: httpTransport,
+		},
 	}
 	}
 	r.client.Jar = cookiejar.NewCookieJar()
 	r.client.Jar = cookiejar.NewCookieJar()
 	return r
 	return r

+ 31 - 31
runtime.go

@@ -51,7 +51,7 @@ func (runtime *Runtime) List() []*Container {
 func (runtime *Runtime) getContainerElement(id string) *list.Element {
 func (runtime *Runtime) getContainerElement(id string) *list.Element {
 	for e := runtime.containers.Front(); e != nil; e = e.Next() {
 	for e := runtime.containers.Front(); e != nil; e = e.Next() {
 		container := e.Value.(*Container)
 		container := e.Value.(*Container)
-		if container.Id == id {
+		if container.ID == id {
 			return e
 			return e
 		}
 		}
 	}
 	}
@@ -83,8 +83,8 @@ func (runtime *Runtime) Load(id string) (*Container, error) {
 	if err := container.FromDisk(); err != nil {
 	if err := container.FromDisk(); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	if container.Id != id {
-		return container, fmt.Errorf("Container %s is stored at %s", container.Id, id)
+	if container.ID != id {
+		return container, fmt.Errorf("Container %s is stored at %s", container.ID, id)
 	}
 	}
 	if container.State.Running {
 	if container.State.Running {
 		container.State.Ghost = true
 		container.State.Ghost = true
@@ -95,12 +95,12 @@ func (runtime *Runtime) Load(id string) (*Container, error) {
 	return container, nil
 	return container, nil
 }
 }
 
 
-// Register makes a container object usable by the runtime as <container.Id>
+// Register makes a container object usable by the runtime as <container.ID>
 func (runtime *Runtime) Register(container *Container) error {
 func (runtime *Runtime) Register(container *Container) error {
-	if container.runtime != nil || runtime.Exists(container.Id) {
+	if container.runtime != nil || runtime.Exists(container.ID) {
 		return fmt.Errorf("Container is already loaded")
 		return fmt.Errorf("Container is already loaded")
 	}
 	}
-	if err := validateId(container.Id); err != nil {
+	if err := validateID(container.ID); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -123,7 +123,7 @@ func (runtime *Runtime) Register(container *Container) error {
 	}
 	}
 	// done
 	// done
 	runtime.containers.PushBack(container)
 	runtime.containers.PushBack(container)
-	runtime.idIndex.Add(container.Id)
+	runtime.idIndex.Add(container.ID)
 
 
 	// When we actually restart, Start() do the monitoring.
 	// When we actually restart, Start() do the monitoring.
 	// However, when we simply 'reattach', we have to restart a monitor
 	// However, when we simply 'reattach', we have to restart a monitor
@@ -133,25 +133,25 @@ func (runtime *Runtime) Register(container *Container) error {
 	//        if so, then we need to restart monitor and init a new lock
 	//        if so, then we need to restart monitor and init a new lock
 	// If the container is supposed to be running, make sure of it
 	// If the container is supposed to be running, make sure of it
 	if container.State.Running {
 	if container.State.Running {
-		if output, err := exec.Command("lxc-info", "-n", container.Id).CombinedOutput(); err != nil {
+		output, err := exec.Command("lxc-info", "-n", container.ID).CombinedOutput()
+		if err != nil {
 			return err
 			return err
-		} else {
-			if !strings.Contains(string(output), "RUNNING") {
-				utils.Debugf("Container %s was supposed to be running be is not.", container.Id)
-				if runtime.autoRestart {
-					utils.Debugf("Restarting")
-					container.State.Ghost = false
-					container.State.setStopped(0)
-					if err := container.Start(); err != nil {
-						return err
-					}
-					nomonitor = true
-				} else {
-					utils.Debugf("Marking as stopped")
-					container.State.setStopped(-127)
-					if err := container.ToDisk(); err != nil {
-						return err
-					}
+		}
+		if !strings.Contains(string(output), "RUNNING") {
+			utils.Debugf("Container %s was supposed to be running be is not.", container.ID)
+			if runtime.autoRestart {
+				utils.Debugf("Restarting")
+				container.State.Ghost = false
+				container.State.setStopped(0)
+				if err := container.Start(); err != nil {
+					return err
+				}
+				nomonitor = true
+			} else {
+				utils.Debugf("Marking as stopped")
+				container.State.setStopped(-127)
+				if err := container.ToDisk(); err != nil {
+					return err
 				}
 				}
 			}
 			}
 		}
 		}
@@ -182,9 +182,9 @@ func (runtime *Runtime) Destroy(container *Container) error {
 		return fmt.Errorf("The given container is <nil>")
 		return fmt.Errorf("The given container is <nil>")
 	}
 	}
 
 
-	element := runtime.getContainerElement(container.Id)
+	element := runtime.getContainerElement(container.ID)
 	if element == nil {
 	if element == nil {
-		return fmt.Errorf("Container %v not found - maybe it was already destroyed?", container.Id)
+		return fmt.Errorf("Container %v not found - maybe it was already destroyed?", container.ID)
 	}
 	}
 
 
 	if err := container.Stop(3); err != nil {
 	if err := container.Stop(3); err != nil {
@@ -194,14 +194,14 @@ func (runtime *Runtime) Destroy(container *Container) error {
 		return err
 		return err
 	} else if mounted {
 	} else if mounted {
 		if err := container.Unmount(); err != nil {
 		if err := container.Unmount(); err != nil {
-			return fmt.Errorf("Unable to unmount container %v: %v", container.Id, err)
+			return fmt.Errorf("Unable to unmount container %v: %v", container.ID, err)
 		}
 		}
 	}
 	}
 	// Deregister the container before removing its directory, to avoid race conditions
 	// Deregister the container before removing its directory, to avoid race conditions
-	runtime.idIndex.Delete(container.Id)
+	runtime.idIndex.Delete(container.ID)
 	runtime.containers.Remove(element)
 	runtime.containers.Remove(element)
 	if err := os.RemoveAll(container.root); err != nil {
 	if err := os.RemoveAll(container.root); err != nil {
-		return fmt.Errorf("Unable to remove filesystem for %v: %v", container.Id, err)
+		return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err)
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -218,7 +218,7 @@ func (runtime *Runtime) restore() error {
 			utils.Debugf("Failed to load container %v: %v", id, err)
 			utils.Debugf("Failed to load container %v: %v", id, err)
 			continue
 			continue
 		}
 		}
-		utils.Debugf("Loaded container %v", container.Id)
+		utils.Debugf("Loaded container %v", container.ID)
 	}
 	}
 	return nil
 	return nil
 }
 }

+ 25 - 25
runtime_test.go

@@ -120,7 +120,7 @@ func TestRuntimeCreate(t *testing.T) {
 	builder := NewBuilder(runtime)
 	builder := NewBuilder(runtime)
 
 
 	container, err := builder.Create(&Config{
 	container, err := builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"ls", "-al"},
 		Cmd:   []string{"ls", "-al"},
 	},
 	},
 	)
 	)
@@ -140,29 +140,29 @@ func TestRuntimeCreate(t *testing.T) {
 	}
 	}
 
 
 	// Make sure the container List() returns is the right one
 	// Make sure the container List() returns is the right one
-	if runtime.List()[0].Id != container.Id {
+	if runtime.List()[0].ID != container.ID {
 		t.Errorf("Unexpected container %v returned by List", runtime.List()[0])
 		t.Errorf("Unexpected container %v returned by List", runtime.List()[0])
 	}
 	}
 
 
 	// Make sure we can get the container with Get()
 	// Make sure we can get the container with Get()
-	if runtime.Get(container.Id) == nil {
+	if runtime.Get(container.ID) == nil {
 		t.Errorf("Unable to get newly created container")
 		t.Errorf("Unable to get newly created container")
 	}
 	}
 
 
 	// Make sure it is the right container
 	// Make sure it is the right container
-	if runtime.Get(container.Id) != container {
+	if runtime.Get(container.ID) != container {
 		t.Errorf("Get() returned the wrong container")
 		t.Errorf("Get() returned the wrong container")
 	}
 	}
 
 
 	// Make sure Exists returns it as existing
 	// Make sure Exists returns it as existing
-	if !runtime.Exists(container.Id) {
+	if !runtime.Exists(container.ID) {
 		t.Errorf("Exists() returned false for a newly created container")
 		t.Errorf("Exists() returned false for a newly created container")
 	}
 	}
 
 
 	// Make sure crete with bad parameters returns an error
 	// Make sure crete with bad parameters returns an error
 	_, err = builder.Create(
 	_, err = builder.Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 		},
 		},
 	)
 	)
 	if err == nil {
 	if err == nil {
@@ -171,7 +171,7 @@ func TestRuntimeCreate(t *testing.T) {
 
 
 	_, err = builder.Create(
 	_, err = builder.Create(
 		&Config{
 		&Config{
-			Image: GetTestImage(runtime).Id,
+			Image: GetTestImage(runtime).ID,
 			Cmd:   []string{},
 			Cmd:   []string{},
 		},
 		},
 	)
 	)
@@ -187,7 +187,7 @@ func TestDestroy(t *testing.T) {
 	}
 	}
 	defer nuke(runtime)
 	defer nuke(runtime)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"ls", "-al"},
 		Cmd:   []string{"ls", "-al"},
 	},
 	},
 	)
 	)
@@ -210,7 +210,7 @@ func TestDestroy(t *testing.T) {
 	}
 	}
 
 
 	// Make sure runtime.Get() refuses to return the unexisting container
 	// Make sure runtime.Get() refuses to return the unexisting container
-	if runtime.Get(container.Id) != nil {
+	if runtime.Get(container.ID) != nil {
 		t.Errorf("Unable to get newly created container")
 		t.Errorf("Unable to get newly created container")
 	}
 	}
 
 
@@ -237,7 +237,7 @@ func TestGet(t *testing.T) {
 	builder := NewBuilder(runtime)
 	builder := NewBuilder(runtime)
 
 
 	container1, err := builder.Create(&Config{
 	container1, err := builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"ls", "-al"},
 		Cmd:   []string{"ls", "-al"},
 	},
 	},
 	)
 	)
@@ -247,7 +247,7 @@ func TestGet(t *testing.T) {
 	defer runtime.Destroy(container1)
 	defer runtime.Destroy(container1)
 
 
 	container2, err := builder.Create(&Config{
 	container2, err := builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"ls", "-al"},
 		Cmd:   []string{"ls", "-al"},
 	},
 	},
 	)
 	)
@@ -257,7 +257,7 @@ func TestGet(t *testing.T) {
 	defer runtime.Destroy(container2)
 	defer runtime.Destroy(container2)
 
 
 	container3, err := builder.Create(&Config{
 	container3, err := builder.Create(&Config{
-		Image: GetTestImage(runtime).Id,
+		Image: GetTestImage(runtime).ID,
 		Cmd:   []string{"ls", "-al"},
 		Cmd:   []string{"ls", "-al"},
 	},
 	},
 	)
 	)
@@ -266,16 +266,16 @@ func TestGet(t *testing.T) {
 	}
 	}
 	defer runtime.Destroy(container3)
 	defer runtime.Destroy(container3)
 
 
-	if runtime.Get(container1.Id) != container1 {
-		t.Errorf("Get(test1) returned %v while expecting %v", runtime.Get(container1.Id), container1)
+	if runtime.Get(container1.ID) != container1 {
+		t.Errorf("Get(test1) returned %v while expecting %v", runtime.Get(container1.ID), container1)
 	}
 	}
 
 
-	if runtime.Get(container2.Id) != container2 {
-		t.Errorf("Get(test2) returned %v while expecting %v", runtime.Get(container2.Id), container2)
+	if runtime.Get(container2.ID) != container2 {
+		t.Errorf("Get(test2) returned %v while expecting %v", runtime.Get(container2.ID), container2)
 	}
 	}
 
 
-	if runtime.Get(container3.Id) != container3 {
-		t.Errorf("Get(test3) returned %v while expecting %v", runtime.Get(container3.Id), container3)
+	if runtime.Get(container3.ID) != container3 {
+		t.Errorf("Get(test3) returned %v while expecting %v", runtime.Get(container3.ID), container3)
 	}
 	}
 
 
 }
 }
@@ -283,7 +283,7 @@ func TestGet(t *testing.T) {
 func findAvailalblePort(runtime *Runtime, port int) (*Container, error) {
 func findAvailalblePort(runtime *Runtime, port int) (*Container, error) {
 	strPort := strconv.Itoa(port)
 	strPort := strconv.Itoa(port)
 	container, err := NewBuilder(runtime).Create(&Config{
 	container, err := NewBuilder(runtime).Create(&Config{
-		Image:     GetTestImage(runtime).Id,
+		Image:     GetTestImage(runtime).ID,
 		Cmd:       []string{"sh", "-c", "echo well hello there | nc -l -p " + strPort},
 		Cmd:       []string{"sh", "-c", "echo well hello there | nc -l -p " + strPort},
 		PortSpecs: []string{strPort},
 		PortSpecs: []string{strPort},
 	},
 	},
@@ -379,7 +379,7 @@ func TestRestore(t *testing.T) {
 
 
 	// Create a container with one instance of docker
 	// Create a container with one instance of docker
 	container1, err := builder.Create(&Config{
 	container1, err := builder.Create(&Config{
-		Image: GetTestImage(runtime1).Id,
+		Image: GetTestImage(runtime1).ID,
 		Cmd:   []string{"ls", "-al"},
 		Cmd:   []string{"ls", "-al"},
 	},
 	},
 	)
 	)
@@ -390,7 +390,7 @@ func TestRestore(t *testing.T) {
 
 
 	// Create a second container meant to be killed
 	// Create a second container meant to be killed
 	container2, err := builder.Create(&Config{
 	container2, err := builder.Create(&Config{
-		Image:     GetTestImage(runtime1).Id,
+		Image:     GetTestImage(runtime1).ID,
 		Cmd:       []string{"/bin/cat"},
 		Cmd:       []string{"/bin/cat"},
 		OpenStdin: true,
 		OpenStdin: true,
 	},
 	},
@@ -406,7 +406,7 @@ func TestRestore(t *testing.T) {
 	}
 	}
 
 
 	if !container2.State.Running {
 	if !container2.State.Running {
-		t.Fatalf("Container %v should appear as running but isn't", container2.Id)
+		t.Fatalf("Container %v should appear as running but isn't", container2.ID)
 	}
 	}
 
 
 	// Simulate a crash/manual quit of dockerd: process dies, states stays 'Running'
 	// Simulate a crash/manual quit of dockerd: process dies, states stays 'Running'
@@ -426,7 +426,7 @@ func TestRestore(t *testing.T) {
 	}
 	}
 
 
 	if !container2.State.Running {
 	if !container2.State.Running {
-		t.Fatalf("Container %v should appear as running but isn't", container2.Id)
+		t.Fatalf("Container %v should appear as running but isn't", container2.ID)
 	}
 	}
 
 
 	// Here are are simulating a docker restart - that is, reloading all containers
 	// Here are are simulating a docker restart - that is, reloading all containers
@@ -442,14 +442,14 @@ func TestRestore(t *testing.T) {
 	runningCount := 0
 	runningCount := 0
 	for _, c := range runtime2.List() {
 	for _, c := range runtime2.List() {
 		if c.State.Running {
 		if c.State.Running {
-			t.Errorf("Running container found: %v (%v)", c.Id, c.Path)
+			t.Errorf("Running container found: %v (%v)", c.ID, c.Path)
 			runningCount++
 			runningCount++
 		}
 		}
 	}
 	}
 	if runningCount != 0 {
 	if runningCount != 0 {
 		t.Fatalf("Expected 0 container alive, %d found", runningCount)
 		t.Fatalf("Expected 0 container alive, %d found", runningCount)
 	}
 	}
-	container3 := runtime2.Get(container1.Id)
+	container3 := runtime2.Get(container1.ID)
 	if container3 == nil {
 	if container3 == nil {
 		t.Fatal("Unable to Get container")
 		t.Fatal("Unable to Get container")
 	}
 	}

+ 100 - 88
server.go

@@ -17,8 +17,12 @@ import (
 	"strings"
 	"strings"
 )
 )
 
 
-func (srv *Server) DockerVersion() ApiVersion {
-	return ApiVersion{VERSION, GIT_COMMIT, srv.runtime.capabilities.MemoryLimit, srv.runtime.capabilities.SwapLimit}
+func (srv *Server) DockerVersion() APIVersion {
+	return APIVersion{
+		Version:   VERSION,
+		GitCommit: GITCOMMIT,
+		GoVersion: runtime.Version(),
+	}
 }
 }
 
 
 func (srv *Server) ContainerKill(name string) error {
 func (srv *Server) ContainerKill(name string) error {
@@ -49,16 +53,16 @@ func (srv *Server) ContainerExport(name string, out io.Writer) error {
 	return fmt.Errorf("No such container: %s", name)
 	return fmt.Errorf("No such container: %s", name)
 }
 }
 
 
-func (srv *Server) ImagesSearch(term string) ([]ApiSearch, error) {
+func (srv *Server) ImagesSearch(term string) ([]APISearch, error) {
 
 
 	results, err := registry.NewRegistry(srv.runtime.root).SearchRepositories(term)
 	results, err := registry.NewRegistry(srv.runtime.root).SearchRepositories(term)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	var outs []ApiSearch
+	var outs []APISearch
 	for _, repo := range results.Results {
 	for _, repo := range results.Results {
-		var out ApiSearch
+		var out APISearch
 		out.Description = repo["description"]
 		out.Description = repo["description"]
 		if len(out.Description) > 45 {
 		if len(out.Description) > 45 {
 			out.Description = utils.Trunc(out.Description, 42) + "..."
 			out.Description = utils.Trunc(out.Description, 42) + "..."
@@ -82,7 +86,7 @@ func (srv *Server) ImageInsert(name, url, path string, out io.Writer, sf *utils.
 	}
 	}
 	defer file.Body.Close()
 	defer file.Body.Close()
 
 
-	config, _, err := ParseRun([]string{img.Id, "echo", "insert", url, path}, srv.runtime.capabilities)
+	config, _, err := ParseRun([]string{img.ID, "echo", "insert", url, path}, srv.runtime.capabilities)
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
@@ -101,8 +105,8 @@ func (srv *Server) ImageInsert(name, url, path string, out io.Writer, sf *utils.
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
-	out.Write(sf.FormatStatus(img.Id))
-	return img.ShortId(), nil
+	out.Write(sf.FormatStatus(img.ID))
+	return img.ShortID(), nil
 }
 }
 
 
 func (srv *Server) ImagesViz(out io.Writer) error {
 func (srv *Server) ImagesViz(out io.Writer) error {
@@ -122,9 +126,9 @@ func (srv *Server) ImagesViz(out io.Writer) error {
 			return fmt.Errorf("Error while getting parent image: %v", err)
 			return fmt.Errorf("Error while getting parent image: %v", err)
 		}
 		}
 		if parentImage != nil {
 		if parentImage != nil {
-			out.Write([]byte(" \"" + parentImage.ShortId() + "\" -> \"" + image.ShortId() + "\"\n"))
+			out.Write([]byte(" \"" + parentImage.ShortID() + "\" -> \"" + image.ShortID() + "\"\n"))
 		} else {
 		} else {
-			out.Write([]byte(" base -> \"" + image.ShortId() + "\" [style=invis]\n"))
+			out.Write([]byte(" base -> \"" + image.ShortID() + "\" [style=invis]\n"))
 		}
 		}
 	}
 	}
 
 
@@ -132,7 +136,7 @@ func (srv *Server) ImagesViz(out io.Writer) error {
 
 
 	for name, repository := range srv.runtime.repositories.Repositories {
 	for name, repository := range srv.runtime.repositories.Repositories {
 		for tag, id := range repository {
 		for tag, id := range repository {
-			reporefs[utils.TruncateId(id)] = append(reporefs[utils.TruncateId(id)], fmt.Sprintf("%s:%s", name, tag))
+			reporefs[utils.TruncateID(id)] = append(reporefs[utils.TruncateID(id)], fmt.Sprintf("%s:%s", name, tag))
 		}
 		}
 	}
 	}
 
 
@@ -143,7 +147,7 @@ func (srv *Server) ImagesViz(out io.Writer) error {
 	return nil
 	return nil
 }
 }
 
 
-func (srv *Server) Images(all bool, filter string) ([]ApiImages, error) {
+func (srv *Server) Images(all bool, filter string) ([]APIImages, error) {
 	var (
 	var (
 		allImages map[string]*Image
 		allImages map[string]*Image
 		err       error
 		err       error
@@ -156,13 +160,13 @@ func (srv *Server) Images(all bool, filter string) ([]ApiImages, error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	outs := []ApiImages{} //produce [] when empty instead of 'null'
+	outs := []APIImages{} //produce [] when empty instead of 'null'
 	for name, repository := range srv.runtime.repositories.Repositories {
 	for name, repository := range srv.runtime.repositories.Repositories {
 		if filter != "" && name != filter {
 		if filter != "" && name != filter {
 			continue
 			continue
 		}
 		}
 		for tag, id := range repository {
 		for tag, id := range repository {
-			var out ApiImages
+			var out APIImages
 			image, err := srv.runtime.graph.Get(id)
 			image, err := srv.runtime.graph.Get(id)
 			if err != nil {
 			if err != nil {
 				log.Printf("Warning: couldn't load %s from %s/%s: %s", id, name, tag, err)
 				log.Printf("Warning: couldn't load %s from %s/%s: %s", id, name, tag, err)
@@ -171,7 +175,7 @@ func (srv *Server) Images(all bool, filter string) ([]ApiImages, error) {
 			delete(allImages, id)
 			delete(allImages, id)
 			out.Repository = name
 			out.Repository = name
 			out.Tag = tag
 			out.Tag = tag
-			out.Id = image.Id
+			out.ID = image.ID
 			out.Created = image.Created.Unix()
 			out.Created = image.Created.Unix()
 			outs = append(outs, out)
 			outs = append(outs, out)
 		}
 		}
@@ -179,8 +183,8 @@ func (srv *Server) Images(all bool, filter string) ([]ApiImages, error) {
 	// Display images which aren't part of a
 	// Display images which aren't part of a
 	if filter == "" {
 	if filter == "" {
 		for _, image := range allImages {
 		for _, image := range allImages {
-			var out ApiImages
-			out.Id = image.Id
+			var out APIImages
+			out.ID = image.ID
 			out.Created = image.Created.Unix()
 			out.Created = image.Created.Unix()
 			outs = append(outs, out)
 			outs = append(outs, out)
 		}
 		}
@@ -188,7 +192,7 @@ func (srv *Server) Images(all bool, filter string) ([]ApiImages, error) {
 	return outs, nil
 	return outs, nil
 }
 }
 
 
-func (srv *Server) DockerInfo() ApiInfo {
+func (srv *Server) DockerInfo() *APIInfo {
 	images, _ := srv.runtime.graph.All()
 	images, _ := srv.runtime.graph.All()
 	var imgcount int
 	var imgcount int
 	if images == nil {
 	if images == nil {
@@ -196,29 +200,27 @@ func (srv *Server) DockerInfo() ApiInfo {
 	} else {
 	} else {
 		imgcount = len(images)
 		imgcount = len(images)
 	}
 	}
-	var out ApiInfo
-	out.Containers = len(srv.runtime.List())
-	out.Version = VERSION
-	out.Images = imgcount
-	out.GoVersion = runtime.Version()
-	if os.Getenv("DEBUG") != "" {
-		out.Debug = true
-		out.NFd = utils.GetTotalUsedFds()
-		out.NGoroutines = runtime.NumGoroutine()
+	return &APIInfo{
+		Containers:  len(srv.runtime.List()),
+		Images:      imgcount,
+		MemoryLimit: srv.runtime.capabilities.MemoryLimit,
+		SwapLimit:   srv.runtime.capabilities.SwapLimit,
+		Debug:       os.Getenv("DEBUG") != "",
+		NFd:         utils.GetTotalUsedFds(),
+		NGoroutines: runtime.NumGoroutine(),
 	}
 	}
-	return out
 }
 }
 
 
-func (srv *Server) ImageHistory(name string) ([]ApiHistory, error) {
+func (srv *Server) ImageHistory(name string) ([]APIHistory, error) {
 	image, err := srv.runtime.repositories.LookupImage(name)
 	image, err := srv.runtime.repositories.LookupImage(name)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	var outs []ApiHistory = []ApiHistory{} //produce [] when empty instead of 'null'
+	outs := []APIHistory{} //produce [] when empty instead of 'null'
 	err = image.WalkHistory(func(img *Image) error {
 	err = image.WalkHistory(func(img *Image) error {
-		var out ApiHistory
-		out.Id = srv.runtime.repositories.ImageName(img.ShortId())
+		var out APIHistory
+		out.ID = srv.runtime.repositories.ImageName(img.ShortID())
 		out.Created = img.Created.Unix()
 		out.Created = img.Created.Unix()
 		out.CreatedBy = strings.Join(img.ContainerConfig.Cmd, " ")
 		out.CreatedBy = strings.Join(img.ContainerConfig.Cmd, " ")
 		outs = append(outs, out)
 		outs = append(outs, out)
@@ -235,17 +237,17 @@ func (srv *Server) ContainerChanges(name string) ([]Change, error) {
 	return nil, fmt.Errorf("No such container: %s", name)
 	return nil, fmt.Errorf("No such container: %s", name)
 }
 }
 
 
-func (srv *Server) Containers(all bool, n int, since, before string) []ApiContainers {
+func (srv *Server) Containers(all bool, n int, since, before string) []APIContainers {
 	var foundBefore bool
 	var foundBefore bool
 	var displayed int
 	var displayed int
-	retContainers := []ApiContainers{}
+	retContainers := []APIContainers{}
 
 
 	for _, container := range srv.runtime.List() {
 	for _, container := range srv.runtime.List() {
 		if !container.State.Running && !all && n == -1 && since == "" && before == "" {
 		if !container.State.Running && !all && n == -1 && since == "" && before == "" {
 			continue
 			continue
 		}
 		}
 		if before != "" {
 		if before != "" {
-			if container.ShortId() == before {
+			if container.ShortID() == before {
 				foundBefore = true
 				foundBefore = true
 				continue
 				continue
 			}
 			}
@@ -256,13 +258,13 @@ func (srv *Server) Containers(all bool, n int, since, before string) []ApiContai
 		if displayed == n {
 		if displayed == n {
 			break
 			break
 		}
 		}
-		if container.ShortId() == since {
+		if container.ShortID() == since {
 			break
 			break
 		}
 		}
 		displayed++
 		displayed++
 
 
-		c := ApiContainers{
-			Id: container.Id,
+		c := APIContainers{
+			ID: container.ID,
 		}
 		}
 		c.Image = srv.runtime.repositories.ImageName(container.Image)
 		c.Image = srv.runtime.repositories.ImageName(container.Image)
 		c.Command = fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
 		c.Command = fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
@@ -283,7 +285,7 @@ func (srv *Server) ContainerCommit(name, repo, tag, author, comment string, conf
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
 	}
 	}
-	return img.ShortId(), err
+	return img.ShortID(), err
 }
 }
 
 
 func (srv *Server) ContainerTag(name, repo, tag string, force bool) error {
 func (srv *Server) ContainerTag(name, repo, tag string, force bool) error {
@@ -304,22 +306,23 @@ func (srv *Server) pullImage(r *registry.Registry, out io.Writer, imgId, endpoin
 	for _, id := range history {
 	for _, id := range history {
 		if !srv.runtime.graph.Exists(id) {
 		if !srv.runtime.graph.Exists(id) {
 			out.Write(sf.FormatStatus("Pulling %s metadata", id))
 			out.Write(sf.FormatStatus("Pulling %s metadata", id))
-			imgJson, err := r.GetRemoteImageJson(id, endpoint, token)
+			imgJSON, err := r.GetRemoteImageJSON(id, endpoint, token)
 			if err != nil {
 			if err != nil {
 				// FIXME: Keep goging in case of error?
 				// FIXME: Keep goging in case of error?
 				return err
 				return err
 			}
 			}
-			img, err := NewImgJson(imgJson)
+			img, err := NewImgJSON(imgJSON)
 			if err != nil {
 			if err != nil {
 				return fmt.Errorf("Failed to parse json: %s", err)
 				return fmt.Errorf("Failed to parse json: %s", err)
 			}
 			}
 
 
 			// Get the layer
 			// Get the layer
 			out.Write(sf.FormatStatus("Pulling %s fs layer", id))
 			out.Write(sf.FormatStatus("Pulling %s fs layer", id))
-			layer, contentLength, err := r.GetRemoteImageLayer(img.Id, endpoint, token)
+			layer, contentLength, err := r.GetRemoteImageLayer(img.ID, endpoint, token)
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
+			defer layer.Close()
 			if err := srv.runtime.graph.Register(utils.ProgressReader(layer, contentLength, out, sf.FormatProgress("Downloading", "%v/%v (%v)"), sf), false, img); err != nil {
 			if err := srv.runtime.graph.Register(utils.ProgressReader(layer, contentLength, out, sf.FormatProgress("Downloading", "%v/%v (%v)"), sf), false, img); err != nil {
 				return err
 				return err
 			}
 			}
@@ -328,8 +331,8 @@ func (srv *Server) pullImage(r *registry.Registry, out io.Writer, imgId, endpoin
 	return nil
 	return nil
 }
 }
 
 
-func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, remote, askedTag string, sf *utils.StreamFormatter) error {
-	out.Write(sf.FormatStatus("Pulling repository %s from %s", remote, auth.IndexServerAddress()))
+func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, local, remote, askedTag string, sf *utils.StreamFormatter) error {
+	out.Write(sf.FormatStatus("Pulling repository %s from %s", local, auth.IndexServerAddress()))
 	repoData, err := r.GetRepositoryData(remote)
 	repoData, err := r.GetRepositoryData(remote)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -354,22 +357,22 @@ func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, remote, a
 		}
 		}
 	} else {
 	} else {
 		// Otherwise, check that the tag exists and use only that one
 		// Otherwise, check that the tag exists and use only that one
-		if id, exists := tagsList[askedTag]; !exists {
-			return fmt.Errorf("Tag %s not found in repositoy %s", askedTag, remote)
-		} else {
-			repoData.ImgList[id].Tag = askedTag
+		id, exists := tagsList[askedTag]
+		if !exists {
+			return fmt.Errorf("Tag %s not found in repositoy %s", askedTag, local)
 		}
 		}
+		repoData.ImgList[id].Tag = askedTag
 	}
 	}
 
 
 	for _, img := range repoData.ImgList {
 	for _, img := range repoData.ImgList {
 		if askedTag != "" && img.Tag != askedTag {
 		if askedTag != "" && img.Tag != askedTag {
-			utils.Debugf("(%s) does not match %s (id: %s), skipping", img.Tag, askedTag, img.Id)
+			utils.Debugf("(%s) does not match %s (id: %s), skipping", img.Tag, askedTag, img.ID)
 			continue
 			continue
 		}
 		}
-		out.Write(sf.FormatStatus("Pulling image %s (%s) from %s", img.Id, img.Tag, remote))
+		out.Write(sf.FormatStatus("Pulling image %s (%s) from %s", img.ID, img.Tag, remote))
 		success := false
 		success := false
 		for _, ep := range repoData.Endpoints {
 		for _, ep := range repoData.Endpoints {
-			if err := srv.pullImage(r, out, img.Id, "https://"+ep+"/v1", repoData.Tokens, sf); err != nil {
+			if err := srv.pullImage(r, out, img.ID, "https://"+ep+"/v1", repoData.Tokens, sf); err != nil {
 				out.Write(sf.FormatStatus("Error while retrieving image for tag: %s (%s); checking next endpoint", askedTag, err))
 				out.Write(sf.FormatStatus("Error while retrieving image for tag: %s (%s); checking next endpoint", askedTag, err))
 				continue
 				continue
 			}
 			}
@@ -384,7 +387,7 @@ func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, remote, a
 		if askedTag != "" && tag != askedTag {
 		if askedTag != "" && tag != askedTag {
 			continue
 			continue
 		}
 		}
-		if err := srv.runtime.repositories.Set(remote, tag, id, true); err != nil {
+		if err := srv.runtime.repositories.Set(local, tag, id, true); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
@@ -404,8 +407,12 @@ func (srv *Server) ImagePull(name, tag, endpoint string, out io.Writer, sf *util
 		}
 		}
 		return nil
 		return nil
 	}
 	}
-
-	if err := srv.pullRepository(r, out, name, tag, sf); err != nil {
+	remote := name
+	parts := strings.Split(name, "/")
+	if len(parts) > 2 {
+		remote = fmt.Sprintf("src/%s", url.QueryEscape(strings.Join(parts, "/")))
+	}
+	if err := srv.pullRepository(r, out, name, remote, tag, sf); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -459,16 +466,16 @@ func (srv *Server) getImageList(localRepo map[string]string) ([]*registry.ImgDat
 			return nil, err
 			return nil, err
 		}
 		}
 		img.WalkHistory(func(img *Image) error {
 		img.WalkHistory(func(img *Image) error {
-			if _, exists := imageSet[img.Id]; exists {
+			if _, exists := imageSet[img.ID]; exists {
 				return nil
 				return nil
 			}
 			}
-			imageSet[img.Id] = struct{}{}
-			checksum, err := srv.getChecksum(img.Id)
+			imageSet[img.ID] = struct{}{}
+			checksum, err := srv.getChecksum(img.ID)
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
 			imgList = append([]*registry.ImgData{{
 			imgList = append([]*registry.ImgData{{
-				Id:       img.Id,
+				ID:       img.ID,
 				Checksum: checksum,
 				Checksum: checksum,
 				Tag:      tag,
 				Tag:      tag,
 			}}, imgList...)
 			}}, imgList...)
@@ -487,7 +494,13 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name stri
 	}
 	}
 	out.Write(sf.FormatStatus("Sending image list"))
 	out.Write(sf.FormatStatus("Sending image list"))
 
 
-	repoData, err := r.PushImageJsonIndex(name, imgList, false)
+	srvName := name
+	parts := strings.Split(name, "/")
+	if len(parts) > 2 {
+		srvName = fmt.Sprintf("src/%s", url.QueryEscape(strings.Join(parts, "/")))
+	}
+
+	repoData, err := r.PushImageJSONIndex(srvName, imgList, false)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -496,22 +509,22 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name stri
 		out.Write(sf.FormatStatus("Pushing repository %s to %s (%d tags)", name, ep, len(localRepo)))
 		out.Write(sf.FormatStatus("Pushing repository %s to %s (%d tags)", name, ep, len(localRepo)))
 		// For each image within the repo, push them
 		// For each image within the repo, push them
 		for _, elem := range imgList {
 		for _, elem := range imgList {
-			if _, exists := repoData.ImgList[elem.Id]; exists {
+			if _, exists := repoData.ImgList[elem.ID]; exists {
 				out.Write(sf.FormatStatus("Image %s already on registry, skipping", name))
 				out.Write(sf.FormatStatus("Image %s already on registry, skipping", name))
 				continue
 				continue
 			}
 			}
-			if err := srv.pushImage(r, out, name, elem.Id, ep, repoData.Tokens, sf); err != nil {
+			if err := srv.pushImage(r, out, name, elem.ID, ep, repoData.Tokens, sf); err != nil {
 				// FIXME: Continue on error?
 				// FIXME: Continue on error?
 				return err
 				return err
 			}
 			}
-			out.Write(sf.FormatStatus("Pushing tags for rev [%s] on {%s}", elem.Id, ep+"/users/"+name+"/"+elem.Tag))
-			if err := r.PushRegistryTag(name, elem.Id, elem.Tag, ep, repoData.Tokens); err != nil {
+			out.Write(sf.FormatStatus("Pushing tags for rev [%s] on {%s}", elem.ID, ep+"/users/"+srvName+"/"+elem.Tag))
+			if err := r.PushRegistryTag(srvName, elem.ID, elem.Tag, ep, repoData.Tokens); err != nil {
 				return err
 				return err
 			}
 			}
 		}
 		}
 	}
 	}
 
 
-	if _, err := r.PushImageJsonIndex(name, imgList, true); err != nil {
+	if _, err := r.PushImageJSONIndex(srvName, imgList, true); err != nil {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil
@@ -531,14 +544,14 @@ func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgId,
 		return err
 		return err
 	}
 	}
 	imgData := &registry.ImgData{
 	imgData := &registry.ImgData{
-		Id:       imgId,
+		ID:       imgId,
 		Checksum: checksum,
 		Checksum: checksum,
 	}
 	}
 
 
 	// Send the json
 	// Send the json
-	if err := r.PushImageJsonRegistry(imgData, jsonRaw, ep, token); err != nil {
+	if err := r.PushImageJSONRegistry(imgData, jsonRaw, ep, token); err != nil {
 		if err == registry.ErrAlreadyExists {
 		if err == registry.ErrAlreadyExists {
-			out.Write(sf.FormatStatus("Image %s already uploaded ; skipping", imgData.Id))
+			out.Write(sf.FormatStatus("Image %s already uploaded ; skipping", imgData.ID))
 			return nil
 			return nil
 		}
 		}
 		return err
 		return err
@@ -571,7 +584,7 @@ func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgId,
 	}
 	}
 
 
 	// Send the layer
 	// Send the layer
-	if err := r.PushImageLayerRegistry(imgData.Id, utils.ProgressReader(layerData, int(layerData.Size), out, sf.FormatProgress("", "%v/%v (%v)"), sf), ep, token); err != nil {
+	if err := r.PushImageLayerRegistry(imgData.ID, utils.ProgressReader(layerData, int(layerData.Size), out, sf.FormatProgress("Pushing", "%v/%v (%v)"), sf), ep, token); err != nil {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil
@@ -595,7 +608,7 @@ func (srv *Server) ImagePush(name, endpoint string, out io.Writer, sf *utils.Str
 		return err
 		return err
 	}
 	}
 	out.Write(sf.FormatStatus("The push refers to an image: [%s]", name))
 	out.Write(sf.FormatStatus("The push refers to an image: [%s]", name))
-	if err := srv.pushImage(r, out, name, img.Id, endpoint, nil, sf); err != nil {
+	if err := srv.pushImage(r, out, name, img.ID, endpoint, nil, sf); err != nil {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil
@@ -632,11 +645,11 @@ func (srv *Server) ImageImport(src, repo, tag string, in io.Reader, out io.Write
 	}
 	}
 	// Optionally register the image at REPO/TAG
 	// Optionally register the image at REPO/TAG
 	if repo != "" {
 	if repo != "" {
-		if err := srv.runtime.repositories.Set(repo, tag, img.Id, true); err != nil {
+		if err := srv.runtime.repositories.Set(repo, tag, img.ID, true); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
-	out.Write(sf.FormatStatus(img.ShortId()))
+	out.Write(sf.FormatStatus(img.ShortID()))
 	return nil
 	return nil
 }
 }
 
 
@@ -657,7 +670,7 @@ func (srv *Server) ContainerCreate(config *Config) (string, error) {
 		}
 		}
 		return "", err
 		return "", err
 	}
 	}
-	return container.ShortId(), nil
+	return container.ShortID(), nil
 }
 }
 
 
 func (srv *Server) ContainerRestart(name string, t int) error {
 func (srv *Server) ContainerRestart(name string, t int) error {
@@ -694,7 +707,7 @@ func (srv *Server) ContainerDestroy(name string, removeVolume bool) error {
 			for volumeId := range volumes {
 			for volumeId := range volumes {
 				// If the requested volu
 				// If the requested volu
 				if c, exists := usedVolumes[volumeId]; exists {
 				if c, exists := usedVolumes[volumeId]; exists {
-					log.Printf("The volume %s is used by the container %s. Impossible to remove it. Skipping.\n", volumeId, c.Id)
+					log.Printf("The volume %s is used by the container %s. Impossible to remove it. Skipping.\n", volumeId, c.ID)
 					continue
 					continue
 				}
 				}
 				if err := srv.runtime.volumes.Delete(volumeId); err != nil {
 				if err := srv.runtime.volumes.Delete(volumeId); err != nil {
@@ -710,9 +723,9 @@ func (srv *Server) ContainerDestroy(name string, removeVolume bool) error {
 
 
 var ErrImageReferenced = errors.New("Image referenced by a repository")
 var ErrImageReferenced = errors.New("Image referenced by a repository")
 
 
-func (srv *Server) deleteImageAndChildren(id string, imgs *[]ApiRmi) error {
+func (srv *Server) deleteImageAndChildren(id string, imgs *[]APIRmi) error {
 	// If the image is referenced by a repo, do not delete
 	// If the image is referenced by a repo, do not delete
-	if len(srv.runtime.repositories.ById()[id]) != 0 {
+	if len(srv.runtime.repositories.ByID()[id]) != 0 {
 		return ErrImageReferenced
 		return ErrImageReferenced
 	}
 	}
 
 
@@ -723,12 +736,11 @@ func (srv *Server) deleteImageAndChildren(id string, imgs *[]ApiRmi) error {
 		return err
 		return err
 	}
 	}
 	for _, img := range byParents[id] {
 	for _, img := range byParents[id] {
-		if err := srv.deleteImageAndChildren(img.Id, imgs); err != nil {
+		if err := srv.deleteImageAndChildren(img.ID, imgs); err != nil {
 			if err != ErrImageReferenced {
 			if err != ErrImageReferenced {
 				return err
 				return err
-			} else {
-				referenced = true
 			}
 			}
+			referenced = true
 		}
 		}
 	}
 	}
 	if referenced {
 	if referenced {
@@ -748,13 +760,13 @@ func (srv *Server) deleteImageAndChildren(id string, imgs *[]ApiRmi) error {
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		*imgs = append(*imgs, ApiRmi{Deleted: utils.TruncateId(id)})
+		*imgs = append(*imgs, APIRmi{Deleted: utils.TruncateID(id)})
 		return nil
 		return nil
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
-func (srv *Server) deleteImageParents(img *Image, imgs *[]ApiRmi) error {
+func (srv *Server) deleteImageParents(img *Image, imgs *[]APIRmi) error {
 	if img.Parent != "" {
 	if img.Parent != "" {
 		parent, err := srv.runtime.graph.Get(img.Parent)
 		parent, err := srv.runtime.graph.Get(img.Parent)
 		if err != nil {
 		if err != nil {
@@ -769,18 +781,18 @@ func (srv *Server) deleteImageParents(img *Image, imgs *[]ApiRmi) error {
 	return nil
 	return nil
 }
 }
 
 
-func (srv *Server) deleteImage(img *Image, repoName, tag string) (*[]ApiRmi, error) {
+func (srv *Server) deleteImage(img *Image, repoName, tag string) (*[]APIRmi, error) {
 	//Untag the current image
 	//Untag the current image
-	var imgs []ApiRmi
+	var imgs []APIRmi
 	tagDeleted, err := srv.runtime.repositories.Delete(repoName, tag)
 	tagDeleted, err := srv.runtime.repositories.Delete(repoName, tag)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 	if tagDeleted {
 	if tagDeleted {
-		imgs = append(imgs, ApiRmi{Untagged: img.ShortId()})
+		imgs = append(imgs, APIRmi{Untagged: img.ShortID()})
 	}
 	}
-	if len(srv.runtime.repositories.ById()[img.Id]) == 0 {
-		if err := srv.deleteImageAndChildren(img.Id, &imgs); err != nil {
+	if len(srv.runtime.repositories.ByID()[img.ID]) == 0 {
+		if err := srv.deleteImageAndChildren(img.ID, &imgs); err != nil {
 			if err != ErrImageReferenced {
 			if err != ErrImageReferenced {
 				return &imgs, err
 				return &imgs, err
 			}
 			}
@@ -793,13 +805,13 @@ func (srv *Server) deleteImage(img *Image, repoName, tag string) (*[]ApiRmi, err
 	return &imgs, nil
 	return &imgs, nil
 }
 }
 
 
-func (srv *Server) ImageDelete(name string, autoPrune bool) (*[]ApiRmi, error) {
+func (srv *Server) ImageDelete(name string, autoPrune bool) (*[]APIRmi, error) {
 	img, err := srv.runtime.repositories.LookupImage(name)
 	img, err := srv.runtime.repositories.LookupImage(name)
 	if err != nil {
 	if err != nil {
 		return nil, fmt.Errorf("No such image: %s", name)
 		return nil, fmt.Errorf("No such image: %s", name)
 	}
 	}
 	if !autoPrune {
 	if !autoPrune {
-		if err := srv.runtime.graph.Delete(img.Id); err != nil {
+		if err := srv.runtime.graph.Delete(img.ID); err != nil {
 			return nil, fmt.Errorf("Error deleting image %s: %s", name, err.Error())
 			return nil, fmt.Errorf("Error deleting image %s: %s", name, err.Error())
 		}
 		}
 		return nil, nil
 		return nil, nil
@@ -829,7 +841,7 @@ func (srv *Server) ImageGetCached(imgId string, config *Config) (*Image, error)
 		if _, exists := imageMap[img.Parent]; !exists {
 		if _, exists := imageMap[img.Parent]; !exists {
 			imageMap[img.Parent] = make(map[string]struct{})
 			imageMap[img.Parent] = make(map[string]struct{})
 		}
 		}
-		imageMap[img.Parent][img.Id] = struct{}{}
+		imageMap[img.Parent][img.ID] = struct{}{}
 	}
 	}
 
 
 	// Loop on the children of the given image and check the config
 	// Loop on the children of the given image and check the config

+ 2 - 2
server_test.go

@@ -65,7 +65,7 @@ func TestCreateRm(t *testing.T) {
 
 
 	srv := &Server{runtime: runtime}
 	srv := &Server{runtime: runtime}
 
 
-	config, _, err := ParseRun([]string{GetTestImage(runtime).Id, "echo test"}, nil)
+	config, _, err := ParseRun([]string{GetTestImage(runtime).ID, "echo test"}, nil)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -98,7 +98,7 @@ func TestCreateStartRestartStopStartKillRm(t *testing.T) {
 
 
 	srv := &Server{runtime: runtime}
 	srv := &Server{runtime: runtime}
 
 
-	config, _, err := ParseRun([]string{GetTestImage(runtime).Id, "/bin/cat"}, nil)
+	config, _, err := ParseRun([]string{GetTestImage(runtime).ID, "/bin/cat"}, nil)
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}

+ 14 - 14
tags.go

@@ -11,7 +11,7 @@ import (
 	"strings"
 	"strings"
 )
 )
 
 
-const DEFAULT_TAG = "latest"
+const DEFAULTTAG = "latest"
 
 
 type TagStore struct {
 type TagStore struct {
 	path         string
 	path         string
@@ -72,7 +72,7 @@ func (store *TagStore) LookupImage(name string) (*Image, error) {
 		// (so we can pass all errors here)
 		// (so we can pass all errors here)
 		repoAndTag := strings.SplitN(name, ":", 2)
 		repoAndTag := strings.SplitN(name, ":", 2)
 		if len(repoAndTag) == 1 {
 		if len(repoAndTag) == 1 {
-			repoAndTag = append(repoAndTag, DEFAULT_TAG)
+			repoAndTag = append(repoAndTag, DEFAULTTAG)
 		}
 		}
 		if i, err := store.GetImage(repoAndTag[0], repoAndTag[1]); err != nil {
 		if i, err := store.GetImage(repoAndTag[0], repoAndTag[1]); err != nil {
 			return nil, err
 			return nil, err
@@ -87,31 +87,31 @@ func (store *TagStore) LookupImage(name string) (*Image, error) {
 
 
 // Return a reverse-lookup table of all the names which refer to each image
 // Return a reverse-lookup table of all the names which refer to each image
 // Eg. {"43b5f19b10584": {"base:latest", "base:v1"}}
 // Eg. {"43b5f19b10584": {"base:latest", "base:v1"}}
-func (store *TagStore) ById() map[string][]string {
-	byId := make(map[string][]string)
+func (store *TagStore) ByID() map[string][]string {
+	byID := make(map[string][]string)
 	for repoName, repository := range store.Repositories {
 	for repoName, repository := range store.Repositories {
 		for tag, id := range repository {
 		for tag, id := range repository {
 			name := repoName + ":" + tag
 			name := repoName + ":" + tag
-			if _, exists := byId[id]; !exists {
-				byId[id] = []string{name}
+			if _, exists := byID[id]; !exists {
+				byID[id] = []string{name}
 			} else {
 			} else {
-				byId[id] = append(byId[id], name)
-				sort.Strings(byId[id])
+				byID[id] = append(byID[id], name)
+				sort.Strings(byID[id])
 			}
 			}
 		}
 		}
 	}
 	}
-	return byId
+	return byID
 }
 }
 
 
 func (store *TagStore) ImageName(id string) string {
 func (store *TagStore) ImageName(id string) string {
-	if names, exists := store.ById()[id]; exists && len(names) > 0 {
+	if names, exists := store.ByID()[id]; exists && len(names) > 0 {
 		return names[0]
 		return names[0]
 	}
 	}
-	return utils.TruncateId(id)
+	return utils.TruncateID(id)
 }
 }
 
 
 func (store *TagStore) DeleteAll(id string) error {
 func (store *TagStore) DeleteAll(id string) error {
-	names, exists := store.ById()[id]
+	names, exists := store.ByID()[id]
 	if !exists || len(names) == 0 {
 	if !exists || len(names) == 0 {
 		return nil
 		return nil
 	}
 	}
@@ -162,7 +162,7 @@ func (store *TagStore) Set(repoName, tag, imageName string, force bool) error {
 		return err
 		return err
 	}
 	}
 	if tag == "" {
 	if tag == "" {
-		tag = DEFAULT_TAG
+		tag = DEFAULTTAG
 	}
 	}
 	if err := validateRepoName(repoName); err != nil {
 	if err := validateRepoName(repoName); err != nil {
 		return err
 		return err
@@ -183,7 +183,7 @@ func (store *TagStore) Set(repoName, tag, imageName string, force bool) error {
 		}
 		}
 		store.Repositories[repoName] = repo
 		store.Repositories[repoName] = repo
 	}
 	}
-	repo[tag] = img.Id
+	repo[tag] = img.ID
 	return store.Save()
 	return store.Save()
 }
 }
 
 

+ 7 - 105
term/term.go

@@ -7,104 +7,6 @@ import (
 	"unsafe"
 	"unsafe"
 )
 )
 
 
-type Termios struct {
-	Iflag  uintptr
-	Oflag  uintptr
-	Cflag  uintptr
-	Lflag  uintptr
-	Cc     [20]byte
-	Ispeed uintptr
-	Ospeed uintptr
-}
-
-const (
-	// Input flags
-	inpck  = 0x010
-	istrip = 0x020
-	icrnl  = 0x100
-	ixon   = 0x200
-
-	// Output flags
-	opost = 0x1
-
-	// Control flags
-	cs8 = 0x300
-
-	// Local flags
-	icanon = 0x100
-	iexten = 0x400
-)
-
-const (
-	HUPCL   = 0x4000
-	ICANON  = 0x100
-	ICRNL   = 0x100
-	IEXTEN  = 0x400
-	BRKINT  = 0x2
-	CFLUSH  = 0xf
-	CLOCAL  = 0x8000
-	CREAD   = 0x800
-	CS5     = 0x0
-	CS6     = 0x100
-	CS7     = 0x200
-	CS8     = 0x300
-	CSIZE   = 0x300
-	CSTART  = 0x11
-	CSTATUS = 0x14
-	CSTOP   = 0x13
-	CSTOPB  = 0x400
-	CSUSP   = 0x1a
-	IGNBRK  = 0x1
-	IGNCR   = 0x80
-	IGNPAR  = 0x4
-	IMAXBEL = 0x2000
-	INLCR   = 0x40
-	INPCK   = 0x10
-	ISIG    = 0x80
-	ISTRIP  = 0x20
-	IUTF8   = 0x4000
-	IXANY   = 0x800
-	IXOFF   = 0x400
-	IXON    = 0x200
-	NOFLSH  = 0x80000000
-	OCRNL   = 0x10
-	OFDEL   = 0x20000
-	OFILL   = 0x80
-	ONLCR   = 0x2
-	ONLRET  = 0x40
-	ONOCR   = 0x20
-	ONOEOT  = 0x8
-	OPOST   = 0x1
-	RENB    = 0x1000
-	PARMRK  = 0x8
-	PARODD  = 0x2000
-
-	TOSTOP   = 0x400000
-	VDISCARD = 0xf
-	VDSUSP   = 0xb
-	VEOF     = 0x0
-	VEOL     = 0x1
-	VEOL2    = 0x2
-	VERASE   = 0x3
-	VINTR    = 0x8
-	VKILL    = 0x5
-	VLNEXT   = 0xe
-	VMIN     = 0x10
-	VQUIT    = 0x9
-	VREPRINT = 0x6
-	VSTART   = 0xc
-	VSTATUS  = 0x12
-	VSTOP    = 0xd
-	VSUSP    = 0xa
-	VT0      = 0x0
-	VT1      = 0x10000
-	VTDLY    = 0x10000
-	VTIME    = 0x11
-	ECHO     = 0x00000008
-
-	PENDIN = 0x20000000
-)
-
 type State struct {
 type State struct {
 	termios Termios
 	termios Termios
 }
 }
@@ -128,21 +30,21 @@ func SetWinsize(fd uintptr, ws *Winsize) error {
 }
 }
 
 
 // IsTerminal returns true if the given file descriptor is a terminal.
 // IsTerminal returns true if the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
+func IsTerminal(fd uintptr) bool {
 	var termios Termios
 	var termios Termios
-	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&termios)))
+	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&termios)))
 	return err == 0
 	return err == 0
 }
 }
 
 
 // Restore restores the terminal connected to the given file descriptor to a
 // Restore restores the terminal connected to the given file descriptor to a
 // previous state.
 // previous state.
-func Restore(fd int, state *State) error {
-	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)))
+func Restore(fd uintptr, state *State) error {
+	_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)))
 	return err
 	return err
 }
 }
 
 
 func SetRawTerminal() (*State, error) {
 func SetRawTerminal() (*State, error) {
-	oldState, err := MakeRaw(int(os.Stdin.Fd()))
+	oldState, err := MakeRaw(os.Stdin.Fd())
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -150,12 +52,12 @@ func SetRawTerminal() (*State, error) {
 	signal.Notify(c, os.Interrupt)
 	signal.Notify(c, os.Interrupt)
 	go func() {
 	go func() {
 		_ = <-c
 		_ = <-c
-		Restore(int(os.Stdin.Fd()), oldState)
+		Restore(os.Stdin.Fd(), oldState)
 		os.Exit(0)
 		os.Exit(0)
 	}()
 	}()
 	return oldState, err
 	return oldState, err
 }
 }
 
 
 func RestoreTerminal(state *State) {
 func RestoreTerminal(state *State) {
-	Restore(int(os.Stdin.Fd()), state)
+	Restore(os.Stdin.Fd(), state)
 }
 }

+ 27 - 5
term/termios_darwin.go

@@ -8,23 +8,45 @@ import (
 const (
 const (
 	getTermios = syscall.TIOCGETA
 	getTermios = syscall.TIOCGETA
 	setTermios = syscall.TIOCSETA
 	setTermios = syscall.TIOCSETA
+
+	ECHO    = 0x00000008
+	ONLCR   = 0x2
+	ISTRIP  = 0x20
+	INLCR   = 0x40
+	ISIG    = 0x80
+	IGNCR   = 0x80
+	ICANON  = 0x100
+	ICRNL   = 0x100
+	IXOFF   = 0x400
+	IXON    = 0x200
 )
 )
 
 
+type Termios struct {
+	Iflag  uint64
+	Oflag  uint64
+	Cflag  uint64
+	Lflag  uint64
+	Cc     [20]byte
+	Ispeed uint64
+	Ospeed uint64
+}
+
 // MakeRaw put the terminal connected to the given file descriptor into raw
 // MakeRaw put the terminal connected to the given file descriptor into raw
 // mode and returns the previous state of the terminal so that it can be
 // mode and returns the previous state of the terminal so that it can be
 // restored.
 // restored.
-func MakeRaw(fd int) (*State, error) {
+func MakeRaw(fd uintptr) (*State, error) {
 	var oldState State
 	var oldState State
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
 	newState := oldState.termios
 	newState := oldState.termios
-	newState.Iflag &^= ISTRIP | INLCR | IGNCR | IXON | IXOFF
+	newState.Iflag &^= (ISTRIP | INLCR | IGNCR | IXON | IXOFF)
 	newState.Iflag |= ICRNL
 	newState.Iflag |= ICRNL
 	newState.Oflag |= ONLCR
 	newState.Oflag |= ONLCR
-	newState.Lflag &^= ECHO | ICANON | ISIG
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
+	newState.Lflag &^= (ECHO | ICANON | ISIG)
+
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
 		return nil, err
 		return nil, err
 	}
 	}
 
 

+ 22 - 36
term/termios_linux.go

@@ -5,54 +5,40 @@ import (
 	"unsafe"
 	"unsafe"
 )
 )
 
 
-// #include <termios.h>
-// #include <sys/ioctl.h>
-/*
-void MakeRaw(int fd) {
-  struct termios t;
-
-  // FIXME: Handle errors?
-  ioctl(fd, TCGETS, &t);
-
-  t.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
-  t.c_oflag &= ~OPOST;
-  t.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
-  t.c_cflag &= ~(CSIZE | PARENB);
-  t.c_cflag |= CS8;
-
-  ioctl(fd, TCSETS, &t);
-}
-*/
-import "C"
-
 const (
 const (
 	getTermios = syscall.TCGETS
 	getTermios = syscall.TCGETS
 	setTermios = syscall.TCSETS
 	setTermios = syscall.TCSETS
 )
 )
 
 
+type Termios struct {
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [20]byte
+	Ispeed uint32
+	Ospeed uint32
+}
+
 // MakeRaw put the terminal connected to the given file descriptor into raw
 // MakeRaw put the terminal connected to the given file descriptor into raw
 // mode and returns the previous state of the terminal so that it can be
 // mode and returns the previous state of the terminal so that it can be
 // restored.
 // restored.
-func MakeRaw(fd int) (*State, error) {
+func MakeRaw(fd uintptr) (*State, error) {
 	var oldState State
 	var oldState State
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TCGETS, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
 		return nil, err
 		return nil, err
 	}
 	}
-	C.MakeRaw(C.int(fd))
-	return &oldState, nil
-
-	// FIXME: post on goland issues this: very same as the C function bug non-working
 
 
-	// newState := oldState.termios
+	newState := oldState.termios
 
 
-	// newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
-	// newState.Oflag &^= OPOST
-	// newState.Lflag &^= (ECHO | syscall.ECHONL | ICANON | ISIG | IEXTEN)
-	// newState.Cflag &^= (CSIZE | syscall.PARENB)
-	// newState.Cflag |= CS8
+	newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON)
+	newState.Oflag &^= syscall.OPOST
+	newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
+	newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
+	newState.Cflag |= syscall.CS8
 
 
-	// if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TCSETS, uintptr(unsafe.Pointer(&newState))); err != 0 {
-	// 	return nil, err
-	// }
-	// return &oldState, nil
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
+		return nil, err
+	}
+	return &oldState, nil
 }
 }

+ 7 - 7
utils/utils.go

@@ -34,7 +34,7 @@ func Go(f func() error) chan error {
 // Request a given URL and return an io.Reader
 // Request a given URL and return an io.Reader
 func Download(url string, stderr io.Writer) (*http.Response, error) {
 func Download(url string, stderr io.Writer) (*http.Response, error) {
 	var resp *http.Response
 	var resp *http.Response
-	var err error = nil
+	var err error
 	if resp, err = http.Get(url); err != nil {
 	if resp, err = http.Get(url); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -349,11 +349,11 @@ func (idx *TruncIndex) Get(s string) (string, error) {
 	return string(idx.bytes[before:after]), err
 	return string(idx.bytes[before:after]), err
 }
 }
 
 
-// TruncateId returns a shorthand version of a string identifier for convenience.
+// TruncateID returns a shorthand version of a string identifier for convenience.
 // A collision with other shorthands is very unlikely, but possible.
 // A collision with other shorthands is very unlikely, but possible.
 // In case of a collision a lookup with TruncIndex.Get() will fail, and the caller
 // In case of a collision a lookup with TruncIndex.Get() will fail, and the caller
 // will need to use a langer prefix, or the full-length Id.
 // will need to use a langer prefix, or the full-length Id.
-func TruncateId(id string) string {
+func TruncateID(id string) string {
 	shortLen := 12
 	shortLen := 12
 	if len(id) < shortLen {
 	if len(id) < shortLen {
 		shortLen = len(id)
 		shortLen = len(id)
@@ -566,7 +566,7 @@ func NewWriteFlusher(w io.Writer) *WriteFlusher {
 	return &WriteFlusher{w: w, flusher: flusher}
 	return &WriteFlusher{w: w, flusher: flusher}
 }
 }
 
 
-type JsonMessage struct {
+type JSONMessage struct {
 	Status   string `json:"status,omitempty"`
 	Status   string `json:"status,omitempty"`
 	Progress string `json:"progress,omitempty"`
 	Progress string `json:"progress,omitempty"`
 	Error    string `json:"error,omitempty"`
 	Error    string `json:"error,omitempty"`
@@ -585,7 +585,7 @@ func (sf *StreamFormatter) FormatStatus(format string, a ...interface{}) []byte
 	sf.used = true
 	sf.used = true
 	str := fmt.Sprintf(format, a...)
 	str := fmt.Sprintf(format, a...)
 	if sf.json {
 	if sf.json {
-		b, err := json.Marshal(&JsonMessage{Status:str});
+		b, err := json.Marshal(&JSONMessage{Status:str});
 		if err != nil {
 		if err != nil {
 			return sf.FormatError(err)
 			return sf.FormatError(err)
 		}
 		}
@@ -597,7 +597,7 @@ func (sf *StreamFormatter) FormatStatus(format string, a ...interface{}) []byte
 func (sf *StreamFormatter) FormatError(err error) []byte {
 func (sf *StreamFormatter) FormatError(err error) []byte {
 	sf.used = true
 	sf.used = true
 	if sf.json {
 	if sf.json {
-		if b, err := json.Marshal(&JsonMessage{Error:err.Error()}); err == nil {
+		if b, err := json.Marshal(&JSONMessage{Error:err.Error()}); err == nil {
 			return b
 			return b
 		}
 		}
 		return []byte("{\"error\":\"format error\"}")
 		return []byte("{\"error\":\"format error\"}")
@@ -608,7 +608,7 @@ func (sf *StreamFormatter) FormatError(err error) []byte {
 func (sf *StreamFormatter) FormatProgress(action, str string) []byte {
 func (sf *StreamFormatter) FormatProgress(action, str string) []byte {
 	sf.used = true
 	sf.used = true
 	if sf.json {
 	if sf.json {
-		b, err := json.Marshal(&JsonMessage{Progress:str})
+		b, err := json.Marshal(&JSONMessage{Status: action, Progress:str})
 		if err != nil {
 		if err != nil {
                         return nil
                         return nil
                 }
                 }