feat: Unified runtime environment status (#7978)

This commit is contained in:
zhengkunwang 2025-02-24 17:20:07 +08:00 committed by GitHub
parent ff32281257
commit e6c1094c08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 222 additions and 234 deletions

View file

@ -8,26 +8,27 @@ import (
)
type RuntimeDTO struct {
ID uint `json:"id"`
Name string `json:"name"`
Resource string `json:"resource"`
AppDetailID uint `json:"appDetailID"`
AppID uint `json:"appID"`
Source string `json:"source"`
Status string `json:"status"`
Type string `json:"type"`
Image string `json:"image"`
Params map[string]interface{} `json:"params"`
Message string `json:"message"`
Version string `json:"version"`
CreatedAt time.Time `json:"createdAt"`
CodeDir string `json:"codeDir"`
AppParams []AppParam `json:"appParams"`
Port string `json:"port"`
Path string `json:"path"`
ExposedPorts []request.ExposedPort `json:"exposedPorts"`
Environments []request.Environment `json:"environments"`
Volumes []request.Volume `json:"volumes"`
ID uint `json:"id"`
Name string `json:"name"`
Resource string `json:"resource"`
AppDetailID uint `json:"appDetailID"`
AppID uint `json:"appID"`
Source string `json:"source"`
Status string `json:"status"`
Type string `json:"type"`
Image string `json:"image"`
Params map[string]interface{} `json:"params"`
Message string `json:"message"`
Version string `json:"version"`
CreatedAt time.Time `json:"createdAt"`
CodeDir string `json:"codeDir"`
AppParams []AppParam `json:"appParams"`
Port string `json:"port"`
Path string `json:"path"`
ExposedPorts []request.ExposedPort `json:"exposedPorts"`
Environments []request.Environment `json:"environments"`
Volumes []request.Volume `json:"volumes"`
ContainerStatus string `json:"containerStatus"`
}
type PackageScripts struct {

View file

@ -119,7 +119,7 @@ func handleRuntimeRecover(runtime *model.Runtime, recoverFile string, isRollback
}
oldRuntime.ID = runtime.ID
oldRuntime.Status = constant.RuntimeStarting
oldRuntime.Status = constant.StatusStarting
if err := runtimeRepo.Save(&oldRuntime); err != nil {
global.LOG.Errorf("save db app install failed, err: %v", err)
return err

View file

@ -102,7 +102,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
Resource: create.Resource,
Type: create.Type,
Version: create.Version,
Status: constant.RuntimeNormal,
Status: constant.StatusNormal,
}
return nil, runtimeRepo.Create(context.Background(), runtime)
}
@ -196,14 +196,17 @@ func (r *RuntimeService) Page(req request.RuntimeSearch) (int64, []response.Runt
if err != nil {
return 0, nil, err
}
if err = SyncRuntimesStatus(runtimes); err != nil {
return 0, nil, err
}
for _, runtime := range runtimes {
runtimeDTO := response.NewRuntimeDTO(runtime)
runtimeDTO.Params = make(map[string]interface{})
envs, err := gotenv.Unmarshal(runtime.Env)
envMap, err := gotenv.Unmarshal(runtime.Env)
if err != nil {
return 0, nil, err
}
for k, v := range envs {
for k, v := range envMap {
runtimeDTO.Params[k] = v
}
res = append(res, runtimeDTO)
@ -498,7 +501,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
switch runtime.Type {
case constant.RuntimePHP:
runtime.Image = req.Image
runtime.Status = constant.RuntimeBuildIng
runtime.Status = constant.StatusBuilding
_ = runtimeRepo.Save(runtime)
client, err := docker.NewClient()
if err != nil {
@ -514,7 +517,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
runtime.Version = req.Version
runtime.CodeDir = req.CodeDir
runtime.Port = strings.Join(hostPorts, ",")
runtime.Status = constant.RuntimeReCreating
runtime.Status = constant.StatusReCreating
_ = runtimeRepo.Save(runtime)
go reCreateRuntime(runtime)
}
@ -559,7 +562,7 @@ func (r *RuntimeService) OperateRuntime(req request.RuntimeOperate) error {
}
defer func() {
if err != nil {
runtime.Status = constant.RuntimeError
runtime.Status = constant.StatusError
runtime.Message = err.Error()
_ = runtimeRepo.Save(runtime)
}
@ -576,7 +579,7 @@ func (r *RuntimeService) OperateRuntime(req request.RuntimeOperate) error {
if err = runComposeCmdWithLog(req.Operate, runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
return err
}
runtime.Status = constant.RuntimeStopped
runtime.Status = constant.StatusStopped
case constant.RuntimeRestart:
if err = restartRuntime(runtime); err != nil {
return err
@ -661,7 +664,7 @@ func (r *RuntimeService) SyncForRestart() error {
return err
}
for _, runtime := range runtimes {
if runtime.Status == constant.RuntimeBuildIng || runtime.Status == constant.RuntimeReCreating || runtime.Status == constant.RuntimeStarting || runtime.Status == constant.RuntimeCreating {
if runtime.Status == constant.StatusBuilding || runtime.Status == constant.StatusReCreating || runtime.Status == constant.StatusStarting || runtime.Status == constant.StatusCreating {
runtime.Status = constant.SystemRestart
runtime.Message = "System restart causing interrupt"
_ = runtimeRepo.Save(&runtime)

View file

@ -55,7 +55,7 @@ func handleRuntime(create request.RuntimeCreate, runtime *model.Runtime, fileOp
}
runtime.DockerCompose = string(composeContent)
runtime.Env = string(envContent)
runtime.Status = constant.RuntimeCreating
runtime.Status = constant.StatusCreating
runtime.CodeDir = create.CodeDir
nodeDetail, err := appDetailRepo.GetFirst(repo.WithByID(runtime.AppDetailID))
@ -89,7 +89,7 @@ func handlePHP(create request.RuntimeCreate, runtime *model.Runtime, fileOp file
runtime.DockerCompose = string(composeContent)
runtime.Env = string(envContent)
runtime.Params = string(forms)
runtime.Status = constant.RuntimeBuildIng
runtime.Status = constant.StatusBuilding
go buildRuntime(runtime, "", "", false)
return
@ -97,14 +97,14 @@ func handlePHP(create request.RuntimeCreate, runtime *model.Runtime, fileOp file
func startRuntime(runtime *model.Runtime) {
if err := runComposeCmdWithLog("up", runtime.GetComposePath(), runtime.GetLogPath()); err != nil {
runtime.Status = constant.RuntimeError
runtime.Status = constant.StatusError
runtime.Message = err.Error()
_ = runtimeRepo.Save(runtime)
return
}
if err := SyncRuntimeContainerStatus(runtime); err != nil {
runtime.Status = constant.RuntimeError
runtime.Status = constant.StatusError
runtime.Message = err.Error()
_ = runtimeRepo.Save(runtime)
return
@ -115,7 +115,7 @@ func reCreateRuntime(runtime *model.Runtime) {
var err error
defer func() {
if err != nil {
runtime.Status = constant.RuntimeError
runtime.Status = constant.StatusError
runtime.Message = err.Error()
_ = runtimeRepo.Save(runtime)
}
@ -155,6 +155,45 @@ func runComposeCmdWithLog(operate string, composePath string, logPath string) er
return nil
}
func SyncRuntimesStatus(runtimes []model.Runtime) error {
cli, err := docker.NewClient()
if err != nil {
return err
}
defer cli.Close()
var containerNames []string
runtimeContainer := make(map[string]int)
for index, runtime := range runtimes {
containerNames = append(containerNames, runtime.ContainerName)
runtimeContainer["/"+runtime.ContainerName] = index
}
containers, err := cli.ListContainersByName(containerNames)
if err != nil {
return err
}
for _, contain := range containers {
if index, ok := runtimeContainer[contain.Names[0]]; ok {
switch contain.State {
case "exited":
runtimes[index].Status = constant.StatusError
case "running":
runtimes[index].Status = constant.StatusRunning
case "paused":
runtimes[index].Status = constant.StatusStopped
case "restarting":
runtimes[index].Status = constant.StatusRestarting
}
delete(runtimeContainer, contain.Names[0])
}
}
for _, index := range runtimeContainer {
if runtimes[index].Status != constant.StatusBuilding {
runtimes[index].Status = constant.StatusStopped
}
}
return nil
}
func SyncRuntimeContainerStatus(runtime *model.Runtime) error {
env, err := gotenv.Unmarshal(runtime.Env)
if err != nil {
@ -182,14 +221,14 @@ func SyncRuntimeContainerStatus(runtime *model.Runtime) error {
switch container.State {
case "exited":
runtime.Status = constant.RuntimeError
runtime.Status = constant.StatusError
case "running":
runtime.Status = constant.RuntimeRunning
runtime.Status = constant.StatusRunning
case "paused":
runtime.Status = constant.RuntimeStopped
runtime.Status = constant.StatusStopped
default:
if runtime.Status != constant.RuntimeBuildIng {
runtime.Status = constant.RuntimeStopped
if runtime.Status != constant.StatusBuilding {
runtime.Status = constant.StatusStopped
}
}
@ -232,7 +271,7 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
err = cmd.Run()
if err != nil {
runtime.Status = constant.RuntimeError
runtime.Status = constant.StatusError
runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + stderrBuf.String()
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + buserr.New("ErrCmdTimeout").Error()
@ -286,7 +325,7 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
}
if out, err := compose.Up(composePath); err != nil {
runtime.Status = constant.RuntimeStartErr
runtime.Status = constant.StatusStartErr
runtime.Message = out
} else {
extensions := getRuntimeEnv(runtime.Env, "PHP_EXTENSIONS")
@ -294,13 +333,13 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
installCmd := fmt.Sprintf("docker exec -i %s %s %s", runtime.ContainerName, "install-ext", extensions)
err = cmd2.ExecWithLogFile(installCmd, 60*time.Minute, logPath)
if err != nil {
runtime.Status = constant.RuntimeError
runtime.Status = constant.StatusError
runtime.Message = buserr.New("ErrImageBuildErr").Error() + ":" + err.Error()
_ = runtimeRepo.Save(runtime)
return
}
}
runtime.Status = constant.RuntimeRunning
runtime.Status = constant.StatusRunning
}
}
_ = runtimeRepo.Save(runtime)

View file

@ -4,17 +4,6 @@ const (
ResourceLocal = "local"
ResourceAppstore = "appstore"
RuntimeNormal = "normal"
RuntimeError = "error"
RuntimeBuildIng = "building"
RuntimeStarting = "starting"
RuntimeRunning = "running"
RuntimeReCreating = "recreating"
RuntimeStopped = "stopped"
RuntimeUnhealthy = "unhealthy"
RuntimeCreating = "creating"
RuntimeStartErr = "startErr"
RuntimePHP = "php"
RuntimeNode = "node"
RuntimeJava = "java"

View file

@ -1,17 +1,26 @@
package constant
const (
StatusRunning = "Running"
StatusDone = "Done"
StatusWaiting = "Waiting"
StatusSuccess = "Success"
StatusFailed = "Failed"
StatusUploading = "Uploading"
StatusEnable = "Enable"
StatusDisable = "Disable"
StatusNone = "None"
StatusDeleted = "Deleted"
StatusExecuting = "Executing"
StatusRunning = "Running"
StatusDone = "Done"
StatusWaiting = "Waiting"
StatusSuccess = "Success"
StatusFailed = "Failed"
StatusUploading = "Uploading"
StatusEnable = "Enable"
StatusDisable = "Disable"
StatusNone = "None"
StatusDeleted = "Deleted"
StatusExecuting = "Executing"
StatusBuilding = "Building"
StatusReCreating = "Recreating"
StatusStopped = "Stopped"
StatusCreating = "Creating"
StatusStartErr = "StartErr"
StatusNormal = "Normal"
StatusError = "Error"
StatusStarting = "Starting"
StatusRestarting = "ReStarting"
OrderDesc = "descending"
OrderAsc = "ascending"

View file

@ -1,9 +1,9 @@
@font-face {
font-family: "iconfont"; /* Project id 4776196 */
src: url('iconfont.woff2?t=1739873339591') format('woff2'),
url('iconfont.woff?t=1739873339591') format('woff'),
url('iconfont.ttf?t=1739873339591') format('truetype'),
url('iconfont.svg?t=1739873339591#iconfont') format('svg');
src: url('iconfont.woff2?t=1740384606757') format('woff2'),
url('iconfont.woff?t=1740384606757') format('woff'),
url('iconfont.ttf?t=1740384606757') format('truetype'),
url('iconfont.svg?t=1740384606757#iconfont') format('svg');
}
.iconfont {

View file

@ -16,10 +16,10 @@
@click="onOperate('start')"
:disabled="data.status === 'Installing'"
>
{{ $t('app.start') }}
{{ $t('commons.operate.start') }}
</el-button>
<el-button type="primary" v-if="data.status === 'Running'" link @click="onOperate('stop')">
{{ $t('app.stop') }}
{{ $t('commons.operate.stop') }}
</el-button>
<el-divider direction="vertical" />
<el-button
@ -28,7 +28,7 @@
:disabled="data.status === 'Installing'"
@click="onOperate('restart')"
>
{{ $t('commons.button.restart') }}
{{ $t('commons.operate.restart') }}
</el-button>
<el-divider direction="vertical" />
<el-button
@ -38,7 +38,7 @@
@click="onOperate('reload')"
:disabled="data.status !== 'Running'"
>
{{ $t('app.reload') }}
{{ $t('commons.operate.reload') }}
</el-button>
<el-divider v-if="data.app === 'OpenResty'" direction="vertical" />
<el-button
@ -136,8 +136,8 @@ const onCheck = async (key: any, name: any) => {
const onOperate = async (operation: string) => {
operateReq.operate = operation;
ElMessageBox.confirm(
i18n.global.t('app.operatorHelper', [i18n.global.t('app.' + operation)]),
i18n.global.t('app.' + operation),
i18n.global.t('app.operatorHelper', [i18n.global.t('commons.operate.' + operation)]),
i18n.global.t('commons.operate.' + operation),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -294,7 +294,7 @@ const message = {
executing: 'Executing',
installerr: 'Installation failed',
applyerror: 'Apply failed',
interrupt: 'Interrupted',
systemrestart: 'Interrupted',
},
units: {
second: 'Second',
@ -1871,9 +1871,6 @@ const message = {
author: 'Author',
source: 'Source',
appName: 'Application Name',
start: 'Start',
stop: 'Stop',
rebuild: 'Rebuild',
deleteWarn:
'The delete operation will delete all data and backups together. This operation cannot be rolled back. Do you want to continue? ',
syncSuccess: 'Sync successfully',

View file

@ -288,7 +288,7 @@ const message = {
executing: '実行中',
installerr: 'インストールに失敗しました',
applyerror: '適用に失敗しました',
interrupt: '中断',
systemrestart: '中断',
},
units: {
second: '2番目|2番目|',
@ -1729,9 +1729,6 @@ const message = {
author: '著者',
source: 'ソース',
appName: 'アプリケーション名',
start: '始める',
stop: '停止',
rebuild: '再構築します',
deleteWarn:
'削除操作はすべてのデータとバックアップを一緒に削除しますこの操作はロールバックすることはできません続けたいですか',
syncSuccess: '正常に同期しました',

View file

@ -289,7 +289,7 @@ const message = {
executing: '실행 ',
installerr: '설치 실패',
applyerror: '적용 실패',
interrupt: '중단됨',
systemrestart: '중단됨',
},
units: {
second: ' | | ',
@ -1699,9 +1699,6 @@ const message = {
author: '저자',
source: '출처',
appName: '애플리케이션 이름',
start: '시작',
stop: '중지',
rebuild: '재빌드',
deleteWarn:
'삭제 작업은 모든 데이터와 백업을 함께 삭제합니다. 작업은 되돌릴 없습니다. 계속 하시겠습니까?',
syncSuccess: '동기화 성공',

View file

@ -295,7 +295,7 @@ const message = {
executing: 'Melaksanakan',
installerr: 'Pemasangan gagal',
applyerror: 'Permohonan gagal',
interrupt: 'Dihentikan',
systemrestart: 'Dihentikan',
},
units: {
second: 'saat | saat | saat',
@ -1786,9 +1786,6 @@ const message = {
author: 'Pengarang',
source: 'Sumber',
appName: 'Nama Aplikasi',
start: 'Mula',
stop: 'Henti',
rebuild: 'Bina Semula',
deleteWarn:
'Operasi memadam akan memadam semua data dan sandaran bersama. Operasi ini tidak boleh dipulihkan. Adakah anda mahu meneruskan?',
syncSuccess: 'Disegerakkan dengan berjaya',

View file

@ -293,7 +293,7 @@ const message = {
executing: 'Executando',
installerr: 'Falha na instalação',
applyerror: 'Falha na aplicação',
interrupt: 'Interrompido',
systemrestart: 'Interrompido',
},
units: {
second: 'segundo | segundos | segundos',
@ -1773,9 +1773,6 @@ const message = {
author: 'Autor',
source: 'Fonte',
appName: 'Nome do Aplicativo',
start: 'Iniciar',
stop: 'Parar',
rebuild: 'Reconstruir',
deleteWarn:
'A operação de exclusão excluirá todos os dados e backups juntos. Esta operação não pode ser desfeita. Deseja continuar?',
syncSuccess: 'Sincronizado com sucesso',

View file

@ -289,7 +289,7 @@ const message = {
executing: 'Выполнение',
installerr: 'Ошибка установки',
applyerror: 'Ошибка применения',
interrupt: 'Прервано',
systemrestart: 'Прервано',
},
units: {
second: ' секунда | секунда | секунд',
@ -1769,9 +1769,6 @@ const message = {
author: 'Автор',
source: 'Источник',
appName: 'Название приложения',
start: 'Запустить',
stop: 'Остановить',
rebuild: 'Пересобрать',
deleteWarn:
'Операция удаления удалит все данные и резервные копии. Эту операцию нельзя отменить. Хотите продолжить?',
syncSuccess: 'Синхронизация выполнена успешно',

View file

@ -288,7 +288,7 @@ const message = {
executing: '執行中',
installerr: '安裝失敗',
applyerror: '申請失敗',
interrupt: '中斷',
systemrestart: '中斷',
},
units: {
second: '秒',
@ -1756,9 +1756,6 @@ const message = {
author: '作者',
source: '來源',
appName: '應用名稱',
start: '啟動',
stop: '停止',
rebuild: '重建',
deleteWarn: '刪除操作會把所有數據和備份一並刪除此操作不可回滾是否繼續',
syncSuccess: '同步成功',
canUpgrade: '可升級',

View file

@ -76,6 +76,14 @@ const message = {
down: '停止',
up: '启动',
},
operate: {
start: '启动',
stop: '停止',
restart: '重启',
reload: '重载',
rebuild: '重建',
sync: '同步',
},
search: {
timeStart: '开始时间',
timeEnd: '结束时间',
@ -286,7 +294,7 @@ const message = {
executing: '执行中',
installerr: '安装失败',
applyerror: '申请失败',
interrupt: '中断',
systemrestart: '中断',
},
units: {
second: '秒',
@ -1723,9 +1731,6 @@ const message = {
author: '作者',
source: '来源',
appName: '应用名称',
start: '启动',
stop: '停止',
rebuild: '重建',
deleteWarn: '删除操作会把所有数据和备份一并删除此操作不可回滚是否继续',
syncSuccess: '同步成功',
canUpgrade: '可升级',

View file

@ -539,8 +539,8 @@ const operate = async () => {
const onOperate = async (operation: string) => {
ElMessageBox.confirm(
i18n.global.t('app.operatorHelper', [i18n.global.t('app.' + operation)]),
i18n.global.t('app.' + operation),
i18n.global.t('app.operatorHelper', [i18n.global.t('commons.operate.' + operation)]),
i18n.global.t('commons.operate.' + operation),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
@ -553,7 +553,7 @@ const onOperate = async (operation: string) => {
const buttons = [
{
label: i18n.global.t('commons.button.sync'),
label: i18n.global.t('commons.operate.sync'),
click: (row: any) => {
openOperate(row, 'sync');
},
@ -567,7 +567,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.rebuild'),
label: i18n.global.t('commons.operate.rebuild'),
click: (row: any) => {
openOperate(row, 'rebuild');
},
@ -581,7 +581,7 @@ const buttons = [
},
},
{
label: i18n.global.t('commons.button.restart'),
label: i18n.global.t('commons.operate.restart'),
click: (row: any) => {
openOperate(row, 'restart');
},
@ -595,7 +595,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.start'),
label: i18n.global.t('commons.operate.start'),
click: (row: any) => {
openOperate(row, 'start');
},
@ -611,7 +611,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.stop'),
label: i18n.global.t('commons.operate.stop'),
click: (row: any) => {
openOperate(row, 'stop');
},

View file

@ -0,0 +1,27 @@
<template>
<el-popover v-if="showMessage" placement="bottom" :width="400" trigger="hover" :content="row.message">
<template #reference>
<Status :key="row.status" :status="row.status" />
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status" />
</div>
</template>
<script setup>
import { defineProps, computed } from 'vue';
import Status from '@/components/status/index.vue';
const props = defineProps({
row: {
type: Object,
required: true,
},
});
const showMessage = computed(() => {
return props.row.status === 'Error' || props.row.status === 'SystemRestart';
});
</script>

View file

@ -53,25 +53,15 @@
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }">
<el-popover
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
<RuntimeStatus :row="row" />
</template>
</el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button>
<el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column
@ -107,7 +97,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util';
import OperateDonet from '@/views/website/runtime/dotnet/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang';
import RouterMenu from '../index.vue';
@ -118,6 +107,7 @@ import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus';
import { GlobalStore } from '@/store';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null;
const loading = ref(false);
@ -147,7 +137,7 @@ const req = reactive<Runtime.RuntimeReq>({
});
const buttons = [
{
label: i18n.global.t('app.stop'),
label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id);
},
@ -156,7 +146,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.start'),
label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id);
},
@ -165,7 +155,7 @@ const buttons = [
},
},
{
label: i18n.global.t('commons.button.restart'),
label: i18n.global.t('commons.operate.restart'),
click: function (row: Runtime.Runtime) {
operateRuntime('restart', row.id);
},
@ -238,8 +228,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => {
try {
const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]),
i18n.global.t('commons.button.' + operate),
i18n.global.t('runtime.operatorHelper', [i18n.global.t('ommons.operate.' + operate)]),
i18n.global.t('ommons.operate.' + operate),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -53,26 +53,15 @@
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }">
<el-popover
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
popper-class="max-h-[300px] overflow-auto"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
<RuntimeStatus :row="row" />
</template>
</el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button>
<el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column
@ -108,7 +97,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util';
import Operate from '@/views/website/runtime/go/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang';
import RouterMenu from '../index.vue';
@ -118,6 +106,7 @@ import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null;
const loading = ref(false);
@ -142,7 +131,7 @@ const req = reactive<Runtime.RuntimeReq>({
});
const buttons = [
{
label: i18n.global.t('app.stop'),
label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id);
},
@ -151,7 +140,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.start'),
label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id);
},
@ -233,8 +222,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => {
try {
const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]),
i18n.global.t('commons.button.' + operate),
i18n.global.t('runtime.operatorHelper', [i18n.global.t('ommons.operate.' + operate)]),
i18n.global.t('ommons.operate.' + operate),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -53,25 +53,15 @@
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }">
<el-popover
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
<RuntimeStatus :row="row" />
</template>
</el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button>
<el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column
@ -107,7 +97,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util';
import OperateJava from '@/views/website/runtime/java/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang';
import RouterMenu from '../index.vue';
@ -117,6 +106,7 @@ import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null;
const loading = ref(false);
@ -141,7 +131,7 @@ const req = reactive<Runtime.RuntimeReq>({
});
const buttons = [
{
label: i18n.global.t('app.stop'),
label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id);
},
@ -150,7 +140,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.start'),
label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id);
},
@ -232,8 +222,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => {
try {
const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]),
i18n.global.t('commons.button.' + operate),
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.operate' + operate)]),
i18n.global.t('commons.operate.' + operate),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -53,25 +53,15 @@
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }">
<el-popover
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
<RuntimeStatus :row="row" />
</template>
</el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button>
<el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column
@ -108,7 +98,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util';
import OperateNode from '@/views/website/runtime/node/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang';
import RouterMenu from '../index.vue';
@ -119,6 +108,7 @@ import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null;
const loading = ref(false);
@ -153,7 +143,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.stop'),
label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id);
},
@ -162,7 +152,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.start'),
label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id);
},
@ -248,8 +238,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => {
try {
const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]),
i18n.global.t('commons.button.' + operate),
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.operate.' + operate)]),
i18n.global.t('commons.operate.' + operate),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),

View file

@ -66,20 +66,7 @@
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }">
<el-popover
v-if="row.status === 'error' || row.status === 'systemRestart'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
<RuntimeStatus :row="row" />
</template>
</el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="">
@ -134,12 +121,12 @@ import ExtManagement from './extension-management/index.vue';
import Extensions from './extension-template/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue';
import CreateRuntime from '@/views/website/runtime/php/create/index.vue';
import Status from '@/components/status/index.vue';
import RouterMenu from '../index.vue';
import Log from '@/components/log-dialog/index.vue';
import ComposeLogs from '@/components/compose-log/index.vue';
import Config from '@/views/website/runtime/php/config/index.vue';
import Supervisor from '@/views/website/runtime/php/supervisor/index.vue';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
const paginationConfig = reactive({
cacheSizeKey: 'runtime-page-size',
@ -177,7 +164,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.stop'),
label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id);
},
@ -186,7 +173,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.start'),
label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id);
},
@ -277,7 +264,7 @@ const openSupervisor = (row: Runtime.Runtime) => {
};
const openLog = (row: Runtime.RuntimeDTO) => {
if (row.status == 'running') {
if (row.status == 'Running') {
composeLogRef.value.acceptParams({ compose: row.path + '/docker-compose.yml', resource: row.name });
} else {
logRef.value.acceptParams({ id: row.id, type: 'php', tail: row.status == 'building', heightDiff: 220 });

View file

@ -53,25 +53,15 @@
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }">
<el-popover
v-if="row.status === 'error'"
placement="bottom"
:width="400"
trigger="hover"
:content="row.message"
>
<template #reference>
<Status :key="row.status" :status="row.status"></Status>
</template>
</el-popover>
<div v-else>
<Status :key="row.status" :status="row.status"></Status>
</div>
<RuntimeStatus :row="row" />
</template>
</el-table-column>
<el-table-column :label="$t('commons.button.log')" prop="path" min-width="90px">
<template #default="{ row }">
<el-button @click="openLog(row)" link type="primary">{{ $t('website.check') }}</el-button>
<el-button @click="openLog(row)" link type="primary" v-if="row.status != 'Stopped'">
{{ $t('website.check') }}
</el-button>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column
@ -107,7 +97,6 @@ import { Runtime } from '@/api/interface/runtime';
import { OperateRuntime, RuntimeDeleteCheck, SearchRuntimes, SyncRuntime } from '@/api/modules/runtime';
import { dateFormat } from '@/utils/util';
import Operate from '@/views/website/runtime/python/operate/index.vue';
import Status from '@/components/status/index.vue';
import Delete from '@/views/website/runtime/delete/index.vue';
import i18n from '@/lang';
import RouterMenu from '../index.vue';
@ -117,6 +106,7 @@ import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus';
import RuntimeStatus from '@/views/website/runtime/components/runtime-status.vue';
let timer: NodeJS.Timer | null = null;
const loading = ref(false);
@ -141,7 +131,7 @@ const req = reactive<Runtime.RuntimeReq>({
});
const buttons = [
{
label: i18n.global.t('app.stop'),
label: i18n.global.t('commons.operate.stop'),
click: function (row: Runtime.Runtime) {
operateRuntime('down', row.id);
},
@ -150,7 +140,7 @@ const buttons = [
},
},
{
label: i18n.global.t('app.start'),
label: i18n.global.t('commons.operate.start'),
click: function (row: Runtime.Runtime) {
operateRuntime('up', row.id);
},
@ -232,8 +222,8 @@ const goDashboard = async (port: any, protocol: string) => {
const operateRuntime = async (operate: string, ID: number) => {
try {
const action = await ElMessageBox.confirm(
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.button.' + operate)]),
i18n.global.t('commons.button.' + operate),
i18n.global.t('runtime.operatorHelper', [i18n.global.t('commons.operate.' + operate)]),
i18n.global.t('commons.operate.' + operate),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),