mirror of https://github.com/1Panel-dev/1Panel
fix: 解决 Swarm 模式下,启用 live-restore 重启失败的问题 (#564)
parent
cca1406f0f
commit
4c2fb7095d
|
@ -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"`
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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: '中开启',
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue