nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 52 lines 1.5 kB view raw
1use std::{ 2 env, 3 io::{Write, stdout}, 4 os::unix::ffi::OsStrExt, 5 os::unix::fs, 6 path::{Path, PathBuf}, 7 process::Command, 8}; 9 10use anyhow::{Context, Result, bail}; 11 12/// Canonicalize `path` in a chroot at the specified `root`. 13pub fn canonicalize_in_chroot(root: &str, path: &Path) -> Result<PathBuf> { 14 let output = Command::new("chroot-realpath") 15 .arg(root) 16 .arg(path.as_os_str()) 17 .output() 18 .context("Failed to run chroot-realpath. Most likely, the binary is not on PATH")?; 19 20 if !output.status.success() { 21 bail!( 22 "chroot-realpath exited unsuccessfully: {}", 23 String::from_utf8_lossy(&output.stderr) 24 ); 25 } 26 27 let output = 28 String::from_utf8(output.stdout).context("Failed to decode stdout of chroot-realpath")?; 29 30 Ok(PathBuf::from(&output)) 31} 32 33/// Entrypoint for the `chroot-realpath` binary. 34pub fn chroot_realpath() -> Result<()> { 35 let args: Vec<String> = env::args().collect(); 36 37 if args.len() != 3 { 38 bail!("Usage: {} <chroot> <path>", args[0]); 39 } 40 41 fs::chroot(&args[1]).context("Failed to chroot")?; 42 std::env::set_current_dir("/").context("Failed to change directory")?; 43 44 let path = std::fs::canonicalize(&args[2]) 45 .with_context(|| format!("Failed to canonicalize {}", args[2]))?; 46 47 stdout() 48 .write_all(path.into_os_string().as_bytes()) 49 .context("Failed to write output")?; 50 51 Ok(()) 52}