Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/dev' into update/k8s
Browse files Browse the repository at this point in the history
  • Loading branch information
RWDai committed May 7, 2024
2 parents 1c2b345 + 8637b4b commit 97d666f
Show file tree
Hide file tree
Showing 14 changed files with 99 additions and 56 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ documentation = "https://docs.rs/spacegate/"
repository = "https://github.com/ideal-world/spacegate"
edition = "2021"
license = "MIT/Apache-2.0"
rust-version = "1.64"
rust-version = "1.76"

[workspace.dependencies]
spacegate-kernel = { path = "./crates/kernel" }
Expand Down
2 changes: 1 addition & 1 deletion binary/spacegate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ readme = "../../README.md"


[features]
default = ["fs", "dylib"]
default = ["fs"]
full = ["k8s", "fs", "redis", "axum"]
build-k8s = ["k8s", "redis", "axum"]
build-local = ["fs", "redis", "axum"]
Expand Down
3 changes: 3 additions & 0 deletions binary/spacegate/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,15 @@ pub struct Args {
/// ## Redis
/// `-c redis:redis://some-redis-url`
#[arg(short, long, env)]
#[cfg_attr(feature = "build-k8s", arg(default_value_t=Config::K8s(String::from("default"))))]
#[cfg_attr(all(not(feature = "build-k8s"), target_family = "unix", feature="fs"), arg(default_value_t=Config::File(PathBuf::from("/etc/spacegate"))))]
pub config: Config,
/// The dynamic lib plugins dir
///
/// # Example
/// If you are using linux, you may put the plugins dll in `/lib/spacegate/plugins`.
/// `-p /lib/spacegate/plugins`
#[arg(short, long, env)]
#[cfg_attr(target_family = "unix", arg(default_value = "/lib/spacegate/plugins"))]
pub plugins: Option<PathBuf>,
}
4 changes: 4 additions & 0 deletions crates/config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#![warn(clippy::indexing_slicing, clippy::unwrap_used, clippy::dbg_macro, clippy::undocumented_unsafe_blocks)]
//! This crate is aim to manage the configuration of spacegate application with various backends.
/// re-export spacegate_model
pub mod model;
/// Configuration backends and services traits
pub mod service;

pub use model::*;
6 changes: 5 additions & 1 deletion crates/config/src/service.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
// pub mod backend;
/// Config file format
pub mod config_format;
/// File system backend
#[cfg(feature = "fs")]
pub mod fs;
/// Kubernetes backend
#[cfg(feature = "k8s")]
pub mod k8s;
/// In-memory backend
pub mod memory;
/// Redis backend
#[cfg(feature = "redis")]
pub mod redis;
use std::{collections::BTreeMap, error::Error, str::FromStr};
Expand Down
18 changes: 17 additions & 1 deletion crates/extension/axum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ use axum::{BoxError, Router};
use tokio::sync::RwLock;
use tokio::task::JoinHandle;
use tokio_util::sync::CancellationToken;

/// Default port for the global server
const GLOBAL_SERVER_PORT: u16 = 9876;
/// Default host for the global server
const GLOBAL_SERVER_HOST: IpAddr = IpAddr::V6(Ipv6Addr::UNSPECIFIED);
/// Default bind to [::]:9876
const GLOBAL_SERVER_BIND: SocketAddr = SocketAddr::new(GLOBAL_SERVER_HOST, GLOBAL_SERVER_PORT);
#[derive(Debug)]
struct AxumServerInner {
Expand All @@ -32,6 +34,13 @@ impl Default for AxumServerInner {
}
}

/// Global axum http server for spacegate and its plugins.
///
/// # Usage
/// ```
/// # use spacegate_ext_axum::GlobalAxumServer;
/// let server = GlobalAxumServer::default();
/// ```
#[derive(Debug, Clone)]
pub struct GlobalAxumServer(Arc<RwLock<AxumServerInner>>);

Expand All @@ -42,6 +51,7 @@ impl Default for GlobalAxumServer {
}

impl GlobalAxumServer {
/// Set the bind address for the server. If the server is already running, new bind address will take effect after restart.
pub async fn set_bind<A>(&self, socket_addr: A)
where
A: Into<SocketAddr>,
Expand All @@ -50,10 +60,14 @@ impl GlobalAxumServer {
let mut wg = self.0.write().await;
wg.bind = socket_addr;
}

/// Set the cancellation token for the server.
pub async fn set_cancellation(&self, token: CancellationToken) {
let mut wg = self.0.write().await;
wg.cancel_token = token;
}

/// Modify the router with the given closure.
pub async fn modify_router<M>(&self, modify: M)
where
M: FnOnce(Router) -> Router,
Expand All @@ -64,11 +78,13 @@ impl GlobalAxumServer {
wg.router = (modify)(swap_out)
}

/// Start the server, if the server is already running, it will be restarted.
pub async fn start(&self) -> Result<(), std::io::Error> {
let mut wg = self.0.write().await;
wg.start().await
}

/// Shutdown the server.
pub async fn shutdown(&self) -> Result<(), std::io::Error> {
let mut wg = self.0.write().await;
wg.shutdown().await
Expand Down
20 changes: 10 additions & 10 deletions crates/extension/redis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,11 @@ use std::{collections::HashMap, sync::RwLock};
pub use deadpool_redis::{Connection, Manager, Pool};
pub use redis;
use redis::RedisResult;
/// hash: {gateway name} -> {gateway config}
pub const CONF_GATEWAY_KEY: &str = "sg:conf:gateway";
/// hash: {gateway name} -> {<http route name> -> <http route config>}
pub const CONF_HTTP_ROUTE_KEY: &str = "sg:conf:route:http:";
/// string: {timestamp}##{changed obj}##{method}##{changed gateway name}##{changed route name} -> None
/// changed obj: gateway/httproute
/// method: create/update/delete
/// changed route name: None or <route name>
pub const CONF_CHANGE_TRIGGER: &str = "sg:conf:change:trigger:";

/// Wrapper for pooled Redis client.
#[derive(Clone)]
pub struct RedisClient {
/// Pooled Redis client.
pub redis_conn_pool: Pool,
}

Expand All @@ -25,12 +18,13 @@ impl std::fmt::Debug for RedisClient {
}

impl RedisClient {
/// Create a new Redis client from connect url.
pub fn new(url: impl AsRef<str>) -> RedisResult<Self> {
let url = url.as_ref();
let redis_conn_pool = Pool::builder(Manager::new(url)?).build().expect("Failed to create Redis pool");
Ok(Self { redis_conn_pool })
}

/// Get a connection from the pool.
pub async fn get_conn(&self) -> Connection {
self.redis_conn_pool.get().await.unwrap()
}
Expand All @@ -42,29 +36,35 @@ impl From<&str> for RedisClient {
}
}

/// Redis Client Repository.
#[derive(Debug, Default)]
pub struct RedisClientRepo {
repos: RwLock<HashMap<String, RedisClient>>,
}

impl RedisClientRepo {
/// Get the global Redis client repository instance.
pub fn global() -> &'static Self {
static INIT: std::sync::OnceLock<RedisClientRepo> = std::sync::OnceLock::new();
INIT.get_or_init(Self::new)
}

/// Create a new Redis client repository.
pub fn new() -> Self {
Self { repos: RwLock::default() }
}

/// Add a Redis client to the repository.
pub fn add(&self, name: impl Into<String>, client: impl Into<RedisClient>) {
self.repos.write().expect("poisoned global redis client repo").insert(name.into(), client.into());
}

/// Get a Redis client from the repository by its name.
pub fn get(&self, name: &str) -> Option<RedisClient> {
self.repos.read().expect("poisoned global redis client repo").get(name).cloned()
}

/// Remove a Redis client from the repository by its name.
pub fn remove(&self, name: &str) -> Option<RedisClient> {
self.repos.write().expect("poisoned global redis client repo").remove(name)
}
Expand Down
19 changes: 0 additions & 19 deletions crates/extension/tracing/Cargo.toml

This file was deleted.

1 change: 0 additions & 1 deletion crates/extension/tracing/src/lib.rs

This file was deleted.

16 changes: 0 additions & 16 deletions crates/shell/src/constants.rs

This file was deleted.

10 changes: 8 additions & 2 deletions crates/shell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,24 @@ pub use spacegate_config::model;
pub use spacegate_config::model::{BoxError, BoxResult};
use spacegate_config::service::{CreateListener, Retrieve};
use spacegate_config::Config;
/// re-export spacegate_kernel
pub use spacegate_kernel as kernel;
/// re-export spacegate_plugin
pub use spacegate_plugin as plugin;
use tokio::signal;
use tracing::{info, instrument};

/// Configuration retrieval and event listener
pub mod config;
pub mod constants;
/// http extensions
pub mod extension;
/// Spacegate service creation
pub mod server;

#[cfg(feature = "ext-axum")]
pub use spacegate_ext_axum as ext_axum;
#[cfg(feature = "ext-redis")]
pub use spacegate_ext_redis;
pub use spacegate_ext_redis as ext_redis;

#[cfg(feature = "fs")]
/// # Startup the gateway by config file
Expand Down
7 changes: 3 additions & 4 deletions crates/shell/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,12 @@ fn collect_http_route(
#[cfg(feature = "k8s")]
{
use crate::extension::k8s_service::K8sService;
use spacegate_config::model::BackendHost;
use spacegate_kernel::helper_layers::map_request::{add_extension::add_extension, MapRequestLayer};
use spacegate_kernel::BoxLayer;
if let BackendHost::K8sService(data) = backend.host {
let namespace_ext = K8sService(data.into());
if let BackendHost::K8sService(ref data) = backend.host {
let namespace_ext = K8sService(data.clone().into());
// need to add to front
builder = builder.plugin(SgBoxLayer::new(MapRequestLayer::new(add_extension(namespace_ext, true))))
builder = builder.plugin(BoxLayer::new(MapRequestLayer::new(add_extension(namespace_ext, true))))
}
}
builder = builder.host(host).port(backend.port);
Expand Down
34 changes: 34 additions & 0 deletions resource/install/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CONFIG_PATH=/etc/spacegate/config.json
PLUGIN_PATH=/lib/spacegate/plugins
BIN_PATH=/usr/local/bin
cargo build --release --features dylib
sudo cp target/release/spacegate $BIN_PATH

# Create config file
sudo mkdir /etc/spacegate

if [ -f $CONFIG_PATH ]; then
echo "Config file already exists"
else
sudo echo "{}" > /etc/spacegate/config.json
sudo chmod 666 /etc/spacegate/config.json
fi

if [ -f $PLUGIN_PATH ]; then
echo "Plugin dir already exists"
else
# Create plugin directory
sudo mkdir $PLUGIN_PATH
fi


if [ -f /etc/systemd/system/spacegate.service ]; then
echo "Systemd unit file already exists"
else
# Create systemd service
sudo cp resource/install/spacegate.service /etc/systemd/system/spacegate.service
fi

# Enable and start service
sudo systemctl enable spacegate
sudo systemctl start spacegate
13 changes: 13 additions & 0 deletions resource/install/spacegate.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Spacegate

[Service]
PIDFile=/run/spacegate.pid
ExecStart=spacegate
Restart=always
ExecStop=/bin/kill -INT $MAINPID
KillSignal=SIGINT
TimeoutStopSec=5

[Install]
WantedBy=multi-user.target

0 comments on commit 97d666f

Please sign in to comment.