forked from coop-cloud/abra
fix: teach app version command to read new versions
This commit is contained in:
parent
b69aed3bcf
commit
d0828c4d8d
@ -2,12 +2,12 @@ package app
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
appPkg "coopcloud.tech/abra/pkg/app"
|
"coopcloud.tech/abra/pkg/catalogue"
|
||||||
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/client/stack"
|
"coopcloud.tech/abra/pkg/client/stack"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
@ -32,65 +32,56 @@ func getImagePath(image string) (string, error) {
|
|||||||
var appVersionCommand = &cli.Command{
|
var appVersionCommand = &cli.Command{
|
||||||
Name: "version",
|
Name: "version",
|
||||||
Aliases: []string{"v"},
|
Aliases: []string{"v"},
|
||||||
Usage: "Show version of all services in app",
|
Usage: "Show app version",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
app := internal.ValidateApp(c)
|
app := internal.ValidateApp(c)
|
||||||
|
stackName := app.StackName()
|
||||||
|
|
||||||
composeFiles, err := config.GetAppComposeFiles(app.Type, app.Env)
|
cl, err := client.New(app.Server)
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
opts := stack.Deploy{Composefiles: composeFiles}
|
|
||||||
compose, err := config.GetAppComposeConfig(app.Type, opts, app.Env)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch := make(chan stack.StackStatus, len(compose.Services))
|
logrus.Debugf("checking whether '%s' is already deployed", stackName)
|
||||||
for _, service := range compose.Services {
|
|
||||||
label := fmt.Sprintf("coop-cloud.%s.%s.version", app.StackName(), service.Name)
|
isDeployed, deployedVersion, err := stack.IsDeployed(c.Context, cl, stackName)
|
||||||
go func(s string, l string) {
|
if err != nil {
|
||||||
ch <- stack.GetDeployedServicesByLabel(s, l)
|
logrus.Fatal(err)
|
||||||
}(app.Server, label)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tableCol := []string{"name", "image", "version", "digest"}
|
if deployedVersion == "" {
|
||||||
|
logrus.Fatalf("failed to determine version of deployed '%s'", app.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isDeployed {
|
||||||
|
logrus.Fatalf("'%s' is not deployed?", app.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
recipeMeta, err := catalogue.GetRecipeMeta(app.Type)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
versionsMeta := make(map[string]catalogue.ServiceMeta)
|
||||||
|
for _, recipeVersion := range recipeMeta.Versions {
|
||||||
|
if currentVersion, exists := recipeVersion[deployedVersion]; exists {
|
||||||
|
versionsMeta = currentVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(versionsMeta) == 0 {
|
||||||
|
logrus.Fatalf("PANIC: could not retrieve deployed version ('%s') from recipe catalogue?", deployedVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
tableCol := []string{"name", "image", "version", "tag", "digest"}
|
||||||
table := abraFormatter.CreateTable(tableCol)
|
table := abraFormatter.CreateTable(tableCol)
|
||||||
|
|
||||||
statuses := make(map[string]stack.StackStatus)
|
for serviceName, versionMeta := range versionsMeta {
|
||||||
for range compose.Services {
|
table.Append([]string{serviceName, versionMeta.Image, deployedVersion, versionMeta.Tag, versionMeta.Digest})
|
||||||
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()
|
table.Render()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
BashComplete: func(c *cli.Context) {
|
BashComplete: func(c *cli.Context) {
|
||||||
|
@ -54,15 +54,15 @@ type tag = string
|
|||||||
// service represents a service within a recipe.
|
// service represents a service within a recipe.
|
||||||
type service = string
|
type service = string
|
||||||
|
|
||||||
// serviceMeta represents meta info associated with a service.
|
// ServiceMeta represents meta info associated with a service.
|
||||||
type serviceMeta struct {
|
type ServiceMeta struct {
|
||||||
Digest string `json:"digest"`
|
Digest string `json:"digest"`
|
||||||
Image string `json:"image"`
|
Image string `json:"image"`
|
||||||
Tag string `json:"tag"`
|
Tag string `json:"tag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecipeVersions are the versions associated with a recipe.
|
// RecipeVersions are the versions associated with a recipe.
|
||||||
type RecipeVersions []map[tag]map[service]serviceMeta
|
type RecipeVersions []map[tag]map[service]ServiceMeta
|
||||||
|
|
||||||
// RecipeMeta represents metadata for a recipe in the abra catalogue.
|
// RecipeMeta represents metadata for a recipe in the abra catalogue.
|
||||||
type RecipeMeta struct {
|
type RecipeMeta struct {
|
||||||
@ -420,7 +420,7 @@ func GetRecipeVersions(recipeName string) (RecipeVersions, error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
versionMeta := make(map[string]serviceMeta)
|
versionMeta := make(map[string]ServiceMeta)
|
||||||
for _, service := range recipe.Config.Services {
|
for _, service := range recipe.Config.Services {
|
||||||
|
|
||||||
img, err := reference.ParseNormalizedNamed(service.Image)
|
img, err := reference.ParseNormalizedNamed(service.Image)
|
||||||
@ -438,7 +438,7 @@ func GetRecipeVersions(recipeName string) (RecipeVersions, error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
versionMeta[service.Name] = serviceMeta{
|
versionMeta[service.Name] = ServiceMeta{
|
||||||
Digest: digest,
|
Digest: digest,
|
||||||
Image: path,
|
Image: path,
|
||||||
Tag: img.(reference.NamedTagged).Tag(),
|
Tag: img.(reference.NamedTagged).Tag(),
|
||||||
@ -447,7 +447,7 @@ func GetRecipeVersions(recipeName string) (RecipeVersions, error) {
|
|||||||
logrus.Debugf("collecting digest: '%s', image: '%s', tag: '%s'", digest, path, tag)
|
logrus.Debugf("collecting digest: '%s', image: '%s', tag: '%s'", digest, path, tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
versions = append(versions, map[string]map[string]serviceMeta{tag: versionMeta})
|
versions = append(versions, map[string]map[string]ServiceMeta{tag: versionMeta})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
@ -93,6 +93,19 @@ func GetAllDeployedServices(contextName string) StackStatus {
|
|||||||
return StackStatus{services, nil}
|
return StackStatus{services, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDeployedServicesByName filters services by name
|
||||||
|
func GetDeployedServicesByName(ctx context.Context, cl *dockerclient.Client, stackName, serviceName string) StackStatus {
|
||||||
|
filters := filters.NewArgs()
|
||||||
|
filters.Add("name", fmt.Sprintf("%s_%s", stackName, serviceName))
|
||||||
|
|
||||||
|
services, err := cl.ServiceList(ctx, types.ServiceListOptions{Filters: filters})
|
||||||
|
if err != nil {
|
||||||
|
return StackStatus{[]swarm.Service{}, err}
|
||||||
|
}
|
||||||
|
|
||||||
|
return StackStatus{services, nil}
|
||||||
|
}
|
||||||
|
|
||||||
// IsDeployed chekcks whether an appp is deployed or not.
|
// IsDeployed chekcks whether an appp is deployed or not.
|
||||||
func IsDeployed(ctx context.Context, cl *dockerclient.Client, stackName string) (bool, string, error) {
|
func IsDeployed(ctx context.Context, cl *dockerclient.Client, stackName string) (bool, string, error) {
|
||||||
version := ""
|
version := ""
|
||||||
|
Loading…
Reference in New Issue
Block a user