From 54e2cea83b3c200d895df02e15bcee2af32363fa Mon Sep 17 00:00:00 2001 From: Bat Date: Tue, 19 Jun 2018 14:08:44 +0100 Subject: [PATCH] Start a setup script For now, it checks if the instance is ready, and if it is not starts the actual setup script. Only the first actual step of the script, checking for native dependencies, is implemented. --- Cargo.lock | 10 +++++++ Cargo.toml | 1 + src/main.rs | 19 ++++-------- src/setup.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 src/setup.rs diff --git a/Cargo.lock b/Cargo.lock index 1708ea5..9300832 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,6 +245,14 @@ dependencies = [ "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "colored" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "comrak" version = "0.2.12" @@ -999,6 +1007,7 @@ dependencies = [ "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "bcrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "comrak 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1998,6 +2007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6" "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" +"checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum comrak 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "053b26c8ce23b4c505a9479beace98f95899e0bf5c5255cf0219e9b0f48cf6ea" "checksum cookie 0.11.0-dev (git+https://github.com/alexcrichton/cookie-rs?rev=0365a18)" = "" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" diff --git a/Cargo.toml b/Cargo.toml index 87c2e87..4f5b0f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ ammonia = "1.1.0" array_tool = "1.0" base64 = "0.9" bcrypt = "0.2" +colored = "1.6" comrak = "0.2" dotenv = "*" failure = "0.1" diff --git a/src/main.rs b/src/main.rs index 5455d85..3ad26d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ extern crate array_tool; extern crate base64; extern crate bcrypt; extern crate chrono; +extern crate colored; extern crate comrak; extern crate failure; #[macro_use] @@ -35,18 +36,17 @@ extern crate tera; extern crate url; extern crate webfinger; -use diesel::{pg::PgConnection, r2d2::{ConnectionManager, Pool}}; -use dotenv::dotenv; use rocket_contrib::Template; use std::env; mod activity_pub; mod db_conn; mod models; +mod safe_string; mod schema; +mod setup; mod routes; mod utils; -mod safe_string; lazy_static! { pub static ref BASE_URL: String = env::var("BASE_URL") @@ -56,17 +56,8 @@ lazy_static! { .unwrap_or(format!("postgres://plume:plume@localhost/{}", env::var("DB_NAME").unwrap_or(String::from("plume")))); } -type PgPool = Pool>; - -/// Initializes a database pool. -fn init_pool() -> PgPool { - dotenv().ok(); - - let manager = ConnectionManager::::new(DB_URL.as_str()); - Pool::new(manager).expect("DB pool error") -} - fn main() { + let pool = setup::check(); rocket::ignite() .mount("/", routes![ routes::blogs::details, @@ -133,7 +124,7 @@ fn main() { routes::errors::not_found, routes::errors::server_error ]) - .manage(init_pool()) + .manage(pool) .attach(Template::custom(|engines| { rocket_i18n::tera(&mut engines.tera); })) diff --git a/src/setup.rs b/src/setup.rs new file mode 100644 index 0000000..42bf985 --- /dev/null +++ b/src/setup.rs @@ -0,0 +1,85 @@ +use colored::Colorize; +use diesel::{pg::PgConnection, r2d2::{ConnectionManager, Pool}}; +use dotenv::dotenv; +use std::io; +use std::process::{exit, Command}; + +use DB_URL; +use db_conn::DbConn; +use models::instance::Instance; + +type PgPool = Pool>; + +/// Initializes a database pool. +fn init_pool() -> Option { + dotenv().ok(); + + let manager = ConnectionManager::::new(DB_URL.as_str()); + Pool::new(manager).ok() +} + +pub fn check() -> PgPool { + if let Some(pool) = init_pool() { + match pool.get() { + Ok(conn) => { + let db_conn = DbConn(conn); + if Instance::get_local(&*db_conn).is_none() { + run_setup(); + } + } + Err(_) => panic!("Couldn't connect to database") + } + pool + } else { + run_setup(); + init_pool().unwrap() + } +} + +fn run_setup() { + println!("\n\n"); + println!("{}\n{}\n{}\n\n{}", + "Welcome in the Plume setup tool.".magenta(), + "It will help you setup your new instance, by asking you a few questions.".magenta(), + "Then you'll be able to enjoy Plume!".magenta(), + "First let's check that you have all the required dependencies. Press Enter to start." + ); + read_line(); + check_native_deps(); +} + +fn check_native_deps() { + let mut not_found = Vec::new(); + if !try_run("psql") { + not_found.push(("PostgreSQL", "sudo apt install postgres")); + } + if !try_run("gettext") { + not_found.push(("GetText", "sudo apt install gettext")) + } + if !try_run("diesel") { + not_found.push(("Diesel CLI", "cargo install diesel_cli")) + } + + if not_found.len() > 0 { + println!("{}\n", "Some native dependencies are missing:".red()); + for (dep, install) in not_found.into_iter() { + println!("{}", format!(" - {} (can be installed with `{}`, on Debian based distributions)", dep, install).red()) + } + println!("\nRetry once you have installed them."); + exit(1); + } else { + println!("{}", "✔️ All native dependencies are present".green()) + } +} + +fn try_run(command: &'static str) -> bool { + Command::new(command) + .output() + .is_ok() +} + +fn read_line() -> String { + let mut input = String::new(); + io::stdin().read_line(&mut input).expect("Unable to read line"); + input +}