You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.9 KiB
Rust
94 lines
2.9 KiB
Rust
use std::io::stdout;
|
|
|
|
use buildkit_llb::ops::source::ImageSource;
|
|
use buildkit_llb::prelude::*;
|
|
|
|
fn main() {
|
|
let image = Source::image("library/alpine:latest");
|
|
let commands = build_init_commands(&image);
|
|
let commands = build_modify_commands(&image, commands);
|
|
|
|
let base_fs = FileSystem::sequence()
|
|
.custom_name("assemble outputs")
|
|
.append(FileSystem::mkdir(
|
|
OutputIdx(0),
|
|
LayerPath::Scratch("/files"),
|
|
));
|
|
|
|
let (final_fs, final_output) =
|
|
commands
|
|
.into_iter()
|
|
.zip(0..)
|
|
.fold((base_fs, 0), |(fs, last_output), (output, idx)| {
|
|
let layer = fs.append(
|
|
FileSystem::copy()
|
|
.from(LayerPath::Other(output, format!("/file-{}.out", idx)))
|
|
.to(
|
|
OutputIdx(idx + 1),
|
|
LayerPath::Own(
|
|
OwnOutputIdx(last_output),
|
|
format!("/files/file-{}.out", idx),
|
|
),
|
|
),
|
|
);
|
|
|
|
(layer, idx + 1)
|
|
});
|
|
|
|
Terminal::with(final_fs.output(final_output))
|
|
.write_definition(stdout())
|
|
.unwrap()
|
|
}
|
|
|
|
fn build_init_commands(image: &ImageSource) -> Vec<OperationOutput> {
|
|
(0..100)
|
|
.map(|idx| {
|
|
let base_dir = format!("/file/{}", idx);
|
|
let shell = format!("echo 'test {}' > /out{}/file.out", idx, base_dir);
|
|
|
|
let output_mount = FileSystem::mkdir(OutputIdx(0), LayerPath::Scratch(&base_dir))
|
|
.make_parents(true)
|
|
.into_operation()
|
|
.ignore_cache(true)
|
|
.ref_counted();
|
|
|
|
Command::run("/bin/sh")
|
|
.args(&["-c", &shell])
|
|
.mount(Mount::ReadOnlyLayer(image.output(), "/"))
|
|
.mount(Mount::Layer(OutputIdx(0), output_mount.output(0), "/out"))
|
|
.ignore_cache(true)
|
|
.ref_counted()
|
|
.output(0)
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn build_modify_commands<'a>(
|
|
image: &'a ImageSource,
|
|
layers: Vec<OperationOutput<'a>>,
|
|
) -> Vec<OperationOutput<'a>> {
|
|
layers
|
|
.into_iter()
|
|
.zip(0..)
|
|
.map(|(output, idx)| {
|
|
let shell = format!(
|
|
"sed s/test/modified/ < /in/file/{}/file.in > /out/file-{}.out",
|
|
idx, idx
|
|
);
|
|
|
|
Command::run("/bin/sh")
|
|
.args(&["-c", &shell])
|
|
.mount(Mount::ReadOnlyLayer(image.output(), "/"))
|
|
.mount(Mount::Scratch(OutputIdx(0), "/out"))
|
|
.mount(Mount::ReadOnlySelector(
|
|
output,
|
|
format!("/in/file/{}/file.in", idx),
|
|
format!("file/{}/file.out", idx),
|
|
))
|
|
.ignore_cache(true)
|
|
.ref_counted()
|
|
.output(0)
|
|
})
|
|
.collect()
|
|
}
|