fix: 解决 Swarm 模式下,启用 live-restore 重启失败的问题 (#564)

pull/566/head
ssongliu 2023-04-10 17:04:23 +08:00 committed by GitHub
parent cca1406f0f
commit 4c2fb7095d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 24 deletions

View File

@ -5,6 +5,7 @@ type DaemonJsonUpdateByFile struct {
} }
type DaemonJsonConf struct { type DaemonJsonConf struct {
IsSwarm bool `json:"isSwarm"`
Status string `json:"status"` Status string `json:"status"`
Version string `json:"version"` Version string `json:"version"`
Mirrors []string `json:"registryMirrors"` Mirrors []string `json:"registryMirrors"`

View File

@ -49,59 +49,60 @@ func (u *DockerService) LoadDockerStatus() string {
} }
func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf { func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf {
status := constant.StatusRunning var data dto.DaemonJsonConf
data.IPTables = true
data.Status = constant.StatusRunning
stdout, err := cmd.Exec("systemctl is-active docker") stdout, err := cmd.Exec("systemctl is-active docker")
if string(stdout) != "active\n" || err != nil { if string(stdout) != "active\n" || err != nil {
status = constant.Stopped data.Status = constant.Stopped
} }
version := "-" data.IsSwarm = false
stdout2, _ := cmd.Exec("docker info | grep Swarm")
if string(stdout2) == " Swarm: active\n" {
data.IsSwarm = true
}
data.Version = "-"
client, err := docker.NewDockerClient() client, err := docker.NewDockerClient()
if err == nil { if err == nil {
ctx := context.Background() ctx := context.Background()
itemVersion, err := client.ServerVersion(ctx) itemVersion, err := client.ServerVersion(ctx)
if err == nil { if err == nil {
version = itemVersion.Version data.Version = itemVersion.Version
} }
} }
if _, err := os.Stat(constant.DaemonJsonPath); err != nil { if _, err := os.Stat(constant.DaemonJsonPath); err != nil {
return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version} return &data
} }
file, err := os.ReadFile(constant.DaemonJsonPath) file, err := os.ReadFile(constant.DaemonJsonPath)
if err != nil { if err != nil {
return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version} return &data
} }
var conf daemonJsonItem var conf daemonJsonItem
deamonMap := make(map[string]interface{}) deamonMap := make(map[string]interface{})
if err := json.Unmarshal(file, &deamonMap); err != nil { if err := json.Unmarshal(file, &deamonMap); err != nil {
return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version} return &data
} }
arr, err := json.Marshal(deamonMap) arr, err := json.Marshal(deamonMap)
if err != nil { if err != nil {
return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version} return &data
} }
if err := json.Unmarshal(arr, &conf); err != nil { if err := json.Unmarshal(arr, &conf); err != nil {
return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version} return &data
} }
if _, ok := deamonMap["iptables"]; !ok { if _, ok := deamonMap["iptables"]; !ok {
conf.IPTables = true conf.IPTables = true
} }
driver := "cgroupfs" data.CgroupDriver = "cgroupfs"
for _, opt := range conf.ExecOpts { for _, opt := range conf.ExecOpts {
if strings.HasPrefix(opt, "native.cgroupdriver=") { if strings.HasPrefix(opt, "native.cgroupdriver=") {
driver = strings.ReplaceAll(opt, "native.cgroupdriver=", "") data.CgroupDriver = strings.ReplaceAll(opt, "native.cgroupdriver=", "")
break break
} }
} }
data := dto.DaemonJsonConf{ data.Mirrors = conf.Mirrors
Status: status, data.Registries = conf.Registries
Version: version, data.IPTables = conf.IPTables
Mirrors: conf.Mirrors, data.LiveRestore = conf.LiveRestore
Registries: conf.Registries,
IPTables: conf.IPTables,
LiveRestore: conf.LiveRestore,
CgroupDriver: driver,
}
return &data return &data
} }

View File

@ -247,6 +247,7 @@ export namespace Container {
operation: string; operation: string;
} }
export interface DaemonJsonConf { export interface DaemonJsonConf {
isSwarm: boolean;
status: string; status: string;
version: string; version: string;
registryMirrors: Array<string>; registryMirrors: Array<string>;

View File

@ -557,7 +557,9 @@ const message = {
mirrorsHelper: mirrorsHelper:
'If empty, mirror acceleration is disabled. The accelerated URL is used first for the operation, and will skipped when the request times out', 'If empty, mirror acceleration is disabled. The accelerated URL is used first for the operation, and will skipped when the request times out',
registries: 'Insecure registries', registries: 'Insecure registries',
liveHelper: 'Whether to close all containers when stopping the docker service', liveHelper:
'Allows the running container state to be preserved in case of unexpected shutdown or crash of the Docker daemon',
liveWithSwarmHelper: 'live-restore daemon configuration is incompatible with swarm mode.',
daemonJsonPath: 'Conf Path', daemonJsonPath: 'Conf Path',
serviceUnavailable: 'Docker service is not started at present, please click', serviceUnavailable: 'Docker service is not started at present, please click',
startIn: ' to start', startIn: ' to start',

View File

@ -564,7 +564,8 @@ const message = {
mirrors: '', mirrors: '',
mirrorsHelper: '使 URL 使', mirrorsHelper: '使 URL 使',
registries: '', registries: '',
liveHelper: ' docker ', liveHelper: ' Docker ',
liveWithSwarmHelper: 'live-restore Swarm ',
daemonJsonPath: '', daemonJsonPath: '',
serviceUnavailable: ' Docker ', serviceUnavailable: ' Docker ',
startIn: '', startIn: '',

View File

@ -66,8 +66,11 @@
<el-switch v-model="form.iptables"></el-switch> <el-switch v-model="form.iptables"></el-switch>
</el-form-item> </el-form-item>
<el-form-item label="live-restore" prop="liveRestore"> <el-form-item label="live-restore" prop="liveRestore">
<el-switch v-model="form.liveRestore"></el-switch> <el-switch :disabled="form.isSwarm" v-model="form.liveRestore"></el-switch>
<span class="input-help">{{ $t('container.liveHelper') }}</span> <span class="input-help">{{ $t('container.liveHelper') }}</span>
<span v-if="form.isSwarm" class="input-help">
{{ $t('container.liveWithSwarmHelper') }}
</span>
</el-form-item> </el-form-item>
<el-form-item label="cgroup-driver" prop="cgroupDriver"> <el-form-item label="cgroup-driver" prop="cgroupDriver">
<el-radio-group v-model="form.cgroupDriver"> <el-radio-group v-model="form.cgroupDriver">
@ -151,6 +154,7 @@ const extensions = [javascript(), oneDark];
const confShowType = ref('base'); const confShowType = ref('base');
const form = reactive({ const form = reactive({
isSwarm: false,
status: '', status: '',
version: '', version: '',
mirrors: '', mirrors: '',
@ -250,6 +254,7 @@ const onSubmitSave = async () => {
let itemMirrors = form.mirrors.split('\n'); let itemMirrors = form.mirrors.split('\n');
let itemRegistries = form.registries.split('\n'); let itemRegistries = form.registries.split('\n');
let param = { let param = {
isSwarm: form.isSwarm,
status: form.status, status: form.status,
version: '', version: '',
registryMirrors: itemMirrors.filter(function (el) { registryMirrors: itemMirrors.filter(function (el) {
@ -294,6 +299,7 @@ const changeMode = async () => {
const search = async () => { const search = async () => {
const res = await loadDaemonJson(); const res = await loadDaemonJson();
form.isSwarm = res.data.isSwarm;
form.status = res.data.status; form.status = res.data.status;
form.version = res.data.version; form.version = res.data.version;
form.cgroupDriver = res.data.cgroupDriver; form.cgroupDriver = res.data.cgroupDriver;