}
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();
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
}
/// returned by start_upload
pub struct Uploading {
- instance: Arc<InstanceName>,
id: Id,
+ instance: Arc<InstanceName>,
file: DigestWrite<BufWriter<fs::File>>,
}
+/// returned by start_upload
+pub struct Uploaded {
+ id: Id,
+ file: fs::File,
+}
+
#[derive(Debug,Copy,Clone,Error)]
#[error("{0}")]
#[repr(transparent)]
impl Uploading {
#[throws(MgmtError)]
- pub fn bulk<R>(&mut self, data: &mut R)
+ pub fn bulk<R>(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);