package docker import ( "bytes" "context" "io" "strconv" "strings" "github.com/cuigh/swirl/misc" "github.com/cuigh/swirl/model" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" ) // ContainerList return containers on the host. func ContainerList(args *model.ContainerListArgs) (infos []*model.ContainerListInfo, totalCount int, err error) { err = mgr.Do(func(ctx context.Context, cli *client.Client) (err error) { var ( containers []types.Container opts = types.ContainerListOptions{Filters: filters.NewArgs()} ) if args.Filter == "" { opts.All = true } else { opts.Filters.Add("status", args.Filter) } if args.Name != "" { opts.Filters.Add("name", args.Name) } containers, err = cli.ContainerList(ctx, opts) if err == nil { //sort.Slice(containers, func(i, j int) bool { // return containers[i] < containers[j].Description.Hostname //}) totalCount = len(containers) start, end := misc.Page(totalCount, args.PageIndex, args.PageSize) containers = containers[start:end] if length := len(containers); length > 0 { infos = make([]*model.ContainerListInfo, length) for i, c := range containers { infos[i] = model.NewContainerListInfo(c) } } } return }) return } // ContainerInspect return detail information of a container. func ContainerInspect(id string) (container types.ContainerJSON, err error) { err = mgr.Do(func(ctx context.Context, cli *client.Client) (err error) { container, err = cli.ContainerInspect(ctx, id) return }) return } // ContainerInspectRaw return container raw information. func ContainerInspectRaw(id string) (container types.ContainerJSON, raw []byte, err error) { var ( ctx context.Context cli *client.Client ) if ctx, cli, err = mgr.Client(); err == nil { container, raw, err = cli.ContainerInspectWithRaw(ctx, id, true) } return } // ContainerRemove remove a container. func ContainerRemove(id string) error { return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) { opts := types.ContainerRemoveOptions{} err = cli.ContainerRemove(ctx, id, opts) return }) } // ContainerLogs returns the logs generated by a container. func ContainerLogs(id string, line int, timestamps bool) (stdout, stderr *bytes.Buffer, err error) { var ( ctx context.Context cli *client.Client rc io.ReadCloser ) ctx, cli, err = mgr.Client() if err != nil { return } opts := types.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, Tail: strconv.Itoa(line), Timestamps: timestamps, //Since: (time.Hour * 24).String() } if rc, err = cli.ContainerLogs(ctx, id, opts); err == nil { defer rc.Close() stdout = &bytes.Buffer{} stderr = &bytes.Buffer{} _, err = stdcopy.StdCopy(stdout, stderr, rc) } return } // ContainerExecCreate creates an exec instance. func ContainerExecCreate(id string, cmd string) (resp types.IDResponse, err error) { err = mgr.Do(func(ctx context.Context, cli *client.Client) (err error) { opts := types.ExecConfig{ AttachStdin: true, AttachStdout: true, AttachStderr: true, Tty: true, //User: "root", Cmd: strings.Split(cmd, " "), } //cli.DialSession() resp, err = cli.ContainerExecCreate(ctx, id, opts) return }) return } // ContainerExecAttach attaches a connection to an exec process in the server. func ContainerExecAttach(id string) (resp types.HijackedResponse, err error) { err = mgr.Do(func(ctx context.Context, cli *client.Client) (err error) { opts := types.ExecStartCheck{ Detach: false, Tty: true, } resp, err = cli.ContainerExecAttach(ctx, id, opts) return err }) return } // ContainerExecStart starts an exec instance. func ContainerExecStart(id string) error { return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) { opts := types.ExecStartCheck{ Detach: false, Tty: true, } return cli.ContainerExecStart(ctx, id, opts) }) }