forked from toolshed/abra
		
	Compare commits
	
		
			11 Commits
		
	
	
		
			0.3.1-rc1
			...
			0.3.1-alph
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| fcbf41ee95 | |||
| 5add4ccc1b | |||
| 9220a8c09b | |||
| f78a04109c | |||
| b67ad02f87 | |||
| 215431696e | |||
| cd361237e7 | |||
| db10c7b849 | |||
| d38f82ebe7 | |||
| 59031595ea | |||
| 6f26b51f3e | 
| @ -18,6 +18,7 @@ to scaling apps up and spinning them down. | ||||
| 	Subcommands: []*cli.Command{ | ||||
| 		appNewCommand, | ||||
| 		appConfigCommand, | ||||
| 		appRestartCommand, | ||||
| 		appDeployCommand, | ||||
| 		appUpgradeCommand, | ||||
| 		appUndeployCommand, | ||||
|  | ||||
| @ -8,6 +8,7 @@ import ( | ||||
| 	abraFormatter "coopcloud.tech/abra/cli/formatter" | ||||
| 	"coopcloud.tech/abra/pkg/catalogue" | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	"coopcloud.tech/abra/pkg/ssh" | ||||
| 	"coopcloud.tech/tagcmp" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| @ -69,6 +70,12 @@ can take some time. | ||||
| 		} | ||||
| 		sort.Sort(config.ByServerAndType(apps)) | ||||
|  | ||||
| 		for _, app := range apps { | ||||
| 			if err := ssh.EnsureHostKey(app.Server); err != nil { | ||||
| 				logrus.Fatal(err) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		statuses := make(map[string]map[string]string) | ||||
| 		tableCol := []string{"Server", "Type", "Domain"} | ||||
| 		if status { | ||||
|  | ||||
							
								
								
									
										72
									
								
								cli/app/restart.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								cli/app/restart.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | ||||
| package app | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"time" | ||||
|  | ||||
| 	"coopcloud.tech/abra/cli/internal" | ||||
| 	"coopcloud.tech/abra/pkg/client" | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	"github.com/docker/docker/api/types" | ||||
| 	"github.com/docker/docker/api/types/filters" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| ) | ||||
|  | ||||
| var appRestartCommand = &cli.Command{ | ||||
| 	Name:        "restart", | ||||
| 	Usage:       "Restart an app", | ||||
| 	Aliases:     []string{"R"}, | ||||
| 	ArgsUsage:   "<service>", | ||||
| 	Description: `This command restarts a service within a deployed app.`, | ||||
| 	Action: func(c *cli.Context) error { | ||||
| 		app := internal.ValidateApp(c) | ||||
|  | ||||
| 		serviceName := c.Args().Get(1) | ||||
| 		if serviceName == "" { | ||||
| 			err := errors.New("missing service?") | ||||
| 			internal.ShowSubcommandHelpAndError(c, err) | ||||
| 		} | ||||
|  | ||||
| 		cl, err := client.New(app.Server) | ||||
| 		if err != nil { | ||||
| 			logrus.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		serviceFilter := fmt.Sprintf("%s_%s", app.StackName(), serviceName) | ||||
| 		filters := filters.NewArgs() | ||||
| 		filters.Add("name", serviceFilter) | ||||
| 		containerOpts := types.ContainerListOptions{Filters: filters} | ||||
| 		containers, err := cl.ContainerList(c.Context, containerOpts) | ||||
| 		if err != nil { | ||||
| 			logrus.Fatal(err) | ||||
| 		} | ||||
| 		if len(containers) != 1 { | ||||
| 			logrus.Fatalf("expected 1 service but got %v", len(containers)) | ||||
| 		} | ||||
|  | ||||
| 		logrus.Debugf("attempting to restart %s", serviceFilter) | ||||
|  | ||||
| 		timeout := 30 * time.Second | ||||
| 		if err := cl.ContainerRestart(c.Context, containers[0].ID, &timeout); err != nil { | ||||
| 			logrus.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		logrus.Infof("%s service restarted", serviceFilter) | ||||
|  | ||||
| 		return nil | ||||
| 	}, | ||||
| 	BashComplete: func(c *cli.Context) { | ||||
| 		appNames, err := config.GetAppNames() | ||||
| 		if err != nil { | ||||
| 			logrus.Warn(err) | ||||
| 		} | ||||
| 		if c.NArg() > 0 { | ||||
| 			return | ||||
| 		} | ||||
| 		for _, a := range appNames { | ||||
| 			fmt.Println(a) | ||||
| 		} | ||||
| 	}, | ||||
| } | ||||
| @ -8,6 +8,7 @@ import ( | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	"coopcloud.tech/abra/pkg/recipe" | ||||
| 	"coopcloud.tech/abra/pkg/secret" | ||||
| 	"coopcloud.tech/abra/pkg/ssh" | ||||
| 	"github.com/AlecAivazis/survey/v2" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| @ -163,6 +164,10 @@ func NewAction(c *cli.Context) error { | ||||
| 	} | ||||
|  | ||||
| 	if Secrets { | ||||
| 		if err := ssh.EnsureHostKey(NewAppServer); err != nil { | ||||
| 			logrus.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		secrets, err := createSecrets(sanitisedAppName) | ||||
| 		if err != nil { | ||||
| 			logrus.Fatal(err) | ||||
|  | ||||
| @ -8,6 +8,7 @@ import ( | ||||
| 	"coopcloud.tech/abra/pkg/catalogue" | ||||
| 	"coopcloud.tech/abra/pkg/config" | ||||
| 	"coopcloud.tech/abra/pkg/recipe" | ||||
| 	"coopcloud.tech/abra/pkg/ssh" | ||||
| 	"github.com/AlecAivazis/survey/v2" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 	"github.com/urfave/cli/v2" | ||||
| @ -98,6 +99,10 @@ func ValidateApp(c *cli.Context) config.App { | ||||
| 		logrus.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	if err := ssh.EnsureHostKey(app.Server); err != nil { | ||||
| 		logrus.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	logrus.Debugf("validated '%s' as app argument", appName) | ||||
|  | ||||
| 	return app | ||||
|  | ||||
| @ -39,7 +39,7 @@ system. | ||||
|  | ||||
| You may invoke this command in "wizard" mode and be prompted for input: | ||||
|  | ||||
|     abra recipe sync gitea | ||||
|     abra recipe sync | ||||
|  | ||||
| `, | ||||
| 	Action: func(c *cli.Context) error { | ||||
|  | ||||
| @ -36,6 +36,11 @@ update the relevant compose file tags on the local file system. | ||||
| Some image tags cannot be parsed because they do not follow some sort of | ||||
| semver-like convention. In this case, all possible tags will be listed and it | ||||
| is up to the end-user to decide. | ||||
|  | ||||
| You may invoke this command in "wizard" mode and be prompted for input: | ||||
|  | ||||
|     abra recipe upgrade | ||||
|  | ||||
| `, | ||||
| 	ArgsUsage: "<recipe>", | ||||
| 	Flags: []cli.Flag{ | ||||
| @ -44,7 +49,7 @@ is up to the end-user to decide. | ||||
| 		internal.MajorFlag, | ||||
| 	}, | ||||
| 	Action: func(c *cli.Context) error { | ||||
| 		recipe := internal.ValidateRecipe(c) | ||||
| 		recipe := internal.ValidateRecipeWithPrompt(c) | ||||
|  | ||||
| 		bumpType := btoi(internal.Major)*4 + btoi(internal.Minor)*2 + btoi(internal.Patch) | ||||
| 		if bumpType != 0 { | ||||
|  | ||||
| @ -9,7 +9,6 @@ import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"coopcloud.tech/abra/cli/formatter" | ||||
| 	"coopcloud.tech/abra/pkg/ssh" | ||||
| 	"coopcloud.tech/abra/pkg/upstream/convert" | ||||
| 	loader "coopcloud.tech/abra/pkg/upstream/stack" | ||||
| 	stack "coopcloud.tech/abra/pkg/upstream/stack" | ||||
| @ -146,10 +145,6 @@ func LoadAppFiles(servers ...string) (AppFiles, error) { | ||||
|  | ||||
| 	logrus.Debugf("collecting metadata from '%v' servers: '%s'", len(servers), strings.Join(servers, ", ")) | ||||
|  | ||||
| 	if err := EnsureHostKeysAllServers(servers...); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	for _, server := range servers { | ||||
| 		serverDir := path.Join(ABRA_SERVER_FOLDER, server) | ||||
| 		files, err := getAllFilesInDirectory(serverDir) | ||||
| @ -373,15 +368,3 @@ func GetAppComposeConfig(recipe string, opts stack.Deploy, appEnv AppEnv) (*comp | ||||
|  | ||||
| 	return compose, nil | ||||
| } | ||||
|  | ||||
| // EnsureHostKeysAllServers ensures all configured servers have server SSH host keys validated | ||||
| func EnsureHostKeysAllServers(servers ...string) error { | ||||
| 	for _, serverName := range servers { | ||||
| 		logrus.Debugf("ensuring server SSH host key available for %s", serverName) | ||||
| 		if err := ssh.EnsureHostKey(serverName); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -427,6 +427,11 @@ func connectWithPasswordTimeout(host, username, port, pass string, timeout time. | ||||
|  | ||||
| // EnsureHostKey ensures that a host key trusted and added to the ~/.ssh/known_hosts file | ||||
| func EnsureHostKey(hostname string) error { | ||||
| 	if hostname == "default" || hostname == "local" { | ||||
| 		logrus.Debugf("not checking server SSH host key against local/default target") | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	exists, _, err := GetHostKey(hostname) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|  | ||||
| @ -3,10 +3,13 @@ package stack // https://github.com/docker/cli/blob/master/cli/command/stack/swa | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"strings" | ||||
|  | ||||
| 	abraClient "coopcloud.tech/abra/pkg/client" | ||||
| 	"coopcloud.tech/abra/pkg/upstream/convert" | ||||
| 	"github.com/docker/cli/cli/command/service/progress" | ||||
| 	composetypes "github.com/docker/cli/cli/compose/types" | ||||
| 	"github.com/docker/docker/api/types" | ||||
| 	"github.com/docker/docker/api/types/container" | ||||
| @ -346,6 +349,7 @@ func deployServices( | ||||
| 		existingServiceMap[service.Spec.Name] = service | ||||
| 	} | ||||
|  | ||||
| 	var serviceIDs []string | ||||
| 	for internalName, serviceSpec := range services { | ||||
| 		var ( | ||||
| 			name        = namespace.Scope(internalName) | ||||
| @ -405,6 +409,8 @@ func deployServices( | ||||
| 				return errors.Wrapf(err, "failed to update service %s", name) | ||||
| 			} | ||||
|  | ||||
| 			serviceIDs = append(serviceIDs, service.ID) | ||||
|  | ||||
| 			for _, warning := range response.Warnings { | ||||
| 				logrus.Warn(warning) | ||||
| 			} | ||||
| @ -418,11 +424,35 @@ func deployServices( | ||||
| 				createOpts.QueryRegistry = true | ||||
| 			} | ||||
|  | ||||
| 			if _, err := cl.ServiceCreate(ctx, serviceSpec, createOpts); err != nil { | ||||
| 			serviceCreateResponse, err := cl.ServiceCreate(ctx, serviceSpec, createOpts) | ||||
| 			if err != nil { | ||||
| 				return errors.Wrapf(err, "failed to create service %s", name) | ||||
| 			} | ||||
|  | ||||
| 			serviceIDs = append(serviceIDs, serviceCreateResponse.ID) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	logrus.Infof("waiting for services to converge: %s", strings.Join(serviceIDs, ", ")) | ||||
|  | ||||
| 	ch := make(chan error, len(serviceIDs)) | ||||
| 	for _, serviceID := range serviceIDs { | ||||
| 		logrus.Debugf("waiting on %s to converge", serviceID) | ||||
| 		go func(s string) { | ||||
| 			ch <- waitOnService(ctx, cl, s) | ||||
| 		}(serviceID) | ||||
| 	} | ||||
|  | ||||
| 	for _, serviceID := range serviceIDs { | ||||
| 		err := <-ch | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		logrus.Debugf("assuming %s converged successfully", serviceID) | ||||
| 	} | ||||
|  | ||||
| 	logrus.Info("services converged 👌") | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -437,3 +467,17 @@ func getStackSecrets(ctx context.Context, dockerclient client.APIClient, namespa | ||||
| func getStackConfigs(ctx context.Context, dockerclient client.APIClient, namespace string) ([]swarm.Config, error) { | ||||
| 	return dockerclient.ConfigList(ctx, types.ConfigListOptions{Filters: getStackFilter(namespace)}) | ||||
| } | ||||
|  | ||||
| // https://github.com/docker/cli/blob/master/cli/command/service/helpers.go | ||||
| // https://github.com/docker/cli/blob/master/cli/command/service/progress/progress.go | ||||
| func waitOnService(ctx context.Context, cl *dockerclient.Client, serviceID string) error { | ||||
| 	errChan := make(chan error, 1) | ||||
| 	pipeReader, pipeWriter := io.Pipe() | ||||
|  | ||||
| 	go func() { | ||||
| 		errChan <- progress.ServiceProgress(ctx, cl, serviceID, pipeWriter) | ||||
| 	}() | ||||
|  | ||||
| 	go io.Copy(ioutil.Discard, pipeReader) | ||||
| 	return <-errChan | ||||
| } | ||||
|  | ||||
| @ -2,6 +2,15 @@ | ||||
|  | ||||
| ABRA_VERSION="0.3.0-alpha" | ||||
| ABRA_RELEASE_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$ABRA_VERSION" | ||||
| RC_VERSION="0.3.1-alpha-rc1" | ||||
| RC_VERSION_URL="https://git.coopcloud.tech/api/v1/repos/coop-cloud/abra/releases/tags/$RC_VERSION" | ||||
|  | ||||
| for arg in "$@"; do | ||||
|   if [ "$arg" == "--rc" ]; then | ||||
|     ABRA_VERSION="$RC_VERSION" | ||||
|     ABRA_RELEASE_URL="$RC_VERSION_URL" | ||||
|   fi | ||||
| done | ||||
|  | ||||
| function show_banner { | ||||
|   echo "" | ||||
| @ -35,6 +44,7 @@ function install_abra_release { | ||||
|     exit 1 | ||||
|   fi | ||||
|  | ||||
|  | ||||
|   # FIXME: support different architectures | ||||
|   PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m) | ||||
|   FILENAME="abra_"$ABRA_VERSION"_"$PLATFORM"" | ||||
| @ -79,6 +89,7 @@ function install_abra_release { | ||||
|   echo "abra installed to $HOME/.local/bin/abra" | ||||
| } | ||||
|  | ||||
|  | ||||
| function run_installation { | ||||
|   show_banner | ||||
|   install_abra_release | ||||
|  | ||||
		Reference in New Issue
	
	Block a user