github.com/uppal0016/docker_new@v0.0.0-20240123060250-1c98be13ac2c/daemon/top_unix.go (about) 1 //+build !windows 2 3 package daemon 4 5 import ( 6 "fmt" 7 "os/exec" 8 "strconv" 9 "strings" 10 11 "github.com/docker/engine-api/types" 12 ) 13 14 // ContainerTop lists the processes running inside of the given 15 // container by calling ps with the given args, or with the flags 16 // "-ef" if no args are given. An error is returned if the container 17 // is not found, or is not running, or if there are any problems 18 // running ps, or parsing the output. 19 func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) { 20 if psArgs == "" { 21 psArgs = "-ef" 22 } 23 24 container, err := daemon.GetContainer(name) 25 if err != nil { 26 return nil, err 27 } 28 29 if !container.IsRunning() { 30 return nil, errNotRunning{container.ID} 31 } 32 33 if container.IsRestarting() { 34 return nil, errContainerIsRestarting(container.ID) 35 } 36 37 pids, err := daemon.containerd.GetPidsForContainer(container.ID) 38 if err != nil { 39 return nil, err 40 } 41 42 output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output() 43 if err != nil { 44 return nil, fmt.Errorf("Error running ps: %v", err) 45 } 46 47 procList := &types.ContainerProcessList{} 48 49 lines := strings.Split(string(output), "\n") 50 procList.Titles = strings.Fields(lines[0]) 51 52 pidIndex := -1 53 for i, name := range procList.Titles { 54 if name == "PID" { 55 pidIndex = i 56 } 57 } 58 if pidIndex == -1 { 59 return nil, fmt.Errorf("Couldn't find PID field in ps output") 60 } 61 62 // loop through the output and extract the PID from each line 63 for _, line := range lines[1:] { 64 if len(line) == 0 { 65 continue 66 } 67 fields := strings.Fields(line) 68 p, err := strconv.Atoi(fields[pidIndex]) 69 if err != nil { 70 return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err) 71 } 72 73 for _, pid := range pids { 74 if pid == p { 75 // Make sure number of fields equals number of header titles 76 // merging "overhanging" fields 77 process := fields[:len(procList.Titles)-1] 78 process = append(process, strings.Join(fields[len(procList.Titles)-1:], " ")) 79 procList.Processes = append(procList.Processes, process) 80 } 81 } 82 } 83 daemon.LogContainerEvent(container, "top") 84 return procList, nil 85 }