Skip to content

Commit

Permalink
[antlir2][genrule_in_image] mount layer mounts at runtime
Browse files Browse the repository at this point in the history
Summary:
When running a `genrule_in_image` command, properly mount in any
`feature.layer_mount`s into the container.

Test Plan:
```
❯ buck2 test fbcode//antlir/antlir2/genrule_in_image/tests:
Buck UI: https://www.internalfb.com/buck2/534e0055-501a-40c6-9922-ba02a3184b26
Test UI: https://www.internalfb.com/intern/testinfra/testrun/281475372326083
Tests finished: Pass 14. Fail 0. Fatal 0. Skip 0. Build failure 0
```

Reviewed By: epilatow

Differential Revision: D67343514

fbshipit-source-id: d30133d6573a574f9823e73de2cf5a2d5f5509a6
  • Loading branch information
vmagro authored and facebook-github-bot committed Dec 18, 2024
1 parent 5fa9a27 commit 37a76a4
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 0 deletions.
8 changes: 8 additions & 0 deletions antlir/antlir2/genrule_in_image/genrule_in_image.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ load("//antlir/antlir2/bzl:selects.bzl", "selects")
load("//antlir/antlir2/bzl:types.bzl", "LayerInfo")
load("//antlir/antlir2/bzl/image:cfg.bzl", "attrs_selected_by_cfg", "cfg_attrs", "layer_cfg")
load("//antlir/antlir2/bzl/image:layer.bzl", "layer_rule")
load("//antlir/antlir2/bzl/image:mounts.bzl", "all_mounts", "container_mount_args")
load("//antlir/antlir2/os:package.bzl", "get_default_os_for_package", "should_all_images_in_package_use_default_os")

def _impl(ctx: AnalysisContext) -> list[Provider] | Promise:
Expand Down Expand Up @@ -53,6 +54,13 @@ def _impl(ctx: AnalysisContext) -> list[Provider] | Promise:
cmd_args(ctx.attrs._working_format, format = "--working-format={}"),
cmd_args(out.as_output(), format = "--out={}"),
"--dir" if out_is_dir else cmd_args(),
cmd_args([
container_mount_args(mount)
for mount in all_mounts(
features = layer[LayerInfo].features,
parent_layer = layer[LayerInfo].parent[LayerInfo] if layer[LayerInfo].parent else None,
)
]),
"--",
ctx.attrs.bash,
),
Expand Down
15 changes: 15 additions & 0 deletions antlir/antlir2/genrule_in_image/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
* LICENSE file in the root directory of this source tree.
*/

use std::collections::HashMap;
use std::path::Path;
use std::path::PathBuf;

use antlir2_isolate::unshare;
use antlir2_isolate::IsolationContext;
use antlir2_overlayfs::OverlayFs;
use anyhow::anyhow;
use anyhow::ensure;
use anyhow::Context;
use anyhow::Result;
Expand All @@ -28,6 +30,9 @@ struct Args {
#[clap(value_enum, long)]
/// On-disk format of the layer storage
working_format: WorkingFormat,
/// `--bind-mount-ro src dst` creates an RO bind-mount of src to dst in the subvol
#[clap(long, num_args = 2)]
bind_mount_ro: Vec<PathBuf>,
#[clap(flatten)]
out: Out,
#[clap(last(true))]
Expand Down Expand Up @@ -98,6 +103,16 @@ fn main() -> Result<()> {
.tmpfs(Path::new("/tmp"))
.devtmpfs(Path::new("/dev"));

builder.inputs(
args.bind_mount_ro
.chunks(2)
.map(|pair| match pair {
[src, dst] => Ok((dst.clone(), src.clone())),
_ => Err(anyhow!("Unrecognized mount arg: {:?}", pair)),
})
.collect::<anyhow::Result<HashMap<_, _>>>()?,
);

if args.out.dir {
std::fs::create_dir_all(&args.out.out)?;
builder
Expand Down
37 changes: 37 additions & 0 deletions antlir/antlir2/genrule_in_image/tests/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,42 @@ genrule_in_image(
layer = ":with-par",
)

image.layer(
name = "mount-src",
features = [
feature.install_text(
dst = "/file-in-mount-1",
text = "file 1 in mounted layer",
),
feature.install_text(
dst = "/file-in-mount-2",
text = "file 2 in mounted layer",
),
],
)

image.layer(
name = "layer-with-mount",
features = [
feature.ensure_dirs_exist(dirs = "/mnt/layer"),
feature.layer_mount(
mountpoint = "/mnt/layer",
source = ":mount-src",
),
],
parent_layer = ":layer",
)

genrule_in_image(
name = "with-mount",
out = "f",
bash = """
ls /mnt/layer > $OUT
cat /mnt/layer/file-in-mount-1 >> $OUT
""",
layer = ":layer-with-mount",
)

python_unittest(
name = "test",
srcs = ["test.py"],
Expand All @@ -144,5 +180,6 @@ python_unittest(
"NAMED_DIR": "$(location :named-dir)",
"NAMED_OUTS": "$(location :named-outs)",
"SINGLE_FILE": "$(location :single-file)",
"WITH_MOUNT": "$(location :with-mount)",
},
)
7 changes: 7 additions & 0 deletions antlir/antlir2/genrule_in_image/tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,10 @@ def test_installed_par(self) -> None:
f = Path(os.getenv("INSTALLED_PAR"))
self.assertTrue(f.exists())
self.assertEqual(f.read_text(), "From par\n")

def test_with_mount(self) -> None:
f = Path(os.getenv("WITH_MOUNT"))
self.assertTrue(f.exists())
self.assertEqual(
f.read_text(), "file-in-mount-1\nfile-in-mount-2\nfile 1 in mounted layer"
)

0 comments on commit 37a76a4

Please sign in to comment.