Skip to content

Commit

Permalink
implement image pushing and --push/--no-push for build command
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Detjens <[email protected]>
  • Loading branch information
detjensrobert committed Oct 18, 2024
1 parent d5790ec commit 5ef9a9d
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 14 deletions.
43 changes: 42 additions & 1 deletion src/builder/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,48 @@ pub async fn build_image(context: &Path, options: &BuildObject, tag: &str) -> Re
}
}

Ok("".to_string())
Ok(tag.to_string())
}

#[tokio::main(flavor = "current_thread")] // make this a sync function
pub async fn push_image(image_tag: &str, creds: &UserPass) -> Result<String> {
info!("pushing image {image_tag:?} to registry");
let client = client()
.await
// truncate error chain with new error (returned error is way too verbose)
.map_err(|_| anyhow!("could not talk to Docker daemon (is DOCKER_HOST correct?)"))?;

let (image, tag) = image_tag
.rsplit_once(":")
.context("failed to get tag from full image string")?;

let opts = PushImageOptions { tag };
let creds = DockerCredentials {
username: Some(creds.user.clone()),
password: Some(creds.pass.clone()),
..Default::default()
};

let mut push_stream = client.push_image(image, Some(opts), Some(creds));

// stream output to stdout
while let Some(item) = push_stream.next().await {
match item {
// error from stream?
Err(DockerError::DockerResponseServerError {
status_code,
message,
}) => bail!("error from daemon: {message}"),
Err(e) => bail!("{e:?}"),
Ok(msg) => {
debug!("{msg:?}");
if let Some(progress) = msg.progress_detail {
info!("progress: {:?}/{:?}", progress.current, progress.total);
}
}
}
}
Ok(tag.to_string())
}

//
Expand Down
20 changes: 15 additions & 5 deletions src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ fn build_challenge_images(profile_name: &str, chal: &ChallengeConfig) -> Result<
debug!("building images for chal {:?}", chal.directory);
let config = get_config()?;

let built_tags = chal
.pods
chal.pods
.iter()
.filter_map(|p| match &p.image_source {
Image(_) => None,
Expand All @@ -72,9 +71,20 @@ fn build_challenge_images(profile_name: &str, chal: &ChallengeConfig) -> Result<
)
}
})
.collect::<Result<_>>()?;
.collect::<Result<_>>()
}

/// Push passed tags to registry
pub fn push_tags(tags: Vec<String>) -> Result<Vec<String>> {
let config = get_config()?;

trace!("built these images: {built_tags:?}");
let built_tags = tags
.iter()
.map(|tag| {
push_image(tag, &config.registry.build)
.with_context(|| format!("error pushing image {tag}"))
})
.collect::<Result<_>>()?;

return Ok(built_tags);
Ok(built_tags)
}
11 changes: 7 additions & 4 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ pub enum Commands {
/// Deployment profile
#[arg(short, long, value_name = "PROFILE")]
profile: String,

/// Whether to push container images to registry (default: true)
/// Push container images to registry (default: true)
#[arg(long, default_value = "true")]
// TODO: no way to actually set False...
// maybe revisit when negation flags are implemented: https://github.com/clap-rs/clap/issues/815
push: bool,

/// Don't push container images to registry
#[arg(long, default_value = "false")]
no_push: bool,
// TODO: this is hacky. revisit when automatic negation flags are implemented:
// https://github.com/clap-rs/clap/issues/815
},

/// Deploy enabled challenges to cluster, updating any backing resources as necessary.
Expand Down
14 changes: 13 additions & 1 deletion src/commands/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use simplelog::*;
use std::process::exit;

use crate::builder::build_challenges;
use crate::builder::{build_challenges, push_tags};
use crate::configparser::{get_config, get_profile_config};

pub fn run(profile_name: &str, push: &bool) {
Expand All @@ -15,4 +15,16 @@ pub fn run(profile_name: &str, push: &bool) {
}
};
info!("images built successfully!");

if *push {
info!("pushing images...");

match push_tags(tags) {
Ok(_) => info!("images pushed successfully!"),
Err(e) => {
error!("{e:?}");
exit(1)
}
}
};
}
9 changes: 7 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@ fn main() {
commands::check_access::run(profile, kubernetes, frontend, registry)
}

cli::Commands::Build { profile, push } => {
#[allow(unused_variables)]
cli::Commands::Build {
profile,
push,
no_push,
} => {
commands::validate::run();
commands::build::run(profile, push)
commands::build::run(profile, &!no_push)
}

cli::Commands::Deploy {
Expand Down
2 changes: 1 addition & 1 deletion tests/repo/rcds.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
flag_regex: dam{[a-zA-Z...]}

registry:
domain: registry.localhost:5000/damctf
domain: localhost:5000/damctf
# then environment variables e.g. REG_USER/REG_PASS
build:
user: admin
Expand Down

0 comments on commit 5ef9a9d

Please sign in to comment.