diff --git a/Makefile.toml b/Makefile.toml index 0b4f13a..08e5742 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -35,7 +35,7 @@ script = "./scripts/build_musl_libs.sh" [tasks.build_frontend] script = ''' -cd ./bin/u_panel/src/server/fe +cd ./bin/u_panel/src/gui/fe ng build ''' diff --git a/bin/u_agent/Cargo.toml b/bin/u_agent/Cargo.toml index 28bb75a..3b16a92 100644 --- a/bin/u_agent/Cargo.toml +++ b/bin/u_agent/Cargo.toml @@ -7,8 +7,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -daemonize = "0.4.1" -log = "^0.4" +log = { version = "0.4", features = ["release_max_level_off"] } reqwest = { workspace = true } sysinfo = "0.10.5" tokio = { workspace = true, features = ["macros", "rt-multi-thread", "process", "time"] } diff --git a/bin/u_agent/src/lib.rs b/bin/u_agent/src/lib.rs index 32072f2..1fd93e8 100644 --- a/bin/u_agent/src/lib.rs +++ b/bin/u_agent/src/lib.rs @@ -5,14 +5,18 @@ #[macro_use] extern crate log; -use daemonize::Daemonize; -use std::sync::Arc; +use std::process::exit; use tokio::runtime::Builder; use tokio::time::{sleep, Duration}; -use u_lib::config; use u_lib::{ - api::ClientHandler, cache::JobCache, config::get_self_uid, errors::ErrChan, - executor::pop_completed, logging::init_logger, messaging::Reportable, models::AssignedJobById, + api::ClientHandler, + cache::JobCache, + config::{endpoints, get_self_uid}, + error::ErrChan, + executor::pop_completed, + logging::init_logger, + messaging::Reportable, + models::AssignedJobById, runner::JobRunner, }; @@ -53,7 +57,7 @@ pub async fn process_request(jobs: Vec, client: &ClientHandler) } } -async fn error_reporting(client: Arc) -> ! { +async fn error_reporting(client: ClientHandler) -> ! { loop { match ErrChan::recv().await { Some(err) => { @@ -72,7 +76,7 @@ async fn error_reporting(client: Arc) -> ! { } } -async fn agent_loop(client: Arc) -> ! { +async fn agent_loop(client: ClientHandler) -> ! { loop { match client.get_personal_jobs(get_self_uid()).await { Ok(jobs) => { @@ -97,9 +101,8 @@ async fn agent_loop(client: Arc) -> ! { } } -pub fn run_forever() { - let env = config::endpoints::load().unwrap(); - let client = Arc::new(ClientHandler::new(&env.u_server, None)); +pub fn run_forever() -> ! { + let env = endpoints::load().unwrap(); if cfg!(debug_assertions) { init_logger(Some(format!( @@ -112,8 +115,10 @@ pub fn run_forever() { .unwrap() ))); } else { - Daemonize::new().start().unwrap(); + #[cfg(unix)] + u_lib::unix::daemonize() } + info!("Starting agent {}", get_self_uid()); Builder::new_multi_thread() @@ -121,7 +126,15 @@ pub fn run_forever() { .build() .unwrap() .block_on(async { - tokio::spawn(error_reporting(client.clone())); - agent_loop(client).await + match ClientHandler::new(&env.u_server, None).await { + Ok(client) => { + tokio::spawn(error_reporting(client.clone())); + agent_loop(client).await + } + Err(e) => { + error!("client init failed: {}", e); + exit(7) + } + } }) } diff --git a/bin/u_panel/src/argparse.rs b/bin/u_panel/src/argparse.rs index 4e43067..ef26792 100644 --- a/bin/u_panel/src/argparse.rs +++ b/bin/u_panel/src/argparse.rs @@ -113,7 +113,7 @@ pub async fn process_cmd(client: ClientHandler, args: Args) -> PanelResult into_value(client.ping().await?), Cmd::Serve => { - crate::server::serve(client) + crate::gui::serve(client) .await .map_err(|e| UError::PanelError(format!("{e:?}")))?; Value::Null diff --git a/bin/u_panel/src/server/error.rs b/bin/u_panel/src/gui/error.rs similarity index 100% rename from bin/u_panel/src/server/error.rs rename to bin/u_panel/src/gui/error.rs diff --git a/bin/u_panel/src/gui/fe/.browserslistrc b/bin/u_panel/src/gui/fe/.browserslistrc new file mode 100644 index 0000000..4f9ac26 --- /dev/null +++ b/bin/u_panel/src/gui/fe/.browserslistrc @@ -0,0 +1,16 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR diff --git a/bin/u_panel/src/gui/fe/.editorconfig b/bin/u_panel/src/gui/fe/.editorconfig new file mode 100644 index 0000000..59d9a3a --- /dev/null +++ b/bin/u_panel/src/gui/fe/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/bin/u_panel/src/server/fe/.gitignore b/bin/u_panel/src/gui/fe/.gitignore similarity index 100% rename from bin/u_panel/src/server/fe/.gitignore rename to bin/u_panel/src/gui/fe/.gitignore diff --git a/bin/u_panel/src/server/fe/README.md b/bin/u_panel/src/gui/fe/README.md similarity index 100% rename from bin/u_panel/src/server/fe/README.md rename to bin/u_panel/src/gui/fe/README.md diff --git a/bin/u_panel/src/server/fe/angular.json b/bin/u_panel/src/gui/fe/angular.json similarity index 100% rename from bin/u_panel/src/server/fe/angular.json rename to bin/u_panel/src/gui/fe/angular.json diff --git a/bin/u_panel/src/server/fe/karma.conf.js b/bin/u_panel/src/gui/fe/karma.conf.js similarity index 100% rename from bin/u_panel/src/server/fe/karma.conf.js rename to bin/u_panel/src/gui/fe/karma.conf.js diff --git a/bin/u_panel/src/server/fe/package.json b/bin/u_panel/src/gui/fe/package.json similarity index 100% rename from bin/u_panel/src/server/fe/package.json rename to bin/u_panel/src/gui/fe/package.json diff --git a/bin/u_panel/src/server/fe/src/app/app-routing.module.ts b/bin/u_panel/src/gui/fe/src/app/app-routing.module.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/app-routing.module.ts rename to bin/u_panel/src/gui/fe/src/app/app-routing.module.ts diff --git a/bin/u_panel/src/server/fe/src/app/app.component.html b/bin/u_panel/src/gui/fe/src/app/app.component.html similarity index 100% rename from bin/u_panel/src/server/fe/src/app/app.component.html rename to bin/u_panel/src/gui/fe/src/app/app.component.html diff --git a/bin/u_panel/src/server/fe/src/app/app.component.less b/bin/u_panel/src/gui/fe/src/app/app.component.less similarity index 100% rename from bin/u_panel/src/server/fe/src/app/app.component.less rename to bin/u_panel/src/gui/fe/src/app/app.component.less diff --git a/bin/u_panel/src/server/fe/src/app/app.component.spec.ts b/bin/u_panel/src/gui/fe/src/app/app.component.spec.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/app.component.spec.ts rename to bin/u_panel/src/gui/fe/src/app/app.component.spec.ts diff --git a/bin/u_panel/src/server/fe/src/app/app.component.ts b/bin/u_panel/src/gui/fe/src/app/app.component.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/app.component.ts rename to bin/u_panel/src/gui/fe/src/app/app.component.ts diff --git a/bin/u_panel/src/server/fe/src/app/app.module.ts b/bin/u_panel/src/gui/fe/src/app/app.module.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/app.module.ts rename to bin/u_panel/src/gui/fe/src/app/app.module.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/index.ts b/bin/u_panel/src/gui/fe/src/app/core/index.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/index.ts rename to bin/u_panel/src/gui/fe/src/app/core/index.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/models/agent.model.ts b/bin/u_panel/src/gui/fe/src/app/core/models/agent.model.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/models/agent.model.ts rename to bin/u_panel/src/gui/fe/src/app/core/models/agent.model.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/models/index.ts b/bin/u_panel/src/gui/fe/src/app/core/models/index.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/models/index.ts rename to bin/u_panel/src/gui/fe/src/app/core/models/index.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/models/job.model.ts b/bin/u_panel/src/gui/fe/src/app/core/models/job.model.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/models/job.model.ts rename to bin/u_panel/src/gui/fe/src/app/core/models/job.model.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/models/result.model.ts b/bin/u_panel/src/gui/fe/src/app/core/models/result.model.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/models/result.model.ts rename to bin/u_panel/src/gui/fe/src/app/core/models/result.model.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/services/api.service.ts b/bin/u_panel/src/gui/fe/src/app/core/services/api.service.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/services/api.service.ts rename to bin/u_panel/src/gui/fe/src/app/core/services/api.service.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/services/index.ts b/bin/u_panel/src/gui/fe/src/app/core/services/index.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/services/index.ts rename to bin/u_panel/src/gui/fe/src/app/core/services/index.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/agent.component.html b/bin/u_panel/src/gui/fe/src/app/core/tables/agent.component.html similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/agent.component.html rename to bin/u_panel/src/gui/fe/src/app/core/tables/agent.component.html diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/agent.component.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/agent.component.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/agent.component.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/agent.component.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/agent-info-dialog.html b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/agent-info-dialog.html similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/agent-info-dialog.html rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/agent-info-dialog.html diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/agent_info.component.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/agent_info.component.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/agent_info.component.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/agent_info.component.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/assign-job-dialog.html b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/assign-job-dialog.html similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/assign-job-dialog.html rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/assign-job-dialog.html diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/assign_job.component.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/assign_job.component.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/assign_job.component.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/assign_job.component.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/index.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/index.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/index.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/index.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/info-dialog.component.less b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/info-dialog.component.less similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/info-dialog.component.less rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/info-dialog.component.less diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/job-info-dialog.html b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/job-info-dialog.html similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/job-info-dialog.html rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/job-info-dialog.html diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/job_info.component.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/job_info.component.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/job_info.component.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/job_info.component.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/result-info-dialog.html b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/result-info-dialog.html similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/result-info-dialog.html rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/result-info-dialog.html diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/dialogs/result_info.component.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/result_info.component.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/dialogs/result_info.component.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/dialogs/result_info.component.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/index.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/index.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/index.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/index.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/job.component.html b/bin/u_panel/src/gui/fe/src/app/core/tables/job.component.html similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/job.component.html rename to bin/u_panel/src/gui/fe/src/app/core/tables/job.component.html diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/job.component.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/job.component.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/job.component.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/job.component.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/result.component.html b/bin/u_panel/src/gui/fe/src/app/core/tables/result.component.html similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/result.component.html rename to bin/u_panel/src/gui/fe/src/app/core/tables/result.component.html diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/result.component.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/result.component.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/result.component.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/result.component.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/table.component.less b/bin/u_panel/src/gui/fe/src/app/core/tables/table.component.less similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/table.component.less rename to bin/u_panel/src/gui/fe/src/app/core/tables/table.component.less diff --git a/bin/u_panel/src/server/fe/src/app/core/tables/table.component.ts b/bin/u_panel/src/gui/fe/src/app/core/tables/table.component.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/tables/table.component.ts rename to bin/u_panel/src/gui/fe/src/app/core/tables/table.component.ts diff --git a/bin/u_panel/src/server/fe/src/app/core/utils.ts b/bin/u_panel/src/gui/fe/src/app/core/utils.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/app/core/utils.ts rename to bin/u_panel/src/gui/fe/src/app/core/utils.ts diff --git a/bin/u_panel/src/server/fe/src/environments/environment.prod.ts b/bin/u_panel/src/gui/fe/src/environments/environment.prod.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/environments/environment.prod.ts rename to bin/u_panel/src/gui/fe/src/environments/environment.prod.ts diff --git a/bin/u_panel/src/server/fe/src/environments/environment.ts b/bin/u_panel/src/gui/fe/src/environments/environment.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/environments/environment.ts rename to bin/u_panel/src/gui/fe/src/environments/environment.ts diff --git a/bin/u_panel/src/server/fe/src/favicon.ico b/bin/u_panel/src/gui/fe/src/favicon.ico similarity index 100% rename from bin/u_panel/src/server/fe/src/favicon.ico rename to bin/u_panel/src/gui/fe/src/favicon.ico diff --git a/bin/u_panel/src/server/fe/src/index.html b/bin/u_panel/src/gui/fe/src/index.html similarity index 100% rename from bin/u_panel/src/server/fe/src/index.html rename to bin/u_panel/src/gui/fe/src/index.html diff --git a/bin/u_panel/src/server/fe/src/main.ts b/bin/u_panel/src/gui/fe/src/main.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/main.ts rename to bin/u_panel/src/gui/fe/src/main.ts diff --git a/bin/u_panel/src/server/fe/src/polyfills.ts b/bin/u_panel/src/gui/fe/src/polyfills.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/polyfills.ts rename to bin/u_panel/src/gui/fe/src/polyfills.ts diff --git a/bin/u_panel/src/server/fe/src/styles.less b/bin/u_panel/src/gui/fe/src/styles.less similarity index 100% rename from bin/u_panel/src/server/fe/src/styles.less rename to bin/u_panel/src/gui/fe/src/styles.less diff --git a/bin/u_panel/src/server/fe/src/test.ts b/bin/u_panel/src/gui/fe/src/test.ts similarity index 100% rename from bin/u_panel/src/server/fe/src/test.ts rename to bin/u_panel/src/gui/fe/src/test.ts diff --git a/bin/u_panel/src/server/fe/tsconfig.app.json b/bin/u_panel/src/gui/fe/tsconfig.app.json similarity index 100% rename from bin/u_panel/src/server/fe/tsconfig.app.json rename to bin/u_panel/src/gui/fe/tsconfig.app.json diff --git a/bin/u_panel/src/server/fe/tsconfig.json b/bin/u_panel/src/gui/fe/tsconfig.json similarity index 100% rename from bin/u_panel/src/server/fe/tsconfig.json rename to bin/u_panel/src/gui/fe/tsconfig.json diff --git a/bin/u_panel/src/server/fe/tsconfig.spec.json b/bin/u_panel/src/gui/fe/tsconfig.spec.json similarity index 100% rename from bin/u_panel/src/server/fe/tsconfig.spec.json rename to bin/u_panel/src/gui/fe/tsconfig.spec.json diff --git a/bin/u_panel/src/server/mod.rs b/bin/u_panel/src/gui/mod.rs similarity index 98% rename from bin/u_panel/src/server/mod.rs rename to bin/u_panel/src/gui/mod.rs index f613f43..5be4487 100644 --- a/bin/u_panel/src/server/mod.rs +++ b/bin/u_panel/src/gui/mod.rs @@ -11,7 +11,7 @@ use structopt::StructOpt; use u_lib::{api::ClientHandler, unwrap_enum}; #[derive(RustEmbed)] -#[folder = "./src/server/fe/dist/fe/"] +#[folder = "./src/gui/fe/dist/fe/"] struct Files; impl Files { diff --git a/bin/u_panel/src/main.rs b/bin/u_panel/src/main.rs index 9740de3..fa0c980 100644 --- a/bin/u_panel/src/main.rs +++ b/bin/u_panel/src/main.rs @@ -1,5 +1,5 @@ mod argparse; -mod server; +mod gui; #[macro_use] extern crate tracing; @@ -14,7 +14,7 @@ use u_lib::logging::init_logger; #[actix_web::main] async fn main() -> AnyResult<()> { let env = admin::load()?; - let client = ClientHandler::new(&env.u_server, Some(env.admin_auth_token)); + let client = ClientHandler::new(&env.u_server, Some(env.admin_auth_token)).await?; let args = Args::from_args(); init_logger(None::<&str>); diff --git a/bin/u_server/src/handlers.rs b/bin/u_server/src/handlers.rs index b6d0167..bc4eb37 100644 --- a/bin/u_server/src/handlers.rs +++ b/bin/u_server/src/handlers.rs @@ -4,8 +4,8 @@ use crate::db::{PgRepo, UDB}; use crate::error::Error; use u_lib::{ messaging::{AsMsg, BaseMessage, Reportable}, + misc::OneOrVec, models::*, - utils::OneOrVec, }; use uuid::Uuid; use warp::Rejection; @@ -147,6 +147,7 @@ impl Endpoints { None => warn!("Empty agent data"), }, JobType::Shell => (), + JobType::Service => (), JobType::Terminate => todo!(), JobType::Update => todo!(), } diff --git a/bin/u_server/src/u_server.rs b/bin/u_server/src/u_server.rs index 5f45d61..2e60db4 100644 --- a/bin/u_server/src/u_server.rs +++ b/bin/u_server/src/u_server.rs @@ -12,7 +12,7 @@ mod handlers; use db::PgRepo; use error::{Error as ServerError, RejResponse}; use serde::de::DeserializeOwned; -use std::{convert::Infallible, path::PathBuf, sync::Arc}; +use std::{convert::Infallible, sync::Arc}; use u_lib::{ config, db::async_pool, @@ -47,8 +47,10 @@ pub fn init_endpoints( let path = |p: &'static str| warp::post().and(warp::path(p)); let infallible_none = |_| async { Ok::<_, Infallible>((None::,)) }; - let adb = Arc::new(db); - let with_db = warp::any().map(move || adb.clone()); + let with_db = { + let adb = Arc::new(db); + warp::any().map(move || adb.clone()) + }; let get_agents = path("get_agents") .and(with_db.clone()) @@ -179,17 +181,20 @@ pub async fn serve() -> Result<(), ServerError> { preload_jobs(&db).await?; - let certs_dir = PathBuf::from("certs"); let env = config::admin::load().map_err(|e| ServerError::Other(e.to_string()))?; let routes = init_endpoints(&env.admin_auth_token, db) .recover(handle_rejection) .with(custom(logger)); + let server_cert = include_bytes!("../../../certs/server.crt"); + let server_key = include_bytes!("../../../certs/server.key"); + let ca = include_bytes!("../../../certs/ca.crt"); + warp::serve(routes) .tls() - .cert_path(certs_dir.join("server.crt")) - .key_path(certs_dir.join("server.key")) - .client_auth_required_path(certs_dir.join("ca.crt")) + .cert(server_cert) + .key(server_key) + .client_auth_required(ca) .run(([0, 0, 0, 0], config::MASTER_PORT)) .await; Ok(()) diff --git a/deploy/podman-compose.yml b/deploy/podman-compose.yml index 4d23b8c..5e27513 100644 --- a/deploy/podman-compose.yml +++ b/deploy/podman-compose.yml @@ -11,7 +11,6 @@ services: - u_net volumes: - ./u_server:/unki/u_server - - ./certs:/unki/certs - ./logs:/unki/logs:rw working_dir: /unki command: /unki/u_server diff --git a/integration/docker-compose.yml b/integration/docker-compose.yml index a26d9ba..b75bb88 100644 --- a/integration/docker-compose.yml +++ b/integration/docker-compose.yml @@ -16,7 +16,6 @@ services: - u_net volumes: - ../target/x86_64-unknown-linux-musl/${PROFILE:-debug}/u_server:/unki/u_server - - ../certs:/unki/certs - ../logs:/unki/logs:rw working_dir: /unki command: /unki/u_server diff --git a/integration/tests/fixtures/agent.rs b/integration/tests/fixtures/agent.rs index 2e6cdce..dc2689d 100644 --- a/integration/tests/fixtures/agent.rs +++ b/integration/tests/fixtures/agent.rs @@ -8,14 +8,14 @@ pub struct RegisteredAgent { impl RegisteredAgent { pub async fn unregister(self) { - let cli = ClientHandler::new(&ENV.u_server, None); + let cli = ClientHandler::new(&ENV.u_server, None).await.unwrap(); cli.del(self.uid).await.unwrap(); } } #[fixture] pub async fn register_agent() -> RegisteredAgent { - let cli = ClientHandler::new(&ENV.u_server, None); + let cli = ClientHandler::new(&ENV.u_server, None).await.unwrap(); let agent_uid = Uuid::new_v4(); println!("registering agent {agent_uid}"); let resp = cli diff --git a/integration/tests/helpers/panel.rs b/integration/tests/helpers/panel.rs index f8fa576..2de4465 100644 --- a/integration/tests/helpers/panel.rs +++ b/integration/tests/helpers/panel.rs @@ -2,10 +2,7 @@ use serde::de::DeserializeOwned; use serde_json::{from_slice, Value}; use std::fmt::{Debug, Display}; use std::process::{Command, Output}; -use u_lib::{ - datatypes::PanelResult, - utils::{bytes_to_string, ProcOutput}, -}; +use u_lib::{conv::bytes_to_string, datatypes::PanelResult, proc_output::ProcOutput}; const PANEL_BINARY: &str = "/u_panel"; diff --git a/integration/tests/integration/behaviour.rs b/integration/tests/integration/behaviour.rs index 932cb03..35d77b4 100644 --- a/integration/tests/integration/behaviour.rs +++ b/integration/tests/integration/behaviour.rs @@ -4,6 +4,7 @@ use crate::helpers::Panel; use rstest::rstest; use serde_json::{json, to_string}; use std::error::Error; +use std::fs; use std::time::Duration; use tokio::time::sleep; use u_lib::models::*; @@ -13,7 +14,7 @@ type TestResult = Result>; #[rstest] #[tokio::test] -async fn test_registration(#[future] register_agent: RegisteredAgent) -> TestResult { +async fn registration(#[future] register_agent: RegisteredAgent) -> TestResult { let agent = register_agent.await; let agents: Vec = Panel::check_output("agents read"); let found = agents.iter().find(|v| v.id == agent.uid); @@ -23,20 +24,47 @@ async fn test_registration(#[future] register_agent: RegisteredAgent) -> TestRes } #[tokio::test] -async fn test_setup_tasks() -> TestResult { +async fn setup_tasks() -> TestResult { let agents: Vec = Panel::check_output("agents read"); - let agent_uid = match agents.get(0) { - Some(a) => a.id, - None => panic!("Some independent agents should present"), - }; + let agent_uid = agents[0].id; let job_alias = "passwd_contents"; let job = json!( {"alias": job_alias, "payload": b"cat /etc/passwd", "argv": "/bin/bash {}" } ); let cmd = format!("jobs create '{}'", to_string(&job).unwrap()); Panel::check_status(cmd); + let cmd = format!("map create {} {}", agent_uid, job_alias); let assigned_uids: Vec = Panel::check_output(cmd); + + for _ in 0..3 { + let result: Vec = + Panel::check_output(format!("map read {}", assigned_uids[0])); + if result[0].state == JobState::Finished { + return Ok(()); + } else { + sleep(Duration::from_secs(5)).await; + eprintln!("waiting for task"); + } + } + panic!("Job didn't appear in the job map"); +} + +#[tokio::test] +async fn large_payload() -> TestResult { + let agent_uid = Panel::check_output::>("agents read")[0].id; + + let job_alias = "large_payload"; + let payload = fs::read("./tests/bin/echoer").unwrap(); + let job = json!( + {"alias": job_alias, "payload": payload, "argv": "/bin/bash {}" } + ); + let cmd = format!("jobs create '{}'", to_string(&job).unwrap()); + Panel::check_status(cmd); + + let cmd = format!("map create {} {}", agent_uid, job_alias); + let assigned_uids: Vec = Panel::check_output(cmd); + for _ in 0..3 { let result: Vec = Panel::check_output(format!("map read {}", assigned_uids[0])); diff --git a/integration/tests/integration/connection.rs b/integration/tests/integration/connection.rs index 7cfbffc..156a6a1 100644 --- a/integration/tests/integration/connection.rs +++ b/integration/tests/integration/connection.rs @@ -2,7 +2,7 @@ use crate::helpers::ENV; use u_lib::config::MASTER_PORT; #[tokio::test] -async fn test_non_auth_connection_dropped() { +async fn non_auth_connection_dropped() { let client = reqwest::ClientBuilder::new() .danger_accept_invalid_certs(true) .build() diff --git a/lib/u_lib/Cargo.toml b/lib/u_lib/Cargo.toml index 913316a..1324ec6 100644 --- a/lib/u_lib/Cargo.toml +++ b/lib/u_lib/Cargo.toml @@ -18,21 +18,24 @@ futures = "0.3.5" guess_host_triple = "0.1.2" libc = "^0.2" lazy_static = "1.4.0" -log = "*" -nix = "0.17" once_cell = "1.7.2" platforms = "3.0.1" -reqwest = { workspace = true, features = ["native-tls"] } +reqwest = { workspace = true, features = ["native-tls", "blocking"] } shlex = "1.0.0" serde = { workspace = true } serde_json = { workspace = true } strum = { version = "0.20", features = ["derive"] } thiserror = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "sync", "macros", "process", "time"] } +tracing = { workspace = true } tracing-appender = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } uuid = { workspace = true, features = ["serde", "v4"] } +[target.'cfg(unix)'.dependencies] +daemonize = "0.4.1" +nix = "0.17" + [features] panel = [] server = ["dep:diesel", "dep:diesel-derive-enum", "dep:deadpool-diesel"] diff --git a/lib/u_lib/src/api.rs b/lib/u_lib/src/api.rs index 28463d4..444394e 100644 --- a/lib/u_lib/src/api.rs +++ b/lib/u_lib/src/api.rs @@ -1,18 +1,21 @@ use std::collections::HashMap; use std::fmt::Debug; +use std::net::SocketAddr; + +use anyhow::{Context, Result}; +use reqwest::{header, header::HeaderMap, Certificate, Client, Identity, Method, Url}; +use serde::de::DeserializeOwned; +use serde_json::{from_str, Value}; +use uuid::Uuid; use crate::{ config::{get_self_uid, MASTER_PORT}, + conv::opt_to_string, messaging::{self, AsMsg, BaseMessage}, + misc::OneOrVec, models::{self}, - utils::{opt_to_string, OneOrVec}, - UError, + UError, UResult, }; -use anyhow::{Context, Result}; -use reqwest::{header::HeaderMap, Certificate, Client, Identity, Url}; -use serde::de::DeserializeOwned; -use serde_json::from_str; -use uuid::Uuid; const AGENT_IDENTITY: &[u8] = include_bytes!("../../../certs/alice.p12"); const ROOT_CA_CERT: &[u8] = include_bytes!("../../../certs/ca.crt"); @@ -24,28 +27,51 @@ pub struct ClientHandler { } impl ClientHandler { - pub fn new(server: &str, password: Option) -> Self { + pub async fn new(server: &str, password: Option) -> UResult { let identity = Identity::from_pkcs12_der(AGENT_IDENTITY, "").unwrap(); - let mut default_headers = HashMap::from([( - "user-agent".to_string(), - get_self_uid().hyphenated().to_string(), - )]); + let mut default_headers = + HashMap::from([(header::USER_AGENT, get_self_uid().hyphenated().to_string())]); if let Some(pwd) = password { - default_headers.insert("authorization".to_string(), format!("Bearer {pwd}")); + default_headers.insert(header::AUTHORIZATION, format!("Bearer {pwd}")); } - let client = Client::builder() - .identity(identity) - .default_headers(HeaderMap::try_from(&default_headers).unwrap()) - .add_root_certificate(Certificate::from_pem(ROOT_CA_CERT).unwrap()) - .build() - .unwrap(); + let dns_response = Client::new() + .request( + Method::GET, + format!("https://1.1.1.1/dns-query?name={server}&type=A"), + ) + .header(header::ACCEPT, "application/dns-json") + .send() + .await? + .text() + .await?; + + let client = { + let client = Client::builder() + .identity(identity) + .default_headers(HeaderMap::try_from(&default_headers).unwrap()) + .add_root_certificate(Certificate::from_pem(ROOT_CA_CERT).unwrap()); + + match from_str::(&dns_response).unwrap()["Answer"] + .get(0) + .and_then(|a| a.get("data")) + { + Some(ip) => { + let raw_addr = format!("{}:{MASTER_PORT}", ip.as_str().unwrap()); + let addr: SocketAddr = raw_addr.parse().unwrap(); + client.resolve(server, addr) + } + None => client, + } + } + .build() + .unwrap(); - Self { + Ok(Self { client, base_url: Url::parse(&format!("https://{}:{}", server, MASTER_PORT)).unwrap(), - } + }) } async fn req(&self, url: impl AsRef) -> Result { diff --git a/lib/u_lib/src/utils/combined_result.rs b/lib/u_lib/src/combined_result.rs similarity index 97% rename from lib/u_lib/src/utils/combined_result.rs rename to lib/u_lib/src/combined_result.rs index 12dd4d6..2c1c4bb 100644 --- a/lib/u_lib/src/utils/combined_result.rs +++ b/lib/u_lib/src/combined_result.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; -use crate::utils::OneOrVec; +use crate::misc::OneOrVec; use anyhow::Error; pub struct CombinedResult { diff --git a/lib/u_lib/src/utils/conv.rs b/lib/u_lib/src/conv.rs similarity index 100% rename from lib/u_lib/src/utils/conv.rs rename to lib/u_lib/src/conv.rs diff --git a/lib/u_lib/src/errors/chan.rs b/lib/u_lib/src/error/chan.rs similarity index 100% rename from lib/u_lib/src/errors/chan.rs rename to lib/u_lib/src/error/chan.rs diff --git a/lib/u_lib/src/errors/mod.rs b/lib/u_lib/src/error/mod.rs similarity index 100% rename from lib/u_lib/src/errors/mod.rs rename to lib/u_lib/src/error/mod.rs diff --git a/lib/u_lib/src/lib.rs b/lib/u_lib/src/lib.rs index 090ee7d..456e34b 100644 --- a/lib/u_lib/src/lib.rs +++ b/lib/u_lib/src/lib.rs @@ -1,19 +1,27 @@ #![allow(non_upper_case_globals)] pub mod api; pub mod cache; +pub mod combined_result; pub mod config; +pub mod conv; pub mod datatypes; #[cfg(feature = "server")] pub mod db; -pub mod errors; +pub mod error; pub mod executor; pub mod logging; pub mod messaging; +pub mod misc; pub mod models; +pub mod platform; +pub mod proc_output; pub mod runner; -pub mod utils; +pub mod storage; +pub mod tempfile; +#[cfg(unix)] +pub mod unix; -pub use errors::{UError, UResult}; +pub use error::{UError, UResult}; #[cfg(feature = "server")] pub mod schema_exports { @@ -25,7 +33,7 @@ pub mod schema_exports { extern crate diesel; #[macro_use] -extern crate log; +extern crate tracing; #[cfg(test)] #[macro_use] diff --git a/lib/u_lib/src/messaging/base.rs b/lib/u_lib/src/messaging/base.rs index 862f1ff..b397621 100644 --- a/lib/u_lib/src/messaging/base.rs +++ b/lib/u_lib/src/messaging/base.rs @@ -1,8 +1,6 @@ use crate::config::get_self_uid; -//use crate::utils::VecDisplay; use serde::{Deserialize, Serialize}; use std::borrow::Cow; -//use std::fmt::Display; use uuid::Uuid; pub struct Moo<'cow, T: AsMsg + Clone>(pub Cow<'cow, T>); diff --git a/lib/u_lib/src/utils/misc.rs b/lib/u_lib/src/misc.rs similarity index 100% rename from lib/u_lib/src/utils/misc.rs rename to lib/u_lib/src/misc.rs diff --git a/lib/u_lib/src/models/agent.rs b/lib/u_lib/src/models/agent.rs index 7e6dd8d..775688c 100644 --- a/lib/u_lib/src/models/agent.rs +++ b/lib/u_lib/src/models/agent.rs @@ -11,7 +11,9 @@ mod server { #[cfg(feature = "server")] use self::server::*; -use crate::{config::get_self_uid, executor::ExecResult, runner::NamedJobRunner, utils::Platform}; +use crate::{ + config::get_self_uid, executor::ExecResult, platform::Platform, runner::NamedJobRunner, +}; use uuid::Uuid; @@ -63,17 +65,24 @@ impl Agent { self.last_active = SystemTime::now(); } - #[cfg(unix)] pub async fn gather() -> Self { - let mut builder = NamedJobRunner::from_shell(vec![ + #[cfg(unix)] + let cmds = vec![ ("hostname", "uname -a"), ("host_info", "hostnamectl --json=pretty"), ("is_root", "id -u"), ("username", "id -un"), - ]) - .unwrap_one() - .wait() - .await; + ]; + + #[cfg(windows)] + let cmds = vec![ + ("hostname", "uname -a"), + ("host_info", "hostnamectl --json=pretty"), + ("is_root", "id -u"), + ("username", "id -un"), + ]; + + let mut builder = NamedJobRunner::from_shell(cmds).unwrap_one().wait().await; let decoder = |job_result: ExecResult| job_result.unwrap().to_str_result().trim().to_string(); diff --git a/lib/u_lib/src/models/jobs/meta.rs b/lib/u_lib/src/models/jobs/meta.rs index 5758129..8fa53a4 100644 --- a/lib/u_lib/src/models/jobs/meta.rs +++ b/lib/u_lib/src/models/jobs/meta.rs @@ -1,7 +1,7 @@ use super::JobType; #[cfg(feature = "server")] use crate::models::schema::*; -use crate::utils::Platform; +use crate::platform::Platform; use crate::{UError, UResult}; #[cfg(feature = "server")] use diesel::{Identifiable, Insertable, Queryable}; diff --git a/lib/u_lib/src/models/jobs/misc.rs b/lib/u_lib/src/models/jobs/misc.rs index 2df863d..36c06d9 100644 --- a/lib/u_lib/src/models/jobs/misc.rs +++ b/lib/u_lib/src/models/jobs/misc.rs @@ -34,6 +34,7 @@ pub enum JobState { )] pub enum JobType { Init, + Service, #[default] Shell, Terminate, diff --git a/lib/u_lib/src/utils/platform.rs b/lib/u_lib/src/platform.rs similarity index 100% rename from lib/u_lib/src/utils/platform.rs rename to lib/u_lib/src/platform.rs diff --git a/lib/u_lib/src/utils/proc_output.rs b/lib/u_lib/src/proc_output.rs similarity index 97% rename from lib/u_lib/src/utils/proc_output.rs rename to lib/u_lib/src/proc_output.rs index ded026e..01e0f06 100644 --- a/lib/u_lib/src/utils/proc_output.rs +++ b/lib/u_lib/src/proc_output.rs @@ -63,7 +63,7 @@ impl ProcOutput { #[cfg(test)] mod tests { - use crate::utils::{bytes_to_string, ProcOutput}; + use crate::{conv::bytes_to_string, proc_output::ProcOutput}; use std::str; const STDERR_DELIMETER: &'static str = diff --git a/lib/u_lib/src/runner.rs b/lib/u_lib/src/runner.rs index 2025abd..69bb898 100644 --- a/lib/u_lib/src/runner.rs +++ b/lib/u_lib/src/runner.rs @@ -1,9 +1,12 @@ use crate::{ cache::JobCache, + combined_result::CombinedResult, executor::{ExecResult, Waiter}, + misc::OneOrVec, models::{Agent, AssignedJob, AssignedJobById, JobMeta, JobType}, - utils::{CombinedResult, OneOrVec, Platform}, - utils::{ProcOutput, TempFile}, + platform::Platform, + proc_output::ProcOutput, + tempfile::TempFile, UError, UResult, }; use std::collections::HashMap; @@ -128,6 +131,7 @@ pub async fn run_assigned_job(mut job: AssignedJob) -> ExecResult { job.set_result(&Agent::run().await); job.retcode = Some(0); } + JobType::Service => todo!(), JobType::Update => todo!(), JobType::Terminate => exit(0), }; diff --git a/lib/u_lib/src/utils/storage.rs b/lib/u_lib/src/storage.rs similarity index 100% rename from lib/u_lib/src/utils/storage.rs rename to lib/u_lib/src/storage.rs diff --git a/lib/u_lib/src/utils/tempfile.rs b/lib/u_lib/src/tempfile.rs similarity index 94% rename from lib/u_lib/src/utils/tempfile.rs rename to lib/u_lib/src/tempfile.rs index 4a68bee..0dad26f 100644 --- a/lib/u_lib/src/utils/tempfile.rs +++ b/lib/u_lib/src/tempfile.rs @@ -49,13 +49,13 @@ impl Drop for TempFile { #[cfg(test)] mod tests { use super::*; - use crate::utils::bytes_to_string; + use crate::conv::bytes_to_string; use std::path::Path; use std::process::Command; #[test] fn test_file_is_not_busy() { - let binary = include_bytes!("../../tests/fixtures/echoer"); + let binary = include_bytes!("../tests/fixtures/echoer"); for _ in 0..100 { let executable = TempFile::write_exec(binary).unwrap(); let path = executable.get_path(); diff --git a/lib/u_lib/src/utils/unix.rs b/lib/u_lib/src/unix.rs similarity index 90% rename from lib/u_lib/src/utils/unix.rs rename to lib/u_lib/src/unix.rs index a4e4133..98775e7 100644 --- a/lib/u_lib/src/utils/unix.rs +++ b/lib/u_lib/src/unix.rs @@ -1,10 +1,11 @@ +use daemonize::Daemonize; use nix::{ sys::signal::{signal, SigHandler, Signal}, unistd::{chdir, close as fdclose, fork, getppid, setsid, ForkResult}, }; use std::process::exit; -pub fn daemonize() { +fn _daemonize() { if getppid().as_raw() != 1 { setsig(Signal::SIGTTOU, SigHandler::SigIgn); setsig(Signal::SIGTTIN, SigHandler::SigIgn); @@ -30,6 +31,10 @@ pub fn daemonize() { } } +pub fn daemonize() { + Daemonize::new().start().unwrap() +} + pub fn setsig(sig: Signal, hnd: SigHandler) { unsafe { signal(sig, hnd).unwrap(); diff --git a/lib/u_lib/src/utils/mod.rs b/lib/u_lib/src/utils/mod.rs deleted file mode 100644 index cfc3a9b..0000000 --- a/lib/u_lib/src/utils/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -pub mod combined_result; -pub mod conv; -pub mod misc; -pub mod platform; -pub mod proc_output; -pub mod storage; -pub mod tempfile; -#[cfg(unix)] -pub mod unix; - -pub use combined_result::*; -pub use conv::*; -pub use misc::*; -pub use platform::*; -pub use proc_output::*; -pub use storage::*; -pub use tempfile::*; - -#[cfg(unix)] -pub use unix::*; diff --git a/lib/u_lib/src/utils/vec_display.rs b/lib/u_lib/src/utils/vec_display.rs deleted file mode 100644 index 4b9f83c..0000000 --- a/lib/u_lib/src/utils/vec_display.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::{messaging::AsMsg, utils::OneOrVec}; -use serde::{Deserialize, Serialize}; -use std::fmt::{self, Display, Formatter}; -use std::ops::{Deref, DerefMut}; - -#[derive(Serialize, Deserialize, Clone, Default)] -pub struct VecDisplay(pub Vec); - -impl VecDisplay { - pub fn new(inner: impl OneOrVec) -> Self { - VecDisplay(inner.into_vec()) - } - - pub fn into_builtin_vec(self) -> Vec { - self.0 - } -} - -impl Deref for VecDisplay { - type Target = Vec; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for VecDisplay { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl Display for VecDisplay { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - for (i, itm) in self.0.iter().enumerate() { - writeln!(f, "### {}:\n{}\n", i, itm)?; - } - Ok(()) - } -} diff --git a/migrations/2020-10-24-111622_create_all/up.sql b/migrations/2020-10-24-111622_create_all/up.sql index c99082f..619f61a 100644 --- a/migrations/2020-10-24-111622_create_all/up.sql +++ b/migrations/2020-10-24-111622_create_all/up.sql @@ -1,5 +1,5 @@ CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -CREATE TYPE JobType AS ENUM ('shell', 'init', 'python'); +CREATE TYPE JobType AS ENUM ('shell', 'init', 'python', 'service'); CREATE TYPE JobState AS ENUM ('queued', 'running', 'finished'); CREATE TYPE AgentState AS ENUM ('new', 'active', 'banned'); diff --git a/scripts/deploy.sh b/scripts/deploy.sh index c071426..f100487 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -10,8 +10,6 @@ RSYNC="rsync -arzh --progress" ssh $SERVER mkdir -p $REMOTE_DIR/data $RSYNC $ROOTDIR/target/x86_64-unknown-linux-musl/release/{u_server,migrator} $REMOTE_PATH/ -$RSYNC $ROOTDIR/certs/server.{crt,key} $REMOTE_PATH/certs/ -$RSYNC $ROOTDIR/certs/ca.crt $REMOTE_PATH/certs/ $RSYNC $ROOTDIR/.env* $REMOTE_PATH/ $RSYNC $ROOTDIR/deploy/* $REMOTE_PATH/ $RSYNC $ROOTDIR/images/{u_server,u_db}.Dockerfile $REMOTE_PATH/ diff --git a/spec.txt b/spec.txt index 53135f6..7b833d0 100644 --- a/spec.txt +++ b/spec.txt @@ -2,8 +2,6 @@ todos: Upload/download files More tests Agent update (use more JobType's) -Erase log macros in release mode Bump wine version to test agent on windows Store downloaded payload on disk instead of ram Improve web interface -Migrator binary