use std::{
fs::read_dir,
os::{linux::fs::MetadataExt, unix::fs::PermissionsExt},
path::Path,
};
use cargo_metadata::MetadataCommand;
use change_user_run::{create_users, run_command_as_user};
use log::{LevelFilter, debug};
use rootless_run::{RootlessBackend, RootlesskitBackend, RootlesskitOptions, detect_virt};
use simplelog::{ColorChoice, Config, TermLogger, TerminalMode};
use testresult::TestResult;
const RUN_ROOTLESSKIT: &str = "run-rootlesskit";
fn init_logger() {
if TermLogger::init(
LevelFilter::Debug,
Config::default(),
TerminalMode::Stderr,
ColorChoice::Auto,
)
.is_err()
{
debug!("Not initializing another logger, as one is initialized already.");
}
}
pub fn list_files_in_dir(path: impl AsRef<Path>) -> TestResult {
let path = path.as_ref();
let entries = read_dir(path)?;
for entry in entries {
let entry = entry?;
let meta = entry.metadata()?;
debug!(
"{} {}/{} {entry:?}",
meta.permissions().mode(),
meta.st_uid(),
meta.st_gid()
);
if meta.is_dir() {
list_files_in_dir(entry.path())?;
}
}
Ok(())
}
#[test]
#[cfg(target_os = "linux")]
fn rootlesskitbackend_run() -> TestResult {
use std::{collections::HashMap, fs::copy, path::PathBuf};
use rootless_run::SystemdDetectVirtOutput;
init_logger();
let virt = detect_virt()?;
if virt.uses_namespaces() {
panic!("Cannot run this test in an environment that requires kernel namespaces itself.")
}
let stdout = if virt == SystemdDetectVirtOutput::None {
let backend = RootlesskitBackend::new(RootlesskitOptions::default());
let output = backend.run(&["whoami"])?;
if !output.status.success() {
panic!(
"The test failed but should have succeeded:\nstderr: {}",
String::from_utf8_lossy(&output.stderr)
);
}
String::from_utf8_lossy(&output.stdout).to_string()
} else {
use change_user_run::{COVERAGE_ENV_LIST, collect_coverage_data};
let metadata = MetadataCommand::new().exec()?;
let target_dir = metadata.target_directory.into_std_path_buf();
list_files_in_dir(target_dir.join("debug").join("examples"))?;
let test_cmd = PathBuf::from("/usr/local/bin").join(RUN_ROOTLESSKIT);
copy(
target_dir
.join("debug")
.join("examples")
.join(RUN_ROOTLESSKIT),
test_cmd,
)?;
let user = "testuser";
create_users(&[user], None, None)?;
let output = run_command_as_user(
RUN_ROOTLESSKIT,
&["whoami"],
None,
COVERAGE_ENV_LIST,
Some(HashMap::from([(
"LLVM_PROFILE_FILE".to_string(),
"/tmp/alpm-%p-%16m.profraw".to_string(),
)])),
user,
)?;
if !output.status.success() {
panic!("The test failed but should have succeeded:\n{}", output);
}
collect_coverage_data("/tmp")?;
output.stdout
};
assert_eq!("root\n", stdout);
Ok(())
}