feat: --no-cache build flag and Sol build target
- Add --no-cache flag to sunbeam build (passes --no-cache to buildctl) - Add Sol (virtual librarian) as a build target - Wire no_cache through all build functions and dispatch
This commit is contained in:
15
src/cli.rs
15
src/cli.rs
@@ -88,6 +88,9 @@ pub enum Verb {
|
|||||||
/// Apply manifests and rollout restart after pushing (implies --push).
|
/// Apply manifests and rollout restart after pushing (implies --push).
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
deploy: bool,
|
deploy: bool,
|
||||||
|
/// Disable buildkitd layer cache.
|
||||||
|
#[arg(long)]
|
||||||
|
no_cache: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Functional service health checks.
|
/// Functional service health checks.
|
||||||
@@ -243,6 +246,7 @@ pub enum BuildTarget {
|
|||||||
Tuwunel,
|
Tuwunel,
|
||||||
Calendars,
|
Calendars,
|
||||||
Projects,
|
Projects,
|
||||||
|
Sol,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for BuildTarget {
|
impl std::fmt::Display for BuildTarget {
|
||||||
@@ -265,6 +269,7 @@ impl std::fmt::Display for BuildTarget {
|
|||||||
BuildTarget::Tuwunel => "tuwunel",
|
BuildTarget::Tuwunel => "tuwunel",
|
||||||
BuildTarget::Calendars => "calendars",
|
BuildTarget::Calendars => "calendars",
|
||||||
BuildTarget::Projects => "projects",
|
BuildTarget::Projects => "projects",
|
||||||
|
BuildTarget::Sol => "sol",
|
||||||
};
|
};
|
||||||
write!(f, "{s}")
|
write!(f, "{s}")
|
||||||
}
|
}
|
||||||
@@ -465,10 +470,11 @@ mod tests {
|
|||||||
fn test_build_proxy() {
|
fn test_build_proxy() {
|
||||||
let cli = parse(&["sunbeam", "build", "proxy"]);
|
let cli = parse(&["sunbeam", "build", "proxy"]);
|
||||||
match cli.verb {
|
match cli.verb {
|
||||||
Some(Verb::Build { what, push, deploy }) => {
|
Some(Verb::Build { what, push, deploy, no_cache }) => {
|
||||||
assert!(matches!(what, BuildTarget::Proxy));
|
assert!(matches!(what, BuildTarget::Proxy));
|
||||||
assert!(!push);
|
assert!(!push);
|
||||||
assert!(!deploy);
|
assert!(!deploy);
|
||||||
|
assert!(!no_cache);
|
||||||
}
|
}
|
||||||
_ => panic!("expected Build"),
|
_ => panic!("expected Build"),
|
||||||
}
|
}
|
||||||
@@ -479,10 +485,11 @@ mod tests {
|
|||||||
fn test_build_deploy_flag() {
|
fn test_build_deploy_flag() {
|
||||||
let cli = parse(&["sunbeam", "build", "proxy", "--deploy"]);
|
let cli = parse(&["sunbeam", "build", "proxy", "--deploy"]);
|
||||||
match cli.verb {
|
match cli.verb {
|
||||||
Some(Verb::Build { deploy, push, .. }) => {
|
Some(Verb::Build { deploy, push, no_cache, .. }) => {
|
||||||
assert!(deploy);
|
assert!(deploy);
|
||||||
// clap does not imply --push; that logic is in dispatch()
|
// clap does not imply --push; that logic is in dispatch()
|
||||||
assert!(!push);
|
assert!(!push);
|
||||||
|
assert!(!no_cache);
|
||||||
}
|
}
|
||||||
_ => panic!("expected Build"),
|
_ => panic!("expected Build"),
|
||||||
}
|
}
|
||||||
@@ -838,9 +845,9 @@ pub async fn dispatch() -> Result<()> {
|
|||||||
crate::services::cmd_restart(target.as_deref()).await
|
crate::services::cmd_restart(target.as_deref()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Verb::Build { what, push, deploy }) => {
|
Some(Verb::Build { what, push, deploy, no_cache }) => {
|
||||||
let push = push || deploy;
|
let push = push || deploy;
|
||||||
crate::images::cmd_build(&what, push, deploy).await
|
crate::images::cmd_build(&what, push, deploy, no_cache).await
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Verb::Check { target }) => {
|
Some(Verb::Check { target }) => {
|
||||||
|
|||||||
109
src/images.rs
109
src/images.rs
@@ -837,7 +837,7 @@ async fn clear_image_pull_error_pods() -> Result<()> {
|
|||||||
// Per-service build functions
|
// Per-service build functions
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
async fn build_proxy(push: bool, deploy: bool) -> Result<()> {
|
async fn build_proxy(push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
let proxy_dir = crate::config::get_repo_root().join("proxy");
|
let proxy_dir = crate::config::get_repo_root().join("proxy");
|
||||||
if !proxy_dir.is_dir() {
|
if !proxy_dir.is_dir() {
|
||||||
@@ -855,7 +855,7 @@ async fn build_proxy(push: bool, deploy: bool) -> Result<()> {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -866,7 +866,7 @@ async fn build_proxy(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_tuwunel(push: bool, deploy: bool) -> Result<()> {
|
async fn build_tuwunel(push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
let tuwunel_dir = crate::config::get_repo_root().join("tuwunel");
|
let tuwunel_dir = crate::config::get_repo_root().join("tuwunel");
|
||||||
if !tuwunel_dir.is_dir() {
|
if !tuwunel_dir.is_dir() {
|
||||||
@@ -884,7 +884,7 @@ async fn build_tuwunel(push: bool, deploy: bool) -> Result<()> {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -895,7 +895,7 @@ async fn build_tuwunel(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_integration(push: bool, deploy: bool) -> Result<()> {
|
async fn build_integration(push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
let sunbeam_dir = crate::config::get_repo_root();
|
let sunbeam_dir = crate::config::get_repo_root();
|
||||||
let integration_service_dir = sunbeam_dir.join("integration-service");
|
let integration_service_dir = sunbeam_dir.join("integration-service");
|
||||||
@@ -940,7 +940,7 @@ async fn build_integration(push: bool, deploy: bool) -> Result<()> {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@@ -957,7 +957,7 @@ async fn build_integration(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_kratos_admin(push: bool, deploy: bool) -> Result<()> {
|
async fn build_kratos_admin(push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
let kratos_admin_dir = crate::config::get_repo_root().join("kratos-admin");
|
let kratos_admin_dir = crate::config::get_repo_root().join("kratos-admin");
|
||||||
if !kratos_admin_dir.is_dir() {
|
if !kratos_admin_dir.is_dir() {
|
||||||
@@ -978,7 +978,7 @@ async fn build_kratos_admin(push: bool, deploy: bool) -> Result<()> {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -989,7 +989,7 @@ async fn build_kratos_admin(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_meet(push: bool, deploy: bool) -> Result<()> {
|
async fn build_meet(push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
let meet_dir = crate::config::get_repo_root().join("meet");
|
let meet_dir = crate::config::get_repo_root().join("meet");
|
||||||
if !meet_dir.is_dir() {
|
if !meet_dir.is_dir() {
|
||||||
@@ -1009,7 +1009,7 @@ async fn build_meet(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Some("backend-production"),
|
Some("backend-production"),
|
||||||
None,
|
None,
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1035,7 +1035,7 @@ async fn build_meet(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Some("frontend-production"),
|
Some("frontend-production"),
|
||||||
Some(&build_args),
|
Some(&build_args),
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1053,7 +1053,7 @@ async fn build_meet(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_people(push: bool, deploy: bool) -> Result<()> {
|
async fn build_people(push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
let people_dir = crate::config::get_repo_root().join("people");
|
let people_dir = crate::config::get_repo_root().join("people");
|
||||||
if !people_dir.is_dir() {
|
if !people_dir.is_dir() {
|
||||||
@@ -1109,7 +1109,7 @@ async fn build_people(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Some("frontend-production"),
|
Some("frontend-production"),
|
||||||
Some(&build_args),
|
Some(&build_args),
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1160,7 +1160,7 @@ const MESSAGES_COMPONENTS: &[(&str, &str, &str, Option<&str>)] = &[
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
async fn build_messages(what: &str, push: bool, deploy: bool) -> Result<()> {
|
async fn build_messages(what: &str, push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
let messages_dir = crate::config::get_repo_root().join("messages");
|
let messages_dir = crate::config::get_repo_root().join("messages");
|
||||||
if !messages_dir.is_dir() {
|
if !messages_dir.is_dir() {
|
||||||
@@ -1214,7 +1214,7 @@ async fn build_messages(what: &str, push: bool, deploy: bool) -> Result<()> {
|
|||||||
*target,
|
*target,
|
||||||
None,
|
None,
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&cleanup_paths,
|
&cleanup_paths,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1257,6 +1257,7 @@ async fn build_la_suite_frontend(
|
|||||||
namespace: &str,
|
namespace: &str,
|
||||||
push: bool,
|
push: bool,
|
||||||
deploy: bool,
|
deploy: bool,
|
||||||
|
no_cache: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
|
|
||||||
@@ -1307,7 +1308,7 @@ async fn build_la_suite_frontend(
|
|||||||
Some("frontend-production"),
|
Some("frontend-production"),
|
||||||
Some(&build_args),
|
Some(&build_args),
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1439,7 +1440,7 @@ async fn patch_dockerfile_uv(
|
|||||||
Ok((patched_df, cleanup))
|
Ok((patched_df, cleanup))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_projects(push: bool, deploy: bool) -> Result<()> {
|
async fn build_projects(push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
let projects_dir = crate::config::get_repo_root().join("projects");
|
let projects_dir = crate::config::get_repo_root().join("projects");
|
||||||
if !projects_dir.is_dir() {
|
if !projects_dir.is_dir() {
|
||||||
@@ -1457,7 +1458,7 @@ async fn build_projects(push: bool, deploy: bool) -> Result<()> {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1468,7 +1469,36 @@ async fn build_projects(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build_calendars(push: bool, deploy: bool) -> Result<()> {
|
async fn build_sol(push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
|
let env = get_build_env().await?;
|
||||||
|
let sol_dir = crate::config::get_repo_root().join("sol");
|
||||||
|
if !sol_dir.is_dir() {
|
||||||
|
return Err(SunbeamError::build(format!("Sol source not found at {}", sol_dir.display())));
|
||||||
|
}
|
||||||
|
|
||||||
|
let image = format!("{}/studio/sol:latest", env.registry);
|
||||||
|
step(&format!("Building sol -> {image} ..."));
|
||||||
|
|
||||||
|
build_image(
|
||||||
|
&env,
|
||||||
|
&image,
|
||||||
|
&sol_dir.join("Dockerfile"),
|
||||||
|
&sol_dir,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
push,
|
||||||
|
no_cache,
|
||||||
|
&[],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if deploy {
|
||||||
|
deploy_rollout(&env, &["sol"], "matrix", 120, None).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn build_calendars(push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
let env = get_build_env().await?;
|
let env = get_build_env().await?;
|
||||||
let cal_dir = crate::config::get_repo_root().join("calendars");
|
let cal_dir = crate::config::get_repo_root().join("calendars");
|
||||||
if !cal_dir.is_dir() {
|
if !cal_dir.is_dir() {
|
||||||
@@ -1518,7 +1548,7 @@ async fn build_calendars(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Some("backend-production"),
|
Some("backend-production"),
|
||||||
None,
|
None,
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&cleanup,
|
&cleanup,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1535,7 +1565,7 @@ async fn build_calendars(push: bool, deploy: bool) -> Result<()> {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1573,7 +1603,7 @@ async fn build_calendars(push: bool, deploy: bool) -> Result<()> {
|
|||||||
Some("frontend-production"),
|
Some("frontend-production"),
|
||||||
Some(&build_args),
|
Some(&build_args),
|
||||||
push,
|
push,
|
||||||
false,
|
no_cache,
|
||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1601,12 +1631,12 @@ async fn build_calendars(push: bool, deploy: bool) -> Result<()> {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Build an image. Pass push=true to push, deploy=true to also apply + rollout.
|
/// Build an image. Pass push=true to push, deploy=true to also apply + rollout.
|
||||||
pub async fn cmd_build(what: &BuildTarget, push: bool, deploy: bool) -> Result<()> {
|
pub async fn cmd_build(what: &BuildTarget, push: bool, deploy: bool, no_cache: bool) -> Result<()> {
|
||||||
match what {
|
match what {
|
||||||
BuildTarget::Proxy => build_proxy(push, deploy).await,
|
BuildTarget::Proxy => build_proxy(push, deploy, no_cache).await,
|
||||||
BuildTarget::Integration => build_integration(push, deploy).await,
|
BuildTarget::Integration => build_integration(push, deploy, no_cache).await,
|
||||||
BuildTarget::KratosAdmin => build_kratos_admin(push, deploy).await,
|
BuildTarget::KratosAdmin => build_kratos_admin(push, deploy, no_cache).await,
|
||||||
BuildTarget::Meet => build_meet(push, deploy).await,
|
BuildTarget::Meet => build_meet(push, deploy, no_cache).await,
|
||||||
BuildTarget::DocsFrontend => {
|
BuildTarget::DocsFrontend => {
|
||||||
let repo_dir = crate::config::get_repo_root().join("docs");
|
let repo_dir = crate::config::get_repo_root().join("docs");
|
||||||
build_la_suite_frontend(
|
build_la_suite_frontend(
|
||||||
@@ -1620,22 +1650,24 @@ pub async fn cmd_build(what: &BuildTarget, push: bool, deploy: bool) -> Result<(
|
|||||||
"lasuite",
|
"lasuite",
|
||||||
push,
|
push,
|
||||||
deploy,
|
deploy,
|
||||||
|
no_cache,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
BuildTarget::PeopleFrontend | BuildTarget::People => build_people(push, deploy).await,
|
BuildTarget::PeopleFrontend | BuildTarget::People => build_people(push, deploy, no_cache).await,
|
||||||
BuildTarget::Messages => build_messages("messages", push, deploy).await,
|
BuildTarget::Messages => build_messages("messages", push, deploy, no_cache).await,
|
||||||
BuildTarget::MessagesBackend => build_messages("messages-backend", push, deploy).await,
|
BuildTarget::MessagesBackend => build_messages("messages-backend", push, deploy, no_cache).await,
|
||||||
BuildTarget::MessagesFrontend => build_messages("messages-frontend", push, deploy).await,
|
BuildTarget::MessagesFrontend => build_messages("messages-frontend", push, deploy, no_cache).await,
|
||||||
BuildTarget::MessagesMtaIn => build_messages("messages-mta-in", push, deploy).await,
|
BuildTarget::MessagesMtaIn => build_messages("messages-mta-in", push, deploy, no_cache).await,
|
||||||
BuildTarget::MessagesMtaOut => build_messages("messages-mta-out", push, deploy).await,
|
BuildTarget::MessagesMtaOut => build_messages("messages-mta-out", push, deploy, no_cache).await,
|
||||||
BuildTarget::MessagesMpa => build_messages("messages-mpa", push, deploy).await,
|
BuildTarget::MessagesMpa => build_messages("messages-mpa", push, deploy, no_cache).await,
|
||||||
BuildTarget::MessagesSocksProxy => {
|
BuildTarget::MessagesSocksProxy => {
|
||||||
build_messages("messages-socks-proxy", push, deploy).await
|
build_messages("messages-socks-proxy", push, deploy, no_cache).await
|
||||||
}
|
}
|
||||||
BuildTarget::Tuwunel => build_tuwunel(push, deploy).await,
|
BuildTarget::Tuwunel => build_tuwunel(push, deploy, no_cache).await,
|
||||||
BuildTarget::Calendars => build_calendars(push, deploy).await,
|
BuildTarget::Calendars => build_calendars(push, deploy, no_cache).await,
|
||||||
BuildTarget::Projects => build_projects(push, deploy).await,
|
BuildTarget::Projects => build_projects(push, deploy, no_cache).await,
|
||||||
|
BuildTarget::Sol => build_sol(push, deploy, no_cache).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1730,6 +1762,7 @@ mod tests {
|
|||||||
BuildTarget::Tuwunel,
|
BuildTarget::Tuwunel,
|
||||||
BuildTarget::Calendars,
|
BuildTarget::Calendars,
|
||||||
BuildTarget::Projects,
|
BuildTarget::Projects,
|
||||||
|
BuildTarget::Sol,
|
||||||
];
|
];
|
||||||
for t in &targets {
|
for t in &targets {
|
||||||
let s = t.to_string();
|
let s = t.to_string();
|
||||||
|
|||||||
Reference in New Issue
Block a user