Skip to content

Commit

Permalink
Add explicit error for missing exec.d paths (#387)
Browse files Browse the repository at this point in the history
  • Loading branch information
Malax authored Mar 30, 2022
1 parent 9144aba commit 70fcf6a
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
1 change: 1 addition & 0 deletions libcnb/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Allow compilation of libcnb.rs buildpacks on Windows. Please note that this does not imply Windows container support, it's meant to allow running unit tests without cross-compiling. ([#368](https://github.com/Malax/libcnb.rs/pull/368))
- Expose `runtime::libcnb_runtime_detect`, `runtime::libcnb_runtime_build` and their related types for advanced use-cases. Buildpack authors should not use these. ([#375](https://github.com/Malax/libcnb.rs/pull/375)).
- Only create layer `env`, `env.build` and `env.launch` directories when environment variables are being set within them ([#385](https://github.com/Malax/libcnb.rs/pull/385)).
- Add `WriteLayerError::MissingExecDFile` error to ease debugging when an exec.d path is missing ([#387](https://github.com/Malax/libcnb.rs/pull/387)).

## [0.6.0] 2022-02-28

Expand Down
51 changes: 50 additions & 1 deletion libcnb/src/layer/handling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ pub enum WriteLayerError {

#[error("Error while writing layer content metadata TOML: {0}")]
TomlFileError(#[from] TomlFileError),

#[error("Cannot find exec.d file for copying: {0}")]
MissingExecDFile(PathBuf),
}

#[derive(Debug)]
Expand Down Expand Up @@ -262,7 +265,17 @@ fn write_layer<M: Serialize, P: AsRef<Path>>(
fs::create_dir_all(&exec_d_dir)?;

for (name, path) in exec_d_programs {
fs::copy(path, exec_d_dir.join(name))?;
// We could just try to copy the file here and let the call-site deal with the
// IO errors when the path does not exist. We're using an explicit error variant
// for a missing exec.d binary makes it easier to debug issues with packaging
// since the usage of exec.d binaries often relies on implicit packaging the
// buildpack author might not be aware of.
Some(&path)
.filter(|path| path.exists())
.ok_or_else(|| WriteLayerError::MissingExecDFile(path.clone()))
.and_then(|path| {
fs::copy(path, exec_d_dir.join(name)).map_err(WriteLayerError::IoError)
})?;
}
}
}
Expand Down Expand Up @@ -447,6 +460,42 @@ mod tests {
);
}

#[test]
fn write_nonexisting_layer_with_nonexisting_exec_d_path() {
let layer_name = layer_name!("foo");
let temp_dir = tempdir().unwrap();
let layers_dir = temp_dir.path();

let execd_file = PathBuf::from("/this/path/should/not/exist/exec_d_binary");
let write_layer_error = super::write_layer(
&layers_dir,
&layer_name,
&LayerEnv::new(),
&LayerContentMetadata {
types: Some(LayerTypes {
launch: true,
build: true,
cache: false,
}),
metadata: GenericMetadata::default(),
},
ExecDPrograms::Overwrite(HashMap::from([(String::from("foo"), execd_file.clone())])),
)
.unwrap_err();

match write_layer_error {
WriteLayerError::MissingExecDFile(path) => {
assert_eq!(path, execd_file);
}
other => {
panic!(
"Expected WriteLayerError::MissingExecDFile, but got {:?}",
other
);
}
};
}

#[test]
fn write_existing_layer() {
let layer_name = layer_name!("foo");
Expand Down

0 comments on commit 70fcf6a

Please sign in to comment.