Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
grpc: implement ListProcesses
Browse files Browse the repository at this point in the history
ListProcesses returns a list of running processes inside
the container, this function should be called by the runtime
in the ps command implementation.

fixes #193

Signed-off-by: Julio Montes <julio.montes@intel.com>
  • Loading branch information
Julio Montes committed Apr 3, 2018
1 parent ebc656f commit dd113d1
Show file tree
Hide file tree
Showing 5 changed files with 652 additions and 100 deletions.
90 changes: 90 additions & 0 deletions grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
package main

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"syscall"
"time"

Expand Down Expand Up @@ -536,6 +541,91 @@ func (a *agentGRPC) WaitProcess(ctx context.Context, req *pb.WaitProcessRequest)
}, nil
}

func getPIDIndex(title string) int {
// looking for PID field in ps title
fields := strings.Fields(title)
for i, f := range fields {
if f == "PID" {
return i
}
}
return -1
}

func (a *agentGRPC) ListProcesses(ctx context.Context, req *pb.ListProcessesRequest) (*pb.ListProcessesResponse, error) {
resp := &pb.ListProcessesResponse{}

c, err := a.sandbox.getContainer(req.ContainerId)
if err != nil {
return resp, err
}

pids, err := c.container.Processes()
if err != nil {
return resp, err
}

switch req.Format {
case "table":
case "json":
resp.ProcessList, err = json.Marshal(pids)
return resp, err
default:
return resp, fmt.Errorf("invalid format option")
}

psArgs := req.Args
if len(psArgs) == 0 {
psArgs = []string{"-ef"}
}

cmd := exec.Command("ps", psArgs...)
output, err := a.sandbox.subreaper.combinedOutput(cmd)
if err != nil {
return nil, fmt.Errorf("%s: %s", err, output)
}

lines := strings.Split(string(output), "\n")

pidIndex := getPIDIndex(lines[0])

// PID field not found
if pidIndex == -1 {
return nil, fmt.Errorf("failed to find PID field in ps output")
}

// append title
var result bytes.Buffer

result.WriteString(lines[0] + "\n")

for _, line := range lines[1:] {
if len(line) == 0 {
continue
}
fields := strings.Fields(line)
if pidIndex >= len(fields) {
return nil, fmt.Errorf("missing PID field: %s", line)
}

p, err := strconv.Atoi(fields[pidIndex])
if err != nil {
return nil, fmt.Errorf("failed to convert pid to int: %s", fields[pidIndex])
}

// appends pid line
for _, pid := range pids {
if pid == p {
result.WriteString(line + "\n")
break
}
}
}

resp.ProcessList = result.Bytes()
return resp, nil
}

func (a *agentGRPC) RemoveContainer(ctx context.Context, req *pb.RemoveContainerRequest) (*gpb.Empty, error) {
ctr, err := a.sandbox.getContainer(req.ContainerId)
if err != nil {
Expand Down
Loading

0 comments on commit dd113d1

Please sign in to comment.