mirror of https://github.com/1Panel-dev/1Panel
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
5.1 KiB
203 lines
5.1 KiB
package service
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type DockerService struct{}
|
|
|
|
type IDockerService interface {
|
|
UpdateConf(req dto.DaemonJsonConf) error
|
|
UpdateConfByFile(info dto.DaemonJsonUpdateByFile) error
|
|
LoadDockerStatus() string
|
|
LoadDockerConf() *dto.DaemonJsonConf
|
|
OperateDocker(req dto.DockerOperation) error
|
|
}
|
|
|
|
func NewIDockerService() IDockerService {
|
|
return &DockerService{}
|
|
}
|
|
|
|
type daemonJsonItem struct {
|
|
Status string `json:"status"`
|
|
Mirrors []string `json:"registry-mirrors"`
|
|
Registries []string `json:"insecure-registries"`
|
|
Bip string `json:"bip"`
|
|
LiveRestore bool `json:"live-restore"`
|
|
ExecOpts []string `json:"exec-opts"`
|
|
}
|
|
|
|
func (u *DockerService) LoadDockerStatus() string {
|
|
status := constant.StatusRunning
|
|
cmd := exec.Command("systemctl", "is-active", "docker")
|
|
stdout, err := cmd.CombinedOutput()
|
|
if string(stdout) != "active\n" || err != nil {
|
|
status = constant.Stopped
|
|
}
|
|
|
|
return status
|
|
}
|
|
|
|
func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf {
|
|
status := constant.StatusRunning
|
|
cmd := exec.Command("systemctl", "is-active", "docker")
|
|
stdout, err := cmd.CombinedOutput()
|
|
if string(stdout) != "active\n" || err != nil {
|
|
status = constant.Stopped
|
|
}
|
|
fileSetting, err := settingRepo.Get(settingRepo.WithByKey("DaemonJsonPath"))
|
|
if err != nil {
|
|
return &dto.DaemonJsonConf{Status: status}
|
|
}
|
|
if len(fileSetting.Value) == 0 {
|
|
return &dto.DaemonJsonConf{Status: status}
|
|
}
|
|
if _, err := os.Stat(fileSetting.Value); err != nil {
|
|
return &dto.DaemonJsonConf{Status: status}
|
|
}
|
|
file, err := ioutil.ReadFile(fileSetting.Value)
|
|
if err != nil {
|
|
return &dto.DaemonJsonConf{Status: status}
|
|
}
|
|
var conf daemonJsonItem
|
|
deamonMap := make(map[string]interface{})
|
|
if err := json.Unmarshal(file, &deamonMap); err != nil {
|
|
return &dto.DaemonJsonConf{Status: status}
|
|
}
|
|
arr, err := json.Marshal(deamonMap)
|
|
if err != nil {
|
|
return &dto.DaemonJsonConf{Status: status}
|
|
}
|
|
if err := json.Unmarshal(arr, &conf); err != nil {
|
|
return &dto.DaemonJsonConf{Status: status}
|
|
}
|
|
driver := "cgroupfs"
|
|
for _, opt := range conf.ExecOpts {
|
|
if strings.HasPrefix(opt, "native.cgroupdriver=") {
|
|
driver = strings.ReplaceAll(opt, "native.cgroupdriver=", "")
|
|
break
|
|
}
|
|
}
|
|
data := dto.DaemonJsonConf{
|
|
Status: status,
|
|
Mirrors: conf.Mirrors,
|
|
Registries: conf.Registries,
|
|
Bip: conf.Bip,
|
|
LiveRestore: conf.LiveRestore,
|
|
CgroupDriver: driver,
|
|
}
|
|
|
|
return &data
|
|
}
|
|
|
|
func (u *DockerService) UpdateConf(req dto.DaemonJsonConf) error {
|
|
fileSetting, err := settingRepo.Get(settingRepo.WithByKey("DaemonJsonPath"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(fileSetting.Value) == 0 {
|
|
return errors.New("error daemon.json path in request")
|
|
}
|
|
if _, err := os.Stat(fileSetting.Value); err != nil && os.IsNotExist(err) {
|
|
if err = os.MkdirAll(fileSetting.Value, os.ModePerm); err != nil {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
file, err := ioutil.ReadFile(fileSetting.Value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
deamonMap := make(map[string]interface{})
|
|
_ = json.Unmarshal(file, &deamonMap)
|
|
|
|
if len(req.Registries) == 0 {
|
|
delete(deamonMap, "insecure-registries")
|
|
} else {
|
|
deamonMap["insecure-registries"] = req.Registries
|
|
}
|
|
if len(req.Mirrors) == 0 {
|
|
delete(deamonMap, "registry-mirrors")
|
|
} else {
|
|
deamonMap["registry-mirrors"] = req.Mirrors
|
|
}
|
|
if len(req.Bip) == 0 {
|
|
delete(deamonMap, "bip")
|
|
} else {
|
|
deamonMap["bip"] = req.Bip
|
|
}
|
|
if !req.LiveRestore {
|
|
delete(deamonMap, "live-restore")
|
|
} else {
|
|
deamonMap["live-restore"] = req.LiveRestore
|
|
}
|
|
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 := ioutil.WriteFile(fileSetting.Value, newJson, 0640); err != nil {
|
|
return err
|
|
}
|
|
|
|
cmd := exec.Command("systemctl", "restart", "docker")
|
|
stdout, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
return errors.New(string(stdout))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (u *DockerService) UpdateConfByFile(req dto.DaemonJsonUpdateByFile) error {
|
|
file, err := os.OpenFile(req.Path, os.O_WRONLY|os.O_TRUNC, 0640)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
write := bufio.NewWriter(file)
|
|
_, _ = write.WriteString(req.File)
|
|
write.Flush()
|
|
|
|
cmd := exec.Command("systemctl", "restart", "docker")
|
|
stdout, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
return errors.New(string(stdout))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (u *DockerService) OperateDocker(req dto.DockerOperation) error {
|
|
cmd := exec.Command("systemctl", req.Operation, "docker")
|
|
stdout, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
return errors.New(string(stdout))
|
|
}
|
|
return nil
|
|
}
|