1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-17 03:04:46 +08:00

feat: uniform application service status return (#7426)

This commit is contained in:
ssongliu 2024-12-18 18:06:15 +08:00 committed by GitHub
parent f6475e7c7f
commit 55a6cdcf10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 171 additions and 294 deletions

View File

@ -6,7 +6,8 @@ type DaemonJsonUpdateByFile struct {
type DaemonJsonConf struct { type DaemonJsonConf struct {
IsSwarm bool `json:"isSwarm"` IsSwarm bool `json:"isSwarm"`
Status string `json:"status"` IsExist bool `json:"isExist"`
IsActive bool `json:"isActive"`
Version string `json:"version"` Version string `json:"version"`
Mirrors []string `json:"registryMirrors"` Mirrors []string `json:"registryMirrors"`
Registries []string `json:"insecureRegistries"` Registries []string `json:"insecureRegistries"`

View File

@ -2,7 +2,8 @@ package dto
type FirewallBaseInfo struct { type FirewallBaseInfo struct {
Name string `json:"name"` Name string `json:"name"`
Status string `json:"status"` IsExist bool `json:"isExist"`
IsActive bool `json:"isActive"`
Version string `json:"version"` Version string `json:"version"`
PingStatus string `json:"pingStatus"` PingStatus string `json:"pingStatus"`
} }

View File

@ -10,7 +10,8 @@ type SSHUpdate struct {
type SSHInfo struct { type SSHInfo struct {
AutoStart bool `json:"autoStart"` AutoStart bool `json:"autoStart"`
Status string `json:"status"` IsExist bool `json:"isExist"`
IsActive bool `json:"isActive"`
Message string `json:"message"` Message string `json:"message"`
Port string `json:"port"` Port string `json:"port"`
ListenAddress string `json:"listenAddress"` ListenAddress string `json:"listenAddress"`

View File

@ -69,15 +69,19 @@ func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf {
ctx := context.Background() ctx := context.Background()
var data dto.DaemonJsonConf var data dto.DaemonJsonConf
data.IPTables = true data.IPTables = true
data.Status = constant.StatusRunning
data.Version = "-" data.Version = "-"
if cmd.Which("docker") {
data.IsExist = false
return &data
}
data.IsExist = true
client, err := docker.NewDockerClient() client, err := docker.NewDockerClient()
if err != nil { if err != nil {
data.Status = constant.Stopped data.IsActive = false
} else { } else {
defer client.Close() defer client.Close()
if _, err := client.Ping(ctx); err != nil { if _, err := client.Ping(ctx); err != nil {
data.Status = constant.Stopped data.IsActive = false
} }
itemVersion, err := client.ServerVersion(ctx) itemVersion, err := client.ServerVersion(ctx)
if err == nil { if err == nil {

View File

@ -116,8 +116,8 @@ func (u *Fail2BanService) UpdateConf(req dto.Fail2BanUpdate) error {
if client.Name() != itemName { if client.Name() != itemName {
return buserr.WithName("ErrBanAction", itemName) return buserr.WithName("ErrBanAction", itemName)
} }
status, _ := client.Status() isActive, _ := client.Status()
if status != "running" { if !isActive {
return buserr.WithName("ErrBanAction", itemName) return buserr.WithName("ErrBanAction", itemName)
} }
} }

View File

@ -43,13 +43,14 @@ func NewIFirewallService() IFirewallService {
func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) { func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) {
var baseInfo dto.FirewallBaseInfo var baseInfo dto.FirewallBaseInfo
baseInfo.Status = "not running"
baseInfo.Version = "-" baseInfo.Version = "-"
baseInfo.Name = "-" baseInfo.Name = "-"
client, err := firewall.NewFirewallClient() client, err := firewall.NewFirewallClient()
if err != nil { if err != nil {
baseInfo.IsExist = false
return baseInfo, err return baseInfo, err
} }
baseInfo.IsExist = true
baseInfo.Name = client.Name() baseInfo.Name = client.Name()
var wg sync.WaitGroup var wg sync.WaitGroup
@ -60,7 +61,7 @@ func (u *FirewallService) LoadBaseInfo() (dto.FirewallBaseInfo, error) {
}() }()
go func() { go func() {
defer wg.Done() defer wg.Done()
baseInfo.Status, _ = client.Status() baseInfo.IsActive, _ = client.Status()
}() }()
go func() { go func() {
defer wg.Done() defer wg.Done()

View File

@ -45,7 +45,8 @@ func NewISSHService() ISSHService {
func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) { func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
data := dto.SSHInfo{ data := dto.SSHInfo{
AutoStart: true, AutoStart: true,
Status: constant.StatusEnable, IsExist: true,
IsActive: true,
Message: "", Message: "",
Port: "22", Port: "22",
ListenAddress: "", ListenAddress: "",
@ -56,17 +57,13 @@ func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
} }
serviceName, err := loadServiceName() serviceName, err := loadServiceName()
if err != nil { if err != nil {
data.Status = constant.StatusDisable data.IsExist = false
data.Message = err.Error() data.Message = err.Error()
} else { } else {
active, err := systemctl.IsActive(serviceName) active, err := systemctl.IsActive(serviceName)
if !active { data.IsActive = active
data.Status = constant.StatusDisable if !active && err != nil {
if err != nil { data.Message = err.Error()
data.Message = err.Error()
}
} else {
data.Status = constant.StatusEnable
} }
} }
@ -84,7 +81,7 @@ func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
sshConf, err := os.ReadFile(sshPath) sshConf, err := os.ReadFile(sshPath)
if err != nil { if err != nil {
data.Message = err.Error() data.Message = err.Error()
data.Status = constant.StatusDisable data.IsActive = false
} }
lines := strings.Split(string(sshConf), "\n") lines := strings.Split(string(sshConf), "\n")
for _, line := range lines { for _, line := range lines {

View File

@ -13,7 +13,7 @@ type FirewallClient interface {
Stop() error Stop() error
Restart() error Restart() error
Reload() error Reload() error
Status() (string, error) // running not running Status() (bool, error) // running not running
Version() (string, error) Version() (string, error)
ListPort() ([]client.FireInfo, error) ListPort() ([]client.FireInfo, error)

View File

@ -24,12 +24,9 @@ func (f *Firewall) Name() string {
return "firewalld" return "firewalld"
} }
func (f *Firewall) Status() (string, error) { func (f *Firewall) Status() (bool, error) {
stdout, _ := cmd.Exec("firewall-cmd --state") stdout, _ := cmd.Exec("firewall-cmd --state")
if stdout == "running\n" { return stdout == "running\n", nil
return "running", nil
}
return "not running", nil
} }
func (f *Firewall) Version() (string, error) { func (f *Firewall) Version() (string, error) {

View File

@ -27,8 +27,8 @@ func NewIptables() (*Iptables, error) {
return iptables, nil return iptables, nil
} }
func (iptables *Iptables) runf(rule string, a ...any) error { func (iptables *Iptables) run(rule string) error {
stdout, err := cmd.Execf("%s iptables -t nat %s", iptables.CmdStr, fmt.Sprintf(rule, a...)) stdout, err := cmd.Execf("%s iptables -t nat %s", iptables.CmdStr, rule)
if err != nil { if err != nil {
return fmt.Errorf("%s, %s", err, stdout) return fmt.Errorf("%s, %s", err, stdout)
} }
@ -39,6 +39,10 @@ func (iptables *Iptables) runf(rule string, a ...any) error {
return nil return nil
} }
func (iptables *Iptables) runf(rule string, a ...any) error {
return iptables.run(fmt.Sprintf(rule, a...))
}
func (iptables *Iptables) Check() error { func (iptables *Iptables) Check() error {
stdout, err := cmd.Exec("cat /proc/sys/net/ipv4/ip_forward") stdout, err := cmd.Exec("cat /proc/sys/net/ipv4/ip_forward")
if err != nil { 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" { 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) 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 return err
} }

View File

@ -28,16 +28,16 @@ func (f *Ufw) Name() string {
return "ufw" return "ufw"
} }
func (f *Ufw) Status() (string, error) { func (f *Ufw) Status() (bool, error) {
stdout, _ := cmd.Execf("%s status | grep Status", f.CmdStr) stdout, _ := cmd.Execf("%s status | grep Status", f.CmdStr)
if stdout == "Status: active\n" { if stdout == "Status: active\n" {
return "running", nil return true, nil
} }
stdout1, _ := cmd.Execf("%s status | grep 状态", f.CmdStr) stdout1, _ := cmd.Execf("%s status | grep 状态", f.CmdStr)
if stdout1 == "状态: 激活\n" { if stdout1 == "状态: 激活\n" {
return "running", nil return true, nil
} }
return "not running", nil return false, nil
} }
func (f *Ufw) Version() (string, error) { func (f *Ufw) Version() (string, error) {

View File

@ -3,13 +3,10 @@
<div v-show="isOnDetail"> <div v-show="isOnDetail">
<ComposeDetail ref="composeDetailRef" /> <ComposeDetail ref="composeDetailRef" />
</div> </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> <template #leftToolBar>
<el-button type="primary" @click="onOpenDialog()"> <el-button type="primary" @click="onOpenDialog()">
{{ $t('container.createCompose') }} {{ $t('container.createCompose') }}
@ -90,12 +87,13 @@
</template> </template>
<script lang="ts" setup> <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 EditDialog from '@/views/container/compose/edit/index.vue';
import CreateDialog from '@/views/container/compose/create/index.vue'; import CreateDialog from '@/views/container/compose/create/index.vue';
import DeleteDialog from '@/views/container/compose/delete/index.vue'; import DeleteDialog from '@/views/container/compose/delete/index.vue';
import ComposeDetail from '@/views/container/compose/detail/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 i18n from '@/lang';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
import router from '@/routers'; import router from '@/routers';
@ -114,31 +112,16 @@ const paginationConfig = reactive({
}); });
const searchName = ref(); const searchName = ref();
const dockerStatus = ref('Running'); const isActive = ref(false);
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 toComposeFolder = async (row: Container.ComposeInfo) => { const toComposeFolder = async (row: Container.ComposeInfo) => {
router.push({ path: '/hosts/files', query: { path: row.workdir } }); router.push({ path: '/hosts/files', query: { path: row.workdir } });
}; };
const search = async () => { const search = async () => {
if (!isActive.value) {
return;
}
let params = { let params = {
info: searchName.value, info: searchName.value,
page: paginationConfig.currentPage, page: paginationConfig.currentPage,
@ -225,7 +208,4 @@ const buttons = [
}, },
}, },
]; ];
onMounted(() => {
loadStatus();
});
</script> </script>

View File

@ -1,12 +1,8 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt"> <docker-status v-model:isActive="isActive" @search="search" />
<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>
<div class="mt-5"> <div class="mt-5" v-if="isActive">
<el-tag @click="searchWithStatus('all')" v-if="countItem.all" effect="plain" size="large"> <el-tag @click="searchWithStatus('all')" v-if="countItem.all" effect="plain" size="large">
{{ $t('commons.table.all') }} * {{ countItem.all }} {{ $t('commons.table.all') }} * {{ countItem.all }}
</el-tag> </el-tag>
@ -69,7 +65,7 @@
</el-tag> </el-tag>
</div> </div>
<LayoutContent :title="$t('container.container')" :class="{ mask: dockerStatus != 'Running' }"> <LayoutContent :title="$t('container.container')" :class="{ mask: !isActive }">
<template #leftToolBar> <template #leftToolBar>
<el-button type="primary" @click="onContainerOperate('')"> <el-button type="primary" @click="onContainerOperate('')">
{{ $t('container.create') }} {{ $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 TerminalDialog from '@/views/container/container/terminal/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/index.vue'; import CodemirrorDialog from '@/components/codemirror-dialog/index.vue';
import PortJumpDialog from '@/components/port-jump/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 Status from '@/components/status/index.vue';
import { reactive, onMounted, ref, computed } from 'vue'; import { reactive, onMounted, ref, computed } from 'vue';
import { import {
@ -421,7 +418,6 @@ import {
containerOperator, containerOperator,
inspect, inspect,
loadContainerStatus, loadContainerStatus,
loadDockerStatus,
searchContainer, searchContainer,
} from '@/api/modules/container'; } from '@/api/modules/container';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
@ -434,6 +430,7 @@ const globalStore = GlobalStore();
const mobile = computed(() => { const mobile = computed(() => {
return globalStore.isMobile(); return globalStore.isMobile();
}); });
const isActive = ref(false);
const loading = ref(false); const loading = ref(false);
const data = ref(); const data = ref();
@ -466,23 +463,6 @@ const countItem = reactive({
dead: 0, 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) => { const goDashboard = async (port: any) => {
if (port.indexOf('127.0.0.1') !== -1) { if (port.indexOf('127.0.0.1') !== -1) {
MsgWarning(i18n.global.t('container.unExposedPort')); MsgWarning(i18n.global.t('container.unExposedPort'));
@ -499,10 +479,6 @@ const goDashboard = async (port: any) => {
dialogPortJumpRef.value.acceptParams({ port: portEx, ip: ip }); dialogPortJumpRef.value.acceptParams({ port: portEx, ip: ip });
}; };
const goSetting = async () => {
router.push({ name: 'ContainerSetting' });
};
interface Filters { interface Filters {
filters?: string; filters?: string;
} }
@ -517,6 +493,9 @@ const dialogRenameRef = ref();
const dialogPruneRef = ref(); const dialogPruneRef = ref();
const search = async (column?: any) => { const search = async (column?: any) => {
if (!isActive.value) {
return;
}
localStorage.setItem('includeAppStore', includeAppStore.value ? 'true' : 'false'); localStorage.setItem('includeAppStore', includeAppStore.value ? 'true' : 'false');
let filterItem = props.filters ? props.filters : ''; let filterItem = props.filters ? props.filters : '';
paginationConfig.orderBy = column?.order ? column.prop : paginationConfig.orderBy; paginationConfig.orderBy = column?.order ? column.prop : paginationConfig.orderBy;
@ -802,7 +781,6 @@ const buttons = [
onMounted(() => { onMounted(() => {
let includeItem = localStorage.getItem('includeAppStore'); let includeItem = localStorage.getItem('includeAppStore');
includeAppStore.value = !includeItem || includeItem === 'true'; includeAppStore.value = !includeItem || includeItem === 'true';
loadStatus();
}); });
</script> </script>

View 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>

View File

@ -1,12 +1,8 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt"> <docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" @mounted="loadRepos" />
<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 :title="$t('container.image')" :class="{ mask: dockerStatus != 'Running' }"> <LayoutContent :title="$t('container.image')" :class="{ mask: !isActive }">
<template #leftToolBar> <template #leftToolBar>
<el-button type="primary" plain @click="onOpenPull"> <el-button type="primary" plain @click="onOpenPull">
{{ $t('container.imagePull') }} {{ $t('container.imagePull') }}
@ -99,7 +95,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, onMounted, ref, computed } from 'vue'; import { reactive, ref, computed } from 'vue';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
import Pull from '@/views/container/image/pull/index.vue'; 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 Build from '@/views/container/image/build/index.vue';
import Delete from '@/views/container/image/delete/index.vue'; import Delete from '@/views/container/image/delete/index.vue';
import Prune from '@/views/container/image/prune/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 CodemirrorDialog from '@/components/codemirror-dialog/index.vue';
import { import { searchImage, listImageRepo, imageRemove, inspect, containerPrune } from '@/api/modules/container';
searchImage,
listImageRepo,
loadDockerStatus,
imageRemove,
inspect,
containerPrune,
} from '@/api/modules/container';
import i18n from '@/lang'; import i18n from '@/lang';
import router from '@/routers';
import { GlobalStore } from '@/store'; import { GlobalStore } from '@/store';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
@ -144,26 +133,7 @@ const paginationConfig = reactive({
}); });
const searchName = ref(); const searchName = ref();
const dockerStatus = ref('Running'); const isActive = ref(false);
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 mydetail = ref(); const mydetail = ref();
const dialogPullRef = ref(); const dialogPullRef = ref();
@ -176,6 +146,9 @@ const dialogDeleteRef = ref();
const dialogPruneRef = ref(); const dialogPruneRef = ref();
const search = async () => { const search = async () => {
if (!isActive.value) {
return;
}
const repoSearch = { const repoSearch = {
info: searchName.value, info: searchName.value,
page: paginationConfig.currentPage, page: paginationConfig.currentPage,
@ -305,8 +278,4 @@ const buttons = [
}, },
}, },
]; ];
onMounted(() => {
loadStatus();
});
</script> </script>

View File

@ -1,12 +1,8 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt"> <docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
<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 :title="$t('container.network')" :class="{ mask: dockerStatus != 'Running' }"> <LayoutContent :title="$t('container.network')" :class="{ mask: !isActive }">
<template #leftToolBar> <template #leftToolBar>
<el-button type="primary" @click="onCreate()"> <el-button type="primary" @click="onCreate()">
{{ $t('container.createNetwork') }} {{ $t('container.createNetwork') }}
@ -93,14 +89,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import CreateDialog from '@/views/container/network/create/index.vue'; import CreateDialog from '@/views/container/network/create/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/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 { 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 { Container } from '@/api/interface/container';
import i18n from '@/lang'; import i18n from '@/lang';
import router from '@/routers';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import DockerStatus from '@/views/container/docker-status/index.vue';
const loading = ref(); const loading = ref();
const codemirror = ref(); const codemirror = ref();
@ -116,27 +112,7 @@ const paginationConfig = reactive({
const searchName = ref(); const searchName = ref();
const opRef = ref(); const opRef = 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 dialogCreateRef = ref<DialogExpose>(); const dialogCreateRef = ref<DialogExpose>();
interface DialogExpose { interface DialogExpose {
@ -174,6 +150,9 @@ function selectable(row) {
} }
const search = async () => { const search = async () => {
if (!isActive.value) {
return;
}
const params = { const params = {
info: searchName.value, info: searchName.value,
page: paginationConfig.currentPage, page: paginationConfig.currentPage,
@ -249,8 +228,4 @@ const buttons = [
}, },
}, },
]; ];
onMounted(() => {
loadStatus();
});
</script> </script>

View File

@ -1,12 +1,8 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt"> <docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
<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 :title="$t('container.repo')" :class="{ mask: dockerStatus != 'Running' }"> <LayoutContent :title="$t('container.repo')" :class="{ mask: !isActive }">
<template #leftToolBar> <template #leftToolBar>
<el-button type="primary" @click="onOpenDialog('add')"> <el-button type="primary" @click="onOpenDialog('add')">
{{ $t('container.createRepo') }} {{ $t('container.createRepo') }}
@ -66,12 +62,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import OperatorDialog from '@/views/container/repo/operator/index.vue'; 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 { dateFormat } from '@/utils/util';
import { Container } from '@/api/interface/container'; 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 i18n from '@/lang';
import router from '@/routers';
const loading = ref(); const loading = ref();
const data = ref(); const data = ref();
@ -86,27 +82,12 @@ const searchName = ref();
const opRef = ref(); const opRef = ref();
const dockerStatus = ref('Running'); const isActive = ref();
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 search = async () => { const search = async () => {
if (!isActive.value) {
return;
}
let params = { let params = {
info: searchName.value, info: searchName.value,
page: paginationConfig.currentPage, page: paginationConfig.currentPage,
@ -193,8 +174,4 @@ const buttons = [
}, },
}, },
]; ];
onMounted(() => {
loadStatus();
});
</script> </script>

View File

@ -1,12 +1,8 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt"> <docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
<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 :title="$t('container.composeTemplate')" :class="{ mask: dockerStatus != 'Running' }"> <LayoutContent :title="$t('container.composeTemplate')" :class="{ mask: !isActive }">
<template #leftToolBar> <template #leftToolBar>
<el-button type="primary" @click="onOpenDialog('create')"> <el-button type="primary" @click="onOpenDialog('create')">
{{ $t('container.createComposeTemplate') }} {{ $t('container.createComposeTemplate') }}
@ -61,14 +57,14 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, onMounted, ref } from 'vue'; import { reactive, ref } from 'vue';
import { dateFormat } from '@/utils/util'; import { dateFormat } from '@/utils/util';
import { Container } from '@/api/interface/container'; import { Container } from '@/api/interface/container';
import DetailDialog from '@/views/container/template/detail/index.vue'; import DetailDialog from '@/views/container/template/detail/index.vue';
import OperatorDialog from '@/views/container/template/operator/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 i18n from '@/lang';
import router from '@/routers';
const loading = ref(); const loading = ref();
const data = ref(); const data = ref();
@ -84,28 +80,12 @@ const searchName = ref();
const detailRef = ref(); const detailRef = ref();
const opRef = ref(); const opRef = 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 search = async () => { const search = async () => {
if (!isActive.value) {
return;
}
let params = { let params = {
info: searchName.value, info: searchName.value,
page: paginationConfig.currentPage, page: paginationConfig.currentPage,
@ -187,8 +167,4 @@ const buttons = [
}, },
}, },
]; ];
onMounted(() => {
loadStatus();
});
</script> </script>

View File

@ -1,12 +1,8 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<el-card v-if="dockerStatus != 'Running'" class="mask-prompt"> <docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
<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 :title="$t('container.volume')" :class="{ mask: dockerStatus != 'Running' }"> <LayoutContent :title="$t('container.volume')" :class="{ mask: !isActive }">
<template #leftToolBar> <template #leftToolBar>
<el-button type="primary" @click="onCreate()"> <el-button type="primary" @click="onCreate()">
{{ $t('container.createVolume') }} {{ $t('container.createVolume') }}
@ -88,9 +84,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import CreateDialog from '@/views/container/volume/create/index.vue'; import CreateDialog from '@/views/container/volume/create/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/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 { 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 { Container } from '@/api/interface/container';
import i18n from '@/lang'; import i18n from '@/lang';
import router from '@/routers'; import router from '@/routers';
@ -117,26 +114,8 @@ const paginationConfig = reactive({
total: 0, total: 0,
}); });
const searchName = ref(); 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) => { const toFolder = (folder: string) => {
router.push({ path: '/hosts/files', query: { path: folder } }); router.push({ path: '/hosts/files', query: { path: folder } });
}; };
@ -150,6 +129,9 @@ const onCreate = async () => {
}; };
const search = async () => { const search = async () => {
if (!isActive.value) {
return;
}
const params = { const params = {
info: searchName.value, info: searchName.value,
page: paginationConfig.currentPage, page: paginationConfig.currentPage,
@ -234,8 +216,4 @@ const buttons = [
}, },
}, },
]; ];
onMounted(() => {
loadStatus();
});
</script> </script>

View File

@ -9,15 +9,15 @@
@search="search" @search="search"
v-model:loading="loading" v-model:loading="loading"
v-model:mask-show="maskShow" v-model:mask-show="maskShow"
v-model:status="fireStatus" v-model:is-active="isActive"
v-model:name="fireName" v-model:name="fireName"
/> />
<div v-if="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> <span>{{ $t('firewall.firewallNotStart') }}</span>
</el-card> </el-card>
<LayoutContent :title="$t('firewall.forwardRule')" :class="{ mask: fireStatus != 'running' }"> <LayoutContent :title="$t('firewall.forwardRule')" :class="{ mask: !isActive }">
<template #leftToolBar> <template #leftToolBar>
<el-button type="primary" @click="onOpenDialog('create')"> <el-button type="primary" @click="onOpenDialog('create')">
{{ $t('commons.button.create') }}{{ $t('firewall.forwardRule') }} {{ $t('commons.button.create') }}{{ $t('firewall.forwardRule') }}
@ -97,7 +97,7 @@ const searchStatus = ref('');
const searchStrategy = ref(''); const searchStrategy = ref('');
const maskShow = ref(true); const maskShow = ref(true);
const fireStatus = ref('running'); const isActive = ref(false);
const fireName = ref(); const fireName = ref();
const fireStatusRef = ref(); const fireStatusRef = ref();
@ -112,7 +112,7 @@ const paginationConfig = reactive({
}); });
const search = async () => { const search = async () => {
if (fireStatus.value !== 'running') { if (!isActive.value) {
loading.value = false; loading.value = false;
data.value = []; data.value = [];
paginationConfig.total = 0; paginationConfig.total = 0;

View File

@ -10,15 +10,15 @@
v-model:loading="loading" v-model:loading="loading"
v-model:name="fireName" v-model:name="fireName"
v-model:mask-show="maskShow" v-model:mask-show="maskShow"
v-model:status="fireStatus" v-model:is-active="isActive"
/> />
<div v-if="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> <span>{{ $t('firewall.firewallNotStart') }}</span>
</el-card> </el-card>
<LayoutContent :title="$t('firewall.ipRule')" :class="{ mask: fireStatus != 'running' }"> <LayoutContent :title="$t('firewall.ipRule')" :class="{ mask: !isActive }">
<template #leftToolBar> <template #leftToolBar>
<el-button type="primary" @click="onOpenDialog('create')"> <el-button type="primary" @click="onOpenDialog('create')">
{{ $t('commons.button.create') }} {{ $t('firewall.ipRule') }} {{ $t('commons.button.create') }} {{ $t('firewall.ipRule') }}
@ -133,7 +133,7 @@ const searchStrategy = ref('');
const fireName = ref(); const fireName = ref();
const maskShow = ref(true); const maskShow = ref(true);
const fireStatus = ref('running'); const isActive = ref(false);
const fireStatusRef = ref(); const fireStatusRef = ref();
const opRef = ref(); const opRef = ref();
@ -147,7 +147,7 @@ const paginationConfig = reactive({
}); });
const search = async () => { const search = async () => {
if (fireStatus.value !== 'running') { if (!isActive.value) {
loading.value = false; loading.value = false;
data.value = []; data.value = [];
paginationConfig.total = 0; paginationConfig.total = 0;

View File

@ -9,15 +9,15 @@
@search="search" @search="search"
v-model:loading="loading" v-model:loading="loading"
v-model:mask-show="maskShow" v-model:mask-show="maskShow"
v-model:status="fireStatus" v-model:is-active="isActive"
v-model:name="fireName" v-model:name="fireName"
/> />
<div v-if="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> <span>{{ $t('firewall.firewallNotStart') }}</span>
</el-card> </el-card>
<LayoutContent :title="$t('firewall.portRule')" :class="{ mask: fireStatus != 'running' }"> <LayoutContent :title="$t('firewall.portRule')" :class="{ mask: !isActive }">
<template #prompt> <template #prompt>
<el-alert type="info" :closable="false"> <el-alert type="info" :closable="false">
<template #default> <template #default>
@ -184,7 +184,7 @@ const searchStatus = ref('');
const searchStrategy = ref(''); const searchStrategy = ref('');
const maskShow = ref(true); const maskShow = ref(true);
const fireStatus = ref('running'); const isActive = ref(false);
const fireName = ref(); const fireName = ref();
const fireStatusRef = ref(); const fireStatusRef = ref();
@ -199,7 +199,7 @@ const paginationConfig = reactive({
}); });
const search = async () => { const search = async () => {
if (fireStatus.value !== 'running') { if (!isActive.value) {
loading.value = false; loading.value = false;
data.value = []; data.value = [];
paginationConfig.total = 0; paginationConfig.total = 0;

View File

@ -5,19 +5,19 @@
<div class="flex w-full flex-col gap-4 md:flex-row"> <div class="flex w-full flex-col gap-4 md:flex-row">
<div class="flex flex-wrap gap-4"> <div class="flex flex-wrap gap-4">
<el-tag effect="dark" type="success">{{ baseInfo.name }}</el-tag> <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') }} {{ $t('commons.status.running') }}
</el-tag> </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') }} {{ $t('commons.status.stopped') }}
</el-tag> </el-tag>
<el-tag>{{ $t('app.version') }}: {{ baseInfo.version }}</el-tag> <el-tag>{{ $t('app.version') }}: {{ baseInfo.version }}</el-tag>
</div> </div>
<div class="mt-0.5"> <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') }} {{ $t('commons.button.stop') }}
</el-button> </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') }} {{ $t('commons.button.start') }}
</el-button> </el-button>
<el-divider direction="vertical" /> <el-divider direction="vertical" />
@ -51,14 +51,14 @@ import { MsgSuccess } from '@/utils/message';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import { ref } from 'vue'; 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 onPing = ref('Disable');
const oldStatus = ref(); const oldStatus = ref();
const acceptParams = (): void => { const acceptParams = (): void => {
loadBaseInfo(true); 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) => { const loadBaseInfo = async (search: boolean) => {
await loadFireBaseInfo() await loadFireBaseInfo()
@ -67,7 +67,7 @@ const loadBaseInfo = async (search: boolean) => {
onPing.value = baseInfo.value.pingStatus; onPing.value = baseInfo.value.pingStatus;
oldStatus.value = onPing.value; oldStatus.value = onPing.value;
emit('update:name', baseInfo.value.name); emit('update:name', baseInfo.value.name);
emit('update:status', baseInfo.value.status); emit('update:is-active', baseInfo.value.status);
if (search) { if (search) {
emit('search'); emit('search');
} else { } else {
@ -91,7 +91,6 @@ const onOperate = async (operation: string) => {
}) })
.then(async () => { .then(async () => {
emit('update:loading', true); emit('update:loading', true);
emit('update:status', 'running');
emit('update:maskShow', true); emit('update:maskShow', true);
await operateFire(operation) await operateFire(operation)
.then(() => { .then(() => {
@ -117,7 +116,6 @@ const onPingOperate = async (operation: string) => {
}) })
.then(async () => { .then(async () => {
emit('update:loading', true); emit('update:loading', true);
emit('update:status', 'running');
operation = operation === 'Disable' ? 'disablePing' : 'enablePing'; operation = operation === 'Disable' ? 'disablePing' : 'enablePing';
emit('update:maskShow', true); emit('update:maskShow', true);
await operateFire(operation) await operateFire(operation)

View File

@ -7,28 +7,28 @@
<div class="flex w-full flex-col gap-4 md:flex-row"> <div class="flex w-full flex-col gap-4 md:flex-row">
<div class="flex flex-wrap gap-4"> <div class="flex flex-wrap gap-4">
<el-tag class="float-left" effect="dark" type="success">SSH</el-tag> <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') }} {{ $t('commons.status.running') }}
</el-tag> </el-tag>
<el-popover <el-popover
v-if="form.status === 'Disable'" v-if="!form.isActive"
placement="top-start" placement="top-start"
trigger="hover" trigger="hover"
width="450" width="450"
:content="form.message" :content="form.message"
> >
<template #reference> <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') }} {{ $t('commons.status.stopped') }}
</el-tag> </el-tag>
</template> </template>
</el-popover> </el-popover>
</div> </div>
<div class="mt-0.5"> <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') }} {{ $t('commons.button.stop') }}
</el-button> </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') }} {{ $t('commons.button.start') }}
</el-button> </el-button>
<el-divider direction="vertical" /> <el-divider direction="vertical" />
@ -174,7 +174,7 @@ const autoStart = ref('enable');
const sshConf = ref(); const sshConf = ref();
const form = reactive({ const form = reactive({
status: 'enable', isActive: false,
message: '', message: '',
port: 22, port: 22,
listenAddress: '', listenAddress: '',
@ -316,7 +316,7 @@ const changeMode = async () => {
const search = async () => { const search = async () => {
const res = await getSSHInfo(); const res = await getSSHInfo();
form.status = res.data.status; form.isActive = res.data.isActive;
form.port = Number(res.data.port); form.port = Number(res.data.port);
autoStart.value = res.data.autoStart ? 'enable' : 'disable'; autoStart.value = res.data.autoStart ? 'enable' : 'disable';
form.listenAddress = res.data.listenAddress; form.listenAddress = res.data.listenAddress;