feat: #3
parent
f309009a76
commit
faf8300d8f
29
gterm.go
29
gterm.go
|
@ -30,10 +30,12 @@ var tmpl *engine.Engine
|
||||||
var servePublic = http.FileServer(http.FS(public.FS))
|
var servePublic = http.FileServer(http.FS(public.FS))
|
||||||
|
|
||||||
var pool map[string]chan struct{}
|
var pool map[string]chan struct{}
|
||||||
|
var locks map[string]chan struct{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
tmpl = engine.Must(engine.New("").Parse(index))
|
tmpl = engine.Must(engine.New("").Parse(index))
|
||||||
pool = map[string]chan struct{}{}
|
pool = map[string]chan struct{}{}
|
||||||
|
locks = map[string]chan struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type GTerm struct {
|
type GTerm struct {
|
||||||
|
@ -131,6 +133,7 @@ type NewCmdRequest struct {
|
||||||
Envs []string `json:"envs"`
|
Envs []string `json:"envs"`
|
||||||
Args []string `json:"args"`
|
Args []string `json:"args"`
|
||||||
Dir string `json:"dir"`
|
Dir string `json:"dir"`
|
||||||
|
Block bool `json:"block"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GTerm) defaultCmd() *exec.Cmd {
|
func (g *GTerm) defaultCmd() *exec.Cmd {
|
||||||
|
@ -142,6 +145,12 @@ func (g *GTerm) defaultCmd() *exec.Cmd {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GTerm) echo(msg string) *exec.Cmd {
|
||||||
|
cmd := exec.Command("echo", msg)
|
||||||
|
cmd.Env = g.Envs
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GTerm) WS(w http.ResponseWriter, r *http.Request) {
|
func (g *GTerm) WS(w http.ResponseWriter, r *http.Request) {
|
||||||
id := fmt.Sprintf("[%02d] %s", ctr(), ksrv.GetIP(r))
|
id := fmt.Sprintf("[%02d] %s", ctr(), ksrv.GetIP(r))
|
||||||
pool[id] = make(chan struct{}, 1)
|
pool[id] = make(chan struct{}, 1)
|
||||||
|
@ -159,12 +168,28 @@ func (g *GTerm) WS(w http.ResponseWriter, r *http.Request) {
|
||||||
err := json.Unmarshal([]byte(param), req)
|
err := json.Unmarshal([]byte(param), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Error().Err(err).Str("base", newCmd).Str("decrypt", param).Msg("cmd decode failed")
|
l.Error().Err(err).Str("base", newCmd).Str("decrypt", param).Msg("cmd decode failed")
|
||||||
cmd = g.defaultCmd()
|
cmd = g.echo("cmd decode failed")
|
||||||
} else {
|
} else {
|
||||||
l.Info().Interface("cmd", req).Msg("starting cmd")
|
|
||||||
cmd = exec.Command(req.Cmd, req.Args...)
|
cmd = exec.Command(req.Cmd, req.Args...)
|
||||||
cmd.Env = append(req.Envs, "TERM=xterm-256color")
|
cmd.Env = append(req.Envs, "TERM=xterm-256color")
|
||||||
cmd.Dir = req.Dir
|
cmd.Dir = req.Dir
|
||||||
|
if req.Block {
|
||||||
|
lock, ok := locks[newCmd]
|
||||||
|
if !ok {
|
||||||
|
locks[newCmd] = make(chan struct{}, 1)
|
||||||
|
}
|
||||||
|
if len(lock) == 1 {
|
||||||
|
cmd = g.echo("cmd already running")
|
||||||
|
} else {
|
||||||
|
l.Info().Interface("cmd", req).Msg("starting cmd")
|
||||||
|
locks[newCmd] <- struct{}{}
|
||||||
|
defer func() {
|
||||||
|
<-locks[newCmd]
|
||||||
|
close(locks[newCmd])
|
||||||
|
delete(locks, newCmd)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cmd = g.defaultCmd()
|
cmd = g.defaultCmd()
|
||||||
|
|
Loading…
Reference in New Issue