refactor: container

This commit is contained in:
wancat committed 2024-02-19 18:23:52 +08:00
1 parent 075e21fb89
commit 64215d3ef1
7 files changed
+125 -21

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@
"app": "yarn workspace app dev",
"app:local": "yarn workspace app dev:local",
"build": "yarn workspaces foreach -Apt run build",
"dev": "yarn workspaces foreach -Api --include '{server,app}' run watch",
"dev": "yarn workspaces foreach -Api --include '{server,app}' run dev",
"server": "yarn workspace server dev",
"cli": "yarn workspace client start",
"lint": "eslint .",
+3 -3
View File
@@ -1,10 +1,10 @@
import mongoose from 'mongoose'
export { User } from './user.js'
export { User, IUser } from './user.js'
export { Quest, IQuest } from './quest.js'
export { Session } from './session.js'
export { Session, ISession } from './session.js'
export { Command, ICommand } from './command.js'
export { UserProfile } from './userProfile.js'
export { UserProfile, IUserProfile } from './userProfile.js'
export default async function connectDB(uri: string) {
const db = await mongoose.connect(uri)
+1 -1
View File
@@ -44,7 +44,7 @@ const taskSchema = new Schema<ITask>({
export interface ISession {
user: Types.ObjectId
quest: string
containerId: string
containerId: string | null
status: string
createdAt: Date
updatedAt: Date
+2
View File
@@ -45,9 +45,11 @@
},
"devDependencies": {
"@types/bcrypt": "^5.0.2",
"@types/dockerode": "^3.3.23",
"@types/express": "^4.17.21",
"@types/express-session": "^1.17.10",
"@types/jsonwebtoken": "^9.0.5",
"@types/node-schedule": "^2.1.6",
"@types/passport": "^1.0.16",
"@types/passport-github2": "^1.2.9",
"@types/passport-jwt": "^4.0.1",
@@ -14,9 +14,12 @@ const containerOptions = {
HostConfig: {
NetworkMode: config.docker.network,
},
}
} as Docker.ContainerCreateOptions
export function createContainer(name, questId) {
export function createContainer(
name: string,
questId: string
): Promise<Docker.Container> {
const option = {
...containerOptions,
name,
@@ -25,7 +28,7 @@ export function createContainer(name, questId) {
const { hostPwd, mountQuest } = config.docker
if (!config.isProduction && hostPwd && mountQuest === questId) {
logger.info('Mounting quest folder', mountQuest)
option.HostConfig.Binds = [
option.HostConfig!.Binds = [
`${hostPwd}/quests/${mountQuest}/home:/home/commander`,
`${hostPwd}/packages/container:/usr/local/lib/container`,
]
@@ -33,7 +36,9 @@ export function createContainer(name, questId) {
return engine.createContainer(option)
}
export async function getAndStartContainer(id) {
export async function getAndStartContainer(
id: string
): Promise<Docker.Container> {
logger.debug(`Getting container: ${id}`)
const container = engine.getContainer(id)
if (!container) {
@@ -45,7 +50,10 @@ export async function getAndStartContainer(id) {
return container
}
export async function attachContainer(container, { token }) {
export async function attachContainer(
container: Docker.Container,
{ token }: { token: string }
) {
const exec = await container.exec({
AttachStdin: true,
AttachStdout: true,
@@ -67,7 +75,7 @@ export async function attachContainer(container, { token }) {
return execOutput
}
export async function deleteContainer(id) {
export async function deleteContainer(id: string) {
const container = engine.getContainer(id)
if (!container) {
return
@@ -80,8 +88,8 @@ export async function deleteContainer(id) {
await container.remove()
}
function parseJSONOutput(data) {
const { stream, error } = JSON.parse(data.toString())
function parseJSONOutput(data: string) {
const { stream, error } = JSON.parse(data)
if (stream) {
// eslint-disable-next-line no-console
console.log(stream)
@@ -91,7 +99,7 @@ function parseJSONOutput(data) {
}
}
export function buildQuestImage(questPath, questId) {
export function buildQuestImage(questPath: string, questId: string) {
return new Promise((resolve, reject) => {
engine.buildImage(
{
@@ -114,9 +122,9 @@ export function buildQuestImage(questPath, questId) {
data
.toString()
.split('\n')
.map((line) => line.trim())
.filter((line) => line !== '')
.forEach((line) => {
.map((line: string) => line.trim())
.filter((line: string) => line !== '')
.forEach((line: string) => {
parseJSONOutput(line)
})
} catch (error) {
@@ -1,19 +1,31 @@
import schedule from 'node-schedule'
import { Session } from '@linux-odyssey/models'
import type { ISession } from '@linux-odyssey/models'
import type { HydratedDocument } from 'mongoose'
import config from '../config.js'
import { deleteContainer } from './docker.js'
import logger from '../utils/logger.js'
async function disableSession(session) {
async function disableSession(session: HydratedDocument<ISession>) {
if (!session.containerId) {
logger.warn(`Deleting session ${session._id} has no containerId`)
return
}
try {
await deleteContainer(session.containerId)
} catch (err) {
// If the container doesn't exist, we can ignore the error
if (err.statusCode !== 404) {
// Perform runtime check to safely access statusCode
if (typeof err === 'object' && err !== null && 'statusCode' in err) {
const error = err as { statusCode: number }
if (error.statusCode !== 404) {
throw new Error(
`Failed to delete container ${session.containerId} for session ${session._id}`
)
}
} else {
// Handle the case where err is not the expected type
logger.error(`An unexpected error occurred: ${err}`)
}
}
if (session.status === 'active') {
session.status = 'inactive'
+83 -1
View File
@@ -1110,10 +1110,19 @@ __metadata:
languageName: unknown
linkType: soft
"@linux-odyssey/models@npm:*, @linux-odyssey/models@workspace:packages/models":
"@linux-odyssey/game@workspace:packages/game":
version: 0.0.0-use.local
resolution: "@linux-odyssey/game@workspace:packages/game"
dependencies:
"@linux-odyssey/models": "workspace:^"
languageName: unknown
linkType: soft
"@linux-odyssey/models@npm:*, @linux-odyssey/models@workspace:^, @linux-odyssey/models@workspace:packages/models":
version: 0.0.0-use.local
resolution: "@linux-odyssey/models@workspace:packages/models"
dependencies:
"@types/mongoose": "npm:^5.11.97"
mongoose: "npm:^8.0.3"
languageName: unknown
linkType: soft
@@ -1395,6 +1404,26 @@ __metadata:
languageName: node
linkType: hard
"@types/docker-modem@npm:*":
version: 3.0.6
resolution: "@types/docker-modem@npm:3.0.6"
dependencies:
"@types/node": "npm:*"
"@types/ssh2": "npm:*"
checksum: 10c0/d3ffd273148bc883ff9b1a972b1f84c1add6d9a197d2f4fc9774db4c814f39c2e51cc649385b55d781c790c16fb0bf9c1f4c62499bd0f372a4b920190919445d
languageName: node
linkType: hard
"@types/dockerode@npm:^3.3.23":
version: 3.3.23
resolution: "@types/dockerode@npm:3.3.23"
dependencies:
"@types/docker-modem": "npm:*"
"@types/node": "npm:*"
checksum: 10c0/b6bdb2851487ac7168d2a790ef35b50f0521cbf01e636feaca8f7192fe9c4c687c22f71c56767f41b25ceb87d60ebbc052c1e28c6f7d6cc7a69327050569c863
languageName: node
linkType: hard
"@types/express-serve-static-core@npm:^4.17.33":
version: 4.17.43
resolution: "@types/express-serve-static-core@npm:4.17.43"
@@ -1516,6 +1545,24 @@ __metadata:
languageName: node
linkType: hard
"@types/mongoose@npm:^5.11.97":
version: 5.11.97
resolution: "@types/mongoose@npm:5.11.97"
dependencies:
mongoose: "npm:*"
checksum: 10c0/333e692a39734948db700c76f25c7b088f46cb88ba940b80467313acf29752823ff9ed2870045c34e00559c38a4a3b5136ae6634da6dbe56c160a16a50e1dea0
languageName: node
linkType: hard
"@types/node-schedule@npm:^2.1.6":
version: 2.1.6
resolution: "@types/node-schedule@npm:2.1.6"
dependencies:
"@types/node": "npm:*"
checksum: 10c0/5b8f810abf1738f4114c771434ebd17b6ec4f5e29d9f4ca4085b7b5d016f88dd6d99c7fa5c9e0d8583a52781e7ab579f34adfd6927071aa03168b44d9d75e7fd
languageName: node
linkType: hard
"@types/node@npm:*, @types/node@npm:>=10.0.0, @types/node@npm:^20.10.4":
version: 20.11.16
resolution: "@types/node@npm:20.11.16"
@@ -1525,6 +1572,15 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^18.11.18":
version: 18.19.17
resolution: "@types/node@npm:18.19.17"
dependencies:
undici-types: "npm:~5.26.4"
checksum: 10c0/ac2e4910d5f2bb92cb2623f6d4d4d665a39cf1d425993347e6c3756c70a4def21a47241b86f49e1e4f441529753527bbd9be5f08f29fdac38c64035a26b847c7
languageName: node
linkType: hard
"@types/oauth@npm:*":
version: 0.9.4
resolution: "@types/oauth@npm:0.9.4"
@@ -1652,6 +1708,15 @@ __metadata:
languageName: node
linkType: hard
"@types/ssh2@npm:*":
version: 1.11.19
resolution: "@types/ssh2@npm:1.11.19"
dependencies:
"@types/node": "npm:^18.11.18"
checksum: 10c0/d1a6f8bff3602ea40be0f9b41f2c80bdd8debbda412b50cda5d7b973ef3921ede60123ea0c48c9e202d96d71c7dc05c9019b5736e8b2ddc6c457c557f602453e
languageName: node
linkType: hard
"@types/stack-utils@npm:^2.0.0":
version: 2.0.3
resolution: "@types/stack-utils@npm:2.0.3"
@@ -7178,6 +7243,21 @@ __metadata:
languageName: node
linkType: hard
"mongoose@npm:*":
version: 8.1.3
resolution: "mongoose@npm:8.1.3"
dependencies:
bson: "npm:^6.2.0"
kareem: "npm:2.5.1"
mongodb: "npm:6.3.0"
mpath: "npm:0.9.0"
mquery: "npm:5.0.0"
ms: "npm:2.1.3"
sift: "npm:16.0.1"
checksum: 10c0/68cf62251b245fb3f9867f0f66895b751f688dcda4c3b9b9016754ad6d78428535d7a4094f013e6e4545158ed2d766aea94aff4478b7a2e3876cefe79a59447c
languageName: node
linkType: hard
"mongoose@npm:^8.0.3":
version: 8.1.1
resolution: "mongoose@npm:8.1.1"
@@ -8530,9 +8610,11 @@ __metadata:
"@linux-odyssey/models": "npm:*"
"@linux-odyssey/utils": "npm:*"
"@types/bcrypt": "npm:^5.0.2"
"@types/dockerode": "npm:^3.3.23"
"@types/express": "npm:^4.17.21"
"@types/express-session": "npm:^1.17.10"
"@types/jsonwebtoken": "npm:^9.0.5"
"@types/node-schedule": "npm:^2.1.6"
"@types/passport": "npm:^1.0.16"
"@types/passport-github2": "npm:^1.2.9"
"@types/passport-jwt": "npm:^4.0.1"