Some checks failed
		
		
	
	continuous-integration/drone/push Build is failing
				
			See #647 See toolshed/xgettext-go#1
		
			
				
	
	
		
			174 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package app
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"strings"
 | |
| 
 | |
| 	"coopcloud.tech/abra/cli/internal"
 | |
| 	appPkg "coopcloud.tech/abra/pkg/app"
 | |
| 	"coopcloud.tech/abra/pkg/autocomplete"
 | |
| 	"coopcloud.tech/abra/pkg/client"
 | |
| 	"coopcloud.tech/abra/pkg/i18n"
 | |
| 	"coopcloud.tech/abra/pkg/log"
 | |
| 	"coopcloud.tech/abra/pkg/ui"
 | |
| 	upstream "coopcloud.tech/abra/pkg/upstream/service"
 | |
| 	stack "coopcloud.tech/abra/pkg/upstream/stack"
 | |
| 	"github.com/docker/docker/api/types"
 | |
| 	"github.com/spf13/cobra"
 | |
| )
 | |
| 
 | |
| // translators: `abra app restart` aliases. use a comma separated list of aliases with
 | |
| // no spaces in between
 | |
| var appRestartAliases = i18n.G("re")
 | |
| 
 | |
| var AppRestartCommand = &cobra.Command{
 | |
| 	// translators: `app restart` command
 | |
| 	Use:     i18n.G("restart <domain> [[service] | --all-services] [flags]"),
 | |
| 	Aliases: strings.Split(appRestartAliases, ","),
 | |
| 	// translators: Short description for `app restart` command
 | |
| 	Short: i18n.G("Restart an app"),
 | |
| 	Long: i18n.G(`This command restarts services within a deployed app.
 | |
| 
 | |
| Run "abra app ps <domain>" to see a list of service names.
 | |
| 
 | |
| Pass "--all-services/-a" to restart all services.`),
 | |
| 	Example: i18n.G(`  # restart a single app service
 | |
|   abra app restart 1312.net app
 | |
| 
 | |
|   # restart all app services
 | |
|   abra app restart 1312.net -a`),
 | |
| 	Args: cobra.RangeArgs(1, 2),
 | |
| 	ValidArgsFunction: func(
 | |
| 		cmd *cobra.Command,
 | |
| 		args []string,
 | |
| 		toComplete string) ([]string, cobra.ShellCompDirective) {
 | |
| 		switch l := len(args); l {
 | |
| 		case 0:
 | |
| 			return autocomplete.AppNameComplete()
 | |
| 		case 1:
 | |
| 			if !allServices {
 | |
| 				return autocomplete.ServiceNameComplete(args[0])
 | |
| 			}
 | |
| 			return nil, cobra.ShellCompDirectiveDefault
 | |
| 		default:
 | |
| 			return nil, cobra.ShellCompDirectiveError
 | |
| 		}
 | |
| 	},
 | |
| 	Run: func(cmd *cobra.Command, args []string) {
 | |
| 		app := internal.ValidateApp(args)
 | |
| 
 | |
| 		if err := app.Recipe.Ensure(internal.GetEnsureContext()); err != nil {
 | |
| 			log.Fatal(err)
 | |
| 		}
 | |
| 
 | |
| 		var serviceName string
 | |
| 		if len(args) == 2 {
 | |
| 			serviceName = args[1]
 | |
| 		}
 | |
| 
 | |
| 		if serviceName == "" && !allServices {
 | |
| 			log.Fatal(i18n.G("missing [service]"))
 | |
| 		}
 | |
| 
 | |
| 		if serviceName != "" && allServices {
 | |
| 			log.Fatal(i18n.G("cannot use [service] and --all-services/-a together"))
 | |
| 		}
 | |
| 
 | |
| 		var serviceNames []string
 | |
| 		if allServices {
 | |
| 			var err error
 | |
| 			serviceNames, err = appPkg.GetAppServiceNames(app.Name)
 | |
| 			if err != nil {
 | |
| 				log.Fatal(err)
 | |
| 			}
 | |
| 		} else {
 | |
| 			serviceNames = append(serviceNames, serviceName)
 | |
| 		}
 | |
| 
 | |
| 		cl, err := client.New(app.Server)
 | |
| 		if err != nil {
 | |
| 			log.Fatal(err)
 | |
| 		}
 | |
| 
 | |
| 		deployMeta, err := stack.IsDeployed(context.Background(), cl, app.StackName())
 | |
| 		if err != nil {
 | |
| 			log.Fatal(err)
 | |
| 		}
 | |
| 
 | |
| 		if !deployMeta.IsDeployed {
 | |
| 			log.Fatal(i18n.G("%s is not deployed?", app.Name))
 | |
| 		}
 | |
| 
 | |
| 		for _, serviceName := range serviceNames {
 | |
| 			stackServiceName := fmt.Sprintf("%s_%s", app.StackName(), serviceName)
 | |
| 
 | |
| 			service, _, err := cl.ServiceInspectWithRaw(
 | |
| 				context.Background(),
 | |
| 				stackServiceName,
 | |
| 				types.ServiceInspectOptions{},
 | |
| 			)
 | |
| 			if err != nil {
 | |
| 				log.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			log.Debug(i18n.G("attempting to scale %s to 0", stackServiceName))
 | |
| 
 | |
| 			if err := upstream.RunServiceScale(context.Background(), cl, stackServiceName, 0); err != nil {
 | |
| 				log.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			f, err := app.Filters(true, false, serviceName)
 | |
| 			if err != nil {
 | |
| 				log.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			waitOpts := stack.WaitOpts{
 | |
| 				Services:   []ui.ServiceMeta{{Name: stackServiceName, ID: service.ID}},
 | |
| 				AppName:    app.Name,
 | |
| 				ServerName: app.Server,
 | |
| 				Filters:    f,
 | |
| 				NoLog:      true,
 | |
| 				Quiet:      true,
 | |
| 			}
 | |
| 
 | |
| 			if err := stack.WaitOnServices(cmd.Context(), cl, waitOpts); err != nil {
 | |
| 				log.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			log.Debug(i18n.G("%s has been scaled to 0", stackServiceName))
 | |
| 			log.Debug(i18n.G("attempting to scale %s to 1", stackServiceName))
 | |
| 
 | |
| 			if err := upstream.RunServiceScale(context.Background(), cl, stackServiceName, 1); err != nil {
 | |
| 				log.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			if err := stack.WaitOnServices(cmd.Context(), cl, waitOpts); err != nil {
 | |
| 				log.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			log.Debug(i18n.G("%s has been scaled to 1", stackServiceName))
 | |
| 			log.Info(i18n.G("%s service successfully restarted", serviceName))
 | |
| 		}
 | |
| 	},
 | |
| }
 | |
| 
 | |
| var allServices bool
 | |
| 
 | |
| func init() {
 | |
| 	AppRestartCommand.Flags().BoolVarP(
 | |
| 		&internal.Chaos,
 | |
| 		i18n.G("chaos"),
 | |
| 		i18n.G("C"),
 | |
| 		false,
 | |
| 		i18n.G("ignore uncommitted recipes changes"),
 | |
| 	)
 | |
| 	AppRestartCommand.Flags().BoolVarP(
 | |
| 		&allServices,
 | |
| 		i18n.G("all-services"),
 | |
| 		i18n.GC("a", "app restart"),
 | |
| 		false,
 | |
| 		i18n.G("restart all services"),
 | |
| 	)
 | |
| }
 |