added export

This commit is contained in:
Victor Vieux 2013-04-24 16:32:51 +02:00
parent 79512b2a80
commit c7bbe7ca79
2 changed files with 60 additions and 19 deletions

37
api.go
View File

@ -65,6 +65,43 @@ func ListenAndServe(addr string, rtime *Runtime) error {
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) {
log.Println(r.Method, r.RequestURI)
vars := mux.Vars(r)

View File

@ -28,6 +28,7 @@ func ParseCommands(args []string) error {
cmds := map[string]func(args []string) error{
"commit": CmdCommit,
"diff": CmdDiff,
"export": CmdExport,
"images": CmdImages,
"info": CmdInfo,
"inspect": CmdInspect,
@ -65,7 +66,7 @@ func cmdHelp(args []string) error {
// {"attach", "Attach to a running container"},
{"commit", "Create a new image from a container's changes"},
{"diff", "Inspect changes on a container's filesystem"},
// {"export", "Stream the contents of a container as a tar archive"},
{"export", "Stream the contents of a container as a tar archive"},
{"history", "Show the history of an image"},
{"images", "List images"},
// {"import", "Create a new filesystem image from the contents of a tarball"},
@ -759,29 +760,22 @@ func CmdCommit(args []string) error {
return nil
}
/*
func (srv *Server) CmdExport(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
cmd := rcli.Subcmd(stdout,
"export", "CONTAINER",
"Export the contents of a filesystem as a tar archive")
func CmdExport(args []string) error {
cmd := Subcmd("export", "CONTAINER", "Export the contents of a filesystem as a tar archive")
if err := cmd.Parse(args); err != nil {
return nil
}
name := cmd.Arg(0)
if container := srv.runtime.Get(name); container != nil {
data, err := container.Export()
if err != nil {
return err
}
// Stream the entire contents of the container (basically a volatile snapshot)
if _, err := io.Copy(stdout, data); err != nil {
return err
}
if cmd.NArg() != 1 {
cmd.Usage()
return nil
}
return fmt.Errorf("No such container: %s", name)
if err := callStream("GET", "/containers/"+cmd.Arg(0)+"/export", nil, false); err != nil {
return err
}
return nil
}
*/
func CmdDiff(args []string) error {
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
}
clientconn := httputil.NewClientConn(dial, nil)
clientconn.Do(req)
resp, err := clientconn.Do(req)
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()
defer rwc.Close()