-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: preconditions check of disk space
- Loading branch information
Devdutt Shenoi
committed
Jan 29, 2024
1 parent
c17b8c3
commit a504c03
Showing
4 changed files
with
101 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
use std::{fs::metadata, os::unix::fs::MetadataExt, sync::Arc}; | ||
|
||
use flume::Receiver; | ||
use human_bytes::human_bytes; | ||
use log::debug; | ||
use serde::Deserialize; | ||
|
||
use crate::{base::bridge::BridgeTx, Action, ActionResponse, Config}; | ||
|
||
#[derive(thiserror::Error, Debug)] | ||
pub enum Error { | ||
#[error("File io Error: {0}")] | ||
Io(#[from] std::io::Error), | ||
#[error("Disk space is insufficient: {0}")] | ||
InsufficientDisk(String), | ||
} | ||
|
||
#[derive(Deserialize, Clone, PartialEq, Eq, Debug)] | ||
pub struct Preconditions { | ||
#[serde(alias = "content-length")] | ||
content_length: usize, | ||
#[serde(alias = "uncompressed-length")] | ||
uncompressed_length: usize, | ||
} | ||
|
||
pub struct PreconditionChecker { | ||
config: Arc<Config>, | ||
actions_rx: Receiver<Action>, | ||
bridge_tx: BridgeTx, | ||
} | ||
|
||
impl PreconditionChecker { | ||
pub fn new(config: Arc<Config>, actions_rx: Receiver<Action>, bridge_tx: BridgeTx) -> Self { | ||
Self { config, actions_rx, bridge_tx } | ||
} | ||
|
||
#[tokio::main] | ||
pub async fn start(self) { | ||
while let Ok(action) = self.actions_rx.recv() { | ||
let preconditions: Preconditions = match serde_json::from_str(&action.payload) { | ||
Ok(c) => c, | ||
Err(e) => { | ||
let response = ActionResponse::failure(&action.action_id, e.to_string()); | ||
self.bridge_tx.send_action_response(response).await; | ||
continue; | ||
} | ||
}; | ||
|
||
if let Err(e) = self.check_disk_size(preconditions) { | ||
let response = ActionResponse::failure(&action.action_id, e.to_string()); | ||
self.bridge_tx.send_action_response(response).await; | ||
continue; | ||
} | ||
|
||
let response = ActionResponse::progress(&action.action_id, "Checked OK", 100); | ||
self.bridge_tx.send_action_response(response).await; | ||
} | ||
} | ||
|
||
// Fails if there isn't enough space to download and/or install update | ||
// NOTE: both download and installation could happen in the same partition | ||
fn check_disk_size(&self, preconditions: Preconditions) -> Result<(), Error> { | ||
let disk_free_space = | ||
fs2::free_space(&self.config.precondition_checks.as_ref().unwrap().path)? as usize; | ||
let mut required_free_space = preconditions.uncompressed_length; | ||
|
||
// Check if download and installation paths are on the same partition, if yes add download file size to required | ||
if metadata(&self.config.downloader.path)?.dev() | ||
== metadata(&self.config.precondition_checks.as_ref().unwrap().path)?.dev() | ||
{ | ||
required_free_space += preconditions.content_length; | ||
} | ||
|
||
let req_size = human_bytes(required_free_space as f64); | ||
let free_size = human_bytes(disk_free_space as f64); | ||
debug!("The installation requires {req_size}; Disk free space is {free_size}"); | ||
|
||
if required_free_space > disk_free_space { | ||
return Err(Error::InsufficientDisk(free_size)); | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters