Skip to content

Commit

Permalink
Merge torrust#991: Config overhaul: use an explicit section for metadata
Browse files Browse the repository at this point in the history
287e484 feat!: [torrust#958] improve metadata in config files (Jose Celano)

Pull request description:

  The metadata section in the configuration file is changed:

  TOML:

  ```toml
  [metadata]
  app = "torrust-tracker"
  purpose = "configuration"
  schema_version = "2.0.0"
  ```

  JSON:

  ```json
  {
    "metadata": {
      "app": "torrust-tracker",
      "purpose": "configuration",
      "version": "2.0.0"
    }
  }
  ```

  - `app`: the application this config file is used for.
  - `purpose`: the purpose of the file containing these metadata.
  - `schema_version`: the schema version for the file being parsed.

ACKs for top commit:
  josecelano:
    ACK 287e484

Tree-SHA512: 86ee59ddb7a76fee24289d1ea801e7d7e492f5c265d2b6569b0aecc368f3d97d3c7463cf0ebf9fafe16827e8008409c57a994608add2afee97514adf91203746
  • Loading branch information
josecelano committed Aug 2, 2024
2 parents d47ff21 + 287e484 commit f95b16a
Show file tree
Hide file tree
Showing 17 changed files with 93 additions and 43 deletions.
71 changes: 52 additions & 19 deletions packages/configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! Torrust Tracker, which is a `BitTorrent` tracker server.
//!
//! The current version for configuration is [`v2`].
pub mod v2;
pub mod v2_0_0;
pub mod validator;

use std::collections::HashMap;
Expand Down Expand Up @@ -35,67 +35,100 @@ const ENV_VAR_CONFIG_TOML: &str = "TORRUST_TRACKER_CONFIG_TOML";
/// The `tracker.toml` file location.
pub const ENV_VAR_CONFIG_TOML_PATH: &str = "TORRUST_TRACKER_CONFIG_TOML_PATH";

pub type Configuration = v2::Configuration;
pub type Core = v2::core::Core;
pub type HealthCheckApi = v2::health_check_api::HealthCheckApi;
pub type HttpApi = v2::tracker_api::HttpApi;
pub type HttpTracker = v2::http_tracker::HttpTracker;
pub type UdpTracker = v2::udp_tracker::UdpTracker;
pub type Database = v2::database::Database;
pub type Driver = v2::database::Driver;
pub type Threshold = v2::logging::Threshold;
pub type Configuration = v2_0_0::Configuration;
pub type Core = v2_0_0::core::Core;
pub type HealthCheckApi = v2_0_0::health_check_api::HealthCheckApi;
pub type HttpApi = v2_0_0::tracker_api::HttpApi;
pub type HttpTracker = v2_0_0::http_tracker::HttpTracker;
pub type UdpTracker = v2_0_0::udp_tracker::UdpTracker;
pub type Database = v2_0_0::database::Database;
pub type Driver = v2_0_0::database::Driver;
pub type Threshold = v2_0_0::logging::Threshold;

pub type AccessTokens = HashMap<String, String>;

pub const LATEST_VERSION: &str = "2";
pub const LATEST_VERSION: &str = "2.0.0";

/// Info about the configuration specification.
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display, Clone)]
#[display(fmt = "Metadata(app: {app}, purpose: {purpose}, schema_version: {schema_version})")]
pub struct Metadata {
#[serde(default = "Metadata::default_version")]
/// The application this configuration is valid for.
#[serde(default = "Metadata::default_app")]
app: App,

/// The purpose of this parsed file.
#[serde(default = "Metadata::default_purpose")]
purpose: Purpose,

/// The schema version for the configuration.
#[serde(default = "Metadata::default_schema_version")]
#[serde(flatten)]
version: Version,
schema_version: Version,
}

impl Default for Metadata {
fn default() -> Self {
Self {
version: Self::default_version(),
app: Self::default_app(),
purpose: Self::default_purpose(),
schema_version: Self::default_schema_version(),
}
}
}

impl Metadata {
fn default_version() -> Version {
fn default_app() -> App {
App::TorrustTracker
}

fn default_purpose() -> Purpose {
Purpose::Configuration
}

fn default_schema_version() -> Version {
Version::latest()
}
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display, Clone)]
#[serde(rename_all = "kebab-case")]
pub enum App {
TorrustTracker,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display, Clone)]
#[serde(rename_all = "lowercase")]
pub enum Purpose {
Configuration,
}

/// The configuration version.
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Display, Clone)]
#[serde(rename_all = "lowercase")]
pub struct Version {
#[serde(default = "Version::default_semver")]
version: String,
schema_version: String,
}

impl Default for Version {
fn default() -> Self {
Self {
version: Self::default_semver(),
schema_version: Self::default_semver(),
}
}
}

impl Version {
fn new(semver: &str) -> Self {
Self {
version: semver.to_owned(),
schema_version: semver.to_owned(),
}
}

fn latest() -> Self {
Self {
version: LATEST_VERSION.to_string(),
schema_version: LATEST_VERSION.to_string(),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ use derive_more::{Constructor, Display};
use serde::{Deserialize, Serialize};

use super::network::Network;
use crate::v2::database::Database;
use crate::v2_0_0::database::Database;
use crate::validator::{SemanticValidationError, Validator};
use crate::{AnnouncePolicy, TrackerPolicy};

#[allow(clippy::struct_excessive_bools)]
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
pub struct Core {
// Announce policy configuration.
/// Announce policy configuration.
#[serde(default = "Core::default_announce_policy")]
pub announce_policy: AnnouncePolicy,

// Database configuration.
/// Database configuration.
#[serde(default = "Core::default_database")]
pub database: Database,

Expand All @@ -22,23 +22,23 @@ pub struct Core {
#[serde(default = "Core::default_inactive_peer_cleanup_interval")]
pub inactive_peer_cleanup_interval: u64,

// When `true` only approved torrents can be announced in the tracker.
/// When `true` only approved torrents can be announced in the tracker.
#[serde(default = "Core::default_listed")]
pub listed: bool,

// Network configuration.
/// Network configuration.
#[serde(default = "Core::default_network")]
pub net: Network,

// When `true` clients require a key to connect and use the tracker.
/// When `true` clients require a key to connect and use the tracker.
#[serde(default = "Core::default_private")]
pub private: bool,

// Configuration specific when the tracker is running in private mode.
/// Configuration specific when the tracker is running in private mode.
#[serde(default = "Core::default_private_mode")]
pub private_mode: Option<PrivateMode>,

// Tracker policy configuration.
/// Tracker policy configuration.
#[serde(default = "Core::default_tracker_policy")]
pub tracker_policy: TrackerPolicy,

Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ use crate::validator::{SemanticValidationError, Validator};
use crate::{Error, Info, Metadata, Version};

/// This configuration version
const VERSION_2: &str = "2";
const VERSION_2_0_0: &str = "2.0.0";

/// Prefix for env vars that overwrite configuration options.
const CONFIG_OVERRIDE_PREFIX: &str = "TORRUST_TRACKER_CONFIG_OVERRIDE_";
Expand All @@ -267,7 +267,6 @@ const CONFIG_OVERRIDE_SEPARATOR: &str = "__";
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default, Clone)]
pub struct Configuration {
/// Configuration metadata.
#[serde(flatten)]
pub metadata: Metadata,

/// Logging configuration
Expand Down Expand Up @@ -335,9 +334,9 @@ impl Configuration {

let config: Configuration = figment.extract()?;

if config.metadata.version != Version::new(VERSION_2) {
if config.metadata.schema_version != Version::new(VERSION_2_0_0) {
return Err(Error::UnsupportedVersion {
version: config.metadata.version,
version: config.metadata.schema_version,
});
}

Expand Down Expand Up @@ -406,12 +405,15 @@ mod tests {

use std::net::{IpAddr, Ipv4Addr};

use crate::v2::Configuration;
use crate::v2_0_0::Configuration;
use crate::Info;

#[cfg(test)]
fn default_config_toml() -> String {
let config = r#"version = "2"
let config = r#"[metadata]
app = "torrust-tracker"
purpose = "configuration"
schema_version = "2.0.0"
[logging]
threshold = "info"
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl HttpApi {

#[cfg(test)]
mod tests {
use crate::v2::tracker_api::HttpApi;
use crate::v2_0_0::tracker_api::HttpApi;

#[test]
fn http_api_configuration_should_check_if_it_contains_a_token() {
Expand Down
5 changes: 4 additions & 1 deletion share/default/config/tracker.container.mysql.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
version = "2"
[metadata]
app = "torrust-tracker"
purpose = "configuration"
schema_version = "2.0.0"

[core.database]
driver = "mysql"
Expand Down
5 changes: 4 additions & 1 deletion share/default/config/tracker.container.sqlite3.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
version = "2"
[metadata]
app = "torrust-tracker"
purpose = "configuration"
schema_version = "2.0.0"

[core.database]
path = "/var/lib/torrust/tracker/database/sqlite3.db"
Expand Down
5 changes: 4 additions & 1 deletion share/default/config/tracker.development.sqlite3.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
version = "2"
[metadata]
app = "torrust-tracker"
purpose = "configuration"
schema_version = "2.0.0"

[[udp_trackers]]
bind_address = "0.0.0.0:6969"
Expand Down
5 changes: 4 additions & 1 deletion share/default/config/tracker.e2e.container.sqlite3.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
version = "2"
[metadata]
app = "torrust-tracker"
purpose = "configuration"
schema_version = "2.0.0"

[core.database]
path = "/var/lib/torrust/tracker/database/sqlite3.db"
Expand Down
5 changes: 4 additions & 1 deletion share/default/config/tracker.udp.benchmarking.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
version = "2"
[metadata]
app = "torrust-tracker"
purpose = "configuration"
schema_version = "2.0.0"

[logging]
threshold = "error"
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub const DEFAULT_PATH_CONFIG: &str = "./share/default/config/tracker.developmen
#[must_use]
pub fn initialize_configuration() -> Configuration {
let info = Info::new(DEFAULT_PATH_CONFIG.to_string()).expect("info to load configuration is not valid");
Configuration::load(&info).expect("configuration should be loaded from provided info")
Configuration::load(&info).expect("error loading configuration from sources")
}

#[cfg(test)]
Expand Down
6 changes: 3 additions & 3 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ use derive_more::Constructor;
use error::PeerKeyError;
use tokio::sync::mpsc::error::SendError;
use torrust_tracker_clock::clock::Time;
use torrust_tracker_configuration::v2::database;
use torrust_tracker_configuration::v2_0_0::database;
use torrust_tracker_configuration::{AnnouncePolicy, Core, TORRENT_PEERS_LIMIT};
use torrust_tracker_located_error::Located;
use torrust_tracker_primitives::info_hash::InfoHash;
Expand Down Expand Up @@ -1841,7 +1841,7 @@ mod tests {
use std::time::Duration;

use torrust_tracker_clock::clock::Time;
use torrust_tracker_configuration::v2::core::PrivateMode;
use torrust_tracker_configuration::v2_0_0::core::PrivateMode;

use crate::core::auth::Key;
use crate::core::tests::the_tracker::private_tracker;
Expand Down Expand Up @@ -1893,7 +1893,7 @@ mod tests {
use std::time::Duration;

use torrust_tracker_clock::clock::Time;
use torrust_tracker_configuration::v2::core::PrivateMode;
use torrust_tracker_configuration::v2_0_0::core::PrivateMode;

use crate::core::auth::Key;
use crate::core::tests::the_tracker::private_tracker;
Expand Down

0 comments on commit f95b16a

Please sign in to comment.