Compare commits
	
		
			17 Commits
		
	
	
		
			0.8.0-rc2-
			...
			add-waitin
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 412e366200 | |||
| f5cadcc5f0 | |||
| 
						
						
							
						
						5ae73f700e
	
				 | 
					
					
						|||
| 
						
						
							
						
						63d419caae
	
				 | 
					
					
						|||
| 
						
						
							
						
						179b66d65c
	
				 | 
					
					
						|||
| 
						
						
							
						
						c9144d90f3
	
				 | 
					
					
						|||
| 
						
						
							
						
						ebf5d82c56
	
				 | 
					
					
						|||
| 
						
						
							
						
						8bb98ed0ed
	
				 | 
					
					
						|||
| 
						
						
							
						
						23f5745cb8
	
				 | 
					
					
						|||
| 
						
						
							
						
						2cd453ae8d
	
				 | 
					
					
						|||
| 
						
						
							
						
						e42cc0f91d
	
				 | 
					
					
						|||
| ae1a6c45f9 | |||
| 65fdaf43cc | |||
| 2d135329bb | |||
| 3e95319969 | |||
| 1de45a6508 | |||
| 1208438cba | 
@ -93,6 +93,7 @@ recipes.
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		isLatestHash := false
 | 
			
		||||
		version := deployedVersion
 | 
			
		||||
		if version == "unknown" && !internal.Chaos {
 | 
			
		||||
			catl, err := recipe.ReadRecipeCatalogue(conf)
 | 
			
		||||
@ -114,6 +115,7 @@ recipes.
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					logrus.Fatal(err)
 | 
			
		||||
				}
 | 
			
		||||
				isLatestHash = true
 | 
			
		||||
				version = formatter.SmallSHA(head.String())
 | 
			
		||||
				logrus.Warn("no versions detected, using latest commit")
 | 
			
		||||
				if err := recipe.EnsureLatest(app.Recipe, conf); err != nil {
 | 
			
		||||
@ -129,7 +131,7 @@ recipes.
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if version != "unknown" && !internal.Chaos {
 | 
			
		||||
		if version != "unknown" && !internal.Chaos && !isLatestHash {
 | 
			
		||||
			if err := recipe.EnsureVersion(app.Recipe, version); err != nil {
 | 
			
		||||
				logrus.Fatal(err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -84,7 +84,11 @@ var appLogsCommand = cli.Command{
 | 
			
		||||
	Before:       internal.SubCommandBefore,
 | 
			
		||||
	BashComplete: autocomplete.AppNameComplete,
 | 
			
		||||
	Action: func(c *cli.Context) error {
 | 
			
		||||
		conf := runtime.New(runtime.WithOffline(internal.Offline))
 | 
			
		||||
		conf := runtime.New(
 | 
			
		||||
			runtime.WithOffline(internal.Offline),
 | 
			
		||||
			runtime.WithEnsureRecipeExists(false),
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		app := internal.ValidateApp(c, conf)
 | 
			
		||||
 | 
			
		||||
		cl, err := client.New(app.Server)
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,11 @@ var appNewCommand = cli.Command{
 | 
			
		||||
	Before:    internal.SubCommandBefore,
 | 
			
		||||
	ArgsUsage: "[<recipe>]",
 | 
			
		||||
	Action: func(c *cli.Context) error {
 | 
			
		||||
		conf := runtime.New(runtime.WithOffline(internal.Offline))
 | 
			
		||||
		conf := runtime.New(
 | 
			
		||||
			runtime.WithOffline(internal.Offline),
 | 
			
		||||
			runtime.WithEnsureRecipeUpToDate(false),
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		recipe := internal.ValidateRecipeWithPrompt(c, conf)
 | 
			
		||||
 | 
			
		||||
		if err := recipePkg.EnsureUpToDate(recipe.Name, conf); err != nil {
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,11 @@ your SSH keys configured on your account.
 | 
			
		||||
	Before:       internal.SubCommandBefore,
 | 
			
		||||
	BashComplete: autocomplete.RecipeNameComplete,
 | 
			
		||||
	Action: func(c *cli.Context) error {
 | 
			
		||||
		conf := runtime.New(runtime.WithOffline(internal.Offline))
 | 
			
		||||
		conf := runtime.New(
 | 
			
		||||
			runtime.WithOffline(internal.Offline),
 | 
			
		||||
			runtime.WithEnsureRecipeUpToDate(false),
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		recipe := internal.ValidateRecipeWithPrompt(c, conf)
 | 
			
		||||
 | 
			
		||||
		imagesTmp, err := getImageVersions(recipe)
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,11 @@ auto-generate it for you. The <recipe> configuration will be updated on the
 | 
			
		||||
local file system.
 | 
			
		||||
`,
 | 
			
		||||
	Action: func(c *cli.Context) error {
 | 
			
		||||
		conf := runtime.New(runtime.WithOffline(internal.Offline))
 | 
			
		||||
		conf := runtime.New(
 | 
			
		||||
			runtime.WithOffline(internal.Offline),
 | 
			
		||||
			runtime.WithEnsureRecipeUpToDate(false),
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		recipe := internal.ValidateRecipeWithPrompt(c, conf)
 | 
			
		||||
 | 
			
		||||
		mainApp, err := internal.GetMainAppImage(recipe)
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,11 @@ var recipeVersionCommand = cli.Command{
 | 
			
		||||
	Before:       internal.SubCommandBefore,
 | 
			
		||||
	BashComplete: autocomplete.RecipeNameComplete,
 | 
			
		||||
	Action: func(c *cli.Context) error {
 | 
			
		||||
		conf := runtime.New(runtime.WithOffline(internal.Offline))
 | 
			
		||||
		conf := runtime.New(
 | 
			
		||||
			runtime.WithOffline(internal.Offline),
 | 
			
		||||
			runtime.WithEnsureRecipeUpToDate(false),
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		recipe := internal.ValidateRecipe(c, conf)
 | 
			
		||||
 | 
			
		||||
		catalogue, err := recipePkg.ReadRecipeCatalogue(conf)
 | 
			
		||||
 | 
			
		||||
@ -236,9 +236,10 @@ func Get(recipeName string, conf *runtime.Config) (Recipe, error) {
 | 
			
		||||
 | 
			
		||||
	meta, err := GetRecipeMeta(recipeName, conf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if strings.Contains(err.Error(), "does not exist") {
 | 
			
		||||
		switch err.(type) {
 | 
			
		||||
		case RecipeMissingFromCatalogue:
 | 
			
		||||
			meta = RecipeMeta{}
 | 
			
		||||
		} else {
 | 
			
		||||
		default:
 | 
			
		||||
			return Recipe{}, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -252,6 +253,11 @@ func Get(recipeName string, conf *runtime.Config) (Recipe, error) {
 | 
			
		||||
 | 
			
		||||
// EnsureExists ensures that a recipe is locally cloned
 | 
			
		||||
func EnsureExists(recipeName string, conf *runtime.Config) error {
 | 
			
		||||
	if !conf.RecipeExists {
 | 
			
		||||
		logrus.Debug("skipping ensuring recipe locally exists")
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
			
		||||
 | 
			
		||||
	if _, err := os.Stat(recipeDir); os.IsNotExist(err) {
 | 
			
		||||
@ -339,6 +345,11 @@ func EnsureVersion(recipeName, version string) error {
 | 
			
		||||
 | 
			
		||||
// EnsureLatest makes sure the latest commit is checked out for a local recipe repository
 | 
			
		||||
func EnsureLatest(recipeName string, conf *runtime.Config) error {
 | 
			
		||||
	if !conf.RecipeLatest {
 | 
			
		||||
		logrus.Debug("skipping ensuring recipe is synced with remote")
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
			
		||||
 | 
			
		||||
	isClean, err := gitPkg.IsClean(recipeDir)
 | 
			
		||||
@ -368,7 +379,12 @@ func EnsureLatest(recipeName string, conf *runtime.Config) error {
 | 
			
		||||
 | 
			
		||||
	meta, err := GetRecipeMeta(recipeName, conf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
		switch err.(type) {
 | 
			
		||||
		case RecipeMissingFromCatalogue:
 | 
			
		||||
			meta = RecipeMeta{}
 | 
			
		||||
		default:
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var branch plumbing.ReferenceName
 | 
			
		||||
@ -584,6 +600,11 @@ func GetStringInBetween(recipeName, str, start, end string) (result string, err
 | 
			
		||||
 | 
			
		||||
// EnsureUpToDate ensures that the local repo is synced to the remote
 | 
			
		||||
func EnsureUpToDate(recipeName string, conf *runtime.Config) error {
 | 
			
		||||
	if !conf.RecipeLatest {
 | 
			
		||||
		logrus.Debug("skipping ensuring recipe is synced with remote")
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	recipeDir := path.Join(config.RECIPES_DIR, recipeName)
 | 
			
		||||
 | 
			
		||||
	isClean, err := gitPkg.IsClean(recipeDir)
 | 
			
		||||
@ -719,6 +740,14 @@ func VersionsOfService(recipe, serviceName string, conf *runtime.Config) ([]stri
 | 
			
		||||
	return versions, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RecipeMissingFromCatalogue signifies a recipe is not present in the catalogue.
 | 
			
		||||
type RecipeMissingFromCatalogue struct{ err string }
 | 
			
		||||
 | 
			
		||||
// Error outputs the error message.
 | 
			
		||||
func (r RecipeMissingFromCatalogue) Error() string {
 | 
			
		||||
	return r.err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetRecipeMeta retrieves the recipe metadata from the recipe catalogue.
 | 
			
		||||
func GetRecipeMeta(recipeName string, conf *runtime.Config) (RecipeMeta, error) {
 | 
			
		||||
	catl, err := ReadRecipeCatalogue(conf)
 | 
			
		||||
@ -728,7 +757,9 @@ func GetRecipeMeta(recipeName string, conf *runtime.Config) (RecipeMeta, error)
 | 
			
		||||
 | 
			
		||||
	recipeMeta, ok := catl[recipeName]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return RecipeMeta{}, fmt.Errorf("recipe %s does not exist?", recipeName)
 | 
			
		||||
		return RecipeMeta{}, RecipeMissingFromCatalogue{
 | 
			
		||||
			err: fmt.Sprintf("recipe %s does not exist?", recipeName),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := EnsureExists(recipeName, conf); err != nil {
 | 
			
		||||
 | 
			
		||||
@ -2,14 +2,23 @@ package runtime
 | 
			
		||||
 | 
			
		||||
import "github.com/sirupsen/logrus"
 | 
			
		||||
 | 
			
		||||
// Config is a runtime behaviour modifier.
 | 
			
		||||
type Config struct {
 | 
			
		||||
	Offline bool
 | 
			
		||||
	Offline      bool // Whether or not Abra should prefer local / offline access
 | 
			
		||||
	RecipeExists bool // Whether or not Abra should ensure the recipe is locally cloned
 | 
			
		||||
	RecipeLatest bool // Whether or not Abra should ensure the recipe has the latest commit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Option is a runtime configuration option.
 | 
			
		||||
type Option func(c *Config)
 | 
			
		||||
 | 
			
		||||
// New creates a new runtime configuration.
 | 
			
		||||
func New(opts ...Option) *Config {
 | 
			
		||||
	conf := &Config{Offline: false}
 | 
			
		||||
	conf := &Config{
 | 
			
		||||
		Offline:      false,
 | 
			
		||||
		RecipeExists: true,
 | 
			
		||||
		RecipeLatest: true,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, optFunc := range opts {
 | 
			
		||||
		optFunc(conf)
 | 
			
		||||
@ -18,6 +27,8 @@ func New(opts ...Option) *Config {
 | 
			
		||||
	return conf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithOffline ensures Abra attempts to prefer local file system and offline
 | 
			
		||||
// access.
 | 
			
		||||
func WithOffline(offline bool) Option {
 | 
			
		||||
	return func(c *Config) {
 | 
			
		||||
		if offline {
 | 
			
		||||
@ -26,3 +37,23 @@ func WithOffline(offline bool) Option {
 | 
			
		||||
		c.Offline = offline
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithEnsureRecipeExists ensures recipe exists locally.
 | 
			
		||||
func WithEnsureRecipeExists(exists bool) Option {
 | 
			
		||||
	return func(c *Config) {
 | 
			
		||||
		if exists {
 | 
			
		||||
			logrus.Debugf("runtime config: ensuring recipe exists")
 | 
			
		||||
		}
 | 
			
		||||
		c.RecipeExists = exists
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithEnsureRecipeUpToDate ensures recipe is synced with the remote.
 | 
			
		||||
func WithEnsureRecipeUpToDate(upToDate bool) Option {
 | 
			
		||||
	return func(c *Config) {
 | 
			
		||||
		if upToDate {
 | 
			
		||||
			logrus.Debugf("runtime config: ensuring recipe is synced with remote")
 | 
			
		||||
		}
 | 
			
		||||
		c.RecipeLatest = upToDate
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,8 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/signal"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"coopcloud.tech/abra/pkg/upstream/convert"
 | 
			
		||||
@ -414,7 +415,7 @@ func deployServices(
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logrus.Infof("waiting for services to converge: %s", strings.Join(serviceNames, ", "))
 | 
			
		||||
	logrus.Infof("Starting to poll for deployment status for: %s", appName)
 | 
			
		||||
	ch := make(chan error, len(serviceIDs))
 | 
			
		||||
	for serviceID, serviceName := range serviceIDs {
 | 
			
		||||
		logrus.Debugf("waiting on %s to converge", serviceName)
 | 
			
		||||
@ -431,7 +432,7 @@ func deployServices(
 | 
			
		||||
		logrus.Debugf("assuming %s converged successfully", serviceID)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logrus.Info("services converged 👌")
 | 
			
		||||
	logrus.Infof("Successfully deployed %s", appName)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
@ -454,6 +455,10 @@ func WaitOnService(ctx context.Context, cl *dockerClient.Client, serviceID, appN
 | 
			
		||||
	errChan := make(chan error, 1)
 | 
			
		||||
	pipeReader, pipeWriter := io.Pipe()
 | 
			
		||||
 | 
			
		||||
	sigintChannel := make(chan os.Signal, 1)
 | 
			
		||||
	signal.Notify(sigintChannel, os.Interrupt)
 | 
			
		||||
	defer signal.Stop(sigintChannel)
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		errChan <- progress.ServiceProgress(ctx, cl, serviceID, pipeWriter)
 | 
			
		||||
	}()
 | 
			
		||||
@ -465,6 +470,14 @@ func WaitOnService(ctx context.Context, cl *dockerClient.Client, serviceID, appN
 | 
			
		||||
	select {
 | 
			
		||||
	case err := <-errChan:
 | 
			
		||||
		return err
 | 
			
		||||
	case <-sigintChannel:
 | 
			
		||||
		return fmt.Errorf(fmt.Sprintf(`
 | 
			
		||||
Cancelling polling for %s, deployment is still continuing.  
 | 
			
		||||
 | 
			
		||||
If you want to stop the deployment try:
 | 
			
		||||
	abra app undeploy %s
 | 
			
		||||
 | 
			
		||||
`, appName, appName))
 | 
			
		||||
	case <-time.After(timeout):
 | 
			
		||||
		return fmt.Errorf(fmt.Sprintf(`
 | 
			
		||||
%s has not converged (%s second timeout reached).
 | 
			
		||||
@ -481,7 +494,7 @@ And inspect the logs with:
 | 
			
		||||
 | 
			
		||||
    abra app logs %s
 | 
			
		||||
 | 
			
		||||
If a service is failing to even start, try smoke out the error with:
 | 
			
		||||
If a service is failing to even start, try to smoke out the error with:
 | 
			
		||||
 | 
			
		||||
    abra app errors --watch %s
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@
 | 
			
		||||
    "gomodTidy"
 | 
			
		||||
  ],
 | 
			
		||||
  "ignoreDeps": [
 | 
			
		||||
    "github.com/urfave/cli"
 | 
			
		||||
    "github.com/urfave/cli",
 | 
			
		||||
    "goreleaser/goreleaser"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user