feat: detect shell for --kernel
- Move detect_shell() to new src/utils.rs for reuse - Use detected shell in QEMU VM mode (bash when available) - Update chroot.rs and qemu_vm.rs to use shared function
This commit is contained in:
+3
-12
@@ -18,22 +18,13 @@ pub fn run_chroot(
|
|||||||
eprintln!("Warning: Failed to set hostname: {}", e);
|
eprintln!("Warning: Failed to set hostname: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect shell before chroot (we're still outside)
|
||||||
|
let shell = crate::utils::detect_shell(rootfs);
|
||||||
|
|
||||||
// Change to root directory in chroot
|
// Change to root directory in chroot
|
||||||
chroot(rootfs).context("Failed to chroot")?;
|
chroot(rootfs).context("Failed to chroot")?;
|
||||||
|
|
||||||
// Now we're inside the chroot - set up environment based on chroot filesystem
|
// Now we're inside the chroot - set up environment based on chroot filesystem
|
||||||
// Determine shell path (check inside chroot, not host)
|
|
||||||
let shell = if Path::new("/bin/bash").exists() {
|
|
||||||
"/bin/bash"
|
|
||||||
} else if Path::new("/bin/sh").exists() {
|
|
||||||
"/bin/sh"
|
|
||||||
} else if Path::new("/usr/bin/bash").exists() {
|
|
||||||
"/usr/bin/bash"
|
|
||||||
} else if Path::new("/usr/bin/sh").exists() {
|
|
||||||
"/usr/bin/sh"
|
|
||||||
} else {
|
|
||||||
"/bin/sh" // Will fail with clear error if not present
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set up environment variables (after chroot, so paths are correct)
|
// Set up environment variables (after chroot, so paths are correct)
|
||||||
let env = setup_environment(shell, &host_term);
|
let env = setup_environment(shell, &host_term);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
mod chroot;
|
mod chroot;
|
||||||
|
mod utils;
|
||||||
mod cli;
|
mod cli;
|
||||||
mod config;
|
mod config;
|
||||||
mod distro;
|
mod distro;
|
||||||
|
|||||||
+7
-4
@@ -54,6 +54,9 @@ pub fn launch_qemu(config: QemuConfig) -> Result<()> {
|
|||||||
qemu_bin, get_arch_package_suffix(&config.arch), get_arch_package_suffix(&config.arch), get_arch_package_suffix(&config.arch)
|
qemu_bin, get_arch_package_suffix(&config.arch), get_arch_package_suffix(&config.arch), get_arch_package_suffix(&config.arch)
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
|
// Detect the best available shell in the rootfs
|
||||||
|
let shell = crate::utils::detect_shell(&config.rootfs_path);
|
||||||
|
|
||||||
// Generate a unique hostname like "ecr-vm-a1b2c3"
|
// Generate a unique hostname like "ecr-vm-a1b2c3"
|
||||||
let hostname_suffix = format!("{:x}", (std::process::id() as u64)
|
let hostname_suffix = format!("{:x}", (std::process::id() as u64)
|
||||||
.wrapping_mul(std::time::SystemTime::now()
|
.wrapping_mul(std::time::SystemTime::now()
|
||||||
@@ -72,14 +75,14 @@ pub fn launch_qemu(config: QemuConfig) -> Result<()> {
|
|||||||
let kernel_append = if let Some(ref cmd) = config.command {
|
let kernel_append = if let Some(ref cmd) = config.command {
|
||||||
let cmd_str = cmd.join(" ");
|
let cmd_str = cmd.join(" ");
|
||||||
format!(
|
format!(
|
||||||
"console=ttyS0 quiet rdinit=/bin/sh -- -c \"echo {} >/etc/hostname; hostname {}; setsid sh -c 'exec sh </dev/ttyS0 >/dev/ttyS0 2>&1 -c {}'\"",
|
"console=ttyS0 quiet rdinit=/bin/sh -- -c \"echo {} >/etc/hostname; hostname {}; setsid sh -c 'exec {} </dev/ttyS0 >/dev/ttyS0 2>&1 -c {}'\"",
|
||||||
hostname, hostname, cmd_str
|
hostname, hostname, shell, cmd_str
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// Default to interactive shell with proper job control
|
// Default to interactive shell with proper job control
|
||||||
format!(
|
format!(
|
||||||
"console=ttyS0 quiet rdinit=/bin/sh -- -c \"echo {} >/etc/hostname; hostname {}; setsid sh -c 'exec sh </dev/ttyS0 >/dev/ttyS0 2>&1'\"",
|
"console=ttyS0 quiet rdinit=/bin/sh -- -c \"echo {} >/etc/hostname; hostname {}; setsid sh -c 'exec {} </dev/ttyS0 >/dev/ttyS0 2>&1'\"",
|
||||||
hostname, hostname
|
hostname, hostname, shell
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
/// Detect the best available shell in a rootfs
|
||||||
|
/// Checks for bash first, falls back to sh
|
||||||
|
/// Returns the path relative to the rootfs (e.g., "/bin/bash")
|
||||||
|
pub fn detect_shell(rootfs: &Path) -> &'static str {
|
||||||
|
// Check for bash first (preferred)
|
||||||
|
if rootfs.join("bin/bash").exists() {
|
||||||
|
"/bin/bash"
|
||||||
|
} else if rootfs.join("bin/sh").exists() {
|
||||||
|
"/bin/sh"
|
||||||
|
} else if rootfs.join("usr/bin/bash").exists() {
|
||||||
|
"/usr/bin/bash"
|
||||||
|
} else if rootfs.join("usr/bin/sh").exists() {
|
||||||
|
"/usr/bin/sh"
|
||||||
|
} else {
|
||||||
|
"/bin/sh" // Will fail with clear error if not present
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user