Skip to content

Commit d4963cd

Browse files
committed
wip
Signed-off-by: Colin Walters <[email protected]>
1 parent d596a32 commit d4963cd

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

Justfile

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,23 @@ mdbook-serve: build-mdbook
112112
#
113113
# This is the unified command that:
114114
# - Auto-discovers new CLI commands and creates man page templates
115-
# - Syncs CLI options from Rust code to existing man page templates
115+
# - Syncs CLI options from Rust code to existing man page templates
116116
# - Updates JSON schema files
117117
#
118118
# Use this after adding, removing, or modifying CLI options or schemas.
119119
update-generated:
120120
cargo run -p xtask update-generated
121+
122+
# Fast development loop: Build and deploy to a persistent bcvk VM
123+
#
124+
# On first run: Creates a VM named "bootc-dev" from the built image
125+
# On subsequent runs: Upgrades the VM to the newly built image and reboots
126+
#
127+
# This enables a fast edit-compile-debug cycle:
128+
# just build bcvk-up -> edit code -> just build bcvk-up -> just bcvk-ssh
129+
bcvk-up: build
130+
cargo xtask bcvk-up localhost/bootc
131+
132+
# SSH into the bootc-dev VM
133+
bcvk-ssh:
134+
bcvk libvirt ssh bootc-dev

crates/xtask/src/xtask.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ enum Commands {
5858
RunTmt(RunTmtArgs),
5959
/// Provision a VM for manual TMT testing
6060
TmtProvision(TmtProvisionArgs),
61+
/// Create or upgrade a persistent development VM
62+
BcvkUp(BcvkUpArgs),
6163
}
6264

6365
/// Arguments for run-tmt command
@@ -94,6 +96,17 @@ struct TmtProvisionArgs {
9496
vm_name: Option<String>,
9597
}
9698

99+
/// Arguments for bcvk-up command
100+
#[derive(Debug, Args)]
101+
struct BcvkUpArgs {
102+
/// Image name (e.g., "localhost/bootc")
103+
image: String,
104+
105+
/// VM name (defaults to "bootc-dev")
106+
#[arg(long, default_value = "bootc-dev")]
107+
vm_name: String,
108+
}
109+
97110
fn main() {
98111
use std::io::Write as _;
99112

@@ -138,6 +151,7 @@ fn try_main() -> Result<()> {
138151
Commands::Spec => spec(&sh),
139152
Commands::RunTmt(args) => run_tmt(&sh, &args),
140153
Commands::TmtProvision(args) => tmt_provision(&sh, &args),
154+
Commands::BcvkUp(args) => bcvk_up(&sh, &args),
141155
}
142156
}
143157

@@ -876,3 +890,43 @@ fn tmt_provision(sh: &Shell, args: &TmtProvisionArgs) -> Result<()> {
876890

877891
Ok(())
878892
}
893+
894+
/// Create or upgrade a persistent development VM
895+
/// On first run, creates a new VM. On subsequent runs, upgrades and reboots.
896+
#[context("Managing development VM")]
897+
fn bcvk_up(sh: &Shell, args: &BcvkUpArgs) -> Result<()> {
898+
let vm_name = &args.vm_name;
899+
let image = &args.image;
900+
901+
// Check if VM exists by listing all VMs
902+
let list_output = cmd!(sh, "bcvk libvirt list --format=json").read()?;
903+
let vms: Vec<serde_json::Value> =
904+
serde_json::from_str(&list_output).context("Parsing bcvk list output")?;
905+
let vm_exists = vms.iter().any(|vm| {
906+
vm.get("name")
907+
.and_then(|n| n.as_str())
908+
.map(|n| n == vm_name)
909+
.unwrap_or(false)
910+
});
911+
912+
if vm_exists {
913+
println!("VM '{}' exists, upgrading to new image...", vm_name);
914+
915+
// Run bootc upgrade with error checking
916+
println!("Running bootc upgrade...");
917+
cmd!(sh, "bcvk libvirt ssh {vm_name} -- bootc upgrade")
918+
.run()
919+
.context("Failed to upgrade bootc")?;
920+
921+
// Now reboot (this will drop the connection, so ignore the error)
922+
println!("Rebooting VM...");
923+
cmd!(sh, "bcvk libvirt ssh {vm_name} -- systemctl reboot")
924+
.ignore_stderr()
925+
.ignore_status()
926+
.run()?;
927+
} else {
928+
cmd!(sh, "bcvk libvirt run --bind-storage-ro --name {vm_name} {image}").run()?;
929+
println!("Connect with: just bcvk-ssh");
930+
}
931+
Ok(())
932+
}

0 commit comments

Comments
 (0)