Skip to content

Commit

Permalink
muvm-guest: Support root and user init scripts
Browse files Browse the repository at this point in the history
Introduce two scripts that can be placed in ~/.local/share/muvm

- init.sh: Executed as root, before dropping privileges
- user.sh: Executed as the user, after dropping privileges

If the files are also present in lower-priority XDG dirs (systemwide),
those are executed first.

This makes it possible to add custom VM configuration and setup or
debugging scripts without having to hack on the muvm code.

Signed-off-by: Asahi Lina <[email protected]>
  • Loading branch information
asahilina committed Oct 15, 2024
1 parent 98e2563 commit 475d018
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/muvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ tempfile = { version = "3.10.1", default-features = false, features = [] }
tokio = { version = "1.38.0", default-features = false, features = ["io-util", "macros", "net", "process", "rt-multi-thread", "sync"] }
tokio-stream = { version = "0.1.15", default-features = false, features = ["net", "sync"] }
uuid = { version = "1.10.0", default-features = false, features = ["std", "v7"] }
xdg = "2.5.2"

[features]
default = []
Expand Down
29 changes: 29 additions & 0 deletions crates/muvm/src/guest/bin/muvm-guest.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::cmp;
use std::env;
use std::os::unix::process::CommandExt as _;
use std::process::Command;

Expand All @@ -13,6 +14,7 @@ use muvm::guest::sommelier::exec_sommelier;
use muvm::guest::user::setup_user;
use muvm::guest::x11::setup_x11_forwarding;
use muvm::utils::env::find_in_path;
use nix::unistd::User;
use rustix::process::{getrlimit, setrlimit, Resource};

fn main() -> Result<()> {
Expand Down Expand Up @@ -40,6 +42,18 @@ fn main() -> Result<()> {
}
Command::new("/usr/lib/systemd/systemd-udevd").spawn()?;

let user = User::from_uid(options.uid)?.unwrap();

// Hack to fetch the XDG directories for our target user, before we
// change uid.
// SAFETY: Safe if and only if `muvm-guest` program is not multithreaded.
// See https://doc.rust-lang.org/std/env/fn.set_var.html#safety
env::set_var("HOME", user.dir);
let xdg_dirs = xdg::BaseDirectories::with_prefix("muvm")?;
// SAFETY: Safe if and only if `muvm-guest` program is not multithreaded.
// See https://doc.rust-lang.org/std/env/fn.set_var.html#safety
env::remove_var("HOME");

setup_fex()?;

configure_network()?;
Expand All @@ -50,6 +64,14 @@ fn main() -> Result<()> {
.spawn()?;
}

for init_file in xdg_dirs.find_data_files("init.sh") {
Command::new(init_file)
.arg(format!("{}", options.uid))
.arg(format!("{}", options.gid))
.status()
.context("Failed to execute init.sh")?;
}

let run_path = match setup_user(options.username, options.uid, options.gid) {
Ok(p) => p,
Err(err) => return Err(err).context("Failed to set up user, bailing out"),
Expand All @@ -63,6 +85,13 @@ fn main() -> Result<()> {

setup_x11_forwarding(run_path)?;

for init_file in xdg_dirs.find_data_files("user.sh") {
eprintln!("{:?}", init_file);
Command::new(init_file)
.status()
.context("Failed to execute user.sh")?;
}

// Will not return if successful.
exec_sommelier(&options.command, &options.command_args)
.context("Failed to execute sommelier")?;
Expand Down

0 comments on commit 475d018

Please sign in to comment.