mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: uniform application service status return (#7426)
This commit is contained in:
parent
f6475e7c7f
commit
55a6cdcf10
@ -6,7 +6,8 @@ type DaemonJsonUpdateByFile struct {
|
||||
|
||||
type DaemonJsonConf struct {
|
||||
IsSwarm bool `json:"isSwarm"`
|
||||
Status string `json:"status"`
|
||||
IsExist bool `json:"isExist"`
|
||||
IsActive bool `json:"isActive"`
|
||||
Version string `json:"version"`
|
||||
Mirrors []string `json:"registryMirrors"`
|
||||
Registries []string `json:"insecureRegistries"`
|
||||
|
@ -2,7 +2,8 @@ package dto
|
||||
|
||||
type FirewallBaseInfo struct {
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
IsExist bool `json:"isExist"`
|
||||
IsActive bool `json:"isActive"`
|
||||
Version string `json:"version"`
|
||||
PingStatus string `json:"pingStatus"`
|
||||
}
|
||||
|
@ -10,7 +10,8 @@ type SSHUpdate struct {
|
||||
|
||||
type SSHInfo struct {
|
||||
AutoStart bool `json:"autoStart"`
|
||||
Status string `json:"status"`
|
||||
IsExist bool `json:"isExist"`
|
||||
IsActive bool `json:"isActive"`
|
||||
Message string `json:"message"`
|
||||
Port string `json:"port"`
|
||||
ListenAddress string `json:"listenAddress"`
|
||||
|
@ -69,15 +69,19 @@ func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf {
|
||||
ctx := context.Background()
|
||||
var data dto.DaemonJsonConf
|
||||
data.IPTables = true
|
||||
data.Status = constant.StatusRunning
|
||||
data.Version = "-"
|
||||
if cmd.Which("docker") {
|
||||
data.IsExist = false
|
||||
return &data
|
||||
}
|
||||
data.IsExist = true
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
data.Status = constant.Stopped
|
||||
data.IsActive = false
|
||||
} else {
|
||||
defer client.Close()
|
||||
if _, err := client.Ping(ctx); err != nil {
|
||||
data.Status = constant.Stopped
|
||||
data.IsActive = false
|
||||
}
|
||||
itemVersion, err := client.ServerVersion(ctx)
|
||||
if err == nil {
|
||||
|
@ -116,8 +116,8 @@ func (u *Fail2BanService) UpdateConf(req dto.Fail2BanUpdate) error {
|
||||
if client.Name() != itemName {
|
||||
return buserr.WithName("ErrBanAction", itemName)
|
||||
}
|
||||
status, _ := client.Status()
|
||||
if status != "running" {
|
||||
isActive, _ := client.Status()
|
||||
if !isActive {
|
||||
return buserr.WithName("ErrBanAction", itemName)
|
||||
}
|
||||
}
|
||||
|
@ -43,13 +43,14 @@ func NewIFirewallService() IFirewallService {
|
||||
|
||||
func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) {
|
||||
var baseInfo dto.FirewallBaseInfo
|
||||
baseInfo.Status = "not running"
|
||||
baseInfo.Version = "-"
|
||||
baseInfo.Name = "-"
|
||||
client, err := firewall.NewFirewallClient()
|
||||
if err != nil {
|
||||
baseInfo.IsExist = false
|
||||
return baseInfo, err
|
||||
}
|
||||
baseInfo.IsExist = true
|
||||
baseInfo.Name = client.Name()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
@ -60,7 +61,7 @@ func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) {
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
baseInfo.Status, _ = client.Status()
|
||||
baseInfo.IsActive, _ = client.Status()
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
@ -45,7 +45,8 @@ func NewISSHService() ISSHService {
|
||||
func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
|
||||
data := dto.SSHInfo{
|
||||
AutoStart: true,
|
||||
Status: constant.StatusEnable,
|
||||
IsExist: true,
|
||||
IsActive: true,
|
||||
Message: "",
|
||||
Port: "22",
|
||||
ListenAddress: "",
|
||||
@ -56,17 +57,13 @@ func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
|
||||
}
|
||||
serviceName, err := loadServiceName()
|
||||
if err != nil {
|
||||
data.Status = constant.StatusDisable
|
||||
data.IsExist = false
|
||||
data.Message = err.Error()
|
||||
} else {
|
||||
active, err := systemctl.IsActive(serviceName)
|
||||
if !active {
|
||||
data.Status = constant.StatusDisable
|
||||
if err != nil {
|
||||
data.Message = err.Error()
|
||||
}
|
||||
} else {
|
||||
data.Status = constant.StatusEnable
|
||||
data.IsActive = active
|
||||
if !active && err != nil {
|
||||
data.Message = err.Error()
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +81,7 @@ func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
|
||||
sshConf, err := os.ReadFile(sshPath)
|
||||
if err != nil {
|
||||
data.Message = err.Error()
|
||||
data.Status = constant.StatusDisable
|
||||
data.IsActive = false
|
||||
}
|
||||
lines := strings.Split(string(sshConf), "\n")
|
||||
for _, line := range lines {
|
||||
|
@ -13,7 +13,7 @@ type FirewallClient interface {
|
||||
Stop() error
|
||||
Restart() error
|
||||
Reload() error
|
||||
Status() (string, error) // running not running
|
||||
Status() (bool, error) // running not running
|
||||
Version() (string, error)
|
||||
|
||||
ListPort() ([]client.FireInfo, error)
|
||||
|
@ -24,12 +24,9 @@ func (f *Firewall) Name() string {
|
||||
return "firewalld"
|
||||
}
|
||||
|
||||
func (f *Firewall) Status() (string, error) {
|
||||
func (f *Firewall) Status() (bool, error) {
|
||||
stdout, _ := cmd.Exec("firewall-cmd --state")
|
||||
if stdout == "running\n" {
|
||||
return "running", nil
|
||||
}
|
||||
return "not running", nil
|
||||
return stdout == "running\n", nil
|
||||
}
|
||||
|
||||
func (f *Firewall) Version() (string, error) {
|
||||
|
@ -27,8 +27,8 @@ func NewIptables() (*Iptables, error) {
|
||||
return iptables, nil
|
||||
}
|
||||
|
||||
func (iptables *Iptables) runf(rule string, a ...any) error {
|
||||
stdout, err := cmd.Execf("%s iptables -t nat %s", iptables.CmdStr, fmt.Sprintf(rule, a...))
|
||||
func (iptables *Iptables) run(rule string) error {
|
||||
stdout, err := cmd.Execf("%s iptables -t nat %s", iptables.CmdStr, rule)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s, %s", err, stdout)
|
||||
}
|
||||
@ -39,6 +39,10 @@ func (iptables *Iptables) runf(rule string, a ...any) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iptables *Iptables) runf(rule string, a ...any) error {
|
||||
return iptables.run(fmt.Sprintf(rule, a...))
|
||||
}
|
||||
|
||||
func (iptables *Iptables) Check() error {
|
||||
stdout, err := cmd.Exec("cat /proc/sys/net/ipv4/ip_forward")
|
||||
if err != nil {
|
||||
@ -100,7 +104,7 @@ func (iptables *Iptables) NatAdd(protocol, src, destIp, destPort string, save bo
|
||||
if destIp != "" && destIp != "127.0.0.1" && destIp != "localhost" {
|
||||
rule = fmt.Sprintf("-A %s -p %s --dport %s -j DNAT --to-destination %s:%s", NatChain, protocol, src, destIp, destPort)
|
||||
}
|
||||
if err := iptables.runf(rule); err != nil {
|
||||
if err := iptables.run(rule); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -28,16 +28,16 @@ func (f *Ufw) Name() string {
|
||||
return "ufw"
|
||||
}
|
||||
|
||||
func (f *Ufw) Status() (string, error) {
|
||||
func (f *Ufw) Status() (bool, error) {
|
||||
stdout, _ := cmd.Execf("%s status | grep Status", f.CmdStr)
|
||||
if stdout == "Status: active\n" {
|
||||
return "running", nil
|
||||
return true, nil
|
||||
}
|
||||
stdout1, _ := cmd.Execf("%s status | grep 状态", f.CmdStr)
|
||||
if stdout1 == "状态: 激活\n" {
|
||||
return "running", nil
|
||||
return true, nil
|
||||
}
|
||||
return "not running", nil
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (f *Ufw) Version() (string, error) {
|
||||
|
@ -3,13 +3,10 @@
|
||||
<div v-show="isOnDetail">
|
||||
<ComposeDetail ref="composeDetailRef" />
|
||||
</div>
|
||||
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt">
|
||||
<span>{{ $t('container.serviceUnavailable') }}</span>
|
||||
<el-button type="primary" link class="bt" @click="goSetting">【 {{ $t('container.setting') }} 】</el-button>
|
||||
<span>{{ $t('container.startIn') }}</span>
|
||||
</el-card>
|
||||
|
||||
<LayoutContent v-if="!isOnDetail" :title="$t('container.compose')" :class="{ mask: dockerStatus != 'Running' }">
|
||||
<docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
|
||||
|
||||
<LayoutContent v-if="!isOnDetail" :title="$t('container.compose')" :class="{ mask: !isActive }">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" @click="onOpenDialog()">
|
||||
{{ $t('container.createCompose') }}
|
||||
@ -90,12 +87,13 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, onMounted, ref } from 'vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import EditDialog from '@/views/container/compose/edit/index.vue';
|
||||
import CreateDialog from '@/views/container/compose/create/index.vue';
|
||||
import DeleteDialog from '@/views/container/compose/delete/index.vue';
|
||||
import ComposeDetail from '@/views/container/compose/detail/index.vue';
|
||||
import { loadContainerLog, loadDockerStatus, searchCompose } from '@/api/modules/container';
|
||||
import { loadContainerLog, searchCompose } from '@/api/modules/container';
|
||||
import DockerStatus from '@/views/container/docker-status/index.vue';
|
||||
import i18n from '@/lang';
|
||||
import { Container } from '@/api/interface/container';
|
||||
import router from '@/routers';
|
||||
@ -114,31 +112,16 @@ const paginationConfig = reactive({
|
||||
});
|
||||
const searchName = ref();
|
||||
|
||||
const dockerStatus = ref('Running');
|
||||
const loadStatus = async () => {
|
||||
loading.value = true;
|
||||
await loadDockerStatus()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
dockerStatus.value = res.data;
|
||||
if (dockerStatus.value === 'Running') {
|
||||
search();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dockerStatus.value = 'Failed';
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const goSetting = async () => {
|
||||
router.push({ name: 'ContainerSetting' });
|
||||
};
|
||||
const isActive = ref(false);
|
||||
|
||||
const toComposeFolder = async (row: Container.ComposeInfo) => {
|
||||
router.push({ path: '/hosts/files', query: { path: row.workdir } });
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
if (!isActive.value) {
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
info: searchName.value,
|
||||
page: paginationConfig.currentPage,
|
||||
@ -225,7 +208,4 @@ const buttons = [
|
||||
},
|
||||
},
|
||||
];
|
||||
onMounted(() => {
|
||||
loadStatus();
|
||||
});
|
||||
</script>
|
||||
|
@ -1,12 +1,8 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt">
|
||||
<span>{{ $t('container.serviceUnavailable') }}</span>
|
||||
<el-button type="primary" class="bt" link @click="goSetting">【 {{ $t('container.setting') }} 】</el-button>
|
||||
<span>{{ $t('container.startIn') }}</span>
|
||||
</el-card>
|
||||
<docker-status v-model:isActive="isActive" @search="search" />
|
||||
|
||||
<div class="mt-5">
|
||||
<div class="mt-5" v-if="isActive">
|
||||
<el-tag @click="searchWithStatus('all')" v-if="countItem.all" effect="plain" size="large">
|
||||
{{ $t('commons.table.all') }} * {{ countItem.all }}
|
||||
</el-tag>
|
||||
@ -69,7 +65,7 @@
|
||||
</el-tag>
|
||||
</div>
|
||||
|
||||
<LayoutContent :title="$t('container.container')" :class="{ mask: dockerStatus != 'Running' }">
|
||||
<LayoutContent :title="$t('container.container')" :class="{ mask: !isActive }">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" @click="onContainerOperate('')">
|
||||
{{ $t('container.create') }}
|
||||
@ -414,6 +410,7 @@ import ContainerLogDialog from '@/views/container/container/log/index.vue';
|
||||
import TerminalDialog from '@/views/container/container/terminal/index.vue';
|
||||
import CodemirrorDialog from '@/components/codemirror-dialog/index.vue';
|
||||
import PortJumpDialog from '@/components/port-jump/index.vue';
|
||||
import DockerStatus from '@/views/container/docker-status/index.vue';
|
||||
import Status from '@/components/status/index.vue';
|
||||
import { reactive, onMounted, ref, computed } from 'vue';
|
||||
import {
|
||||
@ -421,7 +418,6 @@ import {
|
||||
containerOperator,
|
||||
inspect,
|
||||
loadContainerStatus,
|
||||
loadDockerStatus,
|
||||
searchContainer,
|
||||
} from '@/api/modules/container';
|
||||
import { Container } from '@/api/interface/container';
|
||||
@ -434,6 +430,7 @@ const globalStore = GlobalStore();
|
||||
const mobile = computed(() => {
|
||||
return globalStore.isMobile();
|
||||
});
|
||||
const isActive = ref(false);
|
||||
|
||||
const loading = ref(false);
|
||||
const data = ref();
|
||||
@ -466,23 +463,6 @@ const countItem = reactive({
|
||||
dead: 0,
|
||||
});
|
||||
|
||||
const dockerStatus = ref('Running');
|
||||
const loadStatus = async () => {
|
||||
loading.value = true;
|
||||
await loadDockerStatus()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
dockerStatus.value = res.data;
|
||||
if (dockerStatus.value === 'Running') {
|
||||
search();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dockerStatus.value = 'Failed';
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const goDashboard = async (port: any) => {
|
||||
if (port.indexOf('127.0.0.1') !== -1) {
|
||||
MsgWarning(i18n.global.t('container.unExposedPort'));
|
||||
@ -499,10 +479,6 @@ const goDashboard = async (port: any) => {
|
||||
dialogPortJumpRef.value.acceptParams({ port: portEx, ip: ip });
|
||||
};
|
||||
|
||||
const goSetting = async () => {
|
||||
router.push({ name: 'ContainerSetting' });
|
||||
};
|
||||
|
||||
interface Filters {
|
||||
filters?: string;
|
||||
}
|
||||
@ -517,6 +493,9 @@ const dialogRenameRef = ref();
|
||||
const dialogPruneRef = ref();
|
||||
|
||||
const search = async (column?: any) => {
|
||||
if (!isActive.value) {
|
||||
return;
|
||||
}
|
||||
localStorage.setItem('includeAppStore', includeAppStore.value ? 'true' : 'false');
|
||||
let filterItem = props.filters ? props.filters : '';
|
||||
paginationConfig.orderBy = column?.order ? column.prop : paginationConfig.orderBy;
|
||||
@ -802,7 +781,6 @@ const buttons = [
|
||||
onMounted(() => {
|
||||
let includeItem = localStorage.getItem('includeAppStore');
|
||||
includeAppStore.value = !includeItem || includeItem === 'true';
|
||||
loadStatus();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
40
frontend/src/views/container/docker-status/index.vue
Normal file
40
frontend/src/views/container/docker-status/index.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card v-if="isActive !== null && !isActive" class="mask-prompt">
|
||||
<span>{{ $t('container.serviceUnavailable') }}</span>
|
||||
<el-button type="primary" link class="bt" @click="goSetting">【 {{ $t('container.setting') }} 】</el-button>
|
||||
<span>{{ $t('container.startIn') }}</span>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { loadDockerStatus } from '@/api/modules/container';
|
||||
import router from '@/routers';
|
||||
|
||||
const em = defineEmits(['search', 'mounted', 'update:is-active', 'update:loading']);
|
||||
const isActive = ref(null);
|
||||
const loadStatus = async () => {
|
||||
em('update:loading', true);
|
||||
await loadDockerStatus()
|
||||
.then((res) => {
|
||||
isActive.value = res.data === 'Running';
|
||||
em('update:is-active', isActive.value);
|
||||
em('search');
|
||||
em('mounted');
|
||||
})
|
||||
.catch(() => {
|
||||
em('update:loading', false);
|
||||
em('update:is-active', false);
|
||||
});
|
||||
};
|
||||
|
||||
const goSetting = async () => {
|
||||
router.push({ name: 'ContainerSetting' });
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadStatus();
|
||||
});
|
||||
</script>
|
@ -1,12 +1,8 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt">
|
||||
<span>{{ $t('container.serviceUnavailable') }}</span>
|
||||
<el-button type="primary" link class="bt" @click="goSetting">【 {{ $t('container.setting') }} 】</el-button>
|
||||
<span>{{ $t('container.startIn') }}</span>
|
||||
</el-card>
|
||||
<docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" @mounted="loadRepos" />
|
||||
|
||||
<LayoutContent :title="$t('container.image')" :class="{ mask: dockerStatus != 'Running' }">
|
||||
<LayoutContent :title="$t('container.image')" :class="{ mask: !isActive }">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" plain @click="onOpenPull">
|
||||
{{ $t('container.imagePull') }}
|
||||
@ -99,7 +95,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, onMounted, ref, computed } from 'vue';
|
||||
import { reactive, ref, computed } from 'vue';
|
||||
import { dateFormat } from '@/utils/util';
|
||||
import { Container } from '@/api/interface/container';
|
||||
import Pull from '@/views/container/image/pull/index.vue';
|
||||
@ -110,17 +106,10 @@ import Load from '@/views/container/image/load/index.vue';
|
||||
import Build from '@/views/container/image/build/index.vue';
|
||||
import Delete from '@/views/container/image/delete/index.vue';
|
||||
import Prune from '@/views/container/image/prune/index.vue';
|
||||
import DockerStatus from '@/views/container/docker-status/index.vue';
|
||||
import CodemirrorDialog from '@/components/codemirror-dialog/index.vue';
|
||||
import {
|
||||
searchImage,
|
||||
listImageRepo,
|
||||
loadDockerStatus,
|
||||
imageRemove,
|
||||
inspect,
|
||||
containerPrune,
|
||||
} from '@/api/modules/container';
|
||||
import { searchImage, listImageRepo, imageRemove, inspect, containerPrune } from '@/api/modules/container';
|
||||
import i18n from '@/lang';
|
||||
import router from '@/routers';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
@ -144,26 +133,7 @@ const paginationConfig = reactive({
|
||||
});
|
||||
const searchName = ref();
|
||||
|
||||
const dockerStatus = ref('Running');
|
||||
const loadStatus = async () => {
|
||||
loading.value = true;
|
||||
await loadDockerStatus()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
dockerStatus.value = res.data;
|
||||
if (dockerStatus.value === 'Running') {
|
||||
search();
|
||||
loadRepos();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dockerStatus.value = 'Failed';
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const goSetting = async () => {
|
||||
router.push({ name: 'ContainerSetting' });
|
||||
};
|
||||
const isActive = ref(false);
|
||||
|
||||
const mydetail = ref();
|
||||
const dialogPullRef = ref();
|
||||
@ -176,6 +146,9 @@ const dialogDeleteRef = ref();
|
||||
const dialogPruneRef = ref();
|
||||
|
||||
const search = async () => {
|
||||
if (!isActive.value) {
|
||||
return;
|
||||
}
|
||||
const repoSearch = {
|
||||
info: searchName.value,
|
||||
page: paginationConfig.currentPage,
|
||||
@ -305,8 +278,4 @@ const buttons = [
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
onMounted(() => {
|
||||
loadStatus();
|
||||
});
|
||||
</script>
|
||||
|
@ -1,12 +1,8 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt">
|
||||
<span>{{ $t('container.serviceUnavailable') }}</span>
|
||||
<el-button type="primary" link class="bt" @click="goSetting">【 {{ $t('container.setting') }} 】</el-button>
|
||||
<span>{{ $t('container.startIn') }}</span>
|
||||
</el-card>
|
||||
<docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
|
||||
|
||||
<LayoutContent :title="$t('container.network')" :class="{ mask: dockerStatus != 'Running' }">
|
||||
<LayoutContent :title="$t('container.network')" :class="{ mask: !isActive }">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" @click="onCreate()">
|
||||
{{ $t('container.createNetwork') }}
|
||||
@ -93,14 +89,14 @@
|
||||
<script lang="ts" setup>
|
||||
import CreateDialog from '@/views/container/network/create/index.vue';
|
||||
import CodemirrorDialog from '@/components/codemirror-dialog/index.vue';
|
||||
import { reactive, onMounted, ref } from 'vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { dateFormat } from '@/utils/util';
|
||||
import { deleteNetwork, searchNetwork, inspect, loadDockerStatus, containerPrune } from '@/api/modules/container';
|
||||
import { deleteNetwork, searchNetwork, inspect, containerPrune } from '@/api/modules/container';
|
||||
import { Container } from '@/api/interface/container';
|
||||
import i18n from '@/lang';
|
||||
import router from '@/routers';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import DockerStatus from '@/views/container/docker-status/index.vue';
|
||||
|
||||
const loading = ref();
|
||||
const codemirror = ref();
|
||||
@ -116,27 +112,7 @@ const paginationConfig = reactive({
|
||||
const searchName = ref();
|
||||
|
||||
const opRef = ref();
|
||||
|
||||
const dockerStatus = ref('Running');
|
||||
const loadStatus = async () => {
|
||||
loading.value = true;
|
||||
await loadDockerStatus()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
dockerStatus.value = res.data;
|
||||
if (dockerStatus.value === 'Running') {
|
||||
search();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dockerStatus.value = 'Failed';
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const goSetting = async () => {
|
||||
router.push({ name: 'ContainerSetting' });
|
||||
};
|
||||
|
||||
const isActive = ref(false);
|
||||
const dialogCreateRef = ref<DialogExpose>();
|
||||
|
||||
interface DialogExpose {
|
||||
@ -174,6 +150,9 @@ function selectable(row) {
|
||||
}
|
||||
|
||||
const search = async () => {
|
||||
if (!isActive.value) {
|
||||
return;
|
||||
}
|
||||
const params = {
|
||||
info: searchName.value,
|
||||
page: paginationConfig.currentPage,
|
||||
@ -249,8 +228,4 @@ const buttons = [
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
onMounted(() => {
|
||||
loadStatus();
|
||||
});
|
||||
</script>
|
||||
|
@ -1,12 +1,8 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt">
|
||||
<span>{{ $t('container.serviceUnavailable') }}</span>
|
||||
<el-button type="primary" link class="bt" @click="goSetting">【 {{ $t('container.setting') }} 】</el-button>
|
||||
<span>{{ $t('container.startIn') }}</span>
|
||||
</el-card>
|
||||
<docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
|
||||
|
||||
<LayoutContent :title="$t('container.repo')" :class="{ mask: dockerStatus != 'Running' }">
|
||||
<LayoutContent :title="$t('container.repo')" :class="{ mask: !isActive }">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" @click="onOpenDialog('add')">
|
||||
{{ $t('container.createRepo') }}
|
||||
@ -66,12 +62,12 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import OperatorDialog from '@/views/container/repo/operator/index.vue';
|
||||
import { reactive, onMounted, ref } from 'vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { dateFormat } from '@/utils/util';
|
||||
import { Container } from '@/api/interface/container';
|
||||
import { checkRepoStatus, deleteImageRepo, loadDockerStatus, searchImageRepo } from '@/api/modules/container';
|
||||
import { checkRepoStatus, deleteImageRepo, searchImageRepo } from '@/api/modules/container';
|
||||
import DockerStatus from '@/views/container/docker-status/index.vue';
|
||||
import i18n from '@/lang';
|
||||
import router from '@/routers';
|
||||
|
||||
const loading = ref();
|
||||
const data = ref();
|
||||
@ -86,27 +82,12 @@ const searchName = ref();
|
||||
|
||||
const opRef = ref();
|
||||
|
||||
const dockerStatus = ref('Running');
|
||||
const loadStatus = async () => {
|
||||
loading.value = true;
|
||||
await loadDockerStatus()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
dockerStatus.value = res.data;
|
||||
if (dockerStatus.value === 'Running') {
|
||||
search();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dockerStatus.value = 'Failed';
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const goSetting = async () => {
|
||||
router.push({ name: 'ContainerSetting' });
|
||||
};
|
||||
const isActive = ref();
|
||||
|
||||
const search = async () => {
|
||||
if (!isActive.value) {
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
info: searchName.value,
|
||||
page: paginationConfig.currentPage,
|
||||
@ -193,8 +174,4 @@ const buttons = [
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
onMounted(() => {
|
||||
loadStatus();
|
||||
});
|
||||
</script>
|
||||
|
@ -1,12 +1,8 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt">
|
||||
<span>{{ $t('container.serviceUnavailable') }}</span>
|
||||
<el-button type="primary" link class="bt" @click="goSetting">【 {{ $t('container.setting') }} 】</el-button>
|
||||
<span>{{ $t('container.startIn') }}</span>
|
||||
</el-card>
|
||||
<docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
|
||||
|
||||
<LayoutContent :title="$t('container.composeTemplate')" :class="{ mask: dockerStatus != 'Running' }">
|
||||
<LayoutContent :title="$t('container.composeTemplate')" :class="{ mask: !isActive }">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" @click="onOpenDialog('create')">
|
||||
{{ $t('container.createComposeTemplate') }}
|
||||
@ -61,14 +57,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, onMounted, ref } from 'vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { dateFormat } from '@/utils/util';
|
||||
import { Container } from '@/api/interface/container';
|
||||
import DetailDialog from '@/views/container/template/detail/index.vue';
|
||||
import OperatorDialog from '@/views/container/template/operator/index.vue';
|
||||
import { deleteComposeTemplate, loadDockerStatus, searchComposeTemplate } from '@/api/modules/container';
|
||||
import { deleteComposeTemplate, searchComposeTemplate } from '@/api/modules/container';
|
||||
import DockerStatus from '@/views/container/docker-status/index.vue';
|
||||
import i18n from '@/lang';
|
||||
import router from '@/routers';
|
||||
|
||||
const loading = ref();
|
||||
const data = ref();
|
||||
@ -84,28 +80,12 @@ const searchName = ref();
|
||||
|
||||
const detailRef = ref();
|
||||
const opRef = ref();
|
||||
|
||||
const dockerStatus = ref('Running');
|
||||
const loadStatus = async () => {
|
||||
loading.value = true;
|
||||
await loadDockerStatus()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
dockerStatus.value = res.data;
|
||||
if (dockerStatus.value === 'Running') {
|
||||
search();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dockerStatus.value = 'Failed';
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const goSetting = async () => {
|
||||
router.push({ name: 'ContainerSetting' });
|
||||
};
|
||||
const isActive = ref(false);
|
||||
|
||||
const search = async () => {
|
||||
if (!isActive.value) {
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
info: searchName.value,
|
||||
page: paginationConfig.currentPage,
|
||||
@ -187,8 +167,4 @@ const buttons = [
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
onMounted(() => {
|
||||
loadStatus();
|
||||
});
|
||||
</script>
|
||||
|
@ -1,12 +1,8 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt">
|
||||
<span>{{ $t('container.serviceUnavailable') }}</span>
|
||||
<el-button type="primary" link class="bt" @click="goSetting">【 {{ $t('container.setting') }} 】</el-button>
|
||||
<span>{{ $t('container.startIn') }}</span>
|
||||
</el-card>
|
||||
<docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
|
||||
|
||||
<LayoutContent :title="$t('container.volume')" :class="{ mask: dockerStatus != 'Running' }">
|
||||
<LayoutContent :title="$t('container.volume')" :class="{ mask: !isActive }">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" @click="onCreate()">
|
||||
{{ $t('container.createVolume') }}
|
||||
@ -88,9 +84,10 @@
|
||||
<script lang="ts" setup>
|
||||
import CreateDialog from '@/views/container/volume/create/index.vue';
|
||||
import CodemirrorDialog from '@/components/codemirror-dialog/index.vue';
|
||||
import { reactive, onMounted, ref, computed } from 'vue';
|
||||
import DockerStatus from '@/views/container/docker-status/index.vue';
|
||||
import { reactive, ref, computed } from 'vue';
|
||||
import { computeSize, dateFormat } from '@/utils/util';
|
||||
import { deleteVolume, searchVolume, inspect, loadDockerStatus, containerPrune } from '@/api/modules/container';
|
||||
import { deleteVolume, searchVolume, inspect, containerPrune } from '@/api/modules/container';
|
||||
import { Container } from '@/api/interface/container';
|
||||
import i18n from '@/lang';
|
||||
import router from '@/routers';
|
||||
@ -117,26 +114,8 @@ const paginationConfig = reactive({
|
||||
total: 0,
|
||||
});
|
||||
const searchName = ref();
|
||||
const isActive = ref(false);
|
||||
|
||||
const dockerStatus = ref('Running');
|
||||
const loadStatus = async () => {
|
||||
loading.value = true;
|
||||
await loadDockerStatus()
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
dockerStatus.value = res.data;
|
||||
if (dockerStatus.value === 'Running') {
|
||||
search();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dockerStatus.value = 'Failed';
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const goSetting = async () => {
|
||||
router.push({ name: 'ContainerSetting' });
|
||||
};
|
||||
const toFolder = (folder: string) => {
|
||||
router.push({ path: '/hosts/files', query: { path: folder } });
|
||||
};
|
||||
@ -150,6 +129,9 @@ const onCreate = async () => {
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
if (!isActive.value) {
|
||||
return;
|
||||
}
|
||||
const params = {
|
||||
info: searchName.value,
|
||||
page: paginationConfig.currentPage,
|
||||
@ -234,8 +216,4 @@ const buttons = [
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
onMounted(() => {
|
||||
loadStatus();
|
||||
});
|
||||
</script>
|
||||
|
@ -9,15 +9,15 @@
|
||||
@search="search"
|
||||
v-model:loading="loading"
|
||||
v-model:mask-show="maskShow"
|
||||
v-model:status="fireStatus"
|
||||
v-model:is-active="isActive"
|
||||
v-model:name="fireName"
|
||||
/>
|
||||
<div v-if="fireName !== '-'">
|
||||
<el-card v-if="fireStatus != 'running' && maskShow" class="mask-prompt">
|
||||
<el-card v-if="!isActive && maskShow" class="mask-prompt">
|
||||
<span>{{ $t('firewall.firewallNotStart') }}</span>
|
||||
</el-card>
|
||||
|
||||
<LayoutContent :title="$t('firewall.forwardRule')" :class="{ mask: fireStatus != 'running' }">
|
||||
<LayoutContent :title="$t('firewall.forwardRule')" :class="{ mask: !isActive }">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" @click="onOpenDialog('create')">
|
||||
{{ $t('commons.button.create') }}{{ $t('firewall.forwardRule') }}
|
||||
@ -97,7 +97,7 @@ const searchStatus = ref('');
|
||||
const searchStrategy = ref('');
|
||||
|
||||
const maskShow = ref(true);
|
||||
const fireStatus = ref('running');
|
||||
const isActive = ref(false);
|
||||
const fireName = ref();
|
||||
const fireStatusRef = ref();
|
||||
|
||||
@ -112,7 +112,7 @@ const paginationConfig = reactive({
|
||||
});
|
||||
|
||||
const search = async () => {
|
||||
if (fireStatus.value !== 'running') {
|
||||
if (!isActive.value) {
|
||||
loading.value = false;
|
||||
data.value = [];
|
||||
paginationConfig.total = 0;
|
||||
|
@ -10,15 +10,15 @@
|
||||
v-model:loading="loading"
|
||||
v-model:name="fireName"
|
||||
v-model:mask-show="maskShow"
|
||||
v-model:status="fireStatus"
|
||||
v-model:is-active="isActive"
|
||||
/>
|
||||
|
||||
<div v-if="fireName !== '-'">
|
||||
<el-card v-if="fireStatus != 'running' && maskShow" class="mask-prompt">
|
||||
<el-card v-if="!isActive && maskShow" class="mask-prompt">
|
||||
<span>{{ $t('firewall.firewallNotStart') }}</span>
|
||||
</el-card>
|
||||
|
||||
<LayoutContent :title="$t('firewall.ipRule')" :class="{ mask: fireStatus != 'running' }">
|
||||
<LayoutContent :title="$t('firewall.ipRule')" :class="{ mask: !isActive }">
|
||||
<template #leftToolBar>
|
||||
<el-button type="primary" @click="onOpenDialog('create')">
|
||||
{{ $t('commons.button.create') }} {{ $t('firewall.ipRule') }}
|
||||
@ -133,7 +133,7 @@ const searchStrategy = ref('');
|
||||
const fireName = ref();
|
||||
|
||||
const maskShow = ref(true);
|
||||
const fireStatus = ref('running');
|
||||
const isActive = ref(false);
|
||||
const fireStatusRef = ref();
|
||||
|
||||
const opRef = ref();
|
||||
@ -147,7 +147,7 @@ const paginationConfig = reactive({
|
||||
});
|
||||
|
||||
const search = async () => {
|
||||
if (fireStatus.value !== 'running') {
|
||||
if (!isActive.value) {
|
||||
loading.value = false;
|
||||
data.value = [];
|
||||
paginationConfig.total = 0;
|
||||
|
@ -9,15 +9,15 @@
|
||||
@search="search"
|
||||
v-model:loading="loading"
|
||||
v-model:mask-show="maskShow"
|
||||
v-model:status="fireStatus"
|
||||
v-model:is-active="isActive"
|
||||
v-model:name="fireName"
|
||||
/>
|
||||
<div v-if="fireName !== '-'">
|
||||
<el-card v-if="fireStatus != 'running' && maskShow" class="mask-prompt">
|
||||
<el-card v-if="!isActive && maskShow" class="mask-prompt">
|
||||
<span>{{ $t('firewall.firewallNotStart') }}</span>
|
||||
</el-card>
|
||||
|
||||
<LayoutContent :title="$t('firewall.portRule')" :class="{ mask: fireStatus != 'running' }">
|
||||
<LayoutContent :title="$t('firewall.portRule')" :class="{ mask: !isActive }">
|
||||
<template #prompt>
|
||||
<el-alert type="info" :closable="false">
|
||||
<template #default>
|
||||
@ -184,7 +184,7 @@ const searchStatus = ref('');
|
||||
const searchStrategy = ref('');
|
||||
|
||||
const maskShow = ref(true);
|
||||
const fireStatus = ref('running');
|
||||
const isActive = ref(false);
|
||||
const fireName = ref();
|
||||
const fireStatusRef = ref();
|
||||
|
||||
@ -199,7 +199,7 @@ const paginationConfig = reactive({
|
||||
});
|
||||
|
||||
const search = async () => {
|
||||
if (fireStatus.value !== 'running') {
|
||||
if (!isActive.value) {
|
||||
loading.value = false;
|
||||
data.value = [];
|
||||
paginationConfig.total = 0;
|
||||
|
@ -5,19 +5,19 @@
|
||||
<div class="flex w-full flex-col gap-4 md:flex-row">
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<el-tag effect="dark" type="success">{{ baseInfo.name }}</el-tag>
|
||||
<el-tag round v-if="baseInfo.status === 'running'" type="success">
|
||||
<el-tag round v-if="baseInfo.isActive" type="success">
|
||||
{{ $t('commons.status.running') }}
|
||||
</el-tag>
|
||||
<el-tag round v-if="baseInfo.status === 'not running'" type="info">
|
||||
<el-tag round v-if="!baseInfo.isActive" type="info">
|
||||
{{ $t('commons.status.stopped') }}
|
||||
</el-tag>
|
||||
<el-tag>{{ $t('app.version') }}: {{ baseInfo.version }}</el-tag>
|
||||
</div>
|
||||
<div class="mt-0.5">
|
||||
<el-button type="primary" v-if="baseInfo.status === 'running'" @click="onOperate('stop')" link>
|
||||
<el-button type="primary" v-if="baseInfo.isActive" @click="onOperate('stop')" link>
|
||||
{{ $t('commons.button.stop') }}
|
||||
</el-button>
|
||||
<el-button type="primary" v-if="baseInfo.status !== 'running'" @click="onOperate('start')" link>
|
||||
<el-button type="primary" v-if="!baseInfo.isActive" @click="onOperate('start')" link>
|
||||
{{ $t('commons.button.start') }}
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
@ -51,14 +51,14 @@ import { MsgSuccess } from '@/utils/message';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const baseInfo = ref<Host.FirewallBase>({ status: '', name: '', version: '', pingStatus: '' });
|
||||
const baseInfo = ref<Host.FirewallBase>({ isActive: false, isExist: false, name: '', version: '', pingStatus: '' });
|
||||
const onPing = ref('Disable');
|
||||
const oldStatus = ref();
|
||||
|
||||
const acceptParams = (): void => {
|
||||
loadBaseInfo(true);
|
||||
};
|
||||
const emit = defineEmits(['search', 'update:status', 'update:loading', 'update:maskShow', 'update:name']);
|
||||
const emit = defineEmits(['search', 'update:is-active', 'update:loading', 'update:maskShow', 'update:name']);
|
||||
|
||||
const loadBaseInfo = async (search: boolean) => {
|
||||
await loadFireBaseInfo()
|
||||
@ -67,7 +67,7 @@ const loadBaseInfo = async (search: boolean) => {
|
||||
onPing.value = baseInfo.value.pingStatus;
|
||||
oldStatus.value = onPing.value;
|
||||
emit('update:name', baseInfo.value.name);
|
||||
emit('update:status', baseInfo.value.status);
|
||||
emit('update:is-active', baseInfo.value.status);
|
||||
if (search) {
|
||||
emit('search');
|
||||
} else {
|
||||
@ -91,7 +91,6 @@ const onOperate = async (operation: string) => {
|
||||
})
|
||||
.then(async () => {
|
||||
emit('update:loading', true);
|
||||
emit('update:status', 'running');
|
||||
emit('update:maskShow', true);
|
||||
await operateFire(operation)
|
||||
.then(() => {
|
||||
@ -117,7 +116,6 @@ const onPingOperate = async (operation: string) => {
|
||||
})
|
||||
.then(async () => {
|
||||
emit('update:loading', true);
|
||||
emit('update:status', 'running');
|
||||
operation = operation === 'Disable' ? 'disablePing' : 'enablePing';
|
||||
emit('update:maskShow', true);
|
||||
await operateFire(operation)
|
||||
|
@ -7,28 +7,28 @@
|
||||
<div class="flex w-full flex-col gap-4 md:flex-row">
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<el-tag class="float-left" effect="dark" type="success">SSH</el-tag>
|
||||
<el-tag round v-if="form.status === 'Enable'" type="success">
|
||||
<el-tag round v-if="form.isActive" type="success">
|
||||
{{ $t('commons.status.running') }}
|
||||
</el-tag>
|
||||
<el-popover
|
||||
v-if="form.status === 'Disable'"
|
||||
v-if="!form.isActive"
|
||||
placement="top-start"
|
||||
trigger="hover"
|
||||
width="450"
|
||||
:content="form.message"
|
||||
>
|
||||
<template #reference>
|
||||
<el-tag round v-if="form.status === 'Disable'" type="info">
|
||||
<el-tag round v-if="!form.isActive" type="info">
|
||||
{{ $t('commons.status.stopped') }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="mt-0.5">
|
||||
<el-button v-if="form.status === 'Enable'" type="primary" @click="onOperate('stop')" link>
|
||||
<el-button v-if="form.isActive" type="primary" @click="onOperate('stop')" link>
|
||||
{{ $t('commons.button.stop') }}
|
||||
</el-button>
|
||||
<el-button v-if="form.status === 'Disable'" type="primary" @click="onOperate('start')" link>
|
||||
<el-button v-if="!form.isActive" type="primary" @click="onOperate('start')" link>
|
||||
{{ $t('commons.button.start') }}
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
@ -174,7 +174,7 @@ const autoStart = ref('enable');
|
||||
|
||||
const sshConf = ref();
|
||||
const form = reactive({
|
||||
status: 'enable',
|
||||
isActive: false,
|
||||
message: '',
|
||||
port: 22,
|
||||
listenAddress: '',
|
||||
@ -316,7 +316,7 @@ const changeMode = async () => {
|
||||
|
||||
const search = async () => {
|
||||
const res = await getSSHInfo();
|
||||
form.status = res.data.status;
|
||||
form.isActive = res.data.isActive;
|
||||
form.port = Number(res.data.port);
|
||||
autoStart.value = res.data.autoStart ? 'enable' : 'disable';
|
||||
form.listenAddress = res.data.listenAddress;
|
||||
|
Loading…
x
Reference in New Issue
Block a user