swirl/biz/container.go

201 lines
5.9 KiB
Go
Raw Normal View History

2021-12-06 12:24:22 +00:00
package biz
import (
"context"
"time"
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/docker"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/mount"
)
2021-12-16 12:23:08 +00:00
type ContainerBiz interface {
2021-12-17 12:13:58 +00:00
Search(node, name, status string, pageIndex, pageSize int) ([]*Container, int, error)
Find(node, id string) (container *Container, raw string, err error)
Delete(node, id string, user web.User) (err error)
FetchLogs(node, id string, lines int, timestamps bool) (stdout, stderr string, err error)
ExecCreate(node, id string, cmd string) (resp types.IDResponse, err error)
ExecAttach(node, id string) (resp types.HijackedResponse, err error)
ExecStart(node, id string) error
2021-12-16 12:23:08 +00:00
}
func NewContainer(d *docker.Docker) ContainerBiz {
return &containerBiz{d: d}
}
type containerBiz struct {
d *docker.Docker
}
2021-12-17 12:13:58 +00:00
func (b *containerBiz) Find(node, id string) (c *Container, raw string, err error) {
2021-12-16 12:23:08 +00:00
var (
cj types.ContainerJSON
r []byte
)
2021-12-17 12:13:58 +00:00
if cj, r, err = b.d.ContainerInspect(context.TODO(), node, id); err == nil {
2021-12-16 12:23:08 +00:00
raw, err = indentJSON(r)
}
if err == nil {
c = newContainerDetail(&cj)
}
return
}
2021-12-17 12:13:58 +00:00
func (b *containerBiz) Search(node, name, status string, pageIndex, pageSize int) (containers []*Container, total int, err error) {
list, total, err := b.d.ContainerList(context.TODO(), node, name, status, pageIndex, pageSize)
2021-12-16 12:23:08 +00:00
if err != nil {
return nil, 0, err
}
containers = make([]*Container, len(list))
for i, nr := range list {
containers[i] = newContainerSummary(&nr)
}
return containers, total, nil
}
2021-12-17 12:13:58 +00:00
func (b *containerBiz) Delete(node, id string, user web.User) (err error) {
err = b.d.ContainerRemove(context.TODO(), node, id)
2021-12-16 12:23:08 +00:00
//if err == nil {
// Event.CreateContainer(model.EventActionDelete, id, user)
//}
return
}
2021-12-17 12:13:58 +00:00
func (b *containerBiz) ExecCreate(node, id, cmd string) (resp types.IDResponse, err error) {
return b.d.ContainerExecCreate(context.TODO(), node, id, cmd)
2021-12-16 12:23:08 +00:00
}
2021-12-17 12:13:58 +00:00
func (b *containerBiz) ExecAttach(node, id string) (resp types.HijackedResponse, err error) {
return b.d.ContainerExecAttach(context.TODO(), node, id)
2021-12-16 12:23:08 +00:00
}
2021-12-17 12:13:58 +00:00
func (b *containerBiz) ExecStart(node, id string) error {
return b.d.ContainerExecStart(context.TODO(), node, id)
2021-12-16 12:23:08 +00:00
}
2021-12-17 12:13:58 +00:00
func (b *containerBiz) FetchLogs(node, id string, lines int, timestamps bool) (string, string, error) {
stdout, stderr, err := b.d.ContainerLogs(context.TODO(), node, id, lines, timestamps)
2021-12-16 12:23:08 +00:00
if err != nil {
return "", "", err
}
return stdout.String(), stderr.String(), nil
}
2021-12-06 12:24:22 +00:00
type Container struct {
ID string `json:"id"`
Name string `json:"name"`
Image string `json:"image,omitempty"`
Command string `json:"command,omitempty"`
CreatedAt string `json:"createdAt"`
Ports []*ContainerPort `json:"ports,omitempty"`
SizeRw int64 `json:"sizeRw"`
SizeRootFs int64 `json:"sizeRootFs"`
Labels data.Options `json:"labels"`
State string `json:"state"`
Status string `json:"status"`
NetworkMode string `json:"networkMode"`
Mounts []*ContainerMount `json:"mounts"`
2021-12-16 12:23:08 +00:00
PID int `json:"pid,omitempty"`
StartedAt string `json:"startedAt,omitempty"`
2021-12-06 12:24:22 +00:00
}
type ContainerPort struct {
IP string `json:"ip,omitempty"`
PrivatePort uint16 `json:"privatePort,omitempty"`
PublicPort uint16 `json:"publicPort,omitempty"`
Type string `json:"type,omitempty"`
}
type ContainerMount struct {
Type mount.Type `json:"type,omitempty"`
Name string `json:"name,omitempty"`
Source string `json:"source,omitempty"`
Destination string `json:"destination,omitempty"`
Driver string `json:"driver,omitempty"`
Mode string `json:"mode,omitempty"`
RW bool `json:"rw,omitempty"`
Propagation mount.Propagation `json:"propagation,omitempty"`
}
func newContainerMount(m types.MountPoint) *ContainerMount {
return &ContainerMount{
Type: m.Type,
Name: m.Name,
Source: m.Source,
Destination: m.Destination,
Driver: m.Driver,
Mode: m.Mode,
RW: m.RW,
Propagation: m.Propagation,
}
}
func newContainerSummary(c *types.Container) *Container {
container := &Container{
ID: c.ID,
Name: c.Names[0],
Image: normalizeImage(c.Image),
Command: c.Command,
CreatedAt: formatTime(time.Unix(c.Created, 0)),
SizeRw: c.SizeRw,
SizeRootFs: c.SizeRootFs,
Labels: mapToOptions(c.Labels),
State: c.State,
Status: c.Status,
NetworkMode: c.HostConfig.NetworkMode,
}
for _, p := range c.Ports {
container.Ports = append(container.Ports, &ContainerPort{
IP: p.IP,
PrivatePort: p.PrivatePort,
PublicPort: p.PublicPort,
Type: p.Type,
})
}
for _, m := range c.Mounts {
container.Mounts = append(container.Mounts, newContainerMount(m))
}
return container
}
func newContainerDetail(c *types.ContainerJSON) *Container {
created, _ := time.Parse(time.RFC3339Nano, c.Created)
startedAt, _ := time.Parse(time.RFC3339Nano, c.State.StartedAt)
container := &Container{
ID: c.ID,
Name: c.Name,
Image: c.Image,
//Command: c.Command,
CreatedAt: formatTime(created),
Labels: mapToOptions(c.Config.Labels),
State: c.State.Status,
//Status: c.Status,
NetworkMode: string(c.HostConfig.NetworkMode),
2021-12-16 12:23:08 +00:00
PID: c.State.Pid,
StartedAt: formatTime(startedAt),
2021-12-06 12:24:22 +00:00
}
if c.SizeRw != nil {
container.SizeRw = *c.SizeRw
}
if c.SizeRootFs != nil {
container.SizeRootFs = *c.SizeRootFs
}
//for _, p := range c.Ports {
// container.Ports = append(container.Ports, &ContainerPort{
// IP: p.IP,
// PrivatePort: p.PrivatePort,
// PublicPort: p.PublicPort,
// Type: p.Type,
// })
//}
for _, m := range c.Mounts {
container.Mounts = append(container.Mounts, newContainerMount(m))
}
return container
}