1Panel/backend/app/service/docker.go

195 lines
5.0 KiB
Go
Raw Normal View History

2022-11-14 19:19:42 +08:00
package service
import (
"bufio"
2023-01-05 17:29:27 +08:00
"context"
2022-11-14 19:19:42 +08:00
"encoding/json"
"os"
2023-01-05 17:29:27 +08:00
"path"
2022-11-14 19:19:42 +08:00
"strings"
"github.com/1Panel-dev/1Panel/backend/app/dto"
2022-11-18 16:14:23 +08:00
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
2023-01-05 17:29:27 +08:00
"github.com/1Panel-dev/1Panel/backend/utils/docker"
2022-11-18 16:14:23 +08:00
"github.com/pkg/errors"
2022-11-14 19:19:42 +08:00
)
type DockerService struct{}
type IDockerService interface {
UpdateConf(req dto.DaemonJsonConf) error
UpdateConfByFile(info dto.DaemonJsonUpdateByFile) error
2022-12-07 17:28:14 +08:00
LoadDockerStatus() string
LoadDockerConf() *dto.DaemonJsonConf
OperateDocker(req dto.DockerOperation) error
2022-11-14 19:19:42 +08:00
}
func NewIDockerService() IDockerService {
return &DockerService{}
}
type daemonJsonItem struct {
Status string `json:"status"`
Mirrors []string `json:"registry-mirrors"`
Registries []string `json:"insecure-registries"`
LiveRestore bool `json:"live-restore"`
ExecOpts []string `json:"exec-opts"`
}
2022-12-07 17:28:14 +08:00
func (u *DockerService) LoadDockerStatus() string {
status := constant.StatusRunning
stdout, err := cmd.Exec("systemctl is-active docker")
if string(stdout) != "active\n" || err != nil {
status = constant.Stopped
}
2022-12-08 11:56:07 +08:00
2022-12-07 17:28:14 +08:00
return status
}
func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf {
status := constant.StatusRunning
stdout, err := cmd.Exec("systemctl is-active docker")
2022-12-08 11:56:07 +08:00
if string(stdout) != "active\n" || err != nil {
2022-12-07 17:28:14 +08:00
status = constant.Stopped
}
2023-01-05 17:29:27 +08:00
version := "-"
client, err := docker.NewDockerClient()
if err == nil {
ctx := context.Background()
itemVersion, err := client.ServerVersion(ctx)
if err == nil {
version = itemVersion.Version
}
2022-12-07 17:28:14 +08:00
}
2023-01-05 17:29:27 +08:00
if _, err := os.Stat(constant.DaemonJsonPath); err != nil {
return &dto.DaemonJsonConf{Status: status, Version: version}
2022-12-07 17:28:14 +08:00
}
file, err := os.ReadFile(constant.DaemonJsonPath)
2022-12-07 17:28:14 +08:00
if err != nil {
2023-01-05 17:29:27 +08:00
return &dto.DaemonJsonConf{Status: status, Version: version}
2022-11-14 19:19:42 +08:00
}
var conf daemonJsonItem
deamonMap := make(map[string]interface{})
if err := json.Unmarshal(file, &deamonMap); err != nil {
2023-01-05 17:29:27 +08:00
return &dto.DaemonJsonConf{Status: status, Version: version}
2022-11-14 19:19:42 +08:00
}
arr, err := json.Marshal(deamonMap)
if err != nil {
2023-01-05 17:29:27 +08:00
return &dto.DaemonJsonConf{Status: status, Version: version}
2022-11-14 19:19:42 +08:00
}
if err := json.Unmarshal(arr, &conf); err != nil {
2023-01-05 17:29:27 +08:00
return &dto.DaemonJsonConf{Status: status, Version: version}
2022-11-14 19:19:42 +08:00
}
driver := "cgroupfs"
for _, opt := range conf.ExecOpts {
if strings.HasPrefix(opt, "native.cgroupdriver=") {
driver = strings.ReplaceAll(opt, "native.cgroupdriver=", "")
break
}
}
data := dto.DaemonJsonConf{
2022-12-07 17:28:14 +08:00
Status: status,
2023-01-05 17:29:27 +08:00
Version: version,
2022-11-14 19:19:42 +08:00
Mirrors: conf.Mirrors,
Registries: conf.Registries,
LiveRestore: conf.LiveRestore,
CgroupDriver: driver,
}
2022-12-07 17:28:14 +08:00
return &data
2022-11-14 19:19:42 +08:00
}
func (u *DockerService) UpdateConf(req dto.DaemonJsonConf) error {
2023-01-05 17:29:27 +08:00
if _, err := os.Stat(constant.DaemonJsonPath); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(path.Dir(constant.DaemonJsonPath), os.ModePerm); err != nil {
return err
2022-12-07 17:28:14 +08:00
}
2023-01-05 17:29:27 +08:00
_, _ = os.Create(constant.DaemonJsonPath)
2022-12-07 17:28:14 +08:00
}
file, err := os.ReadFile(constant.DaemonJsonPath)
2022-12-07 17:28:14 +08:00
if err != nil {
2022-11-14 19:19:42 +08:00
return err
}
2022-12-07 17:28:14 +08:00
deamonMap := make(map[string]interface{})
_ = json.Unmarshal(file, &deamonMap)
2022-12-02 14:10:01 +08:00
if len(req.Registries) == 0 {
delete(deamonMap, "insecure-registries")
} else {
deamonMap["insecure-registries"] = req.Registries
}
if len(req.Mirrors) == 0 {
delete(deamonMap, "registry-mirrors")
2022-12-02 14:10:01 +08:00
} else {
deamonMap["registry-mirrors"] = req.Mirrors
2022-12-02 14:10:01 +08:00
}
if !req.LiveRestore {
delete(deamonMap, "live-restore")
} else {
deamonMap["live-restore"] = req.LiveRestore
}
2022-11-14 19:19:42 +08:00
if opts, ok := deamonMap["exec-opts"]; ok {
if optsValue, isArray := opts.([]interface{}); isArray {
for i := 0; i < len(optsValue); i++ {
if opt, isStr := optsValue[i].(string); isStr {
if strings.HasPrefix(opt, "native.cgroupdriver=") {
optsValue[i] = "native.cgroupdriver=" + req.CgroupDriver
break
}
}
}
}
} else {
if req.CgroupDriver == "systemd" {
deamonMap["exec-opts"] = []string{"native.cgroupdriver=systemd"}
}
}
newJson, err := json.MarshalIndent(deamonMap, "", "\t")
if err != nil {
return err
}
if err := os.WriteFile(constant.DaemonJsonPath, newJson, 0640); err != nil {
2022-11-14 19:19:42 +08:00
return err
}
2022-11-18 16:14:23 +08:00
stdout, err := cmd.Exec("systemctl restart docker")
2022-11-18 16:14:23 +08:00
if err != nil {
return errors.New(string(stdout))
}
2022-11-14 19:19:42 +08:00
return nil
}
func (u *DockerService) UpdateConfByFile(req dto.DaemonJsonUpdateByFile) error {
2023-03-10 18:05:02 +08:00
file, err := os.OpenFile(constant.DaemonJsonPath, os.O_WRONLY|os.O_TRUNC, 0640)
2022-11-14 19:19:42 +08:00
if err != nil {
return err
}
defer file.Close()
write := bufio.NewWriter(file)
_, _ = write.WriteString(req.File)
write.Flush()
stdout, err := cmd.Exec("systemctl restart docker")
2022-11-18 16:14:23 +08:00
if err != nil {
return errors.New(string(stdout))
}
2022-11-14 19:19:42 +08:00
return nil
}
2022-12-07 17:28:14 +08:00
func (u *DockerService) OperateDocker(req dto.DockerOperation) error {
service := "docker"
if req.Operation == "stop" {
service = "docker.service"
if req.StopSocket {
service = "docker.socket"
}
}
stdout, err := cmd.Execf("systemctl %s %s ", req.Operation, service)
2022-12-07 17:28:14 +08:00
if err != nil {
return errors.New(string(stdout))
}
return nil
}