clonebox 0.1.2__py3-none-any.whl → 0.1.3__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
@@ -492,7 +492,7 @@ def deduplicate_list(items: list, key=None) -> list:
492
492
 
493
493
 
494
494
  def generate_clonebox_yaml(snapshot, detector, deduplicate: bool = True,
495
- target_path: str = None, vm_name: str = None) -> str:
495
+ target_path: str = None, vm_name: str = None, network_mode: str = "auto") -> str:
496
496
  """Generate YAML config from system snapshot."""
497
497
  sys_info = detector.get_system_info()
498
498
 
@@ -559,6 +559,7 @@ def generate_clonebox_yaml(snapshot, detector, deduplicate: bool = True,
559
559
  "vcpus": vcpus,
560
560
  "gui": True,
561
561
  "base_image": None,
562
+ "network_mode": network_mode,
562
563
  },
563
564
  "services": services,
564
565
  "packages": [
@@ -605,6 +606,7 @@ def create_vm_from_config(config: dict, start: bool = False, user_session: bool
605
606
  packages=config.get("packages", []),
606
607
  services=config.get("services", []),
607
608
  user_session=user_session,
609
+ network_mode=config["vm"].get("network_mode", "auto"),
608
610
  )
609
611
 
610
612
  cloner = SelectiveVMCloner(user_session=user_session)
@@ -655,7 +657,8 @@ def cmd_clone(args):
655
657
  snapshot, detector,
656
658
  deduplicate=args.dedupe,
657
659
  target_path=str(target_path),
658
- vm_name=vm_name
660
+ vm_name=vm_name,
661
+ network_mode=args.network
659
662
  )
660
663
 
661
664
  # Save config file
@@ -863,6 +866,8 @@ def main():
863
866
  clone_parser.add_argument("--dedupe", action="store_true", default=True, help="Remove duplicate entries")
864
867
  clone_parser.add_argument("--user", "-u", action="store_true",
865
868
  help="Use user session (qemu:///session) - no root required, stores in ~/.local/share/libvirt/")
869
+ clone_parser.add_argument("--network", choices=["auto", "default", "user"], default="auto",
870
+ help="Network mode: auto (default), default (libvirt network), user (slirp)")
866
871
  clone_parser.set_defaults(func=cmd_clone)
867
872
 
868
873
  args = parser.parse_args()
clonebox/cloner.py CHANGED
@@ -32,6 +32,7 @@ class VMConfig:
32
32
  packages: list = field(default_factory=list)
33
33
  services: list = field(default_factory=list)
34
34
  user_session: bool = False # Use qemu:///session instead of qemu:///system
35
+ network_mode: str = "auto" # auto|default|user
35
36
 
36
37
  def to_dict(self) -> dict:
37
38
  return {
@@ -91,6 +92,25 @@ class SelectiveVMCloner:
91
92
  return self.USER_IMAGES_DIR
92
93
  return self.SYSTEM_IMAGES_DIR
93
94
 
95
+ def _default_network_active(self) -> bool:
96
+ """Check if libvirt default network is active."""
97
+ try:
98
+ net = self.conn.networkLookupByName("default")
99
+ return net.isActive() == 1
100
+ except libvirt.libvirtError:
101
+ return False
102
+
103
+ def resolve_network_mode(self, config: VMConfig) -> str:
104
+ """Resolve network mode based on config and session type."""
105
+ mode = (config.network_mode or "auto").lower()
106
+ if mode == "auto":
107
+ if self.user_session and not self._default_network_active():
108
+ return "user"
109
+ return "default"
110
+ if mode in {"default", "user"}:
111
+ return mode
112
+ return "default"
113
+
94
114
  def check_prerequisites(self) -> dict:
95
115
  """Check system prerequisites for VM creation."""
96
116
  images_dir = self.get_images_dir()
@@ -123,8 +143,11 @@ class SelectiveVMCloner:
123
143
  except libvirt.libvirtError:
124
144
  checks["network_error"] = (
125
145
  "Default network not found or inactive.\n"
126
- " Start it with: sudo virsh net-start default\n"
127
- " Or create it: sudo virsh net-define /usr/share/libvirt/networks/default.xml"
146
+ " For user session, CloneBox can use user-mode networking (slirp) automatically.\n"
147
+ " Or create a user network:\n"
148
+ " virsh --connect qemu:///session net-define /tmp/default-network.xml\n"
149
+ " virsh --connect qemu:///session net-start default\n"
150
+ " Or use system session: clonebox clone . (without --user)\n"
128
151
  )
129
152
 
130
153
  # Check images directory
@@ -215,6 +238,13 @@ class SelectiveVMCloner:
215
238
  cloudinit_iso = self._create_cloudinit_iso(vm_dir, config)
216
239
  log(f"[cyan]☁️ Created cloud-init ISO with {len(config.packages)} packages[/]")
217
240
 
241
+ # Resolve network mode
242
+ network_mode = self.resolve_network_mode(config)
243
+ if network_mode == "user":
244
+ log("[yellow]⚠️ Using user-mode networking (slirp) because default libvirt network is unavailable[/]")
245
+ else:
246
+ log(f"[dim]Network mode: {network_mode}[/]")
247
+
218
248
  # Generate VM XML
219
249
  vm_xml = self._generate_vm_xml(config, root_disk, cloudinit_iso)
220
250
 
@@ -288,9 +318,14 @@ class SelectiveVMCloner:
288
318
  ET.SubElement(fs, "target", dir=tag)
289
319
 
290
320
  # Network interface
291
- iface = ET.SubElement(devices, "interface", type="network")
292
- ET.SubElement(iface, "source", network="default")
293
- ET.SubElement(iface, "model", type="virtio")
321
+ network_mode = self.resolve_network_mode(config)
322
+ if network_mode == "user":
323
+ iface = ET.SubElement(devices, "interface", type="user")
324
+ ET.SubElement(iface, "model", type="virtio")
325
+ else:
326
+ iface = ET.SubElement(devices, "interface", type="network")
327
+ ET.SubElement(iface, "source", network="default")
328
+ ET.SubElement(iface, "model", type="virtio")
294
329
 
295
330
  # Serial console
296
331
  serial = ET.SubElement(devices, "serial", type="pty")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clonebox
3
- Version: 0.1.2
3
+ Version: 0.1.3
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
@@ -65,7 +65,28 @@ CloneBox lets you create isolated virtual machines with only the applications, d
65
65
 
66
66
  ## Installation
67
67
 
68
- ### Prerequisites
68
+ ### Quick Setup (Recommended)
69
+
70
+ Run the setup script to automatically install dependencies and configure the environment:
71
+
72
+ ```bash
73
+ # Clone the repository
74
+ git clone https://github.com/wronai/clonebox.git
75
+ cd clonebox
76
+
77
+ # Run the setup script
78
+ ./setup.sh
79
+ ```
80
+
81
+ The setup script will:
82
+ - Install all required packages (QEMU, libvirt, Python, etc.)
83
+ - Add your user to the necessary groups
84
+ - Configure libvirt networks
85
+ - Install clonebox in development mode
86
+
87
+ ### Manual Installation
88
+
89
+ #### Prerequisites
69
90
 
70
91
  ```bash
71
92
  # Install libvirt and QEMU/KVM
@@ -82,7 +103,7 @@ newgrp libvirt
82
103
  sudo apt install genisoimage
83
104
  ```
84
105
 
85
- ### Install CloneBox
106
+ #### Install CloneBox
86
107
 
87
108
  ```bash
88
109
  # From source
@@ -296,6 +317,63 @@ clonebox detect --yaml --dedupe -o my-config.yaml
296
317
  - Python 3.8+
297
318
  - User in `libvirt` group
298
319
 
320
+ ## Troubleshooting
321
+
322
+ ### Network Issues
323
+
324
+ If you encounter "Network not found" or "network 'default' is not active" errors:
325
+
326
+ ```bash
327
+ # Run the network fix script
328
+ ./fix-network.sh
329
+
330
+ # Or manually fix:
331
+ virsh --connect qemu:///session net-destroy default 2>/dev/null
332
+ virsh --connect qemu:///session net-undefine default 2>/dev/null
333
+ virsh --connect qemu:///session net-define /tmp/default-network.xml
334
+ virsh --connect qemu:///session net-start default
335
+ ```
336
+
337
+ ### Permission Issues
338
+
339
+ If you get permission errors:
340
+
341
+ ```bash
342
+ # Ensure user is in libvirt and kvm groups
343
+ sudo usermod -aG libvirt $USER
344
+ sudo usermod -aG kvm $USER
345
+
346
+ # Log out and log back in for groups to take effect
347
+ ```
348
+
349
+ ### VM Already Exists
350
+
351
+ If you get "domain already exists" error:
352
+
353
+ ```bash
354
+ # List VMs
355
+ clonebox list
356
+
357
+ # Stop and delete the existing VM
358
+ clonebox delete <vm-name>
359
+
360
+ # Or use virsh directly
361
+ virsh --connect qemu:///session destroy <vm-name>
362
+ virsh --connect qemu:///session undefine <vm-name>
363
+ ```
364
+
365
+ ### virt-viewer not found
366
+
367
+ If GUI doesn't open:
368
+
369
+ ```bash
370
+ # Install virt-viewer
371
+ sudo apt install virt-viewer
372
+
373
+ # Then connect manually
374
+ virt-viewer --connect qemu:///session <vm-name>
375
+ ```
376
+
299
377
  ## License
300
378
 
301
379
  MIT License - see [LICENSE](LICENSE) file.
@@ -0,0 +1,10 @@
1
+ clonebox/__init__.py,sha256=IOk7G0DiSQ33EGbFC0xbnnFB9aou_6yuyFxvycQEvA0,407
2
+ clonebox/cli.py,sha256=tg_tinIH3D6Q1xAjhXu7P4msl2XcxLo8XUHMDxkOFis,31996
3
+ clonebox/cloner.py,sha256=bB37BFYY7_xlfOSdk05zrUsrw7ewItRBMb7EJkYFA_0,19671
4
+ clonebox/detector.py,sha256=Umg4CRJU61yV3a1AvR_0tOfjBMCCIbiQdDAAhlrOL5k,11916
5
+ clonebox-0.1.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
6
+ clonebox-0.1.3.dist-info/METADATA,sha256=W6d_Km3nbulNWpl5Z6KctOHciT1o14o4OnAELJMAfbc,11996
7
+ clonebox-0.1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
8
+ clonebox-0.1.3.dist-info/entry_points.txt,sha256=FES95Vi3btfViLEEoHdb8nikNxTqzaooi9ehZw9ZfWI,47
9
+ clonebox-0.1.3.dist-info/top_level.txt,sha256=LdMo2cvCrEcRGH2M8JgQNVsCoszLV0xug6kx1JnaRjo,9
10
+ clonebox-0.1.3.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- clonebox/__init__.py,sha256=IOk7G0DiSQ33EGbFC0xbnnFB9aou_6yuyFxvycQEvA0,407
2
- clonebox/cli.py,sha256=Zk9D99G2Zcaeb0Pw3eNhv0EtLYKPcpE0GyB3QtuhvgQ,31625
3
- clonebox/cloner.py,sha256=qfMpx7tS5Eozvhi2ZzBc5GY6HLYotncuMakeknHnTwo,18099
4
- clonebox/detector.py,sha256=Umg4CRJU61yV3a1AvR_0tOfjBMCCIbiQdDAAhlrOL5k,11916
5
- clonebox-0.1.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
6
- clonebox-0.1.2.dist-info/METADATA,sha256=YtSqXudDO6TrPtAZzbP5fbMvf-PHarUpkY55ZGpHplw,10374
7
- clonebox-0.1.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
8
- clonebox-0.1.2.dist-info/entry_points.txt,sha256=FES95Vi3btfViLEEoHdb8nikNxTqzaooi9ehZw9ZfWI,47
9
- clonebox-0.1.2.dist-info/top_level.txt,sha256=LdMo2cvCrEcRGH2M8JgQNVsCoszLV0xug6kx1JnaRjo,9
10
- clonebox-0.1.2.dist-info/RECORD,,