diff --git a/cli/app/ps.go b/cli/app/ps.go index b593a64f..cbe5bb0f 100644 --- a/cli/app/ps.go +++ b/cli/app/ps.go @@ -2,7 +2,8 @@ package app import ( "context" - "strings" + "encoding/json" + "fmt" "time" "coopcloud.tech/abra/cli/internal" @@ -10,11 +11,13 @@ import ( "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/formatter" - "coopcloud.tech/abra/pkg/service" + "coopcloud.tech/abra/pkg/recipe" + abraService "coopcloud.tech/abra/pkg/service" stack "coopcloud.tech/abra/pkg/upstream/stack" "github.com/buger/goterm" dockerFormatter "github.com/docker/cli/cli/command/formatter" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" dockerClient "github.com/docker/docker/client" "github.com/sirupsen/logrus" "github.com/urfave/cli" @@ -27,6 +30,7 @@ var appPsCommand = cli.Command{ ArgsUsage: "", Description: "Show a more detailed status output of a specific deployed app", Flags: []cli.Flag{ + internal.MachineReadableFlag, internal.WatchFlag, internal.DebugFlag, }, @@ -40,7 +44,7 @@ var appPsCommand = cli.Command{ logrus.Fatal(err) } - isDeployed, _, err := stack.IsDeployed(context.Background(), cl, app.StackName()) + isDeployed, deployedVersion, err := stack.IsDeployed(context.Background(), cl, app.StackName()) if err != nil { logrus.Fatal(err) } @@ -49,6 +53,15 @@ var appPsCommand = cli.Command{ logrus.Fatalf("%s is not deployed?", app.Name) } + statuses, err := config.GetAppStatuses([]config.App{app}, true) + if statusMeta, ok := statuses[app.StackName()]; ok { + if _, exists := statusMeta["chaos"]; !exists { + if err := recipe.EnsureVersion(app.Recipe, deployedVersion); err != nil { + logrus.Fatal(err) + } + } + } + if !internal.Watch { showPSOutput(c, app, cl) return nil @@ -66,36 +79,77 @@ var appPsCommand = cli.Command{ // showPSOutput renders ps output. func showPSOutput(c *cli.Context, app config.App, cl *dockerClient.Client) { - filters, err := app.Filters(true, true) + composeFiles, err := config.GetComposeFiles(app.Recipe, app.Env) if err != nil { logrus.Fatal(err) + return } - containers, err := cl.ContainerList(context.Background(), types.ContainerListOptions{Filters: filters}) + deployOpts := stack.Deploy{ + Composefiles: composeFiles, + Namespace: app.StackName(), + Prune: false, + ResolveImage: stack.ResolveImageAlways, + } + compose, err := config.GetAppComposeConfig(app.Name, deployOpts, app.Env) if err != nil { logrus.Fatal(err) + return } - tableCol := []string{"service name", "image", "created", "status", "state", "ports"} - table := formatter.CreateTable(tableCol) + var tablerows [][]string + allContainerStats := make(map[string]map[string]string) + for _, service := range compose.Services { + filters := filters.NewArgs() + filters.Add("name", fmt.Sprintf("^%s_%s", app.StackName(), service.Name)) - for _, container := range containers { - var containerNames []string - for _, containerName := range container.Names { - trimmed := strings.TrimPrefix(containerName, "/") - containerNames = append(containerNames, trimmed) + containers, err := cl.ContainerList(context.Background(), types.ContainerListOptions{Filters: filters}) + if err != nil { + logrus.Fatal(err) + return } - tableRow := []string{ - service.ContainerToServiceName(container.Names, app.StackName()), - formatter.RemoveSha(container.Image), - formatter.HumanDuration(container.Created), - container.Status, - container.State, - dockerFormatter.DisplayablePorts(container.Ports), + var containerStats map[string]string + + if len(containers) == 0 { + containerStats = map[string]string{ + "service name": service.Name, + "image": "unknown", + "created": "unknown", + "status": "unknown", + "state": "unknown", + "ports": "unknown", + } + } else { + container := containers[0] + containerStats = map[string]string{ + "service name": abraService.ContainerToServiceName(container.Names, app.StackName()), + "image": formatter.RemoveSha(container.Image), + "created": formatter.HumanDuration(container.Created), + "status": container.Status, + "state": container.State, + "ports": dockerFormatter.DisplayablePorts(container.Ports), + } } - table.Append(tableRow) + allContainerStats[containerStats["service name"]] = containerStats + + var tablerow []string = []string{containerStats["service name"], containerStats["image"], containerStats["created"], containerStats["status"], containerStats["state"], containerStats["ports"]} + tablerows = append(tablerows, tablerow) + } + if internal.MachineReadable { + jsonstring, err := json.Marshal(allContainerStats) + if err != nil { + logrus.Fatal(err) + } else { + fmt.Println(string(jsonstring)) + } + return + } else { + tableCol := []string{"service name", "image", "created", "status", "state", "ports"} + table := formatter.CreateTable(tableCol) + for _, row := range tablerows { + table.Append(row) + } + table.Render() } - - table.Render() }