From 705a339e49405185878d9393d836c76eccf6b9bc Mon Sep 17 00:00:00 2001 From: Amir Raminfar Date: Mon, 26 Nov 2018 14:52:20 -0800 Subject: [PATCH] Adds sorting and cleans up ids and names --- assets/App.vue | 6 ++--- docker/client.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ docker/types.go | 13 +++++++++ main.go | 37 +++++++++++++------------- 4 files changed, 103 insertions(+), 22 deletions(-) create mode 100644 docker/client.go create mode 100644 docker/types.go diff --git a/assets/App.vue b/assets/App.vue index 9eecda8e..0b9b464d 100644 --- a/assets/App.vue +++ b/assets/App.vue @@ -14,12 +14,12 @@ diff --git a/docker/client.go b/docker/client.go new file mode 100644 index 00000000..b07f7775 --- /dev/null +++ b/docker/client.go @@ -0,0 +1,69 @@ +package docker + +import ( + "context" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/events" + "github.com/docker/docker/client" + "io" + "log" + "sort" + "strings" +) + +type dockerClient struct { + cli *client.Client +} + +type DockerClient interface { + ListContainers() ([]Container, error) + ContainerLogs(ctx context.Context, id string) (io.ReadCloser, error) + Events(ctx context.Context) (<-chan events.Message, <-chan error) +} + +func NewDockerClient() DockerClient { + cli, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + log.Fatal(err) + } + return &dockerClient{cli} +} + +func (d *dockerClient) ListContainers() ([]Container, error) { + list, err := d.cli.ContainerList(context.Background(), types.ContainerListOptions{}) + if err != nil { + return nil, err + } + + var containers []Container + for _, c := range list { + + container := Container{ + ID: c.ID[:12], + Names: c.Names, + Name: strings.TrimPrefix(c.Names[0], "/"), + Image: c.Image, + ImageID: c.ImageID, + Command: c.Command, + Created: c.Created, + State: c.State, + Status: c.Status, + } + containers = append(containers, container) + } + + sort.Slice(containers, func(i, j int) bool { + return containers[i].Name < containers[j].Name + }) + + return containers, nil +} + +func (d *dockerClient) ContainerLogs(ctx context.Context, id string) (io.ReadCloser, error) { + options := types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Follow: true, Tail: "300", Timestamps: true} + return d.cli.ContainerLogs(ctx, id, options) +} + +func (d *dockerClient) Events(ctx context.Context) (<-chan events.Message, <-chan error) { + return d.cli.Events(ctx, types.EventsOptions{}) +} diff --git a/docker/types.go b/docker/types.go new file mode 100644 index 00000000..5f7620ea --- /dev/null +++ b/docker/types.go @@ -0,0 +1,13 @@ +package docker + +type Container struct { + ID string `json:"id"` + Names []string `json:"names"` + Name string `json:"name"` + Image string `json:"image"` + ImageID string `json:"imageId"` + Command string `json:"command"` + Created int64 `json:"created"` + State string `json:"state"` + Status string `json:"status"` +} diff --git a/main.go b/main.go index 8226872b..3393c346 100644 --- a/main.go +++ b/main.go @@ -5,8 +5,7 @@ import ( "encoding/binary" "encoding/json" "fmt" - "github.com/docker/docker/api/types" - "github.com/docker/docker/client" + "github.com/amir20/dozzle/docker" "github.com/gobuffalo/packr" "github.com/gorilla/mux" flag "github.com/spf13/pflag" @@ -17,23 +16,19 @@ import ( ) var ( - cli *client.Client - addr = "" - base = "/" - version = "dev" - commit = "none" - date = "unknown" + dockerClient docker.DockerClient + addr = "" + base = "/" + version = "dev" + commit = "none" + date = "unknown" ) func init() { flag.StringVar(&addr, "addr", ":8080", "http service address") flag.StringVar(&base, "base", "/", "base address of the application to mount") - var err error - cli, err = client.NewClientWithOpts(client.FromEnv) - if err != nil { - log.Fatal(err) - } + dockerClient = docker.NewDockerClient() flag.Parse() } @@ -73,11 +68,16 @@ func versionHandler(w http.ResponseWriter, r *http.Request) { } func listContainers(w http.ResponseWriter, r *http.Request) { - containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}) + containers, err := dockerClient.ListContainers() if err != nil { - log.Fatal(err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + err = json.NewEncoder(w).Encode(containers) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return } - json.NewEncoder(w).Encode(containers) } func handleIndex(box packr.Box, w http.ResponseWriter) { @@ -113,10 +113,9 @@ func streamLogs(w http.ResponseWriter, r *http.Request) { return } - options := types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Follow: true, Tail: "300", Timestamps: true} ctx, cancel := context.WithCancel(context.Background()) defer cancel() - reader, err := cli.ContainerLogs(ctx, id, options) + reader, err := dockerClient.ContainerLogs(ctx, id) if err != nil { log.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -165,7 +164,7 @@ func streamEvents(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - messages, _ := cli.Events(ctx, types.EventsOptions{}) + messages, _ := dockerClient.Events(ctx) for message := range messages { switch message.Action {