2021-10-19 14:16:10 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use structopt::StructOpt;
|
|
|
|
|
2022-09-07 16:36:46 +00:00
|
|
|
use garage_util::version::garage_version;
|
2022-09-07 09:59:56 +00:00
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
#[derive(StructOpt, Debug)]
|
|
|
|
pub enum Command {
|
|
|
|
/// Run Garage server
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "server", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Server,
|
|
|
|
|
|
|
|
/// Get network status
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "status", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Status,
|
|
|
|
|
2021-11-09 11:24:04 +00:00
|
|
|
/// Operations on individual Garage nodes
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "node", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Node(NodeOperation),
|
|
|
|
|
2021-11-09 11:24:04 +00:00
|
|
|
/// Operations on the assignation of node roles in the cluster layout
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "layout", version = garage_version())]
|
2021-11-09 11:24:04 +00:00
|
|
|
Layout(LayoutOperation),
|
|
|
|
|
|
|
|
/// Operations on buckets
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "bucket", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Bucket(BucketOperation),
|
|
|
|
|
2021-11-09 11:24:04 +00:00
|
|
|
/// Operations on S3 access keys
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "key", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Key(KeyOperation),
|
|
|
|
|
2021-12-16 12:17:09 +00:00
|
|
|
/// Run migrations from previous Garage version
|
|
|
|
/// (DO NOT USE WITHOUT READING FULL DOCUMENTATION)
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "migrate", version = garage_version())]
|
2021-12-16 12:17:09 +00:00
|
|
|
Migrate(MigrateOpt),
|
|
|
|
|
2022-06-15 18:20:28 +00:00
|
|
|
/// Start repair of node data on remote node
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "repair", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Repair(RepairOpt),
|
|
|
|
|
2022-06-15 18:20:28 +00:00
|
|
|
/// Offline reparation of node data (these repairs must be run offline
|
|
|
|
/// directly on the server node)
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "offline-repair", version = garage_version())]
|
2022-06-15 18:20:28 +00:00
|
|
|
OfflineRepair(OfflineRepairOpt),
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
/// Gather node statistics
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "stats", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Stats(StatsOpt),
|
2022-07-08 11:30:26 +00:00
|
|
|
|
|
|
|
/// Manage background workers
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "worker", version = garage_version())]
|
2022-12-13 13:23:45 +00:00
|
|
|
Worker(WorkerOperation),
|
|
|
|
|
|
|
|
/// Low-level debug operations on data blocks
|
|
|
|
#[structopt(name = "block", version = garage_version())]
|
|
|
|
Block(BlockOperation),
|
2021-10-19 14:16:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(StructOpt, Debug)]
|
|
|
|
pub enum NodeOperation {
|
2021-11-09 11:24:04 +00:00
|
|
|
/// Print identifier (public key) of this Garage node
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "id", version = garage_version())]
|
2021-11-09 11:24:04 +00:00
|
|
|
NodeId(NodeIdOpt),
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
/// Connect to Garage node that is currently isolated from the system
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "connect", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Connect(ConnectNodeOpt),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(StructOpt, Debug)]
|
|
|
|
pub struct NodeIdOpt {
|
|
|
|
/// Do not print usage instructions to stderr
|
|
|
|
#[structopt(short = "q", long = "quiet")]
|
|
|
|
pub(crate) quiet: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(StructOpt, Debug)]
|
|
|
|
pub struct ConnectNodeOpt {
|
|
|
|
/// Node public key and address, in the format:
|
|
|
|
/// `<public key hexadecimal>@<ip or hostname>:<port>`
|
|
|
|
pub(crate) node: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(StructOpt, Debug)]
|
2021-11-09 11:24:04 +00:00
|
|
|
pub enum LayoutOperation {
|
|
|
|
/// Assign role to Garage node
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "assign", version = garage_version())]
|
2021-11-09 11:24:04 +00:00
|
|
|
Assign(AssignRoleOpt),
|
|
|
|
|
|
|
|
/// Remove role from Garage cluster node
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "remove", version = garage_version())]
|
2021-11-09 11:24:04 +00:00
|
|
|
Remove(RemoveRoleOpt),
|
|
|
|
|
|
|
|
/// Show roles currently assigned to nodes and changes staged for commit
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "show", version = garage_version())]
|
2021-11-09 11:24:04 +00:00
|
|
|
Show,
|
|
|
|
|
|
|
|
/// Apply staged changes to cluster layout
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "apply", version = garage_version())]
|
2021-11-09 11:24:04 +00:00
|
|
|
Apply(ApplyLayoutOpt),
|
|
|
|
|
|
|
|
/// Revert staged changes to cluster layout
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "revert", version = garage_version())]
|
2021-11-09 11:24:04 +00:00
|
|
|
Revert(RevertLayoutOpt),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(StructOpt, Debug)]
|
|
|
|
pub struct AssignRoleOpt {
|
2022-03-16 13:43:04 +00:00
|
|
|
/// Node(s) to which to assign role (prefix of hexadecimal node id)
|
|
|
|
#[structopt(required = true)]
|
|
|
|
pub(crate) node_ids: Vec<String>,
|
2021-10-19 14:16:10 +00:00
|
|
|
|
|
|
|
/// Location (zone or datacenter) of the node
|
|
|
|
#[structopt(short = "z", long = "zone")]
|
|
|
|
pub(crate) zone: Option<String>,
|
|
|
|
|
|
|
|
/// Capacity (in relative terms, use 1 to represent your smallest server)
|
|
|
|
#[structopt(short = "c", long = "capacity")]
|
|
|
|
pub(crate) capacity: Option<u32>,
|
|
|
|
|
|
|
|
/// Gateway-only node
|
|
|
|
#[structopt(short = "g", long = "gateway")]
|
|
|
|
pub(crate) gateway: bool,
|
|
|
|
|
2021-11-09 11:24:04 +00:00
|
|
|
/// Optional tags to add to node
|
2021-10-19 14:16:10 +00:00
|
|
|
#[structopt(short = "t", long = "tag")]
|
2021-11-09 11:24:04 +00:00
|
|
|
pub(crate) tags: Vec<String>,
|
2021-10-19 14:16:10 +00:00
|
|
|
|
|
|
|
/// Replaced node(s): list of node IDs that will be removed from the current cluster
|
|
|
|
#[structopt(long = "replace")]
|
|
|
|
pub(crate) replace: Vec<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(StructOpt, Debug)]
|
2021-11-09 11:24:04 +00:00
|
|
|
pub struct RemoveRoleOpt {
|
|
|
|
/// Node whose role to remove (prefix of hexadecimal node id)
|
2021-10-19 14:16:10 +00:00
|
|
|
pub(crate) node_id: String,
|
2021-11-09 11:24:04 +00:00
|
|
|
}
|
2021-10-19 14:16:10 +00:00
|
|
|
|
2021-11-09 11:24:04 +00:00
|
|
|
#[derive(StructOpt, Debug)]
|
|
|
|
pub struct ApplyLayoutOpt {
|
|
|
|
/// Version number of new configuration: this command will fail if
|
|
|
|
/// it is not exactly 1 + the previous configuration's version
|
|
|
|
#[structopt(long = "version")]
|
|
|
|
pub(crate) version: Option<u64>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(StructOpt, Debug)]
|
|
|
|
pub struct RevertLayoutOpt {
|
|
|
|
/// Version number of old configuration to which to revert
|
|
|
|
#[structopt(long = "version")]
|
|
|
|
pub(crate) version: Option<u64>,
|
2021-10-19 14:16:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub enum BucketOperation {
|
|
|
|
/// List buckets
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "list", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
List,
|
|
|
|
|
|
|
|
/// Get bucket info
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "info", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Info(BucketOpt),
|
|
|
|
|
|
|
|
/// Create bucket
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "create", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Create(BucketOpt),
|
|
|
|
|
|
|
|
/// Delete bucket
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "delete", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Delete(DeleteBucketOpt),
|
|
|
|
|
2021-12-15 17:36:15 +00:00
|
|
|
/// Alias bucket under new name
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "alias", version = garage_version())]
|
2021-12-15 17:36:15 +00:00
|
|
|
Alias(AliasBucketOpt),
|
|
|
|
|
|
|
|
/// Remove bucket alias
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "unalias", version = garage_version())]
|
2021-12-15 17:36:15 +00:00
|
|
|
Unalias(UnaliasBucketOpt),
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
/// Allow key to read or write to bucket
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "allow", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Allow(PermBucketOpt),
|
|
|
|
|
|
|
|
/// Deny key from reading or writing to bucket
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "deny", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Deny(PermBucketOpt),
|
|
|
|
|
|
|
|
/// Expose as website or not
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "website", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Website(WebsiteOpt),
|
2022-06-15 18:20:28 +00:00
|
|
|
|
|
|
|
/// Set the quotas for this bucket
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "set-quotas", version = garage_version())]
|
2022-06-15 18:20:28 +00:00
|
|
|
SetQuotas(SetQuotasOpt),
|
2022-11-04 10:55:59 +00:00
|
|
|
|
|
|
|
/// Clean up (abort) old incomplete multipart uploads
|
|
|
|
#[structopt(name = "cleanup-incomplete-uploads", version = garage_version())]
|
|
|
|
CleanupIncompleteUploads(CleanupIncompleteUploadsOpt),
|
2021-10-19 14:16:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct WebsiteOpt {
|
|
|
|
/// Create
|
|
|
|
#[structopt(long = "allow")]
|
|
|
|
pub allow: bool,
|
|
|
|
|
|
|
|
/// Delete
|
|
|
|
#[structopt(long = "deny")]
|
|
|
|
pub deny: bool,
|
|
|
|
|
|
|
|
/// Bucket name
|
|
|
|
pub bucket: String,
|
2022-01-06 11:58:21 +00:00
|
|
|
|
|
|
|
/// Index document: the suffix appended to request paths ending by /
|
|
|
|
#[structopt(short = "i", long = "index-document", default_value = "index.html")]
|
|
|
|
pub index_document: String,
|
|
|
|
|
|
|
|
/// Error document: the optionnal document returned when an error occurs
|
|
|
|
#[structopt(short = "e", long = "error-document")]
|
|
|
|
pub error_document: Option<String>,
|
2021-10-19 14:16:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct BucketOpt {
|
|
|
|
/// Bucket name
|
|
|
|
pub name: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct DeleteBucketOpt {
|
|
|
|
/// Bucket name
|
|
|
|
pub name: String,
|
|
|
|
|
|
|
|
/// If this flag is not given, the bucket won't be deleted
|
|
|
|
#[structopt(long = "yes")]
|
|
|
|
pub yes: bool,
|
|
|
|
}
|
|
|
|
|
2021-12-15 17:36:15 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct AliasBucketOpt {
|
|
|
|
/// Existing bucket name (its alias in global namespace or its full hex uuid)
|
|
|
|
pub existing_bucket: String,
|
|
|
|
|
|
|
|
/// New bucket name
|
|
|
|
pub new_name: String,
|
|
|
|
|
|
|
|
/// Make this alias local to the specified access key
|
|
|
|
#[structopt(long = "local")]
|
|
|
|
pub local: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct UnaliasBucketOpt {
|
|
|
|
/// Bucket name
|
|
|
|
pub name: String,
|
|
|
|
|
|
|
|
/// Unalias in bucket namespace local to this access key
|
|
|
|
#[structopt(long = "local")]
|
|
|
|
pub local: Option<String>,
|
|
|
|
}
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct PermBucketOpt {
|
|
|
|
/// Access key name or ID
|
|
|
|
#[structopt(long = "key")]
|
|
|
|
pub key_pattern: String,
|
|
|
|
|
|
|
|
/// Allow/deny read operations
|
|
|
|
#[structopt(long = "read")]
|
|
|
|
pub read: bool,
|
|
|
|
|
|
|
|
/// Allow/deny write operations
|
|
|
|
#[structopt(long = "write")]
|
|
|
|
pub write: bool,
|
|
|
|
|
2021-12-16 10:47:58 +00:00
|
|
|
/// Allow/deny administrative operations operations
|
|
|
|
/// (such as deleting bucket or changing bucket website configuration)
|
|
|
|
#[structopt(long = "owner")]
|
|
|
|
pub owner: bool,
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
/// Bucket name
|
|
|
|
pub bucket: String,
|
|
|
|
}
|
|
|
|
|
2022-06-15 18:20:28 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct SetQuotasOpt {
|
|
|
|
/// Bucket name
|
|
|
|
pub bucket: String,
|
|
|
|
|
|
|
|
/// Set a maximum size for the bucket (specify a size e.g. in MiB or GiB,
|
|
|
|
/// or `none` for no size restriction)
|
|
|
|
#[structopt(long = "max-size")]
|
|
|
|
pub max_size: Option<String>,
|
|
|
|
|
|
|
|
/// Set a maximum number of objects for the bucket (or `none` for no restriction)
|
|
|
|
#[structopt(long = "max-objects")]
|
|
|
|
pub max_objects: Option<String>,
|
|
|
|
}
|
|
|
|
|
2022-11-04 10:55:59 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct CleanupIncompleteUploadsOpt {
|
|
|
|
/// Abort multipart uploads older than this value
|
|
|
|
#[structopt(long = "older-than", default_value = "1d")]
|
|
|
|
pub older_than: String,
|
|
|
|
|
|
|
|
/// Name of bucket(s) to clean up
|
|
|
|
#[structopt(required = true)]
|
|
|
|
pub buckets: Vec<String>,
|
|
|
|
}
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub enum KeyOperation {
|
|
|
|
/// List keys
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "list", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
List,
|
|
|
|
|
|
|
|
/// Get key info
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "info", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Info(KeyOpt),
|
|
|
|
|
|
|
|
/// Create new key
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "new", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
New(KeyNewOpt),
|
|
|
|
|
|
|
|
/// Rename key
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "rename", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Rename(KeyRenameOpt),
|
|
|
|
|
|
|
|
/// Delete key
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "delete", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Delete(KeyDeleteOpt),
|
|
|
|
|
2022-01-05 14:12:59 +00:00
|
|
|
/// Set permission flags for key
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "allow", version = garage_version())]
|
2022-01-05 14:12:59 +00:00
|
|
|
Allow(KeyPermOpt),
|
|
|
|
|
|
|
|
/// Unset permission flags for key
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "deny", version = garage_version())]
|
2022-01-05 14:12:59 +00:00
|
|
|
Deny(KeyPermOpt),
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
/// Import key
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "import", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Import(KeyImportOpt),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct KeyOpt {
|
|
|
|
/// ID or name of the key
|
|
|
|
pub key_pattern: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct KeyNewOpt {
|
|
|
|
/// Name of the key
|
|
|
|
#[structopt(long = "name", default_value = "Unnamed key")]
|
|
|
|
pub name: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct KeyRenameOpt {
|
|
|
|
/// ID or name of the key
|
|
|
|
pub key_pattern: String,
|
|
|
|
|
|
|
|
/// New name of the key
|
|
|
|
pub new_name: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct KeyDeleteOpt {
|
|
|
|
/// ID or name of the key
|
|
|
|
pub key_pattern: String,
|
|
|
|
|
|
|
|
/// Confirm deletion
|
|
|
|
#[structopt(long = "yes")]
|
|
|
|
pub yes: bool,
|
|
|
|
}
|
|
|
|
|
2022-01-05 14:12:59 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct KeyPermOpt {
|
|
|
|
/// ID or name of the key
|
|
|
|
pub key_pattern: String,
|
|
|
|
|
|
|
|
/// Flag that allows key to create buckets using S3's CreateBucket call
|
|
|
|
#[structopt(long = "create-bucket")]
|
|
|
|
pub create_bucket: bool,
|
|
|
|
}
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug)]
|
|
|
|
pub struct KeyImportOpt {
|
|
|
|
/// Access key ID
|
|
|
|
pub key_id: String,
|
|
|
|
|
|
|
|
/// Secret access key
|
|
|
|
pub secret_key: String,
|
|
|
|
|
|
|
|
/// Key name
|
|
|
|
#[structopt(short = "n", default_value = "Imported key")]
|
|
|
|
pub name: String,
|
|
|
|
}
|
|
|
|
|
2021-12-16 12:17:09 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Clone)]
|
|
|
|
pub struct MigrateOpt {
|
|
|
|
/// Confirm the launch of the migrate operation
|
|
|
|
#[structopt(long = "yes")]
|
|
|
|
pub yes: bool,
|
|
|
|
|
|
|
|
#[structopt(subcommand)]
|
|
|
|
pub what: MigrateWhat,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)]
|
|
|
|
pub enum MigrateWhat {
|
|
|
|
/// Migrate buckets and permissions from v0.5.0
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "buckets050", version = garage_version())]
|
2021-12-16 12:17:09 +00:00
|
|
|
Buckets050,
|
|
|
|
}
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Clone)]
|
|
|
|
pub struct RepairOpt {
|
|
|
|
/// Launch repair operation on all nodes
|
|
|
|
#[structopt(short = "a", long = "all-nodes")]
|
|
|
|
pub all_nodes: bool,
|
|
|
|
|
|
|
|
/// Confirm the launch of the repair operation
|
|
|
|
#[structopt(long = "yes")]
|
|
|
|
pub yes: bool,
|
|
|
|
|
|
|
|
#[structopt(subcommand)]
|
2021-10-27 08:36:04 +00:00
|
|
|
pub what: RepairWhat,
|
2021-10-19 14:16:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)]
|
|
|
|
pub enum RepairWhat {
|
|
|
|
/// Only do a full sync of metadata tables
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "tables", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Tables,
|
|
|
|
/// Only repair (resync/rebalance) the set of stored blocks
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "blocks", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Blocks,
|
|
|
|
/// Only redo the propagation of object deletions to the version table (slow)
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "versions", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
Versions,
|
|
|
|
/// Only redo the propagation of version deletions to the block ref table (extremely slow)
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "block_refs", version = garage_version())]
|
2021-10-19 14:16:10 +00:00
|
|
|
BlockRefs,
|
2021-06-23 23:34:28 +00:00
|
|
|
/// Verify integrity of all blocks on disc (extremely slow, i/o intensive)
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "scrub", version = garage_version())]
|
2021-10-27 08:36:04 +00:00
|
|
|
Scrub {
|
2022-07-08 11:30:26 +00:00
|
|
|
#[structopt(subcommand)]
|
|
|
|
cmd: ScrubCmd,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)]
|
|
|
|
pub enum ScrubCmd {
|
|
|
|
/// Start scrub
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "start", version = garage_version())]
|
2022-07-08 11:30:26 +00:00
|
|
|
Start,
|
|
|
|
/// Pause scrub (it will resume automatically after 24 hours)
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "pause", version = garage_version())]
|
2022-07-08 11:30:26 +00:00
|
|
|
Pause,
|
|
|
|
/// Resume paused scrub
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "resume", version = garage_version())]
|
2022-07-08 11:30:26 +00:00
|
|
|
Resume,
|
|
|
|
/// Cancel scrub in progress
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "cancel", version = garage_version())]
|
2022-07-08 11:30:26 +00:00
|
|
|
Cancel,
|
|
|
|
/// Set tranquility level for in-progress and future scrubs
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "set-tranquility", version = garage_version())]
|
2022-07-08 11:30:26 +00:00
|
|
|
SetTranquility {
|
|
|
|
#[structopt()]
|
2021-11-03 17:28:43 +00:00
|
|
|
tranquility: u32,
|
2021-06-23 23:34:28 +00:00
|
|
|
},
|
2021-10-19 14:16:10 +00:00
|
|
|
}
|
|
|
|
|
2022-06-15 18:20:28 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Clone)]
|
|
|
|
pub struct OfflineRepairOpt {
|
|
|
|
/// Confirm the launch of the repair operation
|
|
|
|
#[structopt(long = "yes")]
|
|
|
|
pub yes: bool,
|
|
|
|
|
|
|
|
#[structopt(subcommand)]
|
|
|
|
pub what: OfflineRepairWhat,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)]
|
|
|
|
pub enum OfflineRepairWhat {
|
|
|
|
/// Repair K2V item counters
|
|
|
|
#[cfg(feature = "k2v")]
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "k2v_item_counters", version = garage_version())]
|
2022-06-15 18:20:28 +00:00
|
|
|
K2VItemCounters,
|
|
|
|
/// Repair object counters
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "object_counters", version = garage_version())]
|
2022-06-15 18:20:28 +00:00
|
|
|
ObjectCounters,
|
|
|
|
}
|
|
|
|
|
2021-10-19 14:16:10 +00:00
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Clone)]
|
|
|
|
pub struct StatsOpt {
|
|
|
|
/// Gather statistics from all nodes
|
|
|
|
#[structopt(short = "a", long = "all-nodes")]
|
|
|
|
pub all_nodes: bool,
|
|
|
|
|
|
|
|
/// Gather detailed statistics (this can be long)
|
|
|
|
#[structopt(short = "d", long = "detailed")]
|
|
|
|
pub detailed: bool,
|
|
|
|
}
|
2022-07-08 11:30:26 +00:00
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)]
|
2022-12-13 13:23:45 +00:00
|
|
|
pub enum WorkerOperation {
|
2022-07-08 11:30:26 +00:00
|
|
|
/// List all workers on Garage node
|
2022-09-07 09:59:56 +00:00
|
|
|
#[structopt(name = "list", version = garage_version())]
|
2022-07-08 11:30:26 +00:00
|
|
|
List {
|
|
|
|
#[structopt(flatten)]
|
|
|
|
opt: WorkerListOpt,
|
|
|
|
},
|
2022-12-13 11:24:30 +00:00
|
|
|
/// Get detailed information about a worker
|
|
|
|
#[structopt(name = "info", version = garage_version())]
|
|
|
|
Info { tid: usize },
|
2022-09-02 13:34:21 +00:00
|
|
|
/// Set worker parameter
|
2022-09-07 16:16:01 +00:00
|
|
|
#[structopt(name = "set", version = garage_version())]
|
2022-09-02 13:34:21 +00:00
|
|
|
Set {
|
|
|
|
#[structopt(subcommand)]
|
|
|
|
opt: WorkerSetCmd,
|
|
|
|
},
|
2022-07-08 11:30:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone, Copy)]
|
|
|
|
pub struct WorkerListOpt {
|
|
|
|
/// Show only busy workers
|
|
|
|
#[structopt(short = "b", long = "busy")]
|
|
|
|
pub busy: bool,
|
|
|
|
/// Show only workers with errors
|
|
|
|
#[structopt(short = "e", long = "errors")]
|
|
|
|
pub errors: bool,
|
|
|
|
}
|
2022-09-02 13:34:21 +00:00
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)]
|
|
|
|
pub enum WorkerSetCmd {
|
|
|
|
/// Set tranquility of scrub operations
|
2022-09-07 16:16:01 +00:00
|
|
|
#[structopt(name = "scrub-tranquility", version = garage_version())]
|
2022-09-02 13:34:21 +00:00
|
|
|
ScrubTranquility { tranquility: u32 },
|
2022-09-02 15:18:13 +00:00
|
|
|
/// Set number of concurrent block resync workers
|
2022-12-13 10:44:11 +00:00
|
|
|
#[structopt(name = "resync-worker-count", version = garage_version())]
|
|
|
|
ResyncWorkerCount { worker_count: usize },
|
2022-09-02 15:18:13 +00:00
|
|
|
/// Set tranquility of block resync operations
|
2022-09-07 16:16:01 +00:00
|
|
|
#[structopt(name = "resync-tranquility", version = garage_version())]
|
2022-09-02 13:34:21 +00:00
|
|
|
ResyncTranquility { tranquility: u32 },
|
|
|
|
}
|
2022-12-13 13:23:45 +00:00
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)]
|
|
|
|
pub enum BlockOperation {
|
|
|
|
/// List all blocks that currently have a resync error
|
|
|
|
#[structopt(name = "list-errors", version = garage_version())]
|
|
|
|
ListErrors,
|
|
|
|
/// Get detailed information about a single block
|
|
|
|
#[structopt(name = "info", version = garage_version())]
|
|
|
|
Info {
|
|
|
|
/// Hash of the block for which to retrieve information
|
|
|
|
hash: String,
|
|
|
|
},
|
|
|
|
/// Retry now the resync of one or many blocks
|
|
|
|
#[structopt(name = "retry-now", version = garage_version())]
|
|
|
|
RetryNow {
|
|
|
|
/// Retry all blocks that have a resync error
|
|
|
|
#[structopt(long = "all")]
|
|
|
|
all: bool,
|
|
|
|
/// Hashes of the block to retry to resync now
|
|
|
|
blocks: Vec<String>,
|
|
|
|
},
|
|
|
|
/// Delete all objects referencing a missing block
|
|
|
|
#[structopt(name = "purge", version = garage_version())]
|
|
|
|
Purge {
|
|
|
|
/// Mandatory to confirm this operation
|
|
|
|
#[structopt(long = "yes")]
|
|
|
|
yes: bool,
|
|
|
|
/// Hashes of the block to purge
|
|
|
|
blocks: Vec<String>,
|
|
|
|
},
|
|
|
|
}
|