Skip to content

Commit 994c08d

Browse files
authored
Merge pull request #1179 from input-output-hk/jpraynaud/1160-fix-verify-archive-snapshotter
Fix verify archive in aggregator Snapshotter
2 parents 6e110c2 + c9265a0 commit 994c08d

File tree

3 files changed

+58
-10
lines changed

3 files changed

+58
-10
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mithril-aggregator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-aggregator"
3-
version = "0.3.75"
3+
version = "0.3.76"
44
description = "A Mithril Aggregator server"
55
authors = { workspace = true }
66
edition = { workspace = true }

mithril-aggregator/src/snapshotter.rs

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ use flate2::Compression;
22
use flate2::{read::GzDecoder, write::GzEncoder};
33
use mithril_common::StdResult;
44
use slog_scope::{info, warn};
5-
use std::fs::File;
6-
use std::io::{self, Seek, SeekFrom};
5+
use std::fs::{self, File};
6+
use std::io::{self, Read, Seek, SeekFrom};
77
use std::path::{Path, PathBuf};
88
use std::sync::RwLock;
9-
use tar::Archive;
9+
use tar::{Archive, Entry, EntryType};
1010
use thiserror::Error;
1111

1212
use crate::dependency_injection::DependenciesBuilderError;
@@ -57,6 +57,10 @@ pub enum SnapshotError {
5757
#[error("Invalid archive error: {0}")]
5858
InvalidArchiveError(String),
5959

60+
/// Set when the snapshotter fails verifying a snapshot.
61+
#[error("Archive verification error: {0}")]
62+
VerifyArchiveError(String),
63+
6064
/// Set when the snapshotter fails at uploading the snapshot.
6165
#[error("Upload file error: `{0}`")]
6266
UploadFileError(String),
@@ -165,12 +169,56 @@ impl GzipSnapshotter {
165169
let snapshot_file_tar = GzDecoder::new(snapshot_file_tar_gz);
166170
let mut snapshot_archive = Archive::new(snapshot_file_tar);
167171

168-
match snapshot_archive.entries()?.find(|e| e.is_err()) {
169-
Some(Err(e)) => Err(SnapshotError::InvalidArchiveError(format!(
170-
"invalid entry with error: '{e:?}'"
171-
))),
172-
_ => Ok(()),
172+
let unpack_temp_dir = std::env::temp_dir().join("mithril_snapshotter_verify_archive");
173+
if unpack_temp_dir.exists() {
174+
fs::remove_dir_all(&unpack_temp_dir)
175+
.map_err(|e| SnapshotError::VerifyArchiveError(e.to_string()))?;
176+
}
177+
fs::create_dir_all(&unpack_temp_dir)
178+
.map_err(|e| SnapshotError::VerifyArchiveError(e.to_string()))?;
179+
let unpack_temp_file = &unpack_temp_dir.join("unpack.tmp");
180+
181+
for e in snapshot_archive.entries()? {
182+
match e {
183+
Err(e) => {
184+
return Err(SnapshotError::InvalidArchiveError(format!(
185+
"invalid entry with error: '{:?}'",
186+
e
187+
)))
188+
}
189+
Ok(entry) => Self::unpack_and_delete_file_from_entry(entry, unpack_temp_file)?,
190+
}
191+
}
192+
193+
Ok(())
194+
}
195+
196+
// Helper to unpack and delete a file from en entry, for archive verification purpose
197+
fn unpack_and_delete_file_from_entry<R: Read>(
198+
entry: Entry<R>,
199+
unpack_file_path: &Path,
200+
) -> Result<(), SnapshotError> {
201+
if entry.header().entry_type() != EntryType::Directory {
202+
let mut file = entry;
203+
match file.unpack(unpack_file_path) {
204+
Err(e) => {
205+
return Err(SnapshotError::InvalidArchiveError(format!(
206+
"can't unpack entry with error: '{:?}'",
207+
e
208+
)))
209+
}
210+
Ok(_) => {
211+
if let Err(e) = fs::remove_file(unpack_file_path) {
212+
return Err(SnapshotError::VerifyArchiveError(format!(
213+
"can't remove temporary unpacked file with error: '{:?}'",
214+
e
215+
)));
216+
}
217+
}
218+
}
173219
}
220+
221+
Ok(())
174222
}
175223
}
176224

0 commit comments

Comments
 (0)