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

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 <lina@asahilina.net>
  • Loading branch information
asahilina committed Oct 15, 2024
1 parent 98e2563 commit 7109741
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 7109741

Please sign in to comment.