diff --git a/docs/tasks.md b/docs/tasks.md index 5f84524..19f1257 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -43,7 +43,11 @@ 6. [x] VM should be separated by a per-session VM daemon process (only accepts if to shut down vm and itself). 7. [x] setup vibebox commands 8. [ ] setup cli commands. -9. [ ] fix ui overlap. + 1. [x] Organize all the params. + 2. [ ] Remove old cli. + 3. [ ] add an actual config file. + 4. [ ] set up the cli. +9. [ ] fix ui overlap, and consistency issue. 10. [ ] intensive integration test. ## Publish diff --git a/src/instance.rs b/src/instance.rs index 4773a59..cdc3a4f 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -20,14 +20,14 @@ use uuid::Uuid; use crate::{ commands, - session_manager::{INSTANCE_DIR_NAME, INSTANCE_TOML_FILENAME}, + session_manager::{INSTANCE_DIR_NAME, INSTANCE_FILENAME}, tui::AppState, vm::{self, LoginAction, VmInput}, }; const SSH_KEY_NAME: &str = "ssh_key"; #[allow(dead_code)] -const SERIAL_LOG_NAME: &str = "serial.log"; +pub(crate) const SERIAL_LOG_NAME: &str = "serial.log"; const DEFAULT_SSH_USER: &str = "vibecoder"; const SSH_CONNECT_RETRIES: usize = 30; const SSH_CONNECT_DELAY_MS: u64 = 500; @@ -126,7 +126,7 @@ pub(crate) fn ensure_ssh_keypair( pub(crate) fn load_or_create_instance_config( instance_dir: &Path, ) -> Result> { - let config_path = instance_dir.join(INSTANCE_TOML_FILENAME); + let config_path = instance_dir.join(INSTANCE_FILENAME); let mut config = if config_path.exists() { let raw = fs::read_to_string(&config_path)?; toml::from_str::(&raw)? @@ -167,7 +167,7 @@ pub fn touch_last_active(instance_dir: &Path) -> Result<(), Box>>> = Arc::new(Mutex::new(None)); - let instance_path = instance_dir.join(INSTANCE_TOML_FILENAME); + let instance_path = instance_dir.join(INSTANCE_FILENAME); let config_for_output = config.clone(); let log_for_output = log_file.clone(); let ssh_connected_for_output = ssh_connected.clone(); diff --git a/src/session_manager.rs b/src/session_manager.rs index d840611..1900529 100644 --- a/src/session_manager.rs +++ b/src/session_manager.rs @@ -11,8 +11,7 @@ use crate::config::CONFIG_FILENAME; pub const INSTANCE_DIR_NAME: &str = ".vibebox"; pub const GLOBAL_CACHE_DIR_NAME: &str = "vibebox"; pub const GLOBAL_DIR_NAME: &str = ".vibebox"; -pub const INSTANCE_TOML_FILENAME: &str = "instance.toml"; -pub const SESSION_TEMP_PREFIX: &str = "sessions"; +pub const INSTANCE_FILENAME: &str = "instance.toml"; pub const SESSION_TOML_SUFFIX: &str = ".toml"; const SESSIONS_DIR_NAME: &str = "sessions"; @@ -100,7 +99,8 @@ impl SessionManager { } else { tracing::warn!( directory = %directory.display(), - "missing session id in instance.toml" + file = INSTANCE_FILENAME, + "missing session id in instance file" ); } } @@ -158,7 +158,7 @@ impl SessionManager { } fn session_path_for(&self, id: &str) -> PathBuf { - let filename = format!("{id}.toml"); + let filename = format!("{id}{SESSION_TOML_SUFFIX}"); self.sessions_dir.join(filename) } @@ -225,9 +225,7 @@ fn read_session_file(path: &Path) -> Result { } fn read_instance_metadata(directory: &Path) -> Result { - let instance_path = directory - .join(INSTANCE_DIR_NAME) - .join(INSTANCE_TOML_FILENAME); + let instance_path = directory.join(INSTANCE_DIR_NAME).join(INSTANCE_FILENAME); if !instance_path.exists() { return Ok(InstanceMetadata::default()); } @@ -256,7 +254,7 @@ fn atomic_write(path: &Path, content: &[u8]) -> io::Result<()> { fs::create_dir_all(parent)?; let mut temp = tempfile::Builder::new() - .prefix(SESSION_TEMP_PREFIX) + .prefix(SESSIONS_DIR_NAME) .suffix(SESSION_TOML_SUFFIX) .tempfile_in(parent)?; temp.write_all(content)?; @@ -285,7 +283,7 @@ mod tests { let instance_dir = project_dir.join(INSTANCE_DIR_NAME); fs::create_dir_all(&instance_dir).unwrap(); let content = format!("id = \"{id}\"\nlast_active = \"{last_active}\"\n"); - fs::write(instance_dir.join(INSTANCE_TOML_FILENAME), content).unwrap(); + fs::write(instance_dir.join(INSTANCE_FILENAME), content).unwrap(); } #[test] @@ -306,9 +304,10 @@ mod tests { assert_eq!(dirs[0], project_dir.canonicalize().unwrap()); assert!(mgr.index_path().exists()); - let session_path = mgr - .index_path() - .join("019bf290-cccc-7c23-ba1d-dce7e6d40693.toml"); + let session_path = mgr.index_path().join(format!( + "019bf290-cccc-7c23-ba1d-dce7e6d40693{}", + SESSION_TOML_SUFFIX + )); assert!(session_path.exists()); } @@ -329,9 +328,10 @@ mod tests { let sessions = mgr.list_sessions().unwrap(); assert!(sessions.is_empty()); - let session_path = mgr - .index_path() - .join("019bf290-cccc-7c23-ba1d-dce7e6d40693.toml"); + let session_path = mgr.index_path().join(format!( + "019bf290-cccc-7c23-ba1d-dce7e6d40693{}", + SESSION_TOML_SUFFIX + )); assert!(!session_path.exists()); } @@ -340,7 +340,11 @@ mod tests { let temp = TempDir::new().unwrap(); let mgr = manager(&temp); fs::create_dir_all(mgr.index_path()).unwrap(); - fs::write(mgr.index_path().join("bad.toml"), "not toml").unwrap(); + fs::write( + mgr.index_path().join(format!("bad{SESSION_TOML_SUFFIX}")), + "not toml", + ) + .unwrap(); let err = mgr.list_sessions().unwrap_err(); assert!(matches!(err, SessionError::TomlDe(_))); diff --git a/src/vm.rs b/src/vm.rs index 347d588..67680ac 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -43,6 +43,10 @@ const START_TIMEOUT: Duration = Duration::from_secs(60); const DEFAULT_EXPECT_TIMEOUT: Duration = Duration::from_secs(30); const LOGIN_EXPECT_TIMEOUT: Duration = Duration::from_secs(120); const PROVISION_SCRIPT: &str = include_str!("provision.sh"); +const PROVISION_SCRIPT_NAME: &str = "provision.sh"; +const DEFAULT_RAW_NAME: &str = "default.raw"; +const INSTANCE_RAW_NAME: &str = "instance.raw"; +const BASE_DISK_RAW_NAME: &str = "disk.raw"; #[derive(Clone)] pub(crate) enum LoginAction { @@ -158,8 +162,8 @@ where basename_compressed.trim_end_matches(".tar.xz") )); - let default_raw = cache_dir.join("default.raw"); - let instance_raw = instance_dir.join("instance.raw"); + let default_raw = cache_dir.join(DEFAULT_RAW_NAME); + let instance_raw = instance_dir.join(INSTANCE_RAW_NAME); // Prepare system-wide directories fs::create_dir_all(&cache_dir)?; @@ -212,11 +216,6 @@ where for share in [ DirectoryShare::new(home.join(".codex"), "/usr/local/codex".into(), false), DirectoryShare::new(home.join(".claude"), "/usr/local/claude".into(), false), - DirectoryShare::new( - "/Users/zhangjie/Documents/Code/CompletePrograms/vibebox/.ssh".into(), - "/usr/local/ssh".into(), - true, - ), ] .into_iter() .flatten() @@ -629,7 +628,11 @@ fn ensure_base_image( println!("Decompressing base image..."); let status = Command::new("tar") - .args(["-xOf", &base_compressed.to_string_lossy(), "disk.raw"]) + .args([ + "-xOf", + &base_compressed.to_string_lossy(), + BASE_DISK_RAW_NAME, + ]) .stdout(std::fs::File::create(base_raw)?) .status()?; @@ -655,7 +658,7 @@ fn ensure_default_image( println!("Configuring base image..."); fs::copy(base_raw, default_raw)?; - let provision_command = script_command_from_content("provision.sh", PROVISION_SCRIPT)?; + let provision_command = script_command_from_content(PROVISION_SCRIPT_NAME, PROVISION_SCRIPT)?; run_vm( default_raw, &[Send(provision_command)], diff --git a/src/vm_manager.rs b/src/vm_manager.rs index 809394c..8745679 100644 --- a/src/vm_manager.rs +++ b/src/vm_manager.rs @@ -15,16 +15,18 @@ use std::{ }; use crate::{ + instance::SERIAL_LOG_NAME, instance::{ InstanceConfig, build_ssh_login_actions, ensure_instance_dir, ensure_ssh_keypair, extract_ipv4, load_or_create_instance_config, write_instance_config, }, - session_manager::GLOBAL_DIR_NAME, + session_manager::{GLOBAL_DIR_NAME, INSTANCE_FILENAME}, vm::{self, DirectoryShare, LoginAction, VmInput}, }; const VM_MANAGER_SOCKET_NAME: &str = "vm.sock"; const VM_MANAGER_LOCK_NAME: &str = "vm.lock"; +const VM_MANAGER_LOG_NAME: &str = "vm_manager.log"; pub fn ensure_manager( raw_args: &[std::ffi::OsString], @@ -132,7 +134,7 @@ fn spawn_manager_process( cmd.env("VIBEBOX_LOG_NO_COLOR", "1"); cmd.env("VIBEBOX_AUTO_SHUTDOWN_MS", auto_shutdown_ms.to_string()); tracing::info!(auto_shutdown_ms, "vm manager process spawn requested"); - let log_path = instance_dir.join("vm_manager.log"); + let log_path = instance_dir.join(VM_MANAGER_LOG_NAME); let log_file = fs::OpenOptions::new() .create(true) .write(true) @@ -280,7 +282,7 @@ fn spawn_manager_io( vm_output_fd: std::os::unix::io::OwnedFd, vm_input_fd: std::os::unix::io::OwnedFd, ) -> vm::IoContext { - let log_path = instance_dir.join("serial.log"); + let log_path = instance_dir.join(SERIAL_LOG_NAME); let log_file = fs::OpenOptions::new() .create(true) .write(true) @@ -289,7 +291,7 @@ fn spawn_manager_io( .ok() .map(|file| Arc::new(Mutex::new(file))); - let instance_path = instance_dir.join("instance.toml"); + let instance_path = instance_dir.join(INSTANCE_FILENAME); let config_for_output = config.clone(); let log_for_output = log_file.clone(); let mut line_buf = String::new(); @@ -465,7 +467,7 @@ fn run_manager_with( let mut config = load_or_create_instance_config(&instance_dir)?; if config.vm_ipv4.is_some() { config.vm_ipv4 = None; - write_instance_config(&instance_dir.join("instance.toml"), &config)?; + write_instance_config(&instance_dir.join(INSTANCE_FILENAME), &config)?; } let config = Arc::new(Mutex::new(config));