Create config using figment

This commit is contained in:
SeanOMik 2023-04-25 21:50:34 -04:00
parent a3eda9e883
commit 89757973a9
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
10 changed files with 199 additions and 14 deletions

3
.gitignore vendored
View File

@ -2,4 +2,5 @@
.env .env
.vscode .vscode
test.db test.db
/registry /registry
config.toml

124
Cargo.lock generated
View File

@ -37,6 +37,12 @@ version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
[[package]]
name = "argmap"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c007f456524f3f1e06e8929963425b5dadf8616d9110ea0809840c16997994e9"
[[package]] [[package]]
name = "async-stream" name = "async-stream"
version = "0.3.5" version = "0.3.5"
@ -79,6 +85,15 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "atomic"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@ -430,6 +445,7 @@ name = "docker-registry"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"argmap",
"async-stream", "async-stream",
"async-trait", "async-trait",
"axum", "axum",
@ -437,6 +453,8 @@ dependencies = [
"bytes", "bytes",
"chrono", "chrono",
"clap", "clap",
"figment",
"figment-cliarg-provider",
"futures", "futures",
"jws", "jws",
"pin-project-lite", "pin-project-lite",
@ -453,6 +471,7 @@ dependencies = [
"tracing-log", "tracing-log",
"tracing-subscriber", "tracing-subscriber",
"uuid", "uuid",
"wild",
] ]
[[package]] [[package]]
@ -473,6 +492,30 @@ version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 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]] [[package]]
name = "flume" name = "flume"
version = "0.10.14" version = "0.10.14"
@ -621,6 +664,12 @@ dependencies = [
"wasi 0.11.0+wasi-snapshot-preview1", "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]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.3"
@ -779,6 +828,12 @@ dependencies = [
"hashbrown", "hashbrown",
] ]
[[package]]
name = "inlinable_string"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
[[package]] [[package]]
name = "instant" name = "instant"
version = "0.1.12" version = "0.1.12"
@ -1018,6 +1073,29 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" 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]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.2.0" version = "2.2.0"
@ -1101,6 +1179,19 @@ dependencies = [
"unicode-ident", "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]] [[package]]
name = "quote" name = "quote"
version = "0.3.15" version = "0.3.15"
@ -1673,6 +1764,15 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "toml"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "tower" name = "tower"
version = "0.4.13" version = "0.4.13"
@ -1791,6 +1891,15 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 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]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.8" version = "0.3.8"
@ -1986,6 +2095,15 @@ dependencies = [
"webpki", "webpki",
] ]
[[package]]
name = "wild"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b116685a6be0c52f5a103334cbff26db643826c7b3735fc0a3ba9871310a74"
dependencies = [
"glob",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"
@ -2073,3 +2191,9 @@ name = "windows_x86_64_msvc"
version = "0.42.0" version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
[[package]]
name = "yansi"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"

View File

@ -38,3 +38,8 @@ axum-macros = "0.3.7"
tower-http = { version = "0.4.0", features = [ "trace", "normalize-path" ] } tower-http = { version = "0.4.0", features = [ "trace", "normalize-path" ] }
tower-layer = { version = "0.3.2" } 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"

3
config-example.toml Normal file
View File

@ -0,0 +1,3 @@
listen_address = "127.0.0.1"
listen_port = "3000"
url = "http://localhost:3000/"

View File

@ -36,7 +36,7 @@ pub async fn list_repositories(Query(params): Query<ListRepositoriesParams>, sta
let last_repo = repos.last().and_then(|s| Some(s.clone())); let last_repo = repos.last().and_then(|s| Some(s.clone()));
// Construct the link header // Construct the link header
let url = crate::REGISTRY_URL; let url = &state.config.url;
let mut url = format!("<{}/v2/_catalog?n={}", url, limit); let mut url = format!("<{}/v2/_catalog?n={}", url, limit);
if let Some(last_repo) = last_repo { if let Some(last_repo) = last_repo {
url += &format!("&limit={}", last_repo); url += &format!("&limit={}", last_repo);

View File

@ -37,7 +37,7 @@ pub async fn list_tags(Path((name, )): Path<(String, )>, Query(params): Query<Li
let last_tag = tags.last(); let last_tag = tags.last();
// Construct the link header // Construct the link header
let url = crate::REGISTRY_URL; let url = &state.config.url;
let mut url = format!("<{}/v2/{}/tags/list?n={}", url, name, limit); let mut url = format!("<{}/v2/{}/tags/list?n={}", url, name, limit);
if let Some(last_tag) = last_tag { if let Some(last_tag) = last_tag {
url += &format!("&limit={}", last_tag.name); url += &format!("&limit={}", last_tag.name);

View File

@ -70,7 +70,7 @@ pub async fn chunked_upload_layer_patch(Path((name, layer_uuid)): Path<(String,
(0, written_size) (0, written_size)
}; };
let full_uri = format!("{}/v2/{}/blobs/uploads/{}", crate::REGISTRY_URL, name, layer_uuid); let full_uri = format!("{}/v2/{}/blobs/uploads/{}", &state.config.url, name, layer_uuid);
( (
StatusCode::ACCEPTED, StatusCode::ACCEPTED,
[ [

View File

@ -1,22 +1,23 @@
use sqlx::{Sqlite, Pool}; use sqlx::{Sqlite, Pool};
use crate::storage::StorageDriver; use crate::storage::StorageDriver;
use crate::config::Config;
use tokio::sync::Mutex; use tokio::sync::Mutex;
pub struct AppState { pub struct AppState {
pub database: Pool<Sqlite>, pub database: Pool<Sqlite>,
pub storage: Mutex<Box<dyn StorageDriver>>, pub storage: Mutex<Box<dyn StorageDriver>>,
pub config: Config,
} }
impl AppState { impl AppState {
pub fn new/* <S> */(database: Pool<Sqlite>, storage: Mutex<Box<dyn StorageDriver>>) -> Self pub fn new(database: Pool<Sqlite>, storage: Mutex<Box<dyn StorageDriver>>, config: Config) -> Self
/* where
S: StorageDriver, */
{ {
Self { Self {
database, database,
storage storage,
config,
} }
} }
} }

47
src/config.rs Normal file
View File

@ -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<Self, figment::Error> {
// The path of the config file without the file extension
let path = {
let args: Vec<String> = 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)
}
}

View File

@ -4,8 +4,10 @@ mod database;
mod dto; mod dto;
mod storage; mod storage;
mod byte_stream; mod byte_stream;
mod config;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
use axum::http::Request; use axum::http::Request;
@ -26,9 +28,9 @@ use database::Database;
use crate::storage::StorageDriver; use crate::storage::StorageDriver;
use crate::storage::filesystem::FilesystemDriver; 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 /// Encode the 'name' path parameter in the url
async fn change_request_paths<B>(mut request: Request<B>, next: Next<B>) -> Response { async fn change_request_paths<B>(mut request: Request<B>, next: Next<B>) -> Response {
@ -62,7 +64,10 @@ async fn main() -> std::io::Result<()> {
let storage_driver: Mutex<Box<dyn StorageDriver>> = Mutex::new(Box::new(FilesystemDriver::new("registry/blobs"))); let storage_driver: Mutex<Box<dyn StorageDriver>> = 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() tracing_subscriber::fmt()
.with_max_level(Level::DEBUG) .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 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 {}", app_addr);
debug!("Starting http server, listening on {}", addr); axum::Server::bind(&app_addr)
axum::Server::bind(&addr)
.serve(layered_app.into_make_service()) .serve(layered_app.into_make_service())
.await .await
.unwrap(); .unwrap();