Commit 75221ace authored by 王曜嵚 Wang Yaoqin's avatar 王曜嵚 Wang Yaoqin

dev: 调试接口

parent 24900cd7
......@@ -10,7 +10,10 @@
<span title="分支" class="secondary branch">分支:{{ info?.branch }}</span>
<span title="目录" class="secondary">目录:/var/logwire-platform</span>
</div>
<div class="row" style="margin-top: 50px;">
<div v-if="tip" class="row" style="color: #ffa15b;word-break: break-all;">
<span>Tip: {{ tip }}</span>
</div>
<div class="row" style="position: absolute;bottom: 0px;">
<div class="extra-operation" @click="navigateTo('/git')">
<svg t="1714466723924" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13200" width="200" height="200"><path d="M738.986667 868.693333c0 47.786667 37.546667 85.333333 85.333333 85.333334s85.333333-37.546667 85.333333-85.333334-37.546667-85.333333-85.333333-85.333333-85.333333 39.253333-85.333333 85.333333z" p-id="13201"></path><path d="M824.32 979.626667c-61.44 0-110.933333-49.493333-110.933333-110.933334s49.493333-110.933333 110.933333-110.933333 110.933333 49.493333 110.933333 110.933333-49.493333 110.933333-110.933333 110.933334z m0-170.666667c-32.426667 0-59.733333 27.306667-59.733333 59.733333s27.306667 59.733333 59.733333 59.733334 59.733333-27.306667 59.733333-59.733334-27.306667-59.733333-59.733333-59.733333z" p-id="13202"></path><path d="M269.653333 868.693333c0 47.786667 37.546667 85.333333 85.333334 85.333334s85.333333-37.546667 85.333333-85.333334-37.546667-85.333333-85.333333-85.333333-85.333333 39.253333-85.333334 85.333333z" p-id="13203"></path><path d="M354.986667 979.626667c-61.44 0-110.933333-49.493333-110.933334-110.933334s49.493333-110.933333 110.933334-110.933333 110.933333 49.493333 110.933333 110.933333-49.493333 110.933333-110.933333 110.933334z m0-170.666667c-32.426667 0-59.733333 27.306667-59.733334 59.733333s27.306667 59.733333 59.733334 59.733334 59.733333-27.306667 59.733333-59.733334-27.306667-59.733333-59.733333-59.733333z" p-id="13204"></path><path d="M269.653333 186.026667c0 47.786667 37.546667 85.333333 85.333334 85.333333s85.333333-37.546667 85.333333-85.333333-37.546667-85.333333-85.333333-85.333334-85.333333 39.253333-85.333334 85.333334z" p-id="13205"></path><path d="M354.986667 296.96c-61.44 0-110.933333-49.493333-110.933334-110.933333s49.493333-110.933333 110.933334-110.933334 110.933333 49.493333 110.933333 110.933334-49.493333 110.933333-110.933333 110.933333z m0-170.666667c-32.426667 0-59.733333 27.306667-59.733334 59.733334s27.306667 59.733333 59.733334 59.733333 59.733333-27.306667 59.733333-59.733333-27.306667-59.733333-59.733333-59.733334z" p-id="13206"></path><path d="M824.32 808.96c-13.653333 0-25.6-11.946667-25.6-25.6v-85.333333c0-68.266667-110.933333-114.346667-218.453333-157.013334-75.093333-30.72-150.186667-61.44-199.68-104.106666V785.066667c0 13.653333-11.946667 25.6-25.6 25.6s-25.6-11.946667-25.6-25.6V273.066667c0-13.653333 11.946667-25.6 25.6-25.6s25.6 11.946667 25.6 25.6v63.146666c0 68.266667 110.933333 114.346667 218.453333 157.013334 122.88 51.2 250.88 102.4 250.88 204.8v85.333333c0 13.653333-11.946667 25.6-25.6 25.6z" p-id="13207"></path></svg>
切换分支
......@@ -52,21 +55,31 @@
import { Socket, io } from 'socket.io-client';
import { useUserStore } from '~/store/user';
let { pending, data: info } = useLazyFetch('/api/devops/v1/getProjectInfo')
let tip = ref('')
let { pending, data: info, execute } = useLazyFetch('/api/devops/v1/getProjectInfo')
watch(info, (info) => {
useUserStore().setBranchV1({ branchV1: info?.branch || '' })
if (info && info.status) {
tip.value = getTip(info.status) || ''
}
})
let socket: Socket = getWebSocket()
onMounted(() => {
socket.on('ChangeV1Status', (e: any) => {
if (info.value) info.value.status = e
socket.on('v1', (e: string) => {
const data = JSON.parse(e) as { type: string , message: string }
if (data.type === 'Tip') {
tip.value = data.message
} else if (data.type === 'Status') {
info.value!.status = data.message as any
tip.value = getTip(data.message) || ''
}
})
})
onUnmounted(() => {
socket.removeListener('ChangeV1Status')
socket.removeListener('v1')
})
function handleOpenVscode() {
......@@ -80,7 +93,6 @@ function getStatusLabel(status?: string) {
['created', "已创建"],
['running', '运行中'],
['launched', '正在运行'],
['stopped', '已停止'],
['compiling', '编译中'],
['compiled', '已编译']
])
......@@ -97,9 +109,16 @@ async function handleCompile() {
}
async function handleInstall() {
await $fetch('/api/devops/v1/install', { method: 'post' })
if (info.value) {
info.value.branch = 'master'
}
execute()
}
function getTip (status: string) {
const HOST = process.env.NODE_ENV === 'production' ? '192.168.0.4' : (process.env.DEVHOST || '192.168.0.190')
const port = useUserStore().port
const map = new Map([
['null', '请点击右侧按钮完成项目初始化'],
['launched', `请代理后端请求到 ${HOST}:${port}`]
])
return map.get(status)
}
</script>
......@@ -117,6 +136,7 @@ async function handleInstall() {
flex: 1;
overflow: hidden;
padding: 20px;
position: relative;
}
.project-card__settings{
width: 60px;
......
......@@ -10,7 +10,11 @@
<span title="分支" class="secondary branch">分支:{{ info?.branch }}</span>
<span title="目录" class="secondary">目录:/var/logwire-backend</span>
</div>
<div class="row" style="margin-top: 50px;">
<div v-if="tip" class="row" style="color: #ffa15b;word-break: break-all;">
<span>TIP: </span>
<span v-html="tip"></span>
</div>
<div class="row" style="position: absolute;bottom: 0px;">
<div class="extra-operation" @click="navigateTo('/git')">
<svg t="1714466723924" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13200" width="200" height="200"><path d="M738.986667 868.693333c0 47.786667 37.546667 85.333333 85.333333 85.333334s85.333333-37.546667 85.333333-85.333334-37.546667-85.333333-85.333333-85.333333-85.333333 39.253333-85.333333 85.333333z" p-id="13201"></path><path d="M824.32 979.626667c-61.44 0-110.933333-49.493333-110.933333-110.933334s49.493333-110.933333 110.933333-110.933333 110.933333 49.493333 110.933333 110.933333-49.493333 110.933333-110.933333 110.933334z m0-170.666667c-32.426667 0-59.733333 27.306667-59.733333 59.733333s27.306667 59.733333 59.733333 59.733334 59.733333-27.306667 59.733333-59.733334-27.306667-59.733333-59.733333-59.733333z" p-id="13202"></path><path d="M269.653333 868.693333c0 47.786667 37.546667 85.333333 85.333334 85.333334s85.333333-37.546667 85.333333-85.333334-37.546667-85.333333-85.333333-85.333333-85.333333 39.253333-85.333334 85.333333z" p-id="13203"></path><path d="M354.986667 979.626667c-61.44 0-110.933333-49.493333-110.933334-110.933334s49.493333-110.933333 110.933334-110.933333 110.933333 49.493333 110.933333 110.933333-49.493333 110.933333-110.933333 110.933334z m0-170.666667c-32.426667 0-59.733333 27.306667-59.733334 59.733333s27.306667 59.733333 59.733334 59.733334 59.733333-27.306667 59.733333-59.733334-27.306667-59.733333-59.733333-59.733333z" p-id="13204"></path><path d="M269.653333 186.026667c0 47.786667 37.546667 85.333333 85.333334 85.333333s85.333333-37.546667 85.333333-85.333333-37.546667-85.333333-85.333333-85.333334-85.333333 39.253333-85.333334 85.333334z" p-id="13205"></path><path d="M354.986667 296.96c-61.44 0-110.933333-49.493333-110.933334-110.933333s49.493333-110.933333 110.933334-110.933334 110.933333 49.493333 110.933333 110.933334-49.493333 110.933333-110.933333 110.933333z m0-170.666667c-32.426667 0-59.733333 27.306667-59.733334 59.733334s27.306667 59.733333 59.733334 59.733333 59.733333-27.306667 59.733333-59.733333-27.306667-59.733333-59.733333-59.733334z" p-id="13206"></path><path d="M824.32 808.96c-13.653333 0-25.6-11.946667-25.6-25.6v-85.333333c0-68.266667-110.933333-114.346667-218.453333-157.013334-75.093333-30.72-150.186667-61.44-199.68-104.106666V785.066667c0 13.653333-11.946667 25.6-25.6 25.6s-25.6-11.946667-25.6-25.6V273.066667c0-13.653333 11.946667-25.6 25.6-25.6s25.6 11.946667 25.6 25.6v63.146666c0 68.266667 110.933333 114.346667 218.453333 157.013334 122.88 51.2 250.88 102.4 250.88 204.8v85.333333c0 13.653333-11.946667 25.6-25.6 25.6z" p-id="13207"></path></svg>
切换分支
......@@ -44,7 +48,7 @@
<div class="setting-item" v-if="info?.status === 'compiled'" title="运行" @click="handleExecute">
<svg t="1714466279198" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1111" width="200" height="200"><path d="M512 193.536c175.616 0 318.464 142.848 318.464 318.464s-142.848 318.464-318.464 318.464S193.536 687.616 193.536 512 336.384 193.536 512 193.536M512 102.4c-226.304 0-409.6 183.296-409.6 409.6s183.296 409.6 409.6 409.6 409.6-183.296 409.6-409.6-183.296-409.6-409.6-409.6z" p-id="1112"></path><path d="M670.208 483.328L456.192 360.96a26.0096 26.0096 0 0 0-38.912 22.528v244.736c0 19.968 21.504 32.256 38.912 22.528l214.016-122.368c17.408-10.24 17.408-35.328 0-45.056z" p-id="1113"></path></svg>
</div>
<div class="setting-item" v-if="info?.status === 'launched'" title="停止" @click="handleStop">
<div class="setting-item" v-if="info?.status === 'launched' || info?.status === 'debug-launched'" title="停止" @click="handleStop">
<svg t="1714466309184" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1264" width="200" height="200"><path d="M611.328 638.464H412.672c-14.848 0-27.136-12.288-27.136-27.136V412.672c0-14.848 12.288-27.136 27.136-27.136h198.144c14.848 0 27.136 12.288 27.136 27.136v198.144c0.512 15.36-11.776 27.648-26.624 27.648z" p-id="1265"></path><path d="M512 193.536c175.616 0 318.464 142.848 318.464 318.464s-142.848 318.464-318.464 318.464S193.536 687.616 193.536 512 336.384 193.536 512 193.536M512 102.4c-226.304 0-409.6 183.296-409.6 409.6s183.296 409.6 409.6 409.6 409.6-183.296 409.6-409.6-183.296-409.6-409.6-409.6z" p-id="1266"></path></svg>
</div>
<div v-if="info?.status?.endsWith('ing')" class="setting-item">
......@@ -73,21 +77,31 @@
import { Socket, io } from 'socket.io-client';
import { useUserStore } from '~/store/user';
let { pending, data: info } = useLazyFetch('/api/devops/v2/getProjectInfo')
let tip = ref('')
let { pending, data: info, execute } = useLazyFetch('/api/devops/v2/getProjectInfo')
watch(info, (info) => {
useUserStore().setBranchV2({ branchV2: info?.branch || '' })
if (info && info.status) {
tip.value = getTip(info.status) || ''
}
})
let socket: Socket = getWebSocket()
onMounted(() => {
socket.on('ChangeV2Status', (e: any) => {
console.log('info', info, e)
if (info.value) info.value.status = e
socket.on('v2', (e: string) => {
const data = JSON.parse(e) as { type: string , message: string }
if (data.type === 'Tip') {
tip.value = data.message
} else if (data.type === 'Status') {
info.value!.status = data.message as any
tip.value = getTip(data.message) || ''
}
})
})
onUnmounted(() => {
socket.removeListener('changeV2Status')
socket.removeListener('v2')
})
function handleOpenVscode() {
window.open(window.location.protocol + '//' + window.location.hostname + ':' + useUserStore().port + '/vscode?folder=/var/logwire-backend', '_blank')
......@@ -100,7 +114,7 @@ function getStatusLabel(status?: string) {
['created', "已创建"],
['running', '运行中'],
['launched', '正在运行'],
['stopped', '已停止'],
['debugLaunched', '正在调试'],
['compiling', '编译中'],
['compiled', '已编译']
])
......@@ -123,9 +137,17 @@ async function handleCompile() {
}
async function handleInstall() {
await $fetch('/api/devops/v2/install', { method: 'post' })
if (info.value) {
info.value.branch = 'master'
}
execute()
}
function getTip (status: string) {
const HOST = process.env.NODE_ENV === 'production' ? '192.168.0.4' : (process.env.DEVHOST || '192.168.0.190')
const port = useUserStore().port
const map = new Map([
['null', '请点击右侧按钮完成项目初始化'],
['launched', `请代理后端请求到 ${HOST}:${port}, 开发环境域名和端口号为 ${(info.value?.tenants as any)?.host}`]
])
return map.get(status)
}
</script>
......@@ -144,6 +166,7 @@ async function handleInstall() {
flex: 1;
overflow: hidden;
padding: 20px;
position: relative;
}
.project-card__settings{
width: 60px;
......
......@@ -7,7 +7,11 @@ export default defineEventHandler(async (event) => {
let docker = createDockerFactory(username)
LogUtil.clear(username)
await changeProjectStatus( 'v1', username, 'status', 'compiling')
await changeProjectStatus('v1', username, 'status', 'compiling')
const rowV2 = await getPgTableData('v2', username)
if (rowV2?.status === 'launched') {
await changeProjectStatus('v2', username, 'status', 'compiled')
}
// 每次编译前把已有的 tenants_config 文件夹拷贝到一个地方,编译完成后,再拷贝回来
let container = await docker.checkContainer( username + '.node')
......
......@@ -11,6 +11,10 @@ export default defineEventHandler(async (event) => {
LogUtil.printInfo(username, '程序启动中')
await changeProjectStatus( 'v1', username, 'status', 'running')
const rowV2 = await getPgTableData('v2', username)
if (rowV2?.status === 'launched') {
await changeProjectStatus('v2', username, 'status', 'compiled')
}
if (!container) {
throw new Error('没有创建容器,请先初始化容器')
}
......
import Dockerode from "dockerode"
import LogUtil from "~/server/utils/log"
import LogUtil, { sendSocketMessage } from "~/server/utils/log"
import path from 'path'
export default defineEventHandler(async (event) => {
let username = event.context.username
let pgClient = await createPgClientFactory(username)
let isClonedSuccess = true
let sshKey = ''
try {
LogUtil.clear(username)
let docker = createDockerFactory(username)
const rowV2 = await getPgTableData( 'v2', username)
if (!rowV2 || rowV2?.status === 'null' || !rowV2?.status) {
throw new Error('请先初始化 V2')
}
let rowV1 = await getPgTableData('v1', username)
if (!rowV1) await insertPgTableData('v1', username)
await changeProjectStatus( 'v1', username, 'status', 'creating')
......@@ -22,20 +18,48 @@ export default defineEventHandler(async (event) => {
}
// 创建 postgres 不一定要在本机,即使是 dev 环境也可以联远程的容器
await LogUtil.run(username, 'v1-创建 postgres 容器', async () => {
if (process.env.NODE_ENV?.trim() !== 'production') {
let postgresInfo = await docker.checkContainer('postgres_12')
if (!postgresInfo) {
let postgres = await docker.checkAndCreateContainer({ name: 'postgres_12', img: 'postgres:12', env: ["POSTGRES_PASSWORD=postgres"], portBindings: { '5432/tcp': [{ HostPort: PgPort.toString() }] } })
await docker.startContainer({ container: postgres })
await sleep(3000)
}
const database = username + '_v1'
let result = await executePgQuery({ client: pgClient, query: "SELECT u.datname FROM pg_catalog.pg_database u where u.datname='" + database + "';" })
let client = await createPgClientFactory()
let result = await executePgQuery({ client, query: "SELECT u.datname FROM pg_catalog.pg_database u where u.datname='" + database + "';" })
if (result.rows.length === 0) {
await executePgQuery({ client: pgClient, query: 'CREATE DATABASE ' + database })
const client = await createPgClient({ host: HOST, port: PgPort, database: database })
await executePgQuery({ client, query: 'CREATE DATABASE ' + database })
await client.end()
client = await createPgClient({ host: HOST, port: PgPort, database: database })
await executePgQuery({ client, query: 'CREATE SCHEMA library' })
await client.end()
}
}
})
await LogUtil.run(username, 'v1-创建 redis 容器', async () => {
if (process.env.NODE_ENV?.trim() !== 'production') {
let redisInfo = await docker.checkContainer('redis')
if (!redisInfo) {
let redis = await docker.checkAndCreateContainer({ name: 'redis', img: 'redis', portBindings: { '6379/tcp': [{ HostPort: '6379' }] } })
await docker.startContainer({ container: redis })
}
}
})
await LogUtil.run(username, '检查 SSH Key', async () => {
sshKey = await checkSshExists(username)
LogUtil.printWarning(username, `${username}@greaconsulting.com 用户 SSH key 为 <strong>${sshKey.replace(/\n/g, '')}</strong>, 若克隆仓库失败, 请检查是否放入 Gitlab SSH 设置中并重试\n`)
})
await LogUtil.run(username, 'v1-克隆仓库', async () => {
isClonedSuccess = false
await docker.execContainerCommand({ container, cmd: ['git', 'config' ,'--global', 'core.sshCommand', 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'] })
await docker.execContainerCommand({ container, cmd: 'rm -rf /var/logwire-platform' })
await docker.execContainerCommand({ container, cmd: 'git clone ssh://git@gitlab.logwire.cn:13389/logwire/logwire-platform.git', dir: '/var' })
isClonedSuccess = true
})
await LogUtil.run(username, 'v1-安装 openjdk ', async () => {
......@@ -64,11 +88,15 @@ export default defineEventHandler(async (event) => {
})
await changeProjectStatus( 'v1', username, 'status', 'created')
await stopPgClient(pgClient)
LogUtil.printSuccess(username, 'installed')
} catch (err: any) {
await changeProjectStatus( 'v1', username, 'status', 'null')
await stopPgClient(pgClient)
if (!isClonedSuccess) {
const message = `初始化中克隆仓库失败,请将 <strong>${sshKey.replace(/\n/g, '')}</strong> 放入 Gitlab SSH 设置中并重试`
const type = 'Tip'
const eventData = { type, message }
sendSocketMessage(username, 'v1', JSON.stringify(eventData))
}
LogUtil.printError(username, (err instanceof Error ? err.message : JSON.stringify(err)))
setResponseStatus(event, 500)
return err
......
......@@ -9,6 +9,7 @@ export default defineEventHandler(async (event) => {
throw new Error('没有创建容器,请先初始化容器')
}
LogUtil.printInfo(username, `程序停止中......`)
await changeProjectStatus( 'v1', username, 'status', 'stopping')
await docker.execContainerCommand({ container, cmd: 'pm2 delete platform', quiet: true })
LogUtil.printInfo(username, `程序已停止`)
await changeProjectStatus( 'v1', username, 'status', 'compiled')
......
......@@ -9,6 +9,11 @@ export default defineEventHandler(async (event) => {
let docker = createDockerFactory(username)
await changeProjectStatus( 'v2', username, 'status', 'compiling')
const rowV1 = await getPgTableData('v1', username)
if (rowV1?.status === 'launched') {
await changeProjectStatus('v2', username, 'status', 'compiled')
}
// TODO: 在后端发送 websocket 通知前端状态变更
// 每次编译前把已有的 tenants_config 文件夹拷贝到一个地方,编译完成后,再拷贝回来
......
......@@ -15,6 +15,11 @@ export default defineEventHandler(async (event) => {
const port = rowUser!.port
const debug = rowV2!.debug
if (rowV2?.status !== 'compiled') {
throw new Error('调试只可以在已创建状态下进行')
}
await changeProjectStatus( 'v2', username, 'status', 'running')
// 有可能本身就关闭了
try {
LogUtil.print(username, `[progress] [[1;34mLoading[m] 关闭已存在的 Nginx 服务 ...... \n`)
......@@ -63,5 +68,5 @@ export default defineEventHandler(async (event) => {
LogUtil.print(username, `[progress] [[1;34mInfo[m] 请设置开发环境域名和端口号 <strong>${tenants?.host}</strong> 上\n`)
LogUtil.print(username, `[progress] [[1;34mInfo[m] 调试程序已启动,请IP地址为 <strong>${debug?.host}</strong> 后端访问 <strong>${HOST}:${port}</strong> 进行调试\n`)
await changeProjectStatus( 'v2', username, 'status', 'running')
await changeProjectStatus( 'v2', username, 'status', 'debug-launched')
})
\ No newline at end of file
......@@ -14,6 +14,10 @@ export default defineEventHandler(async (event) => {
LogUtil.printInfo(username, `程序初始化中......`)
await changeProjectStatus( 'v2', username, 'status', 'running')
const rowV1 = await getPgTableData('v1', username)
if (rowV1?.status === 'launched') {
await changeProjectStatus('v2', username, 'status', 'compiled')
}
if (!container) {
throw new Error('没有创建容器,请先初始化容器')
}
......
import Dockerode from "dockerode"
import LogUtil, { sendProjectStatus } from "~/server/utils/log"
import LogUtil, { sendProjectStatus, sendSocketMessage } from "~/server/utils/log"
import fs from 'fs'
import path from 'path'
import { changeProjectStatus } from "~/server/utils/postgres"
export default defineEventHandler(async (event) => {
let username = event.context.username
let pgClient = await createPgClientFactory('backend_helper')
let isClonedSuccess = true
let sshKey = ''
try {
LogUtil.clear(username)
let docker = createDockerFactory(username)
let host = docker.host
let container: Dockerode.Container = {} as Dockerode.Container
const port = (await getPgTableData( 'user', username))?.port
const row = await getPgTableData('v2', username)
......@@ -28,7 +28,7 @@ export default defineEventHandler(async (event) => {
await docker.startContainer({ container })
})
await LogUtil.run(username, '检查 SSH Key', async () => {
let sshKey = await checkSshExists(username)
sshKey = await checkSshExists(username)
LogUtil.printWarning(username, `${username}@greaconsulting.com 用户 SSH key 为 <strong>${sshKey.replace(/\n/g, '')}</strong>, 若克隆仓库失败, 请检查是否放入 Gitlab SSH 设置中并重试\n`)
})
// 创建 postgres 不一定要在本机,即使是 dev 环境也可以联远程的容器
......@@ -52,9 +52,12 @@ export default defineEventHandler(async (event) => {
})
await LogUtil.run(username, '创建 redis 容器', async () => {
if (process.env.NODE_ENV?.trim() !== 'production') {
let redisInfo = await docker.checkContainer('redis')
if (!redisInfo) {
let redis = await docker.checkAndCreateContainer({ name: 'redis', img: 'redis', portBindings: { '6379/tcp': [{ HostPort: '6379' }] } })
await docker.startContainer({ container: redis })
}
}
})
await LogUtil.run(username, '创建 zookeeper 容器', async () => {
if (process.env.NODE_ENV?.trim() !== 'production') {
......@@ -88,9 +91,11 @@ export default defineEventHandler(async (event) => {
})
await LogUtil.run(username, '克隆仓库', async () => {
isClonedSuccess = false
await docker.execContainerCommand({ container, cmd: ['git', 'config' ,'--global', 'core.sshCommand', 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'] })
await docker.execContainerCommand({ container, cmd: 'rm -rf /var/logwire-backend' })
await docker.execContainerCommand({ container, cmd: 'git clone ssh://git@gitlab.logwire.cn:13389/logwire2/logwire-backend.git', dir: '/var' })
isClonedSuccess = true
})
// await LogUtil.run(username, '添加源', async () => {
// let txt = await docker.getFile({ container, path: '/etc/apt/sources.list' })
......@@ -189,11 +194,15 @@ export default defineEventHandler(async (event) => {
await setPgTableData('v2', username, 'debug', JSON.stringify(debug))
})
await changeProjectStatus( 'v2', username, 'status', 'created')
await stopPgClient(pgClient)
LogUtil.printSuccess(username, '安装成功')
} catch (err: any) {
await changeProjectStatus( 'v2', username, 'status', 'null')
await stopPgClient(pgClient)
if (!isClonedSuccess) {
const message = `初始化中克隆仓库失败,请将 <strong>${sshKey.replace(/\n/g, '')}</strong> 放入 Gitlab SSH 设置中并重试`
const type = 'Tip'
const eventData = { type, message }
sendSocketMessage(username, 'v2', JSON.stringify(eventData))
}
LogUtil.printError(username, (err instanceof Error ? err.message : JSON.stringify(err)))
setResponseStatus(event, 500)
return err
......
......@@ -9,6 +9,7 @@ export default defineEventHandler(async (event) => {
throw new Error('没有创建容器,请先初始化容器')
}
LogUtil.printInfo(username, `程序停止中......`)
await changeProjectStatus( 'v2', username, 'status', 'stopping')
await docker.execContainerCommand({ container, cmd: 'pm2 delete backend', quiet: true })
await docker.execContainerCommand({ container, cmd: 'pm2 delete gateway', quiet: true })
LogUtil.print(username, `程序已停止`)
......
......@@ -14,9 +14,17 @@ export function getWebsocketIo (username: string) {
}
export function sendProjectStatus (platform: 'v1' | 'v2', username: string, status: string) {
const eventName = platform === 'v1' ? 'ChangeV1Status' : 'ChangeV2Status'
const socket = getWebsocketIo(username)
socket.emit(eventName, status)
const eventData = {
type: 'Status',
message: status
}
socket.emit(platform, JSON.stringify(eventData))
}
export function sendSocketMessage (username: string, eventName: string, message: string) {
const socket = getWebsocketIo(username)
socket.emit(eventName, message)
}
export default class LogUtil {
......@@ -50,4 +58,8 @@ export default class LogUtil {
let socket = getWebsocketIo(username)
socket.emit('ClearLog')
}
static printNotification (username: string, notification: string) {
let socket = getWebsocketIo(username)
socket.emit('Notification', removeUnreadCharacter(notification))
}
}
......@@ -42,7 +42,7 @@ export type TableUser = { username: string, port: number }
export type TableV2 = {
username: string
status: 'null' | 'created' | 'stopped' | 'running' | 'launched' | 'creating' | 'compiling' | 'compiled'
status: 'null' | 'created' | 'running' | 'launched' | 'debug-launched' | 'creating' | 'compiling' | 'compiled'
tenants: Record<string, any>
debug: Record<string, any>
has_debugged: boolean
......@@ -51,7 +51,7 @@ export type TableV2 = {
export type TableV1 = {
username: string
status: 'null' | 'created' | 'stopped' | 'running' | 'launched' | 'creating' | 'compiling' | 'compiled'
status: 'null' | 'created' | 'running' | 'launched' | 'creating' | 'compiling' | 'compiled'
serverProperties: { id: any, key: string, value: string }[]
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment