github.com/mutagen-io/mutagen@v0.18.0-rc1/cmd/mutagen/forward/pause.go (about) 1 package forward 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/spf13/cobra" 8 9 "google.golang.org/grpc" 10 11 "github.com/mutagen-io/mutagen/cmd" 12 "github.com/mutagen-io/mutagen/cmd/mutagen/daemon" 13 14 "github.com/mutagen-io/mutagen/pkg/grpcutil" 15 "github.com/mutagen-io/mutagen/pkg/selection" 16 forwardingsvc "github.com/mutagen-io/mutagen/pkg/service/forwarding" 17 promptingsvc "github.com/mutagen-io/mutagen/pkg/service/prompting" 18 ) 19 20 // PauseWithSelection is an orchestration convenience method that performs a 21 // pause operation using the provided daemon connection and session selection. 22 func PauseWithSelection( 23 daemonConnection *grpc.ClientConn, 24 selection *selection.Selection, 25 ) error { 26 // Initiate command line messaging. 27 statusLinePrinter := &cmd.StatusLinePrinter{} 28 promptingCtx, promptingCancel := context.WithCancel(context.Background()) 29 prompter, promptingErrors, err := promptingsvc.Host( 30 promptingCtx, promptingsvc.NewPromptingClient(daemonConnection), 31 &cmd.StatusLinePrompter{Printer: statusLinePrinter}, false, 32 ) 33 if err != nil { 34 promptingCancel() 35 return fmt.Errorf("unable to initiate prompting: %w", err) 36 } 37 38 // Perform the pause operation, cancel prompting, and handle errors. 39 forwardingService := forwardingsvc.NewForwardingClient(daemonConnection) 40 request := &forwardingsvc.PauseRequest{ 41 Prompter: prompter, 42 Selection: selection, 43 } 44 response, err := forwardingService.Pause(context.Background(), request) 45 promptingCancel() 46 <-promptingErrors 47 if err != nil { 48 statusLinePrinter.BreakIfPopulated() 49 return grpcutil.PeelAwayRPCErrorLayer(err) 50 } else if err = response.EnsureValid(); err != nil { 51 statusLinePrinter.BreakIfPopulated() 52 return fmt.Errorf("invalid pause response received: %w", err) 53 } 54 55 // Success. 56 statusLinePrinter.Clear() 57 return nil 58 } 59 60 // pauseMain is the entry point for the pause command. 61 func pauseMain(_ *cobra.Command, arguments []string) error { 62 // Create session selection specification. 63 selection := &selection.Selection{ 64 All: pauseConfiguration.all, 65 Specifications: arguments, 66 LabelSelector: pauseConfiguration.labelSelector, 67 } 68 if err := selection.EnsureValid(); err != nil { 69 return fmt.Errorf("invalid session selection specification: %w", err) 70 } 71 72 // Connect to the daemon and defer closure of the connection. 73 daemonConnection, err := daemon.Connect(true, true) 74 if err != nil { 75 return fmt.Errorf("unable to connect to daemon: %w", err) 76 } 77 defer daemonConnection.Close() 78 79 // Perform the pause operation. 80 return PauseWithSelection(daemonConnection, selection) 81 } 82 83 // pauseCommand is the pause command. 84 var pauseCommand = &cobra.Command{ 85 Use: "pause [<session>...]", 86 Short: "Pause a forwarding session", 87 RunE: pauseMain, 88 SilenceUsage: true, 89 } 90 91 // pauseConfiguration stores configuration for the pause command. 92 var pauseConfiguration struct { 93 // help indicates whether or not to show help information and exit. 94 help bool 95 // all indicates whether or not all sessions should be paused. 96 all bool 97 // labelSelector encodes a label selector to be used in identifying which 98 // sessions should be paused. 99 labelSelector string 100 } 101 102 func init() { 103 // Grab a handle for the command line flags. 104 flags := pauseCommand.Flags() 105 106 // Disable alphabetical sorting of flags in help output. 107 flags.SortFlags = false 108 109 // Manually add a help flag to override the default message. Cobra will 110 // still implement its logic automatically. 111 flags.BoolVarP(&pauseConfiguration.help, "help", "h", false, "Show help information") 112 113 // Wire up pause flags. 114 flags.BoolVarP(&pauseConfiguration.all, "all", "a", false, "Pause all sessions") 115 flags.StringVar(&pauseConfiguration.labelSelector, "label-selector", "", "Pause sessions matching the specified label selector") 116 }