2021-12-06 12:24:22 +00:00
|
|
|
package biz
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/cuigh/auxo/data"
|
|
|
|
"github.com/cuigh/swirl/docker"
|
|
|
|
"github.com/docker/docker/api/types/swarm"
|
|
|
|
)
|
|
|
|
|
2021-12-16 12:23:08 +00:00
|
|
|
type TaskBiz interface {
|
2022-01-06 08:54:14 +00:00
|
|
|
Search(ctx context.Context, node, service, mode string, pageIndex, pageSize int) (tasks []*Task, total int, err error)
|
|
|
|
Find(ctx context.Context, id string) (task *Task, raw string, err error)
|
|
|
|
FetchLogs(ctx context.Context, id string, lines int, timestamps bool) (stdout, stderr string, err error)
|
2021-12-16 12:23:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewTask(d *docker.Docker) TaskBiz {
|
|
|
|
return &taskBiz{d: d}
|
|
|
|
}
|
|
|
|
|
|
|
|
type taskBiz struct {
|
|
|
|
d *docker.Docker
|
|
|
|
}
|
|
|
|
|
2022-01-06 08:54:14 +00:00
|
|
|
func (b *taskBiz) Find(ctx context.Context, id string) (task *Task, raw string, err error) {
|
2021-12-16 12:23:08 +00:00
|
|
|
var (
|
|
|
|
t swarm.Task
|
|
|
|
s swarm.Service
|
|
|
|
r []byte
|
|
|
|
)
|
2021-12-20 06:28:43 +00:00
|
|
|
|
2022-01-06 08:54:14 +00:00
|
|
|
t, r, err = b.d.TaskInspect(ctx, id)
|
2021-12-24 11:52:29 +00:00
|
|
|
if err != nil {
|
|
|
|
if docker.IsErrNotFound(err) {
|
|
|
|
err = nil
|
|
|
|
}
|
|
|
|
return
|
2021-12-16 12:23:08 +00:00
|
|
|
}
|
2021-12-20 06:28:43 +00:00
|
|
|
|
2021-12-24 11:52:29 +00:00
|
|
|
raw, err = indentJSON(r)
|
2021-12-16 12:23:08 +00:00
|
|
|
if err == nil {
|
2021-12-20 06:28:43 +00:00
|
|
|
m, _ := b.d.NodeMap()
|
|
|
|
task = newTask(&t, m)
|
|
|
|
|
|
|
|
// Fill service name
|
2022-01-06 08:54:14 +00:00
|
|
|
if s, _, _ = b.d.ServiceInspect(ctx, t.ServiceID, false); s.Spec.Name == "" {
|
2021-12-16 12:23:08 +00:00
|
|
|
task.ServiceName = task.ServiceID
|
|
|
|
} else {
|
|
|
|
task.ServiceName = s.Spec.Name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-01-06 08:54:14 +00:00
|
|
|
func (b *taskBiz) Search(ctx context.Context, node, service, state string, pageIndex, pageSize int) (tasks []*Task, total int, err error) {
|
2021-12-16 12:23:08 +00:00
|
|
|
var list []swarm.Task
|
2022-01-06 08:54:14 +00:00
|
|
|
list, total, err = b.d.TaskList(ctx, node, service, state, pageIndex, pageSize)
|
2021-12-16 12:23:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-12-20 06:28:43 +00:00
|
|
|
m, _ := b.d.NodeMap()
|
2021-12-16 12:23:08 +00:00
|
|
|
tasks = make([]*Task, len(list))
|
|
|
|
for i, t := range list {
|
2021-12-20 06:28:43 +00:00
|
|
|
tasks[i] = newTask(&t, m)
|
|
|
|
if m != nil {
|
|
|
|
if n, ok := m[t.NodeID]; ok {
|
|
|
|
tasks[i].NodeName = n.Name
|
|
|
|
}
|
|
|
|
}
|
2021-12-16 12:23:08 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-01-06 08:54:14 +00:00
|
|
|
func (b *taskBiz) FetchLogs(ctx context.Context, id string, lines int, timestamps bool) (string, string, error) {
|
|
|
|
stdout, stderr, err := b.d.TaskLogs(ctx, 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 Task struct {
|
|
|
|
ID string `json:"id"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
Version uint64 `json:"version"`
|
|
|
|
Image string `json:"image"`
|
|
|
|
Slot int `json:"slot"`
|
|
|
|
State swarm.TaskState `json:"state"`
|
|
|
|
ServiceID string `json:"serviceId"`
|
|
|
|
ServiceName string `json:"serviceName"`
|
|
|
|
NodeID string `json:"nodeId"`
|
2021-12-20 06:28:43 +00:00
|
|
|
NodeName string `json:"nodeName"`
|
2021-12-06 12:24:22 +00:00
|
|
|
ContainerID string `json:"containerId"`
|
|
|
|
PID int `json:"pid"`
|
|
|
|
ExitCode int `json:"exitCode"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
Error string `json:"error"`
|
|
|
|
Env data.Options `json:"env,omitempty"`
|
|
|
|
Labels data.Options `json:"labels,omitempty"`
|
|
|
|
Networks []TaskNetwork `json:"networks"`
|
|
|
|
CreatedAt string `json:"createdAt"`
|
|
|
|
UpdatedAt string `json:"updatedAt"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type TaskNetwork struct {
|
|
|
|
ID string `json:"id"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
IPs []string `json:"ips"`
|
|
|
|
}
|
|
|
|
|
2021-12-20 06:28:43 +00:00
|
|
|
func newTask(t *swarm.Task, nodes map[string]*docker.Node) *Task {
|
2021-12-06 12:24:22 +00:00
|
|
|
task := &Task{
|
|
|
|
ID: t.ID,
|
|
|
|
Name: t.Name,
|
|
|
|
Version: t.Version.Index,
|
|
|
|
Image: normalizeImage(t.Spec.ContainerSpec.Image),
|
|
|
|
Slot: t.Slot,
|
|
|
|
State: t.Status.State,
|
|
|
|
ServiceID: t.ServiceID,
|
|
|
|
NodeID: t.NodeID,
|
2021-12-20 06:28:43 +00:00
|
|
|
NodeName: t.NodeID,
|
2021-12-06 12:24:22 +00:00
|
|
|
Message: t.Status.Message,
|
|
|
|
Error: t.Status.Err,
|
|
|
|
Env: envToOptions(t.Spec.ContainerSpec.Env),
|
|
|
|
Labels: mapToOptions(t.Labels),
|
|
|
|
CreatedAt: formatTime(t.CreatedAt),
|
|
|
|
UpdatedAt: formatTime(t.UpdatedAt),
|
|
|
|
}
|
|
|
|
if t.Status.ContainerStatus != nil {
|
|
|
|
task.ContainerID = t.Status.ContainerStatus.ContainerID
|
|
|
|
task.PID = t.Status.ContainerStatus.PID
|
|
|
|
task.ExitCode = t.Status.ContainerStatus.ExitCode
|
|
|
|
}
|
|
|
|
for _, n := range t.NetworksAttachments {
|
|
|
|
task.Networks = append(task.Networks, TaskNetwork{
|
|
|
|
ID: n.Network.ID,
|
|
|
|
Name: n.Network.Spec.Name,
|
|
|
|
IPs: n.Addresses,
|
|
|
|
})
|
|
|
|
}
|
2021-12-20 06:28:43 +00:00
|
|
|
// Fill node name
|
|
|
|
if nodes != nil {
|
|
|
|
if n, ok := nodes[t.NodeID]; ok {
|
|
|
|
task.NodeName = n.Name
|
|
|
|
}
|
|
|
|
}
|
2021-12-06 12:24:22 +00:00
|
|
|
return task
|
|
|
|
}
|