Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F11825785
D3717.id9624.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
D3717.id9624.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Fri, Sep 26, 02:21 (20 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3017653
Default Alt Text
D3717.id9624.diff (11 KB)
Attached To
Mode
D3717: Port Alkane HTTP server to axum
Attached
Detach File
Event Timeline
Log In to Comment