From ec3f78b8cdb4cdc73c9d679d3861d695bf04b8f8 Mon Sep 17 00:00:00 2001 From: plazmoid Date: Mon, 25 Oct 2021 02:16:36 +0500 Subject: [PATCH] fuck web, tui init --- Cargo.toml | 4 +- bin/u_panel/Cargo.toml | 8 ++- bin/u_panel/src/argparse.rs | 7 +- bin/u_panel/src/main.rs | 1 + bin/u_panel/src/tui/mod.rs | 82 +++++++++++++++++++++++ bin/u_panel/src/tui/state.rs | 53 +++++++++++++++ bin/u_panel/src/tui/ui.rs | 26 +++++++ integration/tests/tests.rs | 14 ++-- lib/u_lib/src/errors/variants.rs | 3 + {integration => scripts}/get_docker_ip.sh | 0 10 files changed, 187 insertions(+), 11 deletions(-) create mode 100644 bin/u_panel/src/tui/mod.rs create mode 100644 bin/u_panel/src/tui/state.rs create mode 100644 bin/u_panel/src/tui/ui.rs rename {integration => scripts}/get_docker_ip.sh (100%) diff --git a/Cargo.toml b/Cargo.toml index 9cb212d..c22386b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,8 +2,8 @@ members = [ "bin/u_agent", "bin/u_panel", - "bin/u_panel/be", - "bin/u_panel/fe", + #"bin/u_panel/be", + #"bin/u_panel/fe", "bin/u_run", "bin/u_server", "lib/u_lib", diff --git a/bin/u_panel/Cargo.toml b/bin/u_panel/Cargo.toml index 511cdbf..c357f5a 100644 --- a/bin/u_panel/Cargo.toml +++ b/bin/u_panel/Cargo.toml @@ -14,5 +14,9 @@ uuid = "0.6.5" serde_json = "1.0.4" serde = { version = "1.0.114", features = ["derive"] } tokio = "1.11.0" -be = { version = "*", path = "./be" } -u_lib = { version = "*", path = "../../lib/u_lib" } \ No newline at end of file +# be = { version = "*", path = "./be" } +u_lib = { version = "*", path = "../../lib/u_lib" } +tui = { version = "0.16", default-features = false, features = ['crossterm'] } +crossterm = "0.22.1" +anyhow = "1.0.44" +strum = { version = "0.22.0", features = ["derive"] } diff --git a/bin/u_panel/src/argparse.rs b/bin/u_panel/src/argparse.rs index 03cfb2b..b3df203 100644 --- a/bin/u_panel/src/argparse.rs +++ b/bin/u_panel/src/argparse.rs @@ -19,7 +19,7 @@ enum Cmd { Agents(LD), Jobs(JobALD), Jobmap(JobMapALD), - Server, + TUI, } #[derive(StructOpt, Debug)] @@ -101,7 +101,7 @@ pub async fn process_cmd(args: Args) -> UResult<()> { } let token = env::var("ADMIN_AUTH_TOKEN").map_err(|_| UError::WrongToken)?; - let cli_handler = ClientHandler::new(None).password(token); + let cli_handler = ClientHandler::new(None).password(token.clone()); let printer = Printer { json: args.json }; match args.cmd { Cmd::Agents(action) => match action { @@ -131,7 +131,8 @@ pub async fn process_cmd(args: Args) -> UResult<()> { JobMapALD::List { uid } => printer.print(cli_handler.get_agent_jobs(uid).await), JobMapALD::Delete { uid } => printer.print(cli_handler.del(Some(uid)).await), }, - Cmd::Server => be::serve().unwrap(), + //Cmd::Server => be::serve().unwrap(), + Cmd::TUI => crate::tui::init_tui(token).map_err(|e| UError::TUIError(e.to_string()))?, } Ok(()) } diff --git a/bin/u_panel/src/main.rs b/bin/u_panel/src/main.rs index 0ab0a09..65fe81d 100644 --- a/bin/u_panel/src/main.rs +++ b/bin/u_panel/src/main.rs @@ -1,4 +1,5 @@ mod argparse; +mod tui; use argparse::{process_cmd, Args}; use std::process; diff --git a/bin/u_panel/src/tui/mod.rs b/bin/u_panel/src/tui/mod.rs new file mode 100644 index 0000000..2cd7c6b --- /dev/null +++ b/bin/u_panel/src/tui/mod.rs @@ -0,0 +1,82 @@ +mod state; +mod ui; + +use anyhow::Result; +use crossterm::event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}; +use crossterm::execute; +use crossterm::terminal::{ + disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, +}; +use state::State; +use std::panic::set_hook; +use std::process::exit; +use std::{ + io::{stdout, Stdout}, + sync::mpsc, + thread, + time::Duration, +}; +use tui::{backend::CrosstermBackend, Terminal}; + +type Frame<'f> = tui::Frame<'f, CrosstermBackend>; + +pub fn init_tui(token: String) -> Result<()> { + //TODO: fix this + set_hook(Box::new(|p| { + teardown().unwrap(); + eprintln!("{}", p); + exit(254); + })); + let mut state = State::new(token); + if let Err(e) = init(&mut state) { + teardown()?; + return Err(e); + } + Ok(()) +} + +fn init(state: &mut State) -> Result<()> { + let mut stdout = stdout(); + enable_raw_mode()?; + execute!(&mut stdout, EnterAlternateScreen, EnableMouseCapture)?; + + let backend = CrosstermBackend::new(stdout); + let mut terminal = Terminal::new(backend)?; + let (tx, rx) = mpsc::channel(); + + thread::spawn(move || loop { + if event::poll(Duration::from_millis(10)).unwrap() { + match event::read().unwrap() { + key @ Event::Key(_) => tx.send(key).unwrap(), + _ => (), + } + } + }); + + terminal.clear()?; + + loop { + terminal.draw(|f| ui::draw(f, state))?; + match rx.recv()? { + Event::Key(key) => match key.code { + KeyCode::Esc => { + teardown()?; + terminal.show_cursor()?; + break; + } + KeyCode::Left => state.prev_tab(), + KeyCode::Right => state.next_tab(), + _ => (), + }, + _ => unreachable!(), + } + } + Ok(()) +} + +fn teardown() -> Result<()> { + disable_raw_mode()?; + execute!(stdout(), LeaveAlternateScreen, DisableMouseCapture)?; + eprintln!("teardown"); + Ok(()) +} diff --git a/bin/u_panel/src/tui/state.rs b/bin/u_panel/src/tui/state.rs new file mode 100644 index 0000000..d72fbb4 --- /dev/null +++ b/bin/u_panel/src/tui/state.rs @@ -0,0 +1,53 @@ +use std::str::FromStr; +use strum::VariantNames; + +#[derive(strum::Display, strum::EnumVariantNames, strum::EnumString)] +pub enum UiTabs { + Agents, + Jobs, + Map, +} + +impl UiTabs { + pub fn variants() -> &'static [&'static str] { + Self::VARIANTS + } + + pub fn index(&self) -> usize { + let ss = self.to_string(); + Self::VARIANTS.iter().position(|el| **el == ss).unwrap() + } + + pub fn next(&self) -> Self { + let next_idx = (self.index() + 1) % Self::VARIANTS.len(); + Self::from_str(Self::VARIANTS[next_idx]).unwrap() + } + + pub fn prev(&self) -> Self { + let vlen = Self::VARIANTS.len(); + let next_idx = (self.index() + vlen - 1) % vlen; + Self::from_str(Self::VARIANTS[next_idx]).unwrap() + } +} + +pub struct State { + pub token: String, + pub active_tab: UiTabs, +} + +impl State { + pub fn new(token: String) -> Self { + State { + token, + active_tab: UiTabs::Agents, + } + } + + pub fn next_tab(&mut self) { + self.active_tab = self.active_tab.next() + } + + pub fn prev_tab(&mut self) { + self.active_tab = self.active_tab.prev() + } +} diff --git a/bin/u_panel/src/tui/ui.rs b/bin/u_panel/src/tui/ui.rs new file mode 100644 index 0000000..0341afe --- /dev/null +++ b/bin/u_panel/src/tui/ui.rs @@ -0,0 +1,26 @@ +use super::{ + state::{State, UiTabs}, + Frame, +}; +use tui::style::{Color, Style}; +use tui::text::Spans; +use tui::widgets::{Block, Borders, Tabs}; + +pub fn draw(f: &mut Frame, s: &mut State) { + let titles = UiTabs::variants() + .iter() + .cloned() + .map(Spans::from) + .collect(); + let tabs = Tabs::new(titles) + .block( + Block::default() + .title("The whole that you need to know") + .borders(Borders::ALL), + ) + .style(Style::default().fg(Color::White)) + .highlight_style(Style::default().fg(Color::Yellow)) + .divider("-") + .select(s.active_tab.index()); + f.render_widget(tabs, f.size()) +} diff --git a/integration/tests/tests.rs b/integration/tests/tests.rs index 32fcc9f..39293f6 100644 --- a/integration/tests/tests.rs +++ b/integration/tests/tests.rs @@ -11,11 +11,17 @@ extern crate rstest; #[tokio::test] async fn test_non_auth_connection_dropped() { let env_server = env::var("U_SERVER").unwrap(); - match reqwest::get(format!("https://{}:{}", env_server, MASTER_PORT)).await { + let client = reqwest::ClientBuilder::new() + .danger_accept_invalid_certs(true) + .build() + .unwrap(); + match client + .get(format!("https://{}:{}", env_server, MASTER_PORT)) + .send() + .await + { Err(e) => { - assert!(e - .to_string() - .contains("unable to get local issuer certificate")) + assert!(e.to_string().contains("channel closed")) } _ => panic!("no error occured on foreign client connection"), } diff --git a/lib/u_lib/src/errors/variants.rs b/lib/u_lib/src/errors/variants.rs index 0819a96..d84db3a 100644 --- a/lib/u_lib/src/errors/variants.rs +++ b/lib/u_lib/src/errors/variants.rs @@ -65,6 +65,9 @@ pub enum UError { #[error("Panicked: {0}")] Panic(String), + + #[error("UI init error: {0}")] + TUIError(String), } impl UError { diff --git a/integration/get_docker_ip.sh b/scripts/get_docker_ip.sh similarity index 100% rename from integration/get_docker_ip.sh rename to scripts/get_docker_ip.sh