feat: docker 服务不可用时,设置遮罩

pull/69/head
ssongliu 2022-12-07 18:15:56 +08:00 committed by ssongliu
parent 004b997288
commit 9a214885c3
13 changed files with 195 additions and 26 deletions

View File

@ -2,6 +2,7 @@ package service
import (
"bufio"
"context"
"encoding/json"
"io/ioutil"
"os"
@ -39,7 +40,12 @@ type daemonJsonItem struct {
func (u *DockerService) LoadDockerStatus() string {
status := constant.StatusRunning
if _, err := docker.NewDockerClient(); err != nil {
cli, err := docker.NewDockerClient()
if err != nil {
status = constant.Stopped
}
pong, err := cli.Ping(context.Background())
if !pong.Experimental || err != nil {
status = constant.Stopped
}
return status

View File

@ -3,6 +3,7 @@ package service
import (
"encoding/json"
"io/ioutil"
"os"
"os/exec"
"github.com/1Panel-dev/1Panel/backend/app/dto"
@ -56,8 +57,24 @@ func (u *ImageRepoService) Create(imageRepoDto dto.ImageRepoCreate) error {
if imageRepo.ID != 0 {
return constant.ErrRecordExist
}
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
}
}
}
if imageRepoDto.Protocol == "http" {
file, err := ioutil.ReadFile(constant.DaemonJsonDir)
file, err := ioutil.ReadFile(fileSetting.Value)
if err != nil {
return err
}
@ -76,7 +93,7 @@ func (u *ImageRepoService) Create(imageRepoDto dto.ImageRepoCreate) error {
if err != nil {
return err
}
if err := ioutil.WriteFile(constant.DaemonJsonDir, newJson, 0640); err != nil {
if err := ioutil.WriteFile(fileSetting.Value, newJson, 0640); err != nil {
return err
}
}

View File

@ -14,7 +14,6 @@ const (
ComposeOpRestart = "restart"
ComposeOpRemove = "remove"
DaemonJsonDir = "/opt/1Panel/docker/conf/daemon.json"
TmpDockerBuildDir = "/opt/1Panel/data/docker/build"
TmpComposeBuildDir = "/opt/1Panel/data/docker/compose"
)

View File

@ -130,6 +130,9 @@ export const dockerOperate = (params: Container.DockerOperate) => {
export const loadDaemonJson = () => {
return http.get<Container.DaemonJsonConf>(`/containers/daemonjson`);
};
export const loadDockerStatus = () => {
return http.get<string>(`/containers/docker/status`);
};
export const updateDaemonJson = (params: Container.DaemonJsonConf) => {
return http.post(`/containers/daemonjson/update`, params);
};

View File

@ -459,6 +459,8 @@ export default {
registries: 'Insecure registries',
liveHelper: 'Whether to close all containers when stopping the docker service',
daemonJsonPath: 'Conf Path',
serviceUnavailable: 'Docker service is not started at present, please click',
startIn: ' to start',
},
cronjob: {
cronTask: 'Task',

View File

@ -466,6 +466,8 @@ export default {
registries: '',
liveHelper: ' docker ',
daemonJsonPath: '',
serviceUnavailable: ' Docker ',
startIn: '',
},
cronjob: {
cronTask: '',

View File

@ -1,7 +1,14 @@
<template>
<div v-loading="loading">
<Submenu activeName="compose" />
<el-card style="margin-top: 20px">
<el-card width="30%" v-if="dockerStatus != 'Running'" class="mask-prompt">
<span style="font-size: 14px">{{ $t('container.serviceUnavailable') }}</span>
<el-button type="primary" link style="font-size: 14px; margin-bottom: 5px" @click="goSetting">
{{ $t('container.setting') }}
</el-button>
<span style="font-size: 14px">{{ $t('container.startIn') }}</span>
</el-card>
<el-card style="margin-top: 20px" :class="{ mask: dockerStatus != 'Running' }">
<div v-if="!isOnDetail">
<ComplexTable
:pagination-config="paginationConfig"
@ -59,12 +66,13 @@ import EditDialog from '@/views/container/compose/edit/index.vue';
import CreateDialog from '@/views/container/compose/create/index.vue';
import ComposeDetial from '@/views/container/compose/detail/index.vue';
import Submenu from '@/views/container/index.vue';
import { composeOperator, searchCompose } from '@/api/modules/container';
import { composeOperator, loadDockerStatus, searchCompose } from '@/api/modules/container';
import i18n from '@/lang';
import { ElMessage } from 'element-plus';
import { Container } from '@/api/interface/container';
import { useDeleteData } from '@/hooks/use-delete-data';
import { LoadFile } from '@/api/modules/files';
import router from '@/routers';
const data = ref();
const selects = ref<any>([]);
@ -78,6 +86,18 @@ const paginationConfig = reactive({
total: 0,
});
const dockerStatus = ref();
const loadStatus = async () => {
const res = await loadDockerStatus();
dockerStatus.value = res.data;
if (dockerStatus.value === 'Running') {
search();
}
};
const goSetting = async () => {
router.push({ name: 'ContainerSetting' });
};
const search = async () => {
let params = {
page: paginationConfig.currentPage,
@ -158,6 +178,6 @@ const buttons = [
},
];
onMounted(() => {
search();
loadStatus();
});
</script>

View File

@ -1,7 +1,14 @@
<template>
<div>
<Submenu activeName="container" />
<el-card style="margin-top: 20px">
<el-card width="30%" v-if="dockerStatus != 'Running'" class="mask-prompt">
<span style="font-size: 14px">{{ $t('container.serviceUnavailable') }}</span>
<el-button type="primary" link style="font-size: 14px; margin-bottom: 5px" @click="goSetting">
{{ $t('container.setting') }}
</el-button>
<span style="font-size: 14px">{{ $t('container.startIn') }}</span>
</el-card>
<el-card style="margin-top: 20px" :class="{ mask: dockerStatus != 'Running' }">
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
<template #toolbar>
<el-button icon="Plus" type="primary" @click="onCreate()">
@ -88,10 +95,11 @@ import CodemirrorDialog from '@/components/codemirror-dialog/codemirror.vue';
import Submenu from '@/views/container/index.vue';
import { reactive, onMounted, ref } from 'vue';
import { dateFromat } from '@/utils/util';
import { ContainerOperator, inspect, searchContainer } from '@/api/modules/container';
import { ContainerOperator, inspect, loadDockerStatus, searchContainer } from '@/api/modules/container';
import { Container } from '@/api/interface/container';
import { ElMessage, ElMessageBox } from 'element-plus';
import i18n from '@/lang';
import router from '@/routers';
const data = ref();
const selects = ref<any>([]);
@ -101,6 +109,18 @@ const paginationConfig = reactive({
total: 0,
});
const dockerStatus = ref();
const loadStatus = async () => {
const res = await loadDockerStatus();
dockerStatus.value = res.data;
if (dockerStatus.value === 'Running') {
search();
}
};
const goSetting = async () => {
router.push({ name: 'ContainerSetting' });
};
interface Filters {
filters?: string;
}
@ -251,6 +271,6 @@ const buttons = [
];
onMounted(() => {
search();
loadStatus();
});
</script>

View File

@ -1,7 +1,14 @@
<template>
<div v-loading="loading">
<Submenu activeName="image" />
<el-card style="margin-top: 20px">
<el-card width="30%" v-if="dockerStatus != 'Running'" class="mask-prompt">
<span style="font-size: 14px">{{ $t('container.serviceUnavailable') }}</span>
<el-button type="primary" link style="font-size: 14px; margin-bottom: 5px" @click="goSetting">
{{ $t('container.setting') }}
</el-button>
<span style="font-size: 14px">{{ $t('container.startIn') }}</span>
</el-card>
<el-card style="margin-top: 20px" :class="{ mask: dockerStatus != 'Running' }">
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
<template #toolbar>
<el-button @click="onOpenPull">
@ -89,10 +96,11 @@ import Push from '@/views/container/image/push/index.vue';
import Save from '@/views/container/image/save/index.vue';
import Load from '@/views/container/image/load/index.vue';
import Build from '@/views/container/image/build/index.vue';
import { searchImage, listImageRepo, imageRemove } from '@/api/modules/container';
import { searchImage, listImageRepo, imageRemove, loadDockerStatus } from '@/api/modules/container';
import i18n from '@/lang';
import { ElForm } from 'element-plus';
import { useDeleteData } from '@/hooks/use-delete-data';
import router from '@/routers';
const loading = ref(false);
@ -105,6 +113,19 @@ const paginationConfig = reactive({
total: 0,
});
const dockerStatus = ref();
const loadStatus = async () => {
const res = await loadDockerStatus();
dockerStatus.value = res.data;
if (dockerStatus.value === 'Running') {
search();
loadRepos();
}
};
const goSetting = async () => {
router.push({ name: 'ContainerSetting' });
};
const dialogPullRef = ref();
const dialogTagRef = ref();
const dialogPushRef = ref();
@ -206,7 +227,6 @@ const buttons = [
];
onMounted(() => {
search();
loadRepos();
loadStatus();
});
</script>

View File

@ -1,7 +1,14 @@
<template>
<div>
<Submenu activeName="network" />
<el-card style="margin-top: 20px">
<el-card width="30%" v-if="dockerStatus != 'Running'" class="mask-prompt">
<span style="font-size: 14px">{{ $t('container.serviceUnavailable') }}</span>
<el-button type="primary" link style="font-size: 14px; margin-bottom: 5px" @click="goSetting">
{{ $t('container.setting') }}
</el-button>
<span style="font-size: 14px">{{ $t('container.startIn') }}</span>
</el-card>
<el-card style="margin-top: 20px" :class="{ mask: dockerStatus != 'Running' }">
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
<template #toolbar>
<el-button icon="Plus" type="primary" @click="onCreate()">
@ -57,10 +64,11 @@ import CodemirrorDialog from '@/components/codemirror-dialog/codemirror.vue';
import Submenu from '@/views/container/index.vue';
import { reactive, onMounted, ref } from 'vue';
import { dateFromat } from '@/utils/util';
import { deleteNetwork, searchNetwork, inspect } from '@/api/modules/container';
import { deleteNetwork, searchNetwork, inspect, loadDockerStatus } from '@/api/modules/container';
import { Container } from '@/api/interface/container';
import i18n from '@/lang';
import { useDeleteData } from '@/hooks/use-delete-data';
import router from '@/routers';
const detailInfo = ref();
const codemirror = ref();
@ -73,6 +81,18 @@ const paginationConfig = reactive({
total: 0,
});
const dockerStatus = ref();
const loadStatus = async () => {
const res = await loadDockerStatus();
dockerStatus.value = res.data;
if (dockerStatus.value === 'Running') {
search();
}
};
const goSetting = async () => {
router.push({ name: 'ContainerSetting' });
};
const dialogCreateRef = ref<DialogExpose>();
interface DialogExpose {
@ -140,6 +160,6 @@ const buttons = [
];
onMounted(() => {
search();
loadStatus();
});
</script>

View File

@ -1,7 +1,14 @@
<template>
<div>
<Submenu activeName="repo" />
<el-card style="margin-top: 20px">
<el-card width="30%" v-if="dockerStatus != 'Running'" class="mask-prompt">
<span style="font-size: 14px">{{ $t('container.serviceUnavailable') }}</span>
<el-button type="primary" link style="font-size: 14px; margin-bottom: 5px" @click="goSetting">
{{ $t('container.setting') }}
</el-button>
<span style="font-size: 14px">{{ $t('container.startIn') }}</span>
</el-card>
<el-card style="margin-top: 20px" :class="{ mask: dockerStatus != 'Running' }">
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
<template #toolbar>
<el-button icon="Plus" type="primary" @click="onOpenDialog('create')">
@ -40,9 +47,10 @@ import Submenu from '@/views/container/index.vue';
import { reactive, onMounted, ref } from 'vue';
import { dateFromat } from '@/utils/util';
import { Container } from '@/api/interface/container';
import { deleteImageRepo, searchImageRepo } from '@/api/modules/container';
import { deleteImageRepo, loadDockerStatus, searchImageRepo } from '@/api/modules/container';
import { useDeleteData } from '@/hooks/use-delete-data';
import i18n from '@/lang';
import router from '@/routers';
const data = ref();
const selects = ref<any>([]);
@ -52,6 +60,18 @@ const paginationConfig = reactive({
total: 0,
});
const dockerStatus = ref();
const loadStatus = async () => {
const res = await loadDockerStatus();
dockerStatus.value = res.data;
if (dockerStatus.value === 'Running') {
search();
}
};
const goSetting = async () => {
router.push({ name: 'ContainerSetting' });
};
const search = async () => {
let params = {
page: paginationConfig.currentPage,
@ -117,6 +137,6 @@ const buttons = [
];
onMounted(() => {
search();
loadStatus();
});
</script>

View File

@ -1,7 +1,14 @@
<template>
<div>
<Submenu activeName="template" />
<el-card style="margin-top: 20px">
<el-card width="30%" v-if="dockerStatus != 'Running'" class="mask-prompt">
<span style="font-size: 14px">{{ $t('container.serviceUnavailable') }}</span>
<el-button type="primary" link style="font-size: 14px; margin-bottom: 5px" @click="goSetting">
{{ $t('container.setting') }}
</el-button>
<span style="font-size: 14px">{{ $t('container.startIn') }}</span>
</el-card>
<el-card style="margin-top: 20px" :class="{ mask: dockerStatus != 'Running' }">
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
<template #toolbar>
<el-button icon="Plus" type="primary" @click="onOpenDialog('create')">
@ -74,9 +81,10 @@ import { reactive, onMounted, ref } from 'vue';
import { dateFromat } from '@/utils/util';
import { Container } from '@/api/interface/container';
import OperatorDialog from '@/views/container/template/operator/index.vue';
import { deleteComposeTemplate, searchComposeTemplate } from '@/api/modules/container';
import { deleteComposeTemplate, loadDockerStatus, searchComposeTemplate } from '@/api/modules/container';
import { useDeleteData } from '@/hooks/use-delete-data';
import i18n from '@/lang';
import router from '@/routers';
const data = ref();
const selects = ref<any>([]);
@ -90,6 +98,18 @@ const paginationConfig = reactive({
total: 0,
});
const dockerStatus = ref();
const loadStatus = async () => {
const res = await loadDockerStatus();
dockerStatus.value = res.data;
if (dockerStatus.value === 'Running') {
search();
}
};
const goSetting = async () => {
router.push({ name: 'ContainerSetting' });
};
const search = async () => {
let params = {
page: paginationConfig.currentPage,
@ -157,6 +177,6 @@ const buttons = [
];
onMounted(() => {
search();
loadStatus();
});
</script>

View File

@ -1,7 +1,14 @@
<template>
<div>
<Submenu activeName="volume" />
<el-card style="margin-top: 20px">
<el-card width="30%" v-if="dockerStatus != 'Running'" class="mask-prompt">
<span style="font-size: 14px">{{ $t('container.serviceUnavailable') }}</span>
<el-button type="primary" link style="font-size: 14px; margin-bottom: 5px" @click="goSetting">
{{ $t('container.setting') }}
</el-button>
<span style="font-size: 14px">{{ $t('container.startIn') }}</span>
</el-card>
<el-card style="margin-top: 20px" :class="{ mask: dockerStatus != 'Running' }">
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
<template #toolbar>
<el-button icon="Plus" type="primary" @click="onCreate()">
@ -46,10 +53,11 @@ import Submenu from '@/views/container/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/codemirror.vue';
import { reactive, onMounted, ref } from 'vue';
import { dateFromat } from '@/utils/util';
import { deleteVolume, searchVolume, inspect } from '@/api/modules/container';
import { deleteVolume, searchVolume, inspect, loadDockerStatus } from '@/api/modules/container';
import { Container } from '@/api/interface/container';
import i18n from '@/lang';
import { useDeleteData } from '@/hooks/use-delete-data';
import router from '@/routers';
const detailInfo = ref();
const codemirror = ref();
@ -62,6 +70,18 @@ const paginationConfig = reactive({
total: 0,
});
const dockerStatus = ref();
const loadStatus = async () => {
const res = await loadDockerStatus();
dockerStatus.value = res.data;
if (dockerStatus.value === 'Running') {
search();
}
};
const goSetting = async () => {
router.push({ name: 'ContainerSetting' });
};
const dialogCreateRef = ref<DialogExpose>();
interface DialogExpose {
@ -115,6 +135,6 @@ const buttons = [
];
onMounted(() => {
search();
loadStatus();
});
</script>