mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-05 19:20:12 +08:00
feat: new cli client to send and receive msg from api
This commit is contained in:
1 parent
e2e585329f
commit
0153eae673
5 files changed
+93
-17
No files matched your search
@@ -0,0 +1,7 @@
|
||||
version: '3'
|
||||
services:
|
||||
helloworld:
|
||||
image: lancatlin/linux-odyssey:helloworld
|
||||
build:
|
||||
context: .
|
||||
dockerfile: server/quests/helloworld/Dockerfile
|
||||
@@ -0,0 +1,70 @@
|
||||
const readline = require('readline')
|
||||
|
||||
process.stdin.setRawMode(true)
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
terminal: false,
|
||||
})
|
||||
|
||||
async function printResponses(responses, delay = 100) {
|
||||
for (const response of responses) {
|
||||
await printResponse(response, delay)
|
||||
}
|
||||
rl.close()
|
||||
}
|
||||
|
||||
function waitForEnter() {
|
||||
return new Promise((resolve) => {
|
||||
rl.once('line', resolve)
|
||||
})
|
||||
}
|
||||
|
||||
function printResponse(response, delay) {
|
||||
return new Promise((resolve) => {
|
||||
let i = 0
|
||||
const timer = setInterval(() => {
|
||||
process.stdout.write(response[i])
|
||||
i += 1
|
||||
if (i >= response.length) {
|
||||
clearInterval(timer)
|
||||
waitForEnter().then(resolve)
|
||||
}
|
||||
}, delay)
|
||||
|
||||
waitForEnter().then(() => {
|
||||
clearInterval(timer)
|
||||
process.stdout.write(response.slice(i) + '\n')
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function request() {
|
||||
const { API_ENDPOINT, TOKEN, PWD, COMMAND, OUTPUT, EXIT_CODE } = process.env
|
||||
const payload = {
|
||||
command: COMMAND,
|
||||
output: OUTPUT,
|
||||
exit_code: EXIT_CODE,
|
||||
token: TOKEN,
|
||||
pwd: PWD,
|
||||
}
|
||||
try {
|
||||
const res = await fetch(`${API_ENDPOINT}/api/v1/commands`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
const data = await res.json()
|
||||
if (data.responses) {
|
||||
await printResponses(data.responses, 100)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
request()
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:latest
|
||||
FROM node:latest
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
@@ -11,6 +11,8 @@ USER rudeus
|
||||
|
||||
WORKDIR /home/rudeus
|
||||
|
||||
COPY ./home /home/rudeus/
|
||||
COPY ./server/quests/helloworld/home /home/rudeus/
|
||||
|
||||
COPY ./packages/cli/cli.js /usr/local/bin/cli.js
|
||||
|
||||
CMD [ "/bin/bash" ]
|
||||
@@ -2,26 +2,20 @@
|
||||
preexec() {
|
||||
[ -n "$COMP_LINE" ] && return # do nothing if completing
|
||||
[ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # do nothing if completing
|
||||
local command="$BASH_COMMAND"
|
||||
local pwd="$PWD"
|
||||
export COMMAND="$BASH_COMMAND"
|
||||
|
||||
if [[ $command =~ ^(vim|top|less|more|nano) ]]; then
|
||||
local payload=$(printf '{"token": "%s", "pwd": "%s", "command": "%s"}' "$TOKEN" "$pwd" "$command")
|
||||
curl -X POST $API_ENDPOINT/api/v1/commands -H 'accept: */*' -H 'Content-Type: application/json' -d "$payload"
|
||||
if [[ $COMMAND =~ ^(vim|top|less|more|nano) ]]; then
|
||||
node /usr/local/bin/cli.js
|
||||
return
|
||||
fi
|
||||
|
||||
# Execute the command, capture output and exit code
|
||||
local output=$( { eval $command 2>&1; echo $? > /tmp/exit_code; })
|
||||
local exit_code=$(cat /tmp/exit_code)
|
||||
export OUTPUT=$( { eval $COMMAND 2>&1; echo $? > /tmp/exit_code; })
|
||||
export EXIT_CODE=$(cat /tmp/exit_code)
|
||||
|
||||
local output_esc=$(echo $output | jq -Rs .)
|
||||
|
||||
# Store command in variable
|
||||
local payload=$(printf '{"token": "%s", "pwd": "%s", "command": "%s", "exit_code": "%s", "output": %s}' "$TOKEN" "$pwd" "$command" "$exit_code" "$output_esc")
|
||||
|
||||
echo $OUTPUT
|
||||
# Send command to the API
|
||||
curl -X POST $API_ENDPOINT/api/v1/commands -H 'accept: */*' -H 'Content-Type: application/json' -d "$payload" || echo $payload
|
||||
node /usr/local/bin/cli.js
|
||||
|
||||
BASH_COMMAND=""
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import config from '../config.js'
|
||||
|
||||
const engine = new Docker()
|
||||
|
||||
const questPath = '/home/zeko/src/linux-odyssey/server/quests'
|
||||
const projectPath = '/home/zeko/src/linux-odyssey'
|
||||
|
||||
const containerOptions = {
|
||||
Image: 'lancatlin/linux-odyssey:helloworld',
|
||||
@@ -17,7 +17,10 @@ const containerOptions = {
|
||||
HostConfig: {
|
||||
Binds: config.isProduction
|
||||
? []
|
||||
: [`${questPath}/helloworld/home:/home/rudeus`],
|
||||
: [
|
||||
`${projectPath}/server/quests/helloworld/home:/home/rudeus`,
|
||||
`${projectPath}/packages/cli/cli.js:/usr/local/bin/cli.js`,
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user