Skip to content
This repository was archived by the owner on Jun 3, 2026. It is now read-only.

refactor: phase 1 - #30

Open
zeishr wants to merge 15 commits into
devfrom
refactor/phase-1
Open

zeishr wants to merge 15 commits into
devfrom
refactor/phase-1

Conversation

@zeishr

@zeishr zeishr commented Apr 8, 2026

Copy link
Copy Markdown
Owner

This pull request removes several components and dependencies from the workspace, primarily cleaning up the codebase by deleting the xenith-cli, xenith-domain-management, and xenith-debugger crates and their source files. It also updates the workspace membership and shared dependencies in the root Cargo.toml. The main focus is on streamlining the project by eliminating unused or deprecated modules and their associated files.

Workspace and Dependency Cleanup:

  • Removed the xenith-cli, xenith-domain-management, and xenith-debugger crates from the workspace and deleted their Cargo.toml and all Rust source files, including command handlers and configuration modules. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]

Dependency updates:

  • Updated shared workspace dependencies in Cargo.toml by adding several new libraries such as mac-addr, tracing, serde, serde_json, serde_yml, tokio, memflow, memflow-qemu, gdbstub, gdbstub_arch, and pyo3.

These changes help simplify the project structure and prepare the workspace for future development by focusing only on the currently relevant components.

zeishr added 15 commits April 7, 2026 19:39
This commit deletes the entire source code and configuration for:
- xenith-cli
- xenith-debugger
- xenith-domain-management
- xenith-gui
- xenith-scripting
- xenith-vmi
Introduce a new crate to generate randomized hardware identities and
corresponding QEMU arguments. This masks hypervisor presence by
spoofing CPUID, SMBIOS, ACPI tables, and device IDs to match
plausible real-world hardware profiles.
Switch from OsString to String for QEMU argument generation across
multiple modules (acpi, cpuid, devices, smbios, timing). This simplifies
the API and removes unnecessary imports, as these arguments do not
require OS-specific byte representations for current use cases.
Initial implementation of the VM management logic, including:
- A generic `VmBackend` trait for hypervisor abstractions.
- A QEMU backend with QMP integration for process control.
- Configuration management for CPU, memory, disks, and networking.
- Support for snapshots, pausing, and graceful power-down.
Replace the string representation of MAC addresses with the structured
MacAddr type from the mac-addr crate. This improves type safety and
standardizes the handling of hardware identifiers.
Removed several xenith-* members and added xenith-vm and xenith-stealth.
Updated the shared workspace dependencies to include tracing, serde,
tokio, memflow, gdbstub, and pyo3.

The Cargo.lock changes reflect these dependency updates and the
underlying crate graph shifts.
Implement a template-driven system for generating coherent hardware
profiles using a new `templates.yaml` file. This replaces hardcoded
values with a pool of real-world CPU, board, and NIC OUI data.

- Add `serde_yml` dependency for template parsing
- Implement `PlatformTemplate`, `CpuTemplate`, and `BoardTemplate`
- Update `StealthConfig` and `HardwareProfile` to use templates
- Refactor error handling and module exports
- Temporary disable ACPI OEM overrides pending binary blob support
Include serde_yml v0.0.12 and its required sub-dependencies to the
project configuration and lockfile.
- Make struct fields private across `VmConfig`, `DiskImage`, and
  `Snapshot`.
- Add accessor methods and builders for configuration and state.
- Transition `VmConfig` and `DiskImage` operations to use `tokio` for
  async I/O.
- Rename `VmError` to `Error` and update variants to use named fields.
- Add a `prelude` module and expand public exports in `lib.rs`.
- Introduce unit tests for configuration and disk helpers.
Add multiple Intel Corporate OUIs and update vendor names for Realtek
and Micro-Star to improve template authenticity.
The commit adds extensive test coverage across the `xenith-stealth` and
`xenith-vm` crates. This includes unit tests for ACPI, CPUID, SMBIOS,
and device configuration logic, as well as integration tests for VM
lifecycle management, configuration serialization, and QEMU argument
generation.
Apply consistent code formatting across multiple files, reorder imports
for better organization, and relocate helper functions in qemu.rs to
improve readability.
- Move `-no-kvmclock` from a top-level argument to a `-cpu` feature
  flag.
- Add `smbios_safe` helper to strip commas from SMBIOS values,
  preventing QEMU parsing errors.
- Update tests and integration logic to reflect new argument ordering
  and counts.
- Add a new `boot` example to `xenith-vm` for launching VMs with stealth
  profiles.
- Improve QEMU error reporting by capturing stderr on failure.
@zeishr zeishr self-assigned this Apr 8, 2026
@zeishr zeishr added the enhancement New feature or request label Apr 8, 2026
Copilot AI review requested due to automatic review settings April 8, 2026 13:59
let known: Vec<[u8; 3]> = ouis().iter().map(|o| o.bytes()).collect();
let p = HardwareProfile::generate();
let oui = p.mac_address().oui();
assert!(

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR restructures the Rust workspace by removing several legacy crates (CLI / GUI / libvirt-based domain management / VMI stub / scripting / debugger) and introducing a new QEMU-centric VM lifecycle crate plus a new stealth-configuration crate.

Changes:

  • Removed xenith-cli, xenith-domain-management, xenith-debugger, xenith-scripting, xenith-gui, and xenith-vmi from the workspace and deleted their sources.
  • Added xenith-vm (VM config + QEMU backend + QMP control + snapshot operations) with examples and tests.
  • Added xenith-stealth (hardware profile generation + CPUID/SMBIOS/device argument builders) with templates and tests, and updated root workspace deps / Cargo.lock.

Reviewed changes

Copilot reviewed 61 out of 62 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
Cargo.toml Updates workspace members and expands shared workspace dependencies.
Cargo.lock Lockfile update reflecting removed crates and new dependencies (tokio/tracing/qapi/rand/etc.).
xenith-vmi/Cargo.toml Removes the xenith-vmi crate manifest from the repo/workspace.
xenith-vmi/src/lib.rs Removes the xenith-vmi stub library code.
xenith-vm/Cargo.toml Adds the new xenith-vm crate manifest and dependencies (tokio/qapi/etc.).
xenith-vm/src/lib.rs Introduces the xenith-vm public module structure and re-exports.
xenith-vm/src/backend.rs Defines the VmBackend trait abstraction for VM backends.
xenith-vm/src/backend/qemu.rs Implements a QEMU backend: arg building, QMP control, snapshot job polling, pidfile handling.
xenith-vm/src/config.rs Adds VmConfig and NetworkInterface plus TOML load/save and path helpers.
xenith-vm/src/disk.rs Adds DiskImage/DiskFormat and qemu-img create/resize/delete helpers.
xenith-vm/src/display.rs Adds DisplayMode with serde support for config serialization.
xenith-vm/src/error.rs Defines xenith-vm error types and messages.
xenith-vm/src/snapshot.rs Adds the Snapshot value type.
xenith-vm/src/vm.rs Adds the high-level Vm manager wrapper around a backend + config + pid state.
xenith-vm/tests/integration.rs Adds integration tests for config/disk/network/display/snapshot types and TOML round-trips.
xenith-vm/examples/boot.rs Adds an example that launches QEMU using xenith-vm plus xenith-stealth extra args.
xenith-stealth/Cargo.toml Adds the new xenith-stealth crate manifest and dependencies (rand/serde_yml/mac-addr).
xenith-stealth/src/lib.rs Introduces the xenith-stealth module structure and re-exports.
xenith-stealth/src/builder.rs Implements StealthConfig to build a composed QEMU arg list.
xenith-stealth/src/profile.rs Implements random coherent hardware profile generation from YAML templates.
xenith-stealth/src/cpuid.rs Builds -cpu arg with feature flags to hide hypervisor signals.
xenith-stealth/src/smbios.rs Builds -smbios args and sanitizes comma-containing values.
xenith-stealth/src/devices.rs Adds additional QEMU -device args (USB controller/tablet) to reduce detectability.
xenith-stealth/src/acpi.rs Placeholder for future ACPI spoofing args (currently empty).
xenith-stealth/src/timing.rs Placeholder for future timing args (currently empty).
xenith-stealth/src/error.rs Adds stealth-layer error types.
xenith-stealth/templates.yaml Adds the hardware identity template data (OUIs + platforms/boards/CPUs).
xenith-stealth/tests/integration.rs Adds integration tests validating stealth arg properties and coherence.
xenith-scripting/Cargo.toml Removes the xenith-scripting crate manifest.
xenith-scripting/src/lib.rs Removes the xenith-scripting crate source.
xenith-debugger/Cargo.toml Removes the xenith-debugger crate manifest.
xenith-debugger/src/lib.rs Removes the xenith-debugger crate source.
xenith-cli/Cargo.toml Removes the xenith-cli crate manifest.
xenith-cli/src/main.rs Removes the old CLI entrypoint.
xenith-cli/src/commands.rs Removes old CLI command routing.
xenith-cli/src/commands/vm.rs Removes old VM subcommand handling.
xenith-gui/Cargo.toml Removes the xenith-gui crate manifest.
xenith-gui/src/main.rs Removes the xenith-gui binary stub.
xenith-domain-management/Cargo.toml Removes the libvirt/Xen domain management crate manifest.
xenith-domain-management/build.rs Removes the libvirt link directive build script.
xenith-domain-management/src/main.rs Removes the libvirt exploration binary.
xenith-domain-management/src/lib.rs Removes the old domain management library entrypoint.
xenith-domain-management/src/templating.rs Removes the Tera-based XML domain templating implementation.
xenith-domain-management/src/error.rs Removes old driver/config error definitions.
xenith-domain-management/src/driver.rs Removes libvirt driver implementation.
xenith-domain-management/src/driver/identifier.rs Removes domain identifier types.
xenith-domain-management/src/driver/status.rs Removes domain status mapping.
xenith-domain-management/src/domain.rs Removes domain model module.
xenith-domain-management/src/domain/devices.rs Removes domain device modeling.
xenith-domain-management/src/domain/events.rs Removes domain event/action modeling.
xenith-domain-management/src/domain/network.rs Removes domain network modeling.
xenith-domain-management/src/domain/processor.rs Removes SMBIOS/processor modeling.
xenith-domain-management/src/domain/time.rs Removes TSC/time modeling.
xenith-domain-management/src/configuration.rs Removes domain configuration filesystem model.
xenith-domain-management/src/configuration/domain.rs Removes domain config parsing.
xenith-domain-management/src/configuration/disk.rs Removes disk config parsing/model.
xenith-domain-management/src/configuration/image.rs Removes image config model.
xenith-domain-management/src/configuration/template.rs Removes packer template model.
xenith-domain-management/templates/default.xml Removes the default XML template.
xenith-domain-management/tests/fixtures/default.xml Removes XML fixture.
xenith-domain-management/tests/fixtures/default-config.cfg Removes legacy cfg fixture.
xenith-redpill/xenith-redpill-macros/src/technique.rs Minor formatting fix in macro error-return block.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +391 to +399
#[test]
fn display_sdl_adds_display_sdl() {
// VmConfig has no `with_display`, so inject via TOML round-trip.
let toml = format!(
"name = \"argtest\"\nvcpus = 4\nmemory_bytes = {}\ndisks = []\nnetworks = []\ndisplay = \"sdl\"\n",
VmConfig::gib_to_bytes(8)
);
let cfg: VmConfig = toml::from_str(&toml).expect("parse");
let args = args_str(&cfg);

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment claims VmConfig has no with_display, but VmConfig::with_display exists now (xenith-vm/src/config.rs). This is misleading and should be updated; the test can construct the config via with_display(DisplayMode::Sdl) instead of relying on a TOML round-trip.

Copilot uses AI. Check for mistakes.
Comment on lines +124 to +133
#[test]
fn vm_config_runtime_paths_are_nested_under_base_dir() {
// SAFETY: single-threaded test process; no other thread reads XENITH_VM_DIR.
unsafe { std::env::set_var("XENITH_VM_DIR", "/tmp/xenith-test") };
let cfg = make_config("path-test");
assert!(cfg.runtime_dir().starts_with("/tmp/xenith-test"));
assert!(cfg.qmp_socket().starts_with("/tmp/xenith-test"));
assert!(cfg.config_file().starts_with("/tmp/xenith-test"));
unsafe { std::env::remove_var("XENITH_VM_DIR") };
}

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test mutates the process-wide XENITH_VM_DIR environment variable. Rust tests run in parallel by default, so this can race with other tests and become flaky; the safety comment about being single-threaded is not guaranteed. Consider guarding env var mutation with a global mutex / serializing the test, and restore any previous value on exit (even on panic).

Copilot uses AI. Check for mistakes.
Comment thread xenith-vm/src/vm.rs
Comment on lines +64 to +69
pub async fn stop(&mut self) -> Result<(), VmError> {
self.ensure_running()?;
self.backend.stop(&self.config).await?;
self.pid = None;
info!("VM stopped");
Ok(())

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vm::stop clears self.pid and logs "VM stopped" immediately after calling backend.stop, but QemuBackend::stop only issues an ACPI powerdown over QMP and does not wait for the VM to actually exit. This can leave Vm thinking it is stopped while the process (and QMP socket/pidfile) is still alive, enabling inconsistent follow-up calls (including a new start). Consider either waiting for shutdown/exit before clearing pid, or renaming/adjusting the API so it reflects "powerdown requested" semantics.

Copilot uses AI. Check for mistakes.
Comment on lines +104 to +112
async fn save_snapshot(&self, config: &VmConfig, tag: &str) -> Result<(), VmError> {
let qmp = qmp_connect(config).await?;
let job_id = format!("snap-save-{tag}");
qmp.execute(qapi::qmp::snapshot_save {
job_id: job_id.clone(),
tag: tag.to_owned(),
vmstate: String::from("drive0"),
devices: config.drive_ids(),
})

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Snapshot operations hard-code vmstate = "drive0" but pass devices = config.drive_ids(). If no disks are configured, drive_ids() is empty and drive0 won't exist, causing a QMP error at runtime. Consider validating that at least one disk is attached (or making vmstate/devices derive from the actual configured drives) and returning a clear VmError::Config/VmError::Disk early.

Copilot uses AI. Check for mistakes.
Comment on lines +303 to +313
async fn read_pid_file(path: &Path) -> Result<u32, VmError> {
let mut attempts = 0u8;
let pid_str = loop {
match fs::read_to_string(path) {
Ok(s) => break s,
Err(_) if attempts < 5 => {
attempts += 1;
tokio::time::sleep(Duration::from_millis(50)).await;
}
Err(e) => return Err(VmError::Backend(format!("could not read pidfile: {e}"))),
}

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read_pid_file is async but uses blocking std::fs::read_to_string inside a retry loop. On a Tokio runtime this can block the executor thread and impact unrelated async tasks. Prefer tokio::fs::read_to_string (or spawn_blocking) for the pidfile read, keeping the retry/sleep logic the same.

Copilot uses AI. Check for mistakes.
Comment thread xenith-vm/src/disk.rs
Comment on lines +26 to +33
/// A disk image on the host that will be attached to a VM.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiskImage {
path: PathBuf,
format: DiskFormat,
/// Capacity in bytes.
size_bytes: u64,
}

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DiskImage has private fields and no public constructor for representing an existing disk, which forces tests/examples in this PR to construct instances via a TOML/serde round-trip. Consider adding a simple DiskImage::new(...) / DiskImage::from_existing(...) constructor to make the API ergonomic and avoid serialization hacks.

Copilot uses AI. Check for mistakes.
Comment on lines +208 to +212
let pid = vm.pid().expect("PID set after start");
println!("VM started (PID {pid})");
println!("QMP socket: {}", vm.config().qmp_socket().display());
println!("Stop with: xenith-vm stop {}", vm.config().name());
}

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example prints Stop with: xenith-vm stop ..., but this workspace no longer includes a xenith-vm CLI/binary (the crate is a library with examples). This message will confuse users running the example; consider changing it to describe the actual stop mechanism (e.g., call vm.stop() from code, or document the intended future CLI if that's planned).

Copilot uses AI. Check for mistakes.
Comment thread Cargo.toml
Comment on lines 7 to 11
members = [
"xenith-domain-management",
"xenith-vmi",
"xenith-cli",
"xenith-debugger",
"xenith-scripting",
"xenith-vm",
"xenith-stealth",
"xenith-redpill",
"xenith-gui",
]

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description emphasizes removing crates/dependencies, but this change also adds new workspace members (xenith-vm, xenith-stealth) and introduces a large set of new shared dependencies. Consider updating the PR description to reflect the scope (cleanup + new VM/stealth crates) so reviewers understand the intent.

Copilot uses AI. Check for mistakes.
Comment on lines +8 to +12
vec![
// USB controller: Intel Panther Point xHCI (very common on 3rd-gen Intel boards)
String::from("-device"),
String::from("qemu-xhci,id=usb,p2=15,p3=15"),
// USB HID tablet (prevents relative-mouse issues; looks like a real USB device)

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment claims the qemu-xhci device corresponds to an "Intel Panther Point xHCI" controller, but the argument being added is qemu-xhci (QEMU's generic xHCI controller). This is misleading documentation; either adjust the device/model to match the stated hardware, or update the comment to describe what is actually being emulated.

Copilot uses AI. Check for mistakes.
Comment on lines +46 to +53
# took from https://udger.com/resources/mac-address-vendor-detail?name=intel_corporation
- vendor: Intel Corporate
oui: "00:02:B3"
- vendor: Intel Corporate
oui: "00:03:47"
- vendor: Intel Corporate
oui: "00:04:23"
- vendor: Intel Corporate

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: # took from ... should be # taken from ..., and there is trailing whitespace after the 00:04:23 OUI entry. Cleaning this up avoids small documentation/style issues in the templates file.

Copilot uses AI. Check for mistakes.

This branch has not been deployed

No deployments
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants