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

View File

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

View File

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

View File

@@ -1,16 +1,28 @@
{ {
"prod": { "prod": {
"sock_path": "/run/zmp24/zmp24.sock", "io": {
"db": "/data/db" "sock_path": "/run/zmp24/zmp24.sock"
},
"database": {
"path": "/data/db"
}
}, },
"dev": { "dev": {
"bind_to": "[::1]:8080", "io": {
"db": "/tmp/zmp24db" "bind_to": "[::1]:8080"
},
"database": {
"path": "/tmp/zmp24db"
}
}, },
"image": { "image": {
"name": "zmp24", "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 ./zmp24 /usr/bin/zmp24
COPY ./run.sh /run.sh 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" ] CMD [ "/run.sh" ]

View File

@@ -1,10 +1,10 @@
.PHONY: image .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 \ cd dst/image && podman build . -t \
"$$(jq -r .image.name ../../config.json):$$(jq -r .image.version ../../config.json)" "$$(jq -r .image.name ../../config.json):$$(jq -r .image.version ../../config.json)"
dst/image: dst dst/image: dst
mkdir dst/image mkdir -p dst/image
dst/image/Containerfile: dst/image image/image.dockerfile dst/image/Containerfile: dst/image image/image.dockerfile
ln -sf $$(pwd)/image/image.dockerfile dst/image/Containerfile 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 ln -f image/run.sh dst/image/run.sh
chmod +x 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 dst/image/zmp24: dst/image target/$(ARCH)-unknown-linux-musl/release/zmp24
ln -f target/$(ARCH)-unknown-linux-musl/release/zmp24 dst/image/zmp24 ln -f target/$(ARCH)-unknown-linux-musl/release/zmp24 dst/image/zmp24

View File

@@ -1,10 +1,15 @@
#!/bin/sh #!/bin/sh
if [ ! -f /data/config.toml ]
then
cp /default/config.toml /data/config.toml
fi
_term() { _term() {
kill -TERM "$server_pid" 2>/dev/null kill -TERM "$server_pid" 2>/dev/null
} }
trap _term SIGTERM trap _term SIGTERM
/usr/bin/zmp24 & /usr/bin/zmp24 /data/config.toml &
server_pid=$! server_pid=$!
wait "$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 std::sync::Arc;
use chrono::{SecondsFormat, Utc}; use chrono::{SecondsFormat, Utc};
use config::Config;
#[cfg(feature = "dev")] #[cfg(feature = "dev")]
use { use {
inferium::TokioInet, inferium::TokioInet,
@@ -16,6 +17,7 @@ use inferium::h1::AsyncServer;
use tokio::sync::mpsc::{self, Sender}; use tokio::sync::mpsc::{self, Sender};
use std::sync::atomic::AtomicU32; use std::sync::atomic::AtomicU32;
mod config;
mod mime_types; mod mime_types;
mod response_builder; mod response_builder;
mod router; mod router;
@@ -98,13 +100,15 @@ async fn server_handler(
pub struct State { pub struct State {
visit_count: AtomicU32, visit_count: AtomicU32,
db: sled::Db, db: sled::Db,
config: Config,
} }
impl State { impl State {
pub fn new(db_path: &str) -> Self { pub fn new(config: Config) -> Self {
Self { Self {
visit_count: 0.into(), 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)] #[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() { async fn main() {
const BIND_TO: &str = std::env!("BIND_TO"); let args = config::Args::new().expect("invalid arguments");
const DB_PATH: &str = std::env!("DB_PATH"); let conf = load_config(&args.config_path);
logger!(debug "binding to {:?}", conf.io.listen_on());
logger!(debug "binding to {:?}", BIND_TO);
#[cfg(not(feature = "dev"))] #[cfg(not(feature = "dev"))]
delete_if_exists(BIND_TO); delete_if_exists(&conf.io.sock_path);
#[cfg(not(feature = "dev"))] #[cfg(not(feature = "dev"))]
let listener = UnixListener::bind(BIND_TO) let listener = UnixListener::bind(&conf.io.sock_path)
.expect(&format!("could not bind to {:?}", BIND_TO)); .expect(&format!("could not bind to {:?}", conf.io.listen_on()));
#[cfg(feature = "dev")] #[cfg(feature = "dev")]
let listener = TcpListener::bind(BIND_TO).await let listener = TcpListener::bind(&conf.io.bind_to).await
.expect(&format!("could not bind to {:?}", BIND_TO)); .expect(&format!("could not bind to {:?}", conf.io.listen_on()));
let (tx, mut rx) = mpsc::channel::<()>(1); 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!( tokio::select!(
_ = server_handler(listener, tx, state) => {} _ = server_handler(listener, tx, state) => {}
_ = rx.recv() => {}, _ = rx.recv() => {},