From: Ian Jackson Date: Sun, 9 May 2021 23:54:46 +0000 (+0100) Subject: bundles: Split Uploaded out X-Git-Tag: otter-0.6.0~363 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=179164f845f6cf1f577130416cda51398cf77b9b;p=otter.git bundles: Split Uploaded out Signed-off-by: Ian Jackson --- diff --git a/daemon/cmdlistener.rs b/daemon/cmdlistener.rs index 231bf66d..e207be3d 100644 --- a/daemon/cmdlistener.rs +++ b/daemon/cmdlistener.rs @@ -220,7 +220,7 @@ fn execute_and_respond(cs: &mut CommandStreamData, cmd: MgmtCommand, } MC::UploadBundle { game, hash, kind } => { - let (mut upload, auth) = { + let (upload, auth) = { let ag = AccountsGuard::lock(); let gref = Instance::lookup_by_name_unauth(&game)?; let bundles = gref.lock_bundles(); @@ -231,12 +231,12 @@ fn execute_and_respond(cs: &mut CommandStreamData, cmd: MgmtCommand, let upload = bundles.start_upload(ig, kind)?; (upload, auth) }; - upload.bulk(&mut bulk_upload)?; + let uploaded = upload.bulk(&mut bulk_upload, &hash)?; { let gref = Instance::lookup_by_name(&game, auth)?; let mut bundles = gref.lock_bundles(); let mut ig = gref.lock()?; - bundles.finish_upload(&mut ig, upload, &hash)?; + bundles.finish_upload(&mut ig, uploaded)?; }; Fine } diff --git a/src/bundles.rs b/src/bundles.rs index 800bad04..dc40f20f 100644 --- a/src/bundles.rs +++ b/src/bundles.rs @@ -48,11 +48,17 @@ pub struct Loaded { /// returned by start_upload pub struct Uploading { - instance: Arc, id: Id, + instance: Arc, file: DigestWrite>, } +/// returned by start_upload +pub struct Uploaded { + id: Id, + file: fs::File, +} + #[derive(Debug,Copy,Clone,Error)] #[error("{0}")] #[repr(transparent)] @@ -526,26 +532,32 @@ impl InstanceBundles { impl Uploading { #[throws(MgmtError)] - pub fn bulk(&mut self, data: &mut R) + pub fn bulk(self, data: &mut R, expected: &Hash) -> Uploaded where R: Read { - io::copy(data, &mut self.file) - .with_context(|| self.id.path_tmp(&*self.instance)) - .context("copy").map_err(IE::from)? + let Uploading { id, mut file, instance } = self; + let tmp = id.path_tmp(&instance); + + io::copy(data, &mut file) + .with_context(|| tmp.clone()) + .context("copy").map_err(IE::from)?; + + let (hash, file) = file.finish(); + + let file = file.into_inner().map_err(|e| e.into_error()) + .with_context(|| tmp.clone()).context("flush").map_err(IE::from)?; + if hash.as_slice() != &expected.0[..] { throw!(ME::UploadCorrupted) } + + Uploaded { id, file } } } impl InstanceBundles { #[throws(MgmtError)] pub fn finish_upload(&mut self, ig: &mut Instance, - Uploading { instance:_, id, file }: Uploading, - expected: &Hash) { - let (hash, file) = file.finish(); + Uploaded { id, mut file }: Uploaded) { let tmp = id.path_tmp(&ig.name); let install = id.path_(&ig.name); - let mut file = file.into_inner().map_err(|e| e.into_error()) - .with_context(|| tmp.clone()).context("flush").map_err(IE::from)?; - if hash.as_slice() != &expected.0[..] { throw!(ME::UploadCorrupted) } file.rewind().context("rewind"). map_err(IE::from)?; let mut file = BufReader::new(file);