proper config file

This commit is contained in:
Robin Appelman 2024-03-27 13:33:29 +01:00
commit b361d49340
7 changed files with 389 additions and 65 deletions

55
src/config.rs Normal file
View file

@ -0,0 +1,55 @@
use demostf_client::ApiClient;
use serde::Deserialize;
use std::fs::read_to_string;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("Failed to read config from {path}: {error}")]
Read { error: std::io::Error, path: String },
#[error("Failed to parse config from {path}: {error}")]
Parse {
error: toml::de::Error,
path: String,
},
}
#[derive(Debug, Deserialize)]
pub struct Config {
pub api: ApiConfig,
pub source: StorageConfig,
pub target: StorageConfig,
pub migrate: MigrateConfig,
}
impl Config {
pub fn load(path: String) -> Result<Self, ConfigError> {
let content = read_to_string(&path).map_err(|error| ConfigError::Read {
error,
path: path.clone(),
})?;
toml::from_str(&content).map_err(|error| ConfigError::Parse { error, path })
}
}
#[derive(Debug, Deserialize)]
pub struct ApiConfig {
#[serde(default = "default_api_base")]
pub url: String,
pub key_file: String,
}
fn default_api_base() -> String {
ApiClient::DEMOS_TF_BASE_URL.into()
}
#[derive(Debug, Deserialize)]
pub struct MigrateConfig {
pub age: u64,
}
#[derive(Debug, Deserialize)]
pub struct StorageConfig {
pub root: String,
pub backend: String,
}

View file

@ -1,7 +1,9 @@
use crate::config::{Config, ConfigError};
use clap::Parser;
use demostf_client::{ApiClient, Demo, ListOrder, ListParams};
use main_error::{MainError, MainResult};
use md5::Context;
use std::collections::HashMap;
use secretfile::{load, SecretError};
use std::fs::{copy, create_dir_all, remove_file, write, File};
use std::io::Read;
use std::path::{Path, PathBuf};
@ -11,6 +13,8 @@ use time::OffsetDateTime;
use tokio::time::timeout;
use tracing::{error, info, instrument, warn};
mod config;
#[derive(Debug, Error)]
pub enum Error {
#[error("Request failed: {0}")]
@ -19,36 +23,31 @@ pub enum Error {
Api(#[from] demostf_client::Error),
#[error("Backup timed out")]
Timeout,
#[error(transparent)]
Config(#[from] ConfigError),
#[error(transparent)]
Secret(#[from] SecretError),
}
#[derive(Debug, Parser)]
struct Args {
/// Config file
config: String,
}
#[tokio::main]
async fn main() -> Result<(), MainError> {
tracing_subscriber::fmt::init();
let mut args: HashMap<_, _> = dotenvy::vars().collect();
let args = Args::parse();
let config = Config::load(args.config)?;
let source_root: PathBuf = args
.remove("SOURCE_ROOT")
.expect("no SOURCE_ROOT set")
.trim_end_matches('/')
.into();
let target_root: PathBuf = args
.remove("TARGET_ROOT")
.expect("no TARGET_ROOT set")
.trim_end_matches('/')
.into();
let api_key = args.remove("KEY").expect("no KEY set");
let source_backend = args
.remove("SOURCE_BACKEND")
.expect("no SOURCE_BACKEND set");
let target_backend = args
.remove("TARGET_BACKEND")
.expect("no TARGET_BACKEND set");
let age: u64 = args
.get("AGE")
.expect("no AGE set")
.parse()
.expect("invalid AGE");
let source_root: PathBuf = config.source.root.trim_end_matches('/').into();
let target_root: PathBuf = config.target.root.trim_end_matches('/').into();
let api_key = load(&config.api.key_file)?;
let source_backend = config.source.backend;
let target_backend = config.target.backend;
let age = config.migrate.age;
let cutoff = OffsetDateTime::now_utc() - Duration::from_secs(age);
info!(cutoff = display(cutoff), "starting move");