vmmaker/classes/qemu.py
Kumi b09bec7a70
feat: start implementing VM editing and configuration
Introduced a new set of Python classes under `classes/` directory,
enabling functionality to edit and configure virtual machines (VMs)
through a text-based user interface (TUI). Key components include
handling for Linux distribution-specific configurations, partition
mounting, and VM disk manipulation using QEMU tools. This structure
allows for scalable VM management tasks such as user modification,
network configuration, hostname setting, and disk conversion from VMDK
to raw image format.

Additionally, basic infrastructure such as `.gitignore`, `README.md`,
and `requirements.txt` setup is included to ensure a clean development
environment and provide necessary instructions and dependencies for
running the script.

The TUI, powered by npyscreen, facilitates user interaction for
configuring newly cloned VMs, focusing on ease of use and automation of
repetitive tasks.

This comprehensive suite marks a pivotal step towards automating VM
management and customization processes, significantly reducing manual
overhead for system administrators and developers dealing with virtual
environments.
2024-03-29 13:54:37 +01:00

91 lines
2.6 KiB
Python

from pathlib import Path
from typing import Tuple
import os
import shutil
import subprocess
import utils.fdisk
from .mount import PartitionMounter
class VMEditor:
def __init__(self, source: os.PathLike, destination: os.PathLike):
self.source_path = Path(source)
self.destination_path = Path(destination)
self.system_partition: Tuple[str, int] = None
self.mount: PartitionMounter = None
def create_copy(self):
shutil.copytree(self.source_path, self.destination_path)
def update_filenames(self):
for file in self.destination_path.iterdir():
if self.source_path.name in file.name:
file.rename(
self.destination_path
/ file.name.replace(
self.source_path.name, self.destination_path.name
)
)
def update_file_contents(self):
vmxpath = self.destination_path / f"{self.destination_path.name}.vmx"
content = ""
with (vmxpath).open("r") as vmx_in:
content = vmx_in.read()
content = content.replace(self.source_path.name, self.destination_path.name)
with vmxpath.open("w") as vmx_out:
vmx_out.write(content)
for vmdk in self.destination_path.glob("*.vmdk"):
if vmdk.stat().st_size < 1e5:
with vmdk.open("r") as vmdk_in:
content = vmdk_in.read()
content = content.replace(
self.source_path.name, self.destination_path.name
)
with vmdk.open("w") as vmdk_out:
content = vmdk_out.write(content)
def vmdk_to_img(self):
for vmdk in self.destination_path.glob("*.vmdk"):
if vmdk.stem.endswith("-flat"):
continue
img = self.destination_path / f"{vmdk.stem}.img"
subprocess.run(
[
"qemu-img",
"convert",
"-O",
"raw",
str(vmdk),
str(img),
],
check=True,
)
vmdk.unlink()
if (flat := self.destination_path / f"{vmdk.stem}-flat.vmdk").exists():
flat.unlink()
def get_partitions(self):
files = []
for img in self.destination_path.glob("*.img"):
files += utils.fdisk.get_partitions(img)
return files
def mount_system_partition(self):
self.mount = PartitionMounter(*self.system_partition)
self.mount.mount_partition()