package app import ( "context" "fmt" "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/log" "coopcloud.tech/abra/pkg/ui" upstream "coopcloud.tech/abra/pkg/upstream/service" stack "coopcloud.tech/abra/pkg/upstream/stack" "github.com/spf13/cobra" ) var AppRestartCommand = &cobra.Command{ Use: "restart [[service] | --all-services] [flags]", Aliases: []string{"re"}, Short: "Restart an app", Long: `This command restarts services within a deployed app. Run "abra app ps " to see a list of service names. Pass "--all-services/-a" to restart all services.`, Example: ` # 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("missing [service]") } if serviceName != "" && allServices { log.Fatal("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.Fatalf("%s is not deployed?", app.Name) } for _, serviceName := range serviceNames { stackServiceName := fmt.Sprintf("%s_%s", app.StackName(), serviceName) log.Debugf("attempting to scale %s to 0", stackServiceName) // TODO if err := upstream.RunServiceScale(context.Background(), cl, stackServiceName, 0); err != nil { log.Fatal(err) } // TODO if err := stack.WaitOnServices( cmd.Context(), cl, // TODO []ui.ServiceMeta{{Name: stackServiceName, ID: "???"}}, app.Name, app.Server, ); err != nil { log.Fatal(err) } log.Debugf("%s has been scaled to 0", stackServiceName) log.Debugf("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, // TODO []ui.ServiceMeta{{Name: stackServiceName, ID: "???"}}, app.Name, app.Server, ); err != nil { log.Fatal(err) } log.Debugf("%s has been scaled to 1", stackServiceName) log.Infof("%s service successfully restarted", serviceName) } }, } var allServices bool func init() { AppRestartCommand.Flags().BoolVarP( &internal.Chaos, "chaos", "C", false, "ignore uncommitted recipes changes", ) AppRestartCommand.Flags().BoolVarP( &allServices, "all-services", "a", false, "restart all services", ) }