Commit 8a7ef11e authored by 王曜嵚 Wang Yaoqin's avatar 王曜嵚 Wang Yaoqin

dev: v1, v2 相关接口

parent dc682150
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动程序",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\server\\api\\devops\\v2\\install.ts",
"outFiles": [
"${workspaceFolder}/**/*.js"
]
}
]
}
\ No newline at end of file
...@@ -38,6 +38,9 @@ ...@@ -38,6 +38,9 @@
cursor: pointer; cursor: pointer;
} }
#app .sidebar a{ #app .sidebar a{
display: inline-block;
width: 100%;
height: 100%;
color: #fff; color: #fff;
text-decoration: none; text-decoration: none;
} }
......
<template>
<section>
<p>此页面将显示在 /about 路由。</p>
</section>
</template>
\ No newline at end of file
<template>
<NuxtLayout>
<div class='content'>
<div class='container'>
<form class='form' @submit.prevent>
<div class='form-group'>
<div class='form-group__label'>
<label>Email</label>
<p>用户的 Gitlab 邮箱账号</p>
</div>
<div class='form-group__body'>
<input v-model='form.email' />
</div>
</div>
<div class='form-group'>
<div class='form-group__label'>
<label>SSH Key</label>
<p>使用上述的 Email 邮箱生成 Ssh key,用于 Gitlab 中用户认证</p>
</div>
<div class='form-group__body'>
<button class='primary' @click='handleGenerate'>生成 ssh key</button>
</div>
</div>
<div class='form-group'>
<div class='form-group__label'>
<label>V2 分支管理</label>
<p>查看当前分支,切换分支等功能</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>当前分支</span><span>{{ form.currentBranchV2 }}</span></div>
<div class='form-group__item'>
<span>所有分支</span>
<span>
<select v-model='form.targetBranchV2'>
<option v-for='item in branchs' :key='item'>{{ item }}</option>
</select>
</span>
<p>
<button @click='handleCheckout("v2")'>切换分支</button>
</p>
</div>
<div class='form-group__item'>
<span>刷新分支</span>
<p>刷新当前分支</p>
<span><button @click='handleFetch("v2")'>刷新</button></span>
</div>
</div>
</div>
<div class='form-group'>
<div class='form-group__label'>
<label>V1 分支管理</label>
<p>查看当前分支,切换分支等功能</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>当前分支</span><span>{{ form.currentBranchV1 }}</span></div>
<div class='form-group__item'>
<span>所有分支</span>
<span>
<select v-model='form.targetBranchV1'>
<option v-for='item in branchsV1' :key='item'>{{ item }}</option>
</select>
</span>
<p>
<button @click='handleCheckout("v1")'>切换分支</button>
</p>
</div>
<div class='form-group__item'>
<span>刷新分支</span>
<p>刷新当前分支</p>
<span><button @click='handleFetch("v1")'>刷新</button></span>
</div>
</div>
</div>
</form>
</div>
</div>
</NuxtLayout>
</template>
<script lang="ts" setup>
const form = ref({
email: '',
currentBranchV2: '',
currentBranchV1: '',
targetBranchV2: '',
targetBranchV1: ''
})
const branchs = ref([])
const branchsV1 = ref([])
onMounted(() => {
getUserInfo()
getCurrentBranchV2()
getCurrentBranchV1()
getAllBranchV2()
getAllBranchV1()
})
function getUserInfo() {
$fetch('/api/user/getProjectInfo').then((res: any) => {
form.value.email = res.username + '@greaconsulting.com'
console.log(form)
})
}
function getAllBranchV2() {
return $fetch('/api/git/getAllBranchs', { query: { platform: 'v2' } }).then((res: any) => {
branchs.value = res.split('\n').map((o: string) => o.trim()).filter((o: string) => !!o)
})
}
function getAllBranchV1() {
return $fetch('/api/git/getAllBranchs', { query: { platform: 'v1' } }).then((res: any) => {
branchsV1.value = res.split('\n').map((o: string) => o.trim()).filter((o: string) => !!o)
})
}
function getCurrentBranchV2() {
return $fetch('/api/git/getCurrentBranch', { query: { platform: 'v2' } }).then((res: any) => {
form.value.currentBranchV2 = res.trim()
form.value.targetBranchV2 = form.value.currentBranchV2
})
}
function getCurrentBranchV1() {
return $fetch('/api/git/getCurrentBranch', { query: { platform: 'v1' } }).then((res: any) => {
form.value.currentBranchV1 = res.trim()
form.value.targetBranchV1 = form.value.currentBranchV1
})
}
function handleGenerate() {
$fetch('/api/git/generateSsh', { method: 'post', body: { email: form.value.email } }).then(res => {
alert('生成 ssh key: [' + res + '], 请放入 gitlab 的 SSH Key 配置中')
})
}
async function handleFetch(platform: 'v1' | 'v2') {
const branch = platform === 'v2' ? form.value.currentBranchV2 : form.value.currentBranchV1
await $fetch('/api/git/fetch', { method: 'post', body: { branch, platform }})
if (platform === 'v1') {
await getCurrentBranchV1()
await getAllBranchV1()
} else {
await getCurrentBranchV2()
await getAllBranchV2()
}
alert('刷新分支完成,请重新编译运行')
}
async function handleCheckout(platform: 'v1' | 'v2') {
try {
const branch = platform === 'v1' ? form.value.targetBranchV1 : form.value.targetBranchV2
await $fetch('/api/git/checkout', { method: 'post', body: { platform, branch } })
if (platform === 'v1') {
await getCurrentBranchV1()
form.value.currentBranchV1 = form.value.targetBranchV1
} else {
await getCurrentBranchV2()
form.value.currentBranchV2 = form.value.targetBranchV2
}
alert('切换分支完成,请重新编译运行')
// 后端更新完毕
} catch (err) {
console.log(err)
}
}
</script>
<style scoped>
.content {
background-color: #EFEFEF;
overflow: auto;
height: 100%;
padding: 24px;
}
</style>
\ No newline at end of file
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
<button v-else-if='status === "running"' :disabled='loading' @click='handleStop'>停止</button> <button v-else-if='status === "running"' :disabled='loading' @click='handleStop'>停止</button>
<button v-if="status === 'running'" :disabled="loading" @click="handleZip">打包微信压缩文件</button> <button v-if="status === 'running'" :disabled="loading" @click="handleZip">打包微信压缩文件</button>
<button @click="test">测试</button>
</div> </div>
<div class='row'> <div class='row'>
<span style="display: inline-block; width: 150px;">V1: {{ getStatusLabel(statusV1) }}</span> <span style="display: inline-block; width: 150px;">V1: {{ getStatusLabel(statusV1) }}</span>
...@@ -97,10 +96,9 @@ ...@@ -97,10 +96,9 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { useUserStore } from '~/store/user';
import { io } from 'socket.io-client'; import { io } from 'socket.io-client';
const username = ref(useUserStore().username) const username = ref('')
const status = ref('null') // null | created | stopped | running | creating | compiling const status = ref('null') // null | created | stopped | running | creating | compiling
const statusV1 = ref('null') const statusV1 = ref('null')
...@@ -114,29 +112,10 @@ const renderLogs = computed(() => { ...@@ -114,29 +112,10 @@ const renderLogs = computed(() => {
return str.split('\n').map((o: string) => addColorfulTag(o)) return str.split('\n').map((o: string) => addColorfulTag(o))
}) })
onMounted(() => { onMounted(async () => {
const socket = io({ await checkAndRestartDocker()
path: '/socket.io', await getUserInfomation()
auth: { initWebsocket()
username: username.value
}
});
// eslint-disable-next-line no-control-regex
const removeLogPrefix = (log: string) => log.replace(/^\[.*?\]\s/, '').replace(/[\u0000-\u0009]/g, '').replace(/[\u000B-\u001F]/g, '')
const replaceLineFlag = (log: string) => log.replaceAll('\n', '<br />')
socket.on('Log', (log) => {
if (logLevel.value === 'info') {
logs.value.push(replaceLineFlag(removeLogPrefix(log)))
} else {
if (!log.startsWith('[info]')) {
logs.value.push(replaceLineFlag(removeLogPrefix(log)))
}
}
})
handleGetStatus()
checkAndRestartDocker()
}) })
function getStatusLabel(status: string) { function getStatusLabel(status: string) {
return status === 'null' ? "未初始化" return status === 'null' ? "未初始化"
...@@ -148,7 +127,7 @@ function getStatusLabel(status: string) { ...@@ -148,7 +127,7 @@ function getStatusLabel(status: string) {
: '' : ''
} }
function checkAndRestartDocker() { function checkAndRestartDocker() {
$fetch('/api/checkAndRestartDocker', { method: 'post' }) return $fetch('/api/devops/common/checkAndRestartDocker', { method: 'post' })
} }
function addColorfulTag(log: string) { function addColorfulTag(log: string) {
let value = log let value = log
...@@ -157,11 +136,12 @@ function addColorfulTag(log: string) { ...@@ -157,11 +136,12 @@ function addColorfulTag(log: string) {
.replace(/\[1m(.*?)\[m/g, '<span style="color: gray">$1</span>') .replace(/\[1m(.*?)\[m/g, '<span style="color: gray">$1</span>')
return value return value
} }
function handleGetStatus() { function getUserInfomation() {
return $fetch('/api/user/getProjectInfo').then((res: any) => { return $fetch('/api/user/getProjectInfo').then((res: any) => {
status.value = res.status || 'null' status.value = res.status || 'null'
statusV1.value = res['v1-status'] || 'null' statusV1.value = res['v1-status'] || 'null'
port.value = res['node-port'] port.value = res['node-port']
username.value = res.username
if (status.value === 'creating' || status.value === 'compiling') { if (status.value === 'creating' || status.value === 'compiling') {
loading.value = true loading.value = true
} }
...@@ -170,13 +150,34 @@ function handleGetStatus() { ...@@ -170,13 +150,34 @@ function handleGetStatus() {
} }
}) })
} }
function initWebsocket () {
const socket = io({
path: '/socket.io',
auth: {
username: username.value
}
});
// eslint-disable-next-line no-control-regex
const removeLogPrefix = (log: string) => log.replace(/^\[.*?\]\s/, '').replace(/[\u0000-\u0009]/g, '').replace(/[\u000B-\u001F]/g, '')
const replaceLineFlag = (log: string) => log.replaceAll('\n', '<br />')
socket.on('Log', (log) => {
if (logLevel.value === 'info') {
logs.value.push(replaceLineFlag(removeLogPrefix(log)))
} else {
if (!log.startsWith('[info]')) {
logs.value.push(replaceLineFlag(removeLogPrefix(log)))
}
}
})
}
function handleInstall() { function handleInstall() {
if (loading.value) return if (loading.value) return
logs.value = [] logs.value = []
loading.value = true loading.value = true
status.value = 'creating' status.value = 'creating'
$fetch('/api/devops/v2/install', { method: 'post' }) $fetch('/api/devops/v2/install', { method: 'post' })
.then(handleGetStatus, handleGetStatus) .then(getUserInfomation, getUserInfomation)
.finally(() => { .finally(() => {
loading.value = false loading.value = false
}) })
...@@ -186,8 +187,8 @@ function handleInstallV1() { ...@@ -186,8 +187,8 @@ function handleInstallV1() {
logs.value = [] logs.value = []
loading.value = true loading.value = true
statusV1.value = 'creating' statusV1.value = 'creating'
$fetch('/api/installProject-v1', { method: 'post' }) $fetch('/api/devops/v1/install', { method: 'post' })
.then(handleGetStatus, handleGetStatus) .then(getUserInfomation, getUserInfomation)
.finally(() => { .finally(() => {
loading.value = false loading.value = false
}) })
...@@ -197,8 +198,8 @@ function handleCompile() { ...@@ -197,8 +198,8 @@ function handleCompile() {
loading.value = true loading.value = true
logs.value = [] logs.value = []
resetV1() resetV1()
$fetch('/api/backend/compile', { method: 'post'}).then(() => { $fetch('/api/devops/v2/compile', { method: 'post'}).then(() => {
return handleGetStatus() return getUserInfomation()
}).finally(() => { }).finally(() => {
loading.value = false loading.value = false
}) })
...@@ -208,8 +209,8 @@ function handleCompileV1() { ...@@ -208,8 +209,8 @@ function handleCompileV1() {
loading.value = true loading.value = true
logs.value = [] logs.value = []
resetV2() resetV2()
$fetch('/api/backend/compile-v1', { method: 'post'}).then(() => { $fetch('/api/devops/v1/compile', { method: 'post'}).then(() => {
return handleGetStatus() return getUserInfomation()
}).finally(() => { }).finally(() => {
loading.value = false loading.value = false
}) })
...@@ -219,8 +220,8 @@ function handleExecute() { ...@@ -219,8 +220,8 @@ function handleExecute() {
loading.value = true loading.value = true
logs.value = [] logs.value = []
resetV1() resetV1()
$fetch('/api/backend/execute').then(() => { $fetch('/api/devops/v2/execute', { method: 'post' }).then(() => {
return handleGetStatus() return getUserInfomation()
}).finally(() => { }).finally(() => {
loading.value = false loading.value = false
}) })
...@@ -230,8 +231,8 @@ function handleExecuteV1() { ...@@ -230,8 +231,8 @@ function handleExecuteV1() {
loading.value = true loading.value = true
logs.value = [] logs.value = []
resetV2() resetV2()
$fetch('/api/backend/execute-v1', { method: 'post'}).then(() => { $fetch('/api/devops/v1/execute', { method: 'post'}).then(() => {
return handleGetStatus() return getUserInfomation()
}).finally(() => { }).finally(() => {
loading.value = false loading.value = false
}) })
...@@ -240,8 +241,8 @@ function handleStop() { ...@@ -240,8 +241,8 @@ function handleStop() {
if (loading.value) return if (loading.value) return
logs.value = [] logs.value = []
loading.value = true loading.value = true
$fetch('/api/backend/stop', { method: 'post' }).then(() => { $fetch('/api/devops/v2/stop', { method: 'post' }).then(() => {
return handleGetStatus() return getUserInfomation()
}).finally(() => { }).finally(() => {
loading.value = false loading.value = false
}) })
...@@ -250,8 +251,8 @@ function handleStopV1() { ...@@ -250,8 +251,8 @@ function handleStopV1() {
if (loading.value) return if (loading.value) return
logs.value = [] logs.value = []
loading.value = true loading.value = true
$fetch('/api/backend/stop-v1', { method: 'post'}).then(() => { $fetch('/api/devops/v1/stop', { method: 'post'}).then(() => {
return handleGetStatus() return getUserInfomation()
}).finally(() => { }).finally(() => {
loading.value = false loading.value = false
}) })
...@@ -274,19 +275,12 @@ function handleDebug() { ...@@ -274,19 +275,12 @@ function handleDebug() {
if (loading.value) return if (loading.value) return
loading.value = true loading.value = true
logs.value = [] logs.value = []
$fetch('/api/backend/debug', { method: 'post'}).then(() => { $fetch('/api/devops/v2/debug', { method: 'post'}).then(() => {
return handleGetStatus() return getUserInfomation()
}).finally(() => { }).finally(() => {
loading.value = false loading.value = false
}) })
} }
function test() {
$fetch('/api/devops/v2/test').then(() => {
alert('测试成功')
}).catch(() => {
alert('测试失败')
})
}
function resetV1() { function resetV1() {
statusV1.value = 'created' statusV1.value = 'created'
} }
......
<template>
<div>
<NuxtLayout />
</div>
</template>
\ No newline at end of file
<template>
<div>Post</div>
</template>
\ No newline at end of file
<template>
<NuxtLayout>
<div class='content'>
<div class='container'>
<form class='form' ref='form'>
<div class='form-group'>
<div class='form-group__label'>
<label for="none">
<span>postgresV1</span>
<button class='primary' @click='handleSaveConfig("postgresV1")'>保存</button>
</label>
<p>postgresV1 数据库的配置信息</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>数据库</span><span><input v-model='form.postgresV1.database' /></span>
</div>
<div class='form-group__item'><span>用户名</span><span><input v-model='form.postgresV1.username' /></span>
</div>
<div class='form-group__item'><span>密码</span><span><input v-model='form.postgresV1.password' /></span>
</div>
<div class='form-group__item'><span>服务 IP</span><span><input v-model='form.postgresV1.ip' /></span></div>
<div class='form-group__item'><span>服务 PORT</span><span><input v-model='form.postgresV1.port' /></span>
</div>
</div>
</div>
<div class='form-group'>
<div class='form-group__label'>
<label for="none">
<span>redisV1</span>
<button class='primary' @click='handleSaveConfig("redisV1")'>保存</button>
</label>
<p>redisV1 数据库的配置信息</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>服务 IP</span><span><input v-model='form.redisV1.ip' /></span></div>
<div class='form-group__item'><span>服务 PORT</span><span><input v-model='form.redisV1.port' /></span></div>
</div>
</div>
<div class="form-group">
<div class="form-group__label">
<label for="none">
<span>其他配置</span>
<div>
<button type="button" style="margin-right: 10px;" @click.stop="handleAddCustomConfig">新增</button>
<button type="button" class="primary" @click="handleSaveConfig('serverPropertiesV1')">保存</button>
</div>
</label>
</div>
<div class="form-group__body">
<table class="table">
<thead>
<tr>
<td>配置名称</td>
<td>配置值</td>
<td>操作列</td>
</tr>
</thead>
<tbody>
<tr v-for="item in form.serverPropertiesV1" :key="item.id">
<td><input type="text" v-model="item.key"></td>
<td><input type="text" v-model="item.value"></td>
<td><button @click="handleDeleteServerProperty(item)">删除</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
</div>
</div>
</NuxtLayout>
</template>
<script lang="ts" setup>
const form = ref<Record<string, any>>({
postgresV1: {
visible: false,
username: 'postgres',
password: 'postgres',
ip: '192.168.0.4',
port: '25556',
database: 'logwirev1',
schema: 'library'
},
redisV1: {
visible: false,
ip: '192.168.0.4',
port: '25557'
},
tenantsV1: {
visible: false,
id: 'wongyaqi',
port: 8080
},
debug: {
host: '192.168.0.190'
},
serverPropertiesV1: []
})
onMounted(() => {
getData
})
function getData() {
$fetch('/api/getProjectInfo').then((res: any) => {
Object.keys(form.value).forEach(key => {
if (res[key]) {
form.value[key] = res[key]
}
})
})
}
function handleSaveConfig(key: string) {
let value = form.value[key]
$fetch('/api/config/setUserSetting', { method: 'post', body: { key, value }}).then(() => {
alert('保存成功')
}).catch(() => {
alert('保存失败!!!')
})
}
function handleAddCustomConfig() {
form.value.serverPropertiesV1.push({
id: Math.random(),
key: '',
value: ''
})
}
function handleDeleteServerProperty(item: any) {
const index = form.value.serverPropertiesV1.indexOf(item)
form.value.serverPropertiesV1.splice(index, 1)
}
</script>
<style scoped>
.content {
background-color: #EFEFEF;
overflow: auto;
height: 100%;
padding: 24px;
box-sizing: border-box;
}
.table {
width: 100%;
}
.table thead tr td:nth-of-type(3) {
width: 100px;
}
.table input {
width: 100%;
box-sizing: border-box;
}
</style>
\ No newline at end of file
<template>
<NuxtLayout>
<div class='content'>
<div class='container'>
<form class='form' @submit.prevent>
<div class='form-group'>
<div class='form-group__label'>
<label for="none">
<span>Postgres</span>
<button class='primary' @click='handleSaveConfig("postgres")'>保存</button>
</label>
<p>Postgres 数据库的配置信息</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>用户名</span><span><input v-model='form.postgres.username' /></span></div>
<div class='form-group__item'><span>密码</span><span><input v-model='form.postgres.password' /></span></div>
<div class='form-group__item'><span>服务 IP</span><span><input v-model='form.postgres.ip' /></span></div>
<div class='form-group__item'><span>服务 PORT</span><span><input v-model='form.postgres.port' /></span></div>
</div>
</div>
<div class='form-group'>
<div class='form-group__label'>
<label for="none">
<span>Redis</span>
<button class='primary' @click='handleSaveConfig("redis")'>保存</button>
</label>
<p>Redis 数据库的配置信息</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>服务 IP</span><span><input v-model='form.redis.ip' /></span></div>
<div class='form-group__item'><span>服务 PORT</span><span><input v-model='form.redis.port' /></span></div>
</div>
</div>
<div class='form-group'>
<div class='form-group__label'>
<label for="none">
<span>Zookeeper</span>
<button class='primary' @click='handleSaveConfig("zookeeper")'>保存</button>
</label>
<p>Zookeeper 的配置信息</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>服务 IP</span><span><input v-model='form.zookeeper.ip' /></span></div>
<div class='form-group__item'><span>服务 PORT</span><span><input v-model='form.zookeeper.port' /></span></div>
</div>
</div>
<div class='form-group'>
<div class='form-group__label'>
<label for="none">
<span>Rocket MQ</span>
<button class='primary' @click='handleSaveConfig("rocketmq")'>保存</button>
</label>
<p>Rocket MQ 的配置信息</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>服务 IP</span><span><input v-model='form.rocketmq.ip' /></span></div>
<div class='form-group__item'><span>服务 PORT</span><span><input v-model='form.rocketmq.port' /></span></div>
</div>
</div>
<div class='form-group'>
<div class='form-group__label'>
<label for="none">
<span>租户</span>
<button class='primary' @click='handleSaveConfig("tenants")'>保存</button>
</label>
<p>租户 的配置信息</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>租户ID</span><span><input v-model='form.tenants.id' /></span></div>
<div class='form-group__item'><span>租户HOST</span><span><input v-model='form.tenants.host' /></span></div>
<div class='form-group__item'><span>租户数据库Schema</span><span><input v-model='form.tenants["database-schema"]' /></span></div>
<div class='form-group__item'><span>租户主要Schema</span><span><input v-model='form.tenants["primary-schema"]' /></span></div>
</div>
</div>
<div class='form-group'>
<div class='form-group__label'>
<label for="none">
<span>调试</span>
<button class='primary' @click='handleSaveConfig("debug")'>保存</button>
</label>
<p>调试 的配置信息</p>
</div>
<div class='form-group__body'>
<div class='form-group__item'><span>远程调试机 HOST</span><span><input v-model='form.debug.host' /></span></div>
</div>
</div>
<div class="form-group">
<div class="form-group__label">
<label for="none">
<span>其他配置</span>
<div>
<button type="button" style="margin-right: 10px;" @click.stop="handleAddCustomConfig">新增</button>
<button type="button" class="primary" @click="handleSaveConfig('serverProperties')">保存</button>
</div>
</label>
</div>
<div class="form-group__body">
<table class="table">
<thead>
<tr>
<td>配置名称</td>
<td>配置值</td>
<td>操作列</td>
</tr>
</thead>
<tbody>
<tr v-for="item in form.serverProperties" :key="item.id">
<td><input type="text" v-model="item.key"></td>
<td><input type="text" v-model="item.value"></td>
<td><button @click="handleDeleteServerProperty(item)">删除</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
</div>
</div>
</NuxtLayout>
</template>
<script lang="ts" setup>
const form = ref<Record<string, any>>({
postgres: {
visible: false,
username: '',
password: '',
ip: '',
port: '',
database: '',
schema: ''
},
redis: {
visible: false,
ip: '',
port: ''
},
zookeeper: {
visible: false,
ip: '',
port: ''
},
rocketmq: {
visible: false,
ip: '',
port: ''
},
tenants: {
visible: false,
id: '',
host: '',
'database-schema': '',
'primary-namespace': ''
},
debug: {
host: ''
},
serverProperties: []
})
onMounted(() => {
getData()
})
function getData () {
$fetch('/api/user/getProjectInfo').then((res: any) => {
Object.keys(form.value).forEach(key => {
if (res[key]) {
form.value[key] = res[key]
}
})
})
}
function handleSaveConfig (key: string) {
const value = form.value[key]
console.log(key, value)
$fetch('/api/user/setUserSetting', { method: 'post', body: { key, value } }).then(() => {
alert('保存成功')
}).catch(() => {
alert('保存失败!!!')
})
}
function handleEditConfig (key: string) {
form.value[key].visible = true
}
function handleAddCustomConfig () {
form.value.serverProperties.push({
id: Math.random(),
key: '',
value: ''
})
}
function handleDeleteServerProperty (item: any) {
const index = form.value.serverProperties.indexOf(item)
form.value.serverProperties.splice(index, 1)
}
</script>
<style scoped>
.content{
background-color: #EFEFEF;
overflow: auto;
height: 100%;
padding: 24px;
box-sizing: border-box;
}
.table{
width: 100%;
}
.table thead tr td:nth-of-type(3) {
width: 100px;
}
.table input {
width: 100%;
box-sizing: border-box;
}
</style>
import LogUtil from "~/server/utils/log"
// 检测容器运行状态。如果服务器突然被关停,会导致个人服务一直显示“运行中”,但是实际停掉了
export default defineEventHandler(async (event) => {
try {
// 根据传入的端口号,检测
let username = event.context.username
let docker = createDockerFactory(username)
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
if (!container) {
throw new Error('没有创建容器,请先初始化容器')
}
let info = await container.inspect()
if (info.State.Running) {
// 正在运行,则认为正常
return
} else {
LogUtil.print(username, `[progress] [[1;34mInfo[m] 服务器异常关闭,正在重启...... \n`)
await docker.startContainer({ container })
// 依次打开 nginx, vscode-web
try {
await docker.execContainerCommand({ container, cmd: 'lsof -i:80' })
} catch (err) {
try {
await docker.execContainerCommand({ container, cmd: 'nginx' })
LogUtil.print(username, `[progress] [[1;34mInfo[m] Nginx 重启成功...... \n`)
} catch (err) {
throw err
}
}
try {
await docker.execContainerCommand({ container, cmd: 'lsof -i:8000' })
} catch (err) {
try {
docker.execContainerCommand({ container, cmd: 'code-server --bind-addr 127.0.0.1:8000 --auth none' })
LogUtil.print(username, `[progress] [[1;34mInfo[m] Vscode 重启成功...... \n`)
} catch (err) {
throw err
}
}
try { await docker.execContainerCommand({ container, cmd: 'pm2 delete backend' }) } catch (err) {}
try { await docker.execContainerCommand({ container, cmd: 'pm2 delete gateway' }) } catch (err) {}
try { await docker.execContainerCommand({ container, cmd: 'pm2 delete platform' }) } catch (err) {}
const status = getUserConfig(username, 'status')
if (status === 'running') {
setUserConfig(username, 'status', 'stopped')
}
const statusV1 = getUserConfig(username, 'v1-status')
if (statusV1 === 'running') {
setUserConfig(username, 'v1-status', 'stopped')
}
LogUtil.printSuccess(username, '所有服务重启成功')
}
} catch (err) {
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
import LogUtil from "~/server/utils/log"
import path from 'path'
export default defineEventHandler(async (event) => {
try {
let username = event.context.username
let docker = createDockerFactory(username)
let port = getUserConfig(username, 'node-port')
setUserConfig(username, 'v1-status', 'compiling')
// 每次编译前把已有的 tenants_config 文件夹拷贝到一个地方,编译完成后,再拷贝回来
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
if (!container) {
throw new Error('没有创建容器,请先初始化容器')
}
await docker.startContainer({ container })
await docker.preStartSystem({ container, username, platform: 'v1' })
LogUtil.printInfo(username, '编译中')
const pomDir = '/var/logwire-platform/logwire-build/logwire-server/logwire-libs/logwire-web'
await docker.putArchive({ container, tarPath: path.resolve(__dirname, './files/v1/pomWithoutWeb.tar'), targetPath: pomDir })
await docker.execContainerCommand({ container, cmd: ['/bin/bash', '-c', 'export LANG=zh_CN.UTF-8;mvn clean package -Dmaven.test.skip=true'], dir: '/var/logwire-platform/logwire-build'})
await docker.putArchive({ container, tarPath: path.resolve(__dirname, './files/v1/pomWithWeb.tar'), targetPath: pomDir })
const pomVersionStr = await docker.getFile({ container, path: '/var/logwire-platform/logwire-build/logwire-version/pom.xml' })
const version = /<logwire-starter\.version>(.*?)<\/logwire-starter\.version>/.exec(pomVersionStr)?.[1]
const versionWeb = /<logwire-libs\.version>(.*?)<\/logwire-libs\.version>/.exec(pomVersionStr)?.[1]
const projectDir = getUserConfig(username, 'serverPropertiesV1')?.find((o: { key: string, value: string }) => o.key === 'logwire.tenants[0].dir')?.value?.trim() || './projects/demo'
await docker.execContainerCommand({ container, cmd: 'tar -zvcf ../tenants.tar.gz ./projects/demo', dir: '/var/logwire-platform/dist'})
await docker.execContainerCommand({ container, cmd: 'rm -rf dist', dir: '/var/logwire-platform'})
await docker.execContainerCommand({ container, cmd: 'mkdir -p dist/lib', dir: '/var/logwire-platform'})
await docker.execContainerCommand({ container, cmd: 'mkdir -p dist/config', dir: '/var/logwire-platform'})
await docker.execContainerCommand({ container, cmd: 'mkdir -p dist/products', dir: '/var/logwire-platform'})
await docker.execContainerCommand({ container, cmd: `cp logwire-build/logwire-server/logwire-starter/target/logwire-starter-${version}.jar dist/`, dir: '/var/logwire-platform'})
await docker.execContainerCommand({ container, cmd: `cp logwire-build/logwire-server/logwire-libs/logwire-web/target/logwire-web-${versionWeb}.jar dist/lib/`, dir: '/var/logwire-platform'})
await docker.execContainerCommand({ container, cmd: 'tar -zxvf ../tenants.tar.gz', dir: '/var/logwire-platform/dist'})
await docker.execContainerCommand({ container, cmd: 'rm ../tenants.tar.gz', dir: '/var/logwire-platform/dist'})
await copyAndCreateServerPropertiesV1InDocker(username)
LogUtil.printInfo(username, '编译完成')
setUserConfig(username, 'v1-status', 'created')
} catch (err) {
console.log(err)
let username = event.context.username
setUserConfig(username, 'v1-status', 'created')
LogUtil.printError(username, err instanceof Error ? err.message : JSON.stringify(err))
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
import LogUtil from "~/server/utils/log"
export default defineEventHandler(async (event) => {
try {
let username = event.context.username
let docker = createDockerFactory(username)
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
let port = getUserConfig(username, 'node-port')
LogUtil.printInfo(username, '程序启动中')
if (!container) {
throw new Error('没有创建容器,请先初始化容器')
}
// 读取 pom.xml
const pomVersionStr = await docker.getFile({ container, path: '/var/logwire-platform/logwire-build/logwire-version/pom.xml' })
const version = /<logwire-starter\.version>(.*?)<\/logwire-starter\.version>/.exec(pomVersionStr)?.[1]
const versionWeb = /<logwire-libs\.version>(.*?)<\/logwire-libs\.version>/.exec(pomVersionStr)?.[1]
await docker.preStartSystem({ container, username, platform: 'v1' })
await docker.execContainerCommand({ container, cmd: `pm2 start --name platform --no-autorestart java -- -Xms512m -Xmx512m -XX:MaxMetaspaceSize=200m -Dfile.encoding=UTF-8 -Dloader.path=lib -jar logwire-starter-${version}.jar > logwire.log`, dir: '/var/logwire-platform/dist', quiet: true })
LogUtil.print(username, `[progress] [[1;34mInfo[m] 程序运行中...... \n`)
LogUtil.print(username, `[progress] [[1;34mInfo[m] 请代理后端请求到 <strong>192.168.0.4:${port}</strong> 上 \n`)
setUserConfig(username, 'v1-status', 'running')
} catch (err) {
let username = event.context.username
LogUtil.print(username, '[error] [[1;31mError[m]] ' + (err instanceof Error ? err.message : JSON.stringify(err)))
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
import Dockerode from "dockerode"
import LogUtil from "~/server/utils/log"
import path from 'path'
function sleep (ms: number) {
return new Promise<void>((resolve, reject) => {
setTimeout(resolve, ms)
})
}
export default defineEventHandler(async (event) => {
try {
let username = event.context.username
let docker = createDockerFactory(username)
let host = process.env['DOCKER_ENV']?.trim() === 'prod' ? '192.168.0.4' : 'localhost'
let port = getUserConfig(username, 'node-port').toString()
const statusV2 = getUserConfig(username, 'status')
if (statusV2 === 'null' || statusV2 === undefined) {
throw new Error('请先初始化 V2')
}
setUserConfig(username, 'v1-status', 'creating')
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node') as Dockerode.Container
if (!container) {
throw new Error('没有创建容器,请先初始化容器')
}
// 创建 postgres 不一定要在本机,即使是 dev 环境也可以联远程的容器
await LogUtil.run(username, 'v1-创建 postgres 容器', async () => {
if (getUserConfig(username, 'postgresV1.ip') !== '192.168.0.4') {
let postgres = await docker.checkAndCreateContainer({ name: 'postgres', img: 'postgres:12', env: ["POSTGRES_PASSWORD=postgres"], portBindings: { '5432/tcp': [{ HostPort: '30001' }] } })
let info = await postgres.inspect()
await docker.startContainer({ container: postgres })
if (info?.State.Status === 'created') {
info = await postgres.inspect()
await sleep(3000)
let client = await createPgClient({ host: host, port: 30001 })
await executePgQuery({ client, query: 'CREATE DATABASE logwirev2'})
await executePgQuery({ client, query: 'CREATE SCHEMA library' })
await client.end()
}
} else {
// 如果是服务器环境,检查是否存在对应的数据库表,根据不同用户创建不同的数据库
let postgres = await docker.checkContainer('postgres_12')
if (!postgres) {
throw new Error('没有创建服务器上的 Postgres 容器, 请先创建')
}
const datname = username + '_v1'
let client = await createPgClient({ host: host, port: 25556 })
let result = await executePgQuery({ client, query: "SELECT u.datname FROM pg_catalog.pg_database u where u.datname='" + datname + "';" })
if (result.rows.length === 0) {
await executePgQuery({ client, query: 'CREATE DATABASE ' + datname })
client = await createPgClient({ host: host, port: 25556, database: datname })
await executePgQuery({ client, query: 'CREATE SCHEMA library' })
await client.end()
setUserConfig(username, 'postgresV1.database', datname)
}
}
})
await LogUtil.run(username, 'v1-克隆仓库', async () => {
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' })
})
await LogUtil.run(username, 'v1-安装 openjdk ', async () => {
// 文件过大,已存储到容器 /var 目录下
await docker.putArchive({ container, tarPath: path.resolve('/var/openlogic-openjdk-8u402-b06-linux-x64.tar.gz'), targetPath: '/var' })
await docker.execContainerCommand({ container, cmd: 'cp -r openlogic-openjdk-8u402-b06-linux-x64/ java-8-openjdk', dir: '/var' })
await docker.execContainerCommand({ container, cmd: 'rm -rf openlogic-openjdk-8u402-b06-linux-x64', dir: '/var' })
})
await LogUtil.run(username, 'v1-下载字符集', async () => {
await docker.execContainerCommand({ container, cmd: 'rm /etc/locale.gen'})
await docker.execContainerCommand({ container, cmd: 'touch /etc/locale.gen' })
await docker.writeFile({ container, path: '/etc/locale.gen', text: '\'\nzh_CN.UTF-8 UTF-8\''})
await docker.execContainerCommand({ container, cmd: 'apt-get install -y locales' })
await docker.execContainerCommand({ container, cmd: 'locale-gen', dir: '/etc'})
})
await LogUtil.run(username, 'v1-迁移logwire-demo', async () => {
await docker.execContainerCommand({ container, cmd: 'rm -rf /var/logwire-demo' })
await docker.execContainerCommand({ container, cmd: 'mkdir logwire-demo', dir: '/var'})
await docker.execContainerCommand({ container, cmd: 'mkdir -p dist/projects/demo', dir: '/var/logwire-platform'})
await docker.putArchive({ container, tarPath: path.resolve('/var/book.tar'), targetPath: '/var/logwire-demo' })
await docker.execContainerCommand({ container, cmd: 'tar -zvcf ../book.tar .', dir: '/var/logwire-demo/book'})
await docker.execContainerCommand({ container, cmd: 'tar -zvxf book.tar -C /var/logwire-platform/dist/projects/demo', dir: '/var/logwire-demo'})
})
setUserConfig(username, 'v1-status', 'created')
LogUtil.printSuccess(username, 'installed')
} catch (err: any) {
let username = event.context.username
setUserConfig(username, 'v1-status', 'null')
LogUtil.printError(username, (err instanceof Error ? err.message : JSON.stringify(err)))
setResponseStatus(event, 500)
}
})
\ No newline at end of file
import LogUtil from "~/server/utils/log"
export default defineEventHandler(async (event) => {
try {
let username = event.context.username
let docker = createDockerFactory(username)
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
if (!container) {
throw new Error('没有创建容器,请先初始化容器')
}
LogUtil.printInfo(username, `程序停止中......`)
await docker.execContainerCommand({ container, cmd: 'pm2 delete platform', quiet: true })
LogUtil.printInfo(username, `程序已停止`)
setUserConfig(username, 'v1-status', 'stopped')
} catch (err) {
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
import LogUtil from "~/server/utils/log"
export default defineEventHandler(async (event) => {
try {
let username = event.context.username
let docker = createDockerFactory(username)
// 创建 node 容器
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
let port = getUserConfig(username, 'node-port')
if (container) {
LogUtil.print(username, `[progress] [[1;34mInfo[m] 打包微信小程序zip \n`)
await docker.execContainerCommand({ container, cmd: 'rm -f weapp.zip', dir: '/var/logwire-backend/build-output/backend' })
await docker.execContainerCommand({ container, cmd: `zip -q -r weapp.zip miniapp/main/dist miniapp/main/src/pages miniapp/main/src/app.config.ts`, dir: '/var/logwire-backend/build-output/backend' })
LogUtil.print(username, `[progress] [[1;34mInfo[m] 打包结束,访问 <a target="_blank" href="http://192.168.0.4:${port}/download/backend/">http://192.168.0.4:${port}/download/backend/</a> 下载 webapp.zip 文件 \n`)
} else {
throw new Error('没有创建容器,请先初始化容器')
}
} catch (err) {
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
...@@ -187,9 +187,11 @@ export default defineEventHandler(async (event) => { ...@@ -187,9 +187,11 @@ export default defineEventHandler(async (event) => {
setUserConfig(username, 'status', 'created') setUserConfig(username, 'status', 'created')
LogUtil.printSuccess(username, 'Installed') LogUtil.printSuccess(username, 'Installed')
} catch (err: any) { } catch (err: any) {
console.log(err)
let username = event.context.username let username = event.context.username
setUserConfig(username, 'status', 'null') setUserConfig(username, 'status', 'null')
LogUtil.printError(username, (err instanceof Error ? err.message : JSON.stringify(err))) LogUtil.printError(username, (err instanceof Error ? err.message : JSON.stringify(err)))
setResponseStatus(event, 500) setResponseStatus(event, 500)
return err
} }
}) })
\ No newline at end of file
import { getPlatformRootFolder } from "~/server/utils/server"
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event)
let username = event.context.username
let docker = createDockerFactory(username)
let branch = body.branch
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
const dir = getPlatformRootFolder(body.platform)
if (container) {
await docker.startContainer({ container })
await docker.execContainerCommand({ container, cmd: 'git fetch', dir })
if (branch === 'master') {
await docker.execContainerCommand({ container, cmd: 'git checkout master', dir })
await docker.execContainerCommand({ container, cmd: 'git pull', dir })
} else {
await docker.execContainerCommand({ container, cmd: 'git checkout master', dir })
try {
await docker.execContainerCommand({ container, cmd: 'git branch -D ' + branch, dir })
} catch (err) {
// 有可能没有本地分支,这样删除会报错,但是忽视
}
await docker.execContainerCommand({ container, cmd: 'git checkout ' + branch, dir })
}
} else {
throw new Error('没有创建容器,请先初始化容器')
}
} catch (err) {
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
import { getPlatformRootFolder } from "~/server/utils/server"
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event)
let username = event.context.username
let docker = createDockerFactory(username)
let branch = body.branch
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
const dir = getPlatformRootFolder(body.platform)
if (container) {
await docker.startContainer({ container })
await docker.execContainerCommand({ container, cmd: 'git fetch', dir })
// fetch 时有可能本分支被强推了
if (branch === 'master') {
await docker.execContainerCommand({ container, cmd: 'git pull', dir })
} else {
await docker.execContainerCommand({ container, cmd: 'git checkout master', dir })
await docker.execContainerCommand({ container, cmd: 'git branch -D ' + branch, dir })
await docker.execContainerCommand({ container, cmd: 'git checkout ' + branch, dir })
}
} else {
throw new Error('没有创建容器,请先初始化容器')
}
} catch (err) {
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
export default defineEventHandler(async (event) => {
try{
const body = await readBody(event)
let gitEmail = body.email
let username = event.context.username
let docker = createDockerFactory(username)
// 创建 node 容器
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
if (container) {
await docker.startContainer({ container })
await docker.execContainerCommand({ container, cmd: 'rm -rf /root/.ssh' })
await docker.execContainerCommand({ container, cmd: `ssh-keygen -f /root/.ssh/id_rsa -t ed25519 -C "${gitEmail}"` })
let sshKey = await docker.getFile({ container, path: '/root/.ssh/id_rsa.pub' })
return sshKey
} else {
throw new Error('没有创建容器,请先初始化容器')
}
} catch (err) {
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
import { getPlatformRootFolder } from "~/server/utils/server"
export default defineEventHandler(async (event) => {
try {
const query = getQuery(event)
let username = event.context.username
let docker = createDockerFactory(username)
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
const platform = query.platform as 'v1' | 'v2'
if (container) {
await docker.startContainer({ container })
let result = await docker.execContainerCommand({ container, cmd: 'git branch -a', dir: getPlatformRootFolder(platform) })
result = result.split('\n')
.map(o => o.replace('*', '').trim())
.filter(o => o.startsWith('remotes/origin/'))
.map(o => o.replace('remotes/origin/', ''))
.join('\n')
return removeUnreadCharacter(result)
} else {
throw new Error('没有创建容器,请先初始化容器')
}
} catch (err) {
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
import { getPlatformRootFolder } from "~/server/utils/server"
export default defineEventHandler(async (event) => {
try {
const query = getQuery(event)
const { platform } = query
let username = event.context.username
let docker = createDockerFactory(username)
let container = await docker.checkContainer('logwire_backend_helper.' + username + '.node')
if (container) {
await docker.startContainer({ container })
let result = await docker.execContainerCommand({ container, cmd: 'git branch', dir: getPlatformRootFolder(platform as 'v1' | 'v2') })
const arrays = result.split('\n')
let currentBranch = arrays.find(o => o.includes('*'))
currentBranch = currentBranch?.replace(/^.*?\*/, '').trim() || ''
return removeUnreadCharacter(currentBranch)
} else {
throw new Error('没有创建容器,请先初始化容器')
}
} catch (err) {
setResponseStatus(event, 500)
return err
}
})
\ No newline at end of file
...@@ -14,6 +14,7 @@ export default defineEventHandler(async (event) => { ...@@ -14,6 +14,7 @@ export default defineEventHandler(async (event) => {
userSetting['postgres']['database'] = username userSetting['postgres']['database'] = username
userSetting['tenants']['id'] = username userSetting['tenants']['id'] = username
userSetting['tenants']['host'] = `a.test.com:${23333+ (port - 30000)*2},a.test.com:${23334+(port-30000)*2}` userSetting['tenants']['host'] = `a.test.com:${23333+ (port - 30000)*2},a.test.com:${23334+(port-30000)*2}`
userSetting.username = username
const userDataPath = `./server/data/${username}.json` const userDataPath = `./server/data/${username}.json`
writeJson(userDataPath, userSetting) writeJson(userDataPath, userSetting)
} }
......
import LogUtil from "~/server/utils/log"
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
try { try {
const body = await readBody(event)
const { key, value } = body
let username = event.context.username let username = event.context.username
LogUtil.printInfo(username, '测试消息')
} catch (err) { if (typeof key === 'string') {
setUserConfig(username, key, value)
}
} catch(err) {
setResponseStatus(event, 500) setResponseStatus(event, 500)
return err return err
} }
......
...@@ -3,35 +3,58 @@ ...@@ -3,35 +3,58 @@
"visible": false, "visible": false,
"username": "postgres", "username": "postgres",
"password": "postgres", "password": "postgres",
"ip": "192.168.0.4", "ip": "localhost",
"port": "25556", "port": "25556",
"database": "wyq", "database": "wyq",
"schema": "library" "schema": "library"
}, },
"redis": { "redis": {
"visible": false, "visible": false,
"ip": "192.168.0.4", "ip": "localhost",
"port": "25557" "port": "25557"
}, },
"zookeeper": { "zookeeper": {
"visible": false, "visible": false,
"ip": "192.168.0.4", "ip": "localhost",
"port": "2182" "port": "2182"
}, },
"rocketmq": { "rocketmq": {
"visible": false, "visible": false,
"ip": "192.168.0.4", "ip": "localhost",
"port": "9876" "port": "9876"
}, },
"tenants": { "tenants": {
"visible": false, "visible": false,
"id": "wyq", "id": "wyq",
"host": "a.test.com:23335,a.test.com:23336,a.test.com:29000", "host": "a.test.com:23333,a.test.com:23334",
"database-schema": "library", "database-schema": "library",
"primary-namespace": "library" "primary-namespace": "library"
}, },
"node-port": 30001, "postgresV1": {
"status": "running", "visible": false,
"username": "postgres",
"password": "postgres",
"ip": "192.168.0.4",
"port": "25556",
"database": "logwirev2",
"schema": "library"
},
"redisV1": {
"visible": false,
"ip": "192.168.0.4",
"port": "25557"
},
"tenantsV1": {
"visible": false,
"id": "wongyaqi",
"port": 8080
},
"debug": {
"host": "192.168.1.94"
},
"node-port": 30000,
"username": "wyq",
"status": "creating",
"InstallSteps": [ "InstallSteps": [
"创建 node 容器", "创建 node 容器",
"检查 SSH Key", "检查 SSH Key",
...@@ -47,63 +70,6 @@ ...@@ -47,63 +70,6 @@
"创建 zookeeper 容器", "创建 zookeeper 容器",
"创建 rocketmq serv 容器", "创建 rocketmq serv 容器",
"创建 rocketmq broker 容器", "创建 rocketmq broker 容器",
"克隆仓库", "克隆仓库"
"更新源",
"安装 openjdk ",
"安装 maven ",
"修改 maven 源",
"安装 Wetty",
"安装 code-server ",
"安装 nginx ",
"安装 pm2 ",
"配置 nginx ",
"启动 wetty",
"启动 code-server ",
"启动 nginx ",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"初始化调试功能",
"v1-创建 postgres 容器",
"v1-克隆仓库",
"v1-创建 postgres 容器",
"v1-克隆仓库",
"v1-安装 openjdk ",
"v1-更换JDK"
],
"debug": {
"host": "192.168.1.94"
},
"serverProperties": [
{
"id": 0.9830334059659578,
"key": "logwire.security.encryption.key-management-system",
"value": "logwire-kms"
},
{
"id": 0.7282073911484346,
"key": "logwire.security.encryption.logwire-kms.master-key-passwords[0]",
"value": "logwire"
}
],
"v1-status": "created",
"postgresV1": {
"visible": false,
"username": "postgres",
"password": "postgres",
"ip": "192.168.0.4",
"port": "25556",
"database": "wyq_v1",
"schema": "library"
},
"serverPropertiesV1": [
{
"id": 0.7463455633624243,
"key": "logwire.tenants[0].designer.password",
"value": "c4ca4238a0b923820dcc509a6f75849b"
}
] ]
} }
\ No newline at end of file
...@@ -12,6 +12,7 @@ export default defineNitroPlugin((nitroApp: NitroApp) => { ...@@ -12,6 +12,7 @@ export default defineNitroPlugin((nitroApp: NitroApp) => {
io.on("connection", (socket: any) => { io.on("connection", (socket: any) => {
let username = socket.handshake.auth['username'] let username = socket.handshake.auth['username']
console.log('connected success!', username)
setWebsocketIo(username, socket) setWebsocketIo(username, socket)
}); });
......
...@@ -43,7 +43,7 @@ export function getUserAllConfigs (username: string): Record<string, string> { ...@@ -43,7 +43,7 @@ export function getUserAllConfigs (username: string): Record<string, string> {
} }
export function setUserConfig (username: string, config: string, value: any) { export function setUserConfig (username: string, config: string, value: any) {
let jsonPath = path.resolve(__dirname, './database/' + username + '.json') let jsonPath = path.resolve('./server/data/' + username + '.json')
let jsonStr = fs.readFileSync(jsonPath, { encoding: 'utf-8' }) let jsonStr = fs.readFileSync(jsonPath, { encoding: 'utf-8' })
let json = JSON.parse(jsonStr) || {} let json = JSON.parse(jsonStr) || {}
let newJson = lodash.set(json, config, value) let newJson = lodash.set(json, config, value)
...@@ -78,9 +78,9 @@ export async function copyAndCreateServerPropertiesV2InDocker (username: string) ...@@ -78,9 +78,9 @@ export async function copyAndCreateServerPropertiesV2InDocker (username: string)
throw new Error('没有创建容器,请先初始化容器') throw new Error('没有创建容器,请先初始化容器')
} }
let backendText = fs.readFileSync(path.resolve(__dirname, './files/application-server.properties'), { encoding: 'utf-8' }) let backendText = fs.readFileSync(path.resolve('./files/application-server.properties'), { encoding: 'utf-8' })
const userDefaultSettingStr = fs.readFileSync(path.resolve(__dirname, './files/default-user-setting.json'), { encoding: 'utf-8'}) const userDefaultSettingStr = fs.readFileSync(path.resolve('./files/default-user-setting.json'), { encoding: 'utf-8'})
const userConfigsStr = fs.readFileSync(path.resolve(__dirname, './database/' + username + '.json'), { encoding: 'utf-8'}) const userConfigsStr = fs.readFileSync(path.resolve('./database/' + username + '.json'), { encoding: 'utf-8'})
const userDefaultSetting = JSON.parse(userDefaultSettingStr) const userDefaultSetting = JSON.parse(userDefaultSettingStr)
const userConfigs = JSON.parse(userConfigsStr) const userConfigs = JSON.parse(userConfigsStr)
...@@ -129,9 +129,9 @@ export async function copyAndCreateGatewayPropertiesV2InDocker (username: string ...@@ -129,9 +129,9 @@ export async function copyAndCreateGatewayPropertiesV2InDocker (username: string
if (!container) { if (!container) {
throw new Error('没有创建容器,请先初始化容器') throw new Error('没有创建容器,请先初始化容器')
} }
let gatewayText = fs.readFileSync(path.resolve(__dirname, './files/application-gateway.properties'), { encoding: 'utf-8' }) let gatewayText = fs.readFileSync(path.resolve('./files/application-gateway.properties'), { encoding: 'utf-8' })
const userDefaultSettingStr = fs.readFileSync(path.resolve(__dirname, './files/default-user-setting.json'), { encoding: 'utf-8'}) const userDefaultSettingStr = fs.readFileSync(path.resolve('./files/default-user-setting.json'), { encoding: 'utf-8'})
const userConfigsStr = fs.readFileSync(path.resolve(__dirname, './database/' + username + '.json'), { encoding: 'utf-8'}) const userConfigsStr = fs.readFileSync(path.resolve('./database/' + username + '.json'), { encoding: 'utf-8'})
const userDefaultSetting = JSON.parse(userDefaultSettingStr) const userDefaultSetting = JSON.parse(userDefaultSettingStr)
const userConfigs = JSON.parse(userConfigsStr) const userConfigs = JSON.parse(userConfigsStr)
...@@ -151,9 +151,9 @@ export async function copyAndCreateServerPropertiesV1InDocker (username: string) ...@@ -151,9 +151,9 @@ export async function copyAndCreateServerPropertiesV1InDocker (username: string)
if (!container) { if (!container) {
throw new Error('没有创建容器,请先初始化容器') throw new Error('没有创建容器,请先初始化容器')
} }
let backendText = fs.readFileSync(path.resolve(__dirname, './files/v1/application.properties'), { encoding: 'utf-8' }) let backendText = fs.readFileSync(path.resolve('./files/v1/application.properties'), { encoding: 'utf-8' })
const userDefaultSettingStr = fs.readFileSync(path.resolve(__dirname, './files/default-user-setting.json'), { encoding: 'utf-8'}) const userDefaultSettingStr = fs.readFileSync(path.resolve('./files/default-user-setting.json'), { encoding: 'utf-8'})
const userConfigsStr = fs.readFileSync(path.resolve(__dirname, './database/' + username + '.json'), { encoding: 'utf-8'}) const userConfigsStr = fs.readFileSync(path.resolve('./database/' + username + '.json'), { encoding: 'utf-8'})
const userDefaultSetting = JSON.parse(userDefaultSettingStr) const userDefaultSetting = JSON.parse(userDefaultSettingStr)
const userConfigs = JSON.parse(userConfigsStr) const userConfigs = JSON.parse(userConfigsStr)
...@@ -190,13 +190,19 @@ export async function copyAndCreateNginxConfInDocker (username: string) { ...@@ -190,13 +190,19 @@ export async function copyAndCreateNginxConfInDocker (username: string) {
if (!container) { if (!container) {
throw new Error('没有创建容器,请先初始化容器') throw new Error('没有创建容器,请先初始化容器')
} }
const userDefaultSettingStr = fs.readFileSync(path.resolve(__dirname, './files/default-user-setting.json'), { encoding: 'utf-8'}) const userDefaultSettingStr = fs.readFileSync(path.resolve('./files/default-user-setting.json'), { encoding: 'utf-8'})
const userConfigsStr = fs.readFileSync(path.resolve(__dirname, './database/' + username + '.json'), { encoding: 'utf-8'}) const userConfigsStr = fs.readFileSync(path.resolve('./database/' + username + '.json'), { encoding: 'utf-8'})
const userDefaultSetting = JSON.parse(userDefaultSettingStr) const userDefaultSetting = JSON.parse(userDefaultSettingStr)
const userConfigs = JSON.parse(userConfigsStr) const userConfigs = JSON.parse(userConfigsStr)
const nginxConfigStr = fs.readFileSync(path.resolve(__dirname, './files/nginx.conf'), { encoding: 'utf-8' }) const nginxConfigStr = fs.readFileSync(path.resolve('./files/nginx.conf'), { encoding: 'utf-8' })
// 修改调试端口的 NGINX 配置 // 修改调试端口的 NGINX 配置
const replacedNginxConfig = nginxConfigStr.replace(/192.168.1.94/, userConfigs?.debug?.host || userDefaultSetting.debug.host) const replacedNginxConfig = nginxConfigStr.replace(/192.168.1.94/, userConfigs?.debug?.host || userDefaultSetting.debug.host)
await docker.writeFile({ container, path: '/etc/nginx/nginx.conf', text: '\'' + replacedNginxConfig + '\'' }) await docker.writeFile({ container, path: '/etc/nginx/nginx.conf', text: '\'' + replacedNginxConfig + '\'' })
}
export function getPlatformRootFolder (platform: 'v1' | 'v2') {
return platform === 'v1'
? '/var/logwire-platform'
: '/var/logwire-backend'
} }
\ No newline at end of file
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