package app import ( "strings" "time" abraFormatter "coopcloud.tech/abra/cli/formatter" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "github.com/docker/cli/cli/command/formatter" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" ) var watch bool var watchFlag = &cli.BoolFlag{ Name: "watch", Aliases: []string{"w"}, Value: false, Usage: "Watch status by polling repeatedly", Destination: &watch, } var appPsCommand = &cli.Command{ Name: "ps", Usage: "Check app status", Description: "This command shows a more detailed status output of a specific deployed app.", Aliases: []string{"p"}, Flags: []cli.Flag{ watchFlag, }, BashComplete: autocomplete.AppNameComplete, Action: func(c *cli.Context) error { if !watch { showPSOutput(c) return nil } // TODO: how do we make this update in-place in an x-platform way? for { showPSOutput(c) time.Sleep(2 * time.Second) } }, } // showPSOutput renders ps output. func showPSOutput(c *cli.Context) { app := internal.ValidateApp(c) cl, err := client.New(app.Server) if err != nil { logrus.Fatal(err) } filters := filters.NewArgs() filters.Add("name", app.StackName()) containers, err := cl.ContainerList(c.Context, types.ContainerListOptions{Filters: filters}) if err != nil { logrus.Fatal(err) } tableCol := []string{"image", "created", "status", "ports", "app name", "services"} table := abraFormatter.CreateTable(tableCol) for _, container := range containers { var containerNames []string for _, containerName := range container.Names { trimmed := strings.TrimPrefix(containerName, "/") containerNames = append(containerNames, trimmed) } tableRow := []string{ abraFormatter.RemoveSha(container.Image), abraFormatter.HumanDuration(container.Created), container.Status, formatter.DisplayablePorts(container.Ports), app.StackName(), strings.Join(containerNames, "\n"), } table.Append(tableRow) } table.Render() }