Skip to content

Commit 7626689

Browse files
committed
shell: add --sync-exclude flag to exclude paths from --sync
Closes #4887
1 parent 2d4314e commit 7626689

1 file changed

Lines changed: 23 additions & 16 deletions

File tree

cmd/limactl/shell.go

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ func newShellCommand() *cobra.Command {
7373
shellCmd.Flags().Bool("preserve-env", false, "Propagate environment variables to the shell")
7474
shellCmd.Flags().Bool("start", false, "Start the instance if it is not already running")
7575
shellCmd.Flags().String("sync", "", "Copy a host directory to the guest and vice-versa upon exit")
76+
shellCmd.Flags().StringArray("sync-exclude", nil, "Exclude a path from --sync (rsync --exclude syntax); can be passed multiple times")
7677

7778
return shellCmd
7879
}
@@ -196,6 +197,18 @@ func shellAction(cmd *cobra.Command, args []string) error {
196197
return fmt.Errorf("failed to get sync flag: %w", err)
197198
}
198199
syncHostWorkdir := syncDirVal != ""
200+
201+
syncExcludes, err := flags.GetStringArray("sync-exclude")
202+
if err != nil {
203+
return fmt.Errorf("failed to get sync-exclude flag: %w", err)
204+
}
205+
if len(syncExcludes) > 0 && !syncHostWorkdir {
206+
return errors.New("--sync-exclude requires --sync")
207+
}
208+
var excludeArgs []string
209+
for _, e := range syncExcludes {
210+
excludeArgs = append(excludeArgs, "--exclude", e)
211+
}
199212
if syncHostWorkdir && len(inst.Config.Mounts) > 0 {
200213
return errors.New("cannot use `--sync` when the instance has host mounts configured, start the instance with `--mount-none` to disable mounts")
201214
}
@@ -381,11 +394,9 @@ func shellAction(cmd *cobra.Command, args []string) error {
381394
fmt.Sprintf("%s:%s", inst.Name, destRsyncDir),
382395
}
383396
rsync, err = copytool.New(ctx, string(copytool.BackendRsync), paths, &copytool.Options{
384-
Recursive: true,
385-
Verbose: false,
386-
AdditionalArgs: []string{
387-
"--delete",
388-
},
397+
Recursive: true,
398+
Verbose: false,
399+
AdditionalArgs: append([]string{"--delete"}, excludeArgs...),
389400
})
390401
if err != nil {
391402
return err
@@ -439,12 +450,12 @@ func shellAction(cmd *cobra.Command, args []string) error {
439450
if err != nil {
440451
return err
441452
}
442-
return askUserForRsyncBack(ctx, cmd, inst, sshExecForRsync, hostCurrentDir, destRsyncDir, rsync, tty)
453+
return askUserForRsyncBack(ctx, cmd, inst, sshExecForRsync, hostCurrentDir, destRsyncDir, rsync, tty, excludeArgs)
443454
}
444455
return nil
445456
}
446457

447-
func askUserForRsyncBack(ctx context.Context, cmd *cobra.Command, inst *limatype.Instance, sshCmd *exec.Cmd, hostCurrentDir, destRsyncDir string, rsync copytool.CopyTool, tty bool) error {
458+
func askUserForRsyncBack(ctx context.Context, cmd *cobra.Command, inst *limatype.Instance, sshCmd *exec.Cmd, hostCurrentDir, destRsyncDir string, rsync copytool.CopyTool, tty bool, excludeArgs []string) error {
448459
remoteSource := fmt.Sprintf("%s:%s", inst.Name, destRsyncDir)
449460
clean := filepath.Clean(hostCurrentDir)
450461
dirForCleanup := shellescape.Quote(filepath.Join(*inst.Config.User.Home, clean))
@@ -478,7 +489,7 @@ func askUserForRsyncBack(ctx context.Context, cmd *cobra.Command, inst *limatype
478489
return rsyncBack()
479490
}
480491

481-
rawOutput, stats, err := getRsyncStats(ctx, remoteSource, filepath.Dir(hostCurrentDir))
492+
rawOutput, stats, err := getRsyncStats(ctx, remoteSource, filepath.Dir(hostCurrentDir), excludeArgs)
482493
if err != nil {
483494
logrus.WithError(err).Warn("failed to get rsync stats")
484495
}
@@ -749,16 +760,12 @@ func (s *rsyncStats) String() string {
749760
return fmt.Sprintf("added: %d, deleted: %d, modified: %d, metadata: %d", s.Added, s.Deleted, s.Modified, s.Metadata)
750761
}
751762

752-
func getRsyncStats(ctx context.Context, source, destination string) (string, *rsyncStats, error) {
763+
func getRsyncStats(ctx context.Context, source, destination string, excludeArgs []string) (string, *rsyncStats, error) {
753764
paths := []string{source, destination}
765+
addArgs := append([]string{"--dry-run", "--itemize-changes", "-ah", "--delete"}, excludeArgs...)
754766
rsync, err := copytool.New(ctx, string(copytool.BackendRsync), paths, &copytool.Options{
755-
Verbose: true,
756-
AdditionalArgs: []string{
757-
"--dry-run",
758-
"--itemize-changes",
759-
"-ah",
760-
"--delete",
761-
},
767+
Verbose: true,
768+
AdditionalArgs: addArgs,
762769
})
763770
if err != nil {
764771
return "", nil, err

0 commit comments

Comments
 (0)