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.

441 lines
15 KiB
Rust

mod command;
mod context;
mod mount;
pub use command::Command;
pub use mount::Mount;
#[test]
fn serialization() {
use crate::prelude::*;
use buildkit_proto::pb::{op::Op, ExecOp, Meta, NetMode, SecurityMode};
crate::check_op!(
{
Command::run("/bin/sh")
.args(&["-c", "echo 'test string' > /out/file0"])
.env("HOME", "/root")
.custom_name("exec custom name")
},
|digest| { "sha256:dc9a5a3cd84bb1c7b633f1750fdfccd9d0a69d060f8e3babb297bc190e2d7484" },
|description| { vec![("llb.customname", "exec custom name")] },
|caps| { vec![] },
|cached_tail| { vec![] },
|inputs| { vec![] },
|op| {
Op::Exec(ExecOp {
mounts: vec![],
network: NetMode::Unset.into(),
security: SecurityMode::Sandbox.into(),
meta: Some(Meta {
args: crate::utils::test::to_vec(vec![
"/bin/sh",
"-c",
"echo 'test string' > /out/file0",
]),
env: crate::utils::test::to_vec(vec!["HOME=/root"]),
cwd: "/".into(),
user: "root".into(),
extra_hosts: vec![],
proxy_env: None,
}),
})
},
);
}
#[test]
fn serialization_with_env_iter() {
use crate::prelude::*;
use buildkit_proto::pb::{op::Op, ExecOp, Meta, NetMode, SecurityMode};
crate::check_op!(
{
Command::run("cargo").args(&["build"]).env_iter(vec![
("HOME", "/root"),
("PATH", "/bin"),
("CARGO_HOME", "/root/.cargo"),
])
},
|digest| { "sha256:7675be0b02acb379d57bafee5dc749fca7e795fb1e0a92748ccc59a7bc3b491e" },
|description| { vec![] },
|caps| { vec![] },
|cached_tail| { vec![] },
|inputs| { vec![] },
|op| {
Op::Exec(ExecOp {
mounts: vec![],
network: NetMode::Unset.into(),
security: SecurityMode::Sandbox.into(),
meta: Some(Meta {
args: crate::utils::test::to_vec(vec!["cargo", "build"]),
env: crate::utils::test::to_vec(vec![
"HOME=/root",
"PATH=/bin",
"CARGO_HOME=/root/.cargo",
]),
cwd: "/".into(),
user: "root".into(),
extra_hosts: vec![],
proxy_env: None,
}),
})
},
);
}
#[test]
fn serialization_with_cwd() {
use crate::prelude::*;
use buildkit_proto::pb::{op::Op, ExecOp, Meta, NetMode, SecurityMode};
crate::check_op!(
Command::run("cargo").args(&["build"]).cwd("/rust-src"),
|digest| { "sha256:b8120a0e1d1f7fcaa3d6c95db292d064524dc92c6cae8b97672d4e1eafcd03fa" },
|description| { vec![] },
|caps| { vec![] },
|cached_tail| { vec![] },
|inputs| { vec![] },
|op| {
Op::Exec(ExecOp {
mounts: vec![],
network: NetMode::Unset.into(),
security: SecurityMode::Sandbox.into(),
meta: Some(Meta {
args: crate::utils::test::to_vec(vec!["cargo", "build"]),
env: vec![],
cwd: "/rust-src".into(),
user: "root".into(),
extra_hosts: vec![],
proxy_env: None,
}),
})
},
);
}
#[test]
fn serialization_with_user() {
use crate::prelude::*;
use buildkit_proto::pb::{op::Op, ExecOp, Meta, NetMode, SecurityMode};
crate::check_op!(
Command::run("cargo").args(&["build"]).user("builder"),
|digest| { "sha256:7631ea645e2126e9dbc5d9ae789e34301d9d5c80ce89bfa72bc9b82aa43b57c0" },
|description| { vec![] },
|caps| { vec![] },
|cached_tail| { vec![] },
|inputs| { vec![] },
|op| {
Op::Exec(ExecOp {
mounts: vec![],
network: NetMode::Unset.into(),
security: SecurityMode::Sandbox.into(),
meta: Some(Meta {
args: crate::utils::test::to_vec(vec!["cargo", "build"]),
env: vec![],
cwd: "/".into(),
user: "builder".into(),
extra_hosts: vec![],
proxy_env: None,
}),
})
},
);
}
#[test]
fn serialization_with_mounts() {
use crate::prelude::*;
use buildkit_proto::pb::{
op::Op, CacheOpt, CacheSharingOpt, ExecOp, Meta, MountType, NetMode, SecurityMode,
};
let context = Source::local("context");
let builder_image = Source::image("rustlang/rust:nightly");
let final_image = Source::image("library/alpine:latest");
let command = Command::run("cargo")
.args(&["build"])
.mount(Mount::ReadOnlyLayer(builder_image.output(), "/"))
.mount(Mount::Scratch(OutputIdx(1), "/tmp"))
.mount(Mount::ReadOnlySelector(
context.output(),
"/buildkit-frontend",
"/frontend-sources",
))
.mount(Mount::Layer(OutputIdx(0), final_image.output(), "/output"))
.mount(Mount::SharedCache("/root/.cargo"));
crate::check_op!(
command,
|digest| { "sha256:54a66b514361b13b17f8b5aaaa2392a4c07b55ac53303e4f50584f3dfef6add0" },
|description| { vec![] },
|caps| {
vec![
"exec.mount.bind",
"exec.mount.cache",
"exec.mount.cache.sharing",
"exec.mount.selector",
]
},
|cached_tail| {
vec![
"sha256:a60212791641cbeaa3a49de4f7dff9e40ae50ec19d1be9607232037c1db16702",
"sha256:dee2a3d7dd482dd8098ba543ff1dcb01efd29fcd16fdb0979ef556f38564543a",
"sha256:0e6b31ceed3e6dc542018f35a53a0e857e6a188453d32a2a5bbe7aa2971c1220",
]
},
|inputs| {
vec![
(
"sha256:dee2a3d7dd482dd8098ba543ff1dcb01efd29fcd16fdb0979ef556f38564543a",
0,
),
(
"sha256:a60212791641cbeaa3a49de4f7dff9e40ae50ec19d1be9607232037c1db16702",
0,
),
(
"sha256:0e6b31ceed3e6dc542018f35a53a0e857e6a188453d32a2a5bbe7aa2971c1220",
0,
),
]
},
|op| {
Op::Exec(ExecOp {
mounts: vec![
pb::Mount {
input: 0,
selector: "".into(),
dest: "/".into(),
output: -1,
readonly: true,
mount_type: MountType::Bind.into(),
cache_opt: None,
secret_opt: None,
ssh_opt: None,
},
pb::Mount {
input: -1,
selector: "".into(),
dest: "/tmp".into(),
output: 1,
readonly: false,
mount_type: MountType::Bind.into(),
cache_opt: None,
secret_opt: None,
ssh_opt: None,
},
pb::Mount {
input: 1,
selector: "/frontend-sources".into(),
dest: "/buildkit-frontend".into(),
output: -1,
readonly: true,
mount_type: MountType::Bind.into(),
cache_opt: None,
secret_opt: None,
ssh_opt: None,
},
pb::Mount {
input: 2,
selector: "".into(),
dest: "/output".into(),
output: 0,
readonly: false,
mount_type: MountType::Bind.into(),
cache_opt: None,
secret_opt: None,
ssh_opt: None,
},
pb::Mount {
input: -1,
selector: "".into(),
dest: "/root/.cargo".into(),
output: -1,
readonly: false,
mount_type: MountType::Cache.into(),
cache_opt: Some(CacheOpt {
id: "/root/.cargo".into(),
sharing: CacheSharingOpt::Shared.into(),
}),
secret_opt: None,
ssh_opt: None,
},
],
network: NetMode::Unset.into(),
security: SecurityMode::Sandbox.into(),
meta: Some(Meta {
args: crate::utils::test::to_vec(vec!["cargo", "build"]),
env: vec![],
cwd: "/".into(),
user: "root".into(),
extra_hosts: vec![],
proxy_env: None,
}),
})
},
);
}
#[test]
fn serialization_with_several_root_mounts() {
use crate::prelude::*;
use buildkit_proto::pb::{op::Op, ExecOp, Meta, MountType, NetMode, SecurityMode};
let builder_image = Source::image("rustlang/rust:nightly");
let final_image = Source::image("library/alpine:latest");
let command = Command::run("cargo")
.args(&["build"])
.mount(Mount::Scratch(OutputIdx(0), "/tmp"))
.mount(Mount::ReadOnlyLayer(builder_image.output(), "/"))
.mount(Mount::Scratch(OutputIdx(1), "/var"))
.mount(Mount::ReadOnlyLayer(final_image.output(), "/"));
crate::check_op!(
command,
|digest| { "sha256:baa1bf591d2c47058b7361a0284fa8a3f1bd0fac8a93c87affa77ddc0a5026fd" },
|description| { vec![] },
|caps| { vec!["exec.mount.bind"] },
|cached_tail| {
vec!["sha256:0e6b31ceed3e6dc542018f35a53a0e857e6a188453d32a2a5bbe7aa2971c1220"]
},
|inputs| {
vec![(
"sha256:0e6b31ceed3e6dc542018f35a53a0e857e6a188453d32a2a5bbe7aa2971c1220",
0,
)]
},
|op| {
Op::Exec(ExecOp {
mounts: vec![
pb::Mount {
input: 0,
selector: "".into(),
dest: "/".into(),
output: -1,
readonly: true,
mount_type: MountType::Bind.into(),
cache_opt: None,
secret_opt: None,
ssh_opt: None,
},
pb::Mount {
input: -1,
selector: "".into(),
dest: "/tmp".into(),
output: 0,
readonly: false,
mount_type: MountType::Bind.into(),
cache_opt: None,
secret_opt: None,
ssh_opt: None,
},
pb::Mount {
input: -1,
selector: "".into(),
dest: "/var".into(),
output: 1,
readonly: false,
mount_type: MountType::Bind.into(),
cache_opt: None,
secret_opt: None,
ssh_opt: None,
},
],
network: NetMode::Unset.into(),
security: SecurityMode::Sandbox.into(),
meta: Some(Meta {
args: crate::utils::test::to_vec(vec!["cargo", "build"]),
env: vec![],
cwd: "/".into(),
user: "root".into(),
extra_hosts: vec![],
proxy_env: None,
}),
})
},
);
}
#[test]
fn serialization_with_ssh_mounts() {
use crate::prelude::*;
use buildkit_proto::pb::{op::Op, ExecOp, Meta, MountType, NetMode, SecurityMode, SshOpt};
let builder_image = Source::image("rustlang/rust:nightly");
let command = Command::run("cargo")
.args(&["build"])
.mount(Mount::ReadOnlyLayer(builder_image.output(), "/"))
.mount(Mount::OptionalSshAgent("/run/buildkit/ssh_agent.0"));
crate::check_op!(
command,
|digest| { "sha256:1ac1438c67a153878f21fe8067383fd7544901261374eb53ba8bf26e9a5821a5" },
|description| { vec![] },
|caps| { vec!["exec.mount.bind", "exec.mount.ssh"] },
|cached_tail| {
vec!["sha256:dee2a3d7dd482dd8098ba543ff1dcb01efd29fcd16fdb0979ef556f38564543a"]
},
|inputs| {
vec![(
"sha256:dee2a3d7dd482dd8098ba543ff1dcb01efd29fcd16fdb0979ef556f38564543a",
0,
)]
},
|op| {
Op::Exec(ExecOp {
mounts: vec![
pb::Mount {
input: 0,
selector: "".into(),
dest: "/".into(),
output: -1,
readonly: true,
mount_type: MountType::Bind.into(),
cache_opt: None,
secret_opt: None,
ssh_opt: None,
},
pb::Mount {
input: -1,
selector: "".into(),
dest: "/run/buildkit/ssh_agent.0".into(),
output: -1,
readonly: false,
mount_type: MountType::Ssh.into(),
cache_opt: None,
secret_opt: None,
ssh_opt: Some(SshOpt {
mode: 0o600,
optional: true,
..Default::default()
}),
},
],
network: NetMode::Unset.into(),
security: SecurityMode::Sandbox.into(),
meta: Some(Meta {
args: crate::utils::test::to_vec(vec!["cargo", "build"]),
env: vec![],
cwd: "/".into(),
user: "root".into(),
extra_hosts: vec![],
proxy_env: None,
}),
})
},
);
}