diff options
| author | Nikolay Govorov <me@govorov.online> | 2026-01-12 01:15:17 +0000 |
|---|---|---|
| committer | Nikolay Govorov <me@govorov.online> | 2026-01-12 02:14:12 +0000 |
| commit | cbb993457ada8b8528748391b2cb8ee538d22dfa (patch) | |
| tree | eba692b9464f5647f419c0c5b2dc206769a5df6b | |
| parent | b240c88e7ded3cd09122870f6c2b2fe01c1f4215 (diff) | |
| download | tar tar.gz tar.bz2 tar.lz tar.xz tar.zst zip | |
Parse configuration from toml file
Diffstat
| -rw-r--r-- | Cargo.lock | 60 | +56 −4 |
| -rw-r--r-- | Cargo.toml | 2 | +2 −0 |
| -rw-r--r-- | nfpm.yaml | 8 | +8 −0 |
| -rw-r--r-- | pkg/zorian.service | 10 | +4 −6 |
| -rw-r--r-- | pkg/zorian.toml | 2 | +2 −0 |
| -rw-r--r-- | src/main.rs | 46 | +45 −1 |
| -rw-r--r-- | src/service_config.rs | 33 | +26 −7 |
7 files changed, 143 insertions, 18 deletions
diff --git a/Cargo.lock b/Cargo.lock index 538b996..277fba5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -309,7 +309,7 @@ checksum = "cf53e0ebbbc6e45357b199f3b213f3eb330792c8b370e548499f5685470ecb11" dependencies = [ "semver", "serde", - "toml", + "toml 0.9.11+spec-1.1.0", "url", ] @@ -2665,7 +2665,7 @@ dependencies = [ "semver", "serde", "thiserror 2.0.17", - "toml", + "toml 0.9.11+spec-1.1.0", "url", ] @@ -2827,6 +2827,15 @@ dependencies = [ [[package]] name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" @@ -3273,14 +3282,26 @@ dependencies = [ [[package]] name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit", +] + +[[package]] +name = "toml" version = "0.9.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" dependencies = [ "indexmap", "serde_core", - "serde_spanned", - "toml_datetime", + "serde_spanned 1.0.4", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", "winnow", @@ -3298,6 +3319,15 @@ dependencies = [ [[package]] name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" @@ -3306,6 +3336,20 @@ dependencies = [ ] [[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow", +] + +[[package]] name = "toml_parser" version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3315,6 +3359,12 @@ dependencies = [ ] [[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] name = "toml_writer" version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3987,7 +4037,9 @@ dependencies = [ "hyper-util", "minijinja", "regex", + "serde", "tokio", + "toml 0.8.23", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0ab1923..9181e07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,9 @@ hyper-tls = "0.6.0" hyper-util = { version = "0.1.19", features = ["client", "http1", "http2", "tokio"] } minijinja = "2.14.0" regex = "1.12.2" +serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.49.0", features = ["full"] } +toml = "0.8" [dev-dependencies] cargo-deny = "0.19.0" diff --git a/nfpm.yaml b/nfpm.yaml index 09b92dd..473712c 100644 --- a/nfpm.yaml +++ b/nfpm.yaml @@ -35,6 +35,14 @@ contents: file_info: mode: 0644 + - dst: /var/lib/zorian + type: dir + file_info: + mode: 0755 + owner: zorian + group: zorian + + scripts: postinstall: pkg/scripts/postinstall.sh preremove: pkg/scripts/preremove.sh diff --git a/pkg/zorian.service b/pkg/zorian.service index dc43e72..23f0b43 100644 --- a/pkg/zorian.service +++ b/pkg/zorian.service @@ -4,25 +4,23 @@ [Unit] Description=Zorian server (tiny packages caching proxy) Requires=network-online.target -Wants=time-sync.target After=time-sync.target network-online.target remote-fs.target nss-lookup.target +Wants=time-sync.target [Service] Type=exec User=zorian Group=zorian +Restart=always +RestartSec=30 ExecPaths=/usr/local/bin/zorian /usr/lib -ExecStart=/usr/local/bin/zorian --config=/etc/zorian.toml --pid-file=%t/%p/%p.pid +ExecStart=/usr/local/bin/zorian --config=/etc/zorian.toml LimitCORE=infinity LimitNOFILE=500000 -Restart=always -RestartSec=30 # %p is resolved to the systemd unit name RuntimeDirectory=%p LockPersonality=yes -MemoryDenyWriteExecute=yes -NoExecPaths=/ NoNewPrivileges=yes PrivateDevices=yes PrivateTmp=true diff --git a/pkg/zorian.toml b/pkg/zorian.toml index cae76fd..ffe4159 100644 --- a/pkg/zorian.toml +++ b/pkg/zorian.toml @@ -1,3 +1,5 @@ # SPDX-FileCopyrightText: 2026 Nikolay Govorov <me@govorov.online> # SPDX-License-Identifier: AGPL-3.0-or-later +addr="0.0.0.0:3000" +dirname="/var/lib/zorian" diff --git a/src/main.rs b/src/main.rs index c8af044..ed44b60 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-or-later use axum::Router; +use std::path::PathBuf; use std::sync::Arc; mod controller_web; @@ -10,9 +11,52 @@ mod service_config; mod service_storage; mod service_upstream; +const VERSION: &str = env!("CARGO_PKG_VERSION"); +const HELP: &str = "\ +Usage: zorian --config=<path> + +Options: + --help Show this help message + --version Show version +"; + #[tokio::main] async fn main() { - let config = Arc::new(service_config::ConfigService::new()); + let mut config_path = None; + + for arg in std::env::args().skip(1) { + if arg == "--help" || arg == "-h" { + print!("{HELP}"); + return; + } + if arg == "--version" || arg == "-V" { + println!("zorian {VERSION}"); + return; + } + if let Some(path) = arg.strip_prefix("--config=") { + config_path = Some(PathBuf::from(path)); + } + } + + let config_path = config_path.expect("missing --config argument"); + + let config = match service_config::ConfigService::from_file(&config_path).await { + Ok(config) => Arc::new(config), + Err(service_config::ConfigError::Io(e)) => { + eprintln!( + "error: failed to read config file '{}': {e}", + config_path.display() + ); + std::process::exit(1); + } + Err(service_config::ConfigError::Parse(e)) => { + eprintln!( + "error: failed to parse config file '{}': {e}", + config_path.display() + ); + std::process::exit(1); + } + }; let storage = Arc::new(service_storage::StorageService::new(config.clone())); let upstream = Arc::new(service_upstream::UpstreamService::new()); diff --git a/src/service_config.rs b/src/service_config.rs index f97fa67..ab7e1c1 100644 --- a/src/service_config.rs +++ b/src/service_config.rs @@ -1,26 +1,45 @@ // SPDX-FileCopyrightText: 2026 Nikolay Govorov <me@govorov.online> // SPDX-License-Identifier: AGPL-3.0-or-later +use std::io; use std::path::{Path, PathBuf}; +use serde::Deserialize; +use tokio::fs; + +#[derive(Debug)] +pub enum ConfigError { + Io(io::Error), + Parse(toml::de::Error), +} + +#[derive(Debug, Deserialize)] pub struct ConfigService { + #[serde(default = "ConfigService::default_addr")] addr: String, + + #[serde(default = "ConfigService::default_dirname")] dirname: PathBuf, } impl ConfigService { - pub fn new() -> Self { - Self { - addr: "0.0.0.0:3000".to_string(), - dirname: PathBuf::from("./zorian-storage"), - } + pub async fn from_file(path: &Path) -> Result<Self, ConfigError> { + let content = fs::read_to_string(path).await.map_err(ConfigError::Io)?; + let config = toml::from_str(&content).map_err(ConfigError::Parse)?; + Ok(config) } pub fn addr(&self) -> &str { - self.addr.as_str() + &self.addr + } + fn default_addr() -> String { + "0.0.0.0:3000".to_string() } pub fn dirname(&self) -> &Path { - self.dirname.as_path() + &self.dirname + } + fn default_dirname() -> PathBuf { + PathBuf::from("./zorian-storage") } } |
