clonebox 1.1.14__py3-none-any.whl → 1.1.15__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/audit.py +5 -1
- clonebox/cli.py +568 -5
- clonebox/cloner.py +181 -123
- clonebox/plugins/manager.py +85 -0
- clonebox/remote.py +511 -0
- clonebox/secrets.py +9 -6
- clonebox/validator.py +113 -41
- {clonebox-1.1.14.dist-info → clonebox-1.1.15.dist-info}/METADATA +5 -1
- {clonebox-1.1.14.dist-info → clonebox-1.1.15.dist-info}/RECORD +13 -12
- {clonebox-1.1.14.dist-info → clonebox-1.1.15.dist-info}/WHEEL +0 -0
- {clonebox-1.1.14.dist-info → clonebox-1.1.15.dist-info}/entry_points.txt +0 -0
- {clonebox-1.1.14.dist-info → clonebox-1.1.15.dist-info}/licenses/LICENSE +0 -0
- {clonebox-1.1.14.dist-info → clonebox-1.1.15.dist-info}/top_level.txt +0 -0
clonebox/validator.py
CHANGED
|
@@ -34,13 +34,21 @@ class VMValidator:
|
|
|
34
34
|
self.results = {
|
|
35
35
|
"mounts": {"passed": 0, "failed": 0, "total": 0, "details": []},
|
|
36
36
|
"packages": {"passed": 0, "failed": 0, "total": 0, "details": []},
|
|
37
|
-
"snap_packages": {
|
|
37
|
+
"snap_packages": {
|
|
38
|
+
"passed": 0,
|
|
39
|
+
"failed": 0,
|
|
40
|
+
"skipped": 0,
|
|
41
|
+
"total": 0,
|
|
42
|
+
"details": [],
|
|
43
|
+
},
|
|
38
44
|
"services": {"passed": 0, "failed": 0, "total": 0, "details": []},
|
|
39
|
-
"apps": {"passed": 0, "failed": 0, "total": 0, "details": []},
|
|
40
|
-
"smoke": {"passed": 0, "failed": 0, "total": 0, "details": []},
|
|
45
|
+
"apps": {"passed": 0, "failed": 0, "skipped": 0, "total": 0, "details": []},
|
|
46
|
+
"smoke": {"passed": 0, "failed": 0, "skipped": 0, "total": 0, "details": []},
|
|
41
47
|
"overall": "unknown",
|
|
42
48
|
}
|
|
43
49
|
|
|
50
|
+
self._setup_in_progress_cache: Optional[bool] = None
|
|
51
|
+
|
|
44
52
|
def _exec_in_vm(self, command: str, timeout: int = 10) -> Optional[str]:
|
|
45
53
|
"""Execute command in VM using QEMU guest agent."""
|
|
46
54
|
try:
|
|
@@ -105,14 +113,32 @@ class VMValidator:
|
|
|
105
113
|
except Exception:
|
|
106
114
|
return None
|
|
107
115
|
|
|
116
|
+
def _setup_in_progress(self) -> Optional[bool]:
|
|
117
|
+
if self._setup_in_progress_cache is not None:
|
|
118
|
+
return self._setup_in_progress_cache
|
|
119
|
+
|
|
120
|
+
out = self._exec_in_vm(
|
|
121
|
+
"test -f /var/lib/cloud/instance/boot-finished && echo no || echo yes",
|
|
122
|
+
timeout=10,
|
|
123
|
+
)
|
|
124
|
+
if out is None:
|
|
125
|
+
self._setup_in_progress_cache = None
|
|
126
|
+
return None
|
|
127
|
+
|
|
128
|
+
self._setup_in_progress_cache = out.strip() == "yes"
|
|
129
|
+
return self._setup_in_progress_cache
|
|
130
|
+
|
|
108
131
|
def validate_mounts(self) -> Dict:
|
|
109
132
|
"""Validate all mount points and copied data paths."""
|
|
110
133
|
self.console.print("\n[bold]💾 Validating Mounts & Data...[/]")
|
|
111
134
|
|
|
112
135
|
paths = self.config.get("paths", {})
|
|
113
|
-
|
|
136
|
+
# Support both v1 (app_data_paths) and v2 (copy_paths) config formats
|
|
137
|
+
copy_paths = self.config.get("copy_paths", None)
|
|
138
|
+
if not isinstance(copy_paths, dict) or not copy_paths:
|
|
139
|
+
copy_paths = self.config.get("app_data_paths", {})
|
|
114
140
|
|
|
115
|
-
if not paths and not
|
|
141
|
+
if not paths and not copy_paths:
|
|
116
142
|
self.console.print("[dim]No mounts or data paths configured[/]")
|
|
117
143
|
return self.results["mounts"]
|
|
118
144
|
|
|
@@ -171,8 +197,8 @@ class VMValidator:
|
|
|
171
197
|
"status": status
|
|
172
198
|
})
|
|
173
199
|
|
|
174
|
-
# Validate copied paths (app_data_paths)
|
|
175
|
-
for host_path, guest_path in
|
|
200
|
+
# Validate copied paths (copy_paths / app_data_paths)
|
|
201
|
+
for host_path, guest_path in copy_paths.items():
|
|
176
202
|
self.results["mounts"]["total"] += 1
|
|
177
203
|
|
|
178
204
|
# Check if exists and has content
|
|
@@ -270,6 +296,8 @@ class VMValidator:
|
|
|
270
296
|
snap_table.add_column("Status", justify="center")
|
|
271
297
|
snap_table.add_column("Version", style="dim")
|
|
272
298
|
|
|
299
|
+
setup_in_progress = self._setup_in_progress() is True
|
|
300
|
+
|
|
273
301
|
for package in snap_packages:
|
|
274
302
|
self.results["snap_packages"]["total"] += 1
|
|
275
303
|
|
|
@@ -284,16 +312,29 @@ class VMValidator:
|
|
|
284
312
|
{"package": package, "installed": True, "version": version}
|
|
285
313
|
)
|
|
286
314
|
else:
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
315
|
+
if setup_in_progress:
|
|
316
|
+
snap_table.add_row(package, "[yellow]⏳ Pending[/]", "")
|
|
317
|
+
self.results["snap_packages"]["skipped"] += 1
|
|
318
|
+
self.results["snap_packages"]["details"].append(
|
|
319
|
+
{
|
|
320
|
+
"package": package,
|
|
321
|
+
"installed": False,
|
|
322
|
+
"version": None,
|
|
323
|
+
"pending": True,
|
|
324
|
+
}
|
|
325
|
+
)
|
|
326
|
+
else:
|
|
327
|
+
snap_table.add_row(package, "[red]❌ Missing[/]", "")
|
|
328
|
+
self.results["snap_packages"]["failed"] += 1
|
|
329
|
+
self.results["snap_packages"]["details"].append(
|
|
330
|
+
{"package": package, "installed": False, "version": None}
|
|
331
|
+
)
|
|
292
332
|
|
|
293
333
|
self.console.print(snap_table)
|
|
294
|
-
self.
|
|
295
|
-
|
|
296
|
-
|
|
334
|
+
msg = f"{self.results['snap_packages']['passed']}/{self.results['snap_packages']['total']} snap packages installed"
|
|
335
|
+
if self.results["snap_packages"].get("skipped", 0) > 0:
|
|
336
|
+
msg += f" ({self.results['snap_packages']['skipped']} pending)"
|
|
337
|
+
self.console.print(f"[dim]{msg}[/]")
|
|
297
338
|
|
|
298
339
|
return self.results["snap_packages"]
|
|
299
340
|
|
|
@@ -410,7 +451,10 @@ class VMValidator:
|
|
|
410
451
|
def validate_apps(self) -> Dict:
|
|
411
452
|
packages = self.config.get("packages", [])
|
|
412
453
|
snap_packages = self.config.get("snap_packages", [])
|
|
413
|
-
|
|
454
|
+
# Support both v1 (app_data_paths) and v2 (copy_paths) config formats
|
|
455
|
+
copy_paths = self.config.get("copy_paths", None)
|
|
456
|
+
if not isinstance(copy_paths, dict) or not copy_paths:
|
|
457
|
+
copy_paths = self.config.get("app_data_paths", {})
|
|
414
458
|
vm_user = self.config.get("vm", {}).get("username", "ubuntu")
|
|
415
459
|
|
|
416
460
|
snap_app_specs = {
|
|
@@ -469,7 +513,7 @@ class VMValidator:
|
|
|
469
513
|
if snap_pkg in snap_app_specs:
|
|
470
514
|
expected.append(snap_pkg)
|
|
471
515
|
|
|
472
|
-
for _, guest_path in
|
|
516
|
+
for _, guest_path in copy_paths.items():
|
|
473
517
|
if guest_path == "/home/ubuntu/.config/google-chrome":
|
|
474
518
|
expected.append("google-chrome")
|
|
475
519
|
break
|
|
@@ -588,6 +632,9 @@ class VMValidator:
|
|
|
588
632
|
running: Optional[bool] = None
|
|
589
633
|
pid: Optional[str] = None
|
|
590
634
|
note = ""
|
|
635
|
+
pending = False
|
|
636
|
+
|
|
637
|
+
setup_in_progress = self._setup_in_progress() is True
|
|
591
638
|
|
|
592
639
|
if app == "firefox":
|
|
593
640
|
installed = (
|
|
@@ -651,6 +698,10 @@ class VMValidator:
|
|
|
651
698
|
if self.require_running_apps and installed and profile_ok and running is None:
|
|
652
699
|
note = note or "running unknown"
|
|
653
700
|
|
|
701
|
+
if setup_in_progress and not installed:
|
|
702
|
+
pending = True
|
|
703
|
+
note = note or "setup in progress"
|
|
704
|
+
|
|
654
705
|
running_icon = (
|
|
655
706
|
"[dim]—[/]"
|
|
656
707
|
if not installed
|
|
@@ -663,20 +714,18 @@ class VMValidator:
|
|
|
663
714
|
|
|
664
715
|
pid_value = "—" if not installed else ("?" if pid is None else (pid or "—"))
|
|
665
716
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
running_icon,
|
|
671
|
-
pid_value,
|
|
672
|
-
note,
|
|
673
|
-
)
|
|
717
|
+
installed_icon = "[green]✅[/]" if installed else ("[yellow]⏳[/]" if pending else "[red]❌[/]")
|
|
718
|
+
profile_icon = "[green]✅[/]" if profile_ok else ("[yellow]⏳[/]" if pending else "[red]❌[/]")
|
|
719
|
+
|
|
720
|
+
table.add_row(app, installed_icon, profile_icon, running_icon, pid_value, note)
|
|
674
721
|
|
|
675
722
|
should_pass = installed and profile_ok
|
|
676
723
|
if self.require_running_apps and installed and profile_ok:
|
|
677
724
|
should_pass = running is True
|
|
678
725
|
|
|
679
|
-
if
|
|
726
|
+
if pending:
|
|
727
|
+
self.results["apps"]["skipped"] += 1
|
|
728
|
+
elif should_pass:
|
|
680
729
|
self.results["apps"]["passed"] += 1
|
|
681
730
|
else:
|
|
682
731
|
self.results["apps"]["failed"] += 1
|
|
@@ -689,6 +738,7 @@ class VMValidator:
|
|
|
689
738
|
"running": running,
|
|
690
739
|
"pid": pid,
|
|
691
740
|
"note": note,
|
|
741
|
+
"pending": pending,
|
|
692
742
|
}
|
|
693
743
|
)
|
|
694
744
|
|
|
@@ -703,7 +753,10 @@ class VMValidator:
|
|
|
703
753
|
def validate_smoke_tests(self) -> Dict:
|
|
704
754
|
packages = self.config.get("packages", [])
|
|
705
755
|
snap_packages = self.config.get("snap_packages", [])
|
|
706
|
-
|
|
756
|
+
# Support both v1 (app_data_paths) and v2 (copy_paths) config formats
|
|
757
|
+
copy_paths = self.config.get("copy_paths", None)
|
|
758
|
+
if not isinstance(copy_paths, dict) or not copy_paths:
|
|
759
|
+
copy_paths = self.config.get("app_data_paths", {})
|
|
707
760
|
vm_user = self.config.get("vm", {}).get("username", "ubuntu")
|
|
708
761
|
|
|
709
762
|
expected = []
|
|
@@ -715,7 +768,7 @@ class VMValidator:
|
|
|
715
768
|
if snap_pkg in {"pycharm-community", "chromium", "firefox", "code"}:
|
|
716
769
|
expected.append(snap_pkg)
|
|
717
770
|
|
|
718
|
-
for _, guest_path in
|
|
771
|
+
for _, guest_path in copy_paths.items():
|
|
719
772
|
if guest_path == "/home/ubuntu/.config/google-chrome":
|
|
720
773
|
expected.append("google-chrome")
|
|
721
774
|
break
|
|
@@ -790,7 +843,7 @@ class VMValidator:
|
|
|
790
843
|
|
|
791
844
|
if app == "firefox":
|
|
792
845
|
out = self._exec_in_vm(
|
|
793
|
-
f"{user_env} timeout 20 firefox --headless --
|
|
846
|
+
f"{user_env} timeout 20 firefox --headless --version >/dev/null 2>&1 && echo yes || echo no",
|
|
794
847
|
timeout=30,
|
|
795
848
|
)
|
|
796
849
|
return None if out is None else out.strip() == "yes"
|
|
@@ -820,40 +873,51 @@ class VMValidator:
|
|
|
820
873
|
table.add_column("Launch", justify="center")
|
|
821
874
|
table.add_column("Note", style="dim")
|
|
822
875
|
|
|
876
|
+
setup_in_progress = self._setup_in_progress() is True
|
|
823
877
|
for app in expected:
|
|
824
878
|
self.results["smoke"]["total"] += 1
|
|
825
879
|
installed = _installed(app)
|
|
826
880
|
launched: Optional[bool] = None
|
|
827
881
|
note = ""
|
|
882
|
+
pending = False
|
|
828
883
|
|
|
829
884
|
if installed is True:
|
|
830
885
|
launched = _run_test(app)
|
|
831
886
|
if launched is None:
|
|
832
887
|
note = "test failed to execute"
|
|
888
|
+
elif launched is False and setup_in_progress:
|
|
889
|
+
pending = True
|
|
890
|
+
note = note or "setup in progress"
|
|
833
891
|
elif installed is False:
|
|
834
|
-
|
|
892
|
+
if setup_in_progress:
|
|
893
|
+
pending = True
|
|
894
|
+
note = "setup in progress"
|
|
895
|
+
else:
|
|
896
|
+
note = "not installed"
|
|
835
897
|
else:
|
|
836
898
|
note = "install status unknown"
|
|
837
899
|
|
|
838
900
|
installed_icon = (
|
|
839
901
|
"[green]✅[/]"
|
|
840
902
|
if installed is True
|
|
841
|
-
else "[
|
|
903
|
+
else ("[yellow]⏳[/]" if pending else "[red]❌[/]")
|
|
904
|
+
if installed is False
|
|
905
|
+
else "[dim]?[/]"
|
|
842
906
|
)
|
|
843
907
|
launch_icon = (
|
|
844
908
|
"[green]✅[/]"
|
|
845
909
|
if launched is True
|
|
846
|
-
else (
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
else ("[dim]—[/]" if installed is not True else "[dim]?[/]")
|
|
850
|
-
)
|
|
910
|
+
else ("[yellow]⏳[/]" if pending else "[red]❌[/]")
|
|
911
|
+
if launched is False
|
|
912
|
+
else ("[dim]—[/]" if installed is not True else "[dim]?[/]")
|
|
851
913
|
)
|
|
852
914
|
|
|
853
915
|
table.add_row(app, installed_icon, launch_icon, note)
|
|
854
916
|
|
|
855
917
|
passed = installed is True and launched is True
|
|
856
|
-
if
|
|
918
|
+
if pending:
|
|
919
|
+
self.results["smoke"]["skipped"] += 1
|
|
920
|
+
elif passed:
|
|
857
921
|
self.results["smoke"]["passed"] += 1
|
|
858
922
|
else:
|
|
859
923
|
self.results["smoke"]["failed"] += 1
|
|
@@ -864,6 +928,7 @@ class VMValidator:
|
|
|
864
928
|
"installed": installed,
|
|
865
929
|
"launched": launched,
|
|
866
930
|
"note": note,
|
|
931
|
+
"pending": pending,
|
|
867
932
|
}
|
|
868
933
|
)
|
|
869
934
|
|
|
@@ -994,6 +1059,10 @@ class VMValidator:
|
|
|
994
1059
|
|
|
995
1060
|
# Get skipped services count
|
|
996
1061
|
skipped_services = self.results["services"].get("skipped", 0)
|
|
1062
|
+
skipped_snaps = self.results["snap_packages"].get("skipped", 0)
|
|
1063
|
+
skipped_apps = self.results["apps"].get("skipped", 0)
|
|
1064
|
+
skipped_smoke = self.results["smoke"].get("skipped", 0) if self.smoke_test else 0
|
|
1065
|
+
total_skipped = skipped_services + skipped_snaps + skipped_apps + skipped_smoke
|
|
997
1066
|
|
|
998
1067
|
# Print summary
|
|
999
1068
|
self.console.print("\n[bold]📊 Validation Summary[/]")
|
|
@@ -1022,7 +1091,7 @@ class VMValidator:
|
|
|
1022
1091
|
"Snap Packages",
|
|
1023
1092
|
str(self.results["snap_packages"]["passed"]),
|
|
1024
1093
|
str(self.results["snap_packages"]["failed"]),
|
|
1025
|
-
"—",
|
|
1094
|
+
str(skipped_snaps) if skipped_snaps else "—",
|
|
1026
1095
|
str(self.results["snap_packages"]["total"]),
|
|
1027
1096
|
)
|
|
1028
1097
|
summary_table.add_row(
|
|
@@ -1036,21 +1105,24 @@ class VMValidator:
|
|
|
1036
1105
|
"Apps",
|
|
1037
1106
|
str(self.results["apps"]["passed"]),
|
|
1038
1107
|
str(self.results["apps"]["failed"]),
|
|
1039
|
-
"—",
|
|
1108
|
+
str(skipped_apps) if skipped_apps else "—",
|
|
1040
1109
|
str(self.results["apps"]["total"]),
|
|
1041
1110
|
)
|
|
1042
1111
|
summary_table.add_row(
|
|
1043
1112
|
"[bold]TOTAL",
|
|
1044
1113
|
f"[bold green]{total_passed}",
|
|
1045
1114
|
f"[bold red]{total_failed}",
|
|
1046
|
-
f"[dim]{
|
|
1115
|
+
f"[dim]{total_skipped}[/]" if total_skipped else "[dim]0[/]",
|
|
1047
1116
|
f"[bold]{total_checks}",
|
|
1048
1117
|
)
|
|
1049
1118
|
|
|
1050
1119
|
self.console.print(summary_table)
|
|
1051
1120
|
|
|
1052
1121
|
# Determine overall status
|
|
1053
|
-
if total_failed == 0 and total_checks > 0:
|
|
1122
|
+
if total_failed == 0 and total_checks > 0 and total_skipped > 0:
|
|
1123
|
+
self.results["overall"] = "pending"
|
|
1124
|
+
self.console.print("\n[bold yellow]⏳ Setup in progress - some checks are pending[/]")
|
|
1125
|
+
elif total_failed == 0 and total_checks > 0:
|
|
1054
1126
|
self.results["overall"] = "pass"
|
|
1055
1127
|
self.console.print("\n[bold green]✅ All validations passed![/]")
|
|
1056
1128
|
elif total_failed > 0:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clonebox
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.15
|
|
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
|
|
@@ -49,6 +49,10 @@ Requires-Dist: fastapi>=0.100.0; extra == "test"
|
|
|
49
49
|
Provides-Extra: dashboard
|
|
50
50
|
Requires-Dist: fastapi>=0.100.0; extra == "dashboard"
|
|
51
51
|
Requires-Dist: uvicorn>=0.22.0; extra == "dashboard"
|
|
52
|
+
Provides-Extra: secrets
|
|
53
|
+
Requires-Dist: hvac>=2.0.0; extra == "secrets"
|
|
54
|
+
Provides-Extra: full
|
|
55
|
+
Requires-Dist: hvac>=2.0.0; extra == "full"
|
|
52
56
|
Dynamic: license-file
|
|
53
57
|
|
|
54
58
|
# CloneBox 📦
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
clonebox/__init__.py,sha256=CyfHVVq6KqBr4CNERBpXk_O6Q5B35q03YpdQbokVvvI,408
|
|
2
2
|
clonebox/__main__.py,sha256=Fcoyzwwyz5-eC_sBlQk5a5RbKx8uodQz5sKJ190U0NU,135
|
|
3
|
-
clonebox/audit.py,sha256=
|
|
4
|
-
clonebox/cli.py,sha256=
|
|
5
|
-
clonebox/cloner.py,sha256=
|
|
3
|
+
clonebox/audit.py,sha256=1W9vaIjB0A--_p7CgE3cIP5RNckJG1RxJrL-tOb-QmU,14298
|
|
4
|
+
clonebox/cli.py,sha256=45-0HJ_T8O5Ggrd42VZTU1LoTOgIidRPqST7jzP23YM,174764
|
|
5
|
+
clonebox/cloner.py,sha256=gQeaY_Cu6cKLKh_L0z8yuhB877WWunyKBy3vOzD-IMI,99640
|
|
6
6
|
clonebox/container.py,sha256=tiYK1ZB-DhdD6A2FuMA0h_sRNkUI7KfYcJ0tFOcdyeM,6105
|
|
7
7
|
clonebox/dashboard.py,sha256=dMY6odvPq3j6FronhRRsX7aY3qdCwznB-aCWKEmHDNw,5768
|
|
8
8
|
clonebox/detector.py,sha256=vS65cvFNPmUBCX1Y_TMTnSRljw6r1Ae9dlVtACs5XFc,23075
|
|
@@ -15,11 +15,12 @@ clonebox/monitor.py,sha256=zlIarNf8w_i34XI8hZGxxrg5PVZK_Yxm6FQnkhLavRI,9181
|
|
|
15
15
|
clonebox/orchestrator.py,sha256=LvoDZIX47g2pdvMYfCW3NJ5sAiRYKKa45KGlujnJZuI,19871
|
|
16
16
|
clonebox/p2p.py,sha256=6o0JnscKqF9-BftQhW5fF1W6YY1wXshY9LEklNcHGJc,5913
|
|
17
17
|
clonebox/profiles.py,sha256=UP37fX_rhrG_O9ehNFJBUcULPmUtN1A8KsJ6cM44oK0,1986
|
|
18
|
+
clonebox/remote.py,sha256=3qd6q3yEDkbO_btOsytkqub2v9lkmsVu_92KcdmHw6U,15336
|
|
18
19
|
clonebox/resource_monitor.py,sha256=lDR9KyPbVtImeeOkOBPPVP-5yCgoL5hsVFPZ_UqsY0w,5286
|
|
19
20
|
clonebox/resources.py,sha256=IkuM4OdSDV4qhyc0eIynwbAHBTv0aVSxxW-gghsnCAs,6815
|
|
20
21
|
clonebox/rollback.py,sha256=hpwO-8Ehe1pW0wHuZvJkC_qxZ6yEo9otCJRhGIUArCo,5711
|
|
21
|
-
clonebox/secrets.py,sha256=
|
|
22
|
-
clonebox/validator.py,sha256=
|
|
22
|
+
clonebox/secrets.py,sha256=l1jwJcEPB1qMoGNLPjyrkKKr1khh9VmftFJI9BWhgK0,10628
|
|
23
|
+
clonebox/validator.py,sha256=_glRPL6VlTCnIpPTtFa8_cVApcl1h0jU_uyHCfKraUM,44501
|
|
23
24
|
clonebox/backends/libvirt_backend.py,sha256=sIHFIvFO1hIOXEFR_foSkOGBgIzaJVQs-njOU8GdafA,7170
|
|
24
25
|
clonebox/backends/qemu_disk.py,sha256=YsGjYX5sbEf35Y4yjTpNkZat73a4RGBxY-KTVzJhqIs,1687
|
|
25
26
|
clonebox/backends/subprocess_runner.py,sha256=c-IyaMxM1cmUu64h654oAvulm83K5Mu-VQxXJ_0BOds,1506
|
|
@@ -33,15 +34,15 @@ clonebox/interfaces/network.py,sha256=YPIquxEB7sZHczbpuopcZpffTjWYI6cKmAu3wAEFll
|
|
|
33
34
|
clonebox/interfaces/process.py,sha256=njvAIZw_TCjw01KpyVQKIDoRvhTwl0FfVGbQ6mxTROk,1024
|
|
34
35
|
clonebox/plugins/__init__.py,sha256=3cxlz159nokZCOL2c017WqTwt5z00yyn-o-SemP1g6c,416
|
|
35
36
|
clonebox/plugins/base.py,sha256=A2H-2vrYUczNZCDioQ8cAtvaSob4YpXutx7FWMjksC4,10133
|
|
36
|
-
clonebox/plugins/manager.py,sha256=
|
|
37
|
+
clonebox/plugins/manager.py,sha256=W2ithedEEOh9iWSq3_M5_g2SQWl85aI5qrvrjOKv02I,16842
|
|
37
38
|
clonebox/snapshots/__init__.py,sha256=ndlrIavPAiA8z4Ep3-D_EPhOcjNKYFnP3rIpEKaGdb8,273
|
|
38
39
|
clonebox/snapshots/manager.py,sha256=hGzM8V6ZJPXjTqj47c4Kr8idlE-c1Q3gPUvuw1HvS1A,11393
|
|
39
40
|
clonebox/snapshots/models.py,sha256=sRnn3OZE8JG9FZJlRuA3ihO-JXoPCQ3nD3SQytflAao,6206
|
|
40
41
|
clonebox/templates/profiles/ml-dev.yaml,sha256=w07MToGh31xtxpjbeXTBk9BkpAN8A3gv8HeA3ESKG9M,461
|
|
41
42
|
clonebox/templates/profiles/web-stack.yaml,sha256=EBnnGMzML5vAjXmIUbCpbTCwmRaNJiuWd3EcL43DOK8,485
|
|
42
|
-
clonebox-1.1.
|
|
43
|
-
clonebox-1.1.
|
|
44
|
-
clonebox-1.1.
|
|
45
|
-
clonebox-1.1.
|
|
46
|
-
clonebox-1.1.
|
|
47
|
-
clonebox-1.1.
|
|
43
|
+
clonebox-1.1.15.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
44
|
+
clonebox-1.1.15.dist-info/METADATA,sha256=4gxhtiBARsY1QcnwjPU705upAAXQPvTXNiXHzkZaGpI,49052
|
|
45
|
+
clonebox-1.1.15.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
46
|
+
clonebox-1.1.15.dist-info/entry_points.txt,sha256=FES95Vi3btfViLEEoHdb8nikNxTqzaooi9ehZw9ZfWI,47
|
|
47
|
+
clonebox-1.1.15.dist-info/top_level.txt,sha256=LdMo2cvCrEcRGH2M8JgQNVsCoszLV0xug6kx1JnaRjo,9
|
|
48
|
+
clonebox-1.1.15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|