@@ -2011,7 +2011,7 @@ def print_usage():
20112011 Format: /host/path:/guest/path
20122012 Example: -v /home/user/data:/mnt/data
20132013 --sync <mode> Synchronization mode for -v folders.
2014- Supported: sshfs (default), nfs, rsync , scp.
2014+ Supported: rsync (default), sshfs, nfs , scp.
20152015 Note: sshfs/nfs not supported on Windows hosts; rsync requires rsync.exe.
20162016 --data-dir <dir> Directory to store images and metadata (Default: ./output).
20172017 --cache-dir <dir> Directory to cache extracted qcow2 files (avoids re-download and re-extract).
@@ -2737,7 +2737,7 @@ def sync_nfs(ssh_cmd, vhost, vguest, os_name, sudo_cmd):
27372737 if not mounted :
27382738 log ("Warning: Failed to mount shared folder via NFS." )
27392739
2740- def sync_rsync (ssh_cmd , vhost , vguest , os_name , output_dir , vm_name ):
2740+ def sync_rsync (ssh_cmd , vhost , vguest , os_name , output_dir , vm_name , excludes = None ):
27412741 """Syncs a host directory to the guest using rsync (Push mode)."""
27422742 host_rsync = find_rsync ()
27432743 if not host_rsync :
@@ -2860,6 +2860,10 @@ def to_ssh_path(p):
28602860 elif os_name in ["openindiana" , "solaris" , "omnios" ]:
28612861 cmd .extend (["--rsync-path" , "/usr/bin/rsync" ])
28622862
2863+ if excludes :
2864+ for ex in excludes :
2865+ cmd .extend (["--exclude" , ex .replace ("\\ " , "/" )])
2866+
28632867 # Source and Destination come last
28642868 cmd .extend ([src , "{}:{}" .format (remote_host , vguest )])
28652869
@@ -2884,7 +2888,7 @@ def to_ssh_path(p):
28842888 if not synced :
28852889 log ("Warning: Failed to sync shared folder via rsync." )
28862890
2887- def sync_scp (ssh_cmd , vhost , vguest , sshport , hostid_file , ssh_user ):
2891+ def sync_scp (ssh_cmd , vhost , vguest , sshport , hostid_file , ssh_user , excludes = None ):
28882892 """Syncs via scp (Push mode from host to guest)."""
28892893 log ("Syncing via scp: {} -> {}" .format (vhost , vguest ))
28902894
@@ -2903,6 +2907,8 @@ def sync_scp(ssh_cmd, vhost, vguest, sshport, hostid_file, ssh_user):
29032907 if os .path .isdir (vhost ):
29042908 try :
29052909 entries = os .listdir (vhost )
2910+ if excludes :
2911+ entries = [e for e in entries if e not in excludes ]
29062912 except OSError as exc :
29072913 log ("Warning: Failed to read {}: {}" .format (vhost , exc ))
29082914 return
@@ -3061,7 +3067,7 @@ def main():
30613067 'vpaths' : [],
30623068 'ports' : [],
30633069 'vnc' : "" ,
3064- 'sync' : "sshfs " ,
3070+ 'sync' : "rsync " ,
30653071 'qmon' : "" ,
30663072 'disktype' : "" ,
30673073 'public' : False ,
@@ -3174,7 +3180,12 @@ def main():
31743180 config ['vga' ] = args [i + 1 ]
31753181 i += 1
31763182 elif arg == "--sync" :
3177- config ['sync' ] = args [i + 1 ]
3183+ val = args [i + 1 ].lower ()
3184+ if val == "" :
3185+ val = "rsync"
3186+ if val not in ["sshfs" , "nfs" , "rsync" , "scp" ]:
3187+ fatal ("Invalid --sync mode: {}. Supported: rsync, sshfs, nfs, scp." .format (val ))
3188+ config ['sync' ] = val
31783189 i += 1
31793190 elif arg == "--disktype" :
31803191 config ['disktype' ] = args [i + 1 ]
@@ -4691,14 +4702,28 @@ def supports_ansi_color(stream):
46914702 vhost = os .path .abspath (vhost )
46924703 if not vhost or not vguest :
46934704 raise ValueError
4705+
4706+ excludes = []
4707+ for ex_dir in [working_dir , config .get ('cachedir' )]:
4708+ if ex_dir :
4709+ try :
4710+ if os .path .commonpath ([vhost , ex_dir ]) == vhost :
4711+ rel = os .path .relpath (ex_dir , vhost )
4712+ if rel != "." and not rel .startswith (".." ):
4713+ excludes .append (rel )
4714+ except ValueError :
4715+ pass
4716+
46944717 debuglog (config ['debug' ], "Mounting host dir: {} to guest: {}" .format (vhost , vguest ))
4718+ if excludes :
4719+ debuglog (config ['debug' ], "Excluding paths from sync: {}" .format (", " .join (excludes )))
46954720
46964721 if config ['sync' ] == 'nfs' :
46974722 sync_nfs (ssh_base_cmd , vhost , vguest , config ['os' ], sudo_cmd )
46984723 elif config ['sync' ] == 'rsync' :
4699- sync_rsync (ssh_base_cmd , vhost , vguest , config ['os' ], output_dir , vm_name )
4724+ sync_rsync (ssh_base_cmd , vhost , vguest , config ['os' ], output_dir , vm_name , excludes = excludes )
47004725 elif config ['sync' ] == 'scp' :
4701- sync_scp (ssh_base_cmd , vhost , vguest , config ['sshport' ], hostid_file , vm_user )
4726+ sync_scp (ssh_base_cmd , vhost , vguest , config ['sshport' ], hostid_file , vm_user , excludes = excludes )
47024727 else :
47034728 sync_sshfs (ssh_base_cmd , vhost , vguest , config ['os' ], config .get ('release' ))
47044729
0 commit comments