on main help sign in
fix: try to fix provision.sh
commit8669deb07859404772de3a7ccba58527e5737287 authorrobcholz <84130577+robcholz@users.noreply.github.com> dateMon 9 Feb 2026, 02:18 (8 months ago) parent4d15299
2 files changed+61−10
src/provision.sh+2−2 src/vm.rs+59−8
src/provision.sh+2−2
@@ -1,7 +1,7 @@
11#!/bin/bash
22set -eEux
33
4−trap 'rc=$?; echo "[vibebox][error] provisioning failed at: ${BASH_COMMAND} (exit ${rc})"; echo "VIBEBOX_PROVISION_FAILED"; systemctl poweroff || true; exit 1' ERR
4+trap 'rc=$?; echo "[vibebox][error] provisioning failed at: ${BASH_COMMAND} (exit ${rc})"; printf "%s%s\n" VIBEBOX_PROVISION_ FAILED; systemctl poweroff || true; exit 1' ERR
55
66# Wait for network + DNS before apt-get to avoid early boot flakiness.
77wait_for_network() {
@@ -98,5 +98,5 @@ sleep 100 # sleep here so that we don't see the login screen flash up before the
9898EOF
9999
100100# Done provisioning, power off the VM
101−echo "VIBEBOX_PROVISION_OK"
101+printf "%s%s\n" VIBEBOX_PROVISION_ OK
102102systemctl poweroff
src/vm.rs+59−8
@@ -209,8 +209,10 @@ where
209209 let guest_mise_cache = cache_dir.join(".guest-mise-cache");
210210
211211 let instance_dir = project_root.join(INSTANCE_DIR_NAME);
212+ fs::create_dir_all(&instance_dir)?;
212213 let status_file = StatusFile::new(instance_dir.join(STATUS_FILE_NAME));
213214 status_file.update("preparing VM image...");
215+ let provision_log = instance_dir.join("provision.log");
214216
215217 let basename_compressed = DEBIAN_COMPRESSED_DISK_URL.rsplit('/').next().unwrap();
216218 let base_compressed = cache_dir.join(basename_compressed);
@@ -235,6 +237,7 @@ where
235237 &default_raw,
236238 std::slice::from_ref(&mise_directory_share),
237239 Some(&status_file),
240+ Some(&provision_log),
238241 )?;
239242 let _ = ensure_instance_disk(
240243 &instance_raw,
@@ -583,6 +586,7 @@ fn ensure_default_image(
583586 default_raw: &Path,
584587 directory_shares: &[DirectoryShare],
585588 status: Option<&StatusFile>,
589+ provision_log: Option<&Path>,
586590) -> Result<(), Box<dyn std::error::Error>> {
587591 if default_raw.exists() {
588592 return Ok(());
@@ -605,14 +609,31 @@ fn ensure_default_image(
605609 timeout: PROVISION_EXPECT_TIMEOUT,
606610 },
607611 ];
608− if let Err(err) = run_vm(
609− default_raw,
610− &provision_actions,
611− directory_shares,
612− DEFAULT_CPU_COUNT,
613− DEFAULT_RAM_BYTES,
614− None,
615− ) {
612+ let provision_result = if let Some(log_path) = provision_log {
613+ let log_path = log_path.to_path_buf();
614+ run_vm_with_io(
615+ default_raw,
616+ &provision_actions,
617+ directory_shares,
618+ DEFAULT_CPU_COUNT,
619+ DEFAULT_RAM_BYTES,
620+ None,
621+ move |output_monitor, vm_output_fd, vm_input_fd| {
622+ spawn_vm_io_with_log(output_monitor, vm_output_fd, vm_input_fd, log_path)
623+ },
624+ )
625+ } else {
626+ run_vm(
627+ default_raw,
628+ &provision_actions,
629+ directory_shares,
630+ DEFAULT_CPU_COUNT,
631+ DEFAULT_RAM_BYTES,
632+ None,
633+ )
634+ };
635+
636+ if let Err(err) = provision_result {
616637 let _ = fs::remove_file(default_raw);
617638 return Err(err);
618639 }
@@ -915,6 +936,36 @@ pub fn spawn_vm_io(
915936 spawn_vm_io_with_line_handler(output_monitor, vm_output_fd, vm_input_fd, |_| false)
916937}
917938
939+fn spawn_vm_io_with_log(
940+ output_monitor: Arc<OutputMonitor>,
941+ vm_output_fd: OwnedFd,
942+ vm_input_fd: OwnedFd,
943+ log_path: PathBuf,
944+) -> IoContext {
945+ let log_file = fs::OpenOptions::new()
946+ .create(true)
947+ .write(true)
948+ .truncate(true)
949+ .open(&log_path)
950+ .ok()
951+ .map(|file| Arc::new(Mutex::new(file)));
952+
953+ spawn_vm_io_with_hooks(
954+ output_monitor,
955+ vm_output_fd,
956+ vm_input_fd,
957+ IoControl::new(),
958+ |_| false,
959+ move |bytes| {
960+ if let Some(log) = &log_file
961+ && let Ok(mut file) = log.lock()
962+ {
963+ let _ = file.write_all(bytes);
964+ }
965+ },
966+ )
967+}
968+
918969impl IoContext {
919970 pub fn shutdown(self) {
920971 let _ = self.input_tx.send(VmInput::Shutdown);