SHA256
Compare commits
5
Commits
v0.1.0
...
4a4e6927bd
| Author | SHA256 | Date | |
|---|---|---|---|
|
|
4a4e6927bd | ||
|
|
39fb7c55b9 | ||
|
|
6811002ca6 | ||
|
|
20bdd217c4 | ||
|
|
17cea4b89e |
Generated
+13
-221
@@ -2,15 +2,6 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "1.0.0"
|
||||
@@ -61,26 +52,11 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-polyfill"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.13.1"
|
||||
version = "2.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -134,39 +110,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
||||
|
||||
[[package]]
|
||||
name = "critical-section"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-io"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-io"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
@@ -183,35 +132,12 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.7.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||
dependencies = [
|
||||
"atomic-polyfill",
|
||||
"hash32",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"spin",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
@@ -220,14 +146,12 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hive-up"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"nix",
|
||||
"postcard",
|
||||
"regex",
|
||||
"regex-lite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"signal-hook",
|
||||
"time-format",
|
||||
"toml",
|
||||
@@ -235,9 +159,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.14.1"
|
||||
version = "2.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07aa2048142242915a31d35844fb311e0e53fcca590c3a0a40dcf1b841fa09eb"
|
||||
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@@ -249,33 +173,12 @@ version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.189"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.31.3"
|
||||
@@ -294,19 +197,6 @@ version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||
|
||||
[[package]]
|
||||
name = "postcard"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
|
||||
dependencies = [
|
||||
"cobs",
|
||||
"embedded-io 0.4.0",
|
||||
"embedded-io 0.6.1",
|
||||
"heapless",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.107"
|
||||
@@ -326,54 +216,10 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.13.1"
|
||||
name = "regex-lite"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
||||
checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
@@ -405,19 +251,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.151"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.1.1"
|
||||
@@ -447,21 +280,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
@@ -470,35 +288,15 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "3.0.4"
|
||||
version = "3.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f"
|
||||
checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-format"
|
||||
version = "1.2.3"
|
||||
@@ -507,9 +305,9 @@ checksum = "fb54c799611991d3d4a66fee3ff17b9f600c2a0f8c0d34e8209dbd153ff0a87b"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "1.1.5+spec-1.1.0"
|
||||
version = "1.1.6+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12c0ba9680044b4ce98d391a62094047eada0d64860b80166c39f4a6b5640785"
|
||||
checksum = "920602543f0911ab71da12c50d59701da54c196d1a2bf5cb4b75667f137a406a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
@@ -576,9 +374,3 @@ name = "winnow"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||
|
||||
+3
-5
@@ -1,15 +1,13 @@
|
||||
[package]
|
||||
name = "hive-up"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.6", features = ["derive"] }
|
||||
nix = { version = "0", features = ["user"] }
|
||||
postcard = { version = "1.1", features = ["use-std"] }
|
||||
regex = "1"
|
||||
regex-lite = "0.1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
signal-hook = "0.4"
|
||||
time-format = "1.2"
|
||||
toml = "1.1"
|
||||
@@ -19,7 +17,7 @@ lto = true
|
||||
debug = false
|
||||
incremental = false
|
||||
codegen-units = 1
|
||||
opt-level = 2
|
||||
opt-level = "s"
|
||||
strip = true
|
||||
|
||||
[registry]
|
||||
|
||||
@@ -1,3 +1,60 @@
|
||||
# hive-up
|
||||
|
||||
Program to manage update process of Kira Linux. Creating snapshots. Dealing with pacman fail, etc.
|
||||
Program to manage update process of Kira Linux. Creating snapshots. Dealing with pacman fail, etc.
|
||||
|
||||
There should be some documantation here.
|
||||
|
||||
hive-up uses `/var/lib/hive-up/hyve-db.json` file as database for stuff
|
||||
And `/etc/hive-up.toml` as config file.
|
||||
|
||||
As an daemon hive-up righ now doing only periodical checks for updates.
|
||||
|
||||
```text
|
||||
Usage: hive-up <COMMAND>
|
||||
|
||||
Commands:
|
||||
cli Perform local operations
|
||||
remote Ask hive-up daemon something
|
||||
daemon Run hive-up in daemon mode
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-h, --help Print help
|
||||
-V, --version Print version
|
||||
```
|
||||
|
||||
For cli mode:
|
||||
|
||||
```text
|
||||
Usage: hive-up cli <--upgrade|--update-boot|--init-boot-menu|--init-boot>
|
||||
|
||||
Options:
|
||||
--upgrade Perform system upgrade
|
||||
--update-boot Install new kernel into boot partition
|
||||
--init-boot-menu Cleans up and recreates UFI boot menu
|
||||
--init-boot Cleans up and recreates UFI boot menu and /EFI dir content
|
||||
-h, --help Print help
|
||||
```
|
||||
|
||||
For remote mode:
|
||||
|
||||
```text
|
||||
Usage: hive-up remote <--check-updates|--updates-avail|--schedule-update>
|
||||
|
||||
Options:
|
||||
--check-updates Ask daemon to check for updates
|
||||
--updates-avail Ask daemon if there is any updates available
|
||||
--schedule-update Ask daemon to perform system update on next reboot
|
||||
-h, --help Print help
|
||||
```
|
||||
|
||||
`hive-up daemon` - do not have any flags for now.
|
||||
|
||||
`hive-up cli --upgrade` - generally not supposed to be called by user. It get called by system service manager (dinit) after hive-up service stop (on reboot or system shutdown)
|
||||
When `hive-up cli --upgrade` is called, it checks if `update_on_reboot` flag is set in **DB** or `auto_update` flag checked in **config**, and if `updates_available` in **DB** is non zero. Update routine continue only if this conditios are met.
|
||||
|
||||
1. It creates snapshots of `/usr` and `/var` subvolumes
|
||||
2. It sets `update_status` to **false** in **DB**
|
||||
3. Performs update, and if everything was fine sets `update_status` to **true** in **DB**
|
||||
|
||||
After this, system reboots, and on system boot Nyanit figures up what to do with failed updates if any
|
||||
|
||||
@@ -9,4 +9,5 @@ Target = linux-kira-server-lts
|
||||
[Action]
|
||||
Description = Running custom command after kernel update
|
||||
When = PostTransaction
|
||||
Exec = /usr/bin/hive-up cli --update-boot
|
||||
Exec = /usr/bin/hive-up boot update
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Section (Table) headers
|
||||
|
||||
# In [kernel] section user may specify kernel cmd
|
||||
# [kernel]
|
||||
# cmd = ""
|
||||
@@ -1,6 +0,0 @@
|
||||
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
|
||||
-264
@@ -1,264 +0,0 @@
|
||||
// <hive-up - update program fot Kira Linux.>
|
||||
// Copyright (C) <2026> <Kira Foundation>
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/*
|
||||
hive-up daemon logic
|
||||
*/
|
||||
|
||||
use std::os::unix::net::UnixDatagram;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::thread;
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
use crate::hive_config;
|
||||
use crate::hive_config::HiveConfig;
|
||||
use crate::hive_db::{self, HiveDb};
|
||||
use crate::hive_intercom::{self, BzzReq, BzzResp, IntercomError};
|
||||
use crate::hive_system;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DaemonError {
|
||||
IoError(std::io::Error),
|
||||
DBError(hive_db::DBError),
|
||||
ConfigError(hive_config::ConfigError),
|
||||
ExecCommandError(hive_system::ExecCommandError),
|
||||
TimestampError,
|
||||
}
|
||||
|
||||
// 2. Implement From for each wrapped error type
|
||||
impl From<std::io::Error> for DaemonError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
DaemonError::IoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hive_db::DBError> for DaemonError {
|
||||
fn from(err: hive_db::DBError) -> Self {
|
||||
DaemonError::DBError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hive_config::ConfigError> for DaemonError {
|
||||
fn from(err: hive_config::ConfigError) -> Self {
|
||||
DaemonError::ConfigError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hive_system::ExecCommandError> for DaemonError {
|
||||
fn from(err: hive_system::ExecCommandError) -> Self {
|
||||
DaemonError::ExecCommandError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for DaemonError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
DaemonError::IoError(e) => write!(f, "IO Error: {}", e),
|
||||
DaemonError::DBError(e) => write!(f, "Database error: {}", e),
|
||||
DaemonError::ConfigError(e) => write!(f, "Config Error: {}", e),
|
||||
DaemonError::ExecCommandError(e) => write!(f, "Exec Command Error: {}", e),
|
||||
DaemonError::TimestampError => write!(f, "Timestamp Error"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement std::error::Error
|
||||
impl std::error::Error for DaemonError {}
|
||||
|
||||
fn get_timestamp_sec() -> u64 {
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Time went backwards")
|
||||
.as_secs()
|
||||
}
|
||||
|
||||
/// bloking function. Bloaks for configured socker recv timeout
|
||||
fn process_remoute(
|
||||
bzz_db: &mut HiveDb,
|
||||
listening_socket: &UnixDatagram,
|
||||
recv_buf: &mut [u8],
|
||||
) -> Result<(), DaemonError> {
|
||||
// waiting on socket recv_from untill timeout (also using this as a timer)
|
||||
match hive_intercom::socket_recv(&listening_socket, recv_buf) {
|
||||
// we get some request to process
|
||||
Ok((bzz_req, client_addr)) => {
|
||||
match bzz_req {
|
||||
// return awailable updates number
|
||||
BzzReq::UpdatesAvailable => {
|
||||
let resp = BzzResp::UpdatesAvailable(bzz_db.updates_available);
|
||||
if let Err(ex) =
|
||||
hive_intercom::socket_send(&listening_socket, &client_addr, resp)
|
||||
{
|
||||
println!("Error while ansvering cli request: {}", ex);
|
||||
}
|
||||
}
|
||||
// we should apply updates if any on reboot
|
||||
BzzReq::ScheduleUpdate => {
|
||||
// but only if we have actually any updates
|
||||
if bzz_db.updates_available > 0 {
|
||||
bzz_db.update_on_reboot = true;
|
||||
// keep it simple Kira
|
||||
// lets just return err from the loop if something wrong with db
|
||||
hive_db::write_db(&bzz_db)?;
|
||||
// signal remoute that evertyhing go OK
|
||||
if let Err(ex) = hive_intercom::socket_send(
|
||||
&listening_socket,
|
||||
&client_addr,
|
||||
BzzResp::Finish,
|
||||
) {
|
||||
println!("Error while ansvering cli request: {}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
BzzReq::CheckForUpdates => {
|
||||
let resp = BzzResp::Working(1);
|
||||
if let Err(ex) =
|
||||
hive_intercom::socket_send(&listening_socket, &client_addr, resp)
|
||||
{
|
||||
println!("Error while ansvering cli request: {}", ex);
|
||||
} else {
|
||||
// perform update check
|
||||
println!("Cheking for updates...");
|
||||
// now that may fail because of bad internet and idealy we
|
||||
// want to just log error and retry in other time
|
||||
bzz_db.updates_available = match hive_system::check_updates() {
|
||||
Ok(updates_num) => updates_num,
|
||||
Err(ex) => {
|
||||
println!("Error while shecking for updates: {}", ex);
|
||||
0u32
|
||||
}
|
||||
};
|
||||
hive_db::write_db(&bzz_db)?;
|
||||
println!(
|
||||
"Found {} packages that needs to be updated.",
|
||||
bzz_db.updates_available
|
||||
);
|
||||
// send evailable updates numbet to client
|
||||
let resp = BzzResp::UpdatesAvailable(bzz_db.updates_available);
|
||||
if let Err(ex) =
|
||||
hive_intercom::socket_send(&listening_socket, &client_addr, resp)
|
||||
{
|
||||
println!("Error while ansvering cli request: {}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
// if time out - do nothing
|
||||
Err(IntercomError::Timeout) => Ok(()),
|
||||
// if some actual IO error then return it
|
||||
Err(IntercomError::IoError(ex)) => Err(ex.into()),
|
||||
// if other kinds of errors - log and continue
|
||||
Err(ex) => {
|
||||
println!("Got error while listenin to unix socket: {}", ex);
|
||||
print!("Sleeping for 1 secong and continue...");
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// doing what daemons usually beezz
|
||||
fn do_local_work(config: &HiveConfig, bzz_db: &mut HiveDb) -> Result<(), DaemonError> {
|
||||
// if updates check is turned on
|
||||
if config.update.updates_check_interval != 0 {
|
||||
let timestamp = get_timestamp_sec();
|
||||
|
||||
// calculate how many hours passed sinse last update
|
||||
let hours_since_update_check = timestamp
|
||||
.checked_sub(bzz_db.update_check_timestamp)
|
||||
.ok_or(DaemonError::TimestampError)?
|
||||
/ 3600;
|
||||
|
||||
// if more than updates_check_interval specifiyed in config - check for updates
|
||||
if hours_since_update_check > config.update.updates_check_interval {
|
||||
// perform update check
|
||||
println!("Cheking for updates...");
|
||||
// now that may fail because of bad internet and idealy we
|
||||
// want to just log error and retry in other time
|
||||
bzz_db.updates_available = match hive_system::check_updates() {
|
||||
Ok(updates_num) => updates_num,
|
||||
Err(ex) => {
|
||||
println!("Error while shecking for updates: {}", ex);
|
||||
0u32
|
||||
}
|
||||
};
|
||||
hive_db::write_db(&bzz_db)?;
|
||||
println!(
|
||||
"Found {} packages that needs to be updated.",
|
||||
bzz_db.updates_available
|
||||
);
|
||||
|
||||
// if auto download for updates is enabled and there is some updates - download them
|
||||
if config.update.download_updates && bzz_db.updates_available != 0 {
|
||||
println!("Downloadin updates...");
|
||||
match hive_system::download_updates() {
|
||||
Ok(()) => {
|
||||
println!("Updates downloaded...");
|
||||
}
|
||||
Err(ex) => {
|
||||
println!("Error downloading updates: {}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// updating las tcheck for updates timestamp in db
|
||||
bzz_db.update_check_timestamp = get_timestamp_sec();
|
||||
hive_db::write_db(&bzz_db)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run(
|
||||
mut bzz_config: HiveConfig,
|
||||
term_flag: Arc<AtomicBool>,
|
||||
reload_flag: Arc<AtomicBool>,
|
||||
) -> Result<(), DaemonError> {
|
||||
// reading db from disk
|
||||
let mut bzz_db = hive_db::read_db()?;
|
||||
|
||||
// stop flag
|
||||
let mut keep_going = true;
|
||||
|
||||
// init udp unix socket for communication with cli and such
|
||||
let listening_socket = hive_intercom::socket_bind(1)?;
|
||||
let mut recv_buf: Vec<u8> = Vec::with_capacity(1024);
|
||||
|
||||
// main loop (I love loops) (No please just do recursion properly)
|
||||
while keep_going {
|
||||
process_remoute(&mut bzz_db, &listening_socket, recv_buf.as_mut_slice())?;
|
||||
do_local_work(&bzz_config, &mut bzz_db)?;
|
||||
// check termination flags
|
||||
if term_flag.load(Ordering::Relaxed) {
|
||||
println!("SIGTERM recieved - wrapping things up.");
|
||||
keep_going = false;
|
||||
}
|
||||
|
||||
// checking reload signal flag
|
||||
if reload_flag.load(Ordering::Relaxed) {
|
||||
println!("SIGHUP recieved - reloading config and DB.");
|
||||
bzz_config = hive_config::read_config()?;
|
||||
bzz_db = hive_db::read_db()?;
|
||||
println!("Reloaded!");
|
||||
}
|
||||
}
|
||||
|
||||
println!("Exiting...");
|
||||
Ok(())
|
||||
}
|
||||
+2
-13
@@ -22,14 +22,12 @@ use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
use toml;
|
||||
|
||||
const CONFIG_PATH: &str = "/etc/hive_up.toml";
|
||||
const CONFIG_PATH: &str = "/etc/hive-up.toml";
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct HiveConfig {
|
||||
// Matches [kernel] in TOML
|
||||
pub kernel: KernelConfig,
|
||||
// Updates process config
|
||||
pub update: UpdateConfig,
|
||||
pub kernel: Option<KernelConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -38,15 +36,6 @@ pub struct KernelConfig {
|
||||
pub cmd: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UpdateConfig {
|
||||
/// Interval between updates check in hours. 0 - no auto check for updates.
|
||||
pub updates_check_interval: u64,
|
||||
/// Tells hive-up to automatically download updates when awailable.
|
||||
pub download_updates: bool,
|
||||
/// Tells hive-up to automatically perform updates during system reboot.
|
||||
pub auto_update: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ConfigError {
|
||||
|
||||
-119
@@ -1,119 +0,0 @@
|
||||
// <hive-up - update program fot Kira Linux.>
|
||||
// Copyright (C) <2026> <Kira Foundation>
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/*
|
||||
Functions for reading and writyng daemon and updates state
|
||||
*/
|
||||
|
||||
const DB_PATH: &str = "/var/lib/hive-up/hyve-db.json";
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DBError {
|
||||
IoError(std::io::Error),
|
||||
JsonError(serde_json::Error),
|
||||
}
|
||||
|
||||
// 2. Implement From for each wrapped error type
|
||||
impl From<std::io::Error> for DBError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
DBError::IoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for DBError {
|
||||
fn from(err: serde_json::Error) -> Self {
|
||||
DBError::JsonError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for DBError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
DBError::IoError(e) => write!(f, "IO Error: {}", e),
|
||||
DBError::JsonError(e) => {
|
||||
write!(f, "Json parse error: {}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement std::error::Error
|
||||
impl std::error::Error for DBError {}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct HiveDb {
|
||||
/// Timestamp of last check for updates in seconds from UNIX_EPOCH
|
||||
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
|
||||
pub update_status: bool,
|
||||
/// datetime of last snapshot in format "%Y-%m-%dT%H:%M:%S"
|
||||
pub last_snapshot_time: String,
|
||||
/// set to true if we want to apply available updates on reboot
|
||||
pub update_on_reboot: bool,
|
||||
}
|
||||
|
||||
pub fn read_db() -> Result<HiveDb, DBError> {
|
||||
let file_content = fs::read_to_string(DB_PATH)?;
|
||||
let db: HiveDb = serde_json::from_str(&file_content)?;
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
pub fn write_db(db: &HiveDb) -> Result<(), DBError> {
|
||||
let serialized_db = serde_json::to_string(db)?;
|
||||
fs::write(DB_PATH, serialized_db)?;
|
||||
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)
|
||||
}
|
||||
|
||||
///
|
||||
/// 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)
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
// <hive-up - update program fot Kira Linux.>
|
||||
// Copyright (C) <2026> <Kira Foundation>
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/*
|
||||
hive-up unix socket communication
|
||||
*/
|
||||
|
||||
use postcard;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
use std::os::unix::net::{SocketAddr, UnixDatagram};
|
||||
use std::time::Duration;
|
||||
|
||||
pub const SOCKET_DIR: &str = "/run/hive-up";
|
||||
pub const SOCKET_PATH: &str = "/run/hive-up/hive-intercom.soc";
|
||||
pub const CLINET_READ_TIMEOUT_SECONDS: u64 = 88;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IntercomError {
|
||||
IoError(std::io::Error),
|
||||
PostcardError(postcard::Error),
|
||||
ConnectionClosed,
|
||||
Timeout,
|
||||
UnexpectedResponse,
|
||||
ServerError(String),
|
||||
}
|
||||
|
||||
// Wrapping IO errors but separating time out error
|
||||
impl From<std::io::Error> for IntercomError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
if err.kind() == std::io::ErrorKind::TimedOut
|
||||
|| err.kind() == std::io::ErrorKind::WouldBlock
|
||||
{
|
||||
IntercomError::Timeout
|
||||
} else {
|
||||
IntercomError::IoError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<postcard::Error> for IntercomError {
|
||||
fn from(err: postcard::Error) -> Self {
|
||||
IntercomError::PostcardError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for IntercomError {
|
||||
fn from(err: String) -> Self {
|
||||
IntercomError::ServerError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for IntercomError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
IntercomError::IoError(e) => write!(f, "IO Error: {}", e),
|
||||
IntercomError::PostcardError(e) => {
|
||||
write!(f, "Data parsing (postcard) error: {}", e)
|
||||
}
|
||||
IntercomError::Timeout => write!(f, "Operation Timeout"),
|
||||
IntercomError::ConnectionClosed => write!(f, "Connection closed"),
|
||||
IntercomError::UnexpectedResponse => write!(f, "Unexpected response"),
|
||||
IntercomError::ServerError(err) => write!(f, "Server side error: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement std::error::Error
|
||||
impl std::error::Error for IntercomError {}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum BzzResp {
|
||||
/// signalls progress of a task as u16 integer.
|
||||
/// interpretation is up to you.
|
||||
Working(u16),
|
||||
Finish,
|
||||
UpdatesAvailable(u32),
|
||||
Error(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum BzzReq {
|
||||
UpdatesAvailable,
|
||||
CheckForUpdates,
|
||||
ScheduleUpdate,
|
||||
}
|
||||
|
||||
pub fn socket_bind(read_timeout_sec: u64) -> Result<UnixDatagram, std::io::Error> {
|
||||
// create socket directory if it is does not exist
|
||||
if let Ok(path_exist) = fs::exists(SOCKET_DIR)
|
||||
&& path_exist == false
|
||||
{
|
||||
fs::create_dir(SOCKET_DIR)?;
|
||||
}
|
||||
// remove socket file if any present
|
||||
let _ = fs::remove_file(SOCKET_PATH);
|
||||
|
||||
// bind datagram unix socket
|
||||
let socket = UnixDatagram::bind(SOCKET_PATH)?;
|
||||
socket.set_read_timeout(Some(Duration::from_secs(read_timeout_sec)))?;
|
||||
Ok(socket)
|
||||
}
|
||||
|
||||
// for daemon side
|
||||
pub fn socket_send(
|
||||
socket: &UnixDatagram,
|
||||
client_addr: &SocketAddr,
|
||||
resp: BzzResp,
|
||||
) -> Result<(), IntercomError> {
|
||||
let resp_buff = postcard::to_stdvec(&resp)?;
|
||||
socket.send_to_addr(resp_buff.as_slice(), client_addr)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// for daemon side
|
||||
pub fn socket_recv(
|
||||
socket: &UnixDatagram,
|
||||
recv_buf: &mut [u8],
|
||||
) -> Result<(BzzReq, SocketAddr), IntercomError> {
|
||||
match socket.recv_from(recv_buf) {
|
||||
Ok((rec_count, client_addr)) => {
|
||||
if rec_count != 0 {
|
||||
println!("DEBUG: Total bytes recieved {}", rec_count);
|
||||
let decoded_req: BzzReq = postcard::from_bytes(&recv_buf)?;
|
||||
Ok((decoded_req, client_addr))
|
||||
} else {
|
||||
Err(IntercomError::ConnectionClosed)
|
||||
}
|
||||
}
|
||||
Err(ex) => Err(ex.into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn send_and_recv(request: BzzReq) -> Result<BzzResp, IntercomError> {
|
||||
let socket = UnixDatagram::unbound()?;
|
||||
socket.connect(SOCKET_PATH)?;
|
||||
socket.set_read_timeout(Some(Duration::from_secs(CLINET_READ_TIMEOUT_SECONDS)))?;
|
||||
|
||||
let encoded_buf = postcard::to_stdvec(&request)?;
|
||||
|
||||
socket.send(encoded_buf.as_slice())?;
|
||||
|
||||
let mut recv_buf: Vec<u8> = Vec::with_capacity(1024);
|
||||
|
||||
loop {
|
||||
match socket.recv(recv_buf.as_mut_slice()) {
|
||||
Ok(rec_count) => {
|
||||
if rec_count != 0 {
|
||||
println!("DEBUG: Total bytes recieved {}", rec_count);
|
||||
let decoded_resp: BzzResp = postcard::from_bytes(&recv_buf)?;
|
||||
if let BzzResp::Working(progress) = decoded_resp {
|
||||
println!("Working... {}", progress);
|
||||
continue;
|
||||
} else {
|
||||
return Ok(decoded_resp);
|
||||
}
|
||||
} else {
|
||||
return Err(IntercomError::ConnectionClosed);
|
||||
}
|
||||
}
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn client_updates_available() -> Result<u32, IntercomError> {
|
||||
let resp = send_and_recv(BzzReq::UpdatesAvailable)?;
|
||||
match resp {
|
||||
BzzResp::UpdatesAvailable(updates_count) => Ok(updates_count),
|
||||
BzzResp::Error(ex) => Err(IntercomError::ServerError(ex)),
|
||||
_ => Err(IntercomError::UnexpectedResponse),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn client_check_for_updates() -> Result<u32, IntercomError> {
|
||||
let resp = send_and_recv(BzzReq::CheckForUpdates)?;
|
||||
match resp {
|
||||
BzzResp::UpdatesAvailable(updates_count) => Ok(updates_count),
|
||||
BzzResp::Error(ex) => Err(IntercomError::ServerError(ex)),
|
||||
_ => 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),
|
||||
}
|
||||
}
|
||||
+134
-116
@@ -143,53 +143,72 @@ pub fn exec_command_out(cmd: &str, args: &Vec<&str>) -> Result<String, ExecComma
|
||||
/// pacman -Sy
|
||||
/// pacman -Qu
|
||||
/// returns number of updatable packages, returns 0 if there is no updates awailable
|
||||
pub fn check_updates() -> Result<u32, ExecCommandError> {
|
||||
// Synchronize pacman DB
|
||||
exec_command("pacman", &vec!["-Sy"])?;
|
||||
// Check for updates
|
||||
let out = Command::new("pacman").arg("-Qu").output()?;
|
||||
if out.status.success() {
|
||||
Ok(String::from_utf8(out.stdout)?
|
||||
.lines()
|
||||
.count()
|
||||
.try_into()
|
||||
.unwrap())
|
||||
} else {
|
||||
if let Some(code) = out.status.code()
|
||||
&& code == 1
|
||||
{
|
||||
Ok(0)
|
||||
} else {
|
||||
Err(ExecCommandError::Other(format!(
|
||||
"pacman -Qu failed: {}",
|
||||
String::from_utf8(out.stderr)?
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
// pub fn check_updates() -> Result<u32, ExecCommandError> {
|
||||
// // Synchronize pacman DB
|
||||
// exec_command("pacman", &vec!["-Sy"])?;
|
||||
// // Check for updates
|
||||
// let out = Command::new("pacman").arg("-Qu").output()?;
|
||||
// if out.status.success() {
|
||||
// Ok(String::from_utf8(out.stdout)?
|
||||
// .lines()
|
||||
// .count()
|
||||
// .try_into()
|
||||
// .unwrap())
|
||||
// } else {
|
||||
// if let Some(code) = out.status.code()
|
||||
// && code == 1
|
||||
// {
|
||||
// Ok(0)
|
||||
// } else {
|
||||
// Err(ExecCommandError::Other(format!(
|
||||
// "pacman -Qu failed: {}",
|
||||
// String::from_utf8(out.stderr)?
|
||||
// )))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
///
|
||||
/// sudo pacman -Suw --noconfirm --noprogressbar
|
||||
/// Download updates (need to check for updates first)
|
||||
///
|
||||
pub fn download_updates() -> Result<(), ExecCommandError> {
|
||||
exec_command("pacman", &vec!["-Suw", "--noconfirm", "--noprogressbar"])
|
||||
}
|
||||
// pub fn download_updates() -> Result<(), ExecCommandError> {
|
||||
// exec_command("pacman", &vec!["-Suw", "--noconfirm", "--noprogressbar"])
|
||||
// }
|
||||
|
||||
///
|
||||
/// sudo pacman -Su --noconfirm --noprogressbar
|
||||
/// Perform updates
|
||||
///
|
||||
pub fn pkg_upgrade() -> Result<(), ExecCommandError> {
|
||||
exec_command("pacman", &vec!["-Su", "--noconfirm", "--noprogressbar"])
|
||||
}
|
||||
// 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;
|
||||
@@ -246,72 +264,72 @@ pub fn check_if_run_as_root() -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SysUpgradeError {
|
||||
SnapshotError(ExecCommandError),
|
||||
PkgUpgradeErr((String, ExecCommandError)),
|
||||
}
|
||||
// #[derive(Debug)]
|
||||
// pub enum SysUpgradeError {
|
||||
// SnapshotError(ExecCommandError),
|
||||
// PkgUpgradeErr((String, ExecCommandError)),
|
||||
// }
|
||||
|
||||
impl std::fmt::Display for SysUpgradeError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
SysUpgradeError::SnapshotError(e) => write!(f, "Snapshot creation error: {}", e),
|
||||
SysUpgradeError::PkgUpgradeErr((_, e)) => write!(f, "Packages upgrade error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
// impl std::fmt::Display for SysUpgradeError {
|
||||
// fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
// match self {
|
||||
// SysUpgradeError::SnapshotError(e) => write!(f, "Snapshot creation error: {}", e),
|
||||
// SysUpgradeError::PkgUpgradeErr((_, e)) => write!(f, "Packages upgrade error: {}", e),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Implement std::error::Error
|
||||
impl std::error::Error for SysUpgradeError {}
|
||||
// // Implement std::error::Error
|
||||
// impl std::error::Error for SysUpgradeError {}
|
||||
|
||||
///
|
||||
/// Perform system upgrade
|
||||
/// Reruns root snapshot name on success
|
||||
/// In case of upgrade error SysUpgradeError::PkgUpgradeErr contains snapshot time is str format
|
||||
///
|
||||
pub fn sys_upgrade() -> Result<String, SysUpgradeError> {
|
||||
// snapshooting root
|
||||
let snap_time = snapshot_root().map_err(SysUpgradeError::SnapshotError)?;
|
||||
// try to perform packages upgrade
|
||||
match pkg_upgrade() {
|
||||
Ok(_) => Ok(snap_time),
|
||||
Err(ex) => Err(SysUpgradeError::PkgUpgradeErr((snap_time, ex))),
|
||||
}
|
||||
}
|
||||
// pub fn sys_upgrade() -> Result<String, SysUpgradeError> {
|
||||
// // snapshooting root
|
||||
// let snap_time = snapshot_system().map_err(SysUpgradeError::SnapshotError)?;
|
||||
// // try to perform packages upgrade
|
||||
// match pkg_upgrade() {
|
||||
// Ok(_) => Ok(snap_time),
|
||||
// Err(ex) => Err(SysUpgradeError::PkgUpgradeErr((snap_time, ex))),
|
||||
// }
|
||||
// }
|
||||
|
||||
/// 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();
|
||||
|
||||
+41
-115
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use clap::{Parser, Subcommand};
|
||||
use signal_hook;
|
||||
use std;
|
||||
use std::sync::Arc;
|
||||
@@ -24,21 +24,11 @@ mod hive_system;
|
||||
|
||||
mod hive_config;
|
||||
|
||||
use crate::hive_config::HiveConfig;
|
||||
use crate::hive_system::SysUpgradeError;
|
||||
|
||||
mod daemon;
|
||||
mod hive_db;
|
||||
mod hive_intercom;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum HiveUpError {
|
||||
IoError(std::io::Error),
|
||||
HiveSystemCommandError(hive_system::ExecCommandError),
|
||||
HiveDbError(hive_db::DBError),
|
||||
HiveConfigError(hive_config::ConfigError),
|
||||
HiveIntercomError(hive_intercom::IntercomError),
|
||||
HiveDaemonErr(daemon::DaemonError),
|
||||
Other(String),
|
||||
}
|
||||
|
||||
@@ -54,30 +44,12 @@ impl From<hive_system::ExecCommandError> for HiveUpError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hive_db::DBError> for HiveUpError {
|
||||
fn from(err: hive_db::DBError) -> Self {
|
||||
HiveUpError::HiveDbError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hive_config::ConfigError> for HiveUpError {
|
||||
fn from(err: hive_config::ConfigError) -> Self {
|
||||
HiveUpError::HiveConfigError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hive_intercom::IntercomError> for HiveUpError {
|
||||
fn from(err: hive_intercom::IntercomError) -> Self {
|
||||
HiveUpError::HiveIntercomError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<daemon::DaemonError> for HiveUpError {
|
||||
fn from(err: daemon::DaemonError) -> Self {
|
||||
HiveUpError::HiveDaemonErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for HiveUpError {
|
||||
fn from(err: String) -> Self {
|
||||
HiveUpError::Other(err)
|
||||
@@ -95,10 +67,7 @@ impl std::fmt::Display for HiveUpError {
|
||||
match self {
|
||||
HiveUpError::IoError(e) => write!(f, "IO Error: {}", e),
|
||||
HiveUpError::HiveSystemCommandError(e) => write!(f, "ExecCommandError: {}", e),
|
||||
HiveUpError::HiveDbError(ex) => write!(f, "DBError: {}", ex),
|
||||
HiveUpError::HiveConfigError(ex) => write!(f, "Config error: {}", ex),
|
||||
HiveUpError::HiveIntercomError(e) => write!(f, "IntercomError: {}", e),
|
||||
HiveUpError::HiveDaemonErr(e) => write!(f, "HiveDaemonErr: {}", e),
|
||||
HiveUpError::Other(msg) => write!(f, "Error: {}", msg),
|
||||
}
|
||||
}
|
||||
@@ -107,49 +76,34 @@ impl std::fmt::Display for HiveUpError {
|
||||
// Implement std::error::Error
|
||||
impl std::error::Error for HiveUpError {}
|
||||
|
||||
// Define the mutually exclusive group
|
||||
#[derive(Args, Debug)]
|
||||
#[group(required = true, multiple = false)]
|
||||
struct RemoteArgs {
|
||||
/// Ask daemon to check for updates
|
||||
#[arg(long)]
|
||||
check_updates: bool,
|
||||
|
||||
/// Ask daemon if there is any updates available
|
||||
#[arg(long)]
|
||||
updates_avail: bool,
|
||||
|
||||
/// Ask daemon to perform system update on next reboot
|
||||
#[arg(long)]
|
||||
schedule_update: bool,
|
||||
#[derive(Subcommand, Debug)]
|
||||
#[group(required = true)]
|
||||
enum BootCommand {
|
||||
/// Install new kernel into boot partition
|
||||
Update,
|
||||
/// Cleans up and recreates UFI boot menu
|
||||
EfiMenuInit,
|
||||
/// Cleans up and recreates UFI boot menu and /EFI dir content
|
||||
Init,
|
||||
}
|
||||
|
||||
#[derive(Args, Debug)]
|
||||
#[group(required = true, multiple = false)]
|
||||
struct CliArgs {
|
||||
/// Perform system upgrade
|
||||
#[arg(long)]
|
||||
upgrade: bool,
|
||||
/// Install new kernel into boot partition
|
||||
#[arg(long)]
|
||||
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)]
|
||||
#[group(required = true)]
|
||||
enum Pac {
|
||||
/// Creates snapshoots of /usr and /var subvolumea
|
||||
SnapshotSystem,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
#[group(required = true)] // 'multiple = false' enforces exclusivity
|
||||
enum HiveUpMode {
|
||||
/// Perform local operations
|
||||
Cli(CliArgs),
|
||||
/// Ask hive-up daemon something
|
||||
Remote(RemoteArgs),
|
||||
/// Run hive-up in daemon mode
|
||||
Daemon,
|
||||
/// Manage system boot
|
||||
#[command(subcommand)]
|
||||
Boot(BootCommand),
|
||||
|
||||
/// Intended to be used by pacman hooks
|
||||
#[command(subcommand)]
|
||||
Pac(Pac),
|
||||
}
|
||||
|
||||
/// Update program fot Kira Linux :3
|
||||
@@ -161,37 +115,14 @@ struct Cli {
|
||||
mode: HiveUpMode,
|
||||
}
|
||||
|
||||
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 {
|
||||
println!("Starting full system upgrade");
|
||||
match hive_system::sys_upgrade() {
|
||||
Ok(snap_time) => {
|
||||
bzz_db.update_status = true;
|
||||
bzz_db.update_on_reboot = false;
|
||||
bzz_db.last_snapshot_time = snap_time;
|
||||
hive_db::write_db(&bzz_db)?;
|
||||
}
|
||||
Err(SysUpgradeError::PkgUpgradeErr((snap_time, ex))) => {
|
||||
bzz_db.update_status = false;
|
||||
bzz_db.update_on_reboot = false;
|
||||
bzz_db.last_snapshot_time = snap_time;
|
||||
hive_db::write_db(&bzz_db)?;
|
||||
return Err(ex.into());
|
||||
}
|
||||
Err(ex) => return Err(ex.to_string().into()),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> Result<(), HiveUpError> {
|
||||
// registering signals handling
|
||||
// we really do not want for this program to get terminated in a middle of something,
|
||||
// so doing nothing with signals.
|
||||
// second sigtrm should kill it tho
|
||||
let term_flag: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
|
||||
let reload_flag = Arc::new(AtomicBool::new(false));
|
||||
signal_hook::flag::register(signal_hook::consts::SIGTERM, Arc::clone(&term_flag)).unwrap();
|
||||
signal_hook::flag::register(signal_hook::consts::SIGINT, Arc::clone(&term_flag)).unwrap();
|
||||
signal_hook::flag::register(signal_hook::consts::SIGHUP, Arc::clone(&reload_flag)).unwrap();
|
||||
|
||||
let args = Cli::parse();
|
||||
|
||||
@@ -203,35 +134,30 @@ fn main() -> Result<(), HiveUpError> {
|
||||
let bzz_config = hive_config::read_config()?;
|
||||
|
||||
match args.mode {
|
||||
HiveUpMode::Daemon => daemon::run(bzz_config, term_flag.clone(), reload_flag.clone())?,
|
||||
HiveUpMode::Cli(cli_args) => {
|
||||
if cli_args.upgrade {
|
||||
cli_upgrade(bzz_config)?;
|
||||
} else if cli_args.update_boot {
|
||||
HiveUpMode::Boot(boot_submode) => match boot_submode {
|
||||
BootCommand::Update => {
|
||||
println!("Updating boot...");
|
||||
hive_system::boot_update()?;
|
||||
} else if cli_args.init_boot_menu {
|
||||
}
|
||||
BootCommand::EfiMenuInit => {
|
||||
println!("Init EFI boot menu...");
|
||||
hive_system::init_efi_boot_record(&bzz_config.kernel.cmd)?;
|
||||
} else if cli_args.init_boot {
|
||||
let kernel_cmd = bzz_config.kernel.and_then(|kk| kk.cmd.clone());
|
||||
hive_system::init_efi_boot_record(&kernel_cmd)?;
|
||||
}
|
||||
BootCommand::Init => {
|
||||
println!("Init EFI boot menu and EFI partition content...");
|
||||
println!("Init EFI Partition content...");
|
||||
hive_system::init_efi_boot_record(&bzz_config.kernel.cmd)?;
|
||||
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) => {
|
||||
if remote_args.check_updates {
|
||||
let up_num = hive_intercom::client_check_for_updates()?;
|
||||
println!("Updates awailable: {}", up_num);
|
||||
} else if remote_args.updates_avail {
|
||||
let up_num = hive_intercom::client_updates_available()?;
|
||||
println!("Updates awailable: {}", up_num);
|
||||
} else if remote_args.schedule_update {
|
||||
println!("Scheduling system update...");
|
||||
hive_intercom::client_schedule_update()?;
|
||||
print!("Done!")
|
||||
},
|
||||
HiveUpMode::Pac(pac_mode) => match pac_mode {
|
||||
Pac::SnapshotSystem => {
|
||||
println!("Creating system snapshot...");
|
||||
let _ = hive_system::snapshot_system()?;
|
||||
println!("Ok.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user