forked from toolshed/abra
Compare commits
20 Commits
0.1.7-alph
...
0.1.8-alph
Author | SHA1 | Date | |
---|---|---|---|
4235e06943 | |||
a9af0b3627 | |||
a0b4886eba | |||
84489495dc | |||
a8683dc38a | |||
e2128ea5b6 | |||
ca3c5fef0f | |||
4a01e411be | |||
777d49ac1d | |||
deb7d21158 | |||
6db1fdcfba | |||
44dc0edf7b | |||
36ff50312c
|
|||
ff4b978876 | |||
b68547b2c2 | |||
0140f96ca1 | |||
1cb45113db | |||
c764243f3a | |||
dde8afcd43 | |||
98ffc210e1 |
@ -28,7 +28,7 @@ checksum:
|
|||||||
snapshot:
|
snapshot:
|
||||||
name_template: "{{ incpatch .Version }}-next"
|
name_template: "{{ incpatch .Version }}-next"
|
||||||
changelog:
|
changelog:
|
||||||
sort: asc
|
sort: desc
|
||||||
filters:
|
filters:
|
||||||
exclude:
|
exclude:
|
||||||
- "^WIP:"
|
- "^WIP:"
|
||||||
|
@ -32,17 +32,13 @@ var appDeployCommand = &cli.Command{
|
|||||||
app.Env[k] = v
|
app.Env[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exists := app.Env["STACK_NAME"]; !exists {
|
|
||||||
app.Env["STACK_NAME"] = app.StackName()
|
|
||||||
}
|
|
||||||
|
|
||||||
composeFiles, err := config.GetAppComposeFiles(app.Type, app.Env)
|
composeFiles, err := config.GetAppComposeFiles(app.Type, app.Env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
deployOpts := stack.Deploy{
|
deployOpts := stack.Deploy{
|
||||||
Composefiles: composeFiles,
|
Composefiles: composeFiles,
|
||||||
Namespace: app.Env["STACK_NAME"],
|
Namespace: app.StackName(),
|
||||||
Prune: false,
|
Prune: false,
|
||||||
ResolveImage: stack.ResolveImageAlways,
|
ResolveImage: stack.ResolveImageAlways,
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,12 @@ package app
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
||||||
|
"coopcloud.tech/abra/pkg/catalogue"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
|
"coopcloud.tech/tagcmp"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
@ -65,10 +68,10 @@ can take some time.
|
|||||||
}
|
}
|
||||||
sort.Sort(config.ByServerAndType(apps))
|
sort.Sort(config.ByServerAndType(apps))
|
||||||
|
|
||||||
statuses := map[string]string{}
|
statuses := make(map[string]map[string]string)
|
||||||
tableCol := []string{"Server", "Type", "Domain"}
|
tableCol := []string{"Server", "Type", "Domain"}
|
||||||
if status {
|
if status {
|
||||||
tableCol = append(tableCol, "Status")
|
tableCol = append(tableCol, "Status", "Version", "Updates")
|
||||||
statuses, err = config.GetAppStatuses(appFiles)
|
statuses, err = config.GetAppStatuses(appFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
@ -84,10 +87,57 @@ can take some time.
|
|||||||
// If type flag is set, check for it, if not, Type == ""
|
// If type flag is set, check for it, if not, Type == ""
|
||||||
tableRow = []string{app.Server, app.Type, app.Domain}
|
tableRow = []string{app.Server, app.Type, app.Domain}
|
||||||
if status {
|
if status {
|
||||||
if status, ok := statuses[app.StackName()]; ok {
|
stackName := app.StackName()
|
||||||
tableRow = append(tableRow, status)
|
status := "unknown"
|
||||||
|
version := "unknown"
|
||||||
|
if statusMeta, ok := statuses[stackName]; ok {
|
||||||
|
if currentVersion, exists := statusMeta["version"]; exists {
|
||||||
|
version = currentVersion
|
||||||
|
}
|
||||||
|
if statusMeta["status"] != "" {
|
||||||
|
status = statusMeta["status"]
|
||||||
|
}
|
||||||
|
tableRow = append(tableRow, status, version)
|
||||||
} else {
|
} else {
|
||||||
tableRow = append(tableRow, "unknown")
|
tableRow = append(tableRow, status, version)
|
||||||
|
}
|
||||||
|
|
||||||
|
var newUpdates []string
|
||||||
|
if version != "unknown" {
|
||||||
|
updates, err := catalogue.GetRecipeCatalogueVersions(app.Type)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedVersion, err := tagcmp.Parse(version)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, update := range updates {
|
||||||
|
parsedUpdate, err := tagcmp.Parse(update)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if update != version && parsedUpdate.IsGreaterThan(parsedVersion) {
|
||||||
|
newUpdates = append(newUpdates, update)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(newUpdates) == 0 {
|
||||||
|
if version == "unknown" {
|
||||||
|
tableRow = append(tableRow, "unknown")
|
||||||
|
} else {
|
||||||
|
tableRow = append(tableRow, "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"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ var appRemoveCommand = &cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
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)
|
logrus.Fatalf("'%s' is still deployed. Run \"abra app %s undeploy\" or pass --force", app.Name, app.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/formatter"
|
"coopcloud.tech/abra/cli/formatter"
|
||||||
@ -143,8 +144,26 @@ var catalogueGenerateCommand = &cli.Command{
|
|||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ioutil.WriteFile(config.APPS_JSON, recipesJSON, 0644); err != nil {
|
if _, err := os.Stat(config.APPS_JSON); err != nil && os.IsNotExist(err) {
|
||||||
logrus.Fatal(err)
|
if err := ioutil.WriteFile(config.APPS_JSON, recipesJSON, 0644); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if recipeName != "" {
|
||||||
|
catlFS, err := catalogue.ReadRecipeCatalogue()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
catlFS[recipeName] = catl[recipeName]
|
||||||
|
|
||||||
|
updatedRecipesJSON, err := json.MarshalIndent(catlFS, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := ioutil.WriteFile(config.APPS_JSON, updatedRecipesJSON, 0644); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Infof("generated new recipe catalogue in '%s'", config.APPS_JSON)
|
logrus.Infof("generated new recipe catalogue in '%s'", config.APPS_JSON)
|
||||||
|
@ -41,6 +41,10 @@ func ValidateApp(c *cli.Context) config.App {
|
|||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := recipe.EnsureExists(app.Type); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
logrus.Debugf("validated '%s' as app argument", appName)
|
logrus.Debugf("validated '%s' as app argument", appName)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
@ -9,11 +9,11 @@ import (
|
|||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
"coopcloud.tech/abra/pkg/recipe"
|
"coopcloud.tech/abra/pkg/recipe"
|
||||||
|
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||||
"coopcloud.tech/tagcmp"
|
"coopcloud.tech/tagcmp"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
"github.com/go-git/go-git/v5/plumbing/object"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
@ -50,6 +50,14 @@ var CommitFlag = &cli.BoolFlag{
|
|||||||
Destination: &Commit,
|
Destination: &Commit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var TagMessage string
|
||||||
|
var TagMessageFlag = &cli.StringFlag{
|
||||||
|
Name: "tag-comment",
|
||||||
|
Usage: "tag comment. If not given, user will be asked for it",
|
||||||
|
Aliases: []string{"t", "tm"},
|
||||||
|
Destination: &TagMessage,
|
||||||
|
}
|
||||||
|
|
||||||
var recipeReleaseCommand = &cli.Command{
|
var recipeReleaseCommand = &cli.Command{
|
||||||
Name: "release",
|
Name: "release",
|
||||||
Usage: "tag a recipe",
|
Usage: "tag a recipe",
|
||||||
@ -84,6 +92,7 @@ or a rollback of an app.
|
|||||||
PushFlag,
|
PushFlag,
|
||||||
CommitFlag,
|
CommitFlag,
|
||||||
CommitMessageFlag,
|
CommitMessageFlag,
|
||||||
|
TagMessageFlag,
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
recipe := internal.ValidateRecipe(c)
|
recipe := internal.ValidateRecipe(c)
|
||||||
@ -92,17 +101,31 @@ or a rollback of an app.
|
|||||||
imagesTmp := getImageVersions(recipe)
|
imagesTmp := getImageVersions(recipe)
|
||||||
mainApp := getMainApp(recipe)
|
mainApp := getMainApp(recipe)
|
||||||
mainAppVersion := imagesTmp[mainApp]
|
mainAppVersion := imagesTmp[mainApp]
|
||||||
|
|
||||||
|
if err := recipePkg.EnsureExists(recipe.Name); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
if mainAppVersion == "" {
|
if mainAppVersion == "" {
|
||||||
logrus.Fatal("main app version is empty?")
|
logrus.Fatal("main app version is empty?")
|
||||||
}
|
}
|
||||||
|
|
||||||
if tagstring != "" {
|
if tagstring != "" {
|
||||||
_, err := tagcmp.Parse(tagstring)
|
if _, err := tagcmp.Parse(tagstring); err != nil {
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal("invalid tag specified")
|
logrus.Fatal("invalid tag specified")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if TagMessage == "" {
|
||||||
|
prompt := &survey.Input{
|
||||||
|
Message: "tag message",
|
||||||
|
}
|
||||||
|
survey.AskOne(prompt, &TagMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
var createTagOptions git.CreateTagOptions
|
||||||
|
createTagOptions.Message = TagMessage
|
||||||
|
|
||||||
if Commit || (CommitMessage != "") {
|
if Commit || (CommitMessage != "") {
|
||||||
commitRepo, err := git.PlainOpen(directory)
|
commitRepo, err := git.PlainOpen(directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -172,9 +195,7 @@ or a rollback of an app.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.CreateTag(tagstring, head.Hash(), nil) /* &git.CreateTagOptions{
|
repo.CreateTag(tagstring, head.Hash(), &createTagOptions)
|
||||||
Message: tag,
|
|
||||||
})*/
|
|
||||||
logrus.Info(fmt.Sprintf("created tag %s at %s", tagstring, head.Hash()))
|
logrus.Info(fmt.Sprintf("created tag %s at %s", tagstring, head.Hash()))
|
||||||
if Push {
|
if Push {
|
||||||
if err := repo.Push(&git.PushOptions{}); err != nil {
|
if err := repo.Push(&git.PushOptions{}); err != nil {
|
||||||
@ -187,27 +208,33 @@ or a rollback of an app.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the latest tag with its hash, name etc
|
// get the latest tag with its hash, name etc
|
||||||
var lastGitTag *object.Tag
|
var lastGitTag tagcmp.Tag
|
||||||
iter, err := repo.Tags()
|
iter, err := repo.Tags()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := iter.ForEach(func(ref *plumbing.Reference) error {
|
if err := iter.ForEach(func(ref *plumbing.Reference) error {
|
||||||
obj, err := repo.TagObject(ref.Hash())
|
obj, err := repo.TagObject(ref.Hash())
|
||||||
if err == nil {
|
if err != nil {
|
||||||
lastGitTag = obj
|
return err
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return err
|
tagcmpTag, err := tagcmp.Parse(obj.Name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if (lastGitTag == tagcmp.Tag{}) {
|
||||||
|
lastGitTag = tagcmpTag
|
||||||
|
} else if tagcmpTag.IsGreaterThan(lastGitTag) {
|
||||||
|
lastGitTag = tagcmpTag
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
newTag, err := tagcmp.Parse(lastGitTag.Name)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
fmt.Println(lastGitTag)
|
||||||
|
|
||||||
|
newTag := lastGitTag
|
||||||
var newTagString string
|
var newTagString string
|
||||||
if bumpType > 0 {
|
if bumpType > 0 {
|
||||||
if Patch {
|
if Patch {
|
||||||
@ -232,20 +259,17 @@ or a rollback of an app.
|
|||||||
newTag.Minor = "0"
|
newTag.Minor = "0"
|
||||||
newTag.Major = strconv.Itoa(now + 1)
|
newTag.Major = strconv.Itoa(now + 1)
|
||||||
}
|
}
|
||||||
newTagString = newTag.String()
|
|
||||||
} else {
|
} else {
|
||||||
logrus.Fatal("we don't support automatic tag generation yet - specify a version or use one of: --major --minor --patch")
|
logrus.Fatal("we don't support automatic tag generation yet - specify a version or use one of: --major --minor --patch")
|
||||||
}
|
}
|
||||||
|
newTag.Metadata = mainAppVersion
|
||||||
newTagString = fmt.Sprintf("%s+%s", newTagString, mainAppVersion)
|
newTagString = newTag.String()
|
||||||
if Dry {
|
if Dry {
|
||||||
logrus.Info(fmt.Sprintf("dry run only: NOT creating tag %s at %s", newTagString, head.Hash()))
|
logrus.Info(fmt.Sprintf("dry run only: NOT creating tag %s at %s", newTagString, head.Hash()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.CreateTag(newTagString, head.Hash(), nil) /* &git.CreateTagOptions{
|
repo.CreateTag(newTagString, head.Hash(), &createTagOptions)
|
||||||
Message: tag,
|
|
||||||
})*/
|
|
||||||
logrus.Info(fmt.Sprintf("created tag %s at %s", newTagString, head.Hash()))
|
logrus.Info(fmt.Sprintf("created tag %s at %s", newTagString, head.Hash()))
|
||||||
if Push {
|
if Push {
|
||||||
if err := repo.Push(&git.PushOptions{}); err != nil {
|
if err := repo.Push(&git.PushOptions{}); err != nil {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package recipe
|
package recipe
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
@ -11,20 +12,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var recipeSyncCommand = &cli.Command{
|
var recipeSyncCommand = &cli.Command{
|
||||||
Name: "sync",
|
Name: "sync",
|
||||||
Usage: "Ensure recipe version labels are up-to-date",
|
Usage: "Ensure recipe version labels are up-to-date",
|
||||||
Aliases: []string{"s"},
|
Aliases: []string{"s"},
|
||||||
|
ArgsUsage: "<recipe> <version>",
|
||||||
Description: `
|
Description: `
|
||||||
This command will generate labels for the main recipe service (i.e. the service
|
This command will generate labels for the main recipe service (i.e. by
|
||||||
named "app", by convention) which corresponds to the following format:
|
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
|
The <version> is determined by the recipe maintainer and is specified on the
|
||||||
this command by asking for the list of git tags on the local git repository.
|
command-line. The <recipe> configuration will be updated on the local file
|
||||||
The <recipe> configuration will be updated on the local file system.
|
system.
|
||||||
`,
|
`,
|
||||||
ArgsUsage: "<recipe>",
|
|
||||||
BashComplete: func(c *cli.Context) {
|
BashComplete: func(c *cli.Context) {
|
||||||
catl, err := catalogue.ReadRecipeCatalogue()
|
catl, err := catalogue.ReadRecipeCatalogue()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -38,10 +40,17 @@ The <recipe> configuration will be updated on the local file system.
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
|
if c.Args().Len() != 2 {
|
||||||
|
internal.ShowSubcommandHelpAndError(c, errors.New("missing <recipe>/<version> arguments?"))
|
||||||
|
}
|
||||||
|
|
||||||
recipe := internal.ValidateRecipe(c)
|
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
|
var services []string
|
||||||
hasAppService := false
|
hasAppService := false
|
||||||
for _, service := range recipe.Config.Services {
|
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)
|
logrus.Debugf("selecting '%s' as the service to sync version labels", mainService)
|
||||||
|
|
||||||
tags, err := recipe.Tags()
|
label := fmt.Sprintf("coop-cloud.${STACK_NAME}.version=%s", nextTag)
|
||||||
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)
|
|
||||||
if err := recipe.UpdateLabel(mainService, label); err != nil {
|
if err := recipe.UpdateLabel(mainService, label); err != nil {
|
||||||
logrus.Fatal(err)
|
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
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -120,11 +120,11 @@ is up to the end-user to decide.
|
|||||||
var upgradeTag string
|
var upgradeTag string
|
||||||
if bumpType != 0 {
|
if bumpType != 0 {
|
||||||
for _, upTag := range compatible {
|
for _, upTag := range compatible {
|
||||||
upElement, err := tag.UpgradeElement(upTag)
|
upElement, err := tag.UpgradeDelta(upTag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
delta := tagcmp.UpgradeType(upElement)
|
delta := upElement.UpgradeType()
|
||||||
if delta <= bumpType {
|
if delta <= bumpType {
|
||||||
upgradeTag = upTag.String()
|
upgradeTag = upTag.String()
|
||||||
break
|
break
|
||||||
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module coopcloud.tech/abra
|
|||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
coopcloud.tech/tagcmp v0.0.0-20211003080922-7b06d1c16182
|
coopcloud.tech/tagcmp v0.0.0-20211011140827-4f27c74467eb
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.1
|
github.com/AlecAivazis/survey/v2 v2.3.1
|
||||||
github.com/Autonomic-Cooperative/godotenv v1.3.1-0.20210731170023-c37c0920d1a4
|
github.com/Autonomic-Cooperative/godotenv v1.3.1-0.20210731170023-c37c0920d1a4
|
||||||
github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4
|
github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4
|
||||||
|
10
go.sum
10
go.sum
@ -21,12 +21,10 @@ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIA
|
|||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||||
coopcloud.tech/tagcmp v0.0.0-20210906102006-2a8edd82d75d h1:5jeUIiToqQ7vTlLeycdGp4Ezurd6/RTNl5K38usHtoo=
|
coopcloud.tech/tagcmp v0.0.0-20211007122926-aa7b4ff851f6 h1:EV1aomKx6n0jLZ847ejeqroE4K9E+yX5NvEyQufkZVk=
|
||||||
coopcloud.tech/tagcmp v0.0.0-20210906102006-2a8edd82d75d/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
coopcloud.tech/tagcmp v0.0.0-20211007122926-aa7b4ff851f6/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
||||||
coopcloud.tech/tagcmp v0.0.0-20211003074705-03d2daced95c h1:7kCjnhjrOevcJeA/koCyyv20E6AglvqC7biGbLzyrbU=
|
coopcloud.tech/tagcmp v0.0.0-20211011140827-4f27c74467eb h1:Jf+Dnna2kXcNQvcA5JMp6d2Uyvg2pIVJfip9+X5FrH0=
|
||||||
coopcloud.tech/tagcmp v0.0.0-20211003074705-03d2daced95c/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
coopcloud.tech/tagcmp v0.0.0-20211011140827-4f27c74467eb/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
||||||
coopcloud.tech/tagcmp v0.0.0-20211003080922-7b06d1c16182 h1:VGFzudsoGXGRaw5eJE3rErHHUDsmuIJpQkdfKJgrNs4=
|
|
||||||
coopcloud.tech/tagcmp v0.0.0-20211003080922-7b06d1c16182/go.mod h1:ESVm0wQKcbcFi06jItF3rI7enf4Jt2PvbkWpDDHk1DQ=
|
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.1 h1:lzkuHA60pER7L4eYL8qQJor4bUWlJe4V0gqAT19tdOA=
|
github.com/AlecAivazis/survey/v2 v2.3.1 h1:lzkuHA60pER7L4eYL8qQJor4bUWlJe4V0gqAT19tdOA=
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.1/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg=
|
github.com/AlecAivazis/survey/v2 v2.3.1/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg=
|
||||||
|
@ -480,3 +480,23 @@ func GetRecipeVersions(recipeName string) (RecipeVersions, error) {
|
|||||||
|
|
||||||
return versions, nil
|
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
|
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)
|
replacedBytes := strings.Replace(string(bytes), old, label, -1)
|
||||||
|
|
||||||
logrus.Debugf("updating '%s' to '%s' in '%s'", old, label, compose.Filename)
|
logrus.Debugf("updating '%s' to '%s' in '%s'", old, label, compose.Filename)
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/formatter"
|
"coopcloud.tech/abra/cli/formatter"
|
||||||
@ -46,7 +45,12 @@ type App struct {
|
|||||||
|
|
||||||
// StackName gets what the docker safe stack name is for the app
|
// StackName gets what the docker safe stack name is for the app
|
||||||
func (a App) StackName() string {
|
func (a App) StackName() string {
|
||||||
return SanitiseAppName(a.Name)
|
if _, exists := a.Env["STACK_NAME"]; exists {
|
||||||
|
return a.Env["STACK_NAME"]
|
||||||
|
}
|
||||||
|
stackName := SanitiseAppName(a.Name)
|
||||||
|
a.Env["STACK_NAME"] = stackName
|
||||||
|
return stackName
|
||||||
}
|
}
|
||||||
|
|
||||||
// SORTING TYPES
|
// SORTING TYPES
|
||||||
@ -276,8 +280,8 @@ func SanitiseAppName(name string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAppStatuses queries servers to check the deployment status of given apps
|
// GetAppStatuses queries servers to check the deployment status of given apps
|
||||||
func GetAppStatuses(appFiles AppFiles) (map[string]string, error) {
|
func GetAppStatuses(appFiles AppFiles) (map[string]map[string]string, error) {
|
||||||
statuses := map[string]string{}
|
statuses := make(map[string]map[string]string)
|
||||||
|
|
||||||
var unique []string
|
var unique []string
|
||||||
servers := make(map[string]struct{})
|
servers := make(map[string]struct{})
|
||||||
@ -300,10 +304,24 @@ func GetAppStatuses(appFiles AppFiles) (map[string]string, error) {
|
|||||||
for range servers {
|
for range servers {
|
||||||
status := <-ch
|
status := <-ch
|
||||||
for _, service := range status.Services {
|
for _, service := range status.Services {
|
||||||
|
result := make(map[string]string)
|
||||||
name := service.Spec.Labels[convert.LabelNamespace]
|
name := service.Spec.Labels[convert.LabelNamespace]
|
||||||
|
|
||||||
if _, ok := statuses[name]; !ok {
|
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
|
||||||
|
} else {
|
||||||
|
//FIXME: we only need to check containers with the version label not
|
||||||
|
// every single container and then skip when we see no label perf gains
|
||||||
|
// to be had here
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
statuses[name] = result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,20 +333,18 @@ func GetAppStatuses(appFiles AppFiles) (map[string]string, error) {
|
|||||||
// GetAppComposeFiles gets the list of compose files for an app which should be
|
// GetAppComposeFiles gets the list of compose files for an app which should be
|
||||||
// merged into a composetypes.Config while respecting the COMPOSE_FILE env var.
|
// merged into a composetypes.Config while respecting the COMPOSE_FILE env var.
|
||||||
func GetAppComposeFiles(recipe string, appEnv AppEnv) ([]string, error) {
|
func GetAppComposeFiles(recipe string, appEnv AppEnv) ([]string, error) {
|
||||||
|
var composeFiles []string
|
||||||
|
|
||||||
if _, ok := appEnv["COMPOSE_FILE"]; !ok {
|
if _, ok := appEnv["COMPOSE_FILE"]; !ok {
|
||||||
logrus.Debug("no COMPOSE_FILE detected, loading all compose files")
|
logrus.Debug("no COMPOSE_FILE detected, loading compose.yml")
|
||||||
pattern := fmt.Sprintf("%s/%s/compose**yml", APPS_DIR, recipe)
|
path := fmt.Sprintf("%s/%s/compose.yml", APPS_DIR, recipe)
|
||||||
composeFiles, err := filepath.Glob(pattern)
|
composeFiles = append(composeFiles, path)
|
||||||
if err != nil {
|
|
||||||
return composeFiles, err
|
|
||||||
}
|
|
||||||
return composeFiles, nil
|
return composeFiles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var composeFiles []string
|
|
||||||
composeFileEnvVar := appEnv["COMPOSE_FILE"]
|
composeFileEnvVar := appEnv["COMPOSE_FILE"]
|
||||||
envVars := strings.Split(composeFileEnvVar, ":")
|
envVars := strings.Split(composeFileEnvVar, ":")
|
||||||
logrus.Debugf("COMPOSE_FILE detected ('%s'), loading '%s'", composeFileEnvVar, envVars)
|
logrus.Debugf("COMPOSE_FILE detected ('%s'), loading '%s'", composeFileEnvVar, strings.Join(envVars, ", "))
|
||||||
for _, file := range strings.Split(composeFileEnvVar, ":") {
|
for _, file := range strings.Split(composeFileEnvVar, ":") {
|
||||||
path := fmt.Sprintf("%s/%s/%s", APPS_DIR, recipe, file)
|
path := fmt.Sprintf("%s/%s/%s", APPS_DIR, recipe, file)
|
||||||
composeFiles = append(composeFiles, path)
|
composeFiles = append(composeFiles, path)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
ABRA_VERSION="0.1.7-alpha"
|
ABRA_VERSION="0.1.8-alpha"
|
||||||
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION"
|
ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION"
|
||||||
|
|
||||||
function show_banner {
|
function show_banner {
|
||||||
@ -38,7 +38,7 @@ function install_abra_release {
|
|||||||
release_url=$(curl -s "$ABRA_RELEASE_URL" |
|
release_url=$(curl -s "$ABRA_RELEASE_URL" |
|
||||||
python3 -c "import sys, json; \
|
python3 -c "import sys, json; \
|
||||||
payload = json.load(sys.stdin); \
|
payload = json.load(sys.stdin); \
|
||||||
url = [a['browser_download_url'] for a in payload['assets'] if 'x86_64' in a['name']][0]; \
|
url = [a['browser_download_url'] for a in payload['assets'] if 'linux_x86_64' in a['name']][0]; \
|
||||||
print(url)")
|
print(url)")
|
||||||
|
|
||||||
echo "downloading $ABRA_VERSION x86_64 binary release for abra..."
|
echo "downloading $ABRA_VERSION x86_64 binary release for abra..."
|
||||||
|
@ -3,5 +3,5 @@ STACK := abra_installer_script
|
|||||||
default: deploy
|
default: deploy
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
@docker stack rm $(STACK) && \
|
@DOCKER_CONTEXT=swarm.autonomic.zone docker stack rm $(STACK) && \
|
||||||
docker stack deploy -c compose.yml $(STACK)
|
DOCKER_CONTEXT=swarm.autonomic.zone docker stack deploy -c compose.yml $(STACK)
|
||||||
|
Reference in New Issue
Block a user