github.com/mutagen-io/mutagen@v0.18.0-rc1/cmd/mutagen/sync/resume.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  // ResumeWithSelection is an orchestration convenience method that performs a
    21  // resume operation using the provided daemon connection and session selection.
    22  func ResumeWithSelection(
    23  	daemonConnection *grpc.ClientConn,
    24  	selection *selection.Selection,
    25  ) error {
    26  	// Initiate command line prompting.
    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}, true,
    32  	)
    33  	if err != nil {
    34  		promptingCancel()
    35  		return fmt.Errorf("unable to initiate prompting: %w", err)
    36  	}
    37  
    38  	// Perform the resume operation, cancel prompting, and handle errors.
    39  	synchronizationService := synchronizationsvc.NewSynchronizationClient(daemonConnection)
    40  	request := &synchronizationsvc.ResumeRequest{
    41  		Prompter:  prompter,
    42  		Selection: selection,
    43  	}
    44  	response, err := synchronizationService.Resume(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 resume response received: %w", err)
    53  	}
    54  
    55  	// Success.
    56  	statusLinePrinter.Clear()
    57  	return nil
    58  }
    59  
    60  // resumeMain is the entry point for the resume command.
    61  func resumeMain(_ *cobra.Command, arguments []string) error {
    62  	// Create session selection specification.
    63  	selection := &selection.Selection{
    64  		All:            resumeConfiguration.all,
    65  		Specifications: arguments,
    66  		LabelSelector:  resumeConfiguration.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 resume operation.
    80  	return ResumeWithSelection(daemonConnection, selection)
    81  }
    82  
    83  // resumeCommand is the resume command.
    84  var resumeCommand = &cobra.Command{
    85  	Use:          "resume [<session>...]",
    86  	Short:        "Resume a paused or disconnected synchronization session",
    87  	RunE:         resumeMain,
    88  	SilenceUsage: true,
    89  }
    90  
    91  // resumeConfiguration stores configuration for the resume command.
    92  var resumeConfiguration 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 resumed.
    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 := resumeCommand.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(&resumeConfiguration.help, "help", "h", false, "Show help information")
   112  
   113  	// Wire up resume flags.
   114  	flags.BoolVarP(&resumeConfiguration.all, "all", "a", false, "Resume all sessions")
   115  	flags.StringVar(&resumeConfiguration.labelSelector, "label-selector", "", "Resume sessions matching the specified label selector")
   116  }