2
0
Fork 0
mirror of https://git.asonix.dog/asonix/pict-rs synced 2024-11-10 06:25:00 +00:00
pict-rs/src/config/commandline.rs

850 lines
28 KiB
Rust
Raw Normal View History

2022-03-28 04:27:07 +00:00
use crate::{
2023-07-13 22:42:21 +00:00
config::primitives::{LogFormat, Targets},
formats::{AnimationFormat, AudioCodec, ImageFormat, VideoCodec},
2022-03-28 04:27:07 +00:00
serde_str::Serde,
};
2022-03-28 00:10:06 +00:00
use clap::{Parser, Subcommand};
use std::{net::SocketAddr, path::PathBuf};
use url::Url;
2022-03-28 04:27:07 +00:00
impl Args {
pub(super) fn into_output(self) -> Output {
let Args {
config_file,
old_db_path,
log_format,
log_targets,
console_address,
console_buffer_capacity,
opentelemetry_url,
opentelemetry_service_name,
opentelemetry_targets,
save_to,
command,
} = self;
let old_db = OldDb { path: old_db_path };
let tracing = Tracing {
logging: Logging {
format: log_format,
targets: log_targets.map(Serde::new),
},
console: Console {
address: console_address,
buffer_capacity: console_buffer_capacity,
},
opentelemetry: OpenTelemetry {
url: opentelemetry_url,
service_name: opentelemetry_service_name,
targets: opentelemetry_targets.map(Serde::new),
},
};
match command {
Command::Run(Run {
address,
api_key,
worker_id,
client_pool_size,
media_preprocess_steps,
2022-03-28 04:27:07 +00:00
media_max_file_size,
2023-07-13 22:42:21 +00:00
media_image_max_width,
media_image_max_height,
media_image_max_area,
media_image_max_file_size,
media_image_format,
media_animation_max_width,
media_animation_max_height,
media_animation_max_area,
media_animation_max_file_size,
media_animation_max_frame_count,
media_animation_format,
media_video_enable,
media_video_allow_audio,
media_video_max_width,
media_video_max_height,
media_video_max_area,
media_video_max_file_size,
media_video_max_frame_count,
media_video_codec,
2023-07-13 22:42:21 +00:00
media_video_audio_codec,
2022-03-28 04:27:07 +00:00
media_filters,
store,
}) => {
let server = Server {
address,
api_key,
worker_id,
client_pool_size,
};
2023-07-13 22:42:21 +00:00
let image = Image {
max_file_size: media_image_max_file_size,
max_width: media_image_max_width,
max_height: media_image_max_height,
max_area: media_image_max_area,
format: media_image_format,
};
let animation = Animation {
max_file_size: media_animation_max_file_size,
max_width: media_animation_max_width,
max_height: media_animation_max_height,
max_area: media_animation_max_area,
max_frame_count: media_animation_max_frame_count,
format: media_animation_format,
};
let video = Video {
enable: media_video_enable,
allow_audio: media_video_allow_audio,
max_file_size: media_video_max_file_size,
max_width: media_video_max_width,
max_height: media_video_max_height,
max_area: media_video_max_area,
max_frame_count: media_video_max_frame_count,
video_codec: media_video_codec,
audio_codec: media_video_audio_codec,
2023-02-04 23:32:36 +00:00
};
2023-07-13 22:42:21 +00:00
2022-03-28 04:27:07 +00:00
let media = Media {
max_file_size: media_max_file_size,
2023-07-13 22:42:21 +00:00
preprocess_steps: media_preprocess_steps,
2022-03-28 04:27:07 +00:00
filters: media_filters,
2023-07-13 22:42:21 +00:00
image: image.set(),
animation: animation.set(),
video: video.set(),
2022-03-28 04:27:07 +00:00
};
let operation = Operation::Run;
match store {
Some(RunStore::Filesystem(RunFilesystem { system, repo })) => {
let store = Some(Store::Filesystem(system));
Output {
config_format: ConfigFormat {
server,
old_db,
tracing,
media,
store,
repo,
},
operation,
config_file,
save_to,
}
}
Some(RunStore::ObjectStorage(RunObjectStorage { storage, repo })) => {
let store = Some(Store::ObjectStorage(storage));
Output {
config_format: ConfigFormat {
server,
old_db,
tracing,
media,
store,
repo,
},
operation,
config_file,
save_to,
}
}
None => Output {
config_format: ConfigFormat {
server,
old_db,
tracing,
media,
store: None,
repo: None,
},
operation,
config_file,
save_to,
},
}
}
Command::MigrateStore(MigrateStore {
skip_missing_files,
store,
}) => {
2022-03-28 04:27:07 +00:00
let server = Server::default();
let media = Media::default();
match store {
MigrateStoreFrom::Filesystem(MigrateFilesystem { from, to }) => match to {
MigrateStoreTo::Filesystem(MigrateFilesystemInner { to, repo }) => Output {
2022-03-28 04:27:07 +00:00
config_format: ConfigFormat {
server,
old_db,
tracing,
media,
store: None,
repo,
},
operation: Operation::MigrateStore {
skip_missing_files,
2022-03-28 04:27:07 +00:00
from: from.into(),
to: to.into(),
},
config_file,
save_to,
},
MigrateStoreTo::ObjectStorage(MigrateObjectStorageInner { to, repo }) => {
2022-03-28 04:27:07 +00:00
Output {
config_format: ConfigFormat {
server,
old_db,
tracing,
media,
store: None,
repo,
},
operation: Operation::MigrateStore {
skip_missing_files,
2022-03-28 04:27:07 +00:00
from: from.into(),
to: to.into(),
},
config_file,
save_to,
}
}
},
MigrateStoreFrom::ObjectStorage(MigrateObjectStorage { from, to }) => {
match to {
MigrateStoreTo::Filesystem(MigrateFilesystemInner { to, repo }) => {
Output {
config_format: ConfigFormat {
server,
old_db,
tracing,
media,
store: None,
repo,
},
operation: Operation::MigrateStore {
skip_missing_files,
from: from.into(),
to: to.into(),
},
config_file,
save_to,
}
}
MigrateStoreTo::ObjectStorage(MigrateObjectStorageInner {
to,
2022-03-28 04:27:07 +00:00
repo,
}) => Output {
config_format: ConfigFormat {
server,
old_db,
tracing,
media,
store: None,
repo,
},
operation: Operation::MigrateStore {
skip_missing_files,
from: from.into(),
to: to.into(),
},
config_file,
save_to,
2022-03-28 04:27:07 +00:00
},
}
}
2022-03-28 04:27:07 +00:00
}
}
}
}
}
pub(super) struct Output {
pub(super) config_format: ConfigFormat,
pub(super) operation: Operation,
pub(super) save_to: Option<PathBuf>,
pub(super) config_file: Option<PathBuf>,
}
#[allow(clippy::large_enum_variant)]
#[derive(Clone)]
pub(crate) enum Operation {
Run,
MigrateStore {
skip_missing_files: bool,
2022-03-28 04:27:07 +00:00
from: crate::config::primitives::Store,
to: crate::config::primitives::Store,
},
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub(super) struct ConfigFormat {
server: Server,
old_db: OldDb,
tracing: Tracing,
media: Media,
#[serde(skip_serializing_if = "Option::is_none")]
repo: Option<Repo>,
#[serde(skip_serializing_if = "Option::is_none")]
store: Option<Store>,
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct Server {
#[serde(skip_serializing_if = "Option::is_none")]
address: Option<SocketAddr>,
#[serde(skip_serializing_if = "Option::is_none")]
worker_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
2022-03-28 04:27:07 +00:00
api_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
client_pool_size: Option<usize>,
2022-03-28 04:27:07 +00:00
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct Tracing {
logging: Logging,
console: Console,
opentelemetry: OpenTelemetry,
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct Logging {
#[serde(skip_serializing_if = "Option::is_none")]
format: Option<LogFormat>,
#[serde(skip_serializing_if = "Option::is_none")]
targets: Option<Serde<Targets>>,
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct Console {
#[serde(skip_serializing_if = "Option::is_none")]
address: Option<SocketAddr>,
#[serde(skip_serializing_if = "Option::is_none")]
buffer_capacity: Option<usize>,
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct OpenTelemetry {
#[serde(skip_serializing_if = "Option::is_none")]
url: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
service_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
targets: Option<Serde<Targets>>,
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct OldDb {
#[serde(skip_serializing_if = "Option::is_none")]
path: Option<PathBuf>,
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct Media {
2023-07-13 22:42:21 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
max_file_size: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
preprocess_steps: Option<String>,
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
filters: Option<Vec<String>>,
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
image: Option<Image>,
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
animation: Option<Animation>,
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
video: Option<Video>,
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct Image {
#[serde(skip_serializing_if = "Option::is_none")]
max_width: Option<u16>,
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_height: Option<u16>,
2022-09-25 22:36:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_area: Option<u32>,
2023-02-04 23:32:36 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_file_size: Option<usize>,
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
format: Option<ImageFormat>,
}
impl Image {
fn set(self) -> Option<Self> {
let any_set = self.max_width.is_some()
|| self.max_height.is_some()
|| self.max_area.is_some()
|| self.max_file_size.is_some()
|| self.format.is_some();
if any_set {
Some(self)
} else {
None
}
}
}
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct Animation {
2022-09-25 22:36:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_width: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_height: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_area: Option<u32>,
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_frame_count: Option<u32>,
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_file_size: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
format: Option<AnimationFormat>,
}
impl Animation {
fn set(self) -> Option<Self> {
let any_set = self.max_width.is_some()
|| self.max_height.is_some()
|| self.max_area.is_some()
|| self.max_frame_count.is_some()
|| self.max_file_size.is_some()
|| self.format.is_some();
if any_set {
Some(self)
} else {
None
}
}
2022-03-28 04:27:07 +00:00
}
2023-02-04 23:32:36 +00:00
#[derive(Debug, Default, serde::Serialize)]
#[serde(rename_all = "snake_case")]
2023-07-13 22:42:21 +00:00
struct Video {
#[serde(skip_serializing_if = "Option::is_none")]
enable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
allow_audio: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
max_width: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
max_height: Option<u16>,
2023-02-04 23:32:36 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_area: Option<u32>,
2023-02-04 23:32:36 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_frame_count: Option<u32>,
2023-02-04 23:32:36 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
2023-07-13 22:42:21 +00:00
max_file_size: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
video_codec: Option<VideoCodec>,
#[serde(skip_serializing_if = "Option::is_none")]
audio_codec: Option<AudioCodec>,
}
impl Video {
fn set(self) -> Option<Self> {
let any_set = self.enable.is_some()
|| self.allow_audio.is_some()
|| self.max_width.is_some()
|| self.max_height.is_some()
|| self.max_area.is_some()
|| self.max_frame_count.is_some()
|| self.max_file_size.is_some()
|| self.video_codec.is_some()
|| self.audio_codec.is_some();
if any_set {
Some(self)
} else {
None
}
}
2023-02-04 23:32:36 +00:00
}
2022-03-28 00:10:06 +00:00
/// Run the pict-rs application
#[derive(Debug, Parser)]
2022-09-28 23:23:41 +00:00
#[command(author, version, about, long_about = None)]
2022-03-28 04:27:07 +00:00
pub(super) struct Args {
2022-03-28 00:10:06 +00:00
/// Path to the pict-rs configuration file
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
2022-03-28 04:27:07 +00:00
config_file: Option<PathBuf>,
/// Path to the old pict-rs sled database
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
old_db_path: Option<PathBuf>,
2022-03-28 00:10:06 +00:00
/// Format of logs printed to stdout
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
log_format: Option<LogFormat>,
2022-03-28 00:10:06 +00:00
/// Log levels to print to stdout, respects RUST_LOG formatting
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
log_targets: Option<Targets>,
2022-03-28 00:10:06 +00:00
/// Address and port to expose tokio-console metrics
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
console_address: Option<SocketAddr>,
2022-03-28 00:10:06 +00:00
/// Capacity of the console-subscriber Event Buffer
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
console_buffer_capacity: Option<usize>,
2022-03-28 00:10:06 +00:00
/// URL to send OpenTelemetry metrics
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
opentelemetry_url: Option<Url>,
2022-03-28 00:10:06 +00:00
/// Service Name to use for OpenTelemetry
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
opentelemetry_service_name: Option<String>,
2022-03-28 00:10:06 +00:00
/// Log levels to use for OpenTelemetry, respects RUST_LOG formatting
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
opentelemetry_targets: Option<Targets>,
2022-03-28 00:10:06 +00:00
/// File to save the current configuration for reproducible runs
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
save_to: Option<PathBuf>,
2022-03-28 00:10:06 +00:00
2022-09-28 23:23:41 +00:00
#[command(subcommand)]
2022-03-28 04:27:07 +00:00
command: Command,
2022-03-28 00:10:06 +00:00
}
#[derive(Debug, Subcommand)]
2022-03-28 04:27:07 +00:00
enum Command {
2022-03-28 00:10:06 +00:00
/// Runs the pict-rs web server
Run(Run),
/// Migrates from one provided media store to another
MigrateStore(MigrateStore),
}
#[derive(Debug, Parser)]
2022-03-28 04:27:07 +00:00
struct Run {
2022-03-28 00:10:06 +00:00
/// The address and port to bind the pict-rs web server
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
2022-03-28 04:27:07 +00:00
address: Option<SocketAddr>,
2022-03-28 00:10:06 +00:00
/// The API KEY required to access restricted routes
2022-09-28 23:23:41 +00:00
#[arg(long)]
2022-03-28 04:27:07 +00:00
api_key: Option<String>,
2022-03-28 00:10:06 +00:00
/// ID of this pict-rs node. Doesn't do much yet
2022-09-28 23:23:41 +00:00
#[arg(long)]
worker_id: Option<String>,
/// Number of connections the internel HTTP client should maintain in its pool
///
/// This number defaults to 100, and the total number is multiplied by the number of cores
/// available to the program. This means that running on a 2 core system will result in 200
/// pooled connections, and running on a 32 core system will result in 3200 pooled connections.
#[arg(long)]
client_pool_size: Option<usize>,
/// Optional pre-processing steps for uploaded media.
///
/// All still images will be put through these steps before saving
2022-09-28 23:23:41 +00:00
#[arg(long)]
media_preprocess_steps: Option<String>,
2023-07-13 22:42:21 +00:00
/// Which media filters should be enabled on the `process` endpoint
2022-09-28 23:23:41 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_filters: Option<Vec<String>>,
/// The maximum size, in megabytes, for all uploaded media
2022-09-28 23:23:41 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_max_file_size: Option<usize>,
/// The maximum width, in pixels, for uploaded images
2022-09-28 23:23:41 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_image_max_width: Option<u16>,
/// The maximum height, in pixels, for uploaded images
2022-09-28 23:23:41 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_image_max_height: Option<u16>,
/// The maximum area, in pixels, for uploaded images
2022-09-28 23:23:41 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_image_max_area: Option<u32>,
/// The maximum size, in megabytes, for uploaded images
2022-09-28 23:23:41 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_image_max_file_size: Option<usize>,
/// Enforce a specific format for uploaded images
2023-02-04 23:32:36 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_image_format: Option<ImageFormat>,
/// The maximum width, in pixels, for uploaded animations
2023-02-04 23:32:36 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_animation_max_width: Option<u16>,
/// The maximum height, in pixels, for uploaded animations
#[arg(long)]
media_animation_max_height: Option<u16>,
/// The maximum area, in pixels, for uploaded animations
#[arg(long)]
media_animation_max_area: Option<u32>,
/// The maximum number of frames allowed for uploaded animations
#[arg(long)]
media_animation_max_frame_count: Option<u32>,
/// The maximum size, in megabytes, for uploaded animations
#[arg(long)]
media_animation_max_file_size: Option<usize>,
/// Enforce a specific format for uploaded animations
2023-02-04 23:32:36 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_animation_format: Option<AnimationFormat>,
/// Whether to enable video uploads
#[arg(long)]
media_video_enable: Option<bool>,
/// Whether to enable audio in video uploads
media_video_allow_audio: Option<bool>,
/// The maximum width, in pixels, for uploaded videos
#[arg(long)]
media_video_max_width: Option<u16>,
/// The maximum height, in pixels, for uploaded videos
#[arg(long)]
media_video_max_height: Option<u16>,
/// The maximum area, in pixels, for uploaded videos
#[arg(long)]
media_video_max_area: Option<u32>,
/// The maximum number of frames allowed for uploaded videos
2022-09-28 23:23:41 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_video_max_frame_count: Option<u32>,
/// The maximum size, in megabytes, for uploaded videos
2022-09-28 23:23:41 +00:00
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_video_max_file_size: Option<usize>,
/// Enforce a specific video codec for uploaded videos
#[arg(long)]
media_video_codec: Option<VideoCodec>,
/// Enforce a specific audio codec for uploaded videos
#[arg(long)]
2023-07-13 22:42:21 +00:00
media_video_audio_codec: Option<AudioCodec>,
2022-03-28 00:10:06 +00:00
2022-09-28 23:23:41 +00:00
#[command(subcommand)]
2022-03-28 04:27:07 +00:00
store: Option<RunStore>,
2022-03-28 00:10:06 +00:00
}
/// Configure the provided storage
2022-03-28 04:27:07 +00:00
#[derive(Clone, Debug, Subcommand, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type")]
// allow large enum variant - this is an instantiated-once config
#[allow(clippy::large_enum_variant)]
2022-03-28 04:27:07 +00:00
enum Store {
2022-03-28 00:10:06 +00:00
/// configure filesystem storage
Filesystem(Filesystem),
/// configure object storage
ObjectStorage(ObjectStorage),
}
/// Run pict-rs with the provided storage
#[derive(Debug, Subcommand)]
// allow large enum variant - this is an instantiated-once config
#[allow(clippy::large_enum_variant)]
2022-03-28 04:27:07 +00:00
enum RunStore {
2022-03-28 00:10:06 +00:00
/// Run pict-rs with filesystem storage
Filesystem(RunFilesystem),
/// Run pict-rs with object storage
ObjectStorage(RunObjectStorage),
}
#[derive(Debug, Parser)]
struct MigrateStore {
/// Normally, pict-rs will keep retrying when errors occur during migration. This flag tells
/// pict-rs to ignore errors that are caused by files not existing.
#[arg(long)]
skip_missing_files: bool,
#[command(subcommand)]
store: MigrateStoreFrom,
}
2022-03-28 00:10:06 +00:00
/// Configure the pict-rs storage migration
#[derive(Debug, Subcommand)]
// allow large enum variant - this is an instantiated-once config
#[allow(clippy::large_enum_variant)]
enum MigrateStoreFrom {
2022-03-28 00:10:06 +00:00
/// Migrate from the provided filesystem storage
Filesystem(MigrateFilesystem),
/// Migrate from the provided object storage
ObjectStorage(MigrateObjectStorage),
}
2022-03-28 04:27:07 +00:00
/// Configure the destination storage for pict-rs storage migration
#[derive(Debug, Subcommand)]
// allow large enum variant - this is an instantiated-once config
#[allow(clippy::large_enum_variant)]
enum MigrateStoreTo {
2022-03-28 04:27:07 +00:00
/// Migrate to the provided filesystem storage
Filesystem(MigrateFilesystemInner),
/// Migrate to the provided object storage
ObjectStorage(MigrateObjectStorageInner),
}
2022-03-28 00:10:06 +00:00
/// Migrate pict-rs' storage from the provided filesystem storage
#[derive(Debug, Parser)]
2022-03-28 04:27:07 +00:00
struct MigrateFilesystem {
2022-09-28 23:23:41 +00:00
#[command(flatten)]
from: Filesystem,
2022-03-28 04:27:07 +00:00
2022-09-28 23:23:41 +00:00
#[command(subcommand)]
to: MigrateStoreTo,
2022-03-28 04:27:07 +00:00
}
/// Migrate pict-rs' storage to the provided filesystem storage
#[derive(Debug, Parser)]
struct MigrateFilesystemInner {
2022-09-28 23:23:41 +00:00
#[command(flatten)]
to: Filesystem,
2022-03-28 00:10:06 +00:00
2022-09-28 23:23:41 +00:00
#[command(subcommand)]
2022-03-28 04:27:07 +00:00
repo: Option<Repo>,
2022-03-28 00:10:06 +00:00
}
/// Migrate pict-rs' storage from the provided object storage
#[derive(Debug, Parser)]
2022-03-28 04:27:07 +00:00
struct MigrateObjectStorage {
2022-09-28 23:23:41 +00:00
#[command(flatten)]
2022-03-28 04:27:07 +00:00
from: crate::config::primitives::ObjectStorage,
2022-03-28 00:10:06 +00:00
2022-09-28 23:23:41 +00:00
#[command(subcommand)]
to: MigrateStoreTo,
2022-03-28 04:27:07 +00:00
}
/// Migrate pict-rs' storage to the provided object storage
#[derive(Debug, Parser)]
struct MigrateObjectStorageInner {
2022-09-28 23:23:41 +00:00
#[command(flatten)]
2022-03-28 04:27:07 +00:00
to: crate::config::primitives::ObjectStorage,
2022-09-28 23:23:41 +00:00
#[command(subcommand)]
2022-03-28 04:27:07 +00:00
repo: Option<Repo>,
2022-03-28 00:10:06 +00:00
}
/// Run pict-rs with the provided filesystem storage
#[derive(Debug, Parser)]
2022-03-28 04:27:07 +00:00
struct RunFilesystem {
2022-09-28 23:23:41 +00:00
#[command(flatten)]
2022-03-28 04:27:07 +00:00
system: Filesystem,
2022-03-28 00:10:06 +00:00
2022-09-28 23:23:41 +00:00
#[command(subcommand)]
2022-03-28 04:27:07 +00:00
repo: Option<Repo>,
2022-03-28 00:10:06 +00:00
}
/// Run pict-rs with the provided object storage
#[derive(Debug, Parser)]
2022-03-28 04:27:07 +00:00
struct RunObjectStorage {
2022-09-28 23:23:41 +00:00
#[command(flatten)]
2022-03-28 04:27:07 +00:00
storage: ObjectStorage,
2022-03-28 00:10:06 +00:00
2022-09-28 23:23:41 +00:00
#[command(subcommand)]
2022-03-28 04:27:07 +00:00
repo: Option<Repo>,
2022-03-28 00:10:06 +00:00
}
/// Configuration for data repositories
2022-03-28 04:27:07 +00:00
#[derive(Debug, Subcommand, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type")]
enum Repo {
2022-03-28 00:10:06 +00:00
/// Run pict-rs with the provided sled-backed data repository
Sled(Sled),
}
/// Configuration for filesystem media storage
2022-03-28 04:27:07 +00:00
#[derive(Clone, Debug, Parser, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub(super) struct Filesystem {
2022-03-28 00:10:06 +00:00
/// The path to store uploaded media
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
pub(super) path: Option<PathBuf>,
2022-03-28 00:10:06 +00:00
}
/// Configuration for Object Storage
2022-03-28 04:27:07 +00:00
#[derive(Clone, Debug, Parser, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct ObjectStorage {
2022-09-24 19:18:49 +00:00
/// The base endpoint for the object storage
///
/// Examples:
/// - `http://localhost:9000`
/// - `https://s3.dualstack.eu-west-1.amazonaws.com`
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
2022-09-24 19:18:49 +00:00
endpoint: Url,
/// Determines whether to use path style or virtualhost style for accessing objects
///
/// When this is true, objects will be fetched from {endpoint}/{bucket_name}/{object}
/// When false, objects will be fetched from {bucket_name}.{endpoint}/{object}
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
2022-09-24 19:18:49 +00:00
use_path_style: bool,
2022-03-28 00:10:06 +00:00
/// The bucket in which to store media
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
#[serde(skip_serializing_if = "Option::is_none")]
2022-03-28 04:27:07 +00:00
bucket_name: Option<String>,
2022-03-28 00:10:06 +00:00
/// The region the bucket is located in
2022-09-24 19:18:49 +00:00
///
/// For minio deployments, this can just be 'minio'
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
#[serde(skip_serializing_if = "Option::is_none")]
2022-09-24 19:18:49 +00:00
region: Option<String>,
2022-03-28 00:10:06 +00:00
/// The Access Key for the user accessing the bucket
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
#[serde(skip_serializing_if = "Option::is_none")]
2022-03-28 04:27:07 +00:00
access_key: Option<String>,
2022-03-28 00:10:06 +00:00
/// The secret key for the user accessing the bucket
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
#[serde(skip_serializing_if = "Option::is_none")]
2022-03-28 04:27:07 +00:00
secret_key: Option<String>,
2022-03-28 00:10:06 +00:00
/// The session token for accessing the bucket
2022-09-28 23:23:41 +00:00
#[arg(long)]
#[serde(skip_serializing_if = "Option::is_none")]
2022-03-28 04:27:07 +00:00
session_token: Option<String>,
/// How long signatures for object storage requests are valid (in seconds)
///
/// This defaults to 15 seconds
#[arg(long)]
#[serde(skip_serializing_if = "Option::is_none")]
signature_duration: Option<u64>,
/// How long a client can wait on an object storage request before giving up (in seconds)
///
/// This defaults to 30 seconds
#[arg(long)]
#[serde(skip_serializing_if = "Option::is_none")]
client_timeout: Option<u64>,
2022-03-28 00:10:06 +00:00
}
/// Configuration for the sled-backed data repository
2022-03-28 04:27:07 +00:00
#[derive(Debug, Parser, serde::Serialize)]
#[serde(rename_all = "snake_case")]
struct Sled {
2022-03-28 00:10:06 +00:00
/// The path to store the sled database
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
path: Option<PathBuf>,
2022-03-28 00:10:06 +00:00
/// The cache capacity, in bytes, allowed to sled for in-memory operations
2022-09-28 23:23:41 +00:00
#[arg(short, long)]
2022-03-28 04:27:07 +00:00
#[serde(skip_serializing_if = "Option::is_none")]
cache_capacity: Option<u64>,
2023-07-09 00:56:26 +00:00
#[arg(short, long)]
#[serde(skip_serializing_if = "Option::is_none")]
export_path: Option<PathBuf>,
2022-03-28 00:10:06 +00:00
}