diff --git a/crates/muvm/src/bin/muvm.rs b/crates/muvm/src/bin/muvm.rs index 8a62fa02..be46e12e 100644 --- a/crates/muvm/src/bin/muvm.rs +++ b/crates/muvm/src/bin/muvm.rs @@ -405,6 +405,7 @@ fn main() -> Result { emulator: options.emulator, cwd, init_commands, + user_init_commands: options.user_init_commands, }; let mut muvm_config_file = NamedTempFile::new() .context("Failed to create a temporary file to store the muvm guest config")?; diff --git a/crates/muvm/src/cli_options.rs b/crates/muvm/src/cli_options.rs index 92e608c1..7cde5e8b 100644 --- a/crates/muvm/src/cli_options.rs +++ b/crates/muvm/src/cli_options.rs @@ -22,6 +22,7 @@ pub struct Options { pub publish_ports: Vec, pub emulator: Option, pub init_commands: Vec, + pub user_init_commands: Vec, pub command: PathBuf, pub command_args: Vec, } @@ -136,12 +137,20 @@ pub fn options() -> OptionParser { let init_commands = long("execute-pre") .short('x') .help( - "Command to run inside the VM before guest server starts. + "Command to run inside the VM before guest server starts, while still running as root. Can be used for e.g. setting up additional mounts. Can be specified multiple times.", ) .argument("COMMAND") .many(); + let user_init_commands = long("user-execute-pre") + .short('X') + .help( + "Command to run inside the VM before guest server starts, but after the user is set up. + Can be specified multiple times.", + ) + .argument("COMMAND") + .many(); let command = positional("COMMAND").help("the command you want to execute in the vm"); let command_args = any::("COMMAND_ARGS", |arg| { (!["--help", "-h"].contains(&&*arg)).then_some(arg) @@ -163,6 +172,7 @@ pub fn options() -> OptionParser { publish_ports, emulator, init_commands, + user_init_commands, // positionals command, command_args, diff --git a/crates/muvm/src/guest/bin/muvm-guest.rs b/crates/muvm/src/guest/bin/muvm-guest.rs index 892e9898..5ed7d0f7 100644 --- a/crates/muvm/src/guest/bin/muvm-guest.rs +++ b/crates/muvm/src/guest/bin/muvm-guest.rs @@ -111,6 +111,16 @@ fn main() -> Result<()> { Err(err) => return Err(err).context("Failed to set up user, bailing out"), }; + for init_command in options.user_init_commands { + let code = Command::new(&init_command) + .current_dir(&options.cwd) + .spawn()? + .wait()?; + if !code.success() { + return Err(anyhow!("Executing `{}` failed", init_command.display())); + } + } + let pulse_path = run_path.join("pulse"); std::fs::create_dir(&pulse_path) .context("Failed to create `pulse` directory in `XDG_RUNTIME_DIR`")?; diff --git a/crates/muvm/src/utils/launch.rs b/crates/muvm/src/utils/launch.rs index 7b95dcae..6a50d5a6 100644 --- a/crates/muvm/src/utils/launch.rs +++ b/crates/muvm/src/utils/launch.rs @@ -45,6 +45,7 @@ pub struct GuestConfiguration { pub emulator: Option, pub cwd: PathBuf, pub init_commands: Vec, + pub user_init_commands: Vec, } pub const PULSE_SOCKET: u32 = 3333;