Page MenuHomeDevCentral

D3717.id9625.diff
No OneTemporary

D3717.id9625.diff

diff --git a/Cargo.toml b/Cargo.toml
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,28 +1,29 @@
[package]
name = "alkane"
-version = "0.2.0"
+version = "0.3.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+axum = "0.8.4"
env_logger = "^0.11.5"
lazy_static = "^1.5.0"
-limiting-factor = "^0.8.0"
+limiting-factor-axum = "0.1.0"
log = "^0.4.22"
-rocket = "^0.4.11"
-rocket_codegen = "^0.4.11"
serde_yaml = "^0.9.33"
[dependencies.clap]
version = "~4.5.17"
features = ["derive"]
-[dependencies.rocket_contrib]
-version = "^0.4.11"
-default-features = false
-features = ["json"]
-
[dependencies.serde]
version = "^1.0.210"
features = ["derive"]
+
+[dependencies.tokio]
+version = "1.47.1"
+features = [
+ "macros",
+ "rt-multi-thread",
+]
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -61,14 +61,9 @@
| Variable | Description | Default value |
|--------------------|-----------------|---------------|
-| ROCKET_PORT | Server port | 8000 |
-| ROCKET_ADDRESS | Address to bind | 0.0.0.0 |
-
-The following options allow to configure the server:
-
-| Argument | Description | Default value |
-|--------------------|-----------------|---------------|
-| --mounting-point | Mounting point | / |
+| APP_PORT | Server port | 8000 |
+| APP_ADDRESS | Address to bind | 0.0.0.0 |
+| APP_MOUNT_POINT | Mounting point | / |
Nasqueron servers expose Alkane on the port 10206, for the alkane C2H6.
@@ -140,7 +135,7 @@
Alkane is written in Rust using:
- - Rocket and Limiting Factor for the HTTP API
+ - Axum for the HTTP API
- Clap to parse arguments
- serde_yaml to deserialize configuration files
diff --git a/src/actions.rs b/src/actions.rs
--- a/src/actions.rs
+++ b/src/actions.rs
@@ -5,7 +5,6 @@
// License: BSD-2-Clause
// -------------------------------------------------------------
-use crate::command::ServerArgs;
use crate::config::AlkaneConfig;
use crate::db::Database;
use crate::deploy::AlkaneDeployError;
@@ -18,8 +17,8 @@
// Actions only available in CLI
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-pub fn serve(args: ServerArgs, config: AlkaneConfig) {
- run(config, &args.mounting_point);
+pub async fn serve(config: AlkaneConfig) -> bool {
+ run(config).await
}
// -------------------------------------------------------------
diff --git a/src/command.rs b/src/command.rs
--- a/src/command.rs
+++ b/src/command.rs
@@ -16,7 +16,7 @@
#[clap(author="Nasqueron project", version, about="Manage Alkane PaaS", long_about=None)]
pub enum AlkaneCommand {
/// Launch an HTTP server to expose the Alkane REST API
- Server(ServerArgs),
+ Server,
/// Initialize a site
#[command(arg_required_else_help = true)]
@@ -39,12 +39,6 @@
// Subcommands arguments
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#[derive(Debug, Args)]
-pub struct ServerArgs {
- #[arg(long, default_value = "/")]
- pub mounting_point: String,
-}
-
#[derive(Debug, Args)]
pub struct DeployArgs {
/// The name of the site to deploy, using sub.domain.tld format
diff --git a/src/config.rs b/src/config.rs
--- a/src/config.rs
+++ b/src/config.rs
@@ -43,7 +43,7 @@
// the Alkane configuration file alkane.conf
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#[derive(Debug, Deserialize)]
+#[derive(Clone, Debug, Deserialize)]
pub struct AlkaneConfig {
/// The paths to the root directories used by Alkane
roots: HashMap<String, String>,
diff --git a/src/main.rs b/src/main.rs
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,8 +6,6 @@
// Description: Manage nginx and php-fpm Alkane PaaS
// -------------------------------------------------------------
-#![feature(decl_macro)]
-
use std::process::exit;
use clap::Parser;
@@ -35,7 +33,8 @@
// Application entry point
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-fn main() {
+#[tokio::main]
+async fn main() {
env_logger::init();
let command = AlkaneCommand::parse(); // Will exit if argument is missing or --help/--version provided.
@@ -48,8 +47,10 @@
};
match command {
- AlkaneCommand::Server(args) => {
- serve(args, config);
+ AlkaneCommand::Server => {
+ let result = serve(config).await;
+
+ exit(result.to_status_code())
}
AlkaneCommand::Update(args) => {
diff --git a/src/runner/store.rs b/src/runner/store.rs
--- a/src/runner/store.rs
+++ b/src/runner/store.rs
@@ -55,7 +55,9 @@
map.insert("ALKANE_SITE_PATH".to_string(), site.path.clone());
if let Some(context) = &site.context {
- map.insert("ALKANE_SITE_CONTEXT".to_string(), context.clone());
+ if !context.is_empty() {
+ map.insert("ALKANE_SITE_CONTEXT".to_string(), context.clone());
+ }
}
map
diff --git a/src/server/kernel.rs b/src/server/kernel.rs
--- a/src/server/kernel.rs
+++ b/src/server/kernel.rs
@@ -5,8 +5,9 @@
// License: BSD-2-Clause
// -------------------------------------------------------------
-use rocket::ignite;
-use rocket_codegen::routes;
+use axum::Router;
+use axum::routing::{get, post};
+use limiting_factor_axum::app::{App, ServerConfig};
use crate::config::AlkaneConfig;
use crate::server::requests::*;
@@ -15,19 +16,32 @@
// Server entry point
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-pub fn run(config: AlkaneConfig, mounting_point: &str) {
- let routes = routes![
+pub fn get_default_config () -> ServerConfig {
+ ServerConfig {
+ address: "0.0.0.0".to_string(),
+ port: 8000,
+ mount_point: "/".to_string(),
+ }
+}
+
+pub fn get_router () -> Router<AlkaneConfig> {
+ Router::new()
+
// Monitoring
- status,
+ .route("/status", get(status))
+
// Alkane API
- init,
- update,
- deploy,
- is_present,
- ];
-
- ignite()
- .manage(config)
- .mount(mounting_point, routes)
- .launch();
+ .route("/init/{site_name}", post(init))
+ .route("/update/{site_name}", post(update))
+ .route("/deploy/{site_name}", post(deploy))
+ .route("/is_present/{site_name}", get(is_present))
+}
+
+pub async fn run(alkane_config: AlkaneConfig) -> bool {
+ let server_config = ServerConfig::from_env_or(get_default_config());
+
+ let router = get_router()
+ .with_state(alkane_config);
+
+ App::new(server_config, router).run().await
}
diff --git a/src/server/requests.rs b/src/server/requests.rs
--- a/src/server/requests.rs
+++ b/src/server/requests.rs
@@ -5,22 +5,23 @@
// License: BSD-2-Clause
// -------------------------------------------------------------
-use limiting_factor::api::guards::RequestBody;
-use limiting_factor::api::replies::{ApiJsonResponse, ApiResponse};
-use log::{debug, info, warn};
-use rocket::State;
-use rocket_codegen::{get, post};
+use axum::extract::{Path, State};
+use axum::http::StatusCode;
+
+use limiting_factor_axum::api::guards::AxumRequestBody as RequestBody;
+use limiting_factor_axum::api::replies::{ApiJsonResponse, ApiResponse, FailureResponse};
+use log::{debug, info, warn};
use crate::actions;
use crate::config::AlkaneConfig;
+use crate::deploy::DeployError;
use crate::runner::RecipeStatus;
// -------------------------------------------------------------
// Monitoring
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#[get("/status")]
-pub fn status() -> &'static str {
+pub async fn status() -> &'static str {
"ALIVE"
}
@@ -28,70 +29,68 @@
// Alkane requests
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#[get("/is_present/<site_name>")]
-pub fn is_present(site_name: String, config: State<AlkaneConfig>) -> ApiJsonResponse<bool> {
+pub async fn is_present(
+ Path(site_name): Path<String>,
+ State(config): State<AlkaneConfig>,
+) -> ApiJsonResponse<bool> {
actions::is_present(&site_name, &config).into_json_response()
}
-#[post("/init/<site_name>", data = "<context>")]
-pub fn init(
- site_name: String,
+pub async fn init(
+ Path(site_name): Path<String>,
+ State(config): State<AlkaneConfig>,
context: RequestBody,
- config: State<AlkaneConfig>,
) -> ApiJsonResponse<RecipeStatus> {
info!("Deploying {}", &site_name);
let context = context.into_optional_string();
debug!("Context: {:?}", &context);
- match actions::initialize(&site_name, context, &config) {
- Ok(status) => status.into_json_response(),
- Err(error) => {
- warn!("{}", error);
-
- RecipeStatus::Error.into_json_response()
- }
- }
+ actions::initialize(&site_name, context, &config)
+ .into_json_response()
}
-#[post("/update/<site_name>", data = "<context>")]
-pub fn update(
- site_name: String,
+pub async fn update(
+ Path(site_name): Path<String>,
+ State(config): State<AlkaneConfig>,
context: RequestBody,
- config: State<AlkaneConfig>,
) -> ApiJsonResponse<RecipeStatus> {
info!("Deploying {}", &site_name);
let context = context.into_optional_string();
debug!("Context: {:?}", &context);
- match actions::update(&site_name, context, &config) {
- Ok(status) => status.into_json_response(),
- Err(error) => {
- warn!("{}", error);
-
- RecipeStatus::Error.into_json_response()
- }
- }
+ actions::update(&site_name, context, &config)
+ .into_json_response()
}
-#[post("/deploy/<site_name>", data = "<context>")]
-pub fn deploy(
- site_name: String,
+pub async fn deploy(
+ Path(site_name): Path<String>,
+ State(config): State<AlkaneConfig>,
context: RequestBody,
- config: State<AlkaneConfig>,
) -> ApiJsonResponse<RecipeStatus> {
info!("Deploying {}", &site_name);
let context = context.into_optional_string();
debug!("Context: {:?}", &context);
- match actions::deploy(&site_name, context, &config) {
- Ok(status) => status.into_json_response(),
- Err(error) => {
- warn!("{}", error);
+ actions::deploy(&site_name, context, &config)
+ .into_json_response()
+}
+
+// -------------------------------------------------------------
+// Custom error handling
+//
+// Deploy errors are returned as 400 + the Alkane error message
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+impl FailureResponse for DeployError {
+ fn status_code(&self) -> StatusCode {
+ StatusCode::BAD_REQUEST
+ }
- RecipeStatus::Error.into_json_response()
- }
+ fn response(&self) -> String {
+ warn!("{}", self); // Server log
+ format!("{}", self) // API response
}
}
diff --git a/support/freebsd/rc.d/alkane b/support/freebsd/rc.d/alkane
--- a/support/freebsd/rc.d/alkane
+++ b/support/freebsd/rc.d/alkane
@@ -73,7 +73,7 @@
alkane_log_enable="NO"
fi
-alkane_env="${alkane_env} ROCKET_SECRET=$(openssl rand -base64 32) ROCKET_PORT=${alkane_port} ROCKET_ADDRESS=${alkane_address} ${alkane_env}"
+alkane_env="${alkane_env} APP_PORT=${alkane_port} APP_ADDRESS=${alkane_address} ${alkane_env}"
pidfile=/var/run/alkane.pid
procname="/usr/local/bin/alkane"

File Metadata

Mime Type
text/plain
Expires
Fri, Sep 26, 02:17 (20 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3017653
Default Alt Text
D3717.id9625.diff (11 KB)

Event Timeline