Merge pull request #21354 from Microsoft/jjh/getpids
Windows: Minimal docker top implementation
This commit is contained in:
commit
adc6ed5a10
7 changed files with 92 additions and 7 deletions
|
@ -1,12 +1,32 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/engine-api/types"
|
||||
)
|
||||
|
||||
// ContainerTop is not supported on Windows and returns an error.
|
||||
func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) {
|
||||
return nil, fmt.Errorf("Top is not supported on Windows")
|
||||
// ContainerTop is a minimal implementation on Windows currently.
|
||||
// TODO Windows: This needs more work, but needs platform API support.
|
||||
// All we can currently return (particularly in the case of Hyper-V containers)
|
||||
// is a PID and the command.
|
||||
func (daemon *Daemon) ContainerTop(containerID string, psArgs string) (*types.ContainerProcessList, error) {
|
||||
|
||||
// It's really not an equivalent to linux 'ps' on Windows
|
||||
if psArgs != "" {
|
||||
return nil, errors.New("Windows does not support arguments to top")
|
||||
}
|
||||
|
||||
s, err := daemon.containerd.Summary(containerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
procList := &types.ContainerProcessList{}
|
||||
|
||||
for _, v := range s {
|
||||
procList.Titles = append(procList.Titles, strconv.Itoa(int(v.Pid))+" "+v.Command)
|
||||
}
|
||||
return procList, nil
|
||||
}
|
||||
|
|
|
@ -299,6 +299,12 @@ func (clnt *client) GetPidsForContainer(containerID string) ([]int, error) {
|
|||
return pids, nil
|
||||
}
|
||||
|
||||
// Summary returns a summary of the processes running in a container.
|
||||
// This is a no-op on Linux.
|
||||
func (clnt *client) Summary(containerID string) ([]Summary, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (clnt *client) getContainerdContainer(containerID string) (*containerd.Container, error) {
|
||||
resp, err := clnt.remote.apiClient.State(context.Background(), &containerd.StateRequest{Id: containerID})
|
||||
if err != nil {
|
||||
|
|
|
@ -303,6 +303,7 @@ func (clnt *client) Create(containerID string, spec Spec, options ...CreateOptio
|
|||
client: clnt,
|
||||
friendlyName: InitFriendlyName,
|
||||
},
|
||||
commandLine: strings.Join(spec.Process.Args, " "),
|
||||
},
|
||||
processes: make(map[string]*process),
|
||||
},
|
||||
|
@ -396,6 +397,7 @@ func (clnt *client) AddProcess(containerID, processFriendlyName string, procToAd
|
|||
client: clnt,
|
||||
systemPid: pid,
|
||||
},
|
||||
commandLine: createProcessParms.CommandLine,
|
||||
}
|
||||
|
||||
// Make sure the lock is not held while calling back into the daemon
|
||||
|
@ -508,9 +510,53 @@ func (clnt *client) Restore(containerID string, unusedOnWindows ...CreateOption)
|
|||
})
|
||||
}
|
||||
|
||||
// GetPidsForContainers is not implemented on Windows.
|
||||
// GetPidsForContainer returns a list of process IDs running in a container.
|
||||
// Although implemented, this is not used in Windows.
|
||||
func (clnt *client) GetPidsForContainer(containerID string) ([]int, error) {
|
||||
return nil, errors.New("GetPidsForContainer: GetPidsForContainer() not implemented")
|
||||
var pids []int
|
||||
clnt.lock(containerID)
|
||||
defer clnt.unlock(containerID)
|
||||
cont, err := clnt.getContainer(containerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Add the first process
|
||||
pids = append(pids, int(cont.containerCommon.systemPid))
|
||||
// And add all the exec'd processes
|
||||
for _, p := range cont.processes {
|
||||
pids = append(pids, int(p.processCommon.systemPid))
|
||||
}
|
||||
return pids, nil
|
||||
}
|
||||
|
||||
// Summary returns a summary of the processes running in a container.
|
||||
// This is present in Windows to support docker top. In linux, the
|
||||
// engine shells out to ps to get process information. On Windows, as
|
||||
// the containers could be Hyper-V containers, they would not be
|
||||
// visible on the container host. However, libcontainerd does have
|
||||
// that information.
|
||||
func (clnt *client) Summary(containerID string) ([]Summary, error) {
|
||||
var s []Summary
|
||||
clnt.lock(containerID)
|
||||
defer clnt.unlock(containerID)
|
||||
cont, err := clnt.getContainer(containerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Add the first process
|
||||
s = append(s, Summary{
|
||||
Pid: cont.containerCommon.systemPid,
|
||||
Command: cont.ociSpec.Process.Args[0]})
|
||||
// And add all the exec'd processes
|
||||
for _, p := range cont.processes {
|
||||
s = append(s, Summary{
|
||||
Pid: p.processCommon.systemPid,
|
||||
Command: p.commandLine})
|
||||
}
|
||||
return s, nil
|
||||
|
||||
}
|
||||
|
||||
// UpdateResources updates resources for a running container.
|
||||
|
|
|
@ -8,7 +8,10 @@ import (
|
|||
type process struct {
|
||||
processCommon
|
||||
|
||||
// Platform specific fields are below here. There are none presently on Windows.
|
||||
// Platform specific fields are below here.
|
||||
|
||||
// commandLine is to support returning summary information for docker top
|
||||
commandLine string
|
||||
}
|
||||
|
||||
func openReaderFromPipe(p io.ReadCloser) io.Reader {
|
||||
|
|
|
@ -42,6 +42,7 @@ type Client interface {
|
|||
Restore(containerID string, options ...CreateOption) error
|
||||
Stats(containerID string) (*Stats, error)
|
||||
GetPidsForContainer(containerID string) ([]int, error)
|
||||
Summary(containerID string) ([]Summary, error)
|
||||
UpdateResources(containerID string, resources Resources) error
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,9 @@ type Process struct {
|
|||
// Stats contains a stats properties from containerd.
|
||||
type Stats containerd.StatsResponse
|
||||
|
||||
// Summary container a container summary from containerd
|
||||
type Summary struct{}
|
||||
|
||||
// User specifies linux specific user and group information for the container's
|
||||
// main process.
|
||||
type User specs.User
|
||||
|
|
|
@ -11,6 +11,12 @@ type Process windowsoci.Process
|
|||
// User specifies user information for the containers main process.
|
||||
type User windowsoci.User
|
||||
|
||||
// Summary container a container summary from containerd
|
||||
type Summary struct {
|
||||
Pid uint32
|
||||
Command string
|
||||
}
|
||||
|
||||
// Stats contains a stats properties from containerd.
|
||||
type Stats struct{}
|
||||
|
||||
|
|
Loading…
Reference in a new issue