diff options
author | Matthias Beyer <matthias.beyer@atos.net> | 2021-04-12 18:43:04 +0200 |
---|---|---|
committer | Matthias Beyer <matthias.beyer@atos.net> | 2021-04-12 19:34:36 +0200 |
commit | 3537f8e1d174f2ce422c9024a9e0d6df87ad9207 (patch) | |
tree | c400711ba25cbf376c09795c0d503ef82fc7f9b4 | |
parent | b167c4a13f467ea271351b51b2d331f4fb96f95d (diff) |
Filter out the /outputs/ directory
The issue here is that we copy all build results (packages) in the container to
/outputs and then butido uses that directory to fetch the outputs of the build.
But, because how the docker API works, we get a TAR stream from docker that
_contains_ the /outputs directory. But of course, we don't want that.
Until now, that was no issue. But it has become one now that we start adopting
butido for our real-world scenarios.
This patch adds filtering out that /outputs portion of the pathes from the tar
archive when writing all the things to disc.
Signed-off-by: Matthias Beyer <matthias.beyer@atos.net>
Tested-by: Matthias Beyer <matthias.beyer@atos.net>
-rw-r--r-- | doc/containers.md | 2 | ||||
-rw-r--r-- | src/consts.rs | 1 | ||||
-rw-r--r-- | src/filestore/path.rs | 30 | ||||
-rw-r--r-- | src/filestore/staging.rs | 29 |
4 files changed, 52 insertions, 10 deletions
diff --git a/doc/containers.md b/doc/containers.md index cbb62a0..52f4b4a 100644 --- a/doc/containers.md +++ b/doc/containers.md @@ -15,7 +15,7 @@ on. Those are listed here. 1. Dependencies are named `/inputs/<packagename>-<packageversion>.pkg` inside the container 2. Sources are named `/inputs/src-<hashsum>.source` -3. Outputs are expected to be named `/outputs/<packagename>-<packageversion>.pkg` +3. Outputs are expected to be written to the `/outputs` directory The reason for the names lies in the artifact parsing mechanism. If the package is named differently, the artifact parsing mechanism is not able diff --git a/src/consts.rs b/src/consts.rs index 8891f81..5c6dbc4 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -16,6 +16,7 @@ pub const INPUTS_DIR_PATH: &str = "/inputs"; /// The path to the directory inside the container where the outputs of a compile job must be /// located after the script was run pub const OUTPUTS_DIR_PATH: &str = "/outputs"; +pub const OUTPUTS_DIR_NAME: &str = "outputs"; /// The path where the script that is executed inside the container is copied to. pub const SCRIPT_PATH: &str = "/script"; diff --git a/src/filestore/path.rs b/src/filestore/path.rs index e8c7a26..3d74992 100644 --- a/src/filestore/path.rs +++ b/src/filestore/path.rs @@ -92,7 +92,35 @@ impl StoreRoot { where R: std::io::Read, { - ar.unpack(&self.0).map_err(Error::from) + ar.entries()? + .into_iter() + .map_err(Error::from) + .filter_ok(|entry| entry.header().entry_type() == tar::EntryType::Regular) + .and_then_ok(|mut entry| -> Result<_> { + let path = entry + .path() + .context("Getting path from entry in Archive")? + .components() + .filter(|comp| { + log::trace!("Filtering path component: '{:?}'", comp); + let osstr = std::ffi::OsStr::new(crate::consts::OUTPUTS_DIR_NAME); + match comp { + std::path::Component::Normal(s) => *s != osstr, + _ => true, + } + }) + .collect::<PathBuf>(); + + log::trace!("Path = '{:?}'", path); + let unpack_dest = self.0.join(path); + log::trace!("Unpack to = '{:?}'", unpack_dest); + + entry.unpack(unpack_dest) + .map(|_| ()) + .map_err(Error::from) + }) + .collect::<Result<Vec<_>>>() + .map(|_| ()) } } diff --git a/src/filestore/staging.rs b/src/filestore/staging.rs index 73701cd..9f60d32 100644 --- a/src/filestore/staging.rs +++ b/src/filestore/staging.rs @@ -17,6 +17,9 @@ use anyhow::anyhow; use futures::stream::Stream; use indicatif::ProgressBar; use log::trace; +use resiter::AndThen; +use resiter::Filter; +use resiter::Map; use result_inspect::ResultInspect; use crate::filestore::path::ArtifactPath; @@ -54,15 +57,25 @@ impl StagingStore { .and_then(|bytes| { let mut archive = tar::Archive::new(&bytes[..]); - let outputs = archive - .entries() - .context("Fetching entries from tar archive")? - .map(|ent| { - let p = ent? + let outputs = archive.entries()? + .map_err(Error::from) + .filter_ok(|entry| entry.header().entry_type() == tar::EntryType::Regular) + .and_then_ok(|entry| { + let entry = entry .path() - .context("Getting path of TAR entry")? - .into_owned(); - Ok(p) + .context("Getting path from entry in Archive")? + .components() + .filter(|comp| { + log::trace!("Filtering path component: '{:?}'", comp); + let osstr = std::ffi::OsStr::new(crate::consts::OUTPUTS_DIR_NAME); + match comp { + std::path::Component::Normal(s) => *s != osstr, + _ => true, + } + }) + .collect::<std::path::PathBuf>(); + + Ok(entry) }) .inspect(|p| trace!("Path in tar archive: {:?}", p)) .collect::<Result<Vec<_>>>() |