This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knot2 / crates / knot-pack / src / quarantine.rs
2.2 kB 72 lines
1//! The same way one would do this for uploading images onto a server, 2//! we stage pushes such that objects unpack into a separate bare repo 3//! under the incoming prefix, because we treat a push as real only once 4//! every object it referenced actually made it over. 5//! 6//! Hence aborting is as simple as removal of the directory that 7//! represents the push in flight. 8//! 9//! "Why not use `GIT_QUARANTINE_PATH`?" - because we never forked `receive-pack`. 10//! 11//! If you were wondering, this `sweep_incoming` is for a crash between a stage 12//! and migration that would otherwise leak a staging dir. 13 14use std::path::Path; 15 16use knot_git::{INCOMING_PREFIX, Repo, Staging}; 17 18use crate::error::PackError; 19use crate::meter::PackLimits; 20use crate::objects; 21 22pub(crate) struct Quarantine { 23 staging: Staging, 24} 25 26impl Quarantine { 27 pub(crate) fn stage( 28 live: &Repo, 29 pack: Option<&gix_pack::data::File>, 30 limits: &PackLimits, 31 kind: gix::hash::Kind, 32 live_empty: bool, 33 ) -> Result<(Self, Option<objects::FreshClosure>), PackError> { 34 let staging = Staging::new(live)?; 35 let (unpack, closure) = crate::receive::ingest( 36 &staging.repo().objects_dir(), 37 pack, 38 limits, 39 kind, 40 live_empty, 41 ); 42 unpack?; 43 Ok((Self { staging }, closure)) 44 } 45 46 pub(crate) fn repo(&self) -> &Repo { 47 self.staging.repo() 48 } 49 50 pub(crate) fn migrate_into(&self, live: &Repo) -> Result<(), PackError> { 51 self.staging.migrate_into(live).map_err(PackError::from) 52 } 53} 54 55pub fn sweep_incoming(scan_path: &Path) -> usize { 56 walkdir::WalkDir::new(scan_path) 57 .into_iter() 58 .filter_entry(|entry| entry.file_name().to_str() != Some("objects")) 59 .filter_map(Result::ok) 60 .filter(|entry| entry.file_type().is_dir()) 61 .filter(|entry| { 62 entry 63 .file_name() 64 .to_str() 65 .is_some_and(|name| name.starts_with(INCOMING_PREFIX)) 66 }) 67 .map(|entry| entry.into_path()) 68 .collect::<Vec<_>>() 69 .into_iter() 70 .filter(|path| std::fs::remove_dir_all(path).is_ok()) 71 .count() 72}