[] instead fon null, timetsamps and wip import

This commit is contained in:
Victor Vieux 2013-04-30 17:04:31 +02:00
parent 131c6ab3e6
commit 36b968bb09
3 changed files with 99 additions and 54 deletions

89
api.go
View File

@ -10,11 +10,11 @@ import (
"log"
"net"
"net/http"
"net/url"
"os"
"runtime"
"strconv"
"strings"
"time"
)
func ListenAndServe(addr string, rtime *Runtime) error {
@ -105,7 +105,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
w.WriteHeader(500)
return
}
var outs []ApiImages
var outs []ApiImages = []ApiImages{} //produce [] when empty instead of 'null'
for name, repository := range rtime.repositories.Repositories {
if NameFilter != "" && name != NameFilter {
continue
@ -122,7 +122,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
out.Repository = name
out.Tag = tag
out.Id = TruncateId(id)
out.Created = HumanDuration(time.Now().Sub(image.Created)) + " ago"
out.Created = image.Created.Unix()
} else {
out.Id = image.ShortId()
}
@ -137,7 +137,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
out.Repository = "<none>"
out.Tag = "<none>"
out.Id = TruncateId(id)
out.Created = HumanDuration(time.Now().Sub(image.Created)) + " ago"
out.Created = image.Created.Unix()
} else {
out.Id = image.ShortId()
}
@ -189,11 +189,12 @@ func ListenAndServe(addr string, rtime *Runtime) error {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var outs []ApiHistory
var outs []ApiHistory = []ApiHistory{} //produce [] when empty instead of 'null'
err = image.WalkHistory(func(img *Image) error {
var out ApiHistory
out.Id = rtime.repositories.ImageName(img.ShortId())
out.Created = HumanDuration(time.Now().Sub(img.Created)) + " ago"
out.Created = img.Created.Unix()
out.CreatedBy = strings.Join(img.ContainerConfig.Cmd, " ")
return nil
})
@ -318,8 +319,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
if err != nil {
n = -1
}
var outs []ApiContainers
var outs []ApiContainers = []ApiContainers{} //produce [] when empty instead of 'null'
for i, container := range rtime.List() {
if !container.State.Running && All != "1" && n == -1 {
continue
@ -336,7 +336,7 @@ func ListenAndServe(addr string, rtime *Runtime) error {
}
out.Image = rtime.repositories.ImageName(container.Image)
out.Command = command
out.Created = HumanDuration(time.Now().Sub(container.Created)) + " ago"
out.Created = container.Created.Unix()
out.Status = container.State.String()
}
outs = append(outs, out)
@ -427,6 +427,77 @@ func ListenAndServe(addr string, rtime *Runtime) error {
}
})
/* /!\ W.I.P /!\ */
r.Path("/images").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println(r.Method, r.RequestURI)
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
src := r.Form.Get("src")
repo := r.Form.Get("repo")
tag := r.Form.Get("tag")
var archive io.Reader
var resp *http.Response
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 201 Created\r\nContent-Type: application/json\r\n\r\n")
if src == "-" {
r, w := io.Pipe()
go func() {
defer w.Close()
defer Debugf("Closing buffered stdin pipe")
io.Copy(w, file)
}()
archive = r
} else {
u, err := url.Parse(src)
if err != nil {
fmt.Fprintln(file, "Error: "+err.Error())
}
if u.Scheme == "" {
u.Scheme = "http"
u.Host = src
u.Path = ""
}
fmt.Fprintln(file, "Downloading from", u)
// Download with curl (pretty progress bar)
// If curl is not available, fallback to http.Get()
resp, err = Download(u.String(), file)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
archive = ProgressReader(resp.Body, int(resp.ContentLength), file)
}
img, err := rtime.graph.Create(archive, nil, "Imported from "+src)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Optionally register the image at REPO/TAG
if repo != "" {
if err := rtime.repositories.Set(repo, tag, img.Id, true); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
fmt.Fprintln(file, img.ShortId())
})
r.Path("/containers").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println(r.Method, r.RequestURI)
var config Config

View File

@ -2,7 +2,7 @@ package docker
type ApiHistory struct {
Id string
Created string
Created int64
CreatedBy string
}
@ -10,7 +10,7 @@ type ApiImages struct {
Repository string `json:",omitempty"`
Tag string `json:",omitempty"`
Id string
Created string `json:",omitempty"`
Created int64 `json:",omitempty"`
}
type ApiInfo struct {
@ -26,7 +26,7 @@ type ApiContainers struct {
Id string
Image string `json:",omitempty"`
Command string `json:",omitempty"`
Created string `json:",omitempty"`
Created int64 `json:",omitempty"`
Status string `json:",omitempty"`
}

View File

@ -15,6 +15,7 @@ import (
"os"
"strconv"
"text/tabwriter"
"time"
)
const VERSION = "0.1.4"
@ -34,6 +35,7 @@ func ParseCommands(args []string) error {
"images": CmdImages,
"info": CmdInfo,
"inspect": CmdInspect,
//"import": CmdImport,
"history": CmdHistory,
"kill": CmdKill,
"logs": CmdLogs,
@ -71,7 +73,7 @@ func cmdHelp(args []string) error {
{"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"},
//{"import", "Create a new filesystem image from the contents of a tarball"},
{"info", "Display system-wide information"},
{"inspect", "Return low-level information on a container/image"},
{"kill", "Kill a running container"},
@ -436,7 +438,7 @@ func CmdHistory(args []string) error {
fmt.Fprintln(w, "ID\tCREATED\tCREATED BY")
for _, out := range outs {
fmt.Fprintf(w, "%s\t%s\t%s\n", out.Id, out.Created, out.CreatedBy)
fmt.Fprintf(w, "%s\t%s ago\t%s\n", out.Id, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.CreatedBy)
}
w.Flush()
return nil
@ -485,12 +487,9 @@ func CmdKill(args []string) error {
return nil
}
/*
func (srv *Server) CmdImport(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error {
stdout.Flush()
cmd := rcli.Subcmd(stdout, "import", "URL|- [REPOSITORY [TAG]]", "Create a new filesystem image from the contents of a tarball")
var archive io.Reader
var resp *http.Response
/* /!\ W.I.P /!\ */
func CmdImport(args []string) error {
cmd := Subcmd("import", "URL|- [REPOSITORY [TAG]]", "Create a new filesystem image from the contents of a tarball")
if err := cmd.Parse(args); err != nil {
return nil
@ -499,43 +498,18 @@ func (srv *Server) CmdImport(stdin io.ReadCloser, stdout rcli.DockerConn, args .
cmd.Usage()
return nil
}
src := cmd.Arg(0)
if src == "-" {
archive = stdin
} else {
u, err := url.Parse(src)
if err != nil {
return err
}
if u.Scheme == "" {
u.Scheme = "http"
u.Host = src
u.Path = ""
}
fmt.Fprintln(stdout, "Downloading from", u)
// Download with curl (pretty progress bar)
// If curl is not available, fallback to http.Get()
resp, err = Download(u.String(), stdout)
if err != nil {
return err
}
archive = ProgressReader(resp.Body, int(resp.ContentLength), stdout)
}
img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src)
src, repository, tag := cmd.Arg(0), cmd.Arg(1), cmd.Arg(2)
v := url.Values{}
v.Set("repo", repository)
v.Set("tag", tag)
v.Set("src", src)
err := callStream("POST", "/images?"+v.Encode(), nil, false)
if err != nil {
return err
}
// Optionally register the image at REPO/TAG
if repository := cmd.Arg(1); repository != "" {
tag := cmd.Arg(2) // Repository will handle an empty tag properly
if err := srv.runtime.repositories.Set(repository, tag, img.Id, true); err != nil {
return err
}
}
fmt.Fprintln(stdout, img.ShortId())
return nil
}
*/
/*
func (srv *Server) CmdPush(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error {
@ -656,7 +630,7 @@ func CmdImages(args []string) error {
for _, out := range outs {
if !*quiet {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", out.Repository, out.Tag, out.Id, out.Created)
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\n", out.Repository, out.Tag, out.Id, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))))
} else {
fmt.Fprintln(w, out.Id)
}
@ -713,7 +687,7 @@ func CmdPs(args []string) error {
for _, out := range outs {
if !*quiet {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", out.Id, out.Image, out.Command, out.Status, out.Created)
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\n", out.Id, out.Image, out.Command, out.Status, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))))
} else {
fmt.Fprintln(w, out.Id)
}