mirror of https://github.com/docker/docs.git
added export
This commit is contained in:
parent
79512b2a80
commit
c7bbe7ca79
37
api.go
37
api.go
|
@ -65,6 +65,43 @@ func ListenAndServe(addr string, rtime *Runtime) error {
|
||||||
http.Error(w, "No such image: "+name, http.StatusNotFound)
|
http.Error(w, "No such image: "+name, http.StatusNotFound)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
r.Path("/containers/{name:.*}/export").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Println(r.Method, r.RequestURI)
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
name := vars["name"]
|
||||||
|
|
||||||
|
if container := rtime.Get(name); container != nil {
|
||||||
|
|
||||||
|
data, err := container.Export()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
conn, _, err := w.(http.Hijacker).Hijack()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
file, err := conn.(*net.TCPConn).File()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
fmt.Fprintln(file, "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\n\r\n")
|
||||||
|
// Stream the entire contents of the container (basically a volatile snapshot)
|
||||||
|
if _, err := io.Copy(file, data); err != nil {
|
||||||
|
fmt.Fprintln(file, "Error: "+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
http.Error(w, "No such container: "+name, http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
r.Path("/containers/{name:.*}").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
r.Path("/containers/{name:.*}").Methods("GET").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Println(r.Method, r.RequestURI)
|
log.Println(r.Method, r.RequestURI)
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
38
commands.go
38
commands.go
|
@ -28,6 +28,7 @@ func ParseCommands(args []string) error {
|
||||||
cmds := map[string]func(args []string) error{
|
cmds := map[string]func(args []string) error{
|
||||||
"commit": CmdCommit,
|
"commit": CmdCommit,
|
||||||
"diff": CmdDiff,
|
"diff": CmdDiff,
|
||||||
|
"export": CmdExport,
|
||||||
"images": CmdImages,
|
"images": CmdImages,
|
||||||
"info": CmdInfo,
|
"info": CmdInfo,
|
||||||
"inspect": CmdInspect,
|
"inspect": CmdInspect,
|
||||||
|
@ -65,7 +66,7 @@ func cmdHelp(args []string) error {
|
||||||
// {"attach", "Attach to a running container"},
|
// {"attach", "Attach to a running container"},
|
||||||
{"commit", "Create a new image from a container's changes"},
|
{"commit", "Create a new image from a container's changes"},
|
||||||
{"diff", "Inspect changes on a container's filesystem"},
|
{"diff", "Inspect changes on a container's filesystem"},
|
||||||
// {"export", "Stream the contents of a container as a tar archive"},
|
{"export", "Stream the contents of a container as a tar archive"},
|
||||||
{"history", "Show the history of an image"},
|
{"history", "Show the history of an image"},
|
||||||
{"images", "List images"},
|
{"images", "List images"},
|
||||||
// {"import", "Create a new filesystem image from the contents of a tarball"},
|
// {"import", "Create a new filesystem image from the contents of a tarball"},
|
||||||
|
@ -759,29 +760,22 @@ func CmdCommit(args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func CmdExport(args []string) error {
|
||||||
func (srv *Server) CmdExport(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
cmd := Subcmd("export", "CONTAINER", "Export the contents of a filesystem as a tar archive")
|
||||||
cmd := rcli.Subcmd(stdout,
|
|
||||||
"export", "CONTAINER",
|
|
||||||
"Export the contents of a filesystem as a tar archive")
|
|
||||||
if err := cmd.Parse(args); err != nil {
|
if err := cmd.Parse(args); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
name := cmd.Arg(0)
|
|
||||||
if container := srv.runtime.Get(name); container != nil {
|
if cmd.NArg() != 1 {
|
||||||
data, err := container.Export()
|
cmd.Usage()
|
||||||
if err != nil {
|
return nil
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// Stream the entire contents of the container (basically a volatile snapshot)
|
|
||||||
if _, err := io.Copy(stdout, data); err != nil {
|
if err := callStream("GET", "/containers/"+cmd.Arg(0)+"/export", nil, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("No such container: %s", name)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func CmdDiff(args []string) error {
|
func CmdDiff(args []string) error {
|
||||||
cmd := Subcmd("diff", "CONTAINER", "Inspect changes on a container's filesystem")
|
cmd := Subcmd("diff", "CONTAINER", "Inspect changes on a container's filesystem")
|
||||||
|
@ -1010,8 +1004,18 @@ func callStream(method, path string, data interface{}, isTerminal bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
clientconn := httputil.NewClientConn(dial, nil)
|
clientconn := httputil.NewClientConn(dial, nil)
|
||||||
clientconn.Do(req)
|
resp, err := clientconn.Do(req)
|
||||||
defer clientconn.Close()
|
defer clientconn.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fmt.Errorf("error: %s", body)
|
||||||
|
}
|
||||||
|
|
||||||
rwc, _ := clientconn.Hijack()
|
rwc, _ := clientconn.Hijack()
|
||||||
defer rwc.Close()
|
defer rwc.Close()
|
||||||
|
|
Loading…
Reference in New Issue