mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-05 19:20:12 +08:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e37b13d99 | ||
|
|
b2a251576c | ||
|
|
8cc006e3a4 | ||
|
|
d6ae6d818d | ||
|
|
6692ae2b9b | ||
|
|
fab02d03a9 | ||
|
|
9e44ebe415 | ||
|
|
019caf58e4 |
No files matched your search
+1
-1
@@ -3,6 +3,7 @@ PORT=3000
|
||||
BASE_URL=https://example.com
|
||||
SECRET_KEY=YOU_SHOULD_CHANGE_THIS
|
||||
BACKEND_URL=http://backend:3000
|
||||
DOCKER_NETWORK=linux-odyssey-players
|
||||
|
||||
MONGO_ROOT_PASSWORD=adminpassword
|
||||
MONGO_USER=commander
|
||||
@@ -29,7 +30,6 @@ ADMIN_PORT=3001
|
||||
# GITHUB_CLIENT_SECRET=
|
||||
# SURVEY_URL=
|
||||
# BUG_REPORT_URL=
|
||||
# DOCKER_NETWORK=
|
||||
|
||||
# SURVEY_URL=
|
||||
# BUG_REPORT_URL=
|
||||
|
||||
+1
-1
@@ -3,6 +3,7 @@ PORT=3000
|
||||
BASE_URL=http://localhost:5173
|
||||
MONGO_URL=mongodb://localhost:27017/odyssey-test
|
||||
SECRET_KEY=sample-secret
|
||||
DOCKER_NETWORK=linux-odyssey-players-dev
|
||||
|
||||
# Optional
|
||||
# BACKEND_URL=http://host.docker.internal:3000
|
||||
@@ -17,7 +18,6 @@ SECRET_KEY=sample-secret
|
||||
# GITHUB_CLIENT_SECRET=
|
||||
# SURVEY_URL=
|
||||
# BUG_REPORT_URL=
|
||||
# DOCKER_NETWORK=
|
||||
|
||||
# SURVEY_URL=
|
||||
# BUG_REPORT_URL=
|
||||
|
||||
+3
-4
@@ -13,7 +13,7 @@ services:
|
||||
base:
|
||||
image: linuxodyssey/quest-base
|
||||
networks:
|
||||
- players
|
||||
- players-dev
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./quests/Dockerfile
|
||||
@@ -22,7 +22,6 @@ services:
|
||||
|
||||
networks:
|
||||
internal:
|
||||
players:
|
||||
name: linux-odyssey-players
|
||||
players-dev:
|
||||
name: linux-odyssey-players-dev
|
||||
internal: false
|
||||
external: true
|
||||
+29
-8
@@ -1,24 +1,39 @@
|
||||
PROMPT='%F{2}%n%f:%F{6}%~%f $ '
|
||||
unsetopt CASE_GLOB
|
||||
setopt CHASE_LINKS
|
||||
emulate bash
|
||||
# emulate bash
|
||||
|
||||
set +o prompt_cr
|
||||
|
||||
preexec() {
|
||||
export CMD_START_TIME=$(date +%s%N) # capture start time
|
||||
export CMD_NAME=$1 # capture command
|
||||
export CMD_NAME="$1" # capture command
|
||||
export CMD_PID=$$
|
||||
|
||||
# A list of interactive commands
|
||||
interactive_commands=("vim" "nano" "top" "ssh" "less" "zsh" "bash")
|
||||
# # A list of interactive commands
|
||||
# readlink /proc/$PPID/exe
|
||||
interactive_commands=("vim" "nano" "top" "ssh" "less" "zsh" "bash" "script" "exec")
|
||||
# # if [[ $CMD_EXECUTED = 1 ]]; then
|
||||
# # export CMD_EXECUTED=0
|
||||
# # return
|
||||
# # fi
|
||||
|
||||
# Check if the command is in the list of interactive commands
|
||||
# # Check if the command is in the list of interactive commands
|
||||
if [[ " ${interactive_commands[@]} " =~ " $1 " ]]; then
|
||||
# If it is, just execute it normally
|
||||
exec
|
||||
# exec
|
||||
# echo IF
|
||||
return
|
||||
else
|
||||
# If it's not, execute it and redirect its output to a file
|
||||
exec > >(tee /tmp/cmd.out) 2> >(tee /tmp/cmd.error >&2)
|
||||
# exec > >(tee /tmp/cmd.out) 2> >(tee /tmp/cmd.error >&2)
|
||||
# echo ELSE
|
||||
# export CMD_EXECUTED=1
|
||||
# eval >&1 >/tmp/cmd.out
|
||||
# exec >&1
|
||||
# exec
|
||||
script --quiet -O /tmp/cmd.out -c "$CMD_NAME"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -29,7 +44,12 @@ precmd() {
|
||||
export CMD_ERROR_FILE=/tmp/cmd.error
|
||||
|
||||
# Now run your Node.js script with the result as an argument
|
||||
node /usr/local/lib/container/cli.js; rm /tmp/cmd.out /tmp/cmd.error 2>/dev/null
|
||||
node /usr/local/lib/container/cli.js
|
||||
if [[ -n $CMD_PID ]]; then
|
||||
# echo $CMD_PID
|
||||
# kill $CMD_PID
|
||||
fi
|
||||
# rm /tmp/cmd.out /tmp/cmd.error 2>/dev/null
|
||||
|
||||
# Reset variables
|
||||
unset CMD_START_TIME
|
||||
@@ -38,5 +58,6 @@ precmd() {
|
||||
unset CMD_OUTPUT_FILE
|
||||
unset CMD_ERROR_FILE
|
||||
unset CMD_NAME
|
||||
export CMD_EXECUTED=0
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ stages:
|
||||
command:
|
||||
- ^cp hello.txt hello2.txt$
|
||||
files:
|
||||
- path: hello2.txt
|
||||
- path: /home/commander/hello2.txt
|
||||
type: file
|
||||
exceptions:
|
||||
- condition:
|
||||
@@ -224,7 +224,7 @@ stages:
|
||||
command:
|
||||
- ^cp world.txt world2.txt$
|
||||
files:
|
||||
- path: world2.txt
|
||||
- path: /home/commander/world2.txt
|
||||
type: file
|
||||
exceptions:
|
||||
- condition:
|
||||
@@ -292,9 +292,9 @@ stages:
|
||||
command:
|
||||
- ^cp
|
||||
files:
|
||||
- path: notes2
|
||||
- path: /home/commander/notes2
|
||||
type: directory
|
||||
- path: notes2/note.txt
|
||||
- path: /home/commander/notes2/note.txt
|
||||
type: file
|
||||
exceptions:
|
||||
- condition:
|
||||
|
||||
@@ -44,12 +44,12 @@ stages:
|
||||
- ls
|
||||
condition:
|
||||
files:
|
||||
- path: hello.txt
|
||||
- path: /home/commander/hello.txt
|
||||
type: file
|
||||
exceptions:
|
||||
- condition:
|
||||
files:
|
||||
- path: hello$
|
||||
- path: /home/commander/hello
|
||||
type: file
|
||||
responses:
|
||||
- type: narrative
|
||||
@@ -107,12 +107,12 @@ stages:
|
||||
- ls-touch
|
||||
condition:
|
||||
files:
|
||||
- path: world.txt
|
||||
- path: /home/commander/world.txt
|
||||
type: file
|
||||
exceptions:
|
||||
- condition:
|
||||
files:
|
||||
- path: world$
|
||||
- path: /home/commander/world
|
||||
type: file
|
||||
responses:
|
||||
- type: narrative
|
||||
@@ -154,7 +154,7 @@ stages:
|
||||
- ls-2
|
||||
condition:
|
||||
files:
|
||||
- path: notes
|
||||
- path: /home/commander/notes
|
||||
type: folder
|
||||
responses:
|
||||
- type: narrative
|
||||
@@ -203,7 +203,7 @@ stages:
|
||||
- cd-notes
|
||||
condition:
|
||||
files:
|
||||
- path: notes/note.txt
|
||||
- path: /home/commander/notes/note.txt
|
||||
type: file
|
||||
responses:
|
||||
- type: narrative
|
||||
|
||||
@@ -49,9 +49,9 @@ stages:
|
||||
command:
|
||||
- ^mv hello.txt notes$
|
||||
files:
|
||||
- path: notes/hello.txt
|
||||
- path: /home/commander/notes/hello.txt
|
||||
type: file
|
||||
- path: hello.txt
|
||||
- path: /home/commander/hello.txt
|
||||
exists: false
|
||||
responses:
|
||||
- type: narrative
|
||||
@@ -106,9 +106,9 @@ stages:
|
||||
command:
|
||||
- ^mv
|
||||
files:
|
||||
- path: wow.txt
|
||||
- path: /home/commander/wow.txt
|
||||
type: file
|
||||
- path: world.txt
|
||||
- path: /home/commander/world.txt
|
||||
exists: false
|
||||
responses:
|
||||
- type: narrative
|
||||
@@ -148,9 +148,9 @@ stages:
|
||||
command:
|
||||
- ^mv
|
||||
files:
|
||||
- path: docs
|
||||
- path: /home/commander/docs
|
||||
type: directory
|
||||
- path: notes
|
||||
- path: /home/commander/notes
|
||||
exists: false
|
||||
responses:
|
||||
- type: narrative
|
||||
@@ -187,9 +187,9 @@ stages:
|
||||
command:
|
||||
- ^mv
|
||||
files:
|
||||
- path: hi.txt
|
||||
- path: /home/commander/hi.txt
|
||||
type: file
|
||||
- path: docs/hello.txt
|
||||
- path: /home/commander/docs/hello.txt
|
||||
exists: false
|
||||
exceptions:
|
||||
- condition:
|
||||
|
||||
+10
-10
@@ -44,7 +44,7 @@ stages:
|
||||
command:
|
||||
- ^rm\s
|
||||
files:
|
||||
- path: hello.txt
|
||||
- path: /home/commander/hello.txt
|
||||
exists: false
|
||||
responses:
|
||||
- content: |
|
||||
@@ -58,7 +58,7 @@ stages:
|
||||
command:
|
||||
- ^ls$
|
||||
files:
|
||||
- path: hello.txt
|
||||
- path: /home/commander/hello.txt
|
||||
exists: false
|
||||
responses:
|
||||
- content: |
|
||||
@@ -78,9 +78,9 @@ stages:
|
||||
command:
|
||||
- ^rm
|
||||
files:
|
||||
- path: world.txt
|
||||
- path: /home/commander/world.txt
|
||||
exists: false
|
||||
- path: wow.txt
|
||||
- path: /home/commander/wow.txt
|
||||
exists: false
|
||||
responses:
|
||||
- content: |
|
||||
@@ -111,7 +111,7 @@ stages:
|
||||
command:
|
||||
- ^rmdir empty$
|
||||
files:
|
||||
- path: empty
|
||||
- path: /home/commander/empty
|
||||
exists: false
|
||||
responses:
|
||||
- content: |
|
||||
@@ -139,7 +139,7 @@ stages:
|
||||
command:
|
||||
- ^rmdir notes$
|
||||
files:
|
||||
- path: notes
|
||||
- path: /home/commander/notes
|
||||
type: folder
|
||||
exists: true
|
||||
responses:
|
||||
@@ -161,10 +161,10 @@ stages:
|
||||
command:
|
||||
- ^rm
|
||||
files:
|
||||
- path: notes
|
||||
- path: /home/commander/notes
|
||||
type: folder
|
||||
exists: true
|
||||
- path: notes/note.txt
|
||||
- path: /home/commander/notes/note.txt
|
||||
exists: false
|
||||
exceptions:
|
||||
- condition:
|
||||
@@ -203,7 +203,7 @@ stages:
|
||||
task: 使用 `rmdir` 刪除 `notes` 資料夾
|
||||
condition:
|
||||
files:
|
||||
- path: notes
|
||||
- path: /home/commander/notes
|
||||
exists: false
|
||||
responses:
|
||||
- content: |
|
||||
@@ -238,7 +238,7 @@ stages:
|
||||
command:
|
||||
- ^rm -r trash$
|
||||
files:
|
||||
- path: trash
|
||||
- path: /home/commander/trash
|
||||
exists: false
|
||||
responses:
|
||||
- content: |
|
||||
|
||||
@@ -8,6 +8,7 @@ import { asyncHandler } from '../../middleware/error.js'
|
||||
|
||||
export const newCommand = asyncHandler(async (req: Request, res: Response) => {
|
||||
const { command, pwd, output, error, params } = matchedData(req)
|
||||
console.log(command, output, error)
|
||||
|
||||
const { sessionId } = req.user as any
|
||||
const session = await Session.findById(sessionId)
|
||||
|
||||
@@ -72,7 +72,7 @@ function createConfig() {
|
||||
projectRoot,
|
||||
|
||||
docker: {
|
||||
network: get('DOCKER_NETWORK', 'linux-odyssey-players'),
|
||||
network: get('DOCKER_NETWORK', 'linux-odyssey-players-dev'),
|
||||
defaultImage: get('QUEST_IMAGE', 'linuxodyssey/quest-base'),
|
||||
imagePrefix: get('DOCKER_PREFIX', 'linuxodyssey/quest-'),
|
||||
mountQuest: process.env.MOUNT_QUEST === 'true',
|
||||
|
||||
@@ -33,6 +33,9 @@ export async function createContainer(
|
||||
imageId: string
|
||||
): Promise<Docker.Container> {
|
||||
let binds: string[] = []
|
||||
binds.push(
|
||||
`${config.docker.hostProjectRoot}/quests/.includes/zshrc:/etc/zsh/zshrc`
|
||||
)
|
||||
if (await questHomeExists(questId)) {
|
||||
logger.info('Mounting quest home', questId)
|
||||
binds.push(
|
||||
@@ -94,20 +97,21 @@ export async function attachContainer(
|
||||
config.docker.network
|
||||
].IPAddress
|
||||
|
||||
let error: Error | null = null
|
||||
for (let i = 0; i < 10; i++) {
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const stream = await connectToSSH(containerIp, { token })
|
||||
return stream
|
||||
} catch (err) {
|
||||
logger.error('Failed to connect to SSH', err)
|
||||
error = err as Error
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000)
|
||||
})
|
||||
}
|
||||
}
|
||||
throw new Error('Failed to connect to SSH')
|
||||
throw new Error('Failed to connect to SSH', { cause: error })
|
||||
}
|
||||
|
||||
export async function deleteContainer(id: string) {
|
||||
|
||||
Reference in new issue
Block a user