-
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: precondition checks as a feature (#322)
* feat: preconditions check of disk space * Merge branch 'main' into preconditions * fix: use the right term * fix: merge
- Loading branch information
Devdutt Shenoi
authored
Feb 20, 2024
1 parent
4d0cf3b
commit 5018130
Showing
4 changed files
with
100 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
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-size")] | ||
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
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