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  }