Skip to content

Commit 475d018

Browse files
committed
muvm-guest: Support root and user init scripts
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]>
1 parent 98e2563 commit 475d018

3 files changed

Lines changed: 37 additions & 0 deletions

File tree

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/muvm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ tempfile = { version = "3.10.1", default-features = false, features = [] }
2323
tokio = { version = "1.38.0", default-features = false, features = ["io-util", "macros", "net", "process", "rt-multi-thread", "sync"] }
2424
tokio-stream = { version = "0.1.15", default-features = false, features = ["net", "sync"] }
2525
uuid = { version = "1.10.0", default-features = false, features = ["std", "v7"] }
26+
xdg = "2.5.2"
2627

2728
[features]
2829
default = []

crates/muvm/src/guest/bin/muvm-guest.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::cmp;
2+
use std::env;
23
use std::os::unix::process::CommandExt as _;
34
use std::process::Command;
45

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

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

45+
let user = User::from_uid(options.uid)?.unwrap();
46+
47+
// Hack to fetch the XDG directories for our target user, before we
48+
// change uid.
49+
// SAFETY: Safe if and only if `muvm-guest` program is not multithreaded.
50+
// See https://doc.rust-lang.org/std/env/fn.set_var.html#safety
51+
env::set_var("HOME", user.dir);
52+
let xdg_dirs = xdg::BaseDirectories::with_prefix("muvm")?;
53+
// SAFETY: Safe if and only if `muvm-guest` program is not multithreaded.
54+
// See https://doc.rust-lang.org/std/env/fn.set_var.html#safety
55+
env::remove_var("HOME");
56+
4357
setup_fex()?;
4458

4559
configure_network()?;
@@ -50,6 +64,14 @@ fn main() -> Result<()> {
5064
.spawn()?;
5165
}
5266

67+
for init_file in xdg_dirs.find_data_files("init.sh") {
68+
Command::new(init_file)
69+
.arg(format!("{}", options.uid))
70+
.arg(format!("{}", options.gid))
71+
.status()
72+
.context("Failed to execute init.sh")?;
73+
}
74+
5375
let run_path = match setup_user(options.username, options.uid, options.gid) {
5476
Ok(p) => p,
5577
Err(err) => return Err(err).context("Failed to set up user, bailing out"),
@@ -63,6 +85,13 @@ fn main() -> Result<()> {
6385

6486
setup_x11_forwarding(run_path)?;
6587

88+
for init_file in xdg_dirs.find_data_files("user.sh") {
89+
eprintln!("{:?}", init_file);
90+
Command::new(init_file)
91+
.status()
92+
.context("Failed to execute user.sh")?;
93+
}
94+
6695
// Will not return if successful.
6796
exec_sommelier(&options.command, &options.command_args)
6897
.context("Failed to execute sommelier")?;

0 commit comments

Comments
 (0)