mirror of
https://github.com/whyour/qinglong.git
synced 2025-07-27 14:46:06 +08:00
add terminal input stdio
This commit is contained in:
parent
418695c4aa
commit
659078f9d6
|
@ -1,5 +1,6 @@
|
||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import winston from 'winston';
|
import winston from 'winston';
|
||||||
|
import { Connection } from 'sockjs';
|
||||||
import nodeSchedule from 'node-schedule';
|
import nodeSchedule from 'node-schedule';
|
||||||
import { ChildProcessWithoutNullStreams } from 'child_process';
|
import { ChildProcessWithoutNullStreams } from 'child_process';
|
||||||
import {
|
import {
|
||||||
|
@ -33,6 +34,7 @@ export interface TaskCallbacks {
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
onLog?: (message: string) => Promise<void>;
|
onLog?: (message: string) => Promise<void>;
|
||||||
onError?: (message: string) => Promise<void>;
|
onError?: (message: string) => Promise<void>;
|
||||||
|
onMessage?:(cb:(msg:string,conn:Connection)=>void)=>void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
|
@ -120,6 +122,10 @@ export default class ScheduleService {
|
||||||
);
|
);
|
||||||
resolve({ ...others, pid: cp.pid, code });
|
resolve({ ...others, pid: cp.pid, code });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
callbacks.onMessage?.((msg:string,conn:Connection)=>{
|
||||||
|
cp.stdin.write(JSON.parse(msg).message)
|
||||||
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
'[panel][执行任务失败] 命令: %s, 错误信息: %j',
|
'[panel][执行任务失败] 命令: %s, 错误信息: %j',
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
|
import { Connection } from 'sockjs';
|
||||||
import winston from 'winston';
|
import winston from 'winston';
|
||||||
import path, { join } from 'path';
|
import path, { join } from 'path';
|
||||||
import SockService from './sock';
|
import SockService from './sock';
|
||||||
|
@ -22,6 +23,7 @@ export default class ScriptService {
|
||||||
return {
|
return {
|
||||||
onEnd: async (cp, endTime, diff) => {
|
onEnd: async (cp, endTime, diff) => {
|
||||||
await rmPath(filePath);
|
await rmPath(filePath);
|
||||||
|
this.sockService.removeAllListeners('message')
|
||||||
},
|
},
|
||||||
onError: async (message: string) => {
|
onError: async (message: string) => {
|
||||||
this.sockService.sendMessage({
|
this.sockService.sendMessage({
|
||||||
|
@ -35,6 +37,10 @@ export default class ScriptService {
|
||||||
message,
|
message,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
onMessage:(cb:(msg:string,conn:Connection)=>void)=>{
|
||||||
|
this.sockService.off('message',cb)
|
||||||
|
this.sockService.on('message',cb)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,15 @@ import { Service, Inject } from 'typedi';
|
||||||
import winston from 'winston';
|
import winston from 'winston';
|
||||||
import { Connection } from 'sockjs';
|
import { Connection } from 'sockjs';
|
||||||
import { SockMessage } from '../data/sock';
|
import { SockMessage } from '../data/sock';
|
||||||
|
import EventEmitter from 'events';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class SockService {
|
export default class SockService extends EventEmitter{
|
||||||
private clients: Connection[] = [];
|
private clients: Connection[] = [];
|
||||||
|
|
||||||
constructor(@Inject('logger') private logger: winston.Logger) { }
|
constructor(@Inject('logger') private logger: winston.Logger) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
public getClients() {
|
public getClients() {
|
||||||
return this.clients;
|
return this.clients;
|
||||||
|
@ -16,11 +19,17 @@ export default class SockService {
|
||||||
public addClient(conn: Connection) {
|
public addClient(conn: Connection) {
|
||||||
if (this.clients.indexOf(conn) === -1) {
|
if (this.clients.indexOf(conn) === -1) {
|
||||||
this.clients.push(conn);
|
this.clients.push(conn);
|
||||||
|
|
||||||
|
conn.on('data',(msg:string)=>{
|
||||||
|
this.emit('message',msg,conn)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeClient(conn: Connection) {
|
public removeClient(conn: Connection) {
|
||||||
const index = this.clients.indexOf(conn);
|
const index = this.clients.indexOf(conn);
|
||||||
|
conn.removeAllListeners('data')
|
||||||
|
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
this.clients.splice(index, 1);
|
this.clients.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -486,5 +486,7 @@
|
||||||
"NPM 镜像源": "NPM Mirror Source",
|
"NPM 镜像源": "NPM Mirror Source",
|
||||||
"PyPI 镜像源": "PyPI Mirror Source",
|
"PyPI 镜像源": "PyPI Mirror Source",
|
||||||
"alpine linux 镜像源": "Alpine Linux Mirror Source",
|
"alpine linux 镜像源": "Alpine Linux Mirror Source",
|
||||||
"如果恢复失败,可进入容器执行": "If recovery fails, you can enter the container and execute"
|
"如果恢复失败,可进入容器执行": "If recovery fails, you can enter the container and execute",
|
||||||
|
"终端输入": "terminal input",
|
||||||
|
"发送": "send"
|
||||||
}
|
}
|
||||||
|
|
|
@ -486,5 +486,7 @@
|
||||||
"NPM 镜像源": "NPM 镜像源",
|
"NPM 镜像源": "NPM 镜像源",
|
||||||
"PyPI 镜像源": "PyPI 镜像源",
|
"PyPI 镜像源": "PyPI 镜像源",
|
||||||
"alpine linux 镜像源": "alpine linux 镜像源",
|
"alpine linux 镜像源": "alpine linux 镜像源",
|
||||||
"如果恢复失败,可进入容器执行": "如果恢复失败,可进入容器执行"
|
"如果恢复失败,可进入容器执行": "如果恢复失败,可进入容器执行",
|
||||||
|
"终端输入": "终端输入",
|
||||||
|
"发送": "发送"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import React, {
|
||||||
useCallback,
|
useCallback,
|
||||||
useReducer,
|
useReducer,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { Drawer, Button, Tabs, Badge, Select, TreeSelect } from 'antd';
|
import { Drawer, Button, Tabs, Badge, Select, TreeSelect, Input } from 'antd';
|
||||||
import { request } from '@/utils/http';
|
import { request } from '@/utils/http';
|
||||||
import config from '@/utils/config';
|
import config from '@/utils/config';
|
||||||
import SplitPane from 'react-split-pane';
|
import SplitPane from 'react-split-pane';
|
||||||
|
@ -41,6 +41,7 @@ const EditModal = ({
|
||||||
const [settingModalVisible, setSettingModalVisible] =
|
const [settingModalVisible, setSettingModalVisible] =
|
||||||
useState<boolean>(false);
|
useState<boolean>(false);
|
||||||
const [log, setLog] = useState('');
|
const [log, setLog] = useState('');
|
||||||
|
const [raw, setRaw] = useState('')
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const editorRef = useRef<any>(null);
|
const editorRef = useRef<any>(null);
|
||||||
const [isRunning, setIsRunning] = useState(false);
|
const [isRunning, setIsRunning] = useState(false);
|
||||||
|
@ -124,6 +125,12 @@ const EditModal = ({
|
||||||
setLog((p) => `${p}${_message}`);
|
setLog((p) => `${p}${_message}`);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const send=()=>{
|
||||||
|
const ws = WebSocketManager.getInstance();
|
||||||
|
ws.send({ type:'terminalInput', message:raw })
|
||||||
|
setRaw('')
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const ws = WebSocketManager.getInstance();
|
const ws = WebSocketManager.getInstance();
|
||||||
ws.subscribe('manuallyRunScript', handleMessage);
|
ws.subscribe('manuallyRunScript', handleMessage);
|
||||||
|
@ -253,6 +260,12 @@ const EditModal = ({
|
||||||
padding: '0 15px',
|
padding: '0 15px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<div style={{ minWidth: 0, display: 'flex', alignItems: 'center', gap:'8px' }}>
|
||||||
|
<Input placeholder={intl.get('终端输入')} value={raw} onChange={(e)=>{
|
||||||
|
setRaw(e.target.value)
|
||||||
|
}}></Input>
|
||||||
|
<Button type="primary" onClick={send}>{intl.get('发送')}</Button>
|
||||||
|
</div>
|
||||||
<Ansi>{log}</Ansi>
|
<Ansi>{log}</Ansi>
|
||||||
</pre>
|
</pre>
|
||||||
</SplitPane>
|
</SplitPane>
|
||||||
|
|
|
@ -7,4 +7,5 @@ export type SockMessageType =
|
||||||
| 'runSubscriptionEnd'
|
| 'runSubscriptionEnd'
|
||||||
| 'reloadSystem'
|
| 'reloadSystem'
|
||||||
| 'updateNodeMirror'
|
| 'updateNodeMirror'
|
||||||
| 'updateLinuxMirror';
|
| 'updateLinuxMirror'
|
||||||
|
| 'terminalInput';
|
||||||
|
|
Loading…
Reference in New Issue
Block a user