From 89757973a94703ba43ce82a9c53712fc331f13e9 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Tue, 25 Apr 2023 21:50:34 -0400 Subject: [PATCH] Create config using figment --- .gitignore | 3 +- Cargo.lock | 124 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 5 ++ config-example.toml | 3 ++ src/api/catalog.rs | 2 +- src/api/tags.rs | 2 +- src/api/uploads.rs | 2 +- src/app_state.rs | 9 ++-- src/config.rs | 47 +++++++++++++++++ src/main.rs | 16 +++--- 10 files changed, 199 insertions(+), 14 deletions(-) create mode 100644 config-example.toml create mode 100644 src/config.rs diff --git a/.gitignore b/.gitignore index b96bb21..4ebe4f9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .env .vscode test.db -/registry \ No newline at end of file +/registry +config.toml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 308e503..4948682 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,6 +37,12 @@ version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +[[package]] +name = "argmap" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c007f456524f3f1e06e8929963425b5dadf8616d9110ea0809840c16997994e9" + [[package]] name = "async-stream" version = "0.3.5" @@ -79,6 +85,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" +dependencies = [ + "autocfg", +] + [[package]] name = "atty" version = "0.2.14" @@ -430,6 +445,7 @@ name = "docker-registry" version = "0.1.0" dependencies = [ "anyhow", + "argmap", "async-stream", "async-trait", "axum", @@ -437,6 +453,8 @@ dependencies = [ "bytes", "chrono", "clap", + "figment", + "figment-cliarg-provider", "futures", "jws", "pin-project-lite", @@ -453,6 +471,7 @@ dependencies = [ "tracing-log", "tracing-subscriber", "uuid", + "wild", ] [[package]] @@ -473,6 +492,30 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "figment" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9" +dependencies = [ + "atomic", + "pear", + "serde", + "toml", + "uncased", + "version_check", +] + +[[package]] +name = "figment-cliarg-provider" +version = "0.1.0" +source = "git+https://github.com/SeanOMik/figment-cliarg-provider.git?branch=main#9635684d91b89092319ae057de437a7b3c8d6019" +dependencies = [ + "argmap", + "figment", + "wild", +] + [[package]] name = "flume" version = "0.10.14" @@ -621,6 +664,12 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "hashbrown" version = "0.12.3" @@ -779,6 +828,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inlinable_string" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" + [[package]] name = "instant" version = "0.1.12" @@ -1018,6 +1073,29 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" +[[package]] +name = "pear" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec95680a7087503575284e5063e14b694b7a9c0b065e5dceec661e0497127e8" +dependencies = [ + "inlinable_string", + "pear_codegen", + "yansi", +] + +[[package]] +name = "pear_codegen" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9661a3a53f93f09f2ea882018e4d7c88f6ff2956d809a276060476fd8c879d3c" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote 1.0.26", + "syn 2.0.15", +] + [[package]] name = "percent-encoding" version = "2.2.0" @@ -1101,6 +1179,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b" +dependencies = [ + "proc-macro2", + "quote 1.0.26", + "syn 2.0.15", + "version_check", + "yansi", +] + [[package]] name = "quote" version = "0.3.15" @@ -1673,6 +1764,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "tower" version = "0.4.13" @@ -1791,6 +1891,15 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "uncased" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.8" @@ -1986,6 +2095,15 @@ dependencies = [ "webpki", ] +[[package]] +name = "wild" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b116685a6be0c52f5a103334cbff26db643826c7b3735fc0a3ba9871310a74" +dependencies = [ + "glob", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2073,3 +2191,9 @@ name = "windows_x86_64_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/Cargo.toml b/Cargo.toml index fa12c12..4196336 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,3 +38,8 @@ axum-macros = "0.3.7" tower-http = { version = "0.4.0", features = [ "trace", "normalize-path" ] } tower-layer = { version = "0.3.2" } + +figment = { version = "0.10", features = ["toml", "env"] } +figment-cliarg-provider = { git = "https://github.com/SeanOMik/figment-cliarg-provider.git", branch = "main" } +wild = "2.1.0" +argmap = "1.1.2" diff --git a/config-example.toml b/config-example.toml new file mode 100644 index 0000000..fb6e0cd --- /dev/null +++ b/config-example.toml @@ -0,0 +1,3 @@ +listen_address = "127.0.0.1" +listen_port = "3000" +url = "http://localhost:3000/" \ No newline at end of file diff --git a/src/api/catalog.rs b/src/api/catalog.rs index 6905195..0f9eb57 100644 --- a/src/api/catalog.rs +++ b/src/api/catalog.rs @@ -36,7 +36,7 @@ pub async fn list_repositories(Query(params): Query, sta let last_repo = repos.last().and_then(|s| Some(s.clone())); // Construct the link header - let url = crate::REGISTRY_URL; + let url = &state.config.url; let mut url = format!("<{}/v2/_catalog?n={}", url, limit); if let Some(last_repo) = last_repo { url += &format!("&limit={}", last_repo); diff --git a/src/api/tags.rs b/src/api/tags.rs index a4dfff5..971cc48 100644 --- a/src/api/tags.rs +++ b/src/api/tags.rs @@ -37,7 +37,7 @@ pub async fn list_tags(Path((name, )): Path<(String, )>, Query(params): Query
  • , pub storage: Mutex>, + pub config: Config, } impl AppState { - pub fn new/* */(database: Pool, storage: Mutex>) -> Self - /* where - S: StorageDriver, */ + pub fn new(database: Pool, storage: Mutex>, config: Config) -> Self { Self { database, - storage + storage, + config, } } } \ No newline at end of file diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..6e81455 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,47 @@ +use figment::{Figment, providers::{Env, Toml, Format}}; +use figment_cliarg_provider::FigmentCliArgsProvider; +use serde::Deserialize; + +use std::env; + +#[derive(Deserialize)] +pub struct Config { + pub listen_address: String, + pub listen_port: String, + pub url: String, +} + +#[allow(dead_code)] +impl Config { + pub fn new() -> Result { + // The path of the config file without the file extension + let path = { + let args: Vec = wild::args().collect(); + let (_args, argv) = argmap::parse(args.iter()); + + match argv.get("--config-path") { + Some(path) => { + path.first().unwrap().clone() + }, + None => match env::var("ORCA_REG_CONFIG") { + Ok(path) => path, + Err(_) => "config.toml".to_string(), + } + } + }; + + // Merge the config files + let figment = Figment::new() + .join(FigmentCliArgsProvider::new()) + .join(Env::prefixed("ORCA_REG_")) + .join(Toml::file(format!("{}", path))); + + let mut config: Config = figment.extract()?; + + if config.url.ends_with("/") { + config.url = config.url[..config.url.len() - 1].to_string(); + } + + Ok(config) + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d2ddadd..f6389e7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,8 +4,10 @@ mod database; mod dto; mod storage; mod byte_stream; +mod config; use std::net::SocketAddr; +use std::str::FromStr; use std::sync::Arc; use axum::http::Request; @@ -26,9 +28,9 @@ use database::Database; use crate::storage::StorageDriver; use crate::storage::filesystem::FilesystemDriver; -use tower_http::trace::TraceLayer; +use crate::config::Config; -pub const REGISTRY_URL: &'static str = "http://localhost:3000"; // TODO: Move into configuration or something (make sure it doesn't end in /) +use tower_http::trace::TraceLayer; /// Encode the 'name' path parameter in the url async fn change_request_paths(mut request: Request, next: Next) -> Response { @@ -62,7 +64,10 @@ async fn main() -> std::io::Result<()> { let storage_driver: Mutex> = Mutex::new(Box::new(FilesystemDriver::new("registry/blobs"))); - let state = Arc::new(AppState::new(pool, storage_driver)); + let config = Config::new().expect("Failure to parse config!"); + let app_addr = SocketAddr::from_str(&format!("{}:{}", config.listen_address, config.listen_port)).unwrap(); + + let state = Arc::new(AppState::new(pool, storage_driver, config)); tracing_subscriber::fmt() .with_max_level(Level::DEBUG) @@ -98,9 +103,8 @@ async fn main() -> std::io::Result<()> { let layered_app = NormalizePathLayer::trim_trailing_slash().layer(path_middleware.layer(app)); - let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); - debug!("Starting http server, listening on {}", addr); - axum::Server::bind(&addr) + debug!("Starting http server, listening on {}", app_addr); + axum::Server::bind(&app_addr) .serve(layered_app.into_make_service()) .await .unwrap();