SHA256
Compare commits
5
Commits
c61d283177
..
v0.1.1
| Author | SHA256 | Date | |
|---|---|---|---|
|
|
17cea4b89e | ||
|
|
605faa3c19 | ||
|
|
8865fde77c | ||
|
|
03bd83d1e2 | ||
|
|
f35c274e50 |
Generated
+9
-9
@@ -220,7 +220,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hive-up"
|
name = "hive-up"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"nix",
|
"nix",
|
||||||
@@ -235,9 +235,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.14.0"
|
version = "2.14.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
checksum = "07aa2048142242915a31d35844fb311e0e53fcca590c3a0a40dcf1b841fa09eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
@@ -470,9 +470,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "3.0.3"
|
version = "3.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
|
checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -501,15 +501,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time-format"
|
name = "time-format"
|
||||||
version = "1.2.2"
|
version = "1.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "caa08af685f978227b475da86d38312cd1acd5024338bf53a1ab9a799219507d"
|
checksum = "fb54c799611991d3d4a66fee3ff17b9f600c2a0f8c0d34e8209dbd153ff0a87b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "1.1.4+spec-1.1.0"
|
version = "1.1.5+spec-1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5"
|
checksum = "12c0ba9680044b4ce98d391a62094047eada0d64860b80166c39f4a6b5640785"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
|
|||||||
+12
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "hive-up"
|
name = "hive-up"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -13,3 +13,14 @@ serde_json = "1.0"
|
|||||||
signal-hook = "0.4"
|
signal-hook = "0.4"
|
||||||
time-format = "1.2"
|
time-format = "1.2"
|
||||||
toml = "1.1"
|
toml = "1.1"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
debug = false
|
||||||
|
incremental = false
|
||||||
|
codegen-units = 1
|
||||||
|
opt-level = 2
|
||||||
|
strip = true
|
||||||
|
|
||||||
|
[registry]
|
||||||
|
global-min-publish-age = "14 days"
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[Trigger]
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Type = Package
|
||||||
|
Target = linux-kira-lts
|
||||||
|
Target = linux-kira-virt-lts
|
||||||
|
Target = linux-kira-server-lts
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Running custom command after kernel update
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/hive-up cli --update-boot
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
type = process
|
||||||
|
command = /usr/bin/hive-up daemon
|
||||||
|
stop-command = /usr/bin/hive-up cli --upgrade
|
||||||
|
depends-on = network.target
|
||||||
|
logfile = /var/log/dinit/hive-up.log
|
||||||
|
log-type = file
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Section (Table) headers
|
||||||
|
[update]
|
||||||
|
# Interval between updates check in hours. 0 - no auto check for updates.
|
||||||
|
check_interval = 58
|
||||||
|
# Tells hive-up to automatically download updates when awailable.
|
||||||
|
download_updates = true
|
||||||
|
# Tells hive-up to automatically perform updates during system reboot
|
||||||
|
auto_update = false
|
||||||
|
|
||||||
|
# In [kernel] section user may specify kernel cmd
|
||||||
|
# [kernel]
|
||||||
|
# cmd = ""
|
||||||
+2
-2
@@ -176,7 +176,7 @@ fn process_remoute(
|
|||||||
// doing what daemons usually beezz
|
// doing what daemons usually beezz
|
||||||
fn do_local_work(config: &HiveConfig, bzz_db: &mut HiveDb) -> Result<(), DaemonError> {
|
fn do_local_work(config: &HiveConfig, bzz_db: &mut HiveDb) -> Result<(), DaemonError> {
|
||||||
// if updates check is turned on
|
// if updates check is turned on
|
||||||
if config.update.updates_check_interval != 0 {
|
if config.update.check_interval != 0 {
|
||||||
let timestamp = get_timestamp_sec();
|
let timestamp = get_timestamp_sec();
|
||||||
|
|
||||||
// calculate how many hours passed sinse last update
|
// calculate how many hours passed sinse last update
|
||||||
@@ -186,7 +186,7 @@ fn do_local_work(config: &HiveConfig, bzz_db: &mut HiveDb) -> Result<(), DaemonE
|
|||||||
/ 3600;
|
/ 3600;
|
||||||
|
|
||||||
// if more than updates_check_interval specifiyed in config - check for updates
|
// if more than updates_check_interval specifiyed in config - check for updates
|
||||||
if hours_since_update_check > config.update.updates_check_interval {
|
if hours_since_update_check > config.update.check_interval {
|
||||||
// perform update check
|
// perform update check
|
||||||
println!("Cheking for updates...");
|
println!("Cheking for updates...");
|
||||||
// now that may fail because of bad internet and idealy we
|
// now that may fail because of bad internet and idealy we
|
||||||
|
|||||||
+12
-12
@@ -22,26 +22,26 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use toml;
|
use toml;
|
||||||
|
|
||||||
const CONFIG_PATH: &str = "/etc/hive_up.toml";
|
const CONFIG_PATH: &str = "/etc/hive-up.toml";
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct HiveConfig {
|
pub struct HiveConfig {
|
||||||
// Matches [kernel] in TOML
|
// Matches [kernel] in TOML
|
||||||
pub kernel: KernelConfig,
|
pub kernel: Option<KernelConfig>,
|
||||||
// Updates process config
|
// Updates [update] in TOML
|
||||||
pub update: UpdateConfig,
|
pub update: UpdateConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct KernelConfig {
|
pub struct KernelConfig {
|
||||||
/// kernel cmd string that will be passed as kernel boot parameter.
|
/// kernel cmd string that will be passed as kernel boot parameter.
|
||||||
cmd: String,
|
pub cmd: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct UpdateConfig {
|
pub struct UpdateConfig {
|
||||||
/// Interval between updates check in hours. 0 - no auto check for updates.
|
/// Interval between updates check in hours. 0 - no auto check for updates.
|
||||||
pub updates_check_interval: u64,
|
pub check_interval: u64,
|
||||||
/// Tells hive-up to automatically download updates when awailable.
|
/// Tells hive-up to automatically download updates when awailable.
|
||||||
pub download_updates: bool,
|
pub download_updates: bool,
|
||||||
/// Tells hive-up to automatically perform updates during system reboot.
|
/// Tells hive-up to automatically perform updates during system reboot.
|
||||||
@@ -97,11 +97,11 @@ pub fn read_config() -> Result<HiveConfig, ConfigError> {
|
|||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_updates_check_interval(new_interval: u64) -> Result<HiveConfig, ConfigError> {
|
// pub fn change_updates_check_interval(new_interval: u64) -> Result<HiveConfig, ConfigError> {
|
||||||
let mut config: HiveConfig = read_config()?;
|
// let mut config: HiveConfig = read_config()?;
|
||||||
config.update.updates_check_interval = new_interval;
|
// config.update.updates_check_interval = new_interval;
|
||||||
let conf_str = toml::to_string_pretty(&config)?;
|
// let conf_str = toml::to_string_pretty(&config)?;
|
||||||
fs::write(CONFIG_PATH, conf_str)?;
|
// fs::write(CONFIG_PATH, conf_str)?;
|
||||||
|
|
||||||
Ok(config)
|
// Ok(config)
|
||||||
}
|
// }
|
||||||
|
|||||||
+22
-26
@@ -70,10 +70,29 @@ pub struct HiveDb {
|
|||||||
pub update_on_reboot: bool,
|
pub update_on_reboot: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_db() -> Result<HiveDb, DBError> {
|
||||||
|
let bzz_db = HiveDb{
|
||||||
|
update_check_timestamp: 0,
|
||||||
|
updates_available: 0,
|
||||||
|
update_status: false,
|
||||||
|
last_snapshot_time: "".into(),
|
||||||
|
update_on_reboot: false,
|
||||||
|
};
|
||||||
|
write_db(&bzz_db)?;
|
||||||
|
Ok(bzz_db)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_db() -> Result<HiveDb, DBError> {
|
pub fn read_db() -> Result<HiveDb, DBError> {
|
||||||
let file_content = fs::read_to_string(DB_PATH)?;
|
if fs::exists(DB_PATH)? {
|
||||||
let db: HiveDb = serde_json::from_str(&file_content)?;
|
let file_content = fs::read_to_string(DB_PATH)?;
|
||||||
Ok(db)
|
let db: HiveDb = serde_json::from_str(&file_content)?;
|
||||||
|
Ok(db)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println!("WARNING database file do not exist {}", DB_PATH);
|
||||||
|
print!("Creating default db file...");
|
||||||
|
init_db()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_db(db: &HiveDb) -> Result<(), DBError> {
|
pub fn write_db(db: &HiveDb) -> Result<(), DBError> {
|
||||||
@@ -94,26 +113,3 @@ pub fn update_last_check_update_time(new_timestamp: u64) -> Result<u64, DBError>
|
|||||||
Ok(old_value)
|
Ok(old_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// writes new update_status to db
|
|
||||||
/// and returns old db value on success
|
|
||||||
///
|
|
||||||
pub fn update_update_status(sucess_status: bool) -> Result<bool, DBError> {
|
|
||||||
let mut db = read_db()?;
|
|
||||||
let old_value = db.update_status;
|
|
||||||
db.update_status = sucess_status;
|
|
||||||
write_db(&db)?;
|
|
||||||
Ok(old_value)
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// writes new last_update_timestamp to db
|
|
||||||
/// and returns old value on success
|
|
||||||
///
|
|
||||||
pub fn update_last_update_timestamp(new_timestamp: String) -> Result<String, DBError> {
|
|
||||||
let mut db = read_db()?;
|
|
||||||
let old_value = db.last_snapshot_time;
|
|
||||||
db.last_snapshot_time = new_timestamp;
|
|
||||||
write_db(&db)?;
|
|
||||||
Ok(old_value)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -194,3 +194,12 @@ pub fn client_check_for_updates() -> Result<u32, IntercomError> {
|
|||||||
_ => Err(IntercomError::UnexpectedResponse),
|
_ => Err(IntercomError::UnexpectedResponse),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn client_schedule_update() -> Result<(), IntercomError> {
|
||||||
|
let resp = send_and_recv(BzzReq::ScheduleUpdate)?;
|
||||||
|
match resp {
|
||||||
|
BzzResp::Finish => Ok(()),
|
||||||
|
BzzResp::Error(ex) => Err(IntercomError::ServerError(ex)),
|
||||||
|
_ => Err(IntercomError::UnexpectedResponse),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+179
-21
@@ -20,15 +20,19 @@
|
|||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::vec;
|
||||||
use time_format;
|
use time_format;
|
||||||
|
|
||||||
|
const SNAPS_DIR: &str = "/bzz-snaps";
|
||||||
const SNAPS_DIR: &str = "/bzz_snaps";
|
|
||||||
const EFI_BOOT_MOUNT_POINT: &str = "/beefi";
|
const EFI_BOOT_MOUNT_POINT: &str = "/beefi";
|
||||||
|
const UKI_IMAGE_NAME: &str = "/beefi/EFI/linux-kira-lts.efi";
|
||||||
|
const UKI_IMAGE_BACK_NAME: &str = "/beefi/EFI/linux-kira-lts-back.efi";
|
||||||
const EFI_PARTLABEL: &str = "bee-efi";
|
const EFI_PARTLABEL: &str = "bee-efi";
|
||||||
const BOOT_MENU_LABEL: &str = "Kira OS";
|
|
||||||
const UKI_IMAGE_NAME: &str = "\\EFI\\kira-linux-lts.efi";
|
|
||||||
|
|
||||||
|
const BOOT_MENU_LABEL: &str = "Kira OS";
|
||||||
|
const BOOT_MENU_LABEL_BACK: &str = "Kira OS Fallback";
|
||||||
|
const BOOT_UKI_IMAGE_NAME: &str = "\\EFI\\linux-kira-lts.efi";
|
||||||
|
const BOOT_UKI_IMAGE_NAME_BACK: &str = "\\EFI\\linux-kira-lts-back.efi";
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CommandFailed {
|
pub struct CommandFailed {
|
||||||
@@ -309,7 +313,6 @@ pub fn find_partlabel(partlabel: &str) -> Result<Option<String>, ExecCommandErro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// We need to use lsblk to find out parent device, or read topology from sysfs
|
/// We need to use lsblk to find out parent device, or read topology from sysfs
|
||||||
/// (basename $(readlink -f /sys/class/block/sda1/..))
|
/// (basename $(readlink -f /sys/class/block/sda1/..))
|
||||||
@@ -319,8 +322,11 @@ pub fn find_partlabel(partlabel: &str) -> Result<Option<String>, ExecCommandErro
|
|||||||
/// Returns: touple of partition number and parent device as Strings (part_num, par_dev)
|
/// Returns: touple of partition number and parent device as Strings (part_num, par_dev)
|
||||||
/// Returns Error if no efi partition was found
|
/// Returns Error if no efi partition was found
|
||||||
///
|
///
|
||||||
|
/// We need more complex logic for it.
|
||||||
fn get_efi_part_info() -> Result<(String,String), ExecCommandError> {
|
/// Need to alterate between two boot records.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
fn get_efi_part_info() -> Result<(String, String), ExecCommandError> {
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
let re = Regex::new(r#"^PARTN="([0-9]+)" PKNAME="([0-9a-Z]+)"$"#).unwrap();
|
let re = Regex::new(r#"^PARTN="([0-9]+)" PKNAME="([0-9a-Z]+)"$"#).unwrap();
|
||||||
|
|
||||||
@@ -332,29 +338,81 @@ fn get_efi_part_info() -> Result<(String,String), ExecCommandError> {
|
|||||||
// let part_no = captured[1];
|
// let part_no = captured[1];
|
||||||
// let parent_dev = captured[2];
|
// let parent_dev = captured[2];
|
||||||
Ok((captured[1].to_string(), captured[2].to_string()))
|
Ok((captured[1].to_string(), captured[2].to_string()))
|
||||||
|
} else {
|
||||||
|
Err(ExecCommandError::Other(format!(
|
||||||
|
"No EFI partition (with PARTLABEL={}) was found!",
|
||||||
|
EFI_PARTLABEL
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Err(ExecCommandError::Other(format!("No EFI partition (with PARTLABEL={}) was found!", EFI_PARTLABEL)))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// efibootmgr
|
/// List all boot entries hex numbers
|
||||||
|
/// Boot0000* Nyan
|
||||||
|
///
|
||||||
|
fn list_efi_bootnums() -> Result<Vec<String>, ExecCommandError> {
|
||||||
|
use regex::Regex;
|
||||||
|
let re = Regex::new(r#"^Boot([0-9A-F]{4})\* "#).unwrap();
|
||||||
|
let str_res = exec_command_out("efibootmgr", &vec![])?;
|
||||||
|
|
||||||
|
// for each line in output match bootnum
|
||||||
|
// and collect to vector
|
||||||
|
Ok(str_res
|
||||||
|
.lines()
|
||||||
|
.filter_map(|hs| re.captures(hs))
|
||||||
|
.map(|captured| captured[1].to_string())
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// sudo efibootmgr -B -b 0001
|
||||||
|
/// -B (--delete-bootnum)
|
||||||
|
///
|
||||||
|
fn delete_efi_bootnum(bootnum: &str) -> Result<(), ExecCommandError> {
|
||||||
|
exec_command("efibootmgr", &vec!["-B", "-b", bootnum])
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Delets all EFI bootnums
|
||||||
|
/// Returns number of deleted bootnums on success
|
||||||
|
///
|
||||||
|
fn delete_all_efi_bootnums() -> Result<usize, ExecCommandError> {
|
||||||
|
let bootnums = list_efi_bootnums()?;
|
||||||
|
for bootnum in &bootnums {
|
||||||
|
delete_efi_bootnum(bootnum)?;
|
||||||
|
}
|
||||||
|
Ok(bootnums.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Creates EFI boot record
|
||||||
|
/// boot_index - inserting it at specified boot index (bootorder)
|
||||||
/// Assuming boot partition has "bee-efi" PARTLABEL
|
/// Assuming boot partition has "bee-efi" PARTLABEL
|
||||||
///
|
///
|
||||||
/// Generaly lets just add new record with date. Label modification not allways works?
|
fn efi_boot_record_create(
|
||||||
/// May add deletion of old record latel
|
boot_index: u16,
|
||||||
/// sudo efibootmgr --create --disk /dev/nvme0n1 --part 1 --label "Kira OS" --loader '\EFI\nyanlinux\kira-bzz.efi' --unicode 'initrd=\EFI\initrd.img'
|
boot_label: &str,
|
||||||
|
uki_path: &str,
|
||||||
pub fn boot_record_update(maybe_kernel_cmd: Option<&str>) -> Result<(), ExecCommandError> {
|
maybe_kernel_cmd: &Option<String>,
|
||||||
|
) -> Result<(), ExecCommandError> {
|
||||||
let (efi_partno, efi_parent_dev) = get_efi_part_info()?;
|
let (efi_partno, efi_parent_dev) = get_efi_part_info()?;
|
||||||
|
|
||||||
let local_date = time_format::strftime_local("%Y-%m-%d", time_format::now().unwrap()).unwrap();
|
//let local_date = time_format::strftime_local("%Y-%m-%d", time_format::now().unwrap()).unwrap();
|
||||||
let boot_label = format!("{} {}", BOOT_MENU_LABEL, local_date);
|
let string_boot_index = boot_index.to_string();
|
||||||
|
|
||||||
let mut efibootmgr_args: Vec<&str> = vec!["--create", "--disk", &efi_parent_dev, "--part", &efi_partno, "--label", &boot_label, "--loader", UKI_IMAGE_NAME];
|
let mut efibootmgr_args: Vec<&str> = vec![
|
||||||
|
"--create",
|
||||||
|
"--index",
|
||||||
|
&string_boot_index,
|
||||||
|
"--disk",
|
||||||
|
&efi_parent_dev,
|
||||||
|
"--part",
|
||||||
|
&efi_partno,
|
||||||
|
"--label",
|
||||||
|
boot_label,
|
||||||
|
"--loader",
|
||||||
|
uki_path,
|
||||||
|
];
|
||||||
if let Some(kernel_cmd) = maybe_kernel_cmd {
|
if let Some(kernel_cmd) = maybe_kernel_cmd {
|
||||||
efibootmgr_args.push("--unicode");
|
efibootmgr_args.push("--unicode");
|
||||||
efibootmgr_args.push(kernel_cmd);
|
efibootmgr_args.push(kernel_cmd);
|
||||||
@@ -362,5 +420,105 @@ pub fn boot_record_update(maybe_kernel_cmd: Option<&str>) -> Result<(), ExecComm
|
|||||||
exec_command("efibootmgr", &efibootmgr_args)?;
|
exec_command("efibootmgr", &efibootmgr_args)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Deletes all existing boot records and create a default
|
||||||
|
///
|
||||||
|
pub fn init_efi_boot_record(maybe_kernel_cmd: &Option<String>) -> Result<(), ExecCommandError> {
|
||||||
|
// 1 delete all bootnums
|
||||||
|
delete_all_efi_bootnums()?;
|
||||||
|
// 2 create defaul
|
||||||
|
efi_boot_record_create(0, BOOT_MENU_LABEL, BOOT_UKI_IMAGE_NAME, maybe_kernel_cmd)?;
|
||||||
|
efi_boot_record_create(
|
||||||
|
1,
|
||||||
|
BOOT_MENU_LABEL_BACK,
|
||||||
|
BOOT_UKI_IMAGE_NAME_BACK,
|
||||||
|
maybe_kernel_cmd,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// List installed kernels by inspecting /usr/lib/modules directory
|
||||||
|
/// Result is a sorted vector of string
|
||||||
|
///
|
||||||
|
fn list_installed_kernels() -> Result<Vec<String>, ExecCommandError> {
|
||||||
|
use regex::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();
|
||||||
|
|
||||||
|
// Oh boy we roll
|
||||||
|
// finding first dir in /usr/lib/modules that matches common kernel name
|
||||||
|
for r_d_entry in fs::read_dir("/usr/lib/modules")? {
|
||||||
|
let d_entry = r_d_entry?;
|
||||||
|
if d_entry.file_type()?.is_dir() {
|
||||||
|
let maybe_file_name = d_entry.file_name().to_str().map(|s| s.to_string());
|
||||||
|
if let Some(file_name) = maybe_file_name {
|
||||||
|
if re.is_match(&file_name) {
|
||||||
|
kernel_dirs.push(file_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kernel_dirs.sort();
|
||||||
|
Ok(kernel_dirs)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_efi_boot_partition_content() -> Result<(), ExecCommandError> {
|
||||||
|
let kernel_dirs = list_installed_kernels()?;
|
||||||
|
// check if kernel even exist lol
|
||||||
|
if let Some(kernel_dir) = kernel_dirs.last() {
|
||||||
|
let kernel_img_path = format!("/usr/lib/modules/{}/vmlinuz", kernel_dir);
|
||||||
|
let efi_dir = format!("{}/EFI", EFI_BOOT_MOUNT_POINT);
|
||||||
|
println!("Romoving efi dir {}", efi_dir);
|
||||||
|
fs::remove_dir_all(&efi_dir)?;
|
||||||
|
println!("Creating efi dir {}", efi_dir);
|
||||||
|
fs::create_dir(efi_dir)?;
|
||||||
|
println!("Copy {} to {}", kernel_img_path, UKI_IMAGE_NAME);
|
||||||
|
fs::copy(&kernel_img_path, UKI_IMAGE_NAME)?;
|
||||||
|
println!("Copy {} to {}", kernel_img_path, UKI_IMAGE_BACK_NAME);
|
||||||
|
fs::copy(&kernel_img_path, UKI_IMAGE_BACK_NAME)?;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ExecCommandError::Other(
|
||||||
|
"Cannot find kernel files under /usr/lib/modules dir!".into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Ok. Keep it simple kira.
|
||||||
|
/// Lets put new kernel as kira-linux-lts.efi to EFI part.
|
||||||
|
/// Should we save old kernel? Somehow.
|
||||||
|
/// lets rename kira-linux-lts.efi to kira-linux-lts-back.efi
|
||||||
|
/// Lets do not do much else.
|
||||||
|
/// sudo cp /usr/lib/modules/6.18.46-1-kira-lts/vmlinuz /beefi/EFI/kira-linux-lts.efi
|
||||||
|
///
|
||||||
|
pub fn boot_update() -> Result<(), ExecCommandError> {
|
||||||
|
// find vmlinuz path in filesystem
|
||||||
|
let kernel_dirs = list_installed_kernels()?;
|
||||||
|
|
||||||
|
// check if kernel even exist lol
|
||||||
|
if let Some(kernel_dir) = kernel_dirs.last() {
|
||||||
|
let kernel_img_path = format!("/usr/lib/modules/{}/vmlinuz", kernel_dir);
|
||||||
|
// rename old kernel to
|
||||||
|
println!(
|
||||||
|
"Renaming old kernel {} to {}",
|
||||||
|
UKI_IMAGE_NAME, UKI_IMAGE_BACK_NAME
|
||||||
|
);
|
||||||
|
fs::rename(UKI_IMAGE_NAME, UKI_IMAGE_BACK_NAME)?;
|
||||||
|
// copy new kernel image
|
||||||
|
println!(
|
||||||
|
"Copy new kernel from {} to {}",
|
||||||
|
kernel_img_path, UKI_IMAGE_NAME
|
||||||
|
);
|
||||||
|
fs::copy(&kernel_img_path, UKI_IMAGE_NAME)?;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ExecCommandError::Other(
|
||||||
|
"Cannot find kernel files under /usr/lib/modules dir!".into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-4
@@ -15,10 +15,10 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use clap::{Args, Parser, Subcommand};
|
use clap::{Args, Parser, Subcommand};
|
||||||
use signal_hook::{consts::SIGINT, iterator::Signals};
|
use signal_hook;
|
||||||
use std;
|
use std;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
mod hive_system;
|
mod hive_system;
|
||||||
|
|
||||||
@@ -111,13 +111,17 @@ impl std::error::Error for HiveUpError {}
|
|||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
#[group(required = true, multiple = false)]
|
#[group(required = true, multiple = false)]
|
||||||
struct RemoteArgs {
|
struct RemoteArgs {
|
||||||
/// Ask daemon to chack for updates
|
/// Ask daemon to check for updates
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
check_updates: bool,
|
check_updates: bool,
|
||||||
|
|
||||||
/// Ask daemon if there is any updates available
|
/// Ask daemon if there is any updates available
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
updates_avail: bool,
|
updates_avail: bool,
|
||||||
|
|
||||||
|
/// Ask daemon to perform system update on next reboot
|
||||||
|
#[arg(long)]
|
||||||
|
schedule_update: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
@@ -129,6 +133,12 @@ struct CliArgs {
|
|||||||
/// Install new kernel into boot partition
|
/// Install new kernel into boot partition
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
update_boot: bool,
|
update_boot: bool,
|
||||||
|
/// Cleans up and recreates UFI boot menu
|
||||||
|
#[arg(long)]
|
||||||
|
init_boot_menu: bool,
|
||||||
|
/// Cleans up and recreates UFI boot menu and /EFI dir content
|
||||||
|
#[arg(long)]
|
||||||
|
init_boot: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
@@ -198,7 +208,19 @@ fn main() -> Result<(), HiveUpError> {
|
|||||||
if cli_args.upgrade {
|
if cli_args.upgrade {
|
||||||
cli_upgrade(bzz_config)?;
|
cli_upgrade(bzz_config)?;
|
||||||
} else if cli_args.update_boot {
|
} else if cli_args.update_boot {
|
||||||
|
println!("Updating boot...");
|
||||||
|
hive_system::boot_update()?;
|
||||||
|
} else if cli_args.init_boot_menu {
|
||||||
|
println!("Init EFI boot menu...");
|
||||||
|
let kernel_cmd = bzz_config.kernel.and_then(|kk| kk.cmd.clone());
|
||||||
|
hive_system::init_efi_boot_record(&kernel_cmd)?;
|
||||||
|
} else if cli_args.init_boot {
|
||||||
|
println!("Init EFI boot menu and EFI partition content...");
|
||||||
|
println!("Init EFI Partition content...");
|
||||||
|
let kernel_cmd = bzz_config.kernel.and_then(|kk| kk.cmd.clone());
|
||||||
|
hive_system::init_efi_boot_record(&kernel_cmd)?;
|
||||||
|
println!("Init EFI boot menu...");
|
||||||
|
hive_system::init_efi_boot_partition_content()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HiveUpMode::Remote(remote_args) => {
|
HiveUpMode::Remote(remote_args) => {
|
||||||
@@ -208,6 +230,10 @@ fn main() -> Result<(), HiveUpError> {
|
|||||||
} else if remote_args.updates_avail {
|
} else if remote_args.updates_avail {
|
||||||
let up_num = hive_intercom::client_updates_available()?;
|
let up_num = hive_intercom::client_updates_available()?;
|
||||||
println!("Updates awailable: {}", up_num);
|
println!("Updates awailable: {}", up_num);
|
||||||
|
} else if remote_args.schedule_update {
|
||||||
|
println!("Scheduling system update...");
|
||||||
|
hive_intercom::client_schedule_update()?;
|
||||||
|
print!("Done!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user