package app import ( "fmt" "sort" "strings" abraFormatter "coopcloud.tech/abra/cli/formatter" "coopcloud.tech/abra/cli/internal" appPkg "coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/client/stack" "coopcloud.tech/abra/pkg/config" "github.com/docker/distribution/reference" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" ) // getImagePath returns the image name func getImagePath(image string) (string, error) { img, err := reference.ParseNormalizedNamed(image) if err != nil { return "", err } path := reference.Path(img) if strings.Contains(path, "library") { path = strings.Split(path, "/")[1] } logrus.Debugf("parsed '%s' from '%s'", path, image) return path, nil } var appVersionCommand = &cli.Command{ Name: "version", Aliases: []string{"v"}, Usage: "Show version of all services in app", Action: func(c *cli.Context) error { app := internal.ValidateApp(c) composeFiles, err := config.GetAppComposeFiles(app.Type, app.Env) if err != nil { logrus.Fatal(err) } opts := stack.Deploy{Composefiles: composeFiles} compose, err := config.GetAppComposeConfig(app.Type, opts, app.Env) if err != nil { logrus.Fatal(err) } ch := make(chan stack.StackStatus, len(compose.Services)) for _, service := range compose.Services { label := fmt.Sprintf("coop-cloud.%s.%s.version", app.StackName(), service.Name) go func(s string, l string) { ch <- stack.GetDeployedServicesByLabel(s, l) }(app.Server, label) } tableCol := []string{"name", "image", "version", "digest"} table := abraFormatter.CreateTable(tableCol) statuses := make(map[string]stack.StackStatus) for range compose.Services { status := <-ch if len(status.Services) > 0 { serviceName := appPkg.ParseServiceName(status.Services[0].Spec.Name) statuses[serviceName] = status } } sort.SliceStable(compose.Services, func(i, j int) bool { return compose.Services[i].Name < compose.Services[j].Name }) for _, service := range compose.Services { if status, ok := statuses[service.Name]; ok { statusService := status.Services[0] label := fmt.Sprintf("coop-cloud.%s.%s.version", app.StackName(), service.Name) version, digest := appPkg.ParseVersionLabel(statusService.Spec.Labels[label]) image, err := getImagePath(statusService.Spec.Labels["com.docker.stack.image"]) if err != nil { logrus.Fatal(err) } table.Append([]string{service.Name, image, version, digest}) continue } image, err := getImagePath(service.Image) if err != nil { logrus.Fatal(err) } table.Append([]string{service.Name, image, "?", "?"}) } table.Render() return nil }, BashComplete: func(c *cli.Context) { appNames, err := config.GetAppNames() if err != nil { return } if c.NArg() > 0 { return } for _, a := range appNames { fmt.Println(a) } }, }