Added snapshoot selection.

This commit is contained in:
2026-06-22 00:56:09 +02:00
parent 121cd90988
commit c758c68f23
2 changed files with 57 additions and 24 deletions
+9
View File
@@ -7,3 +7,12 @@ edition = "2024"
ratatui = { version = "0.30", default-features = false, features = ["termion"] } ratatui = { version = "0.30", default-features = false, features = ["termion"] }
regex = "1.12.4" regex = "1.12.4"
termion = "4" termion = "4"
[profile.release]
lto = true
debug = false
incremental = false
codegen-units = 1
opt-level = 3
strip = true
+46 -22
View File
@@ -15,29 +15,28 @@
// 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 ratatui::widgets::Borders; use ratatui::widgets::Borders;
use ratatui::{Frame, Terminal, backend::TermionBackend, border, widgets::Paragraph}; use ratatui::{Frame, Terminal, backend::TermionBackend, widgets::Paragraph};
use ratatui::{ use ratatui::{
buffer::Buffer, layout::{Constraint, Layout},
layout::{Constraint, Layout, Rect},
style::{Style, Stylize}, style::{Style, Stylize},
symbols::border, text::{Line},
text::{Line, Text}, widgets::{Block, List, ListState},
widgets::{Block, List, ListState, Widget},
}; };
use std::io::{self, Read, stdout}; use std::io::{self, Read, stdout};
use std::process::ExitCode; use std::process::ExitCode;
use std::thread;
use std::time::Duration;
use termion::event::{Event, Key}; use termion::event::{Event, Key};
use termion::input::TermRead; // Required for .keys()
use termion::raw::IntoRawMode; use termion::raw::IntoRawMode;
mod nyan_system; mod nyan_system;
use nyan_system::{ExecCommandError, exec_command}; use nyan_system::{ExecCommandError};
const BEE_CAT: &str = include_str!("bee_cat.txt"); const BEE_CAT: &str = include_str!("bee_cat.txt");
const ROOT_PARTLABEL: &str = "bee-root"; //const ROOT_PARTLABEL: &str = "bee-root";
const ROOT_DEV: &str = "/dev/disk/by-partlabel/bee-root"; const ROOT_DEV: &str = "/dev/disk/by-partlabel/bee-root";
const TMP_ROOT: &str = "/mnt/bee_root"; const TMP_ROOT: &str = "/mnt/bee_root";
const TMP_ROOT_SNAPS: &str = "/mnt/bee-root/bzz_snaps"; const TMP_ROOT_SNAPS: &str = "/mnt/bee-root/bzz_snaps";
@@ -72,7 +71,7 @@ enum NyanitState {
HandOff(String), HandOff(String),
} }
pub fn init_stage() -> Result<NyanitState, ExecCommandError> { fn init_stage() -> Result<NyanitState, ExecCommandError> {
// mount sysfss // mount sysfss
nyan_system::prepare_env()?; nyan_system::prepare_env()?;
@@ -87,9 +86,10 @@ pub fn init_stage() -> Result<NyanitState, ExecCommandError> {
nyan_system::mount_bee_root(TMP_ROOT, ROOT_DEV)?; nyan_system::mount_bee_root(TMP_ROOT, ROOT_DEV)?;
// list snaps if any // list snaps if any
let snaps_list = nyan_system::list_bzzpss_snaps(TMP_ROOT_SNAPS)?; let mut snaps_list = nyan_system::list_bzzpss_snaps(TMP_ROOT_SNAPS)?;
// if any snaps detected whait for user to press F2 // if any snaps detected whait for user to press F2
if snaps_list.len() > 0 { if snaps_list.len() > 0 {
snaps_list.insert(0, TMP_ROOT.to_string());
return Ok(NyanitState::WaitForF2(snaps_list)); return Ok(NyanitState::WaitForF2(snaps_list));
} }
@@ -98,19 +98,19 @@ pub fn init_stage() -> Result<NyanitState, ExecCommandError> {
} }
pub struct NyanitTUI { pub struct NyanitTUI {
counter: u32,
exit: bool, exit: bool,
state: NyanitState, state: NyanitState,
list_state: ListState, list_state: ListState,
time_counter: u32,
} }
impl NyanitTUI { impl NyanitTUI {
pub fn new() -> io::Result<Self> { pub fn new() -> io::Result<Self> {
Ok(Self { Ok(Self {
counter: 0,
exit: false, exit: false,
state: NyanitState::Init, state: NyanitState::Init,
list_state: ListState::default().with_selected(Some(0)), list_state: ListState::default().with_selected(Some(0)),
time_counter: 0,
}) })
} }
@@ -140,10 +140,12 @@ impl NyanitTUI {
let mut terminal = Terminal::new(backend)?; let mut terminal = Terminal::new(backend)?;
// init tty input and start actually drawing things now! // init tty input and start actually drawing things now!
let mut tty_input: io::Bytes<std::fs::File> = termion::get_tty()?.bytes(); let mut tty_input_async = termion::async_stdin().bytes();
self.time_counter = 0;
while !self.exit { while !self.exit {
terminal.draw(|frame| self.draw(frame))?; terminal.draw(|frame| self.draw(frame))?;
self.handle_events(&mut tty_input)?; self.handle_events(&mut tty_input_async)?;
} }
Ok(()) Ok(())
} }
@@ -209,19 +211,41 @@ impl NyanitTUI {
}; };
} }
fn handle_events(&mut self, tty_input: &mut io::Bytes<std::fs::File>) -> io::Result<()> { fn handle_events(&mut self, tty_input: &mut io::Bytes<termion::AsyncReader>) -> io::Result<()> {
// cheking if there is any input to read
if let Some(item) = tty_input.next() { if let Some(item) = tty_input.next() {
let read_byte = item?; let read_byte = item?;
let e = termion::event::parse_event(read_byte, tty_input)?; let e = termion::event::parse_event(read_byte, tty_input)?;
match &self.state {
NyanitState::WaitForF2(vol_list) => {
if e == Event::Key(Key::F(2)) {
self.state = NyanitState::ChooseSnapshot(vol_list.clone());
}
},
NyanitState::ChooseSnapshot(vol_list) => {
match e { match e {
Event::Key(Key::Up) => { Event::Key(Key::Down) => self.list_state.select_next(),
self.counter += 1; Event::Key(Key::Up) => self.list_state.select_previous(),
} Event::Key(Key::Char('\n')) => if let Some(idx) = self.list_state.selected() {
Event::Key(Key::Down) => { self.state = NyanitState::HandOff(vol_list[idx].clone());
self.counter = self.counter.saturating_sub(1u32); },
}
_ => (), _ => (),
} }
},
_ => ()
}
}
else {
// Tick time
thread::sleep(Duration::from_millis(500));
self.time_counter = self.time_counter.wrapping_add(1u32);
// 2.5 sec wait
if self.time_counter > 5 {
// boot from root
self.state = NyanitState::HandOff(TMP_ROOT.into());
}
} }
Ok(()) Ok(())
} }