@@ -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+
97110fn 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