mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 22:18:07 +08:00
fix: 解决僵尸进程的问题 (#4464)
This commit is contained in:
parent
0cd06803e2
commit
0bf6db1cf8
@ -102,7 +102,7 @@ func (b *BaseApi) RedisWsSsh(c *gin.Context) {
|
|||||||
if wshandleError(wsConn, err) {
|
if wshandleError(wsConn, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer killBash(redisConf.ContainerName, commands, pidMap)
|
defer killBash(redisConf.ContainerName, pidMap)
|
||||||
defer slave.Close()
|
defer slave.Close()
|
||||||
|
|
||||||
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave, false)
|
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave, false)
|
||||||
@ -170,7 +170,7 @@ func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
|
|||||||
if wshandleError(wsConn, err) {
|
if wshandleError(wsConn, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer killBash(containerID, command, pidMap)
|
defer killBash(containerID, pidMap)
|
||||||
defer slave.Close()
|
defer slave.Close()
|
||||||
|
|
||||||
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave, true)
|
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave, true)
|
||||||
@ -221,26 +221,26 @@ func loadMapFromDockerTop(containerID string) map[string]string {
|
|||||||
lines := strings.Split(stdout, "\n")
|
lines := strings.Split(stdout, "\n")
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
parts := strings.Fields(line)
|
parts := strings.Fields(line)
|
||||||
if len(parts) != 2 {
|
if len(parts) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pidMap[parts[0]] = parts[1]
|
pidMap[parts[0]] = strings.Join(parts, " ")
|
||||||
}
|
}
|
||||||
return pidMap
|
return pidMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func killBash(containerID, comm string, pidMap map[string]string) {
|
func killBash(containerID string, pidMap map[string]string) {
|
||||||
sudo := cmd.SudoHandleCmd()
|
sudo := cmd.SudoHandleCmd()
|
||||||
newPidMap := loadMapFromDockerTop(containerID)
|
newPidMap := loadMapFromDockerTop(containerID)
|
||||||
for pid, command := range newPidMap {
|
for pid, newCmd := range newPidMap {
|
||||||
isOld := false
|
isOld := false
|
||||||
for pid2 := range pidMap {
|
for pid2, oldCmd := range pidMap {
|
||||||
if pid == pid2 {
|
if pid == pid2 && oldCmd == newCmd {
|
||||||
isOld = true
|
isOld = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isOld && command == comm {
|
if !isOld {
|
||||||
_, _ = cmd.Execf("%s kill -9 %s", sudo, pid)
|
_, _ = cmd.Execf("%s kill -9 %s", sudo, pid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -626,22 +626,26 @@ func (u *ContainerService) ContainerLogs(wsConn *websocket.Conn, containerType,
|
|||||||
if cmd.CheckIllegal(container, since, tail) {
|
if cmd.CheckIllegal(container, since, tail) {
|
||||||
return buserr.New(constant.ErrCmdIllegal)
|
return buserr.New(constant.ErrCmdIllegal)
|
||||||
}
|
}
|
||||||
command := fmt.Sprintf("docker logs %s", container)
|
commandName := "docker"
|
||||||
|
commandArg := []string{"logs", container}
|
||||||
if containerType == "compose" {
|
if containerType == "compose" {
|
||||||
command = fmt.Sprintf("docker-compose -f %s logs", container)
|
commandName = "docker-compose"
|
||||||
|
commandArg = []string{"-f", container, "logs"}
|
||||||
}
|
}
|
||||||
if tail != "0" {
|
if tail != "0" {
|
||||||
command += " --tail " + tail
|
commandArg = append(commandArg, "--tail")
|
||||||
|
commandArg = append(commandArg, tail)
|
||||||
}
|
}
|
||||||
if since != "all" {
|
if since != "all" {
|
||||||
command += " --since " + since
|
commandArg = append(commandArg, "--since")
|
||||||
|
commandArg = append(commandArg, since)
|
||||||
}
|
}
|
||||||
if follow {
|
if follow {
|
||||||
command += " -f"
|
commandArg = append(commandArg, "-f")
|
||||||
}
|
}
|
||||||
command += " 2>&1"
|
|
||||||
cmd := exec.Command("bash", "-c", command)
|
|
||||||
if !follow {
|
if !follow {
|
||||||
|
commandArg = append(commandArg, "2>&1")
|
||||||
|
cmd := exec.Command(commandName, commandArg...)
|
||||||
stdout, _ := cmd.CombinedOutput()
|
stdout, _ := cmd.CombinedOutput()
|
||||||
if !utf8.Valid(stdout) {
|
if !utf8.Valid(stdout) {
|
||||||
return errors.New("invalid utf8")
|
return errors.New("invalid utf8")
|
||||||
@ -652,50 +656,52 @@ func (u *ContainerService) ContainerLogs(wsConn *websocket.Conn, containerType,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(commandName, commandArg...)
|
||||||
stdout, err := cmd.StdoutPipe()
|
stdout, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
_ = cmd.Process.Signal(syscall.SIGTERM)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
|
_ = cmd.Process.Signal(syscall.SIGTERM)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() {
|
exitCh := make(chan struct{})
|
||||||
_ = cmd.Process.Signal(syscall.SIGTERM)
|
go func() {
|
||||||
_ = cmd.Wait()
|
_, wsData, _ := wsConn.ReadMessage()
|
||||||
|
if string(wsData) == "close conn" {
|
||||||
|
_ = cmd.Process.Signal(syscall.SIGTERM)
|
||||||
|
exitCh <- struct{}{}
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
var exitCh chan struct{}
|
|
||||||
if follow {
|
|
||||||
go func() {
|
|
||||||
_, wsData, _ := wsConn.ReadMessage()
|
|
||||||
if string(wsData) == "close conn" {
|
|
||||||
exitCh <- struct{}{}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer := make([]byte, 1024)
|
go func() {
|
||||||
for {
|
buffer := make([]byte, 1024)
|
||||||
select {
|
for {
|
||||||
case <-exitCh:
|
select {
|
||||||
return nil
|
case <-exitCh:
|
||||||
default:
|
return
|
||||||
n, err := stdout.Read(buffer)
|
default:
|
||||||
if err != nil {
|
n, err := stdout.Read(buffer)
|
||||||
if err == io.EOF {
|
if err != nil {
|
||||||
return err
|
if err == io.EOF {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
global.LOG.Errorf("read bytes from log failed, err: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !utf8.Valid(buffer[:n]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err = wsConn.WriteMessage(websocket.TextMessage, buffer[:n]); err != nil {
|
||||||
|
global.LOG.Errorf("send message with log to ws failed, err: %v", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
global.LOG.Errorf("read bytes from log failed, err: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !utf8.Valid(buffer[:n]) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err = wsConn.WriteMessage(websocket.TextMessage, buffer[:n]); err != nil {
|
|
||||||
global.LOG.Errorf("send message with log to ws failed, err: %v", err)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}()
|
||||||
|
_ = cmd.Wait()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ContainerService) ContainerStats(id string) (*dto.ContainerStats, error) {
|
func (u *ContainerService) ContainerStats(id string) (*dto.ContainerStats, error) {
|
||||||
|
@ -143,6 +143,7 @@ const searchLogs = async () => {
|
|||||||
MsgError(i18n.global.t('container.linesHelper'));
|
MsgError(i18n.global.t('container.linesHelper'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
terminalSocket.value?.send('close conn');
|
||||||
terminalSocket.value?.close();
|
terminalSocket.value?.close();
|
||||||
logInfo.value = '';
|
logInfo.value = '';
|
||||||
const href = window.location.href;
|
const href = window.location.href;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user