Archived
3
0

extract config to external files
Some checks failed
Check indentation / build (push) Has been cancelled
Continuous testing / build (push) Has been cancelled

This commit is contained in:
2025-03-12 23:08:40 +01:00
parent 975ebedace
commit 5513042b1b
10 changed files with 193 additions and 46 deletions

87
Cargo.lock generated
View File

@@ -192,6 +192,12 @@ version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "fs2"
version = "0.4.3"
@@ -217,6 +223,12 @@ version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
[[package]]
name = "humansize"
version = "2.1.3"
@@ -249,6 +261,16 @@ dependencies = [
"cc",
]
[[package]]
name = "indexmap"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "inferium"
version = "0.1.0"
@@ -284,9 +306,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.170"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "libm"
@@ -388,9 +410,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.20.3"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
checksum = "cde51589ab56b20a6f686b2c68f7a0bd6add753d697abf720d63f8db3ab7b1ad"
[[package]]
name = "parking_lot"
@@ -444,9 +466,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.39"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
@@ -516,6 +538,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
dependencies = [
"serde",
]
[[package]]
name = "shlex"
version = "1.3.0"
@@ -591,6 +622,40 @@ dependencies = [
"syn",
]
[[package]]
name = "toml"
version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "unicase"
version = "2.8.1"
@@ -777,6 +842,15 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36"
dependencies = [
"memchr",
]
[[package]]
name = "zmp24"
version = "0.1.0"
@@ -789,4 +863,5 @@ dependencies = [
"serde_json",
"sled",
"tokio",
"toml",
]

View File

@@ -16,6 +16,7 @@ serde = { version = "1.0.218", features = ["derive"] }
serde_json = "1.0.140"
sled = "0.34.7"
tokio = { version = "1.43.0", features = ["macros", "sync", "rt", "rt-multi-thread"] }
toml = "0.8.20"
[features]
dev = []

View File

@@ -6,25 +6,16 @@ ARCH := $(shell uname -m)
FILES_RS := $(shell find src -type f -regex '^.*\.rs$$')
FILES_CLIENT := client/dst/index.html client/dst/script.js client/dst/style.css
MAIN_RS_SRCS := $(FILES_RS) $(FILES_CLIENT) Cargo.toml config.json
MAIN_RS_SRCS := $(FILES_RS) $(FILES_CLIENT) Cargo.toml
SEARCH_REPLACE := lib/search_and_replace/target/release/search_and_replace
DEV_DB := $(shell jq -r .dev.db config.json)
DEV_BIND := $(shell jq -r .dev.bind_to config.json)
PROD_DB := $(shell jq -r .prod.db config.json)
PROD_SOCK_PATH := $(shell jq -r .prod.sock_path config.json)
.PHONY: run
run: $(MAIN_RS_SRCS)
DB_PATH="$(DEV_DB)" \
BIND_TO="$(DEV_BIND)" \
cargo run --features dev
run: $(MAIN_RS_SRCS) dst/dev_config.toml
cargo run --features dev -- dst/dev_config.toml
.PHONY: test
test: target/debug/zmp24
DB_PATH="$(DEV_DB)" \
BIND_TO="$(DEV_BIND)" \
cargo test
.PHONY: test_tabs
@@ -47,22 +38,17 @@ clean: client_clean
dst:
mkdir dst
include lib/config.mk
include client/client.mk
include image/image.mk
target/release/zmp24: $(MAIN_RS_SRCS)
DB_PATH="$(PROD_DB)" \
BIND_TO="$(PROD_SOCK_PATH)" \
cargo build --release
target/debug/zmp24: $(MAIN_RS_SRCS)
DB_PATH="$(DEV_DB)" \
BIND_TO="$(DEV_BIND)" \
cargo build
target/$(ARCH)-unknown-linux-musl/release/zmp24: $(MAIN_RS_SRCS)
DB_PATH="$(PROD_DB)" \
BIND_TO="$(PROD_SOCK_PATH)" \
cargo build --target $(ARCH)-unknown-linux-musl --release
$(SEARCH_REPLACE): lib/search_and_replace/src/main.rs lib/search_and_replace/Cargo.toml

View File

@@ -1,16 +1,28 @@
{
"prod": {
"sock_path": "/run/zmp24/zmp24.sock",
"db": "/data/db"
"io": {
"sock_path": "/run/zmp24/zmp24.sock"
},
"database": {
"path": "/data/db"
}
},
"dev": {
"bind_to": "[::1]:8080",
"db": "/tmp/zmp24db"
"io": {
"bind_to": "[::1]:8080"
},
"database": {
"path": "/tmp/zmp24db"
}
},
"image": {
"name": "zmp24",
"version": "0.1"
"version": "0.2"
}
}

View File

@@ -2,6 +2,7 @@ FROM docker.io/alpine:latest
COPY ./zmp24 /usr/bin/zmp24
COPY ./run.sh /run.sh
RUN apk update && apk add gcompat && mkdir /data
RUN apk update && apk add gcompat && mkdir /data && mkdir /default
COPY ./config.toml /default/config.toml
CMD [ "/run.sh" ]

View File

@@ -1,10 +1,10 @@
.PHONY: image
image: dst/image/zmp24 dst/image/Containerfile dst/image/run.sh config.json
image: dst/image/zmp24 dst/image/Containerfile dst/image/run.sh dst/image/config.toml config.json
cd dst/image && podman build . -t \
"$$(jq -r .image.name ../../config.json):$$(jq -r .image.version ../../config.json)"
dst/image: dst
mkdir dst/image
mkdir -p dst/image
dst/image/Containerfile: dst/image image/image.dockerfile
ln -sf $$(pwd)/image/image.dockerfile dst/image/Containerfile
@@ -13,5 +13,8 @@ dst/image/run.sh: dst/image image/run.sh
ln -f image/run.sh dst/image/run.sh
chmod +x dst/image/run.sh
dst/image/config.toml: dst/image dst/prod_config.toml
ln -f dst/prod_config.toml dst/image/config.toml
dst/image/zmp24: dst/image target/$(ARCH)-unknown-linux-musl/release/zmp24
ln -f target/$(ARCH)-unknown-linux-musl/release/zmp24 dst/image/zmp24

View File

@@ -1,10 +1,15 @@
#!/bin/sh
if [ ! -f /data/config.toml ]
then
cp /default/config.toml /data/config.toml
fi
_term() {
kill -TERM "$server_pid" 2>/dev/null
}
trap _term SIGTERM
/usr/bin/zmp24 &
/usr/bin/zmp24 /data/config.toml &
server_pid=$!
wait "$server_pid"

11
lib/config.mk Normal file
View File

@@ -0,0 +1,11 @@
JQ_INTO_TOML := '.prod|to_entries.[]|if (.value | type == "object") then "\n[" + .key + "]\n" + (.value|to_entries.[] | if (.value | type == "string") then .key + " = \"" + (.value|tostring) + "\"" else .key + " = " + (.value|tostring) end) + "\n" else if (.value | type == "string") then .key + " = \"" + (.value|tostring) + "\"" else .key + " = " + (.value|tostring) end end'
define to_toml
jq -r '.$(1)|to_entries.[]|if (.value | type == "object") then "\n[" + .key + "]\n" + (.value|to_entries.[] | if (.value | type == "string") then .key + " = \"" + (.value|tostring) + "\"" else .key + " = " + (.value|tostring) end) + "\n" else if (.value | type == "string") then .key + " = \"" + (.value|tostring) + "\"" else .key + " = " + (.value|tostring) end end' $(2) > $(3)
endef
dst/dev_config.toml: config.json dst
$(call to_toml,dev,$<,$@)
dst/prod_config.toml: config.json dst
$(call to_toml,prod,$<,$@)

45
src/config.rs Normal file
View File

@@ -0,0 +1,45 @@
use serde::Deserialize;
#[derive(Deserialize)]
pub struct Config {
pub io: IO,
pub database: Database,
}
#[derive(Deserialize)]
pub struct IO {
#[cfg(feature = "dev")]
pub bind_to: String,
#[cfg(not(feature = "dev"))]
pub sock_path: String,
}
#[derive(Deserialize)]
pub struct Database {
pub path: String,
}
impl IO {
pub fn listen_on(&self) -> &str {
#[cfg(feature = "dev")]
return &self.bind_to;
#[cfg(not(feature = "dev"))]
return &self.sock_path;
}
}
pub struct Args {
pub config_path: String,
}
impl Args {
pub fn new() -> Result<Args, ()> {
let mut args = std::env::args();
args.next();
let config_path = args.next().ok_or(())?;
if args.next() != None {
return Err(());
}
Ok(Args { config_path })
}
}

View File

@@ -1,5 +1,6 @@
use std::sync::Arc;
use chrono::{SecondsFormat, Utc};
use config::Config;
#[cfg(feature = "dev")]
use {
inferium::TokioInet,
@@ -16,6 +17,7 @@ use inferium::h1::AsyncServer;
use tokio::sync::mpsc::{self, Sender};
use std::sync::atomic::AtomicU32;
mod config;
mod mime_types;
mod response_builder;
mod router;
@@ -98,13 +100,15 @@ async fn server_handler(
pub struct State {
visit_count: AtomicU32,
db: sled::Db,
config: Config,
}
impl State {
pub fn new(db_path: &str) -> Self {
pub fn new(config: Config) -> Self {
Self {
visit_count: 0.into(),
db: sled::open(db_path).expect("could not open the database")
db: sled::open(&config.database.path).expect("could not open the database"),
config,
}
}
}
@@ -123,26 +127,30 @@ fn delete_if_exists(filepath: &str) {
}
}
fn load_config(config_path: &str) -> Config {
let config = std::fs::read_to_string(config_path).expect("could not load config file");
toml::from_str(&config).expect("could not parse config file")
}
#[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() {
const BIND_TO: &str = std::env!("BIND_TO");
const DB_PATH: &str = std::env!("DB_PATH");
let args = config::Args::new().expect("invalid arguments");
let conf = load_config(&args.config_path);
logger!(debug "binding to {:?}", BIND_TO);
logger!(debug "binding to {:?}", conf.io.listen_on());
#[cfg(not(feature = "dev"))]
delete_if_exists(BIND_TO);
delete_if_exists(&conf.io.sock_path);
#[cfg(not(feature = "dev"))]
let listener = UnixListener::bind(BIND_TO)
.expect(&format!("could not bind to {:?}", BIND_TO));
let listener = UnixListener::bind(&conf.io.sock_path)
.expect(&format!("could not bind to {:?}", conf.io.listen_on()));
#[cfg(feature = "dev")]
let listener = TcpListener::bind(BIND_TO).await
.expect(&format!("could not bind to {:?}", BIND_TO));
let listener = TcpListener::bind(&conf.io.bind_to).await
.expect(&format!("could not bind to {:?}", conf.io.listen_on()));
let (tx, mut rx) = mpsc::channel::<()>(1);
let state = Arc::new(State::new(DB_PATH));
let state = Arc::new(State::new(conf));
logger!(info "server running on {:?}", BIND_TO);
logger!(info "server running on {:?}", state.config.io.listen_on());
tokio::select!(
_ = server_handler(listener, tx, state) => {}
_ = rx.recv() => {},