From 9d54815c2690353a295b602b67084fd1f3c095e8 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Wed, 15 Jan 2020 16:36:27 +0100 Subject: refactor top code Move the top logic from pkg/adapter into the (*libpod.Container).Top(). This way, we drop the dependency from pkg/api on pkg/adapters and have a clearer separation of concerns. Signed-off-by: Valentin Rothberg --- pkg/adapter/containers.go | 85 +------------------------------------- pkg/api/handlers/containers_top.go | 20 +++------ 2 files changed, 7 insertions(+), 98 deletions(-) (limited to 'pkg') diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index a257ef4f4..f66999ffa 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -27,7 +27,6 @@ import ( "github.com/containers/libpod/libpod/logs" "github.com/containers/libpod/pkg/adapter/shortcuts" "github.com/containers/libpod/pkg/systemdgen" - "github.com/containers/psgo" "github.com/containers/storage" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -913,89 +912,7 @@ func (r *LocalRuntime) Top(cli *cliconfig.TopValues) ([]string, error) { return nil, errors.Wrapf(err, "unable to lookup requested container") } - output, psgoErr := container.Top(descriptors) - if psgoErr == nil { - return output, nil - } - - // If we encountered an ErrUnknownDescriptor error, fallback to executing - // ps(1). This ensures backwards compatibility to users depending on ps(1) - // and makes sure we're ~compatible with docker. - if errors.Cause(psgoErr) != psgo.ErrUnknownDescriptor { - return nil, psgoErr - } - - output, err = r.execPS(container, descriptors) - if err != nil { - return nil, errors.Wrapf(err, "error executing ps(1) in the container") - } - - // Trick: filter the ps command from the output instead of - // checking/requiring PIDs in the output. - filtered := []string{} - cmd := strings.Join(descriptors, " ") - for _, line := range output { - if !strings.Contains(line, cmd) { - filtered = append(filtered, line) - } - } - - return filtered, nil -} - -func (r *LocalRuntime) execPS(c *libpod.Container, args []string) ([]string, error) { - rPipe, wPipe, err := os.Pipe() - if err != nil { - return nil, err - } - defer wPipe.Close() - defer rPipe.Close() - - rErrPipe, wErrPipe, err := os.Pipe() - if err != nil { - return nil, err - } - defer wErrPipe.Close() - defer rErrPipe.Close() - - streams := new(libpod.AttachStreams) - streams.OutputStream = wPipe - streams.ErrorStream = wErrPipe - streams.AttachOutput = true - streams.AttachError = true - - stdout := []string{} - go func() { - scanner := bufio.NewScanner(rPipe) - for scanner.Scan() { - stdout = append(stdout, scanner.Text()) - } - }() - stderr := []string{} - go func() { - scanner := bufio.NewScanner(rErrPipe) - for scanner.Scan() { - stderr = append(stderr, scanner.Text()) - } - }() - - cmd := append([]string{"ps"}, args...) - ec, err := c.Exec(false, false, map[string]string{}, cmd, "", "", streams, 0, nil, "") - if err != nil { - return nil, err - } else if ec != 0 { - return nil, errors.Errorf("Runtime failed with exit status: %d and output: %s", ec, strings.Join(stderr, " ")) - } - - if logrus.GetLevel() >= logrus.DebugLevel { - // If we're running in debug mode or higher, we might want to have a - // look at stderr which includes debug logs from conmon. - for _, log := range stderr { - logrus.Debugf("%s", log) - } - } - - return stdout, nil + return container.Top(descriptors) } // ExecContainer executes a command in the container diff --git a/pkg/api/handlers/containers_top.go b/pkg/api/handlers/containers_top.go index 711f6858f..1a310262c 100644 --- a/pkg/api/handlers/containers_top.go +++ b/pkg/api/handlers/containers_top.go @@ -4,10 +4,7 @@ import ( "net/http" "strings" - "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/libpod" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/adapter" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/gorilla/mux" "github.com/gorilla/schema" @@ -30,19 +27,14 @@ func TopContainer(w http.ResponseWriter, r *http.Request) { } name := mux.Vars(r)["name"] + c, err := runtime.LookupContainer(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } - adapterRuntime := adapter.LocalRuntime{} - adapterRuntime.Runtime = runtime - - topValues := cliconfig.TopValues{} - topValues.InputArgs = []string{name, query.PsArgs} - - output, err := adapterRuntime.Top(&topValues) + output, err := c.Top([]string{query.PsArgs}) if err != nil { - if errors.Cause(err) == define.ErrNoSuchCtr { - utils.ContainerNotFound(w, name, err) - return - } utils.InternalServerError(w, err) return } -- cgit v1.2.3-54-g00ecf