tests/inst: Port to cap-std
authorColin Walters <walters@verbum.org>
Fri, 24 Jun 2022 19:28:21 +0000 (15:28 -0400)
committerColin Walters <walters@verbum.org>
Fri, 24 Jun 2022 20:23:05 +0000 (16:23 -0400)
Part of an ongoing effort.

tests/inst/Cargo.toml
tests/inst/src/treegen.rs

index e151c073445ab4aa364e292023c2f86c0f1a21da..e006dda1eefbc2fc9f3817da0d387ddc16f8db31 100644 (file)
@@ -11,6 +11,7 @@ name = "ostree-test"
 path = "src/insttestmain.rs"
 
 [dependencies]
+cap-std-ext = "0.25"
 clap = "2.32.0"
 structopt = "0.3"
 serde = "1.0.111"
@@ -33,8 +34,6 @@ procspawn = "0.8"
 rand = "0.8"
 strum = "0.18.0"
 strum_macros = "0.18.0"
-openat = "0.1.19"
-openat-ext = "0.1.4"
 nix = "0.23.0"
 # See discussion in https://github.com/coreos/rpm-ostree/pull/2569#issuecomment-780569188
 rpmostree-client = { git = "https://github.com/coreos/rpm-ostree", tag = "v2021.3" }
index 29bdffd22d04fd06f761b3a313d37ba76a5deddd..ab0c5bdbb4b326f968417817d60b705f59e8e5bd 100644 (file)
@@ -1,5 +1,8 @@
 use anyhow::{Context, Result};
-use openat_ext::{FileExt, OpenatDirExt};
+use cap_std::fs::Dir;
+use cap_std_ext::cap_std;
+use cap_std_ext::dirext::*;
+use cap_std_ext::rustix::fs::MetadataExt;
 use rand::Rng;
 use sh_inline::bash;
 use std::fs::File;
@@ -52,40 +55,36 @@ pub(crate) fn is_elf(f: &mut File) -> Result<bool> {
 pub(crate) fn mutate_one_executable_to(
     f: &mut File,
     name: &std::ffi::OsStr,
-    dest: &openat::Dir,
+    dest: &Dir,
 ) -> Result<()> {
-    let mut destf = dest
-        .write_file(name, 0o755)
-        .context("Failed to open for write")?;
-    f.copy_to(&destf).context("Failed to copy")?;
-    // ELF is OK with us just appending some junk
-    let extra = rand::thread_rng()
-        .sample_iter(&rand::distributions::Alphanumeric)
-        .take(10)
-        .collect::<Vec<u8>>();
-    destf
-        .write_all(&extra)
-        .context("Failed to append extra data")?;
-    Ok(())
+    let perms = f.metadata()?.permissions();
+    dest.atomic_replace_with(name, |w| {
+        std::io::copy(f, w)?;
+        // ELF is OK with us just appending some junk
+        let extra = rand::thread_rng()
+            .sample_iter(&rand::distributions::Alphanumeric)
+            .take(10)
+            .collect::<Vec<u8>>();
+        w.write_all(&extra).context("Failed to append extra data")?;
+        w.get_mut()
+            .as_file_mut()
+            .set_permissions(cap_std::fs::Permissions::from_std(perms))?;
+        Ok::<_, anyhow::Error>(())
+    })
 }
 
 /// Find ELF files in the srcdir, write new copies to dest (only percentage)
-pub(crate) fn mutate_executables_to(
-    src: &openat::Dir,
-    dest: &openat::Dir,
-    percentage: u32,
-) -> Result<u32> {
+pub(crate) fn mutate_executables_to(src: &Dir, dest: &Dir, percentage: u32) -> Result<u32> {
     use nix::sys::stat::Mode as NixMode;
     assert!(percentage > 0 && percentage <= 100);
     let mut mutated = 0;
-    for entry in src.list_dir(".")? {
+    for entry in src.entries()? {
         let entry = entry?;
-        if src.get_file_type(&entry)? != openat::SimpleType::File {
+        if entry.file_type()? != cap_std::fs::FileType::file() {
             continue;
         }
-        let meta = src.metadata(entry.file_name())?;
-        let st = meta.stat();
-        let mode = NixMode::from_bits_truncate(st.st_mode);
+        let meta = entry.metadata()?;
+        let mode = NixMode::from_bits_truncate(meta.mode());
         // Must be executable
         if !mode.intersects(NixMode::S_IXUSR | NixMode::S_IXGRP | NixMode::S_IXOTH) {
             continue;
@@ -95,17 +94,17 @@ pub(crate) fn mutate_executables_to(
             continue;
         }
         // Greater than 1k in size
-        if st.st_size < 1024 {
+        if meta.size() < 1024 {
             continue;
         }
-        let mut f = src.open_file(entry.file_name())?;
+        let mut f = entry.open()?.into_std();
         if !is_elf(&mut f)? {
             continue;
         }
         if !rand::thread_rng().gen_ratio(percentage, 100) {
             continue;
         }
-        mutate_one_executable_to(&mut f, entry.file_name(), dest)
+        mutate_one_executable_to(&mut f, &entry.file_name(), dest)
             .with_context(|| format!("Failed updating {:?}", entry.file_name()))?;
         mutated += 1;
     }
@@ -124,15 +123,14 @@ pub(crate) fn update_os_tree<P: AsRef<Path>>(
     let tempdir = tempfile::tempdir_in(repo_path.join("tmp"))?;
     let mut mutated = 0;
     {
-        let tempdir = openat::Dir::open(tempdir.path())?;
+        let tempdir = Dir::open_ambient_dir(tempdir.path(), cap_std::ambient_authority())?;
         let binary_dirs = &["usr/bin", "usr/sbin", "usr/lib", "usr/lib64"];
-        let rootfs = openat::Dir::open("/")?;
+        let rootfs = Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
         for v in binary_dirs {
             let v = *v;
-            if let Some(src) = rootfs.sub_dir_optional(v)? {
-                tempdir.ensure_dir("usr", 0o755)?;
-                tempdir.ensure_dir(v, 0o755)?;
-                let dest = tempdir.sub_dir(v)?;
+            if let Some(src) = rootfs.open_dir_optional(v)? {
+                tempdir.create_dir_all(v)?;
+                let dest = tempdir.open_dir(v)?;
                 mutated += mutate_executables_to(&src, &dest, percentage)
                     .with_context(|| format!("Replacing binaries in {v}"))?;
             }