github.com/mutagen-io/mutagen@v0.18.0-rc1/cmd/mutagen/sync/flush.go (about) 1 package sync 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 promptingsvc "github.com/mutagen-io/mutagen/pkg/service/prompting" 17 synchronizationsvc "github.com/mutagen-io/mutagen/pkg/service/synchronization" 18 ) 19 20 // FlushWithSelection is an orchestration convenience method that performs a 21 // flush operation using the provided daemon connection and session selection. 22 func FlushWithSelection( 23 daemonConnection *grpc.ClientConn, 24 selection *selection.Selection, 25 skipWait bool, 26 ) error { 27 // Initiate command line messaging. 28 statusLinePrinter := &cmd.StatusLinePrinter{} 29 promptingCtx, promptingCancel := context.WithCancel(context.Background()) 30 prompter, promptingErrors, err := promptingsvc.Host( 31 promptingCtx, promptingsvc.NewPromptingClient(daemonConnection), 32 &cmd.StatusLinePrompter{Printer: statusLinePrinter}, false, 33 ) 34 if err != nil { 35 promptingCancel() 36 return fmt.Errorf("unable to initiate prompting: %w", err) 37 } 38 39 // Perform the flush operation, cancel prompting, and handle errors. 40 synchronizationService := synchronizationsvc.NewSynchronizationClient(daemonConnection) 41 request := &synchronizationsvc.FlushRequest{ 42 Prompter: prompter, 43 Selection: selection, 44 SkipWait: skipWait, 45 } 46 response, err := synchronizationService.Flush(context.Background(), request) 47 promptingCancel() 48 <-promptingErrors 49 if err != nil { 50 statusLinePrinter.BreakIfPopulated() 51 return grpcutil.PeelAwayRPCErrorLayer(err) 52 } else if err = response.EnsureValid(); err != nil { 53 statusLinePrinter.BreakIfPopulated() 54 return fmt.Errorf("invalid flush response received: %w", err) 55 } 56 57 // Success. 58 statusLinePrinter.Clear() 59 return nil 60 } 61 62 // flushMain is the entry point for the flush command. 63 func flushMain(_ *cobra.Command, arguments []string) error { 64 // Create session selection specification. 65 selection := &selection.Selection{ 66 All: flushConfiguration.all, 67 Specifications: arguments, 68 LabelSelector: flushConfiguration.labelSelector, 69 } 70 if err := selection.EnsureValid(); err != nil { 71 return fmt.Errorf("invalid session selection specification: %w", err) 72 } 73 74 // Connect to the daemon and defer closure of the connection. 75 daemonConnection, err := daemon.Connect(true, true) 76 if err != nil { 77 return fmt.Errorf("unable to connect to daemon: %w", err) 78 } 79 defer daemonConnection.Close() 80 81 // Perform the flush operation. 82 return FlushWithSelection(daemonConnection, selection, flushConfiguration.skipWait) 83 } 84 85 // flushCommand is the flush command. 86 var flushCommand = &cobra.Command{ 87 Use: "flush [<session>...]", 88 Short: "Force a synchronization cycle", 89 RunE: flushMain, 90 SilenceUsage: true, 91 } 92 93 // flushConfiguration stores configuration for the flush command. 94 var flushConfiguration struct { 95 // help indicates whether or not to show help information and exit. 96 help bool 97 // all indicates whether or not all sessions should be flushed. 98 all bool 99 // labelSelector encodes a label selector to be used in identifying which 100 // sessions should be paused. 101 labelSelector string 102 // skipWait indicates whether or not the flush operation should block until 103 // a synchronization cycle completes for each sesion requested. 104 skipWait bool 105 } 106 107 func init() { 108 // Grab a handle for the command line flags. 109 flags := flushCommand.Flags() 110 111 // Disable alphabetical sorting of flags in help output. 112 flags.SortFlags = false 113 114 // Manually add a help flag to override the default message. Cobra will 115 // still implement its logic automatically. 116 flags.BoolVarP(&flushConfiguration.help, "help", "h", false, "Show help information") 117 118 // Wire up flush flags. 119 flags.BoolVarP(&flushConfiguration.all, "all", "a", false, "Flush all sessions") 120 flags.StringVar(&flushConfiguration.labelSelector, "label-selector", "", "Flush sessions matching the specified label selector") 121 flags.BoolVar(&flushConfiguration.skipWait, "skip-wait", false, "Avoid waiting for the resulting synchronization cycle(s) to complete") 122 }