Skip to content

Commit

Permalink
Update metrics buildpack to use new build output
Browse files Browse the repository at this point in the history
  • Loading branch information
schneems committed Sep 26, 2023
1 parent f4ff547 commit 5155a44
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 42 deletions.
29 changes: 14 additions & 15 deletions buildpacks/ruby/src/layers/metrics_agent_install.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::build_output;
use crate::{RubyBuildpack, RubyBuildpackError};
use commons::output::section_log::{log_step, log_step_timed, SectionLogger};
use flate2::read::GzDecoder;
use libcnb::data::layer_content_metadata::LayerTypes;
use libcnb::layer::ExistingLayerStrategy;
Expand Down Expand Up @@ -30,8 +30,8 @@ const DOWNLOAD_URL: &str =
const DOWNLOAD_SHA: &str = "f9bf9f33c949e15ffed77046ca38f8dae9307b6a0181c6af29a25dec46eb2dac";

#[derive(Debug)]
pub(crate) struct MetricsAgentInstall {
pub(crate) section: build_output::Section,
pub(crate) struct MetricsAgentInstall<'a> {
pub _in_section: &'a dyn SectionLogger, // force the layer to be called within a Section logging context, not necessary but it's safer
}

#[derive(Deserialize, Serialize, Debug, Clone)]
Expand Down Expand Up @@ -64,7 +64,7 @@ pub(crate) enum MetricsAgentInstallError {
ChecksumFailed(String),
}

impl Layer for MetricsAgentInstall {
impl<'a> Layer for MetricsAgentInstall<'a> {
type Buildpack = RubyBuildpack;
type Metadata = Metadata;

Expand All @@ -86,12 +86,11 @@ impl Layer for MetricsAgentInstall {
> {
let bin_dir = layer_path.join("bin");

let mut timer = self.section.say_with_inline_timer("Downloading");
let agentmon = install_agentmon(&bin_dir).map_err(RubyBuildpackError::MetricsAgentError)?;

timer.done();
let agentmon = log_step_timed("Downloading", || {
install_agentmon(&bin_dir).map_err(RubyBuildpackError::MetricsAgentError)
})?;

self.section.say("Writing scripts");
log_step("Writing scripts");
let execd = write_execd_script(&agentmon, layer_path)
.map_err(RubyBuildpackError::MetricsAgentError)?;

Expand All @@ -112,7 +111,7 @@ impl Layer for MetricsAgentInstall {
> {
let layer_path = &layer_data.path;

self.section.say("Writing scripts");
log_step("Writing scripts");
let execd = write_execd_script(&layer_path.join("bin").join("agentmon"), layer_path)
.map_err(RubyBuildpackError::MetricsAgentError)?;

Expand All @@ -131,12 +130,13 @@ impl Layer for MetricsAgentInstall {
{
match &layer_data.content_metadata.metadata.download_url {
Some(url) if url == DOWNLOAD_URL => {
self.section.say("Using cached metrics agent");
log_step("Using cached metrics agent");
Ok(ExistingLayerStrategy::Update)
}
Some(url) => {
self.section
.say_with_details("Updating metrics agent", format!("{url} to {DOWNLOAD_URL}"));
log_step(format!(
"Using cached metrics agent ({url} to {DOWNLOAD_URL}"
));
Ok(ExistingLayerStrategy::Recreate)
}
None => Ok(ExistingLayerStrategy::Recreate),
Expand All @@ -151,8 +151,7 @@ impl Layer for MetricsAgentInstall {
libcnb::layer::MetadataMigration<Self::Metadata>,
<Self::Buildpack as libcnb::Buildpack>::Error,
> {
self.section
.say_with_details("Clearing cache", "invalid metadata");
log_step("Clearing cache (invalid metadata)");

Ok(libcnb::layer::MetadataMigration::RecreateLayer)
}
Expand Down
43 changes: 26 additions & 17 deletions buildpacks/ruby/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
#![warn(unused_crate_dependencies)]
#![warn(clippy::pedantic)]
#![allow(clippy::module_name_repetitions)]
use crate::layers::metrics_agent_install::{MetricsAgentInstall, MetricsAgentInstallError};
use crate::layers::{RubyInstallError, RubyInstallLayer};
use commons::cache::CacheError;
use commons::fun_run::CmdError;
use commons::gemfile_lock::GemfileLock;
use commons::metadata_digest::MetadataDigest;
use commons::output::warn_later::WarnGuard;
use core::str::FromStr;
use layers::{
bundle_download_layer::BundleDownloadLayer, bundle_download_layer::BundleDownloadLayerMetadata,
bundle_install_layer::BundleInstallLayer, bundle_install_layer::BundleInstallLayerMetadata,
ruby_install_layer::RubyInstallError, ruby_install_layer::RubyInstallLayer,
ruby_install_layer::RubyInstallLayerMetadata,
bundle_download_layer::{BundleDownloadLayer, BundleDownloadLayerMetadata},
bundle_install_layer::{BundleInstallLayer, BundleInstallLayerMetadata},
metrics_agent_install::{MetricsAgentInstall, MetricsAgentInstallError},
ruby_install_layer::{RubyInstallError, RubyInstallLayer, RubyInstallLayerMetadata},
};
use libcnb::build::{BuildContext, BuildResult, BuildResultBuilder};
use libcnb::data::build_plan::BuildPlanBuilder;
Expand Down Expand Up @@ -92,17 +90,28 @@ impl Buildpack for RubyBuildpack {
let ruby_version = gemfile_lock.resolve_ruby("3.1.3");

// ## Install metrics agent
let section = build_output::section("Metrics agent");
if lockfile_contents.contains("barnes") {
context.handle_layer(
layer_name!("metrics_agent"),
MetricsAgentInstall { section },
)?;
} else {
section.say_with_details(
"Skipping install",
"`gem 'barnes'` not found in Gemfile.lock",
);
(logger, env) = {
let section = logger.section("Metrics agent");
if lockfile_contents.contains("barnes") {
let layer_data = context.handle_layer(
layer_name!("metrics_agent"),
MetricsAgentInstall {
_in_section: section.as_ref(),
},
)?;

(
section.end_section(),
layer_data.env.apply(Scope::Build, &env),
)
} else {
(
section
.step("Skipping install (`gem 'barnes'` not found in Gemfile.lock)")
.end_section(),
env,
)
}
};

// ## Install executable ruby version
Expand Down
12 changes: 12 additions & 0 deletions buildpacks/ruby/src/user_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,18 @@ fn log_our_error(mut log: Box<dyn StartedLogger>, error: RubyBuildpackError) {
Use the information above to debug further.
"});
}
RubyBuildpackError::MetricsAgentError(error) => {
log.section(DEBUG_INFO)
.step(&error.to_string())
.end_section()
.announce()
.error(&formatdoc! {"
Error: Could not install Statsd agent
An error occured while downloading and installing the metrics agent
the buildpack cannot continue.
"});
}
}
}

Expand Down
15 changes: 5 additions & 10 deletions buildpacks/ruby/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use libcnb_test::{
};
use std::thread;
use std::time::{Duration, Instant};
use thiserror::__private::DisplayAsDisplay;
use ureq::Response;

#[test]
Expand Down Expand Up @@ -174,29 +173,25 @@ fn call_root_until_boot(
) -> Result<Response, Box<ureq::Error>> {
let mut count = 0;
let max_time = 10.0_f64; // Seconds
let sleep = 0.1_f64;
let sleep_for = 0.1_f64;

#[allow(clippy::cast_possible_truncation)]
let max_count = (max_time / sleep).floor() as i64;
let max_count = (max_time / sleep_for).floor() as i64;
let mut response = request_container(container, port, "");
while count < max_count {
count += 1;
match response {
Err(ref box_e) => match box_e.as_ref() {
ureq::Error::Transport(e) => {
println!(
"Waiting for connection {}, retrying in {}",
e.as_display(),
sleep
);
ureq::Error::Transport(error) => {
println!("Waiting for connection {error}, retrying in {sleep_for}");
response = request_container(container, port, "");
}
ureq::Error::Status(..) => break,
},
_ => break,
}

thread::sleep(frac_seconds(sleep));
thread::sleep(frac_seconds(sleep_for));
}

println!(
Expand Down

0 comments on commit 5155a44

Please sign in to comment.