Skip to content

Commit

Permalink
[antlir2][genrule_in_image] chown -R $BUCK_SCRATCH_PATH to unprivileg…
Browse files Browse the repository at this point in the history
…ed uid/gid

Summary:
- When an action fails, it's common for `$BUCK_SCRATCH_PATH` to have a bunch of files owned by `root:root`
- This will make sure that `buck` can delete the files afterwards
- This can also happen with `$OUT`, but it's much less common for that to be the problem

Test Plan:
# Before

I was getting lots of permission errors on cleaning up scratch space from failed genrules:

```
$ RUST_LOG=debug buck run //mtia/vm:default -c mtiavm.build=all
Action failed: fbcode//mtia/vm:kernel.modules (antlir2_genrule)
Internal error (stage: materialize_inputs_failed): Error cleaning up output path `buck-out/v2/tmp/fbcode/a4e2dc5b84913c2f/antlir2_genrule`: remove_dir_all(/home/pdel/fbsource/buck-out/v2/tmp/fbcode/a4e2dc5b84913c2f/antlir2_genrule): Permission deni
ed (os error 13)
Reproduce locally: `env -- 'BUCK_SCRATCH_PATH=buck-out/v2/tmp/fbcode/a4e2dc5b84913c2f/antlir2_genrule' sudo buck-out/v2/ ...<omitted>... s/* $OUT        rm -rf $BUCK_SCRATCH_PATH/* # Avoid permission errors during `buck clean`        ' (run `buck2
log what-failed` to get the full command)`
stdout:
stderr:
```

# After

```
$ sudo rm -rf ~/fbsource/buck-out
$ RUST_LOG=debug buck run //mtia/vm:default -c mtiavm.build=all
```

Haven't gotten any more permissions errors after this!

Reviewed By: vmagro

Differential Revision: D66064392

fbshipit-source-id: 5ad2b9223a10da6bbb21f35d81b375c3618b8733
  • Loading branch information
peterdelevoryas authored and facebook-github-bot committed Nov 19, 2024
1 parent a2420fb commit bec1c95
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 12 deletions.
1 change: 1 addition & 0 deletions antlir/antlir2/genrule_in_image/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ rust_binary(
deps = [
"anyhow",
"clap",
"nix",
"serde_json",
"tracing",
"tracing-subscriber",
Expand Down
37 changes: 25 additions & 12 deletions antlir/antlir2/genrule_in_image/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use anyhow::Context;
use anyhow::Result;
use clap::Parser;
use clap::ValueEnum;
use nix::unistd::Gid;
use nix::unistd::Uid;

#[derive(Debug, Parser)]
struct Args {
Expand Down Expand Up @@ -117,10 +119,11 @@ fn main() -> Result<()> {
.setenv(("OUT", "/__genrule_in_image__/out/single_file"));
}

if let Some(scratch) = std::env::var_os("BUCK_SCRATCH_PATH") {
let scratch = std::env::var_os("BUCK_SCRATCH_PATH").map(PathBuf::from);
if let Some(scratch) = scratch.as_ref() {
builder.outputs((
Path::new("/__genrule_in_image__/buck_scratch_path"),
PathBuf::from(scratch.clone()),
scratch.clone(),
));
builder.setenv((
"BUCK_SCRATCH_PATH",
Expand All @@ -138,22 +141,32 @@ fn main() -> Result<()> {
.context(format!("spawn() failed for {:#?}", cmd))?
.wait()
.context(format!("wait() failed for {:#?}", cmd))?;

if let Some(scratch) = scratch.as_ref() {
if let Some((uid, gid)) = rootless.map(|r| r.unprivileged_ids()) {
chown_r(scratch, uid, gid)?;
}
}

ensure!(out.success(), "command failed");

if args.out.dir {
if let Some((uid, gid)) = rootless.map(|r| r.unprivileged_ids()) {
for entry in walkdir::WalkDir::new(&args.out.out)
.into_iter()
.filter_map(Result::ok)
{
std::os::unix::fs::chown(
entry.path(),
uid.map(|u| u.as_raw()),
gid.map(|g| g.as_raw()),
)?;
}
chown_r(&args.out.out, uid, gid)?;
}
}

Ok(())
}

fn chown_r(dir: &Path, uid: Option<Uid>, gid: Option<Gid>) -> std::io::Result<()> {
let uid = uid.map(|u| u.as_raw());
let gid = gid.map(|g| g.as_raw());
for entry in walkdir::WalkDir::new(dir)
.into_iter()
.filter_map(Result::ok)
{
std::os::unix::fs::chown(entry.path(), uid, gid)?;
}
Ok(())
}

0 comments on commit bec1c95

Please sign in to comment.