Add some scaffolding copied from dotdotvote
This commit is contained in:
parent
10af0c3335
commit
2d331c3db0
13
Cargo.toml
13
Cargo.toml
|
@ -6,3 +6,16 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-std = { version = "1", features = ["attributes"] }
|
||||
chrono = "0.4.15"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
dotenv = "~0.15.0"
|
||||
driftwood = "0"
|
||||
handlebars = { version = "~3.4.0", features = ["dir_source"] }
|
||||
html-escape = "~0.2.6"
|
||||
log = "~0.4.8"
|
||||
pretty_env_logger = "~0.3.1"
|
||||
serde_json = "~1.0.0"
|
||||
sqlx = { version = "~0.5.1", features = ["chrono", "json", "offline", "sqlite", "uuid", "runtime-async-std-rustls"] }
|
||||
tide = "0"
|
||||
uuid = { version = "~0.8.1", features = ["v4", "serde"]}
|
||||
|
|
35
README.adoc
35
README.adoc
|
@ -3,3 +3,38 @@
|
|||
Janky is a simple CI system built in Rust. This is performative coding and not
|
||||
intended to be a production system you can actually use.
|
||||
|
||||
|
||||
|
||||
* Two binaries:
|
||||
* `janky-server`
|
||||
* Listens HTTP
|
||||
* Does web shit
|
||||
* Interacts with agents
|
||||
* `janky-agent`:
|
||||
* Run workloads
|
||||
* Listen HTTP
|
||||
* executes commands
|
||||
|
||||
[source]
|
||||
----
|
||||
┌────────┐ │ │http
|
||||
│ │sqlite3 │ Agent │ws
|
||||
│ Server │http │ │
|
||||
│ │ws └──────┬─────┘
|
||||
└───┬────┘ │
|
||||
│ │
|
||||
│ What are your caps? │
|
||||
├──────────────────────────────────────────────────►│
|
||||
│ │
|
||||
│ │
|
||||
│ git,svn,bash,rustc,cargo,websocket │
|
||||
│◄──────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ great, here's some commands │
|
||||
├──────────────────────────────────────────────────►│
|
||||
│ │
|
||||
│ │
|
||||
│ kewl, here's the logs, id, etc │
|
||||
│◄──────────────────────────────────────────────────┤
|
||||
│ │
|
||||
----
|
||||
|
|
145
src/main.rs
145
src/main.rs
|
@ -1,3 +1,144 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
/*
|
||||
* This is the main Janky entrypoint for the server"
|
||||
*/
|
||||
|
||||
use async_std::sync::{Arc, RwLock};
|
||||
use dotenv::dotenv;
|
||||
use handlebars::Handlebars;
|
||||
use log::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AppState<'a> {
|
||||
hb: Arc<RwLock<Handlebars<'a>>>,
|
||||
}
|
||||
|
||||
impl AppState<'_> {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
hb: Arc::new(RwLock::new(Handlebars::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn register_templates(&self) -> Result<(), handlebars::TemplateFileError> {
|
||||
let mut hb = self.hb.write().await;
|
||||
hb.clear_templates();
|
||||
hb.register_templates_directory(".hbs", "views")
|
||||
}
|
||||
|
||||
pub async fn render(
|
||||
&self,
|
||||
name: &str,
|
||||
data: &serde_json::Value,
|
||||
) -> Result<tide::Body, tide::Error> {
|
||||
/*
|
||||
* In debug mode, reload the templates on ever render to avoid
|
||||
* needing a restart
|
||||
*/
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
self.register_templates().await;
|
||||
}
|
||||
let hb = self.hb.read().await;
|
||||
let view = hb.render(name, data)?;
|
||||
Ok(tide::Body::from_string(view))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The routes module contains all the tide routes and the logic to fulfill the responses for each
|
||||
* route.
|
||||
*
|
||||
* Modules are nested for cleaner organization here
|
||||
*/
|
||||
mod routes {
|
||||
use crate::AppState;
|
||||
use log::*;
|
||||
use std::collections::HashMap;
|
||||
use tide::{Body, Request, StatusCode};
|
||||
use uuid::Uuid;
|
||||
|
||||
/**
|
||||
* Helper function to pull out a :uuid parameter from the path
|
||||
*/
|
||||
fn get_uuid_param(req: &Request<AppState<'_>>) -> Result<Uuid, tide::Error> {
|
||||
let uuid = req.param::<String>("uuid");
|
||||
|
||||
if uuid.is_err() {
|
||||
return Err(tide::Error::from_str(
|
||||
StatusCode::BadRequest,
|
||||
"No uuid specified",
|
||||
));
|
||||
}
|
||||
|
||||
debug!("Fetching poll: {:?}", uuid);
|
||||
|
||||
match Uuid::parse_str(&uuid.unwrap()) {
|
||||
Err(_) => Err(tide::Error::from_str(
|
||||
StatusCode::BadRequest,
|
||||
"Invalid uuid specified",
|
||||
)),
|
||||
Ok(uuid) => Ok(uuid),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /
|
||||
*/
|
||||
pub async fn index(req: Request<AppState<'_>>) -> Result<Body, tide::Error> {
|
||||
let params = json!({
|
||||
"page": "home"
|
||||
});
|
||||
let mut body = req.state().render("index", ¶ms).await?;
|
||||
body.set_mime("text/html");
|
||||
Ok(body)
|
||||
}
|
||||
|
||||
pub mod api {
|
||||
use log::*;
|
||||
use tide::{Body, Request, Response, StatusCode};
|
||||
|
||||
use crate::AppState;
|
||||
}
|
||||
}
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() -> Result<(), tide::Error> {
|
||||
pretty_env_logger::init();
|
||||
dotenv().ok();
|
||||
|
||||
//let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
||||
let state = AppState::new();
|
||||
state.register_templates().await;
|
||||
let mut app = tide::with_state(state);
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
info!("Activating RELEASE mode configuration");
|
||||
app.with(driftwood::ApacheCombinedLogger);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
info!("Activating DEBUG mode configuration");
|
||||
info!("Enabling a very liberal CORS policy for debug purposes");
|
||||
use tide::security::{CorsMiddleware, Origin};
|
||||
let cors = CorsMiddleware::new()
|
||||
.allow_methods(
|
||||
"GET, POST, PUT, OPTIONS"
|
||||
.parse::<tide::http::headers::HeaderValue>()
|
||||
.unwrap(),
|
||||
)
|
||||
.allow_origin(Origin::from("*"))
|
||||
.allow_credentials(false);
|
||||
|
||||
app.with(cors);
|
||||
}
|
||||
/*
|
||||
* All builds will have apidocs, since they're handy
|
||||
*/
|
||||
app.at("/static").serve_dir("static/")?;
|
||||
debug!("Configuring routes");
|
||||
app.at("/").get(routes::index);
|
||||
app.listen("0.0.0.0:8000").await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue