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