From 49865c6a979bf0b705a964f68641d6134c4ed623 Mon Sep 17 00:00:00 2001 From: decentral1se Date: Sun, 22 Jan 2023 18:12:11 +0100 Subject: [PATCH] feat: app services command Closes https://git.coopcloud.tech/coop-cloud/organising/issues/372 --- cli/app/app.go | 39 +++++++++++----------- cli/app/services.go | 80 +++++++++++++++++++++++++++++++++++++++++++++ pkg/config/app.go | 6 ++-- 3 files changed, 103 insertions(+), 22 deletions(-) create mode 100644 cli/app/services.go diff --git a/cli/app/app.go b/cli/app/app.go index 2dfd50de..0afa3fa6 100644 --- a/cli/app/app.go +++ b/cli/app/app.go @@ -11,26 +11,27 @@ var AppCommand = cli.Command{ ArgsUsage: "", Description: "Functionality for managing the life cycle of your apps", Subcommands: []cli.Command{ - appNewCommand, - appConfigCommand, - appRestartCommand, - appDeployCommand, - appUpgradeCommand, - appUndeployCommand, - appRemoveCommand, - appCheckCommand, - appListCommand, - appPsCommand, - appLogsCommand, - appCpCommand, - appRunCommand, - appRollbackCommand, - appSecretCommand, - appVolumeCommand, - appVersionCommand, - appErrorsCommand, - appCmdCommand, appBackupCommand, + appCheckCommand, + appCmdCommand, + appConfigCommand, + appCpCommand, + appDeployCommand, + appErrorsCommand, + appListCommand, + appLogsCommand, + appNewCommand, + appPsCommand, + appRemoveCommand, + appRestartCommand, appRestoreCommand, + appRollbackCommand, + appRunCommand, + appSecretCommand, + appServicesCommand, + appUndeployCommand, + appUpgradeCommand, + appVersionCommand, + appVolumeCommand, }, } diff --git a/cli/app/services.go b/cli/app/services.go new file mode 100644 index 00000000..60a7245e --- /dev/null +++ b/cli/app/services.go @@ -0,0 +1,80 @@ +package app + +import ( + "context" + "fmt" + "strings" + + "coopcloud.tech/abra/cli/internal" + "coopcloud.tech/abra/pkg/autocomplete" + "coopcloud.tech/abra/pkg/client" + "coopcloud.tech/abra/pkg/formatter" + "coopcloud.tech/abra/pkg/service" + stack "coopcloud.tech/abra/pkg/upstream/stack" + "github.com/docker/docker/api/types" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" +) + +var appServicesCommand = cli.Command{ + Name: "services", + Aliases: []string{"sr"}, + Usage: "Display all services of an app", + ArgsUsage: "", + Flags: []cli.Flag{ + internal.DebugFlag, + }, + Before: internal.SubCommandBefore, + BashComplete: autocomplete.AppNameComplete, + Action: func(c *cli.Context) error { + app := internal.ValidateApp(c) + + cl, err := client.New(app.Server) + if err != nil { + logrus.Fatal(err) + } + + isDeployed, _, err := stack.IsDeployed(context.Background(), cl, app.StackName()) + if err != nil { + logrus.Fatal(err) + } + + if !isDeployed { + logrus.Fatalf("%s is not deployed?", app.Name) + } + + filters, err := app.Filters(true, true) + if err != nil { + logrus.Fatal(err) + } + + containers, err := cl.ContainerList(context.Background(), types.ContainerListOptions{Filters: filters}) + if err != nil { + logrus.Fatal(err) + } + + tableCol := []string{"service name", "image"} + table := formatter.CreateTable(tableCol) + + for _, container := range containers { + var containerNames []string + for _, containerName := range container.Names { + trimmed := strings.TrimPrefix(containerName, "/") + containerNames = append(containerNames, trimmed) + } + + serviceShortName := service.ContainerToServiceName(container.Names, app.StackName()) + serviceLongName := fmt.Sprintf("%s_%s", app.StackName(), serviceShortName) + + tableRow := []string{ + serviceLongName, + formatter.RemoveSha(container.Image), + } + table.Append(tableRow) + } + + table.Render() + + return nil + }, +} diff --git a/pkg/config/app.go b/pkg/config/app.go index 2ba2143d..65b3d2a2 100644 --- a/pkg/config/app.go +++ b/pkg/config/app.go @@ -45,9 +45,9 @@ type App struct { Path string } -// StackName gets what the docker safe stack name is for the app. This should -// not not shown to the user, use a.Name for that. Give the output of this -// command to Docker only. +// StackName gets whatever the docker safe (uses the right delimiting +// character, e.g. "_") stack name is for the app. In general, you don't want +// to use this to show anything to end-users, you want use a.Name instead. func (a App) StackName() string { if _, exists := a.Env["STACK_NAME"]; exists { return a.Env["STACK_NAME"]