Skip to content

Commit 18a5cbf

Browse files
authored
Merge pull request #18 from anyvm-org/dev
sync
2 parents ce0132d + 404d834 commit 18a5cbf

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

.github/workflows/solaris.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
release: ["11.4", "11.4-gcc"]
2727
arch: [""]
2828
runs: ["ubuntu-24.04"]
29+
sync: ["nfs", "scp"]
2930

3031

3132
uses: ./.github/workflows/testrun.yml
@@ -35,7 +36,7 @@ jobs:
3536
os: solaris
3637
release: ${{ matrix.release }}
3738
arch: ${{ matrix.arch }}
38-
sync: nfs
39+
sync: ${{ matrix.sync }}
3940

4041

4142

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ All examples below use `python3 anyvm.py ...`. You can also run `python3 anyvm.p
206206
- Linux/macOS example: `python3 anyvm.py --os freebsd -v $(pwd):/data`
207207
- Windows example: `python3 anyvm.py --os freebsd -v D:\\data:/data`
208208

209-
- `--sync <mode>`: Sync mechanism used for `-v`.
210-
- Supported: `sshfs` (default), `nfs`, `rsync`, `scp`
209+
- `--sync <mode>`: Sync mechanism used for `-v`. Strictly validated.
210+
- Supported: `rsync` (default), `sshfs`, `nfs`, `scp`. Empty string also defaults to `rsync`. Any other value will cause an error.
211211
- Examples:
212212
- `python3 anyvm.py --os freebsd --sync rsync -v $(pwd):/data`
213213
- `python3 anyvm.py --os solaris --sync scp -v D:\\data:/data`

anyvm.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)