clonebox 1.1.19__py3-none-any.whl → 1.1.20__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
clonebox/cli.py CHANGED
@@ -1884,14 +1884,24 @@ def cmd_test(args):
1884
1884
  # Give QEMU Guest Agent some time to come up (common during early boot)
1885
1885
  qga_ready = _qga_ping(vm_name, conn_uri)
1886
1886
  if not qga_ready:
1887
- for _ in range(12): # ~60s
1887
+ console.print("[yellow]⏳ Waiting for QEMU Guest Agent (up to 60s)...[/]")
1888
+ qga_wait_start = time.time()
1889
+ for attempt in range(12): # ~60s
1888
1890
  time.sleep(5)
1889
1891
  qga_ready = _qga_ping(vm_name, conn_uri)
1892
+ elapsed = int(time.time() - qga_wait_start)
1890
1893
  if qga_ready:
1894
+ console.print(f"[green]✅ QEMU Guest Agent connected after {elapsed}s[/]")
1891
1895
  break
1896
+ if attempt % 2 == 1:
1897
+ console.print(f"[dim] ...still waiting ({elapsed}s elapsed)[/]")
1898
+
1899
+ if not qga_ready:
1900
+ console.print("[yellow]⚠️ QEMU Guest Agent still not connected[/]")
1892
1901
 
1893
1902
  # Check cloud-init status immediately if QGA is ready
1894
1903
  if qga_ready:
1904
+ console.print("[dim] Checking cloud-init status via QGA...[/]")
1895
1905
  status = _qga_exec(
1896
1906
  vm_name, conn_uri, "cloud-init status 2>/dev/null || true", timeout=15
1897
1907
  )
@@ -2068,6 +2078,8 @@ def cmd_test(args):
2068
2078
 
2069
2079
  # Run full validation if requested
2070
2080
  if validate_all and state == "running":
2081
+ console.print("[bold cyan]🔎 Starting deep validation (--validate)[/]")
2082
+ console.print("[dim]This can take a few minutes on first boot (waiting for QGA/cloud-init, checking packages/services).[/]")
2071
2083
  validator = VMValidator(
2072
2084
  config,
2073
2085
  vm_name,
clonebox/validator.py CHANGED
@@ -266,12 +266,17 @@ class VMValidator:
266
266
  self.console.print("[dim]No APT packages configured[/]")
267
267
  return self.results["packages"]
268
268
 
269
+ total_pkgs = len(packages)
270
+ self.console.print(f"[dim]Checking {total_pkgs} packages via QGA...[/]")
271
+
269
272
  pkg_table = Table(title="Package Validation", border_style="cyan")
270
273
  pkg_table.add_column("Package", style="bold")
271
274
  pkg_table.add_column("Status", justify="center")
272
275
  pkg_table.add_column("Version", style="dim")
273
276
 
274
- for package in packages:
277
+ for idx, package in enumerate(packages, 1):
278
+ if idx == 1 or idx % 25 == 0 or idx == total_pkgs:
279
+ self.console.print(f"[dim] ...packages progress: {idx}/{total_pkgs}[/]")
275
280
  self.results["packages"]["total"] += 1
276
281
 
277
282
  # Check if installed
@@ -315,12 +320,17 @@ class VMValidator:
315
320
  self.console.print("[dim]No snap packages configured[/]")
316
321
  return self.results["snap_packages"]
317
322
 
323
+ total_snaps = len(snap_packages)
324
+ self.console.print(f"[dim]Checking {total_snaps} snap packages via QGA...[/]")
325
+
318
326
  snap_table = Table(title="Snap Package Validation", border_style="cyan")
319
327
  snap_table.add_column("Package", style="bold")
320
328
  snap_table.add_column("Status", justify="center")
321
329
  snap_table.add_column("Version", style="dim")
322
330
 
323
- for package in snap_packages:
331
+ for idx, package in enumerate(snap_packages, 1):
332
+ if idx == 1 or idx % 25 == 0 or idx == total_snaps:
333
+ self.console.print(f"[dim] ...snap progress: {idx}/{total_snaps}[/]")
324
334
  self.results["snap_packages"]["total"] += 1
325
335
 
326
336
  # Check if installed
@@ -395,6 +405,9 @@ class VMValidator:
395
405
  self.console.print("[dim]No services configured[/]")
396
406
  return self.results["services"]
397
407
 
408
+ total_svcs = len(services)
409
+ self.console.print(f"[dim]Checking {total_svcs} services via QGA...[/]")
410
+
398
411
  if "skipped" not in self.results["services"]:
399
412
  self.results["services"]["skipped"] = 0
400
413
 
@@ -405,7 +418,9 @@ class VMValidator:
405
418
  svc_table.add_column("PID", justify="right", style="dim")
406
419
  svc_table.add_column("Note", style="dim")
407
420
 
408
- for service in services:
421
+ for idx, service in enumerate(services, 1):
422
+ if idx == 1 or idx % 25 == 0 or idx == total_svcs:
423
+ self.console.print(f"[dim] ...services progress: {idx}/{total_svcs}[/]")
409
424
  if service in self.VM_EXCLUDED_SERVICES:
410
425
  svc_table.add_row(service, "[dim]—[/]", "[dim]—[/]", "[dim]—[/]", "host-only")
411
426
  self.results["services"]["skipped"] += 1
@@ -1144,10 +1159,15 @@ class VMValidator:
1144
1159
  if not self._check_qga_ready():
1145
1160
  wait_deadline = time.time() + 180
1146
1161
  self.console.print("[yellow]⏳ Waiting for QEMU Guest Agent (up to 180s)...[/]")
1162
+ last_log = 0
1147
1163
  while time.time() < wait_deadline:
1148
1164
  time.sleep(5)
1149
1165
  if self._check_qga_ready():
1150
1166
  break
1167
+ elapsed = int(180 - (wait_deadline - time.time()))
1168
+ if elapsed - last_log >= 15:
1169
+ self.console.print(f"[dim] ...still waiting for QGA ({elapsed}s elapsed)[/]")
1170
+ last_log = elapsed
1151
1171
 
1152
1172
  if not self._check_qga_ready():
1153
1173
  self.console.print("[red]❌ QEMU Guest Agent not responding[/]")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clonebox
3
- Version: 1.1.19
3
+ Version: 1.1.20
4
4
  Summary: Clone your workstation environment to an isolated VM with selective apps, paths and services
5
5
  Author: CloneBox Team
6
6
  License: Apache-2.0
@@ -1,7 +1,7 @@
1
1
  clonebox/__init__.py,sha256=CyfHVVq6KqBr4CNERBpXk_O6Q5B35q03YpdQbokVvvI,408
2
2
  clonebox/__main__.py,sha256=Fcoyzwwyz5-eC_sBlQk5a5RbKx8uodQz5sKJ190U0NU,135
3
3
  clonebox/audit.py,sha256=1W9vaIjB0A--_p7CgE3cIP5RNckJG1RxJrL-tOb-QmU,14298
4
- clonebox/cli.py,sha256=yxGj733N1OUt8m4UzqxGV9jBZCdehychpV8KRi7zZJU,179262
4
+ clonebox/cli.py,sha256=xLUs2SWVY6sWonP-304vc--eFc8uvHsEU2boAKjCt8c,180126
5
5
  clonebox/cloner.py,sha256=rU5MERLn2JwayjLM2RsMeOWdY0xJSkCVzXl7dj9uIVM,111622
6
6
  clonebox/container.py,sha256=tiYK1ZB-DhdD6A2FuMA0h_sRNkUI7KfYcJ0tFOcdyeM,6105
7
7
  clonebox/dashboard.py,sha256=dMY6odvPq3j6FronhRRsX7aY3qdCwznB-aCWKEmHDNw,5768
@@ -20,7 +20,7 @@ clonebox/resource_monitor.py,sha256=lDR9KyPbVtImeeOkOBPPVP-5yCgoL5hsVFPZ_UqsY0w,
20
20
  clonebox/resources.py,sha256=IkuM4OdSDV4qhyc0eIynwbAHBTv0aVSxxW-gghsnCAs,6815
21
21
  clonebox/rollback.py,sha256=hpwO-8Ehe1pW0wHuZvJkC_qxZ6yEo9otCJRhGIUArCo,5711
22
22
  clonebox/secrets.py,sha256=l1jwJcEPB1qMoGNLPjyrkKKr1khh9VmftFJI9BWhgK0,10628
23
- clonebox/validator.py,sha256=2d14DHSo7Im-fFJaaDeACN1H82728FmwcZDSPVKbG44,53368
23
+ clonebox/validator.py,sha256=gYBpzHMhp4ruhh_zlQjAcJ6cn-cUO4XBfgjW5KH0K20,54524
24
24
  clonebox/backends/libvirt_backend.py,sha256=_HxB2itduhDsXrWoNTqelUqHEXnPqbnBuFNu8XJkNFA,7269
25
25
  clonebox/backends/qemu_disk.py,sha256=YsGjYX5sbEf35Y4yjTpNkZat73a4RGBxY-KTVzJhqIs,1687
26
26
  clonebox/backends/subprocess_runner.py,sha256=c-IyaMxM1cmUu64h654oAvulm83K5Mu-VQxXJ_0BOds,1506
@@ -44,9 +44,9 @@ clonebox/snapshots/manager.py,sha256=hGzM8V6ZJPXjTqj47c4Kr8idlE-c1Q3gPUvuw1HvS1A
44
44
  clonebox/snapshots/models.py,sha256=sRnn3OZE8JG9FZJlRuA3ihO-JXoPCQ3nD3SQytflAao,6206
45
45
  clonebox/templates/profiles/ml-dev.yaml,sha256=w07MToGh31xtxpjbeXTBk9BkpAN8A3gv8HeA3ESKG9M,461
46
46
  clonebox/templates/profiles/web-stack.yaml,sha256=EBnnGMzML5vAjXmIUbCpbTCwmRaNJiuWd3EcL43DOK8,485
47
- clonebox-1.1.19.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
48
- clonebox-1.1.19.dist-info/METADATA,sha256=mJT8xFHNlOOcqtT7eINj2-QmcIaB4Otz32bUdcATmic,49052
49
- clonebox-1.1.19.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
50
- clonebox-1.1.19.dist-info/entry_points.txt,sha256=FES95Vi3btfViLEEoHdb8nikNxTqzaooi9ehZw9ZfWI,47
51
- clonebox-1.1.19.dist-info/top_level.txt,sha256=LdMo2cvCrEcRGH2M8JgQNVsCoszLV0xug6kx1JnaRjo,9
52
- clonebox-1.1.19.dist-info/RECORD,,
47
+ clonebox-1.1.20.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
48
+ clonebox-1.1.20.dist-info/METADATA,sha256=c2ojciWoFLDyVO20XPZVbUkw0eC1UuGfZDe0d1Wy130,49052
49
+ clonebox-1.1.20.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
50
+ clonebox-1.1.20.dist-info/entry_points.txt,sha256=FES95Vi3btfViLEEoHdb8nikNxTqzaooi9ehZw9ZfWI,47
51
+ clonebox-1.1.20.dist-info/top_level.txt,sha256=LdMo2cvCrEcRGH2M8JgQNVsCoszLV0xug6kx1JnaRjo,9
52
+ clonebox-1.1.20.dist-info/RECORD,,