Compare commits

..

No commits in common. "main" and "0.7.0-rc2-beta" have entirely different histories.

27 changed files with 67 additions and 165 deletions

View File

@ -16,11 +16,11 @@ install:
@go install -ldflags=$(LDFLAGS) $(ABRA) @go install -ldflags=$(LDFLAGS) $(ABRA)
build-dev: build-dev:
@go build -v -ldflags=$(LDFLAGS) $(ABRA) @go build -ldflags=$(LDFLAGS) $(ABRA)
build: build:
@go build -v -ldflags=$(DIST_LDFLAGS) $(ABRA) @go build -ldflags=$(DIST_LDFLAGS) $(ABRA)
@go build -v -ldflags=$(DIST_LDFLAGS) $(KADABRA) @go build -ldflags=$(DIST_LDFLAGS) $(KADABRA)
clean: clean:
@rm '$(GOPATH)/bin/abra' @rm '$(GOPATH)/bin/abra'

View File

@ -16,7 +16,6 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
containerPkg "coopcloud.tech/abra/pkg/container" containerPkg "coopcloud.tech/abra/pkg/container"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
"coopcloud.tech/abra/pkg/upstream/container" "coopcloud.tech/abra/pkg/upstream/container"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -73,14 +72,13 @@ This single file can be used to restore your app. See "abra app restore" for mor
`, `,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
conf := runtime.New()
cl, err := client.New(app.Server) cl, err := client.New(app.Server)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
recipe, err := recipe.Get(app.Recipe, conf) recipe, err := recipe.Get(app.Recipe)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -12,7 +12,6 @@ import (
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
stack "coopcloud.tech/abra/pkg/upstream/stack" stack "coopcloud.tech/abra/pkg/upstream/stack"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
@ -56,7 +55,6 @@ the logs.
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
conf := runtime.New()
cl, err := client.New(app.Server) cl, err := client.New(app.Server)
if err != nil { if err != nil {
@ -73,14 +71,14 @@ the logs.
} }
if !internal.Watch { if !internal.Watch {
if err := checkErrors(c, cl, app, conf); err != nil { if err := checkErrors(c, cl, app); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
return nil return nil
} }
for { for {
if err := checkErrors(c, cl, app, conf); err != nil { if err := checkErrors(c, cl, app); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
@ -90,8 +88,8 @@ the logs.
}, },
} }
func checkErrors(c *cli.Context, cl *dockerClient.Client, app config.App, conf *runtime.Config) error { func checkErrors(c *cli.Context, cl *dockerClient.Client, app config.App) error {
recipe, err := recipe.Get(app.Recipe, conf) recipe, err := recipe.Get(app.Recipe)
if err != nil { if err != nil {
return err return err
} }

View File

@ -11,7 +11,6 @@ import (
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/runtime"
"coopcloud.tech/abra/pkg/service" "coopcloud.tech/abra/pkg/service"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
@ -21,14 +20,12 @@ import (
) )
var logOpts = types.ContainerLogsOptions{ var logOpts = types.ContainerLogsOptions{
Details: false,
Follow: true,
ShowStderr: true, ShowStderr: true,
ShowStdout: true, ShowStdout: true,
Since: "",
Until: "",
Timestamps: true,
Follow: true,
Tail: "20", Tail: "20",
Details: false, Timestamps: true,
} }
// stackLogs lists logs for all stack services // stackLogs lists logs for all stack services
@ -77,21 +74,18 @@ var appLogsCommand = cli.Command{
Usage: "Tail app logs", Usage: "Tail app logs",
Flags: []cli.Flag{ Flags: []cli.Flag{
internal.StdErrOnlyFlag, internal.StdErrOnlyFlag,
internal.SinceLogsFlag,
internal.DebugFlag, internal.DebugFlag,
}, },
Before: internal.SubCommandBefore, Before: internal.SubCommandBefore,
BashComplete: autocomplete.AppNameComplete, BashComplete: autocomplete.AppNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c, runtime.WithEnsureRecipeExists(false)) app := internal.ValidateApp(c)
cl, err := client.New(app.Server) cl, err := client.New(app.Server)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
logOpts.Since = internal.SinceLogs
serviceName := c.Args().Get(1) serviceName := c.Args().Get(1)
if serviceName == "" { if serviceName == "" {
logrus.Debugf("tailing logs for all %s services", app.Recipe) logrus.Debugf("tailing logs for all %s services", app.Recipe)

View File

@ -12,7 +12,6 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
containerPkg "coopcloud.tech/abra/pkg/container" containerPkg "coopcloud.tech/abra/pkg/container"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
"coopcloud.tech/abra/pkg/upstream/container" "coopcloud.tech/abra/pkg/upstream/container"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -56,7 +55,6 @@ Example:
`, `,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
conf := runtime.New()
cl, err := client.New(app.Server) cl, err := client.New(app.Server)
if err != nil { if err != nil {
@ -79,7 +77,7 @@ Example:
} }
} }
recipe, err := recipe.Get(app.Recipe, conf) recipe, err := recipe.Get(app.Recipe)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -8,7 +8,6 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/lint" "coopcloud.tech/abra/pkg/lint"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
stack "coopcloud.tech/abra/pkg/upstream/stack" stack "coopcloud.tech/abra/pkg/upstream/stack"
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
@ -50,7 +49,6 @@ recipes.
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
stackName := app.StackName() stackName := app.StackName()
conf := runtime.New()
if !internal.Chaos { if !internal.Chaos {
if err := recipe.EnsureUpToDate(app.Recipe); err != nil { if err := recipe.EnsureUpToDate(app.Recipe); err != nil {
@ -58,7 +56,7 @@ recipes.
} }
} }
r, err := recipe.Get(app.Recipe, conf) r, err := recipe.Get(app.Recipe)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -10,7 +10,6 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/lint" "coopcloud.tech/abra/pkg/lint"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
stack "coopcloud.tech/abra/pkg/upstream/stack" stack "coopcloud.tech/abra/pkg/upstream/stack"
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
@ -53,7 +52,6 @@ recipes.
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
stackName := app.StackName() stackName := app.StackName()
conf := runtime.New()
cl, err := client.New(app.Server) cl, err := client.New(app.Server)
if err != nil { if err != nil {
@ -66,7 +64,7 @@ recipes.
} }
} }
r, err := recipe.Get(app.Recipe, conf) r, err := recipe.Get(app.Recipe)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -8,7 +8,6 @@ import (
"coopcloud.tech/abra/pkg/client" "coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
"coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/abra/pkg/upstream/stack"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -49,7 +48,6 @@ version.
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
app := internal.ValidateApp(c) app := internal.ValidateApp(c)
stackName := app.StackName() stackName := app.StackName()
conf := runtime.New()
cl, err := client.New(app.Server) cl, err := client.New(app.Server)
if err != nil { if err != nil {
@ -71,7 +69,7 @@ version.
logrus.Fatalf("%s is not deployed?", app.Name) logrus.Fatalf("%s is not deployed?", app.Name)
} }
recipeMeta, err := recipe.GetRecipeMeta(app.Recipe, conf) recipeMeta, err := recipe.GetRecipeMeta(app.Recipe)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -55,7 +55,7 @@ keys configured on your account.
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipeName := c.Args().First() recipeName := c.Args().First()
if recipeName != "" { if recipeName != "" {
internal.ValidateRecipe(c) internal.ValidateRecipe(c, true)
} }
if err := catalogue.EnsureUpToDate(); err != nil { if err := catalogue.EnsureUpToDate(); err != nil {

View File

@ -328,14 +328,6 @@ var StdErrOnlyFlag = &cli.BoolFlag{
Destination: &StdErrOnly, 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 DontWaitConverge bool
var DontWaitConvergeFlag = &cli.BoolFlag{ var DontWaitConvergeFlag = &cli.BoolFlag{
Name: "no-converge-checks, c", Name: "no-converge-checks, c",

View File

@ -15,7 +15,6 @@ import (
"coopcloud.tech/abra/pkg/git" "coopcloud.tech/abra/pkg/git"
"coopcloud.tech/abra/pkg/lint" "coopcloud.tech/abra/pkg/lint"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
"coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/abra/pkg/upstream/stack"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -25,7 +24,6 @@ import (
// DeployAction is the main command-line action for this package // DeployAction is the main command-line action for this package
func DeployAction(c *cli.Context) error { func DeployAction(c *cli.Context) error {
app := ValidateApp(c) app := ValidateApp(c)
conf := runtime.New()
cl, err := client.New(app.Server) cl, err := client.New(app.Server)
if err != nil { if err != nil {
@ -38,7 +36,7 @@ func DeployAction(c *cli.Context) error {
} }
} }
r, err := recipe.Get(app.Recipe, conf) r, err := recipe.Get(app.Recipe)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -85,7 +83,7 @@ func DeployAction(c *cli.Context) error {
} }
version = formatter.SmallSHA(head.String()) version = formatter.SmallSHA(head.String())
logrus.Warn("no versions detected, using latest commit") logrus.Warn("no versions detected, using latest commit")
if err := recipe.EnsureLatest(app.Recipe, conf); err != nil { if err := recipe.EnsureLatest(app.Recipe); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
} }

View File

@ -11,7 +11,6 @@ import (
"coopcloud.tech/abra/pkg/jsontable" "coopcloud.tech/abra/pkg/jsontable"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
"coopcloud.tech/abra/pkg/secret" "coopcloud.tech/abra/pkg/secret"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
dockerClient "github.com/docker/docker/client" dockerClient "github.com/docker/docker/client"
@ -120,7 +119,7 @@ func ensureServerFlag() error {
// NewAction is the new app creation logic // NewAction is the new app creation logic
func NewAction(c *cli.Context) error { func NewAction(c *cli.Context) error {
recipe := ValidateRecipeWithPrompt(c, runtime.WithEnsureRecipeLatest(false)) recipe := ValidateRecipeWithPrompt(c, false)
if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil { if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
logrus.Fatal(err) logrus.Fatal(err)

View File

@ -9,7 +9,6 @@ import (
"coopcloud.tech/abra/pkg/app" "coopcloud.tech/abra/pkg/app"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -19,15 +18,14 @@ import (
var AppName string var AppName string
// ValidateRecipe ensures the recipe arg is valid. // ValidateRecipe ensures the recipe arg is valid.
func ValidateRecipe(c *cli.Context, opts ...runtime.Option) recipe.Recipe { func ValidateRecipe(c *cli.Context, ensureLatest bool) recipe.Recipe {
recipeName := c.Args().First() recipeName := c.Args().First()
conf := runtime.New(opts...)
if recipeName == "" { if recipeName == "" {
ShowSubcommandHelpAndError(c, errors.New("no recipe name provided")) ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
} }
chosenRecipe, err := recipe.Get(recipeName, conf) chosenRecipe, err := recipe.Get(recipeName)
if err != nil { if err != nil {
if c.Command.Name == "generate" { if c.Command.Name == "generate" {
if strings.Contains(err.Error(), "missing a compose") { if strings.Contains(err.Error(), "missing a compose") {
@ -42,8 +40,8 @@ func ValidateRecipe(c *cli.Context, opts ...runtime.Option) recipe.Recipe {
} }
} }
if conf.EnsureRecipeLatest { if ensureLatest {
if err := recipe.EnsureLatest(recipeName, conf); err != nil { if err := recipe.EnsureLatest(recipeName); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
} }
@ -55,9 +53,8 @@ func ValidateRecipe(c *cli.Context, opts ...runtime.Option) recipe.Recipe {
// ValidateRecipeWithPrompt ensures a recipe argument is present before // ValidateRecipeWithPrompt ensures a recipe argument is present before
// validating, asking for input if required. // validating, asking for input if required.
func ValidateRecipeWithPrompt(c *cli.Context, opts ...runtime.Option) recipe.Recipe { func ValidateRecipeWithPrompt(c *cli.Context, ensureLatest bool) recipe.Recipe {
recipeName := c.Args().First() recipeName := c.Args().First()
conf := runtime.New(opts...)
if recipeName == "" && !NoInput { if recipeName == "" && !NoInput {
var recipes []string var recipes []string
@ -105,13 +102,13 @@ func ValidateRecipeWithPrompt(c *cli.Context, opts ...runtime.Option) recipe.Rec
ShowSubcommandHelpAndError(c, errors.New("no recipe name provided")) ShowSubcommandHelpAndError(c, errors.New("no recipe name provided"))
} }
chosenRecipe, err := recipe.Get(recipeName, conf) chosenRecipe, err := recipe.Get(recipeName)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
if conf.EnsureRecipeLatest { if ensureLatest {
if err := recipe.EnsureLatest(recipeName, conf); err != nil { if err := recipe.EnsureLatest(recipeName); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
} }
@ -122,9 +119,8 @@ func ValidateRecipeWithPrompt(c *cli.Context, opts ...runtime.Option) recipe.Rec
} }
// ValidateApp ensures the app name arg is valid. // ValidateApp ensures the app name arg is valid.
func ValidateApp(c *cli.Context, opts ...runtime.Option) config.App { func ValidateApp(c *cli.Context) config.App {
appName := c.Args().First() appName := c.Args().First()
conf := runtime.New(opts...)
if AppName != "" { if AppName != "" {
appName = AppName appName = AppName
@ -140,7 +136,7 @@ func ValidateApp(c *cli.Context, opts ...runtime.Option) config.App {
logrus.Fatal(err) logrus.Fatal(err)
} }
if err := recipe.EnsureExists(app.Recipe, conf); err != nil { if err := recipe.EnsureExists(app.Recipe); err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }

View File

@ -22,7 +22,7 @@ var recipeFetchCommand = cli.Command{
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipeName := c.Args().First() recipeName := c.Args().First()
if recipeName != "" { if recipeName != "" {
internal.ValidateRecipe(c) internal.ValidateRecipe(c, true)
return nil // ValidateRecipe ensures latest checkout return nil // ValidateRecipe ensures latest checkout
} }

View File

@ -24,7 +24,7 @@ var recipeLintCommand = cli.Command{
Before: internal.SubCommandBefore, Before: internal.SubCommandBefore,
BashComplete: autocomplete.RecipeNameComplete, BashComplete: autocomplete.RecipeNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipe(c) recipe := internal.ValidateRecipe(c, true)
if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil { if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
logrus.Fatal(err) logrus.Fatal(err)

View File

@ -13,7 +13,6 @@ import (
gitPkg "coopcloud.tech/abra/pkg/git" gitPkg "coopcloud.tech/abra/pkg/git"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
@ -59,7 +58,7 @@ your SSH keys configured on your account.
Before: internal.SubCommandBefore, Before: internal.SubCommandBefore,
BashComplete: autocomplete.RecipeNameComplete, BashComplete: autocomplete.RecipeNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipeWithPrompt(c, runtime.WithEnsureRecipeLatest(false)) recipe := internal.ValidateRecipeWithPrompt(c, false)
imagesTmp, err := getImageVersions(recipe) imagesTmp, err := getImageVersions(recipe)
if err != nil { if err != nil {

View File

@ -8,7 +8,6 @@ import (
"coopcloud.tech/abra/cli/internal" "coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/runtime"
"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"
@ -42,7 +41,7 @@ auto-generate it for you. The <recipe> configuration will be updated on the
local file system. local file system.
`, `,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipeWithPrompt(c, runtime.WithEnsureRecipeLatest(false)) recipe := internal.ValidateRecipeWithPrompt(c, false)
mainApp, err := internal.GetMainAppImage(recipe) mainApp, err := internal.GetMainAppImage(recipe)
if err != nil { if err != nil {

View File

@ -59,7 +59,7 @@ You may invoke this command in "wizard" mode and be prompted for input:
}, },
Before: internal.SubCommandBefore, Before: internal.SubCommandBefore,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipeWithPrompt(c) recipe := internal.ValidateRecipeWithPrompt(c, true)
if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil { if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
logrus.Fatal(err) logrus.Fatal(err)

View File

@ -5,7 +5,6 @@ import (
"coopcloud.tech/abra/pkg/autocomplete" "coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
recipePkg "coopcloud.tech/abra/pkg/recipe" recipePkg "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -21,7 +20,7 @@ var recipeVersionCommand = cli.Command{
Before: internal.SubCommandBefore, Before: internal.SubCommandBefore,
BashComplete: autocomplete.RecipeNameComplete, BashComplete: autocomplete.RecipeNameComplete,
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
recipe := internal.ValidateRecipe(c, runtime.WithEnsureRecipeLatest(false)) recipe := internal.ValidateRecipe(c, false)
catalogue, err := recipePkg.ReadRecipeCatalogue() catalogue, err := recipePkg.ReadRecipeCatalogue()
if err != nil { if err != nil {

View File

@ -12,7 +12,6 @@ import (
"coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/config"
"coopcloud.tech/abra/pkg/lint" "coopcloud.tech/abra/pkg/lint"
"coopcloud.tech/abra/pkg/recipe" "coopcloud.tech/abra/pkg/recipe"
"coopcloud.tech/abra/pkg/runtime"
"coopcloud.tech/abra/pkg/upstream/convert" "coopcloud.tech/abra/pkg/upstream/convert"
"coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/abra/pkg/upstream/stack"
"coopcloud.tech/tagcmp" "coopcloud.tech/tagcmp"
@ -114,12 +113,10 @@ update chaos deployments use the "--chaos" flag. Use it with care.
logrus.Fatal(err) logrus.Fatal(err)
} }
conf := runtime.New()
if !updateAll { if !updateAll {
stackName := c.Args().Get(0) stackName := c.Args().Get(0)
recipeName := c.Args().Get(1) recipeName := c.Args().Get(1)
err = tryUpgrade(cl, stackName, recipeName, conf) err = tryUpgrade(cl, stackName, recipeName)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -139,7 +136,7 @@ update chaos deployments use the "--chaos" flag. Use it with care.
logrus.Fatal(err) logrus.Fatal(err)
} }
err = tryUpgrade(cl, stackName, recipeName, conf) err = tryUpgrade(cl, stackName, recipeName)
if err != nil { if err != nil {
logrus.Fatal(err) logrus.Fatal(err)
} }
@ -316,8 +313,8 @@ func getAvailableUpgrades(cl *dockerclient.Client, stackName string, recipeName
// processRecipeRepoVersion clones, pulls, checks out the version and lints the // processRecipeRepoVersion clones, pulls, checks out the version and lints the
// recipe repository. // recipe repository.
func processRecipeRepoVersion(recipeName, version string, conf *runtime.Config) error { func processRecipeRepoVersion(recipeName string, version string) error {
if err := recipe.EnsureExists(recipeName, conf); err != nil { if err := recipe.EnsureExists(recipeName); err != nil {
return err return err
} }
@ -329,7 +326,7 @@ func processRecipeRepoVersion(recipeName, version string, conf *runtime.Config)
return err return err
} }
if r, err := recipe.Get(recipeName, conf); err != nil { if r, err := recipe.Get(recipeName); err != nil {
return err return err
} else if err := lint.LintForErrors(r); err != nil { } else if err := lint.LintForErrors(r); err != nil {
return err return err
@ -386,7 +383,7 @@ func createDeployConfig(recipeName string, stackName string, env config.AppEnv)
} }
// tryUpgrade performs the upgrade if all the requirements are fulfilled. // tryUpgrade performs the upgrade if all the requirements are fulfilled.
func tryUpgrade(cl *dockerclient.Client, stackName, recipeName string, conf *runtime.Config) error { func tryUpgrade(cl *dockerclient.Client, stackName string, recipeName string) error {
if recipeName == "" { if recipeName == "" {
logrus.Debugf("Don't update %s due to missing recipe name", stackName) logrus.Debugf("Don't update %s due to missing recipe name", stackName)
return nil return nil
@ -422,13 +419,13 @@ func tryUpgrade(cl *dockerclient.Client, stackName, recipeName string, conf *run
return nil return nil
} }
err = upgrade(cl, stackName, recipeName, upgradeVersion, conf) err = upgrade(cl, stackName, recipeName, upgradeVersion)
return err return err
} }
// upgrade performs all necessary steps to upgrade an app. // upgrade performs all necessary steps to upgrade an app.
func upgrade(cl *dockerclient.Client, stackName, recipeName, upgradeVersion string, conf *runtime.Config) error { func upgrade(cl *dockerclient.Client, stackName string, recipeName string, upgradeVersion string) error {
env, err := getEnv(cl, stackName) env, err := getEnv(cl, stackName)
if err != nil { if err != nil {
return err return err
@ -441,7 +438,7 @@ func upgrade(cl *dockerclient.Client, stackName, recipeName, upgradeVersion stri
Env: env, Env: env,
} }
if err = processRecipeRepoVersion(recipeName, upgradeVersion, conf); err != nil { if err = processRecipeRepoVersion(recipeName, upgradeVersion); err != nil {
return err return err
} }

2
go.mod
View File

@ -12,7 +12,7 @@ require (
github.com/docker/docker v20.10.23+incompatible github.com/docker/docker v20.10.23+incompatible
github.com/docker/go-units v0.5.0 github.com/docker/go-units v0.5.0
github.com/go-git/go-git/v5 v5.5.2 github.com/go-git/go-git/v5 v5.5.2
github.com/hetznercloud/hcloud-go v1.40.0 github.com/hetznercloud/hcloud-go v1.39.0
github.com/moby/sys/signal v0.7.0 github.com/moby/sys/signal v0.7.0
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v0.0.5

4
go.sum
View File

@ -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/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.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hetznercloud/hcloud-go v1.40.0 h1:rchS+LVd80GuAOQUM5pLs0Fn7tb4PflPCuxskLYc1JQ= github.com/hetznercloud/hcloud-go v1.39.0 h1:RUlzI458nGnPR6dlcZlrsGXYC1hQlFbKdm8tVtEQQB0=
github.com/hetznercloud/hcloud-go v1.40.0/go.mod h1:jcKomw7kDIjrJ9FI72S/RdRPK8X8arYzEnXjRM/uXT8= github.com/hetznercloud/hcloud-go v1.39.0/go.mod h1:mepQwR6va27S3UQthaEPGS86jtzSY9xWL1e9dyxXpgA=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= 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/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=

View File

@ -26,7 +26,7 @@ func New(serverName string) (*client.Client, error) {
if serverName != "default" { if serverName != "default" {
context, err := GetContext(serverName) context, err := GetContext(serverName)
if err != nil { if err != nil {
return nil, fmt.Errorf("unknown server, run \"abra server add %s\"?", serverName) return nil, err
} }
ctxEndpoint, err := contextPkg.GetContextEndpoint(context) ctxEndpoint, err := contextPkg.GetContextEndpoint(context)

View File

@ -173,7 +173,7 @@ func newApp(env AppEnv, name string, appFile AppFile) (App, error) {
if !exists { if !exists {
recipe, exists = env["TYPE"] recipe, exists = env["TYPE"]
if !exists { if !exists {
return App{}, fmt.Errorf("%s is missing the TYPE env var?", name) return App{}, fmt.Errorf("%s is missing the RECIPE env var", name)
} }
} }
@ -369,6 +369,13 @@ 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 var bar *progressbar.ProgressBar
if !MachineReadable { if !MachineReadable {
bar = formatter.CreateProgressbar(len(servers), "querying remote servers...") bar = formatter.CreateProgressbar(len(servers), "querying remote servers...")

View File

@ -18,7 +18,6 @@ import (
"coopcloud.tech/abra/pkg/formatter" "coopcloud.tech/abra/pkg/formatter"
gitPkg "coopcloud.tech/abra/pkg/git" gitPkg "coopcloud.tech/abra/pkg/git"
"coopcloud.tech/abra/pkg/limit" "coopcloud.tech/abra/pkg/limit"
"coopcloud.tech/abra/pkg/runtime"
"coopcloud.tech/abra/pkg/upstream/stack" "coopcloud.tech/abra/pkg/upstream/stack"
loader "coopcloud.tech/abra/pkg/upstream/stack" loader "coopcloud.tech/abra/pkg/upstream/stack"
"coopcloud.tech/abra/pkg/web" "coopcloud.tech/abra/pkg/web"
@ -207,8 +206,8 @@ func (r Recipe) Tags() ([]string, error) {
} }
// Get retrieves a recipe. // Get retrieves a recipe.
func Get(recipeName string, conf *runtime.Config) (Recipe, error) { func Get(recipeName string) (Recipe, error) {
if err := EnsureExists(recipeName, conf); err != nil { if err := EnsureExists(recipeName); err != nil {
return Recipe{}, err return Recipe{}, err
} }
@ -234,7 +233,7 @@ func Get(recipeName string, conf *runtime.Config) (Recipe, error) {
return Recipe{}, err return Recipe{}, err
} }
meta, err := GetRecipeMeta(recipeName, conf) meta, err := GetRecipeMeta(recipeName)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "does not exist") { if strings.Contains(err.Error(), "does not exist") {
meta = RecipeMeta{} meta = RecipeMeta{}
@ -251,11 +250,7 @@ func Get(recipeName string, conf *runtime.Config) (Recipe, error) {
} }
// EnsureExists ensures that a recipe is locally cloned // EnsureExists ensures that a recipe is locally cloned
func EnsureExists(recipeName string, conf *runtime.Config) error { func EnsureExists(recipeName string) error {
if !conf.EnsureRecipeExists {
return nil
}
recipeDir := path.Join(config.RECIPES_DIR, recipeName) recipeDir := path.Join(config.RECIPES_DIR, recipeName)
if _, err := os.Stat(recipeDir); os.IsNotExist(err) { if _, err := os.Stat(recipeDir); os.IsNotExist(err) {
@ -338,7 +333,7 @@ func EnsureVersion(recipeName, version string) error {
} }
// EnsureLatest makes sure the latest commit is checked out for a local recipe repository // EnsureLatest makes sure the latest commit is checked out for a local recipe repository
func EnsureLatest(recipeName string, conf *runtime.Config) error { func EnsureLatest(recipeName string) error {
recipeDir := path.Join(config.RECIPES_DIR, recipeName) recipeDir := path.Join(config.RECIPES_DIR, recipeName)
isClean, err := gitPkg.IsClean(recipeDir) isClean, err := gitPkg.IsClean(recipeDir)
@ -366,7 +361,7 @@ func EnsureLatest(recipeName string, conf *runtime.Config) error {
return err return err
} }
meta, err := GetRecipeMeta(recipeName, conf) meta, err := GetRecipeMeta(recipeName)
if err != nil { if err != nil {
return err return err
} }
@ -795,7 +790,7 @@ func VersionsOfService(recipe, serviceName string) ([]string, error) {
} }
// GetRecipeMeta retrieves the recipe metadata from the recipe catalogue. // GetRecipeMeta retrieves the recipe metadata from the recipe catalogue.
func GetRecipeMeta(recipeName string, conf *runtime.Config) (RecipeMeta, error) { func GetRecipeMeta(recipeName string) (RecipeMeta, error) {
catl, err := ReadRecipeCatalogue() catl, err := ReadRecipeCatalogue()
if err != nil { if err != nil {
return RecipeMeta{}, err return RecipeMeta{}, err
@ -806,7 +801,7 @@ func GetRecipeMeta(recipeName string, conf *runtime.Config) (RecipeMeta, error)
return RecipeMeta{}, fmt.Errorf("recipe %s does not exist?", recipeName) return RecipeMeta{}, fmt.Errorf("recipe %s does not exist?", recipeName)
} }
if err := EnsureExists(recipeName, conf); err != nil { if err := EnsureExists(recipeName); err != nil {
return RecipeMeta{}, err return RecipeMeta{}, err
} }
@ -928,9 +923,8 @@ func ReadReposMetadata() (RepoCatalogue, error) {
} }
// GetRecipeVersions retrieves all recipe versions. // GetRecipeVersions retrieves all recipe versions.
func GetRecipeVersions(recipeName string, opts ...runtime.Option) (RecipeVersions, error) { func GetRecipeVersions(recipeName string) (RecipeVersions, error) {
versions := RecipeVersions{} versions := RecipeVersions{}
conf := runtime.New(opts...)
recipeDir := path.Join(config.RECIPES_DIR, recipeName) recipeDir := path.Join(config.RECIPES_DIR, recipeName)
@ -968,7 +962,7 @@ func GetRecipeVersions(recipeName string, opts ...runtime.Option) (RecipeVersion
logrus.Debugf("successfully checked out %s in %s", ref.Name(), recipeDir) logrus.Debugf("successfully checked out %s in %s", ref.Name(), recipeDir)
recipe, err := Get(recipeName, conf) recipe, err := Get(recipeName)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,58 +0,0 @@
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
}
}

View File

@ -77,8 +77,6 @@ func Fatal(hostname string, err error) error {
return fmt.Errorf("connection timed out for %s", hostname) return fmt.Errorf("connection timed out for %s", hostname)
} else if strings.Contains(out, "Permission denied") { } else if strings.Contains(out, "Permission denied") {
return fmt.Errorf("ssh auth: permission denied for %s", hostname) 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 { } else {
return err return err
} }