forked from toolshed/abra
Compare commits
10 Commits
0.7.0-rc2-
...
main
Author | SHA1 | Date | |
---|---|---|---|
96a8cb7aff | |||
9b51d22c20 | |||
d789830ce4 | |||
e4b4084dfd | |||
ff58646cfc | |||
eec6469ba1 | |||
e94f947d20 | |||
cccbe4a2ec | |||
f53cfb6c36 | |||
f55f01a25c |
6
Makefile
6
Makefile
@ -16,11 +16,11 @@ install:
|
||||
@go install -ldflags=$(LDFLAGS) $(ABRA)
|
||||
|
||||
build-dev:
|
||||
@go build -ldflags=$(LDFLAGS) $(ABRA)
|
||||
@go build -v -ldflags=$(LDFLAGS) $(ABRA)
|
||||
|
||||
build:
|
||||
@go build -ldflags=$(DIST_LDFLAGS) $(ABRA)
|
||||
@go build -ldflags=$(DIST_LDFLAGS) $(KADABRA)
|
||||
@go build -v -ldflags=$(DIST_LDFLAGS) $(ABRA)
|
||||
@go build -v -ldflags=$(DIST_LDFLAGS) $(KADABRA)
|
||||
|
||||
clean:
|
||||
@rm '$(GOPATH)/bin/abra'
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
containerPkg "coopcloud.tech/abra/pkg/container"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/abra/pkg/upstream/container"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/api/types"
|
||||
@ -72,13 +73,14 @@ This single file can be used to restore your app. See "abra app restore" for mor
|
||||
`,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
conf := runtime.New()
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
recipe, err := recipe.Get(app.Recipe)
|
||||
recipe, err := recipe.Get(app.Recipe, conf)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
@ -55,6 +56,7 @@ the logs.
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
conf := runtime.New()
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
@ -71,14 +73,14 @@ the logs.
|
||||
}
|
||||
|
||||
if !internal.Watch {
|
||||
if err := checkErrors(c, cl, app); err != nil {
|
||||
if err := checkErrors(c, cl, app, conf); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for {
|
||||
if err := checkErrors(c, cl, app); err != nil {
|
||||
if err := checkErrors(c, cl, app, conf); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
@ -88,8 +90,8 @@ the logs.
|
||||
},
|
||||
}
|
||||
|
||||
func checkErrors(c *cli.Context, cl *dockerClient.Client, app config.App) error {
|
||||
recipe, err := recipe.Get(app.Recipe)
|
||||
func checkErrors(c *cli.Context, cl *dockerClient.Client, app config.App, conf *runtime.Config) error {
|
||||
recipe, err := recipe.Get(app.Recipe, conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/abra/pkg/service"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
@ -20,12 +21,14 @@ import (
|
||||
)
|
||||
|
||||
var logOpts = types.ContainerLogsOptions{
|
||||
Details: false,
|
||||
Follow: true,
|
||||
ShowStderr: true,
|
||||
ShowStdout: true,
|
||||
Tail: "20",
|
||||
Since: "",
|
||||
Until: "",
|
||||
Timestamps: true,
|
||||
Follow: true,
|
||||
Tail: "20",
|
||||
Details: false,
|
||||
}
|
||||
|
||||
// stackLogs lists logs for all stack services
|
||||
@ -74,18 +77,21 @@ var appLogsCommand = cli.Command{
|
||||
Usage: "Tail app logs",
|
||||
Flags: []cli.Flag{
|
||||
internal.StdErrOnlyFlag,
|
||||
internal.SinceLogsFlag,
|
||||
internal.DebugFlag,
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.AppNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
app := internal.ValidateApp(c, runtime.WithEnsureRecipeExists(false))
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
logOpts.Since = internal.SinceLogs
|
||||
|
||||
serviceName := c.Args().Get(1)
|
||||
if serviceName == "" {
|
||||
logrus.Debugf("tailing logs for all %s services", app.Recipe)
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
containerPkg "coopcloud.tech/abra/pkg/container"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/abra/pkg/upstream/container"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/api/types"
|
||||
@ -55,6 +56,7 @@ Example:
|
||||
`,
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
conf := runtime.New()
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
@ -77,7 +79,7 @@ Example:
|
||||
}
|
||||
}
|
||||
|
||||
recipe, err := recipe.Get(app.Recipe)
|
||||
recipe, err := recipe.Get(app.Recipe, conf)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/lint"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"coopcloud.tech/tagcmp"
|
||||
|
||||
@ -49,6 +50,7 @@ recipes.
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
stackName := app.StackName()
|
||||
conf := runtime.New()
|
||||
|
||||
if !internal.Chaos {
|
||||
if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
|
||||
@ -56,7 +58,7 @@ recipes.
|
||||
}
|
||||
}
|
||||
|
||||
r, err := recipe.Get(app.Recipe)
|
||||
r, err := recipe.Get(app.Recipe, conf)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/lint"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
stack "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
@ -52,6 +53,7 @@ recipes.
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
stackName := app.StackName()
|
||||
conf := runtime.New()
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
@ -64,7 +66,7 @@ recipes.
|
||||
}
|
||||
}
|
||||
|
||||
r, err := recipe.Get(app.Recipe)
|
||||
r, err := recipe.Get(app.Recipe, conf)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/client"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -48,6 +49,7 @@ version.
|
||||
Action: func(c *cli.Context) error {
|
||||
app := internal.ValidateApp(c)
|
||||
stackName := app.StackName()
|
||||
conf := runtime.New()
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
@ -69,7 +71,7 @@ version.
|
||||
logrus.Fatalf("%s is not deployed?", app.Name)
|
||||
}
|
||||
|
||||
recipeMeta, err := recipe.GetRecipeMeta(app.Recipe)
|
||||
recipeMeta, err := recipe.GetRecipeMeta(app.Recipe, conf)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ keys configured on your account.
|
||||
Action: func(c *cli.Context) error {
|
||||
recipeName := c.Args().First()
|
||||
if recipeName != "" {
|
||||
internal.ValidateRecipe(c, true)
|
||||
internal.ValidateRecipe(c)
|
||||
}
|
||||
|
||||
if err := catalogue.EnsureUpToDate(); err != nil {
|
||||
|
@ -328,6 +328,14 @@ var StdErrOnlyFlag = &cli.BoolFlag{
|
||||
Destination: &StdErrOnly,
|
||||
}
|
||||
|
||||
var SinceLogs string
|
||||
var SinceLogsFlag = &cli.StringFlag{
|
||||
Name: "since, S",
|
||||
Value: "",
|
||||
Usage: "tail logs since YYYY-MM-DDTHH:MM:SSZ",
|
||||
Destination: &SinceLogs,
|
||||
}
|
||||
|
||||
var DontWaitConverge bool
|
||||
var DontWaitConvergeFlag = &cli.BoolFlag{
|
||||
Name: "no-converge-checks, c",
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/lint"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -24,6 +25,7 @@ import (
|
||||
// DeployAction is the main command-line action for this package
|
||||
func DeployAction(c *cli.Context) error {
|
||||
app := ValidateApp(c)
|
||||
conf := runtime.New()
|
||||
|
||||
cl, err := client.New(app.Server)
|
||||
if err != nil {
|
||||
@ -36,7 +38,7 @@ func DeployAction(c *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
r, err := recipe.Get(app.Recipe)
|
||||
r, err := recipe.Get(app.Recipe, conf)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
@ -83,7 +85,7 @@ func DeployAction(c *cli.Context) error {
|
||||
}
|
||||
version = formatter.SmallSHA(head.String())
|
||||
logrus.Warn("no versions detected, using latest commit")
|
||||
if err := recipe.EnsureLatest(app.Recipe); err != nil {
|
||||
if err := recipe.EnsureLatest(app.Recipe, conf); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/jsontable"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/abra/pkg/secret"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
@ -119,7 +120,7 @@ func ensureServerFlag() error {
|
||||
|
||||
// NewAction is the new app creation logic
|
||||
func NewAction(c *cli.Context) error {
|
||||
recipe := ValidateRecipeWithPrompt(c, false)
|
||||
recipe := ValidateRecipeWithPrompt(c, runtime.WithEnsureRecipeLatest(false))
|
||||
|
||||
if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
|
||||
logrus.Fatal(err)
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/app"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
@ -18,14 +19,15 @@ import (
|
||||
var AppName string
|
||||
|
||||
// ValidateRecipe ensures the recipe arg is valid.
|
||||
func ValidateRecipe(c *cli.Context, ensureLatest bool) recipe.Recipe {
|
||||
func ValidateRecipe(c *cli.Context, opts ...runtime.Option) recipe.Recipe {
|
||||
recipeName := c.Args().First()
|
||||
conf := runtime.New(opts...)
|
||||
|
||||
if recipeName == "" {
|
||||
ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
|
||||
}
|
||||
|
||||
chosenRecipe, err := recipe.Get(recipeName)
|
||||
chosenRecipe, err := recipe.Get(recipeName, conf)
|
||||
if err != nil {
|
||||
if c.Command.Name == "generate" {
|
||||
if strings.Contains(err.Error(), "missing a compose") {
|
||||
@ -40,8 +42,8 @@ func ValidateRecipe(c *cli.Context, ensureLatest bool) recipe.Recipe {
|
||||
}
|
||||
}
|
||||
|
||||
if ensureLatest {
|
||||
if err := recipe.EnsureLatest(recipeName); err != nil {
|
||||
if conf.EnsureRecipeLatest {
|
||||
if err := recipe.EnsureLatest(recipeName, conf); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
@ -53,8 +55,9 @@ func ValidateRecipe(c *cli.Context, ensureLatest bool) recipe.Recipe {
|
||||
|
||||
// ValidateRecipeWithPrompt ensures a recipe argument is present before
|
||||
// validating, asking for input if required.
|
||||
func ValidateRecipeWithPrompt(c *cli.Context, ensureLatest bool) recipe.Recipe {
|
||||
func ValidateRecipeWithPrompt(c *cli.Context, opts ...runtime.Option) recipe.Recipe {
|
||||
recipeName := c.Args().First()
|
||||
conf := runtime.New(opts...)
|
||||
|
||||
if recipeName == "" && !NoInput {
|
||||
var recipes []string
|
||||
@ -102,13 +105,13 @@ func ValidateRecipeWithPrompt(c *cli.Context, ensureLatest bool) recipe.Recipe {
|
||||
ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
|
||||
}
|
||||
|
||||
chosenRecipe, err := recipe.Get(recipeName)
|
||||
chosenRecipe, err := recipe.Get(recipeName, conf)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
if ensureLatest {
|
||||
if err := recipe.EnsureLatest(recipeName); err != nil {
|
||||
if conf.EnsureRecipeLatest {
|
||||
if err := recipe.EnsureLatest(recipeName, conf); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
@ -119,8 +122,9 @@ func ValidateRecipeWithPrompt(c *cli.Context, ensureLatest bool) recipe.Recipe {
|
||||
}
|
||||
|
||||
// ValidateApp ensures the app name arg is valid.
|
||||
func ValidateApp(c *cli.Context) config.App {
|
||||
func ValidateApp(c *cli.Context, opts ...runtime.Option) config.App {
|
||||
appName := c.Args().First()
|
||||
conf := runtime.New(opts...)
|
||||
|
||||
if AppName != "" {
|
||||
appName = AppName
|
||||
@ -136,7 +140,7 @@ func ValidateApp(c *cli.Context) config.App {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
if err := recipe.EnsureExists(app.Recipe); err != nil {
|
||||
if err := recipe.EnsureExists(app.Recipe, conf); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ var recipeFetchCommand = cli.Command{
|
||||
Action: func(c *cli.Context) error {
|
||||
recipeName := c.Args().First()
|
||||
if recipeName != "" {
|
||||
internal.ValidateRecipe(c, true)
|
||||
internal.ValidateRecipe(c)
|
||||
return nil // ValidateRecipe ensures latest checkout
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ var recipeLintCommand = cli.Command{
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipe(c, true)
|
||||
recipe := internal.ValidateRecipe(c)
|
||||
|
||||
if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
|
||||
logrus.Fatal(err)
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/docker/distribution/reference"
|
||||
@ -58,7 +59,7 @@ your SSH keys configured on your account.
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipeWithPrompt(c, false)
|
||||
recipe := internal.ValidateRecipeWithPrompt(c, runtime.WithEnsureRecipeLatest(false))
|
||||
|
||||
imagesTmp, err := getImageVersions(recipe)
|
||||
if err != nil {
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/tagcmp"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/go-git/go-git/v5"
|
||||
@ -41,7 +42,7 @@ auto-generate it for you. The <recipe> configuration will be updated on the
|
||||
local file system.
|
||||
`,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipeWithPrompt(c, false)
|
||||
recipe := internal.ValidateRecipeWithPrompt(c, runtime.WithEnsureRecipeLatest(false))
|
||||
|
||||
mainApp, err := internal.GetMainAppImage(recipe)
|
||||
if err != nil {
|
||||
|
@ -59,7 +59,7 @@ You may invoke this command in "wizard" mode and be prompted for input:
|
||||
},
|
||||
Before: internal.SubCommandBefore,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipeWithPrompt(c, true)
|
||||
recipe := internal.ValidateRecipeWithPrompt(c)
|
||||
|
||||
if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
|
||||
logrus.Fatal(err)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/autocomplete"
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
recipePkg "coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@ -20,7 +21,7 @@ var recipeVersionCommand = cli.Command{
|
||||
Before: internal.SubCommandBefore,
|
||||
BashComplete: autocomplete.RecipeNameComplete,
|
||||
Action: func(c *cli.Context) error {
|
||||
recipe := internal.ValidateRecipe(c, false)
|
||||
recipe := internal.ValidateRecipe(c, runtime.WithEnsureRecipeLatest(false))
|
||||
|
||||
catalogue, err := recipePkg.ReadRecipeCatalogue()
|
||||
if err != nil {
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/lint"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/abra/pkg/upstream/convert"
|
||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"coopcloud.tech/tagcmp"
|
||||
@ -113,10 +114,12 @@ update chaos deployments use the "--chaos" flag. Use it with care.
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
conf := runtime.New()
|
||||
|
||||
if !updateAll {
|
||||
stackName := c.Args().Get(0)
|
||||
recipeName := c.Args().Get(1)
|
||||
err = tryUpgrade(cl, stackName, recipeName)
|
||||
err = tryUpgrade(cl, stackName, recipeName, conf)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
@ -136,7 +139,7 @@ update chaos deployments use the "--chaos" flag. Use it with care.
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
err = tryUpgrade(cl, stackName, recipeName)
|
||||
err = tryUpgrade(cl, stackName, recipeName, conf)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
@ -313,8 +316,8 @@ func getAvailableUpgrades(cl *dockerclient.Client, stackName string, recipeName
|
||||
|
||||
// processRecipeRepoVersion clones, pulls, checks out the version and lints the
|
||||
// recipe repository.
|
||||
func processRecipeRepoVersion(recipeName string, version string) error {
|
||||
if err := recipe.EnsureExists(recipeName); err != nil {
|
||||
func processRecipeRepoVersion(recipeName, version string, conf *runtime.Config) error {
|
||||
if err := recipe.EnsureExists(recipeName, conf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -326,7 +329,7 @@ func processRecipeRepoVersion(recipeName string, version string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if r, err := recipe.Get(recipeName); err != nil {
|
||||
if r, err := recipe.Get(recipeName, conf); err != nil {
|
||||
return err
|
||||
} else if err := lint.LintForErrors(r); err != nil {
|
||||
return err
|
||||
@ -383,7 +386,7 @@ func createDeployConfig(recipeName string, stackName string, env config.AppEnv)
|
||||
}
|
||||
|
||||
// tryUpgrade performs the upgrade if all the requirements are fulfilled.
|
||||
func tryUpgrade(cl *dockerclient.Client, stackName string, recipeName string) error {
|
||||
func tryUpgrade(cl *dockerclient.Client, stackName, recipeName string, conf *runtime.Config) error {
|
||||
if recipeName == "" {
|
||||
logrus.Debugf("Don't update %s due to missing recipe name", stackName)
|
||||
return nil
|
||||
@ -419,13 +422,13 @@ func tryUpgrade(cl *dockerclient.Client, stackName string, recipeName string) er
|
||||
return nil
|
||||
}
|
||||
|
||||
err = upgrade(cl, stackName, recipeName, upgradeVersion)
|
||||
err = upgrade(cl, stackName, recipeName, upgradeVersion, conf)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// upgrade performs all necessary steps to upgrade an app.
|
||||
func upgrade(cl *dockerclient.Client, stackName string, recipeName string, upgradeVersion string) error {
|
||||
func upgrade(cl *dockerclient.Client, stackName, recipeName, upgradeVersion string, conf *runtime.Config) error {
|
||||
env, err := getEnv(cl, stackName)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -438,7 +441,7 @@ func upgrade(cl *dockerclient.Client, stackName string, recipeName string, upgra
|
||||
Env: env,
|
||||
}
|
||||
|
||||
if err = processRecipeRepoVersion(recipeName, upgradeVersion); err != nil {
|
||||
if err = processRecipeRepoVersion(recipeName, upgradeVersion, conf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
2
go.mod
2
go.mod
@ -12,7 +12,7 @@ require (
|
||||
github.com/docker/docker v20.10.23+incompatible
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/go-git/go-git/v5 v5.5.2
|
||||
github.com/hetznercloud/hcloud-go v1.39.0
|
||||
github.com/hetznercloud/hcloud-go v1.40.0
|
||||
github.com/moby/sys/signal v0.7.0
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
|
4
go.sum
4
go.sum
@ -605,8 +605,8 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn
|
||||
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||
github.com/hetznercloud/hcloud-go v1.39.0 h1:RUlzI458nGnPR6dlcZlrsGXYC1hQlFbKdm8tVtEQQB0=
|
||||
github.com/hetznercloud/hcloud-go v1.39.0/go.mod h1:mepQwR6va27S3UQthaEPGS86jtzSY9xWL1e9dyxXpgA=
|
||||
github.com/hetznercloud/hcloud-go v1.40.0 h1:rchS+LVd80GuAOQUM5pLs0Fn7tb4PflPCuxskLYc1JQ=
|
||||
github.com/hetznercloud/hcloud-go v1.40.0/go.mod h1:jcKomw7kDIjrJ9FI72S/RdRPK8X8arYzEnXjRM/uXT8=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
|
@ -26,7 +26,7 @@ func New(serverName string) (*client.Client, error) {
|
||||
if serverName != "default" {
|
||||
context, err := GetContext(serverName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("unknown server, run \"abra server add %s\"?", serverName)
|
||||
}
|
||||
|
||||
ctxEndpoint, err := contextPkg.GetContextEndpoint(context)
|
||||
|
@ -173,7 +173,7 @@ func newApp(env AppEnv, name string, appFile AppFile) (App, error) {
|
||||
if !exists {
|
||||
recipe, exists = env["TYPE"]
|
||||
if !exists {
|
||||
return App{}, fmt.Errorf("%s is missing the RECIPE env var", name)
|
||||
return App{}, fmt.Errorf("%s is missing the TYPE env var?", name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,13 +369,6 @@ func GetAppStatuses(apps []App, MachineReadable bool) (map[string]map[string]str
|
||||
}
|
||||
}
|
||||
|
||||
for server := range servers {
|
||||
// validate that all server connections work
|
||||
if _, err := client.New(server); err != nil {
|
||||
return statuses, err
|
||||
}
|
||||
}
|
||||
|
||||
var bar *progressbar.ProgressBar
|
||||
if !MachineReadable {
|
||||
bar = formatter.CreateProgressbar(len(servers), "querying remote servers...")
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"coopcloud.tech/abra/pkg/formatter"
|
||||
gitPkg "coopcloud.tech/abra/pkg/git"
|
||||
"coopcloud.tech/abra/pkg/limit"
|
||||
"coopcloud.tech/abra/pkg/runtime"
|
||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||
loader "coopcloud.tech/abra/pkg/upstream/stack"
|
||||
"coopcloud.tech/abra/pkg/web"
|
||||
@ -206,8 +207,8 @@ func (r Recipe) Tags() ([]string, error) {
|
||||
}
|
||||
|
||||
// Get retrieves a recipe.
|
||||
func Get(recipeName string) (Recipe, error) {
|
||||
if err := EnsureExists(recipeName); err != nil {
|
||||
func Get(recipeName string, conf *runtime.Config) (Recipe, error) {
|
||||
if err := EnsureExists(recipeName, conf); err != nil {
|
||||
return Recipe{}, err
|
||||
}
|
||||
|
||||
@ -233,7 +234,7 @@ func Get(recipeName string) (Recipe, error) {
|
||||
return Recipe{}, err
|
||||
}
|
||||
|
||||
meta, err := GetRecipeMeta(recipeName)
|
||||
meta, err := GetRecipeMeta(recipeName, conf)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "does not exist") {
|
||||
meta = RecipeMeta{}
|
||||
@ -250,7 +251,11 @@ func Get(recipeName string) (Recipe, error) {
|
||||
}
|
||||
|
||||
// EnsureExists ensures that a recipe is locally cloned
|
||||
func EnsureExists(recipeName string) error {
|
||||
func EnsureExists(recipeName string, conf *runtime.Config) error {
|
||||
if !conf.EnsureRecipeExists {
|
||||
return nil
|
||||
}
|
||||
|
||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||
|
||||
if _, err := os.Stat(recipeDir); os.IsNotExist(err) {
|
||||
@ -333,7 +338,7 @@ func EnsureVersion(recipeName, version string) error {
|
||||
}
|
||||
|
||||
// EnsureLatest makes sure the latest commit is checked out for a local recipe repository
|
||||
func EnsureLatest(recipeName string) error {
|
||||
func EnsureLatest(recipeName string, conf *runtime.Config) error {
|
||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||
|
||||
isClean, err := gitPkg.IsClean(recipeDir)
|
||||
@ -361,7 +366,7 @@ func EnsureLatest(recipeName string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
meta, err := GetRecipeMeta(recipeName)
|
||||
meta, err := GetRecipeMeta(recipeName, conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -790,7 +795,7 @@ func VersionsOfService(recipe, serviceName string) ([]string, error) {
|
||||
}
|
||||
|
||||
// GetRecipeMeta retrieves the recipe metadata from the recipe catalogue.
|
||||
func GetRecipeMeta(recipeName string) (RecipeMeta, error) {
|
||||
func GetRecipeMeta(recipeName string, conf *runtime.Config) (RecipeMeta, error) {
|
||||
catl, err := ReadRecipeCatalogue()
|
||||
if err != nil {
|
||||
return RecipeMeta{}, err
|
||||
@ -801,7 +806,7 @@ func GetRecipeMeta(recipeName string) (RecipeMeta, error) {
|
||||
return RecipeMeta{}, fmt.Errorf("recipe %s does not exist?", recipeName)
|
||||
}
|
||||
|
||||
if err := EnsureExists(recipeName); err != nil {
|
||||
if err := EnsureExists(recipeName, conf); err != nil {
|
||||
return RecipeMeta{}, err
|
||||
}
|
||||
|
||||
@ -923,8 +928,9 @@ func ReadReposMetadata() (RepoCatalogue, error) {
|
||||
}
|
||||
|
||||
// GetRecipeVersions retrieves all recipe versions.
|
||||
func GetRecipeVersions(recipeName string) (RecipeVersions, error) {
|
||||
func GetRecipeVersions(recipeName string, opts ...runtime.Option) (RecipeVersions, error) {
|
||||
versions := RecipeVersions{}
|
||||
conf := runtime.New(opts...)
|
||||
|
||||
recipeDir := path.Join(config.RECIPES_DIR, recipeName)
|
||||
|
||||
@ -962,7 +968,7 @@ func GetRecipeVersions(recipeName string) (RecipeVersions, error) {
|
||||
|
||||
logrus.Debugf("successfully checked out %s in %s", ref.Name(), recipeDir)
|
||||
|
||||
recipe, err := Get(recipeName)
|
||||
recipe, err := Get(recipeName, conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
58
pkg/runtime/runtime.go
Normal file
58
pkg/runtime/runtime.go
Normal file
@ -0,0 +1,58 @@
|
||||
package runtime
|
||||
|
||||
import "github.com/sirupsen/logrus"
|
||||
|
||||
// Config is an internal configuration modifier. It can be instantiated on a
|
||||
// command call and can be changed on the fly to help make decisions further
|
||||
// down in the internals, e.g. whether or not to clone the recipe locally or
|
||||
// not.
|
||||
type Config struct {
|
||||
EnsureRecipeExists bool // ensure that the recipe is cloned locally
|
||||
EnsureRecipeLatest bool // ensure the local recipe has latest changes
|
||||
}
|
||||
|
||||
// Option modified a Config.
|
||||
type Option func(c *Config)
|
||||
|
||||
// New instantiates a new Config.
|
||||
func New(opts ...Option) *Config {
|
||||
conf := &Config{
|
||||
EnsureRecipeExists: true,
|
||||
}
|
||||
|
||||
for _, optFunc := range opts {
|
||||
optFunc(conf)
|
||||
}
|
||||
|
||||
return conf
|
||||
}
|
||||
|
||||
// WithEnsureRecipeExists determines whether or not we should be cloning the
|
||||
// local recipe or not. This can be useful for being more adaptable to offline
|
||||
// scenarios.
|
||||
func WithEnsureRecipeExists(ensureRecipeExists bool) Option {
|
||||
return func(c *Config) {
|
||||
if ensureRecipeExists {
|
||||
logrus.Debugf("runtime config: EnsureRecipeExists = %v, ensuring recipes are cloned", ensureRecipeExists)
|
||||
} else {
|
||||
logrus.Debugf("runtime config: EnsureRecipeExists = %v, not cloning recipes", ensureRecipeExists)
|
||||
}
|
||||
|
||||
c.EnsureRecipeExists = ensureRecipeExists
|
||||
}
|
||||
}
|
||||
|
||||
// WithEnsureRecipeLatest determines whether we should update the local recipes
|
||||
// remotely via Git. This can be useful when e.g. ensuring we have the latest
|
||||
// changes before making new ones.
|
||||
func WithEnsureRecipeLatest(ensureRecipeLatest bool) Option {
|
||||
return func(c *Config) {
|
||||
if ensureRecipeLatest {
|
||||
logrus.Debugf("runtime config: EnsureRecipeLatest = %v, ensuring recipes have latest changes", ensureRecipeLatest)
|
||||
} else {
|
||||
logrus.Debugf("runtime config: EnsureRecipeLatest = %v, leaving recipes alone", ensureRecipeLatest)
|
||||
}
|
||||
|
||||
c.EnsureRecipeLatest = ensureRecipeLatest
|
||||
}
|
||||
}
|
@ -77,6 +77,8 @@ func Fatal(hostname string, err error) error {
|
||||
return fmt.Errorf("connection timed out for %s", hostname)
|
||||
} else if strings.Contains(out, "Permission denied") {
|
||||
return fmt.Errorf("ssh auth: permission denied for %s", hostname)
|
||||
} else if strings.Contains(out, "Network is unreachable") {
|
||||
return fmt.Errorf("unable to connect to %s, network is unreachable?", hostname)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user