From e4b4084dfde2b5d66bfa67c5389ab9a8c1a0ba16 Mon Sep 17 00:00:00 2001 From: decentral1se Date: Mon, 13 Feb 2023 16:40:30 +0100 Subject: [PATCH] fix: stream logs without hitting git.coopcloud.tech Medium-sized options refactor in here too! See https://git.coopcloud.tech/coop-cloud/organising/issues/292. --- cli/app/backup.go | 4 ++- cli/app/errors.go | 10 ++++--- cli/app/logs.go | 3 +- cli/app/restore.go | 4 ++- cli/app/rollback.go | 4 ++- cli/app/upgrade.go | 4 ++- cli/app/version.go | 4 ++- cli/catalogue/catalogue.go | 2 +- cli/internal/deploy.go | 6 ++-- cli/internal/new.go | 3 +- cli/internal/validate.go | 24 +++++++++------- cli/recipe/fetch.go | 2 +- cli/recipe/lint.go | 2 +- cli/recipe/release.go | 3 +- cli/recipe/sync.go | 3 +- cli/recipe/upgrade.go | 2 +- cli/recipe/version.go | 3 +- cli/updater/updater.go | 21 ++++++++------ pkg/recipe/recipe.go | 26 ++++++++++------- pkg/runtime/runtime.go | 58 ++++++++++++++++++++++++++++++++++++++ 20 files changed, 139 insertions(+), 49 deletions(-) create mode 100644 pkg/runtime/runtime.go diff --git a/cli/app/backup.go b/cli/app/backup.go index 142a50e5..8bc1a7ba 100644 --- a/cli/app/backup.go +++ b/cli/app/backup.go @@ -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) } diff --git a/cli/app/errors.go b/cli/app/errors.go index 603c2e7b..4918e87a 100644 --- a/cli/app/errors.go +++ b/cli/app/errors.go @@ -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 } diff --git a/cli/app/logs.go b/cli/app/logs.go index 058399ee..61b47a57 100644 --- a/cli/app/logs.go +++ b/cli/app/logs.go @@ -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" @@ -79,7 +80,7 @@ var appLogsCommand = cli.Command{ 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 { diff --git a/cli/app/restore.go b/cli/app/restore.go index 9b01db8c..d5c2f538 100644 --- a/cli/app/restore.go +++ b/cli/app/restore.go @@ -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) } diff --git a/cli/app/rollback.go b/cli/app/rollback.go index c848a235..223ceda7 100644 --- a/cli/app/rollback.go +++ b/cli/app/rollback.go @@ -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) } diff --git a/cli/app/upgrade.go b/cli/app/upgrade.go index 8a7c2adc..8ea8f4b0 100644 --- a/cli/app/upgrade.go +++ b/cli/app/upgrade.go @@ -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) } diff --git a/cli/app/version.go b/cli/app/version.go index 7ce9fa34..92b3dbc3 100644 --- a/cli/app/version.go +++ b/cli/app/version.go @@ -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) } diff --git a/cli/catalogue/catalogue.go b/cli/catalogue/catalogue.go index a27110fb..b4699a88 100644 --- a/cli/catalogue/catalogue.go +++ b/cli/catalogue/catalogue.go @@ -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 { diff --git a/cli/internal/deploy.go b/cli/internal/deploy.go index 072335cb..3993aecd 100644 --- a/cli/internal/deploy.go +++ b/cli/internal/deploy.go @@ -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) } } diff --git a/cli/internal/new.go b/cli/internal/new.go index b0f1fc8f..b05f2937 100644 --- a/cli/internal/new.go +++ b/cli/internal/new.go @@ -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) diff --git a/cli/internal/validate.go b/cli/internal/validate.go index e4126b60..36f72679 100644 --- a/cli/internal/validate.go +++ b/cli/internal/validate.go @@ -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) } diff --git a/cli/recipe/fetch.go b/cli/recipe/fetch.go index 70187911..b124c80c 100644 --- a/cli/recipe/fetch.go +++ b/cli/recipe/fetch.go @@ -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 } diff --git a/cli/recipe/lint.go b/cli/recipe/lint.go index 802088e4..f9e8e6a5 100644 --- a/cli/recipe/lint.go +++ b/cli/recipe/lint.go @@ -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) diff --git a/cli/recipe/release.go b/cli/recipe/release.go index 40691480..e0c4b696 100644 --- a/cli/recipe/release.go +++ b/cli/recipe/release.go @@ -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 { diff --git a/cli/recipe/sync.go b/cli/recipe/sync.go index f7745ee0..bcc99487 100644 --- a/cli/recipe/sync.go +++ b/cli/recipe/sync.go @@ -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 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 { diff --git a/cli/recipe/upgrade.go b/cli/recipe/upgrade.go index ada187ac..8f7beeeb 100644 --- a/cli/recipe/upgrade.go +++ b/cli/recipe/upgrade.go @@ -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) diff --git a/cli/recipe/version.go b/cli/recipe/version.go index e81aa535..0434d767 100644 --- a/cli/recipe/version.go +++ b/cli/recipe/version.go @@ -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 { diff --git a/cli/updater/updater.go b/cli/updater/updater.go index 679f06a1..e00034c5 100644 --- a/cli/updater/updater.go +++ b/cli/updater/updater.go @@ -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 } diff --git a/pkg/recipe/recipe.go b/pkg/recipe/recipe.go index e226de50..d7b015ae 100644 --- a/pkg/recipe/recipe.go +++ b/pkg/recipe/recipe.go @@ -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 } diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go new file mode 100644 index 00000000..a8580738 --- /dev/null +++ b/pkg/runtime/runtime.go @@ -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 + } +}