SHA256
Changes to snapshot /usr and /var subvolumes instead of root, regex-lite adoption, and initial documentation
This commit is contained in:
+2
-12
@@ -62,7 +62,8 @@ pub struct HiveDb {
|
||||
pub update_check_timestamp: u64,
|
||||
/// non zero if there is updates that can bee applied, showing numbers of packages that can be updated
|
||||
pub updates_available: u32,
|
||||
/// true if last update fas successful
|
||||
/// true if last update was successful
|
||||
/// if it is false - nyanit need to roll back snapshots
|
||||
pub update_status: bool,
|
||||
/// datetime of last snapshot in format "%Y-%m-%dT%H:%M:%S"
|
||||
pub last_snapshot_time: String,
|
||||
@@ -101,15 +102,4 @@ pub fn write_db(db: &HiveDb) -> Result<(), DBError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///
|
||||
/// writes new last update check time to db
|
||||
/// and returns old db value on success
|
||||
///
|
||||
pub fn update_last_check_update_time(new_timestamp: u64) -> Result<u64, DBError> {
|
||||
let mut db = read_db()?;
|
||||
let old_value = db.update_check_timestamp;
|
||||
db.update_check_timestamp = new_timestamp;
|
||||
write_db(&db)?;
|
||||
Ok(old_value)
|
||||
}
|
||||
|
||||
|
||||
+81
-63
@@ -184,12 +184,31 @@ pub fn pkg_upgrade() -> Result<(), ExecCommandError> {
|
||||
exec_command("pacman", &vec!["-Su", "--noconfirm", "--noprogressbar"])
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// bcachefs subvolume snapshot -r / /snap1
|
||||
/// creates read only snapshoy of "subvolume" and places it into "target"]
|
||||
/// bcachefs subvolume snapshot -r /subvolume /target
|
||||
/// -r creates read only snapshot
|
||||
/// returns snapshot time on sucess
|
||||
///
|
||||
pub fn snapshot_root() -> Result<String, ExecCommandError> {
|
||||
pub fn snapshot(subvolume: &str, target: &str) -> Result<(), ExecCommandError> {
|
||||
|
||||
exec_command(
|
||||
"bcachefs",
|
||||
&vec!["subvolume", "snapshot", "-r", subvolume, target],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
/// bcachefs subvolume snapshot -r /target /SNAPS_DIR/bzz-target-yyyy-mm-ddTHH-MM-SS
|
||||
/// Creates read only snapshots of /usr and /var subvolumes
|
||||
/// And places them to /SNAPS_DIR/bzz-usr-yyyy-mm-ddTHH-MM-SS and /SNAPS_DIR/bzz-var-yyyy-mm-ddTHH-MM-SS
|
||||
/// returns snapshot time on sucess
|
||||
///
|
||||
pub fn snapshot_system() -> Result<String, ExecCommandError> {
|
||||
use std::path::Path;
|
||||
// if snaps dir path do not exist - create it
|
||||
let snaps_path = Path::new(SNAPS_DIR);
|
||||
@@ -199,43 +218,42 @@ pub fn snapshot_root() -> Result<String, ExecCommandError> {
|
||||
|
||||
let ts = time_format::now().unwrap();
|
||||
let local_time = time_format::strftime_local("%Y-%m-%dT%H:%M:%S", ts).unwrap();
|
||||
let snapshot_name = format!("{}/bzz-{}", SNAPS_DIR, local_time);
|
||||
let usr_snapshot_name = format!("{}/bzz-usr-{}", SNAPS_DIR, local_time);
|
||||
let var_snapshot_name = format!("{}/bzz-var-{}", SNAPS_DIR, local_time);
|
||||
|
||||
exec_command(
|
||||
"bcachefs",
|
||||
&vec!["subvolume", "snapshot", "-r", "/", &snapshot_name],
|
||||
)?;
|
||||
snapshot("/usr", &usr_snapshot_name)?;
|
||||
snapshot("/var", &var_snapshot_name)?;
|
||||
|
||||
Ok(local_time)
|
||||
}
|
||||
|
||||
//const TMP_ROOT: &str = "/mnt/bee-root";
|
||||
pub fn list_bzzpss_snaps() -> Result<Vec<String>, ExecCommandError> {
|
||||
use regex::Regex;
|
||||
use std::path::Path;
|
||||
// pub fn list_bzzpss_snaps() -> Result<Vec<String>, ExecCommandError> {
|
||||
// use regex::Regex;
|
||||
// use std::path::Path;
|
||||
|
||||
// root snapshoot in a form of bzz-yyyy-mm-ddTHH-MM-SS
|
||||
let re = Regex::new(r"^bzz-[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}-[0-9]{2}-[0-9]{2}$").unwrap();
|
||||
// // root snapshoot in a form of bzz-yyyy-mm-ddTHH-MM-SS
|
||||
// let re = Regex::new(r"^bzz-[a-z]+-[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}-[0-9]{2}-[0-9]{2}$").unwrap();
|
||||
|
||||
let mut res: Vec<String> = Vec::new();
|
||||
// if snaps dir path do not exist return empty list
|
||||
if !Path::new(SNAPS_DIR).exists() {
|
||||
return Ok(res);
|
||||
}
|
||||
// let mut res: Vec<String> = Vec::new();
|
||||
// // if snaps dir path do not exist return empty list
|
||||
// if !Path::new(SNAPS_DIR).exists() {
|
||||
// return Ok(res);
|
||||
// }
|
||||
|
||||
for maybe_entry in fs::read_dir(SNAPS_DIR)? {
|
||||
let entry = maybe_entry?;
|
||||
if entry.file_type()?.is_dir() {
|
||||
if let Some(dir_name) = entry.file_name().to_str()
|
||||
&& re.is_match(dir_name)
|
||||
{
|
||||
res.push(dir_name.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
res.sort();
|
||||
Ok(res)
|
||||
}
|
||||
// for maybe_entry in fs::read_dir(SNAPS_DIR)? {
|
||||
// let entry = maybe_entry?;
|
||||
// if entry.file_type()?.is_dir() {
|
||||
// if let Some(dir_name) = entry.file_name().to_str()
|
||||
// && re.is_match(dir_name)
|
||||
// {
|
||||
// res.push(dir_name.to_string());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// res.sort();
|
||||
// Ok(res)
|
||||
// }
|
||||
|
||||
pub fn check_if_run_as_root() -> bool {
|
||||
use nix::unistd::Uid;
|
||||
@@ -271,7 +289,7 @@ impl std::error::Error for SysUpgradeError {}
|
||||
///
|
||||
pub fn sys_upgrade() -> Result<String, SysUpgradeError> {
|
||||
// snapshooting root
|
||||
let snap_time = snapshot_root().map_err(SysUpgradeError::SnapshotError)?;
|
||||
let snap_time = snapshot_system().map_err(SysUpgradeError::SnapshotError)?;
|
||||
// try to perform packages upgrade
|
||||
match pkg_upgrade() {
|
||||
Ok(_) => Ok(snap_time),
|
||||
@@ -281,37 +299,37 @@ pub fn sys_upgrade() -> Result<String, SysUpgradeError> {
|
||||
|
||||
/// Gets device node aka /dev/sda1 from gpr partition label
|
||||
/// blkid -s PARTLABEL --match-token PARTLABEL="bzz-primary"
|
||||
pub fn find_partlabel(partlabel: &str) -> Result<Option<String>, ExecCommandError> {
|
||||
let out = Command::new("/usr/bin/blkid")
|
||||
.args([
|
||||
"-s",
|
||||
"PARTLABEL",
|
||||
"-t",
|
||||
format!("PARTLABEL=\"{}\"", partlabel).as_str(),
|
||||
])
|
||||
.output()?;
|
||||
if out.status.success() {
|
||||
let out_text = String::from_utf8(out.stdout)?;
|
||||
// pub fn find_partlabel(partlabel: &str) -> Result<Option<String>, ExecCommandError> {
|
||||
// let out = Command::new("/usr/bin/blkid")
|
||||
// .args([
|
||||
// "-s",
|
||||
// "PARTLABEL",
|
||||
// "-t",
|
||||
// format!("PARTLABEL=\"{}\"", partlabel).as_str(),
|
||||
// ])
|
||||
// .output()?;
|
||||
// if out.status.success() {
|
||||
// let out_text = String::from_utf8(out.stdout)?;
|
||||
|
||||
let split_res = out_text.split_once(':').ok_or_else(|| {
|
||||
ExecCommandError::Other(format!("Unexpected blkid output format: \"{}\"", out_text))
|
||||
})?;
|
||||
// let split_res = out_text.split_once(':').ok_or_else(|| {
|
||||
// ExecCommandError::Other(format!("Unexpected blkid output format: \"{}\"", out_text))
|
||||
// })?;
|
||||
|
||||
Ok(Some(split_res.0.to_string()))
|
||||
} else {
|
||||
if let Some(code) = out.status.code()
|
||||
&& code == 2
|
||||
{
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(ExecCommandError::Other(format!(
|
||||
"Error while looking for partlabel={}: \"{}\"",
|
||||
partlabel,
|
||||
String::from_utf8(out.stderr).unwrap_or_else(|ex| ex.to_string())
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ok(Some(split_res.0.to_string()))
|
||||
// } else {
|
||||
// if let Some(code) = out.status.code()
|
||||
// && code == 2
|
||||
// {
|
||||
// Ok(None)
|
||||
// } else {
|
||||
// Err(ExecCommandError::Other(format!(
|
||||
// "Error while looking for partlabel={}: \"{}\"",
|
||||
// partlabel,
|
||||
// String::from_utf8(out.stderr).unwrap_or_else(|ex| ex.to_string())
|
||||
// )))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
///
|
||||
/// We need to use lsblk to find out parent device, or read topology from sysfs
|
||||
@@ -327,7 +345,7 @@ pub fn find_partlabel(partlabel: &str) -> Result<Option<String>, ExecCommandErro
|
||||
///
|
||||
///
|
||||
fn get_efi_part_info() -> Result<(String, String), ExecCommandError> {
|
||||
use regex::Regex;
|
||||
use regex_lite::Regex;
|
||||
let re = Regex::new(r#"^PARTN="([0-9]+)" PKNAME="([0-9a-Z]+)"$"#).unwrap();
|
||||
|
||||
let lsblk_query = format!("PARTLABEL==\"{}\"", EFI_PARTLABEL);
|
||||
@@ -351,7 +369,7 @@ fn get_efi_part_info() -> Result<(String, String), ExecCommandError> {
|
||||
/// Boot0000* Nyan
|
||||
///
|
||||
fn list_efi_bootnums() -> Result<Vec<String>, ExecCommandError> {
|
||||
use regex::Regex;
|
||||
use regex_lite::Regex;
|
||||
let re = Regex::new(r#"^Boot([0-9A-F]{4})\* "#).unwrap();
|
||||
let str_res = exec_command_out("efibootmgr", &vec![])?;
|
||||
|
||||
@@ -444,7 +462,7 @@ pub fn init_efi_boot_record(maybe_kernel_cmd: &Option<String>) -> Result<(), Exe
|
||||
/// Result is a sorted vector of string
|
||||
///
|
||||
fn list_installed_kernels() -> Result<Vec<String>, ExecCommandError> {
|
||||
use regex::Regex;
|
||||
use regex_lite::Regex;
|
||||
|
||||
let re = Regex::new(r#"^[0-9]+\.[0-9]+\.[0-9]+-[0-9]-kira-lts"#).unwrap();
|
||||
let mut kernel_dirs: Vec<String> = Vec::new();
|
||||
|
||||
+4
-1
@@ -163,8 +163,11 @@ struct Cli {
|
||||
|
||||
fn cli_upgrade(bzz_config: HiveConfig) -> Result<(), HiveUpError> {
|
||||
let mut bzz_db = hive_db::read_db()?;
|
||||
if bzz_db.update_on_reboot || bzz_config.update.auto_update {
|
||||
|
||||
if (bzz_db.updates_available !=0) && (bzz_db.update_on_reboot || bzz_config.update.auto_update) {
|
||||
println!("Starting full system upgrade");
|
||||
bzz_db.update_status = false;
|
||||
hive_db::write_db(&bzz_db)?;
|
||||
match hive_system::sys_upgrade() {
|
||||
Ok(snap_time) => {
|
||||
bzz_db.update_status = true;
|
||||
|
||||
Reference in New Issue
Block a user