package app import ( "context" "fmt" "sort" "coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/log" "coopcloud.tech/abra/pkg/upstream/convert" composetypes "github.com/docker/cli/cli/compose/types" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" dockerClient "github.com/docker/docker/client" "github.com/spf13/cobra" ) var AppLabelsCommand = &cobra.Command{ Use: "labels [flags]", Aliases: []string{"lb"}, Short: "Show deployment labels", Long: "Both local recipe and live deployment labels are shown.", Example: " abra app labels 1312.net", Args: cobra.ExactArgs(1), ValidArgsFunction: func( cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return autocomplete.AppNameComplete() }, Run: func(cmd *cobra.Command, args []string) { app := internal.ValidateApp(args) if err := app.Recipe.Ensure(internal.GetEnsureContext()); err != nil { log.Fatal(err) } cl, err := client.New(app.Server) if err != nil { log.Fatal(err) } remoteLabels, err := getLabels(cl, app.StackName()) if err != nil { log.Fatal(err) } rows := [][]string{ {"DEPLOYED LABELS", "---"}, } remoteLabelKeys := make([]string, 0, len(remoteLabels)) for k := range remoteLabels { remoteLabelKeys = append(remoteLabelKeys, k) } sort.Strings(remoteLabelKeys) for _, k := range remoteLabelKeys { rows = append(rows, []string{ k, remoteLabels[k], }) } if len(remoteLabelKeys) == 0 { rows = append(rows, []string{"unknown"}) } rows = append(rows, []string{"RECIPE LABELS", "---"}) config, err := app.Recipe.GetComposeConfig(app.Env) if err != nil { log.Fatal(err) } var localLabelKeys []string var appServiceConfig composetypes.ServiceConfig for _, service := range config.Services { if service.Name == "app" { appServiceConfig = service for k := range service.Deploy.Labels { localLabelKeys = append(localLabelKeys, k) } } } sort.Strings(localLabelKeys) for _, k := range localLabelKeys { rows = append(rows, []string{ k, appServiceConfig.Deploy.Labels[k], }) } overview := formatter.CreateOverview("LABELS OVERVIEW", rows) fmt.Println(overview) }, } // getLabels reads docker labels from running services in the format of "coop-cloud.${STACK_NAME}.${LABEL}". func getLabels(cl *dockerClient.Client, stackName string) (map[string]string, error) { labels := make(map[string]string) filter := filters.NewArgs() filter.Add("label", fmt.Sprintf("%s=%s", convert.LabelNamespace, stackName)) services, err := cl.ServiceList(context.Background(), types.ServiceListOptions{Filters: filter}) if err != nil { return labels, err } for _, service := range services { if service.Spec.Name != fmt.Sprintf("%s_app", stackName) { continue } for k, v := range service.Spec.Labels { labels[k] = v } } return labels, nil } func init() { AppLabelsCommand.Flags().BoolVarP( &internal.Chaos, "chaos", "C", false, "ignore uncommitted recipes changes", ) }