clonebox 1.1.12__tar.gz → 1.1.13__tar.gz
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-1.1.12/src/clonebox.egg-info → clonebox-1.1.13}/PKG-INFO +1 -1
- {clonebox-1.1.12 → clonebox-1.1.13}/pyproject.toml +1 -1
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/cloner.py +18 -10
- {clonebox-1.1.12 → clonebox-1.1.13/src/clonebox.egg-info}/PKG-INFO +1 -1
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_cloner.py +2 -1
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_network.py +10 -34
- {clonebox-1.1.12 → clonebox-1.1.13}/LICENSE +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/README.md +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/setup.cfg +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/__init__.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/__main__.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/backends/libvirt_backend.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/backends/qemu_disk.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/backends/subprocess_runner.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/cli.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/container.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/dashboard.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/detector.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/di.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/exporter.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/health/__init__.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/health/manager.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/health/models.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/health/probes.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/importer.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/interfaces/disk.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/interfaces/hypervisor.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/interfaces/network.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/interfaces/process.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/logging.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/models.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/monitor.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/p2p.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/profiles.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/resource_monitor.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/resources.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/rollback.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/secrets.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/snapshots/__init__.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/snapshots/manager.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/snapshots/models.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/templates/profiles/ml-dev.yaml +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/templates/profiles/web-stack.yaml +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox/validator.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox.egg-info/SOURCES.txt +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox.egg-info/dependency_links.txt +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox.egg-info/entry_points.txt +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox.egg-info/requires.txt +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/src/clonebox.egg-info/top_level.txt +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_cli.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_cloner_simple.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_container.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_coverage_additional.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_coverage_boost_final.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_dashboard_coverage.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_detector.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_models.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_profiles.py +0 -0
- {clonebox-1.1.12 → clonebox-1.1.13}/tests/test_validator.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "clonebox"
|
|
7
|
-
version = "1.1.
|
|
7
|
+
version = "1.1.13"
|
|
8
8
|
description = "Clone your workstation environment to an isolated VM with selective apps, paths and services"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "Apache-2.0"}
|
|
@@ -263,13 +263,21 @@ class SelectiveVMCloner:
|
|
|
263
263
|
|
|
264
264
|
return cached_path
|
|
265
265
|
|
|
266
|
-
def
|
|
267
|
-
"""Check if libvirt default network is active."""
|
|
266
|
+
def _default_network_state(self) -> str:
|
|
268
267
|
try:
|
|
269
|
-
|
|
270
|
-
|
|
268
|
+
active = self.conn.listNetworks() or []
|
|
269
|
+
if "default" in active:
|
|
270
|
+
return "active"
|
|
271
|
+
defined = self.conn.listDefinedNetworks() or []
|
|
272
|
+
if "default" in defined:
|
|
273
|
+
return "inactive"
|
|
274
|
+
return "missing"
|
|
271
275
|
except Exception:
|
|
272
|
-
return
|
|
276
|
+
return "unknown"
|
|
277
|
+
|
|
278
|
+
def _default_network_active(self) -> bool:
|
|
279
|
+
"""Check if libvirt default network is active."""
|
|
280
|
+
return self._default_network_state() == "active"
|
|
273
281
|
|
|
274
282
|
def resolve_network_mode(self, config: VMConfig) -> str:
|
|
275
283
|
"""Resolve network mode based on config and session type."""
|
|
@@ -310,10 +318,9 @@ class SelectiveVMCloner:
|
|
|
310
318
|
)
|
|
311
319
|
|
|
312
320
|
# Check default network
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
except libvirt.libvirtError:
|
|
321
|
+
default_net_state = self._default_network_state()
|
|
322
|
+
checks["default_network"] = default_net_state == "active"
|
|
323
|
+
if default_net_state in {"inactive", "missing", "unknown"}:
|
|
317
324
|
checks["network_error"] = (
|
|
318
325
|
"Default network not found or inactive.\n"
|
|
319
326
|
" For user session, CloneBox can use user-mode networking (slirp) automatically.\n"
|
|
@@ -1404,7 +1411,8 @@ fi
|
|
|
1404
1411
|
" - chown -R 1000:1000 /home/ubuntu/.config /home/ubuntu/.cache /home/ubuntu/.local",
|
|
1405
1412
|
" - chmod 700 /home/ubuntu/.config /home/ubuntu/.cache",
|
|
1406
1413
|
" - systemctl set-default graphical.target",
|
|
1407
|
-
" - systemctl enable gdm3 || systemctl enable gdm || true",
|
|
1414
|
+
" - systemctl enable --now gdm3 || systemctl enable --now gdm || true",
|
|
1415
|
+
" - systemctl start display-manager || true",
|
|
1408
1416
|
]
|
|
1409
1417
|
)
|
|
1410
1418
|
|
|
@@ -167,7 +167,8 @@ class TestSelectiveVMClonerMethods:
|
|
|
167
167
|
def test_check_prerequisites_returns_dict(self, mock_libvirt):
|
|
168
168
|
mock_conn = MagicMock()
|
|
169
169
|
mock_conn.isAlive.return_value = True
|
|
170
|
-
mock_conn.
|
|
170
|
+
mock_conn.listNetworks.return_value = ["default"]
|
|
171
|
+
mock_conn.listDefinedNetworks.return_value = []
|
|
171
172
|
mock_libvirt.open.return_value = mock_conn
|
|
172
173
|
mock_libvirt.openAuth.return_value = mock_conn
|
|
173
174
|
|
|
@@ -54,10 +54,8 @@ class TestNetworkMode:
|
|
|
54
54
|
mock_conn = MagicMock()
|
|
55
55
|
mock_libvirt.open.return_value = mock_conn
|
|
56
56
|
mock_libvirt.openAuth.return_value = mock_conn
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
mock_conn.networkLookupByName.return_value = mock_net
|
|
60
|
-
mock_libvirt.open.return_value = mock_conn
|
|
57
|
+
mock_conn.listNetworks.return_value = ["default"]
|
|
58
|
+
mock_conn.listDefinedNetworks.return_value = []
|
|
61
59
|
|
|
62
60
|
cloner = SelectiveVMCloner(user_session=True)
|
|
63
61
|
config = VMConfig(network_mode="auto")
|
|
@@ -68,18 +66,9 @@ class TestNetworkMode:
|
|
|
68
66
|
@patch("clonebox.cloner.libvirt")
|
|
69
67
|
def test_resolve_network_mode_auto_user_no_default(self, mock_libvirt):
|
|
70
68
|
"""Test auto mode with user session and no default network falls back to user."""
|
|
71
|
-
# Handle missing libvirt module in test environment
|
|
72
|
-
try:
|
|
73
|
-
import libvirt as real_libvirt
|
|
74
|
-
|
|
75
|
-
libvirt_error = real_libvirt.libvirtError
|
|
76
|
-
except ImportError:
|
|
77
|
-
|
|
78
|
-
class libvirt_error(Exception):
|
|
79
|
-
pass
|
|
80
|
-
|
|
81
69
|
mock_conn = MagicMock()
|
|
82
|
-
mock_conn.
|
|
70
|
+
mock_conn.listNetworks.return_value = []
|
|
71
|
+
mock_conn.listDefinedNetworks.return_value = []
|
|
83
72
|
mock_libvirt.open.return_value = mock_conn
|
|
84
73
|
mock_libvirt.openAuth.return_value = mock_conn
|
|
85
74
|
|
|
@@ -134,10 +123,8 @@ class TestNetworkMode:
|
|
|
134
123
|
mock_conn = MagicMock()
|
|
135
124
|
mock_libvirt.open.return_value = mock_conn
|
|
136
125
|
mock_libvirt.openAuth.return_value = mock_conn
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
mock_conn.networkLookupByName.return_value = mock_net
|
|
140
|
-
mock_libvirt.open.return_value = mock_conn
|
|
126
|
+
mock_conn.listNetworks.return_value = ["default"]
|
|
127
|
+
mock_conn.listDefinedNetworks.return_value = []
|
|
141
128
|
|
|
142
129
|
cloner = SelectiveVMCloner()
|
|
143
130
|
assert cloner._default_network_active() is True
|
|
@@ -149,10 +136,8 @@ class TestNetworkMode:
|
|
|
149
136
|
mock_conn = MagicMock()
|
|
150
137
|
mock_libvirt.open.return_value = mock_conn
|
|
151
138
|
mock_libvirt.openAuth.return_value = mock_conn
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
mock_conn.networkLookupByName.return_value = mock_net
|
|
155
|
-
mock_libvirt.open.return_value = mock_conn
|
|
139
|
+
mock_conn.listNetworks.return_value = []
|
|
140
|
+
mock_conn.listDefinedNetworks.return_value = ["default"]
|
|
156
141
|
|
|
157
142
|
cloner = SelectiveVMCloner()
|
|
158
143
|
assert cloner._default_network_active() is False
|
|
@@ -160,18 +145,9 @@ class TestNetworkMode:
|
|
|
160
145
|
@patch("clonebox.cloner.libvirt")
|
|
161
146
|
def test_default_network_active_not_found(self, mock_libvirt):
|
|
162
147
|
"""Test _default_network_active returns False when network not found."""
|
|
163
|
-
# Handle missing libvirt module in test environment
|
|
164
|
-
try:
|
|
165
|
-
import libvirt as real_libvirt
|
|
166
|
-
|
|
167
|
-
libvirt_error = real_libvirt.libvirtError
|
|
168
|
-
except ImportError:
|
|
169
|
-
|
|
170
|
-
class libvirt_error(Exception):
|
|
171
|
-
pass
|
|
172
|
-
|
|
173
148
|
mock_conn = MagicMock()
|
|
174
|
-
mock_conn.
|
|
149
|
+
mock_conn.listNetworks.return_value = []
|
|
150
|
+
mock_conn.listDefinedNetworks.return_value = []
|
|
175
151
|
mock_libvirt.open.return_value = mock_conn
|
|
176
152
|
mock_libvirt.openAuth.return_value = mock_conn
|
|
177
153
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|