mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-23 00:00:52 +00:00
fix: Fix the firewall startup failure (#8141)
This commit is contained in:
@@ -555,13 +555,15 @@ func (u *ContainerService) ContainerInfo(req dto.OperationWithName) (*dto.Contai
|
||||
networkSettings := oldContainer.NetworkSettings
|
||||
bridgeNetworkSettings := networkSettings.Networks[data.Network]
|
||||
if bridgeNetworkSettings.IPAMConfig != nil {
|
||||
ipv4Address := bridgeNetworkSettings.IPAMConfig.IPv4Address
|
||||
data.MacAddr = bridgeNetworkSettings.MacAddress
|
||||
data.Ipv4 = ipv4Address
|
||||
ipv6Address := bridgeNetworkSettings.IPAMConfig.IPv6Address
|
||||
data.Ipv6 = ipv6Address
|
||||
if data.Network != "bridge" {
|
||||
data.Ipv4 = bridgeNetworkSettings.IPAMConfig.IPv4Address
|
||||
data.Ipv6 = bridgeNetworkSettings.IPAMConfig.IPv6Address
|
||||
}
|
||||
} else {
|
||||
data.Ipv4 = bridgeNetworkSettings.IPAddress
|
||||
if data.Network != "bridge" {
|
||||
data.Ipv4 = bridgeNetworkSettings.IPAddress
|
||||
}
|
||||
}
|
||||
data.Hostname = oldContainer.Config.Hostname
|
||||
data.DNS = oldContainer.HostConfig.DNS
|
||||
|
||||
@@ -611,8 +611,10 @@ func (u *FirewallService) updatePingStatus(enable string) error {
|
||||
}
|
||||
|
||||
func (u *FirewallService) addPortsBeforeStart(client firewall.FirewallClient) error {
|
||||
if err := client.Port(fireClient.FireInfo{Port: global.CONF.Base.Port, Protocol: "tcp", Strategy: "accept"}, "add"); err != nil {
|
||||
return err
|
||||
if !global.IsMaster {
|
||||
if err := client.Port(fireClient.FireInfo{Port: global.CONF.Base.Port, Protocol: "tcp", Strategy: "accept"}, "add"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := client.Port(fireClient.FireInfo{Port: "22", Protocol: "tcp", Strategy: "accept"}, "add"); err != nil {
|
||||
return err
|
||||
|
||||
@@ -1860,8 +1860,9 @@ const message = {
|
||||
subscription: 'Subscription',
|
||||
perpetual: 'Perpetual',
|
||||
versionConstraint: '{0} Version Buyout',
|
||||
forceDelete: 'Force delete, will ignore errors during the deletion process and eventually remove metadata',
|
||||
deleteHelper: 'Deleting the license may cause child nodes to be unable to switch, please proceed with caution!',
|
||||
forceUnbind: 'Force Unbind',
|
||||
forceUnbindHelper:
|
||||
'Forcing unbind will ignore any errors that occur during the unbinding process and ultimately release the license binding.',
|
||||
trialInfo: 'Version',
|
||||
authorizationId: 'Authorization ID',
|
||||
authorizedUser: 'Authorized User',
|
||||
@@ -3212,7 +3213,7 @@ const message = {
|
||||
fixSSHConn: 'Manually edit the node to confirm connection information',
|
||||
checkConnInfo: 'Check Agent Connection Information',
|
||||
checkStatus: 'Check Node Service Availability',
|
||||
fixStatus: 'Investigate Node Logs',
|
||||
fixStatus: 'Run "systemctl status 1panel-agent.service" to check if the service is running.',
|
||||
checkAPI: 'Check Node API Availability',
|
||||
fixAPI: 'Check the node logs and verify if the firewall ports are properly opened.',
|
||||
forceDelete: 'Force Delete',
|
||||
|
||||
@@ -1723,6 +1723,9 @@ const message = {
|
||||
subscription: 'サブスクリプション',
|
||||
perpetual: '永久ライセンス',
|
||||
versionConstraint: '{0} バージョン買い取り',
|
||||
forceUnbind: '強制バインド解除',
|
||||
forceUnbindHelper:
|
||||
'強制的にバインド解除を行うと、解除プロセス中に発生するエラーを無視し、最終的にライセンスのバインドを解除します。',
|
||||
trialInfo: 'バージョン',
|
||||
authorizationId: 'サブスクリプション承認ID',
|
||||
authorizedUser: '認定ユーザー',
|
||||
@@ -3024,7 +3027,7 @@ const message = {
|
||||
fixSSHConn: 'ノードを手動で編集し、接続情報を確認',
|
||||
checkConnInfo: 'エージェント接続情報を確認',
|
||||
checkStatus: 'ノードサービスの可用性を確認',
|
||||
fixStatus: 'ノードログを調査',
|
||||
fixStatus: '「systemctl status 1panel-agent.service」を実行して、サービスが起動しているか確認します。',
|
||||
checkAPI: 'ノードAPIの可用性を確認',
|
||||
fixAPI: 'ノードのログを確認し、ファイアウォールのポートが正常に開放されているか確認します。',
|
||||
forceDelete: '強制削除',
|
||||
|
||||
@@ -1697,6 +1697,9 @@ const message = {
|
||||
subscription: '구독',
|
||||
perpetual: '영구 라이선스',
|
||||
versionConstraint: '{0} 버전 일시불 구매',
|
||||
forceUnbind: '강제 바인딩 해제',
|
||||
forceUnbindHelper:
|
||||
'강제 바인딩 해제를 수행하면 해제 과정에서 발생하는 오류를 무시하고 궁극적으로 라이센스 바인딩을 해제합니다.',
|
||||
trialInfo: '버전',
|
||||
authorizationId: '구독 인증 ID',
|
||||
authorizedUser: '인증된 사용자',
|
||||
@@ -2973,7 +2976,7 @@ const message = {
|
||||
fixSSHConn: '노드를 수동으로 편집하여 연결 정보를 확인합니다',
|
||||
checkConnInfo: '에이전트 연결 정보 확인',
|
||||
checkStatus: '노드 서비스 가용성 확인',
|
||||
fixStatus: '노드 로그 조사',
|
||||
fixStatus: '"systemctl status 1panel-agent.service"를 실행하여 서비스가 실행 중인지 확인합니다.',
|
||||
checkAPI: '노드 API 가용성 확인',
|
||||
fixAPI: '노드 로그를 확인하고 방화벽 포트가 정상적으로 열려 있는지 확인합니다.',
|
||||
forceDelete: '강제 삭제',
|
||||
|
||||
@@ -1782,6 +1782,9 @@ const message = {
|
||||
subscription: 'Langganan',
|
||||
perpetual: 'Lesen Perpetual',
|
||||
versionConstraint: '{0} Pembelian versi',
|
||||
forceUnbind: 'Paksakan Nyahikat',
|
||||
forceUnbindHelper:
|
||||
'Memaksa nyahikat akan mengabaikan sebarang ralat yang berlaku semasa proses nyahikat dan akhirnya melepaskan ikatan lesen.',
|
||||
trialInfo: 'Versi',
|
||||
authorizationId: 'ID Kebenaran Langganan',
|
||||
authorizedUser: 'Pengguna yang Dibenarkan',
|
||||
@@ -3094,7 +3097,8 @@ const message = {
|
||||
fixSSHConn: 'Edit nod secara manual untuk mengesahkan maklumat sambungan',
|
||||
checkConnInfo: 'Periksa Maklumat Sambungan Ejen',
|
||||
checkStatus: 'Periksa Ketersediaan Perkhidmatan Nod',
|
||||
fixStatus: 'Siasat Log Nod',
|
||||
fixStatus:
|
||||
'Jalankan "systemctl status 1panel-agent.service" untuk memeriksa sama ada perkhidmatan sedang berjalan.',
|
||||
checkAPI: 'Periksa Ketersediaan API Nod',
|
||||
fixAPI: 'Semak log nod dan periksa sama ada port firewall dibuka dengan betul.',
|
||||
forceDelete: 'Hapus Secara Paksa',
|
||||
|
||||
@@ -1767,6 +1767,9 @@ const message = {
|
||||
subscription: 'Assinatura',
|
||||
perpetual: 'Licença Perpétua',
|
||||
versionConstraint: '{0} Compra do versão',
|
||||
forceUnbind: 'Forçar Desvinculação',
|
||||
forceUnbindHelper:
|
||||
'Forçar a desvinculação ignorará quaisquer erros que ocorram durante o processo de desvinculação e, em última análise, liberará a vinculação da licença.',
|
||||
trialInfo: 'Versão',
|
||||
authorizationId: 'ID de autorização',
|
||||
authorizedUser: 'Usuário autorizado',
|
||||
@@ -3097,7 +3100,7 @@ const message = {
|
||||
fixSSHConn: 'Edite o nó manualmente para confirmar as informações de conexão',
|
||||
checkConnInfo: 'Verificar Informações de Conexão do Agente',
|
||||
checkStatus: 'Verificar Disponibilidade do Serviço do Nó',
|
||||
fixStatus: 'Investigar Logs do Nó',
|
||||
fixStatus: 'Execute "systemctl status 1panel-agent.service" para verificar se o serviço está em execução.',
|
||||
checkAPI: 'Verificar Disponibilidade da API do Nó',
|
||||
fixAPI: 'Verifique os logs do nó e confirme se as portas do firewall estão devidamente abertas.',
|
||||
forceDelete: 'Excluir Forçadamente',
|
||||
|
||||
@@ -1767,6 +1767,9 @@ const message = {
|
||||
subscription: 'Подписка',
|
||||
perpetual: 'Пожизненная лицензия',
|
||||
versionConstraint: '{0} Выкуп версии',
|
||||
forceUnbind: 'Принудительное отвязывание',
|
||||
forceUnbindHelper:
|
||||
'Принудительное отвязывание будет игнорировать любые ошибки, возникающие в процессе отвязывания, и в конечном итоге освободит привязку лицензии.',
|
||||
trialInfo: 'Версия',
|
||||
authorizationId: 'ID авторизации подписки',
|
||||
authorizedUser: 'Авторизованный пользователь',
|
||||
@@ -3087,7 +3090,7 @@ const message = {
|
||||
fixSSHConn: 'Вручную отредактируйте узел, чтобы подтвердить информацию о подключении',
|
||||
checkConnInfo: 'Проверка информации о подключении агента',
|
||||
checkStatus: 'Проверка доступности службы узла',
|
||||
fixStatus: 'Проверка журналов узла',
|
||||
fixStatus: 'Запустите "systemctl status 1panel-agent.service", чтобы проверить, запущена ли служба.',
|
||||
checkAPI: 'Проверка доступности API узла',
|
||||
fixAPI: 'Проверьте журналы узла и убедитесь, что порты брандмауэра правильно открыты.',
|
||||
forceDelete: 'Принудительное удаление',
|
||||
|
||||
@@ -1727,8 +1727,8 @@ const message = {
|
||||
subscription: '訂閱',
|
||||
perpetual: '永久授權',
|
||||
versionConstraint: '{0} 版本買斷',
|
||||
forceDelete: '強制刪除,會忽略刪除過程中產生的錯誤並最終刪除元數據',
|
||||
deleteHelper: '刪除許可證可能導致子節點無法切換,請謹慎操作!',
|
||||
forceUnbind: '強制解除綁定',
|
||||
forceUnbindHelper: '強制解除綁定將忽略解除過程中產生的錯誤,最終解除許可證綁定。',
|
||||
trialInfo: '版本',
|
||||
authorizationId: '訂閱授權 ID',
|
||||
authorizedUser: '被授權方',
|
||||
@@ -2976,7 +2976,7 @@ const message = {
|
||||
fixSSHConn: '手動編輯節點,確認連接資訊',
|
||||
checkConnInfo: '檢查 Agent 連接資訊',
|
||||
checkStatus: '檢查節點服務可用性',
|
||||
fixStatus: '排查節點日誌',
|
||||
fixStatus: '執行 "systemctl status 1panel-agent.service" 以檢查服務是否已啟動。',
|
||||
checkAPI: '檢查節點 API 可用性',
|
||||
fixAPI: '檢查節點日誌,確認防火牆端口是否正常放行。',
|
||||
forceDelete: '強制刪除',
|
||||
|
||||
@@ -1719,8 +1719,8 @@ const message = {
|
||||
subscription: '订阅',
|
||||
perpetual: '永久授权',
|
||||
versionConstraint: '{0} 版本买断',
|
||||
forceDelete: '强制删除,会忽略删除过程中产生的错误并最终删除元数据',
|
||||
deleteHelper: '删除许可证可能导致子节点无法切换,请谨慎操作!',
|
||||
forceUnbind: '强制解绑',
|
||||
forceUnbindHelper: '强制解绑,会忽略解绑过程中产生的错误并最终解除许可证绑定',
|
||||
trialInfo: '版本',
|
||||
authorizationId: '订阅授权 ID',
|
||||
authorizedUser: '被授权方',
|
||||
@@ -2957,7 +2957,7 @@ const message = {
|
||||
fixSSHConn: '手动编辑节点,确认连接信息',
|
||||
checkConnInfo: '检查 Agent 连接信息',
|
||||
checkStatus: '检查节点服务可用性',
|
||||
fixStatus: '排查节点日志',
|
||||
fixStatus: 'systemctl status 1panel-agent.service 检查服务是否已启动',
|
||||
checkAPI: '检查节点 API 可用性',
|
||||
fixAPI: '排查节点日志,检查防火墙端口是否正常放行',
|
||||
forceDelete: '强制删除',
|
||||
|
||||
@@ -425,7 +425,7 @@
|
||||
</LayoutContent>
|
||||
<Command ref="commandRef" />
|
||||
<Confirm ref="confirmRef" @submit="submit" />
|
||||
<TaskLog ref="taskLogRef" width="70%" />
|
||||
<TaskLog ref="taskLogRef" width="70%" @close="goBack" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -462,7 +462,7 @@ const form = reactive<Container.ContainerHelper>({
|
||||
image: '',
|
||||
imageInput: false,
|
||||
forcePull: false,
|
||||
network: '',
|
||||
network: 'bridge',
|
||||
hostname: '',
|
||||
domainName: '',
|
||||
macAddr: '',
|
||||
|
||||
@@ -1,120 +1,126 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<CardWithHeader :header="$t('menu.container')" class="mt-5">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Container')">{{ countItem.containerCount }}</span>
|
||||
</template>
|
||||
<template #header-l>
|
||||
<el-tag size="small" class="ml-5" v-if="countItem.all" effect="plain">
|
||||
{{ $t('commons.table.all') }} * {{ countItem.all }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.running" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.running') }} * {{ countItem.running }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.created" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.created') }} * {{ countItem.created }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.paused" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.paused') }} * {{ countItem.paused }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.restarting" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.restarting') }} * {{ countItem.restarting }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.removing" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.removing') }} * {{ countItem.removing }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.exited" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.exited') }} * {{ countItem.exited }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.dead" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.dead') }} * {{ countItem.dead }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
<el-row :gutter="20" class="mt-5">
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.compose')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Compose')">{{ countItem.composeCount }}</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.composeTemplate')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('ComposeTemplate')">
|
||||
{{ countItem.composeTemplateCount }}
|
||||
</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.image')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Image')">{{ countItem.imageCount }}</span>
|
||||
</template>
|
||||
<template #header-l>
|
||||
<span v-if="countItem.imageSize" effect="plain" class="ml-2 text-xs">
|
||||
{{ $t('commons.status.used') }}: {{ computeSize(countItem.imageSize) }}
|
||||
</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20" class="mt-5">
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.imageRepo')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Repo')">{{ countItem.repoCount }}</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.network')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Network')">{{ countItem.networkCount }}</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.volume')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Volume')">{{ countItem.volumeCount }}</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<CardWithHeader :header="$t('container.setting')" class="mt-5">
|
||||
<template #body>
|
||||
<el-descriptions :column="1" border>
|
||||
<el-descriptions-item :label="$t('container.sockPath')">
|
||||
{{ countItem.sockPath }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('container.mirrors')">
|
||||
<div v-for="item in countItem.mirrors" :key="item" :value="item" :label="item">
|
||||
<div class="mt-1">
|
||||
<el-tag>{{ item }}</el-tag>
|
||||
<docker-status v-model:isActive="isActive" v-model:loading="loading" @search="search" />
|
||||
|
||||
<div :class="{ mask: !isActive }">
|
||||
<CardWithHeader :header="$t('menu.container')" class="mt-5">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Container')">{{ countItem.containerCount }}</span>
|
||||
</template>
|
||||
<template #header-l>
|
||||
<el-tag size="small" class="ml-5" v-if="countItem.all" effect="plain">
|
||||
{{ $t('commons.table.all') }} * {{ countItem.all }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.running" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.running') }} * {{ countItem.running }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.created" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.created') }} * {{ countItem.created }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.paused" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.paused') }} * {{ countItem.paused }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.restarting" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.restarting') }} * {{ countItem.restarting }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.removing" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.removing') }} * {{ countItem.removing }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.exited" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.exited') }} * {{ countItem.exited }}
|
||||
</el-tag>
|
||||
<el-tag size="small" v-if="countItem.dead" effect="plain" class="ml-2">
|
||||
{{ $t('commons.status.dead') }} * {{ countItem.dead }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
<el-row :gutter="20" class="mt-5">
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.compose')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Compose')">{{ countItem.composeCount }}</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.composeTemplate')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('ComposeTemplate')">
|
||||
{{ countItem.composeTemplateCount }}
|
||||
</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.image')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Image')">{{ countItem.imageCount }}</span>
|
||||
</template>
|
||||
<template #header-l>
|
||||
<span v-if="countItem.imageSize" effect="plain" class="ml-2 text-xs">
|
||||
{{ $t('commons.status.used') }}: {{ computeSize(countItem.imageSize) }}
|
||||
</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20" class="mt-5">
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.imageRepo')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Repo')">{{ countItem.repoCount }}</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.network')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Network')">{{ countItem.networkCount }}</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<CardWithHeader :header="$t('container.volume')">
|
||||
<template #body>
|
||||
<span class="count" @click="goRouter('Volume')">{{ countItem.volumeCount }}</span>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<CardWithHeader :header="$t('container.setting')" class="mt-5">
|
||||
<template #body>
|
||||
<el-descriptions :column="1" border>
|
||||
<el-descriptions-item :label="$t('container.sockPath')">
|
||||
{{ countItem.sockPath }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('container.mirrors')">
|
||||
<div v-for="item in countItem.mirrors" :key="item" :value="item" :label="item">
|
||||
<div class="mt-1">
|
||||
<el-tag>{{ item }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-button class="mt-2" type="primary" link @click="goRouter('ContainerSetting')">
|
||||
<el-icon class="mr-1"><Position /></el-icon>
|
||||
{{ $t('container.goSetting') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-button class="mt-2" type="primary" link @click="goRouter('ContainerSetting')">
|
||||
<el-icon class="mr-1"><Position /></el-icon>
|
||||
{{ $t('container.goSetting') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</CardWithHeader>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { loadContainerStatus, loadDaemonJson } from '@/api/modules/container';
|
||||
import DockerStatus from '@/views/container/docker-status/index.vue';
|
||||
import { getSettingInfo } from '@/api/modules/setting';
|
||||
import router from '@/routers';
|
||||
import { computeSize } from '@/utils/util';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
const loading = ref();
|
||||
const isActive = ref(false);
|
||||
const countItem = reactive({
|
||||
all: 0,
|
||||
created: 0,
|
||||
@@ -138,6 +144,14 @@ const countItem = reactive({
|
||||
sockPath: '',
|
||||
});
|
||||
|
||||
const search = () => {
|
||||
if (!isActive.value) {
|
||||
return;
|
||||
}
|
||||
loadContainerCount();
|
||||
loadContainerSetting();
|
||||
};
|
||||
|
||||
const loadContainerCount = async () => {
|
||||
await loadContainerStatus().then((res) => {
|
||||
countItem.all = res.data.all;
|
||||
@@ -173,8 +187,7 @@ const goRouter = async (val: string) => {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadContainerCount();
|
||||
loadContainerSetting();
|
||||
search();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ const loadStatus = async () => {
|
||||
await loadDockerStatus()
|
||||
.then((res) => {
|
||||
isActive.value = res.data === 'Running';
|
||||
em('update:loading', false);
|
||||
em('update:is-active', isActive.value);
|
||||
em('search');
|
||||
em('mounted');
|
||||
|
||||
@@ -90,9 +90,13 @@
|
||||
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="fileName" />
|
||||
<el-table-column :label="$t('app.source')" prop="backupType">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.source">
|
||||
{{ $t('setting.' + row.source) }}
|
||||
<span v-if="row.accountType === 'LOCAL'">
|
||||
{{ $t('setting.LOCAL') }}
|
||||
</span>
|
||||
<span v-if="row.accountType && row.accountType !== 'LOCAL'">
|
||||
{{ $t('setting.' + row.accountType) + ' - ' + row.accountName }}
|
||||
</span>
|
||||
<span v-if="!row.accountType">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('file.dir')" show-overflow-tooltip prop="fileDir" />
|
||||
@@ -205,7 +209,7 @@ const onBackup = async () => {
|
||||
};
|
||||
const onRecover = async () => {
|
||||
let param = {
|
||||
downloadAccountID: currentRow.value.source,
|
||||
downloadAccountID: currentRow.value.downloadAccountID,
|
||||
type: 'redis',
|
||||
name: database.value,
|
||||
detailName: '',
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
<template>
|
||||
<DialogPro v-model="open" :title="$t('commons.button.delete')" size="small">
|
||||
<el-form ref="deleteRef" v-loading="loading" @submit.prevent>
|
||||
<el-form-item>
|
||||
<el-alert :title="$t('license.deleteHelper')" :closable="false" type="warning" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="form.forceDelete" :label="$t('database.unBindForce')" />
|
||||
<span class="input-help">
|
||||
{{ $t('license.forceDelete') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="open = false" :disabled="loading">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="submit" :disabled="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</DialogPro>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { deleteLicense } from '@/api/modules/setting';
|
||||
|
||||
let form = reactive({
|
||||
id: 0,
|
||||
licenseName: '',
|
||||
forceDelete: false,
|
||||
});
|
||||
let open = ref(false);
|
||||
let loading = ref(false);
|
||||
|
||||
const deleteRef = ref<FormInstance>();
|
||||
|
||||
interface DialogProps {
|
||||
id: number;
|
||||
name: string;
|
||||
database: string;
|
||||
}
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const acceptParams = async (prop: DialogProps) => {
|
||||
form.id = prop.id;
|
||||
form.licenseName = prop.name;
|
||||
form.forceDelete = false;
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
loading.value = true;
|
||||
deleteLicense(form.id, form.forceDelete)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
open.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
@@ -83,8 +83,19 @@
|
||||
|
||||
<LicenseImport ref="licenseRef" />
|
||||
<LicenseBind ref="bindRef" />
|
||||
<LicenseDelete ref="delRef" @search="search" />
|
||||
<OpDialog ref="opRef" @search="search" />
|
||||
<OpDialog ref="opRef2" @search="search" @submit="submitUnbind">
|
||||
<template #content>
|
||||
<el-form class="mt-4 mb-1" ref="deleteForm" label-position="left">
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="forceUnbind" :label="$t('license.forceUnbind')" />
|
||||
<span class="input-help">
|
||||
{{ $t('license.forceUnbindHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</OpDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -92,7 +103,6 @@
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { deleteLicense, searchLicense, syncLicense, unbindLicense } from '@/api/modules/setting';
|
||||
import LicenseImport from '@/components/license-import/index.vue';
|
||||
import LicenseDelete from '@/views/setting/license/delete/index.vue';
|
||||
import LicenseBind from '@/views/setting/license/bind/index.vue';
|
||||
import { dateFormat } from '@/utils/util';
|
||||
import i18n from '@/lang';
|
||||
@@ -103,9 +113,11 @@ import { initFavicon } from '@/utils/xpack';
|
||||
const globalStore = GlobalStore();
|
||||
const loading = ref();
|
||||
const licenseRef = ref();
|
||||
const delRef = ref();
|
||||
const bindRef = ref();
|
||||
const opRef = ref();
|
||||
const opRef2 = ref();
|
||||
const forceUnbind = ref();
|
||||
const unbindRow = ref();
|
||||
|
||||
const data = ref();
|
||||
const paginationConfig = reactive({
|
||||
@@ -141,29 +153,33 @@ const onSync = async (row: any) => {
|
||||
};
|
||||
|
||||
const onUnbind = async (row: any) => {
|
||||
ElMessageBox.confirm(i18n.global.t('license.unbindHelper'), i18n.global.t('commons.button.unbind'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
type: 'info',
|
||||
}).then(async () => {
|
||||
loading.value = true;
|
||||
await unbindLicense(row.id)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
if (row.freeCount !== 0) {
|
||||
globalStore.isProductPro = false;
|
||||
initFavicon();
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
search();
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
unbindRow.value = row;
|
||||
opRef2.value.acceptParams({
|
||||
title: i18n.global.t('commons.button.unbind'),
|
||||
names: [row.licenseName],
|
||||
msg: i18n.global.t('license.unbindHelper'),
|
||||
api: null,
|
||||
params: null,
|
||||
});
|
||||
};
|
||||
const submitUnbind = async () => {
|
||||
loading.value = true;
|
||||
await unbindLicense(unbindRow.value.id)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
if (unbindRow.value.freeCount !== 0) {
|
||||
globalStore.isMasterProductPro = false;
|
||||
initFavicon();
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
search();
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
loading.value = true;
|
||||
|
||||
Reference in New Issue
Block a user