mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 22:18:07 +08:00
fix: 解决容器终端断开后未退出进程的问题 (#779)
This commit is contained in:
parent
1208514f37
commit
edf07be281
@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@ -107,14 +108,15 @@ func (b *BaseApi) RedisWsSsh(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
defer wsConn.Close()
|
||||
commands := fmt.Sprintf("docker exec -it %s redis-cli", redisConf.ContainerName)
|
||||
commands := "redis-cli"
|
||||
if len(redisConf.Requirepass) != 0 {
|
||||
commands = fmt.Sprintf("docker exec -it %s redis-cli -a %s --no-auth-warning", redisConf.ContainerName, redisConf.Requirepass)
|
||||
commands = fmt.Sprintf("redis-cli -a %s --no-auth-warning", redisConf.Requirepass)
|
||||
}
|
||||
slave, err := terminal.NewCommand(commands)
|
||||
slave, err := terminal.NewCommand(fmt.Sprintf("docker exec -it %s %s", redisConf.ContainerName, commands))
|
||||
if wshandleError(wsConn, err) {
|
||||
return
|
||||
}
|
||||
defer killBash(redisConf.ContainerName, commands)
|
||||
defer slave.Close()
|
||||
|
||||
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave)
|
||||
@ -177,6 +179,7 @@ func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
|
||||
if wshandleError(wsConn, err) {
|
||||
return
|
||||
}
|
||||
defer killBash(containerID, command)
|
||||
defer slave.Close()
|
||||
|
||||
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave)
|
||||
@ -216,6 +219,15 @@ func wshandleError(ws *websocket.Conn, err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func killBash(containerID, comm string) {
|
||||
sudo := ""
|
||||
if cmd.HasNoPasswordSudo() {
|
||||
sudo = "sudo"
|
||||
}
|
||||
command := exec.Command("sh", "-c", fmt.Sprintf("%s kill -9 $(docker top %s -eo pid,command | grep '%s' | awk '{print $1}')", sudo, containerID, comm))
|
||||
_, _ = command.CombinedOutput()
|
||||
}
|
||||
|
||||
var upGrader = websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024 * 1024 * 10,
|
||||
|
@ -23,7 +23,6 @@ type LocalCommand struct {
|
||||
|
||||
cmd *exec.Cmd
|
||||
pty *os.File
|
||||
ptyClosed chan struct{}
|
||||
}
|
||||
|
||||
func NewCommand(commands string) (*LocalCommand, error) {
|
||||
@ -33,7 +32,6 @@ func NewCommand(commands string) (*LocalCommand, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to start command")
|
||||
}
|
||||
ptyClosed := make(chan struct{})
|
||||
|
||||
lcmd := &LocalCommand{
|
||||
closeSignal: DefaultCloseSignal,
|
||||
@ -41,7 +39,6 @@ func NewCommand(commands string) (*LocalCommand, error) {
|
||||
|
||||
cmd: cmd,
|
||||
pty: pty,
|
||||
ptyClosed: ptyClosed,
|
||||
}
|
||||
|
||||
return lcmd, nil
|
||||
@ -57,16 +54,10 @@ func (lcmd *LocalCommand) Write(p []byte) (n int, err error) {
|
||||
|
||||
func (lcmd *LocalCommand) Close() error {
|
||||
if lcmd.cmd != nil && lcmd.cmd.Process != nil {
|
||||
_ = lcmd.cmd.Process.Signal(lcmd.closeSignal)
|
||||
_ = lcmd.cmd.Process.Kill()
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case <-lcmd.ptyClosed:
|
||||
_ = lcmd.pty.Close()
|
||||
return nil
|
||||
case <-lcmd.closeTimeoutC():
|
||||
_ = lcmd.cmd.Process.Signal(syscall.SIGKILL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (lcmd *LocalCommand) ResizeTerminal(width int, height int) error {
|
||||
@ -100,11 +91,3 @@ func (lcmd *LocalCommand) Wait(quitChan chan bool) {
|
||||
setQuit(quitChan)
|
||||
}
|
||||
}
|
||||
|
||||
func (lcmd *LocalCommand) closeTimeoutC() <-chan time.Time {
|
||||
if lcmd.closeTimeout >= 0 {
|
||||
return time.After(lcmd.closeTimeout)
|
||||
}
|
||||
|
||||
return make(chan time.Time)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user