diff --git a/api.go b/api.go index fe40fbe016..5e1a6d7011 100644 --- a/api.go +++ b/api.go @@ -13,7 +13,7 @@ import ( "strings" ) -const APIVERSION = 1.1 +const APIVERSION = 1.2 func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) { conn, _, err := w.(http.Hijacker).Hijack() @@ -71,8 +71,10 @@ func getBoolParam(value string) (bool, error) { } func getAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - // FIXME: Handle multiple login at once - // FIXME: return specific error code if config file missing? + if version > 1.1 { + w.WriteHeader(http.StatusNotFound) + return nil + } authConfig, err := auth.LoadConfig(srv.runtime.root) if err != nil { if err != auth.ErrConfigFileMissing { @@ -89,29 +91,34 @@ func getAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Reques } func postAuth(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - // FIXME: Handle multiple login at once - config := &auth.AuthConfig{} - if err := json.NewDecoder(r.Body).Decode(config); err != nil { + authConfig := &auth.AuthConfig{} + err := json.NewDecoder(r.Body).Decode(authConfig) + if err != nil { return err } - - authConfig, err := auth.LoadConfig(srv.runtime.root) - if err != nil { - if err != auth.ErrConfigFileMissing { + status := "" + if version > 1.1 { + status, err = auth.Login(authConfig, false) + if err != nil { return err } - authConfig = &auth.AuthConfig{} - } - if config.Username == authConfig.Username { - config.Password = authConfig.Password - } + } else { + localAuthConfig, err := auth.LoadConfig(srv.runtime.root) + if err != nil { + if err != auth.ErrConfigFileMissing { + return err + } + } + if authConfig.Username == localAuthConfig.Username { + authConfig.Password = localAuthConfig.Password + } - newAuthConfig := auth.NewAuthConfig(config.Username, config.Password, config.Email, srv.runtime.root) - status, err := auth.Login(newAuthConfig) - if err != nil { - return err + newAuthConfig := auth.NewAuthConfig(authConfig.Username, authConfig.Password, authConfig.Email, srv.runtime.root) + status, err = auth.Login(newAuthConfig, true) + if err != nil { + return err + } } - if status != "" { b, err := json.Marshal(&APIAuth{Status: status}) if err != nil { @@ -322,7 +329,7 @@ func postImagesCreate(srv *Server, version float64, w http.ResponseWriter, r *ht sf := utils.NewStreamFormatter(version > 1.0) if image != "" { //pull registry := r.Form.Get("registry") - if err := srv.ImagePull(image, tag, registry, w, sf); err != nil { + if err := srv.ImagePull(image, tag, registry, w, sf, &auth.AuthConfig{}); err != nil { if sf.Used() { w.Write(sf.FormatError(err)) return nil @@ -390,6 +397,18 @@ func postImagesInsert(srv *Server, version float64, w http.ResponseWriter, r *ht } func postImagesPush(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { + authConfig := &auth.AuthConfig{} + if version > 1.1 { + if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil { + return err + } + } else { + localAuthConfig, err := auth.LoadConfig(srv.runtime.root) + if err != nil && err != auth.ErrConfigFileMissing { + return err + } + authConfig = localAuthConfig + } if err := parseForm(r); err != nil { return err } @@ -403,7 +422,7 @@ func postImagesPush(srv *Server, version float64, w http.ResponseWriter, r *http w.Header().Set("Content-Type", "application/json") } sf := utils.NewStreamFormatter(version > 1.0) - if err := srv.ImagePush(name, registry, w, sf); err != nil { + if err := srv.ImagePush(name, registry, w, sf, authConfig); err != nil { if sf.Used() { w.Write(sf.FormatError(err)) return nil @@ -490,7 +509,7 @@ func deleteImages(srv *Server, version float64, w http.ResponseWriter, r *http.R return fmt.Errorf("Missing parameter") } name := vars["name"] - imgs, err := srv.ImageDelete(name, version > 1.0) + imgs, err := srv.ImageDelete(name, version > 1.1) if err != nil { return err } diff --git a/api_test.go b/api_test.go index 26fd229379..40b31d4961 100644 --- a/api_test.go +++ b/api_test.go @@ -6,7 +6,6 @@ import ( "bytes" "encoding/json" "github.com/dotcloud/docker/auth" - "github.com/dotcloud/docker/registry" "github.com/dotcloud/docker/utils" "io" "net" @@ -18,7 +17,7 @@ import ( "time" ) -func TestGetAuth(t *testing.T) { +func TestPostAuth(t *testing.T) { runtime, err := newTestRuntime() if err != nil { t.Fatal(err) @@ -54,12 +53,6 @@ func TestGetAuth(t *testing.T) { if r.Code != http.StatusOK && r.Code != 0 { t.Fatalf("%d OK or 0 expected, received %d\n", http.StatusOK, r.Code) } - - newAuthConfig := registry.NewRegistry(runtime.root).GetAuthConfig(false) - if newAuthConfig.Username != authConfig.Username || - newAuthConfig.Email != authConfig.Email { - t.Fatalf("The auth configuration hasn't been set correctly") - } } func TestGetVersion(t *testing.T) { @@ -494,40 +487,6 @@ func TestGetContainersByName(t *testing.T) { } } -func TestPostAuth(t *testing.T) { - runtime, err := newTestRuntime() - if err != nil { - t.Fatal(err) - } - defer nuke(runtime) - - srv := &Server{ - runtime: runtime, - } - - config := &auth.AuthConfig{ - Username: "utest", - Email: "utest@yopmail.com", - } - - authStr := auth.EncodeAuth(config) - auth.SaveConfig(runtime.root, authStr, config.Email) - - r := httptest.NewRecorder() - if err := getAuth(srv, APIVERSION, r, nil, nil); err != nil { - t.Fatal(err) - } - - authConfig := &auth.AuthConfig{} - if err := json.Unmarshal(r.Body.Bytes(), authConfig); err != nil { - t.Fatal(err) - } - - if authConfig.Username != config.Username || authConfig.Email != config.Email { - t.Errorf("The retrieve auth mismatch with the one set.") - } -} - func TestPostCommit(t *testing.T) { runtime, err := newTestRuntime() if err != nil { diff --git a/auth/auth.go b/auth/auth.go index 72cf36efa5..b7ad73b9ed 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -48,7 +48,7 @@ func IndexServerAddress() string { } // create a base64 encoded auth string to store in config -func EncodeAuth(authConfig *AuthConfig) string { +func encodeAuth(authConfig *AuthConfig) string { authStr := authConfig.Username + ":" + authConfig.Password msg := []byte(authStr) encoded := make([]byte, base64.StdEncoding.EncodedLen(len(msg))) @@ -57,7 +57,7 @@ func EncodeAuth(authConfig *AuthConfig) string { } // decode the auth string -func DecodeAuth(authStr string) (*AuthConfig, error) { +func decodeAuth(authStr string) (*AuthConfig, error) { decLen := base64.StdEncoding.DecodedLen(len(authStr)) decoded := make([]byte, decLen) authByte := []byte(authStr) @@ -82,7 +82,7 @@ func DecodeAuth(authStr string) (*AuthConfig, error) { func LoadConfig(rootPath string) (*AuthConfig, error) { confFile := path.Join(rootPath, CONFIGFILE) if _, err := os.Stat(confFile); err != nil { - return nil, ErrConfigFileMissing + return &AuthConfig{rootPath:rootPath}, ErrConfigFileMissing } b, err := ioutil.ReadFile(confFile) if err != nil { @@ -94,7 +94,7 @@ func LoadConfig(rootPath string) (*AuthConfig, error) { } origAuth := strings.Split(arr[0], " = ") origEmail := strings.Split(arr[1], " = ") - authConfig, err := DecodeAuth(origAuth[1]) + authConfig, err := decodeAuth(origAuth[1]) if err != nil { return nil, err } @@ -104,13 +104,13 @@ func LoadConfig(rootPath string) (*AuthConfig, error) { } // save the auth config -func SaveConfig(rootPath, authStr string, email string) error { - confFile := path.Join(rootPath, CONFIGFILE) - if len(email) == 0 { +func SaveConfig(authConfig *AuthConfig) error { + confFile := path.Join(authConfig.rootPath, CONFIGFILE) + if len(authConfig.Email) == 0 { os.Remove(confFile) return nil } - lines := "auth = " + authStr + "\n" + "email = " + email + "\n" + lines := "auth = " + encodeAuth(authConfig) + "\n" + "email = " + authConfig.Email + "\n" b := []byte(lines) err := ioutil.WriteFile(confFile, b, 0600) if err != nil { @@ -120,7 +120,7 @@ func SaveConfig(rootPath, authStr string, email string) error { } // try to register/login to the registry server -func Login(authConfig *AuthConfig) (string, error) { +func Login(authConfig *AuthConfig, store bool) (string, error) { storeConfig := false client := &http.Client{} reqStatusCode := 0 @@ -168,8 +168,10 @@ func Login(authConfig *AuthConfig) (string, error) { status = "Login Succeeded\n" storeConfig = true } else if resp.StatusCode == 401 { - if err := SaveConfig(authConfig.rootPath, "", ""); err != nil { - return "", err + if store { + if err := SaveConfig(authConfig); err != nil { + return "", err + } } return "", fmt.Errorf("Wrong login/password, please try again") } else { @@ -182,9 +184,8 @@ func Login(authConfig *AuthConfig) (string, error) { } else { return "", fmt.Errorf("Unexpected status code [%d] : %s", reqStatusCode, reqBody) } - if storeConfig { - authStr := EncodeAuth(authConfig) - if err := SaveConfig(authConfig.rootPath, authStr, authConfig.Email); err != nil { + if storeConfig && store { + if err := SaveConfig(authConfig); err != nil { return "", err } } diff --git a/buildfile.go b/buildfile.go index e0c5f794a8..e9c6b6cfaf 100644 --- a/buildfile.go +++ b/buildfile.go @@ -61,7 +61,7 @@ func (b *buildFile) CmdFrom(name string) error { remote = name } - if err := b.srv.ImagePull(remote, tag, "", b.out, utils.NewStreamFormatter(false)); err != nil { + if err := b.srv.ImagePull(remote, tag, "", b.out, utils.NewStreamFormatter(false), nil); err != nil { return err } diff --git a/commands.go b/commands.go index eacbd388f0..6748fb0138 100644 --- a/commands.go +++ b/commands.go @@ -287,27 +287,16 @@ func (cli *DockerCli) CmdLogin(args ...string) error { return nil } - body, _, err := cli.call("GET", "/auth", nil) - if err != nil { - return err - } - - var out auth.AuthConfig - err = json.Unmarshal(body, &out) - if err != nil { - return err - } - var username string var password string var email string - fmt.Print("Username (", out.Username, "): ") + fmt.Print("Username (", cli.authConfig.Username, "): ") username = readAndEchoString(os.Stdin, os.Stdout) if username == "" { - username = out.Username + username = cli.authConfig.Username } - if username != out.Username { + if username != cli.authConfig.Username { fmt.Print("Password: ") password = readString(os.Stdin, os.Stdout) @@ -315,20 +304,21 @@ func (cli *DockerCli) CmdLogin(args ...string) error { return fmt.Errorf("Error : Password Required") } - fmt.Print("Email (", out.Email, "): ") + fmt.Print("Email (", cli.authConfig.Email, "): ") email = readAndEchoString(os.Stdin, os.Stdout) if email == "" { - email = out.Email + email = cli.authConfig.Email } } else { - email = out.Email + email = cli.authConfig.Email } + term.RestoreTerminal(oldState) - out.Username = username - out.Password = password - out.Email = email + cli.authConfig.Username = username + cli.authConfig.Password = password + cli.authConfig.Email = email - body, _, err = cli.call("POST", "/auth", out) + body, _, err := cli.call("POST", "/auth", cli.authConfig) if err != nil { return err } @@ -336,10 +326,11 @@ func (cli *DockerCli) CmdLogin(args ...string) error { var out2 APIAuth err = json.Unmarshal(body, &out2) if err != nil { + auth.LoadConfig(os.Getenv("HOME")) return err } + auth.SaveConfig(cli.authConfig) if out2.Status != "" { - term.RestoreTerminal(oldState) fmt.Print(out2.Status) } return nil @@ -724,18 +715,22 @@ func (cli *DockerCli) CmdPush(args ...string) error { return nil } - username, err := cli.checkIfLogged(*registry == "", "push") - if err != nil { + if err := cli.checkIfLogged(*registry == "", "push"); err != nil { return err } if len(strings.SplitN(name, "/", 2)) == 1 { - return fmt.Errorf("Impossible to push a \"root\" repository. Please rename your repository in / (ex: %s/%s)", username, name) + return fmt.Errorf("Impossible to push a \"root\" repository. Please rename your repository in / (ex: %s/%s)", cli.authConfig.Username, name) + } + + buf, err := json.Marshal(cli.authConfig) + if err != nil { + return err } v := url.Values{} v.Set("registry", *registry) - if err := cli.stream("POST", "/images/"+name+"/push?"+v.Encode(), nil, os.Stdout); err != nil { + if err := cli.stream("POST", "/images/"+name+"/push?"+v.Encode(), bytes.NewBuffer(buf), os.Stdout); err != nil { return err } return nil @@ -1296,38 +1291,17 @@ func (cli *DockerCli) CmdRun(args ...string) error { return nil } -func (cli *DockerCli) checkIfLogged(condition bool, action string) (string, error) { - body, _, err := cli.call("GET", "/auth", nil) - if err != nil { - return "", err - } - - var out auth.AuthConfig - err = json.Unmarshal(body, &out) - if err != nil { - return "", err - } - +func (cli *DockerCli) checkIfLogged(condition bool, action string) error { // If condition AND the login failed - if condition && out.Username == "" { + if condition && cli.authConfig.Username == "" { if err := cli.CmdLogin(""); err != nil { - return "", err + return err } - - body, _, err = cli.call("GET", "/auth", nil) - if err != nil { - return "", err - } - err = json.Unmarshal(body, &out) - if err != nil { - return "", err - } - - if out.Username == "" { - return "", fmt.Errorf("Please login prior to %s. ('docker login')", action) + if cli.authConfig.Username == "" { + return fmt.Errorf("Please login prior to %s. ('docker login')", action) } } - return out.Username, nil + return nil } func (cli *DockerCli) call(method, path string, data interface{}) ([]byte, int, error) { @@ -1514,10 +1488,12 @@ func Subcmd(name, signature, description string) *flag.FlagSet { } func NewDockerCli(addr string, port int) *DockerCli { - return &DockerCli{addr, port} + authConfig, _ := auth.LoadConfig(os.Getenv("HOME")) + return &DockerCli{addr, port, authConfig} } type DockerCli struct { - host string - port int + host string + port int + authConfig *auth.AuthConfig } diff --git a/docs/sources/api/docker_remote_api.rst b/docs/sources/api/docker_remote_api.rst index 95abd8339d..824bfa4657 100644 --- a/docs/sources/api/docker_remote_api.rst +++ b/docs/sources/api/docker_remote_api.rst @@ -14,719 +14,44 @@ Docker Remote API - The Remote API is replacing rcli - Default port in the docker deamon is 4243 - The API tends to be REST, but for some complex commands, like attach or pull, the HTTP connection is hijacked to transport stdout stdin and stderr +- Since API version 1.2, the auth configuration is now handled client side, so the client has to send the authConfig as POST in /images/(name)/push -2. Version -========== +2. Versions +=========== -The current verson of the API is 1.1 -Calling /images//insert is the same as calling /v1.1/images//insert +The current verson of the API is 1.2 +Calling /images//insert is the same as calling /v1.2/images//insert You can still call an old version of the api using /v1.0/images//insert -3. Endpoints -============ - -3.1 Containers --------------- - -List containers -*************** - -.. http:get:: /containers/json - - List containers - - **Example request**: - - .. sourcecode:: http - - GET /containers/json?all=1&before=8dfafdbc3a40 HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - [ - { - "Id": "8dfafdbc3a40", - "Image": "base:latest", - "Command": "echo 1", - "Created": 1367854155, - "Status": "Exit 0" - }, - { - "Id": "9cd87474be90", - "Image": "base:latest", - "Command": "echo 222222", - "Created": 1367854155, - "Status": "Exit 0" - }, - { - "Id": "3176a2479c92", - "Image": "base:latest", - "Command": "echo 3333333333333333", - "Created": 1367854154, - "Status": "Exit 0" - }, - { - "Id": "4cb07b47f9fb", - "Image": "base:latest", - "Command": "echo 444444444444444444444444444444444", - "Created": 1367854152, - "Status": "Exit 0" - } - ] - - :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default - :query limit: Show ``limit`` last created containers, include non-running ones. - :query since: Show only containers created since Id, include non-running ones. - :query before: Show only containers created before Id, include non-running ones. - :statuscode 200: no error - :statuscode 400: bad parameter - :statuscode 500: server error - - -Create a container -****************** - -.. http:post:: /containers/create - - Create a container - - **Example request**: - - .. sourcecode:: http - - POST /containers/create HTTP/1.1 - Content-Type: application/json - - { - "Hostname":"", - "User":"", - "Memory":0, - "MemorySwap":0, - "AttachStdin":false, - "AttachStdout":true, - "AttachStderr":true, - "PortSpecs":null, - "Tty":false, - "OpenStdin":false, - "StdinOnce":false, - "Env":null, - "Cmd":[ - "date" - ], - "Dns":null, - "Image":"base", - "Volumes":{}, - "VolumesFrom":"" - } - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 201 OK - Content-Type: application/json - - { - "Id":"e90e34656806" - "Warnings":[] - } - - :jsonparam config: the container's configuration - :statuscode 201: no error - :statuscode 404: no such container - :statuscode 406: impossible to attach (container not running) - :statuscode 500: server error - - -Inspect a container -******************* - -.. http:get:: /containers/(id)/json - - Return low-level information on the container ``id`` - - **Example request**: - - .. sourcecode:: http - - GET /containers/4fa6e0f0c678/json HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - { - "Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2", - "Created": "2013-05-07T14:51:42.041847+02:00", - "Path": "date", - "Args": [], - "Config": { - "Hostname": "4fa6e0f0c678", - "User": "", - "Memory": 0, - "MemorySwap": 0, - "AttachStdin": false, - "AttachStdout": true, - "AttachStderr": true, - "PortSpecs": null, - "Tty": false, - "OpenStdin": false, - "StdinOnce": false, - "Env": null, - "Cmd": [ - "date" - ], - "Dns": null, - "Image": "base", - "Volumes": {}, - "VolumesFrom": "" - }, - "State": { - "Running": false, - "Pid": 0, - "ExitCode": 0, - "StartedAt": "2013-05-07T14:51:42.087658+02:01360", - "Ghost": false - }, - "Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", - "NetworkSettings": { - "IpAddress": "", - "IpPrefixLen": 0, - "Gateway": "", - "Bridge": "", - "PortMapping": null - }, - "SysInitPath": "/home/kitty/go/src/github.com/dotcloud/docker/bin/docker", - "ResolvConfPath": "/etc/resolv.conf", - "Volumes": {} - } - - :statuscode 200: no error - :statuscode 404: no such container - :statuscode 500: server error - - -Inspect changes on a container's filesystem -******************************************* - -.. http:get:: /containers/(id)/changes - - Inspect changes on container ``id`` 's filesystem - - **Example request**: - - .. sourcecode:: http - - GET /containers/4fa6e0f0c678/changes HTTP/1.1 - - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - [ - { - "Path":"/dev", - "Kind":0 - }, - { - "Path":"/dev/kmsg", - "Kind":1 - }, - { - "Path":"/test", - "Kind":1 - } - ] - - :statuscode 200: no error - :statuscode 404: no such container - :statuscode 500: server error - - -Export a container -****************** - -.. http:get:: /containers/(id)/export - - Export the contents of container ``id`` - - **Example request**: - - .. sourcecode:: http - - GET /containers/4fa6e0f0c678/export HTTP/1.1 - - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/octet-stream - - {{ STREAM }} - - :statuscode 200: no error - :statuscode 404: no such container - :statuscode 500: server error - - -Start a container -***************** - -.. http:post:: /containers/(id)/start - - Start the container ``id`` - - **Example request**: - - .. sourcecode:: http - - POST /containers/e90e34656806/start HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - - :statuscode 200: no error - :statuscode 404: no such container - :statuscode 500: server error - - -Stop a contaier -*************** - -.. http:post:: /containers/(id)/stop - - Stop the container ``id`` - - **Example request**: - - .. sourcecode:: http - - POST /containers/e90e34656806/stop?t=5 HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 204 OK - - :query t: number of seconds to wait before killing the container - :statuscode 204: no error - :statuscode 404: no such container - :statuscode 500: server error - - -Restart a container -******************* - -.. http:post:: /containers/(id)/restart - - Restart the container ``id`` - - **Example request**: - - .. sourcecode:: http - - POST /containers/e90e34656806/restart?t=5 HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 204 OK - - :query t: number of seconds to wait before killing the container - :statuscode 204: no error - :statuscode 404: no such container - :statuscode 500: server error - - -Kill a container -**************** - -.. http:post:: /containers/(id)/kill - - Kill the container ``id`` - - **Example request**: - - .. sourcecode:: http - - POST /containers/e90e34656806/kill HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 204 OK - - :statuscode 204: no error - :statuscode 404: no such container - :statuscode 500: server error - - -Attach to a container -********************* - -.. http:post:: /containers/(id)/attach - - Attach to the container ``id`` - - **Example request**: - - .. sourcecode:: http - - POST /containers/16253994b7c4/attach?logs=1&stream=0&stdout=1 HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/vnd.docker.raw-stream - - {{ STREAM }} - - :query logs: 1/True/true or 0/False/false, return logs. Default false - :query stream: 1/True/true or 0/False/false, return stream. Default false - :query stdin: 1/True/true or 0/False/false, if stream=true, attach to stdin. Default false - :query stdout: 1/True/true or 0/False/false, if logs=true, return stdout log, if stream=true, attach to stdout. Default false - :query stderr: 1/True/true or 0/False/false, if logs=true, return stderr log, if stream=true, attach to stderr. Default false - :statuscode 200: no error - :statuscode 400: bad parameter - :statuscode 404: no such container - :statuscode 500: server error - - -Wait a container -**************** - -.. http:post:: /containers/(id)/wait - - Block until container ``id`` stops, then returns the exit code - - **Example request**: - - .. sourcecode:: http - - POST /containers/16253994b7c4/wait HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - {"StatusCode":0} - - :statuscode 200: no error - :statuscode 404: no such container - :statuscode 500: server error - - -Remove a container -******************* - -.. http:delete:: /containers/(id) - - Remove the container ``id`` from the filesystem - - **Example request**: - - .. sourcecode:: http - - DELETE /containers/16253994b7c4?v=1 HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 204 OK - - :query v: 1/True/true or 0/False/false, Remove the volumes associated to the container. Default false - :statuscode 204: no error - :statuscode 400: bad parameter - :statuscode 404: no such container - :statuscode 500: server error - - -3.2 Images ----------- - -List Images -*********** - -.. http:get:: /images/(format) - - List images ``format`` could be json or viz (json default) - - **Example request**: - - .. sourcecode:: http - - GET /images/json?all=0 HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - [ - { - "Repository":"base", - "Tag":"ubuntu-12.10", - "Id":"b750fe79269d", - "Created":1364102658 - }, - { - "Repository":"base", - "Tag":"ubuntu-quantal", - "Id":"b750fe79269d", - "Created":1364102658 - } - ] - - - **Example request**: - - .. sourcecode:: http - - GET /images/viz HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: text/plain - - digraph docker { - "d82cbacda43a" -> "074be284591f" - "1496068ca813" -> "08306dc45919" - "08306dc45919" -> "0e7893146ac2" - "b750fe79269d" -> "1496068ca813" - base -> "27cf78414709" [style=invis] - "f71189fff3de" -> "9a33b36209ed" - "27cf78414709" -> "b750fe79269d" - "0e7893146ac2" -> "d6434d954665" - "d6434d954665" -> "d82cbacda43a" - base -> "e9aa60c60128" [style=invis] - "074be284591f" -> "f71189fff3de" - "b750fe79269d" [label="b750fe79269d\nbase",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; - "e9aa60c60128" [label="e9aa60c60128\nbase2",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; - "9a33b36209ed" [label="9a33b36209ed\ntest",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; - base [style=invisible] - } - - :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default - :statuscode 200: no error - :statuscode 400: bad parameter - :statuscode 500: server error - - -Create an image -*************** - -.. http:post:: /images/create - - Create an image, either by pull it from the registry or by importing it - - **Example request**: - - .. sourcecode:: http - - POST /images/create?fromImage=base HTTP/1.1 - - **Example response v1.1**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - {"status":"Pulling..."} - {"status":"Pulling", "progress":"1/? (n/a)"} - {"error":"Invalid..."} - ... - - **Example response v1.0**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/vnd.docker.raw-stream - - {{ STREAM }} - - :query fromImage: name of the image to pull - :query fromSrc: source to import, - means stdin - :query repo: repository - :query tag: tag - :query registry: the registry to pull from - :statuscode 200: no error - :statuscode 500: server error - - -Insert a file in a image -************************ - -.. http:post:: /images/(name)/insert - - Insert a file from ``url`` in the image ``name`` at ``path`` - - **Example request**: - - .. sourcecode:: http - - POST /images/test/insert?path=/usr&url=myurl HTTP/1.1 - - **Example response v1.1**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - {"status":"Inserting..."} - {"status":"Inserting", "progress":"1/? (n/a)"} - {"error":"Invalid..."} - ... - - **Example response v1.0**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - - {{ STREAM }} - - :statuscode 200: no error - :statuscode 500: server error - - -Inspect an image -**************** - -.. http:get:: /images/(name)/json - - Return low-level information on the image ``name`` - - **Example request**: - - .. sourcecode:: http - - GET /images/base/json HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - { - "id":"b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", - "parent":"27cf784147099545", - "created":"2013-03-23T22:24:18.818426-07:00", - "container":"3d67245a8d72ecf13f33dffac9f79dcdf70f75acb84d308770391510e0c23ad0", - "container_config": - { - "Hostname":"", - "User":"", - "Memory":0, - "MemorySwap":0, - "AttachStdin":false, - "AttachStdout":false, - "AttachStderr":false, - "PortSpecs":null, - "Tty":true, - "OpenStdin":true, - "StdinOnce":false, - "Env":null, - "Cmd": ["/bin/bash"] - ,"Dns":null, - "Image":"base", - "Volumes":null, - "VolumesFrom":"" - } - } - - :statuscode 200: no error - :statuscode 404: no such image - :statuscode 500: server error - - -Get the history of an image -*************************** - -.. http:get:: /images/(name)/history - - Return the history of the image ``name`` - - **Example request**: - - .. sourcecode:: http - - GET /images/base/history HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - [ - { - "Id":"b750fe79269d", - "Created":1364102658, - "CreatedBy":"/bin/bash" - }, - { - "Id":"27cf78414709", - "Created":1364068391, - "CreatedBy":"" - } - ] - - :statuscode 200: no error - :statuscode 404: no such image - :statuscode 500: server error - - -Push an image on the registry +:doc:`docker_remote_api_v1.2` ***************************** +What's new +---------- + +The auth configuration is now handled by the client. +The client should send it's authConfig as POST on each call of /images/(name)/push + +.. http:get:: /auth is now deprecated +.. http:post:: /auth only checks the configuration but doesn't store it on the server + +Deleting an image is now improved, will only untag the image if it has chidrens and remove all the untagged parents if has any. +.. http:post:: /images//delete now returns a JSON with the list of images deleted/untagged + + +:doc:`docker_remote_api_v1.1` +***************************** + +docker v0.4.0 a8ae398_ + +What's new +---------- + +.. http:post:: /images/create +.. http:post:: /images/(name)/insert .. http:post:: /images/(name)/push - Push the image ``name`` on the registry - - **Example request**: - - .. sourcecode:: http - - POST /images/test/push HTTP/1.1 - - **Example response v1.1**: +Uses json stream instead of HTML hijack, it looks like this: .. sourcecode:: http @@ -738,349 +63,17 @@ Push an image on the registry {"error":"Invalid..."} ... - **Example response v1.0**: - .. sourcecode:: http +docker v0.3.4 8d73740_ - HTTP/1.1 200 OK - Content-Type: application/vnd.docker.raw-stream +What's new +---------- - {{ STREAM }} +Initial version - :query registry: the registry you wan to push, optional - :statuscode 200: no error - :statuscode 404: no such image - :statuscode 500: server error - - -Tag an image into a repository -****************************** - -.. http:post:: /images/(name)/tag - - Tag the image ``name`` into a repository - - **Example request**: - - .. sourcecode:: http - - POST /images/test/tag?repo=myrepo&force=0 HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - - :query repo: The repository to tag in - :query force: 1/True/true or 0/False/false, default false - :statuscode 200: no error - :statuscode 400: bad parameter - :statuscode 404: no such image - :statuscode 409: conflict - :statuscode 500: server error - - -Remove an image -*************** - -.. http:delete:: /images/(name) - - Remove the image ``name`` from the filesystem - - **Example request**: - - .. sourcecode:: http - - DELETE /images/test HTTP/1.1 - - **Example response v1.0**: - - .. sourcecode:: http - - HTTP/1.1 204 OK - - **Example response v1.1**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-type: application/json - - [ - {"Untagged":"3e2f21a89f"}, - {"Deleted":"3e2f21a89f"}, - {"Deleted":"53b4f83ac9"} - ] - - :query force: 1/True/true or 0/False/false, default false - :statuscode 200: no error - :statuscode 204: no error - :statuscode 404: no such image - :statuscode 409: conflict - :statuscode 500: server error - - -Search images -************* - -.. http:get:: /images/search - - Search for an image in the docker index - - **Example request**: - - .. sourcecode:: http - - GET /images/search?term=sshd HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - [ - { - "Name":"cespare/sshd", - "Description":"" - }, - { - "Name":"johnfuller/sshd", - "Description":"" - }, - { - "Name":"dhrp/mongodb-sshd", - "Description":"" - } - ] - - :query term: term to search - :statuscode 200: no error - :statuscode 500: server error - - -3.3 Misc --------- - -Build an image from Dockerfile via stdin -**************************************** - -.. http:post:: /build - - Build an image from Dockerfile via stdin - - **Example request**: - - .. sourcecode:: http - - POST /build HTTP/1.1 - - {{ STREAM }} - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - - {{ STREAM }} - - :query t: tag to be applied to the resulting image in case of success - :statuscode 200: no error - :statuscode 500: server error - - -Get default username and email -****************************** - -.. http:get:: /auth - - Get the default username and email - - **Example request**: - - .. sourcecode:: http - - GET /auth HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - { - "username":"hannibal", - "email":"hannibal@a-team.com" - } - - :statuscode 200: no error - :statuscode 500: server error - - -Set auth configuration -********************** - -.. http:post:: /auth - - Get the default username and email - - **Example request**: - - .. sourcecode:: http - - POST /auth HTTP/1.1 - Content-Type: application/json - - { - "username":"hannibal", - "password:"xxxx", - "email":"hannibal@a-team.com" - } - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - - :statuscode 200: no error - :statuscode 204: no error - :statuscode 500: server error - - -Display system-wide information -******************************* - -.. http:get:: /info - - Display system-wide information - - **Example request**: - - .. sourcecode:: http - - GET /info HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - { - "Containers":11, - "Images":16, - "Debug":false, - "NFd": 11, - "NGoroutines":21, - "MemoryLimit":true, - "SwapLimit":false - } - - :statuscode 200: no error - :statuscode 500: server error - - -Show the docker version information -*********************************** - -.. http:get:: /version - - Show the docker version information - - **Example request**: - - .. sourcecode:: http - - GET /version HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 200 OK - Content-Type: application/json - - { - "Version":"0.2.2", - "GitCommit":"5a2a5cc+CHANGES", - "GoVersion":"go1.0.3" - } - - :statuscode 200: no error - :statuscode 500: server error - - -Create a new image from a container's changes -********************************************* - -.. http:post:: /commit - - Create a new image from a container's changes - - **Example request**: - - .. sourcecode:: http - - POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1 - - **Example response**: - - .. sourcecode:: http - - HTTP/1.1 201 OK - Content-Type: application/vnd.docker.raw-stream - - {"Id":"596069db4bf5"} - - :query container: source container - :query repo: repository - :query tag: tag - :query m: commit message - :query author: author (eg. "John Hannibal Smith ") - :query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) - :statuscode 201: no error - :statuscode 404: no such container - :statuscode 500: server error - - -3. Going further -================ - -3.1 Inside 'docker run' ------------------------ - -Here are the steps of 'docker run' : - -* Create the container -* If the status code is 404, it means the image doesn't exists: - * Try to pull it - * Then retry to create the container -* Start the container -* If you are not in detached mode: - * Attach to the container, using logs=1 (to have stdout and stderr from the container's start) and stream=1 -* If in detached mode or only stdin is attached: - * Display the container's id - - -3.2 Hijacking -------------- - -In this first version of the API, some of the endpoints, like /attach, /pull or /push uses hijacking to transport stdin, -stdout and stderr on the same socket. This might change in the future. - -3.3 CORS Requests ------------------ - -To enable cross origin requests to the remote api add the flag "-api-enable-cors" when running docker in daemon mode. - - docker -d -H="192.168.1.9:4243" -api-enable-cors +.. _a8ae398: https://github.com/dotcloud/docker/commit/a8ae398bf52e97148ee7bd0d5868de2e15bd297f +.. _8d73740: https://github.com/dotcloud/docker/commit/8d73740343778651c09160cde9661f5f387b36f4 ================================== Docker Remote API Client Libraries @@ -1105,4 +98,3 @@ and we will add the libraries here. | Javascript (Angular) | dockerui | https://github.com/crosbymichael/dockerui | | **WebUI** | | | +----------------------+----------------+--------------------------------------------+ - diff --git a/docs/sources/api/docker_remote_api_v1.0.rst b/docs/sources/api/docker_remote_api_v1.0.rst new file mode 100644 index 0000000000..a789337093 --- /dev/null +++ b/docs/sources/api/docker_remote_api_v1.0.rst @@ -0,0 +1,1015 @@ +:title: Remote API v1.0 +:description: API Documentation for Docker +:keywords: API, Docker, rcli, REST, documentation + +====================== +Docker Remote API v1.0 +====================== + +.. contents:: Table of Contents + +1. Brief introduction +===================== + +- The Remote API is replacing rcli +- Default port in the docker deamon is 4243 +- The API tends to be REST, but for some complex commands, like attach or pull, the HTTP connection is hijacked to transport stdout stdin and stderr + +2. Endpoints +============ + +2.1 Containers +-------------- + +List containers +*************** + +.. http:get:: /containers/json + + List containers + + **Example request**: + + .. sourcecode:: http + + GET /containers/json?all=1&before=8dfafdbc3a40 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Id": "8dfafdbc3a40", + "Image": "base:latest", + "Command": "echo 1", + "Created": 1367854155, + "Status": "Exit 0" + }, + { + "Id": "9cd87474be90", + "Image": "base:latest", + "Command": "echo 222222", + "Created": 1367854155, + "Status": "Exit 0" + }, + { + "Id": "3176a2479c92", + "Image": "base:latest", + "Command": "echo 3333333333333333", + "Created": 1367854154, + "Status": "Exit 0" + }, + { + "Id": "4cb07b47f9fb", + "Image": "base:latest", + "Command": "echo 444444444444444444444444444444444", + "Created": 1367854152, + "Status": "Exit 0" + } + ] + + :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default + :query limit: Show ``limit`` last created containers, include non-running ones. + :query since: Show only containers created since Id, include non-running ones. + :query before: Show only containers created before Id, include non-running ones. + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 500: server error + + +Create a container +****************** + +.. http:post:: /containers/create + + Create a container + + **Example request**: + + .. sourcecode:: http + + POST /containers/create HTTP/1.1 + Content-Type: application/json + + { + "Hostname":"", + "User":"", + "Memory":0, + "MemorySwap":0, + "AttachStdin":false, + "AttachStdout":true, + "AttachStderr":true, + "PortSpecs":null, + "Tty":false, + "OpenStdin":false, + "StdinOnce":false, + "Env":null, + "Cmd":[ + "date" + ], + "Dns":null, + "Image":"base", + "Volumes":{}, + "VolumesFrom":"" + } + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 201 OK + Content-Type: application/json + + { + "Id":"e90e34656806" + "Warnings":[] + } + + :jsonparam config: the container's configuration + :statuscode 201: no error + :statuscode 404: no such container + :statuscode 406: impossible to attach (container not running) + :statuscode 500: server error + + +Inspect a container +******************* + +.. http:get:: /containers/(id)/json + + Return low-level information on the container ``id`` + + **Example request**: + + .. sourcecode:: http + + GET /containers/4fa6e0f0c678/json HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2", + "Created": "2013-05-07T14:51:42.041847+02:00", + "Path": "date", + "Args": [], + "Config": { + "Hostname": "4fa6e0f0c678", + "User": "", + "Memory": 0, + "MemorySwap": 0, + "AttachStdin": false, + "AttachStdout": true, + "AttachStderr": true, + "PortSpecs": null, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": null, + "Cmd": [ + "date" + ], + "Dns": null, + "Image": "base", + "Volumes": {}, + "VolumesFrom": "" + }, + "State": { + "Running": false, + "Pid": 0, + "ExitCode": 0, + "StartedAt": "2013-05-07T14:51:42.087658+02:01360", + "Ghost": false + }, + "Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", + "NetworkSettings": { + "IpAddress": "", + "IpPrefixLen": 0, + "Gateway": "", + "Bridge": "", + "PortMapping": null + }, + "SysInitPath": "/home/kitty/go/src/github.com/dotcloud/docker/bin/docker", + "ResolvConfPath": "/etc/resolv.conf", + "Volumes": {} + } + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Inspect changes on a container's filesystem +******************************************* + +.. http:get:: /containers/(id)/changes + + Inspect changes on container ``id`` 's filesystem + + **Example request**: + + .. sourcecode:: http + + GET /containers/4fa6e0f0c678/changes HTTP/1.1 + + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Path":"/dev", + "Kind":0 + }, + { + "Path":"/dev/kmsg", + "Kind":1 + }, + { + "Path":"/test", + "Kind":1 + } + ] + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Export a container +****************** + +.. http:get:: /containers/(id)/export + + Export the contents of container ``id`` + + **Example request**: + + .. sourcecode:: http + + GET /containers/4fa6e0f0c678/export HTTP/1.1 + + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/octet-stream + + {{ STREAM }} + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Start a container +***************** + +.. http:post:: /containers/(id)/start + + Start the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/start HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Stop a contaier +*************** + +.. http:post:: /containers/(id)/stop + + Stop the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/stop?t=5 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :query t: number of seconds to wait before killing the container + :statuscode 204: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Restart a container +******************* + +.. http:post:: /containers/(id)/restart + + Restart the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/restart?t=5 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :query t: number of seconds to wait before killing the container + :statuscode 204: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Kill a container +**************** + +.. http:post:: /containers/(id)/kill + + Kill the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/kill HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :statuscode 204: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Attach to a container +********************* + +.. http:post:: /containers/(id)/attach + + Attach to the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/16253994b7c4/attach?logs=1&stream=0&stdout=1 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/vnd.docker.raw-stream + + {{ STREAM }} + + :query logs: 1/True/true or 0/False/false, return logs. Default false + :query stream: 1/True/true or 0/False/false, return stream. Default false + :query stdin: 1/True/true or 0/False/false, if stream=true, attach to stdin. Default false + :query stdout: 1/True/true or 0/False/false, if logs=true, return stdout log, if stream=true, attach to stdout. Default false + :query stderr: 1/True/true or 0/False/false, if logs=true, return stderr log, if stream=true, attach to stderr. Default false + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 404: no such container + :statuscode 500: server error + + +Wait a container +**************** + +.. http:post:: /containers/(id)/wait + + Block until container ``id`` stops, then returns the exit code + + **Example request**: + + .. sourcecode:: http + + POST /containers/16253994b7c4/wait HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"StatusCode":0} + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Remove a container +******************* + +.. http:delete:: /containers/(id) + + Remove the container ``id`` from the filesystem + + **Example request**: + + .. sourcecode:: http + + DELETE /containers/16253994b7c4?v=1 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :query v: 1/True/true or 0/False/false, Remove the volumes associated to the container. Default false + :statuscode 204: no error + :statuscode 400: bad parameter + :statuscode 404: no such container + :statuscode 500: server error + + +2.2 Images +---------- + +List Images +*********** + +.. http:get:: /images/(format) + + List images ``format`` could be json or viz (json default) + + **Example request**: + + .. sourcecode:: http + + GET /images/json?all=0 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Repository":"base", + "Tag":"ubuntu-12.10", + "Id":"b750fe79269d", + "Created":1364102658 + }, + { + "Repository":"base", + "Tag":"ubuntu-quantal", + "Id":"b750fe79269d", + "Created":1364102658 + } + ] + + + **Example request**: + + .. sourcecode:: http + + GET /images/viz HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: text/plain + + digraph docker { + "d82cbacda43a" -> "074be284591f" + "1496068ca813" -> "08306dc45919" + "08306dc45919" -> "0e7893146ac2" + "b750fe79269d" -> "1496068ca813" + base -> "27cf78414709" [style=invis] + "f71189fff3de" -> "9a33b36209ed" + "27cf78414709" -> "b750fe79269d" + "0e7893146ac2" -> "d6434d954665" + "d6434d954665" -> "d82cbacda43a" + base -> "e9aa60c60128" [style=invis] + "074be284591f" -> "f71189fff3de" + "b750fe79269d" [label="b750fe79269d\nbase",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "e9aa60c60128" [label="e9aa60c60128\nbase2",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "9a33b36209ed" [label="9a33b36209ed\ntest",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + base [style=invisible] + } + + :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 500: server error + + +Create an image +*************** + +.. http:post:: /images/create + + Create an image, either by pull it from the registry or by importing it + + **Example request**: + + .. sourcecode:: http + + POST /images/create?fromImage=base HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/vnd.docker.raw-stream + + {{ STREAM }} + + :query fromImage: name of the image to pull + :query fromSrc: source to import, - means stdin + :query repo: repository + :query tag: tag + :query registry: the registry to pull from + :statuscode 200: no error + :statuscode 500: server error + + +Insert a file in a image +************************ + +.. http:post:: /images/(name)/insert + + Insert a file from ``url`` in the image ``name`` at ``path`` + + **Example request**: + + .. sourcecode:: http + + POST /images/test/insert?path=/usr&url=myurl HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + {{ STREAM }} + + :statuscode 200: no error + :statuscode 500: server error + + +Inspect an image +**************** + +.. http:get:: /images/(name)/json + + Return low-level information on the image ``name`` + + **Example request**: + + .. sourcecode:: http + + GET /images/base/json HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "id":"b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", + "parent":"27cf784147099545", + "created":"2013-03-23T22:24:18.818426-07:00", + "container":"3d67245a8d72ecf13f33dffac9f79dcdf70f75acb84d308770391510e0c23ad0", + "container_config": + { + "Hostname":"", + "User":"", + "Memory":0, + "MemorySwap":0, + "AttachStdin":false, + "AttachStdout":false, + "AttachStderr":false, + "PortSpecs":null, + "Tty":true, + "OpenStdin":true, + "StdinOnce":false, + "Env":null, + "Cmd": ["/bin/bash"] + ,"Dns":null, + "Image":"base", + "Volumes":null, + "VolumesFrom":"" + } + } + + :statuscode 200: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Get the history of an image +*************************** + +.. http:get:: /images/(name)/history + + Return the history of the image ``name`` + + **Example request**: + + .. sourcecode:: http + + GET /images/base/history HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Id":"b750fe79269d", + "Created":1364102658, + "CreatedBy":"/bin/bash" + }, + { + "Id":"27cf78414709", + "Created":1364068391, + "CreatedBy":"" + } + ] + + :statuscode 200: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Push an image on the registry +***************************** + +.. http:post:: /images/(name)/push + + Push the image ``name`` on the registry + + **Example request**: + + .. sourcecode:: http + + POST /images/test/push HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/vnd.docker.raw-stream + + {{ STREAM }} + + :query registry: the registry you wan to push, optional + :statuscode 200: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Tag an image into a repository +****************************** + +.. http:post:: /images/(name)/tag + + Tag the image ``name`` into a repository + + **Example request**: + + .. sourcecode:: http + + POST /images/test/tag?repo=myrepo&force=0 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + :query repo: The repository to tag in + :query force: 1/True/true or 0/False/false, default false + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 404: no such image + :statuscode 500: server error + + +Remove an image +*************** + +.. http:delete:: /images/(name) + + Remove the image ``name`` from the filesystem + + **Example request**: + + .. sourcecode:: http + + DELETE /images/test HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :statuscode 204: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Search images +************* + +.. http:get:: /images/search + + Search for an image in the docker index + + **Example request**: + + .. sourcecode:: http + + GET /images/search?term=sshd HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Name":"cespare/sshd", + "Description":"" + }, + { + "Name":"johnfuller/sshd", + "Description":"" + }, + { + "Name":"dhrp/mongodb-sshd", + "Description":"" + } + ] + + :query term: term to search + :statuscode 200: no error + :statuscode 500: server error + + +2.3 Misc +-------- + +Build an image from Dockerfile via stdin +**************************************** + +.. http:post:: /build + + Build an image from Dockerfile via stdin + + **Example request**: + + .. sourcecode:: http + + POST /build HTTP/1.1 + + {{ STREAM }} + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + {{ STREAM }} + + :query t: tag to be applied to the resulting image in case of success + :statuscode 200: no error + :statuscode 500: server error + + +Get default username and email +****************************** + +.. http:get:: /auth + + Get the default username and email + + **Example request**: + + .. sourcecode:: http + + GET /auth HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "username":"hannibal", + "email":"hannibal@a-team.com" + } + + :statuscode 200: no error + :statuscode 500: server error + + +Check auth configuration and store it +************************************* + +.. http:post:: /auth + + Get the default username and email + + **Example request**: + + .. sourcecode:: http + + POST /auth HTTP/1.1 + Content-Type: application/json + + { + "username":"hannibal", + "password:"xxxx", + "email":"hannibal@a-team.com" + } + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + :statuscode 200: no error + :statuscode 204: no error + :statuscode 500: server error + + +Display system-wide information +******************************* + +.. http:get:: /info + + Display system-wide information + + **Example request**: + + .. sourcecode:: http + + GET /info HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Containers":11, + "Images":16, + "Debug":false, + "NFd": 11, + "NGoroutines":21, + "MemoryLimit":true, + "SwapLimit":false + } + + :statuscode 200: no error + :statuscode 500: server error + + +Show the docker version information +*********************************** + +.. http:get:: /version + + Show the docker version information + + **Example request**: + + .. sourcecode:: http + + GET /version HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Version":"0.2.2", + "GitCommit":"5a2a5cc+CHANGES", + "GoVersion":"go1.0.3" + } + + :statuscode 200: no error + :statuscode 500: server error + + +Create a new image from a container's changes +********************************************* + +.. http:post:: /commit + + Create a new image from a container's changes + + **Example request**: + + .. sourcecode:: http + + POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 201 OK + Content-Type: application/vnd.docker.raw-stream + + {"Id":"596069db4bf5"} + + :query container: source container + :query repo: repository + :query tag: tag + :query m: commit message + :query author: author (eg. "John Hannibal Smith ") + :query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) + :statuscode 201: no error + :statuscode 404: no such container + :statuscode 500: server error + + +3. Going further +================ + +3.1 Inside 'docker run' +----------------------- + +Here are the steps of 'docker run' : + +* Create the container +* If the status code is 404, it means the image doesn't exists: + * Try to pull it + * Then retry to create the container +* Start the container +* If you are not in detached mode: + * Attach to the container, using logs=1 (to have stdout and stderr from the container's start) and stream=1 +* If in detached mode or only stdin is attached: + * Display the container's id + + +3.2 Hijacking +------------- + +In this first version of the API, some of the endpoints, like /attach, /pull or /push uses hijacking to transport stdin, +stdout and stderr on the same socket. This might change in the future. diff --git a/docs/sources/api/docker_remote_api_v1.1.rst b/docs/sources/api/docker_remote_api_v1.1.rst new file mode 100644 index 0000000000..3e0ef34eba --- /dev/null +++ b/docs/sources/api/docker_remote_api_v1.1.rst @@ -0,0 +1,1026 @@ + +:title: Remote API v1.1 +:description: API Documentation for Docker +:keywords: API, Docker, rcli, REST, documentation + +====================== +Docker Remote API v1.1 +====================== + +.. contents:: Table of Contents + +1. Brief introduction +===================== + +- The Remote API is replacing rcli +- Default port in the docker deamon is 4243 +- The API tends to be REST, but for some complex commands, like attach or pull, the HTTP connection is hijacked to transport stdout stdin and stderr + +2. Endpoints +============ + +2.1 Containers +-------------- + +List containers +*************** + +.. http:get:: /containers/json + + List containers + + **Example request**: + + .. sourcecode:: http + + GET /containers/json?all=1&before=8dfafdbc3a40 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Id": "8dfafdbc3a40", + "Image": "base:latest", + "Command": "echo 1", + "Created": 1367854155, + "Status": "Exit 0" + }, + { + "Id": "9cd87474be90", + "Image": "base:latest", + "Command": "echo 222222", + "Created": 1367854155, + "Status": "Exit 0" + }, + { + "Id": "3176a2479c92", + "Image": "base:latest", + "Command": "echo 3333333333333333", + "Created": 1367854154, + "Status": "Exit 0" + }, + { + "Id": "4cb07b47f9fb", + "Image": "base:latest", + "Command": "echo 444444444444444444444444444444444", + "Created": 1367854152, + "Status": "Exit 0" + } + ] + + :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default + :query limit: Show ``limit`` last created containers, include non-running ones. + :query since: Show only containers created since Id, include non-running ones. + :query before: Show only containers created before Id, include non-running ones. + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 500: server error + + +Create a container +****************** + +.. http:post:: /containers/create + + Create a container + + **Example request**: + + .. sourcecode:: http + + POST /containers/create HTTP/1.1 + Content-Type: application/json + + { + "Hostname":"", + "User":"", + "Memory":0, + "MemorySwap":0, + "AttachStdin":false, + "AttachStdout":true, + "AttachStderr":true, + "PortSpecs":null, + "Tty":false, + "OpenStdin":false, + "StdinOnce":false, + "Env":null, + "Cmd":[ + "date" + ], + "Dns":null, + "Image":"base", + "Volumes":{}, + "VolumesFrom":"" + } + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 201 OK + Content-Type: application/json + + { + "Id":"e90e34656806" + "Warnings":[] + } + + :jsonparam config: the container's configuration + :statuscode 201: no error + :statuscode 404: no such container + :statuscode 406: impossible to attach (container not running) + :statuscode 500: server error + + +Inspect a container +******************* + +.. http:get:: /containers/(id)/json + + Return low-level information on the container ``id`` + + **Example request**: + + .. sourcecode:: http + + GET /containers/4fa6e0f0c678/json HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2", + "Created": "2013-05-07T14:51:42.041847+02:00", + "Path": "date", + "Args": [], + "Config": { + "Hostname": "4fa6e0f0c678", + "User": "", + "Memory": 0, + "MemorySwap": 0, + "AttachStdin": false, + "AttachStdout": true, + "AttachStderr": true, + "PortSpecs": null, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": null, + "Cmd": [ + "date" + ], + "Dns": null, + "Image": "base", + "Volumes": {}, + "VolumesFrom": "" + }, + "State": { + "Running": false, + "Pid": 0, + "ExitCode": 0, + "StartedAt": "2013-05-07T14:51:42.087658+02:01360", + "Ghost": false + }, + "Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", + "NetworkSettings": { + "IpAddress": "", + "IpPrefixLen": 0, + "Gateway": "", + "Bridge": "", + "PortMapping": null + }, + "SysInitPath": "/home/kitty/go/src/github.com/dotcloud/docker/bin/docker", + "ResolvConfPath": "/etc/resolv.conf", + "Volumes": {} + } + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Inspect changes on a container's filesystem +******************************************* + +.. http:get:: /containers/(id)/changes + + Inspect changes on container ``id`` 's filesystem + + **Example request**: + + .. sourcecode:: http + + GET /containers/4fa6e0f0c678/changes HTTP/1.1 + + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Path":"/dev", + "Kind":0 + }, + { + "Path":"/dev/kmsg", + "Kind":1 + }, + { + "Path":"/test", + "Kind":1 + } + ] + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Export a container +****************** + +.. http:get:: /containers/(id)/export + + Export the contents of container ``id`` + + **Example request**: + + .. sourcecode:: http + + GET /containers/4fa6e0f0c678/export HTTP/1.1 + + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/octet-stream + + {{ STREAM }} + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Start a container +***************** + +.. http:post:: /containers/(id)/start + + Start the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/start HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Stop a contaier +*************** + +.. http:post:: /containers/(id)/stop + + Stop the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/stop?t=5 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :query t: number of seconds to wait before killing the container + :statuscode 204: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Restart a container +******************* + +.. http:post:: /containers/(id)/restart + + Restart the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/restart?t=5 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :query t: number of seconds to wait before killing the container + :statuscode 204: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Kill a container +**************** + +.. http:post:: /containers/(id)/kill + + Kill the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/kill HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :statuscode 204: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Attach to a container +********************* + +.. http:post:: /containers/(id)/attach + + Attach to the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/16253994b7c4/attach?logs=1&stream=0&stdout=1 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/vnd.docker.raw-stream + + {{ STREAM }} + + :query logs: 1/True/true or 0/False/false, return logs. Default false + :query stream: 1/True/true or 0/False/false, return stream. Default false + :query stdin: 1/True/true or 0/False/false, if stream=true, attach to stdin. Default false + :query stdout: 1/True/true or 0/False/false, if logs=true, return stdout log, if stream=true, attach to stdout. Default false + :query stderr: 1/True/true or 0/False/false, if logs=true, return stderr log, if stream=true, attach to stderr. Default false + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 404: no such container + :statuscode 500: server error + + +Wait a container +**************** + +.. http:post:: /containers/(id)/wait + + Block until container ``id`` stops, then returns the exit code + + **Example request**: + + .. sourcecode:: http + + POST /containers/16253994b7c4/wait HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"StatusCode":0} + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Remove a container +******************* + +.. http:delete:: /containers/(id) + + Remove the container ``id`` from the filesystem + + **Example request**: + + .. sourcecode:: http + + DELETE /containers/16253994b7c4?v=1 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :query v: 1/True/true or 0/False/false, Remove the volumes associated to the container. Default false + :statuscode 204: no error + :statuscode 400: bad parameter + :statuscode 404: no such container + :statuscode 500: server error + + +2.2 Images +---------- + +List Images +*********** + +.. http:get:: /images/(format) + + List images ``format`` could be json or viz (json default) + + **Example request**: + + .. sourcecode:: http + + GET /images/json?all=0 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Repository":"base", + "Tag":"ubuntu-12.10", + "Id":"b750fe79269d", + "Created":1364102658 + }, + { + "Repository":"base", + "Tag":"ubuntu-quantal", + "Id":"b750fe79269d", + "Created":1364102658 + } + ] + + + **Example request**: + + .. sourcecode:: http + + GET /images/viz HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: text/plain + + digraph docker { + "d82cbacda43a" -> "074be284591f" + "1496068ca813" -> "08306dc45919" + "08306dc45919" -> "0e7893146ac2" + "b750fe79269d" -> "1496068ca813" + base -> "27cf78414709" [style=invis] + "f71189fff3de" -> "9a33b36209ed" + "27cf78414709" -> "b750fe79269d" + "0e7893146ac2" -> "d6434d954665" + "d6434d954665" -> "d82cbacda43a" + base -> "e9aa60c60128" [style=invis] + "074be284591f" -> "f71189fff3de" + "b750fe79269d" [label="b750fe79269d\nbase",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "e9aa60c60128" [label="e9aa60c60128\nbase2",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "9a33b36209ed" [label="9a33b36209ed\ntest",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + base [style=invisible] + } + + :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 500: server error + + +Create an image +*************** + +.. http:post:: /images/create + + Create an image, either by pull it from the registry or by importing it + + **Example request**: + + .. sourcecode:: http + + POST /images/create?fromImage=base HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"Pulling..."} + {"status":"Pulling", "progress":"1/? (n/a)"} + {"error":"Invalid..."} + ... + + :query fromImage: name of the image to pull + :query fromSrc: source to import, - means stdin + :query repo: repository + :query tag: tag + :query registry: the registry to pull from + :statuscode 200: no error + :statuscode 500: server error + + +Insert a file in a image +************************ + +.. http:post:: /images/(name)/insert + + Insert a file from ``url`` in the image ``name`` at ``path`` + + **Example request**: + + .. sourcecode:: http + + POST /images/test/insert?path=/usr&url=myurl HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"Inserting..."} + {"status":"Inserting", "progress":"1/? (n/a)"} + {"error":"Invalid..."} + ... + + :statuscode 200: no error + :statuscode 500: server error + + +Inspect an image +**************** + +.. http:get:: /images/(name)/json + + Return low-level information on the image ``name`` + + **Example request**: + + .. sourcecode:: http + + GET /images/base/json HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "id":"b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", + "parent":"27cf784147099545", + "created":"2013-03-23T22:24:18.818426-07:00", + "container":"3d67245a8d72ecf13f33dffac9f79dcdf70f75acb84d308770391510e0c23ad0", + "container_config": + { + "Hostname":"", + "User":"", + "Memory":0, + "MemorySwap":0, + "AttachStdin":false, + "AttachStdout":false, + "AttachStderr":false, + "PortSpecs":null, + "Tty":true, + "OpenStdin":true, + "StdinOnce":false, + "Env":null, + "Cmd": ["/bin/bash"] + ,"Dns":null, + "Image":"base", + "Volumes":null, + "VolumesFrom":"" + } + } + + :statuscode 200: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Get the history of an image +*************************** + +.. http:get:: /images/(name)/history + + Return the history of the image ``name`` + + **Example request**: + + .. sourcecode:: http + + GET /images/base/history HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Id":"b750fe79269d", + "Created":1364102658, + "CreatedBy":"/bin/bash" + }, + { + "Id":"27cf78414709", + "Created":1364068391, + "CreatedBy":"" + } + ] + + :statuscode 200: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Push an image on the registry +***************************** + +.. http:post:: /images/(name)/push + + Push the image ``name`` on the registry + + **Example request**: + + .. sourcecode:: http + + POST /images/test/push HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"Pushing..."} + {"status":"Pushing", "progress":"1/? (n/a)"} + {"error":"Invalid..."} + ... + + :query registry: the registry you wan to push, optional + :statuscode 200: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Tag an image into a repository +****************************** + +.. http:post:: /images/(name)/tag + + Tag the image ``name`` into a repository + + **Example request**: + + .. sourcecode:: http + + POST /images/test/tag?repo=myrepo&force=0 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + :query repo: The repository to tag in + :query force: 1/True/true or 0/False/false, default false + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 404: no such image + :statuscode 409: conflict + :statuscode 500: server error + + +Remove an image +*************** + +.. http:delete:: /images/(name) + + Remove the image ``name`` from the filesystem + + **Example request**: + + .. sourcecode:: http + + DELETE /images/test HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :statuscode 204: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Search images +************* + +.. http:get:: /images/search + + Search for an image in the docker index + + **Example request**: + + .. sourcecode:: http + + GET /images/search?term=sshd HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Name":"cespare/sshd", + "Description":"" + }, + { + "Name":"johnfuller/sshd", + "Description":"" + }, + { + "Name":"dhrp/mongodb-sshd", + "Description":"" + } + ] + + :query term: term to search + :statuscode 200: no error + :statuscode 500: server error + + +2.3 Misc +-------- + +Build an image from Dockerfile via stdin +**************************************** + +.. http:post:: /build + + Build an image from Dockerfile via stdin + + **Example request**: + + .. sourcecode:: http + + POST /build HTTP/1.1 + + {{ STREAM }} + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + {{ STREAM }} + + :query t: tag to be applied to the resulting image in case of success + :statuscode 200: no error + :statuscode 500: server error + + +Get default username and email +****************************** + +.. http:get:: /auth + + Get the default username and email + + **Example request**: + + .. sourcecode:: http + + GET /auth HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "username":"hannibal", + "email":"hannibal@a-team.com" + } + + :statuscode 200: no error + :statuscode 500: server error + + +Check auth configuration and store it +************************************* + +.. http:post:: /auth + + Get the default username and email + + **Example request**: + + .. sourcecode:: http + + POST /auth HTTP/1.1 + Content-Type: application/json + + { + "username":"hannibal", + "password:"xxxx", + "email":"hannibal@a-team.com" + } + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + :statuscode 200: no error + :statuscode 204: no error + :statuscode 500: server error + + +Display system-wide information +******************************* + +.. http:get:: /info + + Display system-wide information + + **Example request**: + + .. sourcecode:: http + + GET /info HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Containers":11, + "Images":16, + "Debug":false, + "NFd": 11, + "NGoroutines":21, + "MemoryLimit":true, + "SwapLimit":false + } + + :statuscode 200: no error + :statuscode 500: server error + + +Show the docker version information +*********************************** + +.. http:get:: /version + + Show the docker version information + + **Example request**: + + .. sourcecode:: http + + GET /version HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Version":"0.2.2", + "GitCommit":"5a2a5cc+CHANGES", + "GoVersion":"go1.0.3" + } + + :statuscode 200: no error + :statuscode 500: server error + + +Create a new image from a container's changes +********************************************* + +.. http:post:: /commit + + Create a new image from a container's changes + + **Example request**: + + .. sourcecode:: http + + POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 201 OK + Content-Type: application/vnd.docker.raw-stream + + {"Id":"596069db4bf5"} + + :query container: source container + :query repo: repository + :query tag: tag + :query m: commit message + :query author: author (eg. "John Hannibal Smith ") + :query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) + :statuscode 201: no error + :statuscode 404: no such container + :statuscode 500: server error + + +3. Going further +================ + +3.1 Inside 'docker run' +----------------------- + +Here are the steps of 'docker run' : + +* Create the container +* If the status code is 404, it means the image doesn't exists: + * Try to pull it + * Then retry to create the container +* Start the container +* If you are not in detached mode: + * Attach to the container, using logs=1 (to have stdout and stderr from the container's start) and stream=1 +* If in detached mode or only stdin is attached: + * Display the container's id + + +3.2 Hijacking +------------- + +In this version of the API, /attach uses hijacking to transport stdin, stdout and stderr on the same socket. This might change in the future. diff --git a/docs/sources/api/docker_remote_api_v1.2.rst b/docs/sources/api/docker_remote_api_v1.2.rst new file mode 100644 index 0000000000..8354760e2f --- /dev/null +++ b/docs/sources/api/docker_remote_api_v1.2.rst @@ -0,0 +1,1013 @@ +:title: Remote API v1.2 +:description: API Documentation for Docker +:keywords: API, Docker, rcli, REST, documentation + +====================== +Docker Remote API v1.2 +====================== + +.. contents:: Table of Contents + +1. Brief introduction +===================== + +- The Remote API is replacing rcli +- Default port in the docker deamon is 4243 +- The API tends to be REST, but for some complex commands, like attach or pull, the HTTP connection is hijacked to transport stdout stdin and stderr + +2. Endpoints +============ + +2.1 Containers +-------------- + +List containers +*************** + +.. http:get:: /containers/json + + List containers + + **Example request**: + + .. sourcecode:: http + + GET /containers/json?all=1&before=8dfafdbc3a40 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Id": "8dfafdbc3a40", + "Image": "base:latest", + "Command": "echo 1", + "Created": 1367854155, + "Status": "Exit 0" + }, + { + "Id": "9cd87474be90", + "Image": "base:latest", + "Command": "echo 222222", + "Created": 1367854155, + "Status": "Exit 0" + }, + { + "Id": "3176a2479c92", + "Image": "base:latest", + "Command": "echo 3333333333333333", + "Created": 1367854154, + "Status": "Exit 0" + }, + { + "Id": "4cb07b47f9fb", + "Image": "base:latest", + "Command": "echo 444444444444444444444444444444444", + "Created": 1367854152, + "Status": "Exit 0" + } + ] + + :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default + :query limit: Show ``limit`` last created containers, include non-running ones. + :query since: Show only containers created since Id, include non-running ones. + :query before: Show only containers created before Id, include non-running ones. + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 500: server error + + +Create a container +****************** + +.. http:post:: /containers/create + + Create a container + + **Example request**: + + .. sourcecode:: http + + POST /containers/create HTTP/1.1 + Content-Type: application/json + + { + "Hostname":"", + "User":"", + "Memory":0, + "MemorySwap":0, + "AttachStdin":false, + "AttachStdout":true, + "AttachStderr":true, + "PortSpecs":null, + "Tty":false, + "OpenStdin":false, + "StdinOnce":false, + "Env":null, + "Cmd":[ + "date" + ], + "Dns":null, + "Image":"base", + "Volumes":{}, + "VolumesFrom":"" + } + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 201 OK + Content-Type: application/json + + { + "Id":"e90e34656806" + "Warnings":[] + } + + :jsonparam config: the container's configuration + :statuscode 201: no error + :statuscode 404: no such container + :statuscode 406: impossible to attach (container not running) + :statuscode 500: server error + + +Inspect a container +******************* + +.. http:get:: /containers/(id)/json + + Return low-level information on the container ``id`` + + **Example request**: + + .. sourcecode:: http + + GET /containers/4fa6e0f0c678/json HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2", + "Created": "2013-05-07T14:51:42.041847+02:00", + "Path": "date", + "Args": [], + "Config": { + "Hostname": "4fa6e0f0c678", + "User": "", + "Memory": 0, + "MemorySwap": 0, + "AttachStdin": false, + "AttachStdout": true, + "AttachStderr": true, + "PortSpecs": null, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": null, + "Cmd": [ + "date" + ], + "Dns": null, + "Image": "base", + "Volumes": {}, + "VolumesFrom": "" + }, + "State": { + "Running": false, + "Pid": 0, + "ExitCode": 0, + "StartedAt": "2013-05-07T14:51:42.087658+02:01360", + "Ghost": false + }, + "Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", + "NetworkSettings": { + "IpAddress": "", + "IpPrefixLen": 0, + "Gateway": "", + "Bridge": "", + "PortMapping": null + }, + "SysInitPath": "/home/kitty/go/src/github.com/dotcloud/docker/bin/docker", + "ResolvConfPath": "/etc/resolv.conf", + "Volumes": {} + } + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Inspect changes on a container's filesystem +******************************************* + +.. http:get:: /containers/(id)/changes + + Inspect changes on container ``id`` 's filesystem + + **Example request**: + + .. sourcecode:: http + + GET /containers/4fa6e0f0c678/changes HTTP/1.1 + + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Path":"/dev", + "Kind":0 + }, + { + "Path":"/dev/kmsg", + "Kind":1 + }, + { + "Path":"/test", + "Kind":1 + } + ] + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Export a container +****************** + +.. http:get:: /containers/(id)/export + + Export the contents of container ``id`` + + **Example request**: + + .. sourcecode:: http + + GET /containers/4fa6e0f0c678/export HTTP/1.1 + + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/octet-stream + + {{ STREAM }} + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Start a container +***************** + +.. http:post:: /containers/(id)/start + + Start the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/start HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Stop a contaier +*************** + +.. http:post:: /containers/(id)/stop + + Stop the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/stop?t=5 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :query t: number of seconds to wait before killing the container + :statuscode 204: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Restart a container +******************* + +.. http:post:: /containers/(id)/restart + + Restart the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/restart?t=5 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :query t: number of seconds to wait before killing the container + :statuscode 204: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Kill a container +**************** + +.. http:post:: /containers/(id)/kill + + Kill the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/e90e34656806/kill HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :statuscode 204: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Attach to a container +********************* + +.. http:post:: /containers/(id)/attach + + Attach to the container ``id`` + + **Example request**: + + .. sourcecode:: http + + POST /containers/16253994b7c4/attach?logs=1&stream=0&stdout=1 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/vnd.docker.raw-stream + + {{ STREAM }} + + :query logs: 1/True/true or 0/False/false, return logs. Default false + :query stream: 1/True/true or 0/False/false, return stream. Default false + :query stdin: 1/True/true or 0/False/false, if stream=true, attach to stdin. Default false + :query stdout: 1/True/true or 0/False/false, if logs=true, return stdout log, if stream=true, attach to stdout. Default false + :query stderr: 1/True/true or 0/False/false, if logs=true, return stderr log, if stream=true, attach to stderr. Default false + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 404: no such container + :statuscode 500: server error + + +Wait a container +**************** + +.. http:post:: /containers/(id)/wait + + Block until container ``id`` stops, then returns the exit code + + **Example request**: + + .. sourcecode:: http + + POST /containers/16253994b7c4/wait HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"StatusCode":0} + + :statuscode 200: no error + :statuscode 404: no such container + :statuscode 500: server error + + +Remove a container +******************* + +.. http:delete:: /containers/(id) + + Remove the container ``id`` from the filesystem + + **Example request**: + + .. sourcecode:: http + + DELETE /containers/16253994b7c4?v=1 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 OK + + :query v: 1/True/true or 0/False/false, Remove the volumes associated to the container. Default false + :statuscode 204: no error + :statuscode 400: bad parameter + :statuscode 404: no such container + :statuscode 500: server error + + +2.2 Images +---------- + +List Images +*********** + +.. http:get:: /images/(format) + + List images ``format`` could be json or viz (json default) + + **Example request**: + + .. sourcecode:: http + + GET /images/json?all=0 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Repository":"base", + "Tag":"ubuntu-12.10", + "Id":"b750fe79269d", + "Created":1364102658 + }, + { + "Repository":"base", + "Tag":"ubuntu-quantal", + "Id":"b750fe79269d", + "Created":1364102658 + } + ] + + + **Example request**: + + .. sourcecode:: http + + GET /images/viz HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: text/plain + + digraph docker { + "d82cbacda43a" -> "074be284591f" + "1496068ca813" -> "08306dc45919" + "08306dc45919" -> "0e7893146ac2" + "b750fe79269d" -> "1496068ca813" + base -> "27cf78414709" [style=invis] + "f71189fff3de" -> "9a33b36209ed" + "27cf78414709" -> "b750fe79269d" + "0e7893146ac2" -> "d6434d954665" + "d6434d954665" -> "d82cbacda43a" + base -> "e9aa60c60128" [style=invis] + "074be284591f" -> "f71189fff3de" + "b750fe79269d" [label="b750fe79269d\nbase",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "e9aa60c60128" [label="e9aa60c60128\nbase2",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "9a33b36209ed" [label="9a33b36209ed\ntest",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + base [style=invisible] + } + + :query all: 1/True/true or 0/False/false, Show all containers. Only running containers are shown by default + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 500: server error + + +Create an image +*************** + +.. http:post:: /images/create + + Create an image, either by pull it from the registry or by importing it + + **Example request**: + + .. sourcecode:: http + + POST /images/create?fromImage=base HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"Pulling..."} + {"status":"Pulling", "progress":"1/? (n/a)"} + {"error":"Invalid..."} + ... + + :query fromImage: name of the image to pull + :query fromSrc: source to import, - means stdin + :query repo: repository + :query tag: tag + :query registry: the registry to pull from + :statuscode 200: no error + :statuscode 500: server error + + +Insert a file in a image +************************ + +.. http:post:: /images/(name)/insert + + Insert a file from ``url`` in the image ``name`` at ``path`` + + **Example request**: + + .. sourcecode:: http + + POST /images/test/insert?path=/usr&url=myurl HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"Inserting..."} + {"status":"Inserting", "progress":"1/? (n/a)"} + {"error":"Invalid..."} + ... + + :statuscode 200: no error + :statuscode 500: server error + + +Inspect an image +**************** + +.. http:get:: /images/(name)/json + + Return low-level information on the image ``name`` + + **Example request**: + + .. sourcecode:: http + + GET /images/base/json HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "id":"b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc", + "parent":"27cf784147099545", + "created":"2013-03-23T22:24:18.818426-07:00", + "container":"3d67245a8d72ecf13f33dffac9f79dcdf70f75acb84d308770391510e0c23ad0", + "container_config": + { + "Hostname":"", + "User":"", + "Memory":0, + "MemorySwap":0, + "AttachStdin":false, + "AttachStdout":false, + "AttachStderr":false, + "PortSpecs":null, + "Tty":true, + "OpenStdin":true, + "StdinOnce":false, + "Env":null, + "Cmd": ["/bin/bash"] + ,"Dns":null, + "Image":"base", + "Volumes":null, + "VolumesFrom":"" + } + } + + :statuscode 200: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Get the history of an image +*************************** + +.. http:get:: /images/(name)/history + + Return the history of the image ``name`` + + **Example request**: + + .. sourcecode:: http + + GET /images/base/history HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Id":"b750fe79269d", + "Created":1364102658, + "CreatedBy":"/bin/bash" + }, + { + "Id":"27cf78414709", + "Created":1364068391, + "CreatedBy":"" + } + ] + + :statuscode 200: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Push an image on the registry +***************************** + +.. http:post:: /images/(name)/push + + Push the image ``name`` on the registry + + **Example request**: + + .. sourcecode:: http + + POST /images/test/push HTTP/1.1 + {{ authConfig }} + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"Pushing..."} + {"status":"Pushing", "progress":"1/? (n/a)"} + {"error":"Invalid..."} + ... + + :query registry: the registry you wan to push, optional + :statuscode 200: no error + :statuscode 404: no such image + :statuscode 500: server error + + +Tag an image into a repository +****************************** + +.. http:post:: /images/(name)/tag + + Tag the image ``name`` into a repository + + **Example request**: + + .. sourcecode:: http + + POST /images/test/tag?repo=myrepo&force=0 HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + :query repo: The repository to tag in + :query force: 1/True/true or 0/False/false, default false + :statuscode 200: no error + :statuscode 400: bad parameter + :statuscode 404: no such image + :statuscode 409: conflict + :statuscode 500: server error + + +Remove an image +*************** + +.. http:delete:: /images/(name) + + Remove the image ``name`` from the filesystem + + **Example request**: + + .. sourcecode:: http + + DELETE /images/test HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-type: application/json + + [ + {"Untagged":"3e2f21a89f"}, + {"Deleted":"3e2f21a89f"}, + {"Deleted":"53b4f83ac9"} + ] + + :statuscode 204: no error + :statuscode 404: no such image + :statuscode 409: conflict + :statuscode 500: server error + + +Search images +************* + +.. http:get:: /images/search + + Search for an image in the docker index + + **Example request**: + + .. sourcecode:: http + + GET /images/search?term=sshd HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "Name":"cespare/sshd", + "Description":"" + }, + { + "Name":"johnfuller/sshd", + "Description":"" + }, + { + "Name":"dhrp/mongodb-sshd", + "Description":"" + } + ] + + :query term: term to search + :statuscode 200: no error + :statuscode 500: server error + + +2.3 Misc +-------- + +Build an image from Dockerfile via stdin +**************************************** + +.. http:post:: /build + + Build an image from Dockerfile via stdin + + **Example request**: + + .. sourcecode:: http + + POST /build HTTP/1.1 + + {{ STREAM }} + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + {{ STREAM }} + + :query t: tag to be applied to the resulting image in case of success + :statuscode 200: no error + :statuscode 500: server error + + +Check auth configuration +************************ + +.. http:post:: /auth + + Get the default username and email + + **Example request**: + + .. sourcecode:: http + + POST /auth HTTP/1.1 + Content-Type: application/json + + { + "username":"hannibal", + "password:"xxxx", + "email":"hannibal@a-team.com" + } + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + + :statuscode 200: no error + :statuscode 204: no error + :statuscode 500: server error + + +Display system-wide information +******************************* + +.. http:get:: /info + + Display system-wide information + + **Example request**: + + .. sourcecode:: http + + GET /info HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Containers":11, + "Images":16, + "Debug":false, + "NFd": 11, + "NGoroutines":21, + "MemoryLimit":true, + "SwapLimit":false + } + + :statuscode 200: no error + :statuscode 500: server error + + +Show the docker version information +*********************************** + +.. http:get:: /version + + Show the docker version information + + **Example request**: + + .. sourcecode:: http + + GET /version HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "Version":"0.2.2", + "GitCommit":"5a2a5cc+CHANGES", + "GoVersion":"go1.0.3" + } + + :statuscode 200: no error + :statuscode 500: server error + + +Create a new image from a container's changes +********************************************* + +.. http:post:: /commit + + Create a new image from a container's changes + + **Example request**: + + .. sourcecode:: http + + POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 201 OK + Content-Type: application/vnd.docker.raw-stream + + {"Id":"596069db4bf5"} + + :query container: source container + :query repo: repository + :query tag: tag + :query m: commit message + :query author: author (eg. "John Hannibal Smith ") + :query run: config automatically applied when the image is run. (ex: {"Cmd": ["cat", "/world"], "PortSpecs":["22"]}) + :statuscode 201: no error + :statuscode 404: no such container + :statuscode 500: server error + + +3. Going further +================ + +3.1 Inside 'docker run' +----------------------- + +Here are the steps of 'docker run' : + +* Create the container +* If the status code is 404, it means the image doesn't exists: + * Try to pull it + * Then retry to create the container +* Start the container +* If you are not in detached mode: + * Attach to the container, using logs=1 (to have stdout and stderr from the container's start) and stream=1 +* If in detached mode or only stdin is attached: + * Display the container's id + + +3.2 Hijacking +------------- + +In this version of the API, /attach, uses hijacking to transport stdin, stdout and stderr on the same socket. This might change in the future. + +3.3 CORS Requests +----------------- + +To enable cross origin requests to the remote api add the flag "-api-enable-cors" when running docker in daemon mode. + + docker -d -H="192.168.1.9:4243" -api-enable-cors + diff --git a/registry/registry.go b/registry/registry.go index bd5c6b79c6..64798f24ef 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -473,10 +473,7 @@ type Registry struct { authConfig *auth.AuthConfig } -func NewRegistry(root string) *Registry { - // If the auth file does not exist, keep going - authConfig, _ := auth.LoadConfig(root) - +func NewRegistry(root string, authConfig *auth.AuthConfig) *Registry { httpTransport := &http.Transport{ DisableKeepAlives: true, Proxy: http.ProxyFromEnvironment, diff --git a/runtime_test.go b/runtime_test.go index ae6f7c9c68..d7d9a5a315 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -68,7 +68,7 @@ func init() { runtime: runtime, } // Retrieve the Image - if err := srv.ImagePull(unitTestImageName, "", "", os.Stdout, utils.NewStreamFormatter(false)); err != nil { + if err := srv.ImagePull(unitTestImageName, "", "", os.Stdout, utils.NewStreamFormatter(false), nil); err != nil { panic(err) } } diff --git a/server.go b/server.go index f22898ad5e..34d525a35a 100644 --- a/server.go +++ b/server.go @@ -55,7 +55,7 @@ func (srv *Server) ContainerExport(name string, out io.Writer) 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, nil).SearchRepositories(term) if err != nil { return nil, err } @@ -395,8 +395,8 @@ func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, local, re return nil } -func (srv *Server) ImagePull(name, tag, endpoint string, out io.Writer, sf *utils.StreamFormatter) error { - r := registry.NewRegistry(srv.runtime.root) +func (srv *Server) ImagePull(name, tag, endpoint string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig) error { + r := registry.NewRegistry(srv.runtime.root, authConfig) out = utils.NewWriteFlusher(out) if endpoint != "" { if err := srv.pullImage(r, out, name, endpoint, nil, sf); err != nil { @@ -587,10 +587,10 @@ func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgId, return nil } -func (srv *Server) ImagePush(name, endpoint string, out io.Writer, sf *utils.StreamFormatter) error { +func (srv *Server) ImagePush(name, endpoint string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig) error { out = utils.NewWriteFlusher(out) img, err := srv.runtime.graph.Get(name) - r := registry.NewRegistry(srv.runtime.root) + r := registry.NewRegistry(srv.runtime.root, authConfig) if err != nil { out.Write(sf.FormatStatus("The push refers to a repository [%s] (len: %d)", name, len(srv.runtime.repositories.Repositories[name])))