Browse Source

skeleton remote API, only version working (wip)

Victor Vieux 12 năm trước cách đây
mục cha
commit
c0d5d5969b
5 tập tin đã thay đổi với 128 bổ sung72 xóa
  1. 18 51
      api.go
  2. 7 0
      api_params.go
  3. 0 15
      commands.go
  4. 95 0
      commands2.go
  5. 8 6
      docker/docker.go

+ 18 - 51
api.go

@@ -1,63 +1,30 @@
 package docker
 
 import (
+	"encoding/json"
+	"log"
 	"github.com/gorilla/mux"
 	"net/http"
-	_"encoding/json"
 )
 
+func ListenAndServe(addr string, runtime *Runtime) error {
+	r := mux.NewRouter()
+	log.Printf("Listening for HTTP on %s\n", addr)
 
-type RestEndpoint struct {
-	*mux.Router
-	runtime	*Runtime
-}
-
-func NewRestEndpoint(runtime *Runtime) *RestEndpoint {
-	endpoint := &RestEndpoint{
-		Router:	mux.NewRouter(),
-		runtime: runtime,
-	}
-	endpoint.Path("/images").Methods("GET").HandlerFunc(endpoint.GetImages)
-	endpoint.Path("/images").Methods("POST").HandlerFunc(endpoint.PostImages)
-	endpoint.Path("/images/{id}").Methods("GET").HandlerFunc(endpoint.GetImage)
-	endpoint.Path("/images/{id}").Methods("DELETE").HandlerFunc(endpoint.DeleteImage)
-	endpoint.Path("/containers").Methods("GET").HandlerFunc(endpoint.GetContainers)
-	endpoint.Path("/containers").Methods("POST").HandlerFunc(endpoint.PostContainers)
-	endpoint.Path("/containers/{id}").Methods("GET").HandlerFunc(endpoint.GetContainer)
-	endpoint.Path("/containers/{id}").Methods("DELETE").HandlerFunc(endpoint.DeleteContainer)
-	return endpoint
-}
+	r.Path("/version").Methods("GET", "POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		m := VersionOut{VERSION, GIT_COMMIT, NO_MEMORY_LIMIT}
+		b, err := json.Marshal(m)
+		if err != nil {
+			w.WriteHeader(500)
+		} else {
+			w.Write(b)
+		}
+	})
 
-func (ep *RestEndpoint) GetImages(w http.ResponseWriter, r *http.Response) {
+	r.Path("/images").Methods("GET", "POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		//TODO use runtime
+	})
 
+	return http.ListenAndServe(addr, r)
 }
 
-func (ep *RestEndpoint) PostImages(w http.ResponseWriter, r *http.Response) {
-
-}
-
-func (ep *RestEndpoint) GetImage(w http.ResponseWriter, r *http.Response) {
-
-}
-
-func (ep *RestEndpoint) DeleteImage(w http.ResponseWriter, r *http.Response) {
-
-}
-
-func (ep *RestEndpoint) GetContainers(w http.ResponseWriter, r *http.Response) {
-
-}
-
-func (ep *RestEndpoint) PostContainers(w http.ResponseWriter, r *http.Response) {
-
-}
-
-func (ep *RestEndpoint) GetContainer(w http.ResponseWriter, r *http.Response) {
-
-}
-
-func (ep *RestEndpoint) DeleteContainer(w http.ResponseWriter, r *http.Response) {
-
-}
-
-

+ 7 - 0
api_params.go

@@ -0,0 +1,7 @@
+package docker
+
+type VersionOut struct {
+        Version string
+        GitCommit string
+        MemoryLimitDisabled bool
+}

+ 0 - 15
commands.go

@@ -976,22 +976,7 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout rcli.DockerConn, args ...s
 	return nil
 }
 
-func NewServer() (*Server, error) {
-	if runtime.GOARCH != "amd64" {
-		log.Fatalf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH)
-	}
-	runtime, err := NewRuntime()
-	if err != nil {
-		return nil, err
-	}
-	srv := &Server{
-		runtime: runtime,
-		restEndpoint: NewRestEndpoint(runtime),
-	}
-	return srv, nil
-}
 
 type Server struct {
 	runtime *Runtime
-	restEndpoint *RestEndpoint
 }

+ 95 - 0
commands2.go

@@ -0,0 +1,95 @@
+package docker
+
+import (
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"encoding/json"
+)
+
+func ParseCommands(args []string) error {
+	
+	cmds := map[string]func(args []string) error {
+		"version":cmdVersion,
+	}
+
+	if len(args) > 0 {
+		cmd, exists :=  cmds[args[0]]
+		if !exists {
+			//TODO display commend not found
+			return cmdHelp(args)
+		}
+		return cmd(args)
+	}
+	return cmdHelp(args)
+}
+
+func cmdHelp(args []string) error {
+	help := "Usage: docker COMMAND [arg...]\n\nA self-sufficient runtime for linux containers.\n\nCommands:\n"
+	for _, cmd := range [][]string{
+//		{"attach", "Attach to a running container"},
+//		{"commit", "Create a new image from a container's changes"},
+//		{"diff", "Inspect changes on a container's filesystem"},
+//		{"export", "Stream the contents of a container as a tar archive"},
+//		{"history", "Show the history of an image"},
+//		{"images", "List images"},
+//		{"import", "Create a new filesystem image from the contents of a tarball"},
+//		{"info", "Display system-wide information"},
+//		{"inspect", "Return low-level information on a container"},
+//		{"kill", "Kill a running container"},
+//		{"login", "Register or Login to the docker registry server"},
+//		{"logs", "Fetch the logs of a container"},
+//		{"port", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT"},
+//		{"ps", "List containers"},
+//		{"pull", "Pull an image or a repository from the docker registry server"},
+//		{"push", "Push an image or a repository to the docker registry server"},
+//		{"restart", "Restart a running container"},
+//		{"rm", "Remove a container"},
+//		{"rmi", "Remove an image"},
+//		{"run", "Run a command in a new container"},
+//		{"start", "Start a stopped container"},
+//		{"stop", "Stop a running container"},
+//		{"tag", "Tag an image into a repository"},
+		{"version", "Show the docker version information"},
+//		{"wait", "Block until a container stops, then print its exit code"},
+	} {
+		help += fmt.Sprintf("    %-10.10s%s\n", cmd[0], cmd[1])
+	}
+	fmt.Println(help)
+	return nil
+}
+
+func cmdVersion(args []string) error {
+	body, err := apiCall("version")
+	if err != nil {
+		return err
+	}
+
+	var out VersionOut
+	err = json.Unmarshal(body, &out)
+	if err != nil {
+                return err
+        }
+	fmt.Println("Version:", out.Version)
+        fmt.Println("Git Commit:", out.GitCommit)
+        if out.MemoryLimitDisabled {
+                fmt.Println("Memory limit disabled")
+        }
+
+	return nil
+}
+
+func apiCall(path string) ([]byte, error) {
+	resp, err := http.Get("http://0.0.0.0:4243/" + path) 
+        if err != nil {
+                return nil,err
+        }
+	//TODO check status code
+        defer resp.Body.Close()
+        body, err := ioutil.ReadAll(resp.Body)
+        if err != nil {
+                return nil, err
+        }
+	return body, nil
+
+}

+ 8 - 6
docker/docker.go

@@ -10,6 +10,7 @@ import (
 	"log"
 	"os"
 	"os/signal"
+	"runtime"
 	"syscall"
 )
 
@@ -52,7 +53,7 @@ func main() {
 			log.Fatal(err)
 		}
 	} else {
-		if err := runCommand(flag.Args()); err != nil {
+		if err := docker.ParseCommands(flag.Args()); err != nil {
 			log.Fatal(err)
 		}
 	}
@@ -95,14 +96,15 @@ func daemon(pidfile string) error {
 		os.Exit(0)
 	}()
 
-	service, err := docker.NewServer()
-	if err != nil {
-		return err
+	if runtime.GOARCH != "amd64" {
+		log.Fatalf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH)
 	}
-	if err := http.ListenAndServe("0.0.0.0:4243", service.restEndpoint); err != nil {
+	runtime, err := docker.NewRuntime()
+	if err != nil {
 		return err
 	}
-	return rcli.ListenAndServe("tcp", "127.0.0.1:4242", service)
+
+	return docker.ListenAndServe("0.0.0.0:4243", runtime)
 }
 
 func runCommand(args []string) error {