diff --git a/.drone.yml b/.drone.yml index 0c8a9221..ce576278 100644 --- a/.drone.yml +++ b/.drone.yml @@ -14,7 +14,7 @@ steps: - name: build image: nixpkgs/nix:nixos-22.05 commands: - - nix-build --no-build-output --attr clippy.amd64 --argstr git_version $DRONE_COMMIT + - nix-build --no-build-output --attr clippy.amd64 --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT} - name: unit + func tests image: nixpkgs/nix:nixos-22.05 @@ -34,7 +34,7 @@ steps: - name: integration tests image: nixpkgs/nix:nixos-22.05 commands: - - nix-build --no-build-output --attr clippy.amd64 --argstr git_version $DRONE_COMMIT + - nix-build --no-build-output --attr clippy.amd64 --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT} - nix-shell --attr integration --run ./script/test-smoke.sh || (cat /tmp/garage.log; false) trigger: @@ -57,7 +57,7 @@ steps: - name: build image: nixpkgs/nix:nixos-22.05 commands: - - nix-build --no-build-output --attr pkgs.amd64.release --argstr git_version $DRONE_COMMIT + - nix-build --no-build-output --attr pkgs.amd64.release --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT} - nix-shell --attr rust --run "./script/not-dynamic.sh result/bin/garage" - name: integration @@ -72,6 +72,7 @@ steps: from_secret: garagehq_aws_access_key_id AWS_SECRET_ACCESS_KEY: from_secret: garagehq_aws_secret_access_key + TARGET: "x86_64-unknown-linux-musl" commands: - nix-shell --attr release --run "to_s3" @@ -107,7 +108,7 @@ steps: - name: build image: nixpkgs/nix:nixos-22.05 commands: - - nix-build --no-build-output --attr pkgs.i386.release --argstr git_version $DRONE_COMMIT + - nix-build --no-build-output --attr pkgs.i386.release --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT} - nix-shell --attr rust --run "./script/not-dynamic.sh result/bin/garage" - name: integration @@ -122,6 +123,7 @@ steps: from_secret: garagehq_aws_access_key_id AWS_SECRET_ACCESS_KEY: from_secret: garagehq_aws_secret_access_key + TARGET: "i686-unknown-linux-musl" commands: - nix-shell --attr release --run "to_s3" @@ -156,7 +158,7 @@ steps: - name: build image: nixpkgs/nix:nixos-22.05 commands: - - nix-build --no-build-output --attr pkgs.arm64.release --argstr git_version $DRONE_COMMIT + - nix-build --no-build-output --attr pkgs.arm64.release --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT} - nix-shell --attr rust --run "./script/not-dynamic.sh result/bin/garage" - name: push static binary @@ -166,6 +168,7 @@ steps: from_secret: garagehq_aws_access_key_id AWS_SECRET_ACCESS_KEY: from_secret: garagehq_aws_secret_access_key + TARGET: "aarch64-unknown-linux-musl" commands: - nix-shell --attr release --run "to_s3" @@ -200,7 +203,7 @@ steps: - name: build image: nixpkgs/nix:nixos-22.05 commands: - - nix-build --no-build-output --attr pkgs.arm.release --argstr git_version $DRONE_COMMIT + - nix-build --no-build-output --attr pkgs.arm.release --argstr git_version ${DRONE_TAG:-$DRONE_COMMIT} - nix-shell --attr rust --run "./script/not-dynamic.sh result/bin/garage" - name: push static binary @@ -210,6 +213,7 @@ steps: from_secret: garagehq_aws_access_key_id AWS_SECRET_ACCESS_KEY: from_secret: garagehq_aws_secret_access_key + TARGET: "armv6l-unknown-linux-musleabihf" commands: - nix-shell --attr release --run "to_s3" @@ -265,6 +269,6 @@ trigger: --- kind: signature -hmac: 8495114848396ebb492831fc9bd37b353e1a4add9d72c0a123d109490a5b0db0 +hmac: fa1f98f327abf88486c0c54984287285a4b951efa3776af9dd33b4d782b50815 ... diff --git a/Cargo.lock b/Cargo.lock index d54cabd0..153643ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1196,7 +1196,6 @@ dependencies = [ "futures-util", "garage_util 0.7.0", "gethostname", - "git-version", "hex", "hyper", "k8s-openapi", @@ -1298,6 +1297,7 @@ dependencies = [ "err-derive 0.3.1", "futures", "garage_db", + "git-version", "hex", "http", "hyper", diff --git a/Cargo.nix b/Cargo.nix index 144967ee..edbe1134 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -1659,7 +1659,6 @@ in ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_web" then "futures_util" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.21" { inherit profileName; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_web" then "garage_util" else null } = rustPackages."unknown".garage_util."0.7.0" { inherit profileName; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_web" then "gethostname" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".gethostname."0.2.3" { inherit profileName; }; - ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_web" then "git_version" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".git-version."0.3.5" { inherit profileName; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_web" then "hex" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_web" then "hyper" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".hyper."0.14.18" { inherit profileName; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_rpc" then "k8s_openapi" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".k8s-openapi."0.13.1" { inherit profileName; }; @@ -1772,6 +1771,7 @@ in ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_util" || rootFeatures' ? "garage_web" || rootFeatures' ? "k2v-client" then "err_derive" else null } = buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".err-derive."0.3.1" { profileName = "__noProfile"; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_util" || rootFeatures' ? "garage_web" || rootFeatures' ? "k2v-client" then "futures" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.21" { inherit profileName; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_util" || rootFeatures' ? "garage_web" || rootFeatures' ? "k2v-client" then "garage_db" else null } = rustPackages."unknown".garage_db."0.8.0" { inherit profileName; }; + ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_util" || rootFeatures' ? "garage_web" || rootFeatures' ? "k2v-client" then "git_version" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".git-version."0.3.5" { inherit profileName; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_util" || rootFeatures' ? "garage_web" || rootFeatures' ? "k2v-client" then "hex" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_util" || rootFeatures' ? "garage_web" || rootFeatures' ? "k2v-client" then "http" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".http."0.2.6" { inherit profileName; }; ${ if rootFeatures' ? "garage" || rootFeatures' ? "garage_api" || rootFeatures' ? "garage_block" || rootFeatures' ? "garage_model" || rootFeatures' ? "garage_rpc" || rootFeatures' ? "garage_table" || rootFeatures' ? "garage_util" || rootFeatures' ? "garage_web" || rootFeatures' ? "k2v-client" then "hyper" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".hyper."0.14.18" { inherit profileName; }; @@ -4602,7 +4602,7 @@ in ]; dependencies = { bitflags = rustPackages."registry+https://github.com/rust-lang/crates.io-index".bitflags."1.3.2" { inherit profileName; }; - ${ if hostPlatform.parsed.kernel.name == "android" || hostPlatform.parsed.kernel.name == "linux" then "libc" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".libc."0.2.121" { inherit profileName; }; + ${ if hostPlatform.parsed.kernel.name == "linux" || hostPlatform.parsed.kernel.name == "android" then "libc" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".libc."0.2.121" { inherit profileName; }; ${ if !(hostPlatform.parsed.kernel.name == "linux" || hostPlatform.parsed.kernel.name == "android") then "parking_lot" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".parking_lot."0.11.2" { inherit profileName; }; ${ if !(hostPlatform.parsed.kernel.name == "linux" || hostPlatform.parsed.kernel.name == "android") then "parking_lot_core" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".parking_lot_core."0.8.5" { inherit profileName; }; static_init_macro = buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".static_init_macro."1.0.2" { profileName = "__noProfile"; }; @@ -5622,11 +5622,11 @@ in [ "default" ] ]; dependencies = { - ${ if hostPlatform.config == "aarch64-pc-windows-msvc" || hostPlatform.config == "aarch64-uwp-windows-msvc" then "windows_aarch64_msvc" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".windows_aarch64_msvc."0.32.0" { inherit profileName; }; + ${ if hostPlatform.config == "aarch64-uwp-windows-msvc" || hostPlatform.config == "aarch64-pc-windows-msvc" then "windows_aarch64_msvc" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".windows_aarch64_msvc."0.32.0" { inherit profileName; }; ${ if hostPlatform.config == "i686-uwp-windows-gnu" || hostPlatform.config == "i686-pc-windows-gnu" then "windows_i686_gnu" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".windows_i686_gnu."0.32.0" { inherit profileName; }; - ${ if hostPlatform.config == "i686-uwp-windows-msvc" || hostPlatform.config == "i686-pc-windows-msvc" then "windows_i686_msvc" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".windows_i686_msvc."0.32.0" { inherit profileName; }; + ${ if hostPlatform.config == "i686-pc-windows-msvc" || hostPlatform.config == "i686-uwp-windows-msvc" then "windows_i686_msvc" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".windows_i686_msvc."0.32.0" { inherit profileName; }; ${ if hostPlatform.config == "x86_64-pc-windows-gnu" || hostPlatform.config == "x86_64-uwp-windows-gnu" then "windows_x86_64_gnu" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".windows_x86_64_gnu."0.32.0" { inherit profileName; }; - ${ if hostPlatform.config == "x86_64-uwp-windows-msvc" || hostPlatform.config == "x86_64-pc-windows-msvc" then "windows_x86_64_msvc" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".windows_x86_64_msvc."0.32.0" { inherit profileName; }; + ${ if hostPlatform.config == "x86_64-pc-windows-msvc" || hostPlatform.config == "x86_64-uwp-windows-msvc" then "windows_x86_64_msvc" else null } = rustPackages."registry+https://github.com/rust-lang/crates.io-index".windows_x86_64_msvc."0.32.0" { inherit profileName; }; }; }); diff --git a/default.nix b/default.nix index 4d7558c5..7e44096c 100644 --- a/default.nix +++ b/default.nix @@ -9,8 +9,8 @@ let pkgs = import pkgsSrc { }; compile = import ./nix/compile.nix; build_debug_and_release = (target: { - debug = (compile { inherit target; release = false; }).workspace.garage { compileMode = "build"; }; - release = (compile { inherit target; release = true; }).workspace.garage { compileMode = "build"; }; + debug = (compile { inherit target git_version; release = false; }).workspace.garage { compileMode = "build"; }; + release = (compile { inherit target git_version; release = true; }).workspace.garage { compileMode = "build"; }; }); test = (rustPkgs: pkgs.symlinkJoin { name ="garage-tests"; @@ -25,9 +25,9 @@ in { arm = build_debug_and_release "armv6l-unknown-linux-musleabihf"; }; test = { - amd64 = test (compile { target = "x86_64-unknown-linux-musl"; }); + amd64 = test (compile { inherit git_version; target = "x86_64-unknown-linux-musl"; }); }; clippy = { - amd64 = (compile { compiler = "clippy"; }).workspace.garage { compileMode = "build"; } ; + amd64 = (compile { inherit git_version; compiler = "clippy"; }).workspace.garage { compileMode = "build"; } ; }; } diff --git a/doc/book/cookbook/reverse-proxy.md b/doc/book/cookbook/reverse-proxy.md index 27add5bf..fb918778 100644 --- a/doc/book/cookbook/reverse-proxy.md +++ b/doc/book/cookbook/reverse-proxy.md @@ -280,3 +280,25 @@ Traefik's caching middleware is only available on [entreprise version](https://d [http.middlewares] [http.middlewares.gzip_compress.compress] ``` + +## Caddy + +Your Caddy configuration can be as simple as: + +```caddy +s3.garage.tld, *.s3.garage.tld { + reverse_proxy localhost:3900 192.168.1.2:3900 example.tld:3900 +} + +*.web.garage.tld { + reverse_proxy localhost:3902 192.168.1.2:3900 example.tld:3900 +} + +admin.garage.tld { + reverse_proxy localhost:3903 +} +``` + +But at the same time, the `reverse_proxy` is very flexible. +For a production deployment, you should [read its documentation](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy) as it supports features like DNS discovery of upstreams, load balancing with checks, streaming parameters, etc. + diff --git a/nix/compile.nix b/nix/compile.nix index 49f7c1d6..7986fb0d 100644 --- a/nix/compile.nix +++ b/nix/compile.nix @@ -129,16 +129,7 @@ let (pkgs.rustBuilder.rustLib.makeOverride { name = "garage_rpc"; - overrideAttrs = drv: - (if git_version != null then { - /* [3] */ preConfigure = '' - ${drv.preConfigure or ""} - export GIT_VERSION="${git_version}" - ''; - } else {}) - // { - /* [1] */ setBuildEnv = (buildEnv drv); - }; + overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); }; overrideArgs = old: { /* [4] */ features = if release then [ "kubernetes-discovery" ] else []; }; @@ -151,7 +142,15 @@ let (pkgs.rustBuilder.rustLib.makeOverride { name = "garage_util"; - overrideAttrs = drv: { /* [1] */ setBuildEnv = (buildEnv drv); }; + overrideAttrs = drv: + (if git_version != null then { + /* [3] */ preConfigure = '' + ${drv.preConfigure or ""} + export GIT_VERSION="${git_version}" + ''; + } else {}) + // + { /* [1] */ setBuildEnv = (buildEnv drv); }; }) (pkgs.rustBuilder.rustLib.makeOverride { diff --git a/src/garage/cli/structs.rs b/src/garage/cli/structs.rs index bc44b5ef..9274f80f 100644 --- a/src/garage/cli/structs.rs +++ b/src/garage/cli/structs.rs @@ -1,64 +1,65 @@ use serde::{Deserialize, Serialize}; +use garage_util::version; use structopt::StructOpt; #[derive(StructOpt, Debug)] pub enum Command { /// Run Garage server - #[structopt(name = "server")] + #[structopt(name = "server", version = version::garage())] Server, /// Get network status - #[structopt(name = "status")] + #[structopt(name = "status", version = version::garage())] Status, /// Operations on individual Garage nodes - #[structopt(name = "node")] + #[structopt(name = "node", version = version::garage())] Node(NodeOperation), /// Operations on the assignation of node roles in the cluster layout - #[structopt(name = "layout")] + #[structopt(name = "layout", version = version::garage())] Layout(LayoutOperation), /// Operations on buckets - #[structopt(name = "bucket")] + #[structopt(name = "bucket", version = version::garage())] Bucket(BucketOperation), /// Operations on S3 access keys - #[structopt(name = "key")] + #[structopt(name = "key", version = version::garage())] Key(KeyOperation), /// Run migrations from previous Garage version /// (DO NOT USE WITHOUT READING FULL DOCUMENTATION) - #[structopt(name = "migrate")] + #[structopt(name = "migrate", version = version::garage())] Migrate(MigrateOpt), /// Start repair of node data on remote node - #[structopt(name = "repair")] + #[structopt(name = "repair", version = version::garage())] Repair(RepairOpt), /// Offline reparation of node data (these repairs must be run offline /// directly on the server node) - #[structopt(name = "offline-repair")] + #[structopt(name = "offline-repair", version = version::garage())] OfflineRepair(OfflineRepairOpt), /// Gather node statistics - #[structopt(name = "stats")] + #[structopt(name = "stats", version = version::garage())] Stats(StatsOpt), /// Manage background workers - #[structopt(name = "worker")] + #[structopt(name = "worker", version = version::garage())] Worker(WorkerOpt), } #[derive(StructOpt, Debug)] pub enum NodeOperation { /// Print identifier (public key) of this Garage node - #[structopt(name = "id")] + #[structopt(name = "id", version = version::garage())] NodeId(NodeIdOpt), /// Connect to Garage node that is currently isolated from the system - #[structopt(name = "connect")] + #[structopt(name = "connect", version = version::garage())] Connect(ConnectNodeOpt), } @@ -79,23 +80,23 @@ pub struct ConnectNodeOpt { #[derive(StructOpt, Debug)] pub enum LayoutOperation { /// Assign role to Garage node - #[structopt(name = "assign")] + #[structopt(name = "assign", version = version::garage())] Assign(AssignRoleOpt), /// Remove role from Garage cluster node - #[structopt(name = "remove")] + #[structopt(name = "remove", version = version::garage())] Remove(RemoveRoleOpt), /// Show roles currently assigned to nodes and changes staged for commit - #[structopt(name = "show")] + #[structopt(name = "show", version = version::garage())] Show, /// Apply staged changes to cluster layout - #[structopt(name = "apply")] + #[structopt(name = "apply", version = version::garage())] Apply(ApplyLayoutOpt), /// Revert staged changes to cluster layout - #[structopt(name = "revert")] + #[structopt(name = "revert", version = version::garage())] Revert(RevertLayoutOpt), } @@ -150,43 +151,43 @@ pub struct RevertLayoutOpt { #[derive(Serialize, Deserialize, StructOpt, Debug)] pub enum BucketOperation { /// List buckets - #[structopt(name = "list")] + #[structopt(name = "list", version = version::garage())] List, /// Get bucket info - #[structopt(name = "info")] + #[structopt(name = "info", version = version::garage())] Info(BucketOpt), /// Create bucket - #[structopt(name = "create")] + #[structopt(name = "create", version = version::garage())] Create(BucketOpt), /// Delete bucket - #[structopt(name = "delete")] + #[structopt(name = "delete", version = version::garage())] Delete(DeleteBucketOpt), /// Alias bucket under new name - #[structopt(name = "alias")] + #[structopt(name = "alias", version = version::garage())] Alias(AliasBucketOpt), /// Remove bucket alias - #[structopt(name = "unalias")] + #[structopt(name = "unalias", version = version::garage())] Unalias(UnaliasBucketOpt), /// Allow key to read or write to bucket - #[structopt(name = "allow")] + #[structopt(name = "allow", version = version::garage())] Allow(PermBucketOpt), /// Deny key from reading or writing to bucket - #[structopt(name = "deny")] + #[structopt(name = "deny", version = version::garage())] Deny(PermBucketOpt), /// Expose as website or not - #[structopt(name = "website")] + #[structopt(name = "website", version = version::garage())] Website(WebsiteOpt), /// Set the quotas for this bucket - #[structopt(name = "set-quotas")] + #[structopt(name = "set-quotas", version = version::garage())] SetQuotas(SetQuotasOpt), } @@ -292,35 +293,35 @@ pub struct SetQuotasOpt { #[derive(Serialize, Deserialize, StructOpt, Debug)] pub enum KeyOperation { /// List keys - #[structopt(name = "list")] + #[structopt(name = "list", version = version::garage())] List, /// Get key info - #[structopt(name = "info")] + #[structopt(name = "info", version = version::garage())] Info(KeyOpt), /// Create new key - #[structopt(name = "new")] + #[structopt(name = "new", version = version::garage())] New(KeyNewOpt), /// Rename key - #[structopt(name = "rename")] + #[structopt(name = "rename", version = version::garage())] Rename(KeyRenameOpt), /// Delete key - #[structopt(name = "delete")] + #[structopt(name = "delete", version = version::garage())] Delete(KeyDeleteOpt), /// Set permission flags for key - #[structopt(name = "allow")] + #[structopt(name = "allow", version = version::garage())] Allow(KeyPermOpt), /// Unset permission flags for key - #[structopt(name = "deny")] + #[structopt(name = "deny", version = version::garage())] Deny(KeyPermOpt), /// Import key - #[structopt(name = "import")] + #[structopt(name = "import", version = version::garage())] Import(KeyImportOpt), } @@ -392,7 +393,7 @@ pub struct MigrateOpt { #[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)] pub enum MigrateWhat { /// Migrate buckets and permissions from v0.5.0 - #[structopt(name = "buckets050")] + #[structopt(name = "buckets050", version = version::garage())] Buckets050, } @@ -413,19 +414,19 @@ pub struct RepairOpt { #[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)] pub enum RepairWhat { /// Only do a full sync of metadata tables - #[structopt(name = "tables")] + #[structopt(name = "tables", version = version::garage())] Tables, /// Only repair (resync/rebalance) the set of stored blocks - #[structopt(name = "blocks")] + #[structopt(name = "blocks", version = version::garage())] Blocks, /// Only redo the propagation of object deletions to the version table (slow) - #[structopt(name = "versions")] + #[structopt(name = "versions", version = version::garage())] Versions, /// Only redo the propagation of version deletions to the block ref table (extremely slow) - #[structopt(name = "block_refs")] + #[structopt(name = "block_refs", version = version::garage())] BlockRefs, /// Verify integrity of all blocks on disc (extremely slow, i/o intensive) - #[structopt(name = "scrub")] + #[structopt(name = "scrub", version = version::garage())] Scrub { #[structopt(subcommand)] cmd: ScrubCmd, @@ -435,19 +436,19 @@ pub enum RepairWhat { #[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)] pub enum ScrubCmd { /// Start scrub - #[structopt(name = "start")] + #[structopt(name = "start", version = version::garage())] Start, /// Pause scrub (it will resume automatically after 24 hours) - #[structopt(name = "pause")] + #[structopt(name = "pause", version = version::garage())] Pause, /// Resume paused scrub - #[structopt(name = "resume")] + #[structopt(name = "resume", version = version::garage())] Resume, /// Cancel scrub in progress - #[structopt(name = "cancel")] + #[structopt(name = "cancel", version = version::garage())] Cancel, /// Set tranquility level for in-progress and future scrubs - #[structopt(name = "set-tranquility")] + #[structopt(name = "set-tranquility", version = version::garage())] SetTranquility { #[structopt()] tranquility: u32, @@ -468,10 +469,10 @@ pub struct OfflineRepairOpt { pub enum OfflineRepairWhat { /// Repair K2V item counters #[cfg(feature = "k2v")] - #[structopt(name = "k2v_item_counters")] + #[structopt(name = "k2v_item_counters", version = version::garage())] K2VItemCounters, /// Repair object counters - #[structopt(name = "object_counters")] + #[structopt(name = "object_counters", version = version::garage())] ObjectCounters, } @@ -495,7 +496,7 @@ pub struct WorkerOpt { #[derive(Serialize, Deserialize, StructOpt, Debug, Eq, PartialEq, Clone)] pub enum WorkerCmd { /// List all workers on Garage node - #[structopt(name = "list")] + #[structopt(name = "list", version = version::garage())] List { #[structopt(flatten)] opt: WorkerListOpt, diff --git a/src/garage/main.rs b/src/garage/main.rs index 3fa5c3c0..89888884 100644 --- a/src/garage/main.rs +++ b/src/garage/main.rs @@ -22,6 +22,7 @@ use garage_util::error::*; use garage_rpc::system::*; use garage_rpc::*; +use garage_util::version; use garage_model::helper::error::Error as HelperError; @@ -29,7 +30,7 @@ use admin::*; use cli::*; #[derive(StructOpt, Debug)] -#[structopt(name = "garage")] +#[structopt(name = "garage", version = version::garage(), about = "S3-compatible object store for self-hosted geo-distributed deployments")] struct Opt { /// Host to connect to for admin operations, in the format: /// @: diff --git a/src/rpc/Cargo.toml b/src/rpc/Cargo.toml index 73328993..80a1975c 100644 --- a/src/rpc/Cargo.toml +++ b/src/rpc/Cargo.toml @@ -19,7 +19,6 @@ garage_util = { version = "0.7.0", path = "../util" } arc-swap = "1.0" bytes = "1.0" gethostname = "0.2" -git-version = "0.3.4" hex = "0.4" tracing = "0.1.30" rand = "0.8" diff --git a/src/rpc/system.rs b/src/rpc/system.rs index f9f2970b..fbfbbf56 100644 --- a/src/rpc/system.rs +++ b/src/rpc/system.rs @@ -27,6 +27,7 @@ use garage_util::data::*; use garage_util::error::*; use garage_util::persister::Persister; use garage_util::time::*; +use garage_util::version; use crate::consul::*; #[cfg(feature = "kubernetes-discovery")] @@ -320,11 +321,7 @@ impl System { // also available through RPC) ---- pub fn garage_version(&self) -> &'static str { - option_env!("GIT_VERSION").unwrap_or(git_version::git_version!( - prefix = "git:", - cargo_prefix = "cargo:", - fallback = "unknown" - )) + version::garage() } pub fn get_known_nodes(&self) -> Vec { diff --git a/src/util/Cargo.toml b/src/util/Cargo.toml index 7d79f21a..9f7f8a4e 100644 --- a/src/util/Cargo.toml +++ b/src/util/Cargo.toml @@ -26,6 +26,7 @@ hex = "0.4" tracing = "0.1.30" rand = "0.8" sha2 = "0.10" +git-version = "0.3.4" chrono = "0.4" rmp-serde = "0.15" @@ -45,5 +46,6 @@ hyper = "0.14" opentelemetry = { version = "0.17", features = [ "rt-tokio", "metrics", "trace" ] } + [features] k2v = [] diff --git a/src/util/lib.rs b/src/util/lib.rs index 7152f92a..264cc192 100644 --- a/src/util/lib.rs +++ b/src/util/lib.rs @@ -15,3 +15,4 @@ pub mod persister; pub mod time; pub mod token_bucket; pub mod tranquilizer; +pub mod version; diff --git a/src/util/version.rs b/src/util/version.rs new file mode 100644 index 00000000..8882d035 --- /dev/null +++ b/src/util/version.rs @@ -0,0 +1,7 @@ +pub fn garage() -> &'static str { + option_env!("GIT_VERSION").unwrap_or(git_version::git_version!( + prefix = "git:", + cargo_prefix = "cargo:", + fallback = "unknown" + )) +}