feat: support version/upgrade listing
Closes coop-cloud/organising#130.
This commit is contained in:
parent
98ffc210e1
commit
dde8afcd43
|
@ -2,8 +2,10 @@ package app
|
|||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
||||
"coopcloud.tech/abra/pkg/catalogue"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
@ -65,10 +67,10 @@ can take some time.
|
|||
}
|
||||
sort.Sort(config.ByServerAndType(apps))
|
||||
|
||||
statuses := map[string]string{}
|
||||
statuses := make(map[string]map[string]string)
|
||||
tableCol := []string{"Server", "Type", "Domain"}
|
||||
if status {
|
||||
tableCol = append(tableCol, "Status")
|
||||
tableCol = append(tableCol, "Status", "Version", "Updates")
|
||||
statuses, err = config.GetAppStatuses(appFiles)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
|
@ -84,11 +86,38 @@ can take some time.
|
|||
// If type flag is set, check for it, if not, Type == ""
|
||||
tableRow = []string{app.Server, app.Type, app.Domain}
|
||||
if status {
|
||||
if status, ok := statuses[app.StackName()]; ok {
|
||||
tableRow = append(tableRow, status)
|
||||
stackName := app.StackName()
|
||||
if app.Env["STACK_NAME"] != "" {
|
||||
stackName = app.Env["STACK_NAME"]
|
||||
}
|
||||
|
||||
var version string
|
||||
if status, ok := statuses[stackName]; ok {
|
||||
version = status["version"]
|
||||
tableRow = append(tableRow, status["status"], version)
|
||||
} else {
|
||||
tableRow = append(tableRow, "unknown")
|
||||
}
|
||||
|
||||
var newUpdates []string
|
||||
updates, err := catalogue.GetRecipeCatalogueVersions(app.Type)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
for _, update := range updates {
|
||||
if update != version {
|
||||
newUpdates = append(newUpdates, update)
|
||||
}
|
||||
}
|
||||
if len(newUpdates) == 0 {
|
||||
tableRow = append(tableRow, "none, on latest")
|
||||
} else {
|
||||
// FIXME: jeezus golang why do you not have a list reverse function
|
||||
for i, j := 0, len(newUpdates)-1; i < j; i, j = i+1, j-1 {
|
||||
newUpdates[i], newUpdates[j] = newUpdates[j], newUpdates[i]
|
||||
}
|
||||
tableRow = append(tableRow, strings.Join(newUpdates, "\n"))
|
||||
}
|
||||
}
|
||||
}
|
||||
table.Append(tableRow)
|
||||
|
|
|
@ -63,7 +63,7 @@ var appRemoveCommand = &cli.Command{
|
|||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
if statuses[app.Name] == "deployed" {
|
||||
if statuses[app.Name]["status"] == "deployed" {
|
||||
logrus.Fatalf("'%s' is still deployed. Run \"abra app %s undeploy\" or pass --force", app.Name, app.Name)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package recipe
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
|
@ -14,17 +15,18 @@ var recipeSyncCommand = &cli.Command{
|
|||
Name: "sync",
|
||||
Usage: "Ensure recipe version labels are up-to-date",
|
||||
Aliases: []string{"s"},
|
||||
ArgsUsage: "<recipe> <version>",
|
||||
Description: `
|
||||
This command will generate labels for the main recipe service (i.e. the service
|
||||
named "app", by convention) which corresponds to the following format:
|
||||
This command will generate labels for the main recipe service (i.e. by
|
||||
convention, typically the service named "app") which corresponds to the
|
||||
following format:
|
||||
|
||||
coop-cloud.${STACK_NAME}.version=${RECIPE_TAG}
|
||||
coop-cloud.${STACK_NAME}.version=<version>
|
||||
|
||||
The ${RECIPE_TAG} is determined by the recipe maintainer and is retrieved by
|
||||
this command by asking for the list of git tags on the local git repository.
|
||||
The <recipe> configuration will be updated on the local file system.
|
||||
The <version> is determined by the recipe maintainer and is specified on the
|
||||
command-line. The <recipe> configuration will be updated on the local file
|
||||
system.
|
||||
`,
|
||||
ArgsUsage: "<recipe>",
|
||||
BashComplete: func(c *cli.Context) {
|
||||
catl, err := catalogue.ReadRecipeCatalogue()
|
||||
if err != nil {
|
||||
|
@ -38,10 +40,17 @@ The <recipe> configuration will be updated on the local file system.
|
|||
}
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.Args().Len() != 2 {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("missing <recipe>/<version> arguments?"))
|
||||
}
|
||||
|
||||
recipe := internal.ValidateRecipe(c)
|
||||
|
||||
mainService := "app"
|
||||
// TODO: validate with tagcmp when new commits come in
|
||||
// See https://git.coopcloud.tech/coop-cloud/abra/pulls/109
|
||||
nextTag := c.Args().Get(1)
|
||||
|
||||
mainService := "app"
|
||||
var services []string
|
||||
hasAppService := false
|
||||
for _, service := range recipe.Config.Services {
|
||||
|
@ -67,24 +76,12 @@ The <recipe> configuration will be updated on the local file system.
|
|||
|
||||
logrus.Debugf("selecting '%s' as the service to sync version labels", mainService)
|
||||
|
||||
tags, err := recipe.Tags()
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
if len(tags) == 0 {
|
||||
logrus.Fatalf("no tags detected for '%s'", recipe.Name)
|
||||
}
|
||||
|
||||
latestTag := tags[len(tags)-1]
|
||||
logrus.Infof("choosing '%s' as latest tag for recipe '%s'", latestTag, recipe.Name)
|
||||
|
||||
label := fmt.Sprintf("coop-cloud.${STACK_NAME}.version=%s", latestTag)
|
||||
label := fmt.Sprintf("coop-cloud.${STACK_NAME}.version=%s", nextTag)
|
||||
if err := recipe.UpdateLabel(mainService, label); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
logrus.Infof("added label '%s' to service '%s'", label, mainService)
|
||||
logrus.Infof("synced label '%s' to service '%s'", label, mainService)
|
||||
|
||||
return nil
|
||||
},
|
||||
|
|
|
@ -480,3 +480,23 @@ func GetRecipeVersions(recipeName string) (RecipeVersions, error) {
|
|||
|
||||
return versions, nil
|
||||
}
|
||||
|
||||
// GetRecipeCatalogueVersions list the recipe versions listed in the recipe catalogue.
|
||||
func GetRecipeCatalogueVersions(recipeName string) ([]string, error) {
|
||||
var versions []string
|
||||
|
||||
catl, err := ReadRecipeCatalogue()
|
||||
if err != nil {
|
||||
return versions, err
|
||||
}
|
||||
|
||||
if recipeMeta, exists := catl[recipeName]; exists {
|
||||
for _, versionMeta := range recipeMeta.Versions {
|
||||
for tag := range versionMeta {
|
||||
versions = append(versions, tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return versions, nil
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ func UpdateLabel(pattern, serviceName, label, recipeName string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
old := fmt.Sprintf("coop-cloud.${STACK_NAME}.%s.version=%s", service.Name, value)
|
||||
old := fmt.Sprintf("coop-cloud.${STACK_NAME}.version=%s", value)
|
||||
replacedBytes := strings.Replace(string(bytes), old, label, -1)
|
||||
|
||||
logrus.Debugf("updating '%s' to '%s' in '%s'", old, label, compose.Filename)
|
||||
|
|
|
@ -276,8 +276,8 @@ func SanitiseAppName(name string) string {
|
|||
}
|
||||
|
||||
// GetAppStatuses queries servers to check the deployment status of given apps
|
||||
func GetAppStatuses(appFiles AppFiles) (map[string]string, error) {
|
||||
statuses := map[string]string{}
|
||||
func GetAppStatuses(appFiles AppFiles) (map[string]map[string]string, error) {
|
||||
statuses := make(map[string]map[string]string)
|
||||
|
||||
var unique []string
|
||||
servers := make(map[string]struct{})
|
||||
|
@ -299,11 +299,20 @@ func GetAppStatuses(appFiles AppFiles) (map[string]string, error) {
|
|||
|
||||
for range servers {
|
||||
status := <-ch
|
||||
result := make(map[string]string)
|
||||
for _, service := range status.Services {
|
||||
name := service.Spec.Labels[convert.LabelNamespace]
|
||||
|
||||
if _, ok := statuses[name]; !ok {
|
||||
statuses[name] = "deployed"
|
||||
result["status"] = "deployed"
|
||||
}
|
||||
|
||||
labelKey := fmt.Sprintf("coop-cloud.%s.version", name)
|
||||
if version, ok := service.Spec.Labels[labelKey]; ok {
|
||||
result["version"] = version
|
||||
}
|
||||
|
||||
statuses[name] = result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue