@@ -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