Add dockerfiles and settings checks

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/1/head
trivernis 4 years ago
parent da8b37e8fd
commit 4766ac3f52
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -0,0 +1,11 @@
.idea
.git
.env
.gitignore
*.md
target
Dockerfile
testdata
nodes
config
logs

1
Cargo.lock generated

@ -857,6 +857,7 @@ dependencies = [
"num_cpus",
"parking_lot",
"rand",
"regex",
"rusqlite",
"scheduled-thread-pool",
"serde 1.0.117",

@ -4,6 +4,10 @@ version = "0.1.0"
authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018"
[[bin]]
name = "snekcloud-server"
path = "src/main.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
@ -26,4 +30,5 @@ num_cpus = "1.13.0"
lazy_static = "1.4.0"
parking_lot = "0.11.0"
serde_json = "1.0.59"
fern = "0.6.0"
fern = "0.6.0"
regex = "1.4.2"

@ -0,0 +1,18 @@
FROM rust:alpine AS builder
RUN apk add --no-cache libgcc musl-dev
WORKDIR /usr/src
RUN USER=root cargo new snekcloud-server
WORKDIR /usr/src/snekcloud-server
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release
WORKDIR target/release/
RUN ./snekcloud-server generate-key private_key
RUN timeout 1s ./snekcloud-server || exit 0
RUN cp config/00_default.toml config/10_local.toml
FROM alpine
COPY --from=builder /usr/src/snekcloud-server/target/release/snekcloud-server .
COPY --from=builder /usr/src/snekcloud-server/target/release/config /
COPY --from=builder /usr/src/snekcloud-server/target/release/private_key /
ENTRYPOINT ["./snekcloud-server"]

@ -0,0 +1,18 @@
FROM rust:alpine AS builder
RUN apk add --no-cache libgcc musl-dev
WORKDIR /usr/src
RUN USER=root cargo new snekcloud-server
WORKDIR /usr/src/snekcloud-server
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release
WORKDIR target/release/
RUN ./snekcloud-server generate-key private_key
RUN timeout 1s ./snekcloud-server || exit 0
RUN cp config/00_default.toml config/10_local.toml
FROM scratch
COPY --from=builder /usr/src/snekcloud-server/target/release/snekcloud-server .
COPY --from=builder /usr/src/snekcloud-server/target/release/config /
COPY --from=builder /usr/src/snekcloud-server/target/release/private_key /
ENTRYPOINT ["./snekcloud-server"]

@ -7,7 +7,7 @@ use crate::utils::keys::{
};
use crate::utils::logging::init_logger;
use crate::utils::result::SnekcloudResult;
use crate::utils::settings::{get_settings, Settings};
use crate::utils::settings::{get_settings, Settings, ValidateSettings};
use std::fs;
use std::path::PathBuf;
use structopt::StructOpt;
@ -63,6 +63,7 @@ fn main() -> SnekcloudResult<()> {
fs::write(options.output_file, string_content)?;
}
SubCommand::WriteInfoFile(options) => {
settings.validate();
let key = get_private_key(&settings)?;
let data = NodeData::with_addresses(
settings.node_id,
@ -80,10 +81,19 @@ fn main() -> SnekcloudResult<()> {
}
fn start_server(_options: Opt, settings: &Settings) -> SnekcloudResult<()> {
settings.validate();
let keys = read_node_keys(&settings.node_data_dir)?;
let private_key = get_private_key(settings)?;
let data = NodeData::with_addresses(
settings.node_id.clone(),
settings.listen_addresses.clone(),
private_key.public_key(),
);
data.write_to_file(settings.node_data_dir.join(PathBuf::from("local.toml")))?;
let mut server = SnekcloudServer::new(
settings.node_id.clone(),
get_private_key(settings)?,
private_key,
keys,
settings.num_threads,
);

@ -4,6 +4,7 @@ use crate::utils::result::{SnekcloudError, SnekcloudResult};
use crate::utils::settings::get_settings;
use parking_lot::Mutex;
use scheduled_thread_pool::ScheduledThreadPool;
use std::cmp::{max, min};
use std::collections::HashMap;
use std::mem;
use std::sync::mpsc::channel;
@ -30,6 +31,7 @@ pub struct SnekcloudServer {
impl SnekcloudServer {
/// Creates a new snekcloud server with the provided keys and number of threads
pub fn new(id: String, private_key: SecretKey, keys: Vec<Node>, num_threads: usize) -> Self {
let num_threads = max(max(num_cpus::get(), num_threads), 4);
Self {
inner: VentedServer::new(
id,

@ -1,6 +1,7 @@
use crate::data::node_data::NodeData;
use crate::utils::result::{SnekcloudError, SnekcloudResult};
use crate::utils::settings::get_settings;
use crate::utils::validate_node_id;
use std::fs::create_dir;
use std::path::{Path, PathBuf};
use vented::server::data::Node;
@ -18,10 +19,19 @@ pub fn read_node_keys(path: &PathBuf) -> SnekcloudResult<Vec<Node>> {
create_dir(path)?;
}
let trusted_nodes = get_settings().trusted_nodes;
let own_id = get_settings().node_id;
let content = glob::glob(format!("{}/*.toml", path.to_string_lossy()).as_str())?
.filter_map(|path| {
let data = NodeData::from_file(path.ok()?).ok()?;
let path = path.ok()?;
if path
.file_name()?
.to_string_lossy()
.eq_ignore_ascii_case("local")
{
return None;
}
let data = NodeData::from_file(path).ok()?;
Some(Node {
public_key: data.public_key(),
@ -30,6 +40,7 @@ pub fn read_node_keys(path: &PathBuf) -> SnekcloudResult<Vec<Node>> {
id: data.id,
})
})
.filter(|node| validate_node_id(&node.id) && node.id != own_id)
.collect();
Ok(content)

@ -1,15 +1,14 @@
use rand::RngCore;
use std::path::PathBuf;
use crate::utils::result::SnekcloudResult;
use rand::RngCore;
use regex::Regex;
use serde::Serialize;
use std::fs;
use std::path::PathBuf;
pub mod result;
pub mod keys;
pub mod settings;
pub mod logging;
pub mod result;
pub mod settings;
pub fn get_node_id() -> String {
if let Ok(Some(address)) = mac_address::get_mac_address() {
@ -32,6 +31,7 @@ pub fn get_node_id() -> String {
pub fn write_toml_pretty<T: Serialize>(path: &PathBuf, value: &T) -> SnekcloudResult<()> {
let mut buf_str = String::new();
let mut serializer = toml::Serializer::pretty(&mut buf_str);
serializer.pretty_array(true);
value.serialize(&mut serializer)?;
fs::write(path, buf_str.as_bytes())?;
@ -43,4 +43,12 @@ pub fn write_json_pretty<T: Serialize>(path: &PathBuf, value: &T) -> SnekcloudRe
fs::write(path, string_value.as_bytes())?;
Ok(())
}
}
pub fn validate_node_id(name: &str) -> bool {
lazy_static! {
static ref NODE_REGEX: Regex = Regex::new(r"^\S{1,32}$").expect("Failed to compile regex");
}
!name.eq_ignore_ascii_case("local") && NODE_REGEX.is_match(name)
}

@ -1,7 +1,7 @@
use crate::modules::heartbeat::settings::HeartbeatSettings;
use crate::modules::nodes_refresh::settings::NodesRefreshSettings;
use crate::utils::result::{SnekcloudError, SnekcloudResult};
use crate::utils::{get_node_id, write_toml_pretty};
use crate::utils::result::SnekcloudResult;
use crate::utils::{get_node_id, validate_node_id, write_toml_pretty};
use config::File;
use serde::{Deserialize, Serialize};
use std::fs;
@ -14,6 +14,10 @@ const DEFAULT_CONFIG: &str = "config/00_default.toml";
const GLOB_CONFIG: &str = "config/*.toml";
const ENV_PREFIX: &str = "SNEKCLOUD";
pub trait ValidateSettings {
fn validate(&self);
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Settings {
pub listen_addresses: Vec<String>,
@ -21,7 +25,6 @@ pub struct Settings {
pub private_key: PathBuf,
pub node_data_dir: PathBuf,
pub num_threads: usize,
/// List of trusted nodes
pub trusted_nodes: Vec<String>,
pub send_timeout_secs: u64,
pub redirect_timeout_secs: u64,
@ -41,7 +44,7 @@ impl Default for Settings {
Self {
listen_addresses: vec![],
node_id: get_node_id(),
private_key: PathBuf::from("node_key"),
private_key: PathBuf::from("private_key"),
node_data_dir: PathBuf::from("nodes"),
log_folder: PathBuf::from("logs"),
trusted_nodes: vec![],
@ -53,6 +56,15 @@ impl Default for Settings {
}
}
impl Settings {
pub fn timeouts(&self) -> ServerTimeouts {
ServerTimeouts {
redirect_timeout: Duration::from_secs(self.redirect_timeout_secs),
send_timeout: Duration::from_secs(self.send_timeout_secs),
}
}
}
impl Default for ModuleSettings {
fn default() -> Self {
Self {
@ -62,6 +74,31 @@ impl Default for ModuleSettings {
}
}
impl ValidateSettings for Settings {
fn validate(&self) {
if !self.private_key.exists() {
panic!(format!("Private key {:?} does not exist", self.private_key));
}
if self.send_timeout_secs == 0 {
panic!("Send timeout must be greater than 0");
}
if self.redirect_timeout_secs == 0 {
panic!("Redirect timeout must be greater than 0");
}
if !validate_node_id(&self.node_id) {
panic!(format!("Invalid NodeID {}", self.node_id));
}
if self.num_threads == 0 {
panic!("Thread number must be greater than 0")
}
self.modules.validate();
}
}
impl ValidateSettings for ModuleSettings {
fn validate(&self) {}
}
/// Returns the settings that are lazily retrieved at runtime
pub fn get_settings() -> Settings {
lazy_static! {
@ -87,14 +124,7 @@ fn load_settings() -> SnekcloudResult<Settings> {
)?
.merge(config::Environment::with_prefix(ENV_PREFIX))?;
settings.try_into().map_err(SnekcloudError::from)
}
let settings: Settings = settings.try_into()?;
impl Settings {
pub fn timeouts(&self) -> ServerTimeouts {
ServerTimeouts {
redirect_timeout: Duration::from_secs(self.redirect_timeout_secs),
send_timeout: Duration::from_secs(self.send_timeout_secs),
}
}
Ok(settings)
}

Loading…
Cancel
Save