mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-08-16 16:58:19 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6a6f01ee09 |
Generated
+9
-10
@@ -1075,7 +1075,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garage"
|
name = "garage"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert-json-diff",
|
"assert-json-diff",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -1122,7 +1122,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garage_api"
|
name = "garage_api"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.21.0",
|
"base64 0.21.0",
|
||||||
@@ -1167,7 +1167,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garage_block"
|
name = "garage_block"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"async-compression",
|
"async-compression",
|
||||||
@@ -1192,7 +1192,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garage_db"
|
name = "garage_db"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 4.1.4",
|
"clap 4.1.4",
|
||||||
"err-derive",
|
"err-derive",
|
||||||
@@ -1207,7 +1207,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garage_model"
|
name = "garage_model"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -1234,7 +1234,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garage_rpc"
|
name = "garage_rpc"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -1265,7 +1265,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garage_table"
|
name = "garage_table"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -1287,7 +1287,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garage_util"
|
name = "garage_util"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -1309,7 +1309,6 @@ dependencies = [
|
|||||||
"opentelemetry",
|
"opentelemetry",
|
||||||
"rand",
|
"rand",
|
||||||
"rmp-serde",
|
"rmp-serde",
|
||||||
"rustc_version",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2 0.10.6",
|
"sha2 0.10.6",
|
||||||
@@ -1321,7 +1320,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "garage_web"
|
name = "garage_web"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"err-derive",
|
"err-derive",
|
||||||
"futures",
|
"futures",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ args@{
|
|||||||
ignoreLockHash,
|
ignoreLockHash,
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
nixifiedLockHash = "af19dd561f2ce73d1f609040c1ebdf74420974d96959016da98d44b0e347f013";
|
nixifiedLockHash = "12ff12e9210c87ac93e2f2bdb7007b6232e7efcfa302c272bf0caee6e78abd10";
|
||||||
workspaceSrc = if args.workspaceSrc == null then ./. else args.workspaceSrc;
|
workspaceSrc = if args.workspaceSrc == null then ./. else args.workspaceSrc;
|
||||||
currentLockHash = builtins.hashFile "sha256" (workspaceSrc + /Cargo.lock);
|
currentLockHash = builtins.hashFile "sha256" (workspaceSrc + /Cargo.lock);
|
||||||
lockHashIgnored = if ignoreLockHash
|
lockHashIgnored = if ignoreLockHash
|
||||||
@@ -56,15 +56,15 @@ in
|
|||||||
{
|
{
|
||||||
cargo2nixVersion = "0.11.0";
|
cargo2nixVersion = "0.11.0";
|
||||||
workspace = {
|
workspace = {
|
||||||
garage_db = rustPackages.unknown.garage_db."0.8.2";
|
garage_db = rustPackages.unknown.garage_db."0.8.1";
|
||||||
garage_util = rustPackages.unknown.garage_util."0.8.2";
|
garage_util = rustPackages.unknown.garage_util."0.8.1";
|
||||||
garage_rpc = rustPackages.unknown.garage_rpc."0.8.2";
|
garage_rpc = rustPackages.unknown.garage_rpc."0.8.1";
|
||||||
garage_table = rustPackages.unknown.garage_table."0.8.2";
|
garage_table = rustPackages.unknown.garage_table."0.8.1";
|
||||||
garage_block = rustPackages.unknown.garage_block."0.8.2";
|
garage_block = rustPackages.unknown.garage_block."0.8.1";
|
||||||
garage_model = rustPackages.unknown.garage_model."0.8.2";
|
garage_model = rustPackages.unknown.garage_model."0.8.1";
|
||||||
garage_api = rustPackages.unknown.garage_api."0.8.2";
|
garage_api = rustPackages.unknown.garage_api."0.8.1";
|
||||||
garage_web = rustPackages.unknown.garage_web."0.8.2";
|
garage_web = rustPackages.unknown.garage_web."0.8.1";
|
||||||
garage = rustPackages.unknown.garage."0.8.2";
|
garage = rustPackages.unknown.garage."0.8.1";
|
||||||
k2v-client = rustPackages.unknown.k2v-client."0.1.1";
|
k2v-client = rustPackages.unknown.k2v-client."0.1.1";
|
||||||
};
|
};
|
||||||
"registry+https://github.com/rust-lang/crates.io-index".addr2line."0.19.0" = overridableMkRustCrate (profileName: rec {
|
"registry+https://github.com/rust-lang/crates.io-index".addr2line."0.19.0" = overridableMkRustCrate (profileName: rec {
|
||||||
@@ -1531,9 +1531,9 @@ in
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
"unknown".garage."0.8.2" = overridableMkRustCrate (profileName: rec {
|
"unknown".garage."0.8.1" = overridableMkRustCrate (profileName: rec {
|
||||||
name = "garage";
|
name = "garage";
|
||||||
version = "0.8.2";
|
version = "0.8.1";
|
||||||
registry = "unknown";
|
registry = "unknown";
|
||||||
src = fetchCrateLocal (workspaceSrc + "/src/garage");
|
src = fetchCrateLocal (workspaceSrc + "/src/garage");
|
||||||
features = builtins.concatLists [
|
features = builtins.concatLists [
|
||||||
@@ -1559,14 +1559,14 @@ in
|
|||||||
bytesize = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".bytesize."1.1.0" { inherit profileName; }).out;
|
bytesize = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".bytesize."1.1.0" { inherit profileName; }).out;
|
||||||
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
||||||
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
||||||
garage_api = (rustPackages."unknown".garage_api."0.8.2" { inherit profileName; }).out;
|
garage_api = (rustPackages."unknown".garage_api."0.8.1" { inherit profileName; }).out;
|
||||||
garage_block = (rustPackages."unknown".garage_block."0.8.2" { inherit profileName; }).out;
|
garage_block = (rustPackages."unknown".garage_block."0.8.1" { inherit profileName; }).out;
|
||||||
garage_db = (rustPackages."unknown".garage_db."0.8.2" { inherit profileName; }).out;
|
garage_db = (rustPackages."unknown".garage_db."0.8.1" { inherit profileName; }).out;
|
||||||
garage_model = (rustPackages."unknown".garage_model."0.8.2" { inherit profileName; }).out;
|
garage_model = (rustPackages."unknown".garage_model."0.8.1" { inherit profileName; }).out;
|
||||||
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.2" { inherit profileName; }).out;
|
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.1" { inherit profileName; }).out;
|
||||||
garage_table = (rustPackages."unknown".garage_table."0.8.2" { inherit profileName; }).out;
|
garage_table = (rustPackages."unknown".garage_table."0.8.1" { inherit profileName; }).out;
|
||||||
garage_util = (rustPackages."unknown".garage_util."0.8.2" { inherit profileName; }).out;
|
garage_util = (rustPackages."unknown".garage_util."0.8.1" { inherit profileName; }).out;
|
||||||
garage_web = (rustPackages."unknown".garage_web."0.8.2" { inherit profileName; }).out;
|
garage_web = (rustPackages."unknown".garage_web."0.8.1" { inherit profileName; }).out;
|
||||||
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
||||||
sodiumoxide = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".kuska-sodiumoxide."0.2.5-0" { inherit profileName; }).out;
|
sodiumoxide = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".kuska-sodiumoxide."0.2.5-0" { inherit profileName; }).out;
|
||||||
netapp = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".netapp."0.5.2" { inherit profileName; }).out;
|
netapp = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".netapp."0.5.2" { inherit profileName; }).out;
|
||||||
@@ -1599,9 +1599,9 @@ in
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
"unknown".garage_api."0.8.2" = overridableMkRustCrate (profileName: rec {
|
"unknown".garage_api."0.8.1" = overridableMkRustCrate (profileName: rec {
|
||||||
name = "garage_api";
|
name = "garage_api";
|
||||||
version = "0.8.2";
|
version = "0.8.1";
|
||||||
registry = "unknown";
|
registry = "unknown";
|
||||||
src = fetchCrateLocal (workspaceSrc + "/src/api");
|
src = fetchCrateLocal (workspaceSrc + "/src/api");
|
||||||
features = builtins.concatLists [
|
features = builtins.concatLists [
|
||||||
@@ -1620,11 +1620,11 @@ in
|
|||||||
form_urlencoded = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".form_urlencoded."1.1.0" { inherit profileName; }).out;
|
form_urlencoded = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".form_urlencoded."1.1.0" { inherit profileName; }).out;
|
||||||
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
||||||
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
||||||
garage_block = (rustPackages."unknown".garage_block."0.8.2" { inherit profileName; }).out;
|
garage_block = (rustPackages."unknown".garage_block."0.8.1" { inherit profileName; }).out;
|
||||||
garage_model = (rustPackages."unknown".garage_model."0.8.2" { inherit profileName; }).out;
|
garage_model = (rustPackages."unknown".garage_model."0.8.1" { inherit profileName; }).out;
|
||||||
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.2" { inherit profileName; }).out;
|
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.1" { inherit profileName; }).out;
|
||||||
garage_table = (rustPackages."unknown".garage_table."0.8.2" { inherit profileName; }).out;
|
garage_table = (rustPackages."unknown".garage_table."0.8.1" { inherit profileName; }).out;
|
||||||
garage_util = (rustPackages."unknown".garage_util."0.8.2" { inherit profileName; }).out;
|
garage_util = (rustPackages."unknown".garage_util."0.8.1" { inherit profileName; }).out;
|
||||||
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
||||||
hmac = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hmac."0.12.1" { inherit profileName; }).out;
|
hmac = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hmac."0.12.1" { inherit profileName; }).out;
|
||||||
http = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".http."0.2.8" { inherit profileName; }).out;
|
http = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".http."0.2.8" { inherit profileName; }).out;
|
||||||
@@ -1653,9 +1653,9 @@ in
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
"unknown".garage_block."0.8.2" = overridableMkRustCrate (profileName: rec {
|
"unknown".garage_block."0.8.1" = overridableMkRustCrate (profileName: rec {
|
||||||
name = "garage_block";
|
name = "garage_block";
|
||||||
version = "0.8.2";
|
version = "0.8.1";
|
||||||
registry = "unknown";
|
registry = "unknown";
|
||||||
src = fetchCrateLocal (workspaceSrc + "/src/block");
|
src = fetchCrateLocal (workspaceSrc + "/src/block");
|
||||||
features = builtins.concatLists [
|
features = builtins.concatLists [
|
||||||
@@ -1668,10 +1668,10 @@ in
|
|||||||
bytes = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".bytes."1.3.0" { inherit profileName; }).out;
|
bytes = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".bytes."1.3.0" { inherit profileName; }).out;
|
||||||
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
||||||
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
||||||
garage_db = (rustPackages."unknown".garage_db."0.8.2" { inherit profileName; }).out;
|
garage_db = (rustPackages."unknown".garage_db."0.8.1" { inherit profileName; }).out;
|
||||||
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.2" { inherit profileName; }).out;
|
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.1" { inherit profileName; }).out;
|
||||||
garage_table = (rustPackages."unknown".garage_table."0.8.2" { inherit profileName; }).out;
|
garage_table = (rustPackages."unknown".garage_table."0.8.1" { inherit profileName; }).out;
|
||||||
garage_util = (rustPackages."unknown".garage_util."0.8.2" { inherit profileName; }).out;
|
garage_util = (rustPackages."unknown".garage_util."0.8.1" { inherit profileName; }).out;
|
||||||
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
||||||
opentelemetry = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".opentelemetry."0.17.0" { inherit profileName; }).out;
|
opentelemetry = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".opentelemetry."0.17.0" { inherit profileName; }).out;
|
||||||
rand = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".rand."0.8.5" { inherit profileName; }).out;
|
rand = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".rand."0.8.5" { inherit profileName; }).out;
|
||||||
@@ -1684,9 +1684,9 @@ in
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
"unknown".garage_db."0.8.2" = overridableMkRustCrate (profileName: rec {
|
"unknown".garage_db."0.8.1" = overridableMkRustCrate (profileName: rec {
|
||||||
name = "garage_db";
|
name = "garage_db";
|
||||||
version = "0.8.2";
|
version = "0.8.1";
|
||||||
registry = "unknown";
|
registry = "unknown";
|
||||||
src = fetchCrateLocal (workspaceSrc + "/src/db");
|
src = fetchCrateLocal (workspaceSrc + "/src/db");
|
||||||
features = builtins.concatLists [
|
features = builtins.concatLists [
|
||||||
@@ -1716,9 +1716,9 @@ in
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
"unknown".garage_model."0.8.2" = overridableMkRustCrate (profileName: rec {
|
"unknown".garage_model."0.8.1" = overridableMkRustCrate (profileName: rec {
|
||||||
name = "garage_model";
|
name = "garage_model";
|
||||||
version = "0.8.2";
|
version = "0.8.1";
|
||||||
registry = "unknown";
|
registry = "unknown";
|
||||||
src = fetchCrateLocal (workspaceSrc + "/src/model");
|
src = fetchCrateLocal (workspaceSrc + "/src/model");
|
||||||
features = builtins.concatLists [
|
features = builtins.concatLists [
|
||||||
@@ -1736,11 +1736,11 @@ in
|
|||||||
err_derive = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".err-derive."0.3.1" { profileName = "__noProfile"; }).out;
|
err_derive = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".err-derive."0.3.1" { profileName = "__noProfile"; }).out;
|
||||||
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
||||||
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
||||||
garage_block = (rustPackages."unknown".garage_block."0.8.2" { inherit profileName; }).out;
|
garage_block = (rustPackages."unknown".garage_block."0.8.1" { inherit profileName; }).out;
|
||||||
garage_db = (rustPackages."unknown".garage_db."0.8.2" { inherit profileName; }).out;
|
garage_db = (rustPackages."unknown".garage_db."0.8.1" { inherit profileName; }).out;
|
||||||
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.2" { inherit profileName; }).out;
|
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.1" { inherit profileName; }).out;
|
||||||
garage_table = (rustPackages."unknown".garage_table."0.8.2" { inherit profileName; }).out;
|
garage_table = (rustPackages."unknown".garage_table."0.8.1" { inherit profileName; }).out;
|
||||||
garage_util = (rustPackages."unknown".garage_util."0.8.2" { inherit profileName; }).out;
|
garage_util = (rustPackages."unknown".garage_util."0.8.1" { inherit profileName; }).out;
|
||||||
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
||||||
netapp = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".netapp."0.5.2" { inherit profileName; }).out;
|
netapp = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".netapp."0.5.2" { inherit profileName; }).out;
|
||||||
opentelemetry = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".opentelemetry."0.17.0" { inherit profileName; }).out;
|
opentelemetry = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".opentelemetry."0.17.0" { inherit profileName; }).out;
|
||||||
@@ -1753,9 +1753,9 @@ in
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
"unknown".garage_rpc."0.8.2" = overridableMkRustCrate (profileName: rec {
|
"unknown".garage_rpc."0.8.1" = overridableMkRustCrate (profileName: rec {
|
||||||
name = "garage_rpc";
|
name = "garage_rpc";
|
||||||
version = "0.8.2";
|
version = "0.8.1";
|
||||||
registry = "unknown";
|
registry = "unknown";
|
||||||
src = fetchCrateLocal (workspaceSrc + "/src/rpc");
|
src = fetchCrateLocal (workspaceSrc + "/src/rpc");
|
||||||
features = builtins.concatLists [
|
features = builtins.concatLists [
|
||||||
@@ -1775,7 +1775,7 @@ in
|
|||||||
${ if rootFeatures' ? "garage/consul-discovery" || rootFeatures' ? "garage_rpc/consul-discovery" || rootFeatures' ? "garage_rpc/err-derive" then "err_derive" else null } = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".err-derive."0.3.1" { profileName = "__noProfile"; }).out;
|
${ if rootFeatures' ? "garage/consul-discovery" || rootFeatures' ? "garage_rpc/consul-discovery" || rootFeatures' ? "garage_rpc/err-derive" then "err_derive" else null } = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".err-derive."0.3.1" { profileName = "__noProfile"; }).out;
|
||||||
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
||||||
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
||||||
garage_util = (rustPackages."unknown".garage_util."0.8.2" { inherit profileName; }).out;
|
garage_util = (rustPackages."unknown".garage_util."0.8.1" { inherit profileName; }).out;
|
||||||
gethostname = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".gethostname."0.2.3" { inherit profileName; }).out;
|
gethostname = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".gethostname."0.2.3" { inherit profileName; }).out;
|
||||||
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
||||||
${ if rootFeatures' ? "garage/kubernetes-discovery" || rootFeatures' ? "garage_rpc/k8s-openapi" || rootFeatures' ? "garage_rpc/kubernetes-discovery" then "k8s_openapi" else null } = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".k8s-openapi."0.16.0" { inherit profileName; }).out;
|
${ if rootFeatures' ? "garage/kubernetes-discovery" || rootFeatures' ? "garage_rpc/k8s-openapi" || rootFeatures' ? "garage_rpc/kubernetes-discovery" then "k8s_openapi" else null } = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".k8s-openapi."0.16.0" { inherit profileName; }).out;
|
||||||
@@ -1797,9 +1797,9 @@ in
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
"unknown".garage_table."0.8.2" = overridableMkRustCrate (profileName: rec {
|
"unknown".garage_table."0.8.1" = overridableMkRustCrate (profileName: rec {
|
||||||
name = "garage_table";
|
name = "garage_table";
|
||||||
version = "0.8.2";
|
version = "0.8.1";
|
||||||
registry = "unknown";
|
registry = "unknown";
|
||||||
src = fetchCrateLocal (workspaceSrc + "/src/table");
|
src = fetchCrateLocal (workspaceSrc + "/src/table");
|
||||||
dependencies = {
|
dependencies = {
|
||||||
@@ -1808,9 +1808,9 @@ in
|
|||||||
bytes = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".bytes."1.3.0" { inherit profileName; }).out;
|
bytes = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".bytes."1.3.0" { inherit profileName; }).out;
|
||||||
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
||||||
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
futures_util = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures-util."0.3.25" { inherit profileName; }).out;
|
||||||
garage_db = (rustPackages."unknown".garage_db."0.8.2" { inherit profileName; }).out;
|
garage_db = (rustPackages."unknown".garage_db."0.8.1" { inherit profileName; }).out;
|
||||||
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.2" { inherit profileName; }).out;
|
garage_rpc = (rustPackages."unknown".garage_rpc."0.8.1" { inherit profileName; }).out;
|
||||||
garage_util = (rustPackages."unknown".garage_util."0.8.2" { inherit profileName; }).out;
|
garage_util = (rustPackages."unknown".garage_util."0.8.1" { inherit profileName; }).out;
|
||||||
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
||||||
hexdump = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hexdump."0.1.1" { inherit profileName; }).out;
|
hexdump = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hexdump."0.1.1" { inherit profileName; }).out;
|
||||||
opentelemetry = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".opentelemetry."0.17.0" { inherit profileName; }).out;
|
opentelemetry = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".opentelemetry."0.17.0" { inherit profileName; }).out;
|
||||||
@@ -1822,9 +1822,9 @@ in
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
"unknown".garage_util."0.8.2" = overridableMkRustCrate (profileName: rec {
|
"unknown".garage_util."0.8.1" = overridableMkRustCrate (profileName: rec {
|
||||||
name = "garage_util";
|
name = "garage_util";
|
||||||
version = "0.8.2";
|
version = "0.8.1";
|
||||||
registry = "unknown";
|
registry = "unknown";
|
||||||
src = fetchCrateLocal (workspaceSrc + "/src/util");
|
src = fetchCrateLocal (workspaceSrc + "/src/util");
|
||||||
features = builtins.concatLists [
|
features = builtins.concatLists [
|
||||||
@@ -1839,7 +1839,7 @@ in
|
|||||||
digest = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".digest."0.10.6" { inherit profileName; }).out;
|
digest = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".digest."0.10.6" { inherit profileName; }).out;
|
||||||
err_derive = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".err-derive."0.3.1" { profileName = "__noProfile"; }).out;
|
err_derive = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".err-derive."0.3.1" { profileName = "__noProfile"; }).out;
|
||||||
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
||||||
garage_db = (rustPackages."unknown".garage_db."0.8.2" { inherit profileName; }).out;
|
garage_db = (rustPackages."unknown".garage_db."0.8.1" { inherit profileName; }).out;
|
||||||
git_version = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".git-version."0.3.5" { inherit profileName; }).out;
|
git_version = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".git-version."0.3.5" { inherit profileName; }).out;
|
||||||
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
hex = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hex."0.4.3" { inherit profileName; }).out;
|
||||||
hexdump = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hexdump."0.1.1" { inherit profileName; }).out;
|
hexdump = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hexdump."0.1.1" { inherit profileName; }).out;
|
||||||
@@ -1861,23 +1861,20 @@ in
|
|||||||
devDependencies = {
|
devDependencies = {
|
||||||
mktemp = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".mktemp."0.5.0" { inherit profileName; }).out;
|
mktemp = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".mktemp."0.5.0" { inherit profileName; }).out;
|
||||||
};
|
};
|
||||||
buildDependencies = {
|
|
||||||
rustc_version = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".rustc_version."0.4.0" { profileName = "__noProfile"; }).out;
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
"unknown".garage_web."0.8.2" = overridableMkRustCrate (profileName: rec {
|
"unknown".garage_web."0.8.1" = overridableMkRustCrate (profileName: rec {
|
||||||
name = "garage_web";
|
name = "garage_web";
|
||||||
version = "0.8.2";
|
version = "0.8.1";
|
||||||
registry = "unknown";
|
registry = "unknown";
|
||||||
src = fetchCrateLocal (workspaceSrc + "/src/web");
|
src = fetchCrateLocal (workspaceSrc + "/src/web");
|
||||||
dependencies = {
|
dependencies = {
|
||||||
err_derive = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".err-derive."0.3.1" { profileName = "__noProfile"; }).out;
|
err_derive = (buildRustPackages."registry+https://github.com/rust-lang/crates.io-index".err-derive."0.3.1" { profileName = "__noProfile"; }).out;
|
||||||
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
futures = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".futures."0.3.25" { inherit profileName; }).out;
|
||||||
garage_api = (rustPackages."unknown".garage_api."0.8.2" { inherit profileName; }).out;
|
garage_api = (rustPackages."unknown".garage_api."0.8.1" { inherit profileName; }).out;
|
||||||
garage_model = (rustPackages."unknown".garage_model."0.8.2" { inherit profileName; }).out;
|
garage_model = (rustPackages."unknown".garage_model."0.8.1" { inherit profileName; }).out;
|
||||||
garage_table = (rustPackages."unknown".garage_table."0.8.2" { inherit profileName; }).out;
|
garage_table = (rustPackages."unknown".garage_table."0.8.1" { inherit profileName; }).out;
|
||||||
garage_util = (rustPackages."unknown".garage_util."0.8.2" { inherit profileName; }).out;
|
garage_util = (rustPackages."unknown".garage_util."0.8.1" { inherit profileName; }).out;
|
||||||
http = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".http."0.2.8" { inherit profileName; }).out;
|
http = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".http."0.2.8" { inherit profileName; }).out;
|
||||||
hyper = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hyper."0.14.23" { inherit profileName; }).out;
|
hyper = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hyper."0.14.23" { inherit profileName; }).out;
|
||||||
opentelemetry = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".opentelemetry."0.17.0" { inherit profileName; }).out;
|
opentelemetry = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".opentelemetry."0.17.0" { inherit profileName; }).out;
|
||||||
@@ -2555,7 +2552,7 @@ in
|
|||||||
dependencies = {
|
dependencies = {
|
||||||
base64 = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".base64."0.21.0" { inherit profileName; }).out;
|
base64 = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".base64."0.21.0" { inherit profileName; }).out;
|
||||||
${ if rootFeatures' ? "k2v-client/clap" || rootFeatures' ? "k2v-client/cli" then "clap" else null } = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".clap."4.1.4" { inherit profileName; }).out;
|
${ if rootFeatures' ? "k2v-client/clap" || rootFeatures' ? "k2v-client/cli" then "clap" else null } = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".clap."4.1.4" { inherit profileName; }).out;
|
||||||
${ if rootFeatures' ? "k2v-client/cli" || rootFeatures' ? "k2v-client/garage_util" then "garage_util" else null } = (rustPackages."unknown".garage_util."0.8.2" { inherit profileName; }).out;
|
${ if rootFeatures' ? "k2v-client/cli" || rootFeatures' ? "k2v-client/garage_util" then "garage_util" else null } = (rustPackages."unknown".garage_util."0.8.1" { inherit profileName; }).out;
|
||||||
http = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".http."0.2.8" { inherit profileName; }).out;
|
http = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".http."0.2.8" { inherit profileName; }).out;
|
||||||
hyper_rustls = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hyper-rustls."0.23.2" { inherit profileName; }).out;
|
hyper_rustls = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".hyper-rustls."0.23.2" { inherit profileName; }).out;
|
||||||
log = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".log."0.4.17" { inherit profileName; }).out;
|
log = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".log."0.4.17" { inherit profileName; }).out;
|
||||||
|
|||||||
@@ -32,13 +32,6 @@ in {
|
|||||||
i386 = build_debug_and_release "i686-unknown-linux-musl";
|
i386 = build_debug_and_release "i686-unknown-linux-musl";
|
||||||
arm64 = build_debug_and_release "aarch64-unknown-linux-musl";
|
arm64 = build_debug_and_release "aarch64-unknown-linux-musl";
|
||||||
arm = build_debug_and_release "armv6l-unknown-linux-musleabihf";
|
arm = build_debug_and_release "armv6l-unknown-linux-musleabihf";
|
||||||
win = {
|
|
||||||
amd64 = build_debug_and_release "x86_64-w64-mingw32";
|
|
||||||
};
|
|
||||||
apple = {
|
|
||||||
arm64 = build_debug_and_release "aarch64-apple-darwin";
|
|
||||||
amd64 = build_debug_and_release "x86_64-apple-darwin";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
test = {
|
test = {
|
||||||
amd64 = test (compile {
|
amd64 = test (compile {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ These tools are particularly suitable for debug, backups, website deployments or
|
|||||||
| [AWS CLI](#aws-cli) | ✅ | Recommended |
|
| [AWS CLI](#aws-cli) | ✅ | Recommended |
|
||||||
| [rclone](#rclone) | ✅ | |
|
| [rclone](#rclone) | ✅ | |
|
||||||
| [s3cmd](#s3cmd) | ✅ | |
|
| [s3cmd](#s3cmd) | ✅ | |
|
||||||
| [s5cmd](#s5cmd) | ✅ | |
|
|
||||||
| [(Cyber)duck](#cyberduck) | ✅ | |
|
| [(Cyber)duck](#cyberduck) | ✅ | |
|
||||||
| [WinSCP (libs3)](#winscp) | ✅ | CLI instructions only |
|
| [WinSCP (libs3)](#winscp) | ✅ | CLI instructions only |
|
||||||
| [sftpgo](#sftpgo) | ✅ | |
|
| [sftpgo](#sftpgo) | ✅ | |
|
||||||
@@ -179,26 +178,6 @@ s3cmd put /tmp/hello.txt s3://my-bucket/
|
|||||||
s3cmd get s3://my-bucket/hello.txt hello.txt
|
s3cmd get s3://my-bucket/hello.txt hello.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
## `s5cmd`
|
|
||||||
|
|
||||||
Configure a credentials file as follows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export AWS_ACCESS_KEY_ID=GK...
|
|
||||||
export AWS_SECRET_ACCESS_KEY=
|
|
||||||
export AWS_DEFAULT_REGION='garage'
|
|
||||||
export AWS_ENDPOINT='http://localhost:3900'
|
|
||||||
```
|
|
||||||
|
|
||||||
After adding these environment variables in your shell, `s5cmd` can be used
|
|
||||||
with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
s5cmd --endpoint-url=$AWS_ENDPOINT ls
|
|
||||||
```
|
|
||||||
|
|
||||||
See its usage output for other commands available.
|
|
||||||
|
|
||||||
## Cyberduck & duck {#cyberduck}
|
## Cyberduck & duck {#cyberduck}
|
||||||
|
|
||||||
Both Cyberduck (the GUI) and duck (the CLI) have a concept of "Connection Profiles" that contain some presets for a specific provider.
|
Both Cyberduck (the GUI) and duck (the CLI) have a concept of "Connection Profiles" that contain some presets for a specific provider.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ sort_by = "weight"
|
|||||||
+++
|
+++
|
||||||
|
|
||||||
A cookbook, when you cook, is a collection of recipes.
|
A cookbook, when you cook, is a collection of recipes.
|
||||||
Similarly, Garage's cookbook contains a collection of recipes that are known to work well!
|
Similarly, Garage's cookbook contains a collection of recipes that are known to works well!
|
||||||
This chapter could also be referred as "Tutorials" or "Best practices".
|
This chapter could also be referred as "Tutorials" or "Best practices".
|
||||||
|
|
||||||
- **[Multi-node deployment](@/documentation/cookbook/real-world.md):** This page will walk you through all of the necessary
|
- **[Multi-node deployment](@/documentation/cookbook/real-world.md):** This page will walk you through all of the necessary
|
||||||
@@ -16,10 +16,6 @@ This chapter could also be referred as "Tutorials" or "Best practices".
|
|||||||
source in case a binary is not provided for your architecture, or if you want to
|
source in case a binary is not provided for your architecture, or if you want to
|
||||||
hack with us!
|
hack with us!
|
||||||
|
|
||||||
- **[Binary packages](@/documentation/cookbook/binary-packages.md):** This page
|
|
||||||
lists the different platforms that provide ready-built software packages for
|
|
||||||
Garage.
|
|
||||||
|
|
||||||
- **[Integration with Systemd](@/documentation/cookbook/systemd.md):** This page explains how to run Garage
|
- **[Integration with Systemd](@/documentation/cookbook/systemd.md):** This page explains how to run Garage
|
||||||
as a Systemd service (instead of as a Docker container).
|
as a Systemd service (instead of as a Docker container).
|
||||||
|
|
||||||
@@ -30,10 +26,6 @@ This chapter could also be referred as "Tutorials" or "Best practices".
|
|||||||
|
|
||||||
- **[Configuring a reverse-proxy](@/documentation/cookbook/reverse-proxy.md):** This page explains how to configure a reverse-proxy to add TLS support to your S3 api endpoint.
|
- **[Configuring a reverse-proxy](@/documentation/cookbook/reverse-proxy.md):** This page explains how to configure a reverse-proxy to add TLS support to your S3 api endpoint.
|
||||||
|
|
||||||
- **[Deploying on Kubernetes](@/documentation/cookbook/kubernetes.md):** This page explains how to deploy Garage on Kubernetes using our Helm chart.
|
|
||||||
|
|
||||||
- **[Deploying with Ansible](@/documentation/cookbook/ansible.md):** This page lists available Ansible roles developed by the community to deploy Garage.
|
|
||||||
|
|
||||||
- **[Monitoring Garage](@/documentation/cookbook/monitoring.md)** This page
|
- **[Monitoring Garage](@/documentation/cookbook/monitoring.md)** This page
|
||||||
explains the Prometheus metrics available for monitoring the Garage
|
explains the Prometheus metrics available for monitoring the Garage
|
||||||
cluster/nodes.
|
cluster/nodes.
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
+++
|
|
||||||
title = "Deploying with Ansible"
|
|
||||||
weight = 35
|
|
||||||
+++
|
|
||||||
|
|
||||||
While Ansible is not officially supported to deploy Garage, several community members
|
|
||||||
have published Ansible roles. We list them and compare them below.
|
|
||||||
|
|
||||||
## Comparison of Ansible roles
|
|
||||||
|
|
||||||
| Feature | [ansible-role-garage](#zorun-ansible-role-garage) | [garage-docker-ansible-deploy](#moan0s-garage-docker-ansible-deploy) |
|
|
||||||
|------------------------------------|---------------------------------------------|---------------------------------------------------------------|
|
|
||||||
| **Runtime** | Systemd | Docker |
|
|
||||||
| **Target OS** | Any Linux | Any Linux |
|
|
||||||
| **Architecture** | amd64, arm64, i686 | amd64, arm64 |
|
|
||||||
| **Additional software** | None | Traefik |
|
|
||||||
| **Automatic node connection** | ❌ | ✅ |
|
|
||||||
| **Layout management** | ❌ | ✅ |
|
|
||||||
| **Manage buckets & keys** | ❌ | ✅ (basic) |
|
|
||||||
| **Allow custom Garage config** | ✅ | ❌ |
|
|
||||||
| **Facilitate Garage upgrades** | ✅ | ❌ |
|
|
||||||
| **Multiple instances on one host** | ✅ | ✅ |
|
|
||||||
|
|
||||||
|
|
||||||
## zorun/ansible-role-garage
|
|
||||||
|
|
||||||
[Source code](https://github.com/zorun/ansible-role-garage), [Ansible galaxy](https://galaxy.ansible.com/zorun/garage)
|
|
||||||
|
|
||||||
This role is voluntarily simple: it relies on the official Garage static
|
|
||||||
binaries and only requires Systemd. As such, it should work on any
|
|
||||||
Linux-based OS.
|
|
||||||
|
|
||||||
To make things more flexible, the user has to provide a Garage
|
|
||||||
configuration template. This allows to customize Garage configuration in
|
|
||||||
any way.
|
|
||||||
|
|
||||||
Some more features might be added, such as a way to automatically connect
|
|
||||||
nodes to each other or to define a layout.
|
|
||||||
|
|
||||||
## moan0s/garage-docker-ansible-deploy
|
|
||||||
|
|
||||||
[Source code](https://github.com/moan0s/garage-docker-ansible-deploy), [Blog post](https://hyteck.de/post/garage/)
|
|
||||||
|
|
||||||
This role is based on the Docker image for Garage, and comes with
|
|
||||||
"batteries included": it will additionally install Docker and Traefik. In
|
|
||||||
addition, it is "opinionated" in the sense that it expects a particular
|
|
||||||
deployment structure (one instance per disk, one gateway per host,
|
|
||||||
structured DNS names, etc).
|
|
||||||
|
|
||||||
As a result, this role makes it easier to start with Garage on Ansible,
|
|
||||||
but is less flexible.
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
+++
|
|
||||||
title = "Binary packages"
|
|
||||||
weight = 11
|
|
||||||
+++
|
|
||||||
|
|
||||||
Garage is also available in binary packages on:
|
|
||||||
|
|
||||||
## Alpine Linux
|
|
||||||
|
|
||||||
```bash
|
|
||||||
apk install garage
|
|
||||||
```
|
|
||||||
|
|
||||||
## Arch Linux
|
|
||||||
|
|
||||||
Garage is available in the [AUR](https://aur.archlinux.org/packages/garage).
|
|
||||||
|
|
||||||
## FreeBSD
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pkg install garage
|
|
||||||
```
|
|
||||||
|
|
||||||
## NixOS
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nix-shell -p garage
|
|
||||||
```
|
|
||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
+1
-181
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 74 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 74 KiB |
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garage_api"
|
name = "garage_api"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
authors = ["Alex Auvolat <alex@adnab.me>"]
|
authors = ["Alex Auvolat <alex@adnab.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
@@ -14,11 +14,11 @@ path = "lib.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
garage_model = { version = "0.8.2", path = "../model" }
|
garage_model = { version = "0.8.1", path = "../model" }
|
||||||
garage_table = { version = "0.8.2", path = "../table" }
|
garage_table = { version = "0.8.1", path = "../table" }
|
||||||
garage_block = { version = "0.8.2", path = "../block" }
|
garage_block = { version = "0.8.1", path = "../block" }
|
||||||
garage_util = { version = "0.8.2", path = "../util" }
|
garage_util = { version = "0.8.1", path = "../util" }
|
||||||
garage_rpc = { version = "0.8.2", path = "../rpc" }
|
garage_rpc = { version = "0.8.1", path = "../rpc" }
|
||||||
|
|
||||||
async-trait = "0.1.7"
|
async-trait = "0.1.7"
|
||||||
base64 = "0.21"
|
base64 = "0.21"
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ pub async fn handle_get_cluster_status(garage: &Arc<Garage>) -> Result<Response<
|
|||||||
node: hex::encode(garage.system.id),
|
node: hex::encode(garage.system.id),
|
||||||
garage_version: garage_util::version::garage_version(),
|
garage_version: garage_util::version::garage_version(),
|
||||||
garage_features: garage_util::version::garage_features(),
|
garage_features: garage_util::version::garage_features(),
|
||||||
rust_version: garage_util::version::rust_version(),
|
|
||||||
db_engine: garage.db.engine(),
|
db_engine: garage.db.engine(),
|
||||||
known_nodes: garage
|
known_nodes: garage
|
||||||
.system
|
.system
|
||||||
@@ -107,7 +106,6 @@ struct GetClusterStatusResponse {
|
|||||||
node: String,
|
node: String,
|
||||||
garage_version: &'static str,
|
garage_version: &'static str,
|
||||||
garage_features: Option<&'static [&'static str]>,
|
garage_features: Option<&'static [&'static str]>,
|
||||||
rust_version: &'static str,
|
|
||||||
db_engine: String,
|
db_engine: String,
|
||||||
known_nodes: HashMap<String, KnownNodeResp>,
|
known_nodes: HashMap<String, KnownNodeResp>,
|
||||||
layout: GetClusterLayoutResponse,
|
layout: GetClusterLayoutResponse,
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ use opentelemetry::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use garage_util::error::Error as GarageError;
|
use garage_util::error::Error as GarageError;
|
||||||
use garage_util::forwarded_headers;
|
|
||||||
use garage_util::metrics::{gen_trace_id, RecordDuration};
|
use garage_util::metrics::{gen_trace_id, RecordDuration};
|
||||||
|
|
||||||
pub(crate) trait ApiEndpoint: Send + Sync + 'static {
|
pub(crate) trait ApiEndpoint: Send + Sync + 'static {
|
||||||
@@ -127,9 +126,15 @@ impl<A: ApiHandler> ApiServer<A> {
|
|||||||
) -> Result<Response<Body>, GarageError> {
|
) -> Result<Response<Body>, GarageError> {
|
||||||
let uri = req.uri().clone();
|
let uri = req.uri().clone();
|
||||||
|
|
||||||
if let Ok(forwarded_for_ip_addr) =
|
let has_forwarded_for_header = req.headers().contains_key("x-forwarded-for");
|
||||||
forwarded_headers::handle_forwarded_for_headers(&req.headers())
|
if has_forwarded_for_header {
|
||||||
{
|
let forwarded_for_ip_addr = &req
|
||||||
|
.headers()
|
||||||
|
.get("x-forwarded-for")
|
||||||
|
.expect("Could not parse X-Forwarded-For header")
|
||||||
|
.to_str()
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"{} (via {}) {} {}",
|
"{} (via {}) {} {}",
|
||||||
forwarded_for_ip_addr,
|
forwarded_for_ip_addr,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garage_block"
|
name = "garage_block"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
authors = ["Alex Auvolat <alex@adnab.me>"]
|
authors = ["Alex Auvolat <alex@adnab.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
@@ -14,10 +14,10 @@ path = "lib.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
garage_db = { version = "0.8.2", path = "../db" }
|
garage_db = { version = "0.8.1", path = "../db" }
|
||||||
garage_rpc = { version = "0.8.2", path = "../rpc" }
|
garage_rpc = { version = "0.8.1", path = "../rpc" }
|
||||||
garage_util = { version = "0.8.2", path = "../util" }
|
garage_util = { version = "0.8.1", path = "../util" }
|
||||||
garage_table = { version = "0.8.2", path = "../table" }
|
garage_table = { version = "0.8.1", path = "../table" }
|
||||||
|
|
||||||
opentelemetry = "0.17"
|
opentelemetry = "0.17"
|
||||||
|
|
||||||
|
|||||||
@@ -152,7 +152,6 @@ impl BlockManager {
|
|||||||
tx_scrub_command: ArcSwapOption::new(None),
|
tx_scrub_command: ArcSwapOption::new(None),
|
||||||
});
|
});
|
||||||
block_manager.endpoint.set_handler(block_manager.clone());
|
block_manager.endpoint.set_handler(block_manager.clone());
|
||||||
block_manager.scrub_persister.set_with(|_| ()).unwrap();
|
|
||||||
|
|
||||||
block_manager
|
block_manager
|
||||||
}
|
}
|
||||||
@@ -186,9 +185,6 @@ impl BlockManager {
|
|||||||
vars.register_ro(&self.scrub_persister, "scrub-last-completed", |p| {
|
vars.register_ro(&self.scrub_persister, "scrub-last-completed", |p| {
|
||||||
p.get_with(|x| msec_to_rfc3339(x.time_last_complete_scrub))
|
p.get_with(|x| msec_to_rfc3339(x.time_last_complete_scrub))
|
||||||
});
|
});
|
||||||
vars.register_ro(&self.scrub_persister, "scrub-next-run", |p| {
|
|
||||||
p.get_with(|x| msec_to_rfc3339(x.time_next_run_scrub))
|
|
||||||
});
|
|
||||||
vars.register_ro(&self.scrub_persister, "scrub-corruptions_detected", |p| {
|
vars.register_ro(&self.scrub_persister, "scrub-corruptions_detected", |p| {
|
||||||
p.get_with(|x| x.corruptions_detected)
|
p.get_with(|x| x.corruptions_detected)
|
||||||
});
|
});
|
||||||
|
|||||||
+18
-79
@@ -4,7 +4,7 @@ use std::sync::Arc;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rand::Rng;
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use tokio::select;
|
use tokio::select;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
@@ -19,8 +19,8 @@ use garage_util::tranquilizer::Tranquilizer;
|
|||||||
|
|
||||||
use crate::manager::*;
|
use crate::manager::*;
|
||||||
|
|
||||||
// Full scrub every 25 days with a random element of 10 days mixed in below
|
// Full scrub every 30 days
|
||||||
const SCRUB_INTERVAL: Duration = Duration::from_secs(3600 * 24 * 25);
|
const SCRUB_INTERVAL: Duration = Duration::from_secs(3600 * 24 * 30);
|
||||||
// Scrub tranquility is initially set to 4, but can be changed in the CLI
|
// Scrub tranquility is initially set to 4, but can be changed in the CLI
|
||||||
// and the updated version is persisted over Garage restarts
|
// and the updated version is persisted over Garage restarts
|
||||||
const INITIAL_SCRUB_TRANQUILITY: u32 = 4;
|
const INITIAL_SCRUB_TRANQUILITY: u32 = 4;
|
||||||
@@ -161,51 +161,6 @@ impl Worker for RepairWorker {
|
|||||||
// and whose parameter (esp. speed) can be controlled at runtime.
|
// and whose parameter (esp. speed) can be controlled at runtime.
|
||||||
// ---- ---- ----
|
// ---- ---- ----
|
||||||
|
|
||||||
mod v081 {
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub struct ScrubWorkerPersisted {
|
|
||||||
pub tranquility: u32,
|
|
||||||
pub(crate) time_last_complete_scrub: u64,
|
|
||||||
pub(crate) corruptions_detected: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl garage_util::migrate::InitialFormat for ScrubWorkerPersisted {}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod v082 {
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use super::v081;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub struct ScrubWorkerPersisted {
|
|
||||||
pub tranquility: u32,
|
|
||||||
pub(crate) time_last_complete_scrub: u64,
|
|
||||||
pub(crate) time_next_run_scrub: u64,
|
|
||||||
pub(crate) corruptions_detected: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl garage_util::migrate::Migrate for ScrubWorkerPersisted {
|
|
||||||
type Previous = v081::ScrubWorkerPersisted;
|
|
||||||
const VERSION_MARKER: &'static [u8] = b"G082bswp";
|
|
||||||
|
|
||||||
fn migrate(old: v081::ScrubWorkerPersisted) -> ScrubWorkerPersisted {
|
|
||||||
use crate::repair::randomize_next_scrub_run_time;
|
|
||||||
|
|
||||||
ScrubWorkerPersisted {
|
|
||||||
tranquility: old.tranquility,
|
|
||||||
time_last_complete_scrub: old.time_last_complete_scrub,
|
|
||||||
time_next_run_scrub: randomize_next_scrub_run_time(old.time_last_complete_scrub),
|
|
||||||
corruptions_detected: old.corruptions_detected,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use v082::*;
|
|
||||||
|
|
||||||
pub struct ScrubWorker {
|
pub struct ScrubWorker {
|
||||||
manager: Arc<BlockManager>,
|
manager: Arc<BlockManager>,
|
||||||
rx_cmd: mpsc::Receiver<ScrubWorkerCommand>,
|
rx_cmd: mpsc::Receiver<ScrubWorkerCommand>,
|
||||||
@@ -216,25 +171,17 @@ pub struct ScrubWorker {
|
|||||||
persister: PersisterShared<ScrubWorkerPersisted>,
|
persister: PersisterShared<ScrubWorkerPersisted>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn randomize_next_scrub_run_time(timestamp: u64) -> u64 {
|
#[derive(Serialize, Deserialize)]
|
||||||
// Take SCRUB_INTERVAL and mix in a random interval of 10 days to attempt to
|
pub struct ScrubWorkerPersisted {
|
||||||
// balance scrub load across different cluster nodes.
|
pub tranquility: u32,
|
||||||
|
pub(crate) time_last_complete_scrub: u64,
|
||||||
let next_run_timestamp = timestamp
|
pub(crate) corruptions_detected: u64,
|
||||||
+ SCRUB_INTERVAL
|
|
||||||
.saturating_add(Duration::from_secs(
|
|
||||||
rand::thread_rng().gen_range(0..3600 * 24 * 10),
|
|
||||||
))
|
|
||||||
.as_millis() as u64;
|
|
||||||
|
|
||||||
next_run_timestamp
|
|
||||||
}
|
}
|
||||||
|
impl garage_util::migrate::InitialFormat for ScrubWorkerPersisted {}
|
||||||
impl Default for ScrubWorkerPersisted {
|
impl Default for ScrubWorkerPersisted {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ScrubWorkerPersisted {
|
ScrubWorkerPersisted {
|
||||||
time_last_complete_scrub: 0,
|
time_last_complete_scrub: 0,
|
||||||
time_next_run_scrub: randomize_next_scrub_run_time(now_msec()),
|
|
||||||
tranquility: INITIAL_SCRUB_TRANQUILITY,
|
tranquility: INITIAL_SCRUB_TRANQUILITY,
|
||||||
corruptions_detected: 0,
|
corruptions_detected: 0,
|
||||||
}
|
}
|
||||||
@@ -332,13 +279,12 @@ impl Worker for ScrubWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn status(&self) -> WorkerStatus {
|
fn status(&self) -> WorkerStatus {
|
||||||
let (corruptions_detected, tranquility, time_last_complete_scrub, time_next_run_scrub) =
|
let (corruptions_detected, tranquility, time_last_complete_scrub) =
|
||||||
self.persister.get_with(|p| {
|
self.persister.get_with(|p| {
|
||||||
(
|
(
|
||||||
p.corruptions_detected,
|
p.corruptions_detected,
|
||||||
p.tranquility,
|
p.tranquility,
|
||||||
p.time_last_complete_scrub,
|
p.time_last_complete_scrub,
|
||||||
p.time_next_run_scrub,
|
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -356,16 +302,10 @@ impl Worker for ScrubWorker {
|
|||||||
s.freeform = vec![format!("Scrub paused, resumes at {}", msec_to_rfc3339(*rt))];
|
s.freeform = vec![format!("Scrub paused, resumes at {}", msec_to_rfc3339(*rt))];
|
||||||
}
|
}
|
||||||
ScrubWorkerState::Finished => {
|
ScrubWorkerState::Finished => {
|
||||||
s.freeform = vec![
|
s.freeform = vec![format!(
|
||||||
format!(
|
"Last scrub completed at {}",
|
||||||
"Last scrub completed at {}",
|
msec_to_rfc3339(time_last_complete_scrub)
|
||||||
msec_to_rfc3339(time_last_complete_scrub),
|
)];
|
||||||
),
|
|
||||||
format!(
|
|
||||||
"Next scrub scheduled for {}",
|
|
||||||
msec_to_rfc3339(time_next_run_scrub)
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
@@ -394,10 +334,8 @@ impl Worker for ScrubWorker {
|
|||||||
.tranquilizer
|
.tranquilizer
|
||||||
.tranquilize_worker(self.persister.get_with(|p| p.tranquility)))
|
.tranquilize_worker(self.persister.get_with(|p| p.tranquility)))
|
||||||
} else {
|
} else {
|
||||||
self.persister.set_with(|p| {
|
self.persister
|
||||||
p.time_last_complete_scrub = now_msec();
|
.set_with(|p| p.time_last_complete_scrub = now_msec())?;
|
||||||
p.time_next_run_scrub = randomize_next_scrub_run_time(now_msec());
|
|
||||||
})?;
|
|
||||||
self.work = ScrubWorkerState::Finished;
|
self.work = ScrubWorkerState::Finished;
|
||||||
self.tranquilizer.clear();
|
self.tranquilizer.clear();
|
||||||
Ok(WorkerState::Idle)
|
Ok(WorkerState::Idle)
|
||||||
@@ -412,7 +350,8 @@ impl Worker for ScrubWorker {
|
|||||||
ScrubWorkerState::Running(_) => return WorkerState::Busy,
|
ScrubWorkerState::Running(_) => return WorkerState::Busy,
|
||||||
ScrubWorkerState::Paused(_, resume_time) => (*resume_time, ScrubWorkerCommand::Resume),
|
ScrubWorkerState::Paused(_, resume_time) => (*resume_time, ScrubWorkerCommand::Resume),
|
||||||
ScrubWorkerState::Finished => (
|
ScrubWorkerState::Finished => (
|
||||||
self.persister.get_with(|p| p.time_next_run_scrub),
|
self.persister.get_with(|p| p.time_last_complete_scrub)
|
||||||
|
+ SCRUB_INTERVAL.as_millis() as u64,
|
||||||
ScrubWorkerCommand::Start,
|
ScrubWorkerCommand::Start,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garage_db"
|
name = "garage_db"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
authors = ["Alex Auvolat <alex@adnab.me>"]
|
authors = ["Alex Auvolat <alex@adnab.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garage"
|
name = "garage"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
authors = ["Alex Auvolat <alex@adnab.me>"]
|
authors = ["Alex Auvolat <alex@adnab.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
@@ -21,14 +21,14 @@ path = "tests/lib.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
garage_db = { version = "0.8.2", path = "../db" }
|
garage_db = { version = "0.8.1", path = "../db" }
|
||||||
garage_api = { version = "0.8.2", path = "../api" }
|
garage_api = { version = "0.8.1", path = "../api" }
|
||||||
garage_block = { version = "0.8.2", path = "../block" }
|
garage_block = { version = "0.8.1", path = "../block" }
|
||||||
garage_model = { version = "0.8.2", path = "../model" }
|
garage_model = { version = "0.8.1", path = "../model" }
|
||||||
garage_rpc = { version = "0.8.2", path = "../rpc" }
|
garage_rpc = { version = "0.8.1", path = "../rpc" }
|
||||||
garage_table = { version = "0.8.2", path = "../table" }
|
garage_table = { version = "0.8.1", path = "../table" }
|
||||||
garage_util = { version = "0.8.2", path = "../util" }
|
garage_util = { version = "0.8.1", path = "../util" }
|
||||||
garage_web = { version = "0.8.2", path = "../web" }
|
garage_web = { version = "0.8.1", path = "../web" }
|
||||||
|
|
||||||
backtrace = "0.3"
|
backtrace = "0.3"
|
||||||
bytes = "1.0"
|
bytes = "1.0"
|
||||||
|
|||||||
+1
-2
@@ -820,12 +820,11 @@ impl AdminRpcHandler {
|
|||||||
let mut ret = String::new();
|
let mut ret = String::new();
|
||||||
writeln!(
|
writeln!(
|
||||||
&mut ret,
|
&mut ret,
|
||||||
"\nGarage version: {} [features: {}]\nRust compiler version: {}",
|
"\nGarage version: {} [features: {}]",
|
||||||
garage_util::version::garage_version(),
|
garage_util::version::garage_version(),
|
||||||
garage_util::version::garage_features()
|
garage_util::version::garage_features()
|
||||||
.map(|list| list.join(", "))
|
.map(|list| list.join(", "))
|
||||||
.unwrap_or_else(|| "(unknown)".into()),
|
.unwrap_or_else(|| "(unknown)".into()),
|
||||||
garage_util::version::rust_version(),
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,14 @@ async fn test_admin_bucket_perms() {
|
|||||||
|
|
||||||
ctx.garage
|
ctx.garage
|
||||||
.command()
|
.command()
|
||||||
.args(["bucket", "allow", "--read", "--key", &ctx.key.id, BCKT_NAME])
|
.args([
|
||||||
|
"bucket",
|
||||||
|
"allow",
|
||||||
|
"--read",
|
||||||
|
"--key",
|
||||||
|
&ctx.garage.key.id,
|
||||||
|
BCKT_NAME,
|
||||||
|
])
|
||||||
.quiet()
|
.quiet()
|
||||||
.expect_success_status("Could not create bucket");
|
.expect_success_status("Could not create bucket");
|
||||||
|
|
||||||
@@ -29,7 +36,14 @@ async fn test_admin_bucket_perms() {
|
|||||||
|
|
||||||
ctx.garage
|
ctx.garage
|
||||||
.command()
|
.command()
|
||||||
.args(["bucket", "deny", "--read", "--key", &ctx.key.id, BCKT_NAME])
|
.args([
|
||||||
|
"bucket",
|
||||||
|
"deny",
|
||||||
|
"--read",
|
||||||
|
"--key",
|
||||||
|
&ctx.garage.key.name,
|
||||||
|
BCKT_NAME,
|
||||||
|
])
|
||||||
.quiet()
|
.quiet()
|
||||||
.expect_success_status("Could not create bucket");
|
.expect_success_status("Could not create bucket");
|
||||||
|
|
||||||
@@ -37,7 +51,14 @@ async fn test_admin_bucket_perms() {
|
|||||||
|
|
||||||
ctx.garage
|
ctx.garage
|
||||||
.command()
|
.command()
|
||||||
.args(["bucket", "allow", "--read", "--key", &ctx.key.id, BCKT_NAME])
|
.args([
|
||||||
|
"bucket",
|
||||||
|
"allow",
|
||||||
|
"--read",
|
||||||
|
"--key",
|
||||||
|
&ctx.garage.key.name,
|
||||||
|
BCKT_NAME,
|
||||||
|
])
|
||||||
.quiet()
|
.quiet()
|
||||||
.expect_success_status("Could not create bucket");
|
.expect_success_status("Could not create bucket");
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ async fn test_bucket_all() {
|
|||||||
ctx.garage
|
ctx.garage
|
||||||
.command()
|
.command()
|
||||||
.args(["key", "deny"])
|
.args(["key", "deny"])
|
||||||
.args(["--create-bucket", &ctx.key.id])
|
.args(["--create-bucket", &ctx.garage.key.id])
|
||||||
.quiet()
|
.quiet()
|
||||||
.expect_success_output("Could not deny key to create buckets");
|
.expect_success_output("Could not deny key to create buckets");
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ async fn test_bucket_all() {
|
|||||||
ctx.garage
|
ctx.garage
|
||||||
.command()
|
.command()
|
||||||
.args(["key", "allow"])
|
.args(["key", "allow"])
|
||||||
.args(["--create-bucket", &ctx.key.id])
|
.args(["--create-bucket", &ctx.garage.key.id])
|
||||||
.quiet()
|
.quiet()
|
||||||
.expect_success_output("Could not deny key to create buckets");
|
.expect_success_output("Could not deny key to create buckets");
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
use aws_sdk_s3::{Client, Config, Credentials, Endpoint};
|
use aws_sdk_s3::{Client, Config, Credentials, Endpoint};
|
||||||
|
|
||||||
use super::garage::{Instance, Key};
|
use super::garage::Instance;
|
||||||
|
|
||||||
pub fn build_client(instance: &Instance, key: &Key) -> Client {
|
pub fn build_client(instance: &Instance) -> Client {
|
||||||
let credentials = Credentials::new(&key.id, &key.secret, None, None, "garage-integ-test");
|
let credentials = Credentials::new(
|
||||||
|
&instance.key.id,
|
||||||
|
&instance.key.secret,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
"garage-integ-test",
|
||||||
|
);
|
||||||
let endpoint = Endpoint::immutable(instance.s3_uri());
|
let endpoint = Endpoint::immutable(instance.s3_uri());
|
||||||
|
|
||||||
let config = Config::builder()
|
let config = Config::builder()
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ use garage_api::signature;
|
|||||||
/// You should ever only use this to send requests AWS sdk won't send,
|
/// You should ever only use this to send requests AWS sdk won't send,
|
||||||
/// like to reproduce behavior of unusual implementations found to be
|
/// like to reproduce behavior of unusual implementations found to be
|
||||||
/// problematic.
|
/// problematic.
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct CustomRequester {
|
pub struct CustomRequester {
|
||||||
key: Key,
|
key: Key,
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
@@ -23,18 +22,18 @@ pub struct CustomRequester {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CustomRequester {
|
impl CustomRequester {
|
||||||
pub fn new_s3(instance: &Instance, key: &Key) -> Self {
|
pub fn new_s3(instance: &Instance) -> Self {
|
||||||
CustomRequester {
|
CustomRequester {
|
||||||
key: key.clone(),
|
key: instance.key.clone(),
|
||||||
uri: instance.s3_uri(),
|
uri: instance.s3_uri(),
|
||||||
service: "s3",
|
service: "s3",
|
||||||
client: Client::new(),
|
client: Client::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_k2v(instance: &Instance, key: &Key) -> Self {
|
pub fn new_k2v(instance: &Instance) -> Self {
|
||||||
CustomRequester {
|
CustomRequester {
|
||||||
key: key.clone(),
|
key: instance.key.clone(),
|
||||||
uri: instance.k2v_uri(),
|
uri: instance.k2v_uri(),
|
||||||
service: "k2v",
|
service: "k2v",
|
||||||
client: Client::new(),
|
client: Client::new(),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ static GARAGE_TEST_SECRET: &str =
|
|||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct Key {
|
pub struct Key {
|
||||||
pub name: Option<String>,
|
pub name: String,
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub secret: String,
|
pub secret: String,
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ pub struct Key {
|
|||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
process: process::Child,
|
process: process::Child,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub default_key: Key,
|
pub key: Key,
|
||||||
pub s3_port: u16,
|
pub s3_port: u16,
|
||||||
pub k2v_port: u16,
|
pub k2v_port: u16,
|
||||||
pub web_port: u16,
|
pub web_port: u16,
|
||||||
@@ -102,7 +102,7 @@ api_bind_addr = "127.0.0.1:{admin_port}"
|
|||||||
Instance {
|
Instance {
|
||||||
process: child,
|
process: child,
|
||||||
path,
|
path,
|
||||||
default_key: Key::default(),
|
key: Key::default(),
|
||||||
s3_port: port,
|
s3_port: port,
|
||||||
k2v_port: port + 1,
|
k2v_port: port + 1,
|
||||||
web_port: port + 3,
|
web_port: port + 3,
|
||||||
@@ -111,27 +111,14 @@ api_bind_addr = "127.0.0.1:{admin_port}"
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn setup(&mut self) {
|
fn setup(&mut self) {
|
||||||
self.wait_for_boot();
|
|
||||||
self.setup_layout();
|
|
||||||
self.default_key = self.key(Some("garage_test"));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn wait_for_boot(&mut self) {
|
|
||||||
use std::{thread, time::Duration};
|
use std::{thread, time::Duration};
|
||||||
|
|
||||||
// 60 * 2 seconds = 120 seconds = 2min
|
// Wait for node to be ready
|
||||||
for _ in 0..60 {
|
thread::sleep(Duration::from_secs(2));
|
||||||
let termination = self
|
|
||||||
.command()
|
self.setup_layout();
|
||||||
.args(["status"])
|
|
||||||
.quiet()
|
self.key = self.new_key("garage_test");
|
||||||
.status()
|
|
||||||
.expect("Unable to run command");
|
|
||||||
if termination.success() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
thread::sleep(Duration::from_secs(2));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_layout(&self) {
|
fn setup_layout(&self) {
|
||||||
@@ -182,17 +169,14 @@ api_bind_addr = "127.0.0.1:{admin_port}"
|
|||||||
.expect("Could not build garage endpoint URI")
|
.expect("Could not build garage endpoint URI")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn key(&self, maybe_name: Option<&str>) -> Key {
|
pub fn new_key(&self, name: &str) -> Key {
|
||||||
let mut key = Key::default();
|
let mut key = Key::default();
|
||||||
|
|
||||||
let mut cmd = self.command();
|
let output = self
|
||||||
let base = cmd.args(["key", "new"]);
|
.command()
|
||||||
let with_name = match maybe_name {
|
.args(["key", "new"])
|
||||||
Some(name) => base.args(["--name", name]),
|
.args(["--name", name])
|
||||||
None => base,
|
.expect_success_output("Could not create key");
|
||||||
};
|
|
||||||
|
|
||||||
let output = with_name.expect_success_output("Could not create key");
|
|
||||||
let stdout = String::from_utf8(output.stdout).unwrap();
|
let stdout = String::from_utf8(output.stdout).unwrap();
|
||||||
|
|
||||||
for line in stdout.lines() {
|
for line in stdout.lines() {
|
||||||
@@ -209,7 +193,7 @@ api_bind_addr = "127.0.0.1:{admin_port}"
|
|||||||
assert!(!key.secret.is_empty(), "Invalid key: Key secret is empty");
|
assert!(!key.secret.is_empty(), "Invalid key: Key secret is empty");
|
||||||
|
|
||||||
Key {
|
Key {
|
||||||
name: maybe_name.map(String::from),
|
name: name.to_owned(),
|
||||||
..key
|
..key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,13 @@ use custom_requester::CustomRequester;
|
|||||||
|
|
||||||
const REGION: Region = Region::from_static("garage-integ-test");
|
const REGION: Region = Region::from_static("garage-integ-test");
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
pub garage: &'static garage::Instance,
|
pub garage: &'static garage::Instance,
|
||||||
pub key: garage::Key,
|
|
||||||
pub client: Client,
|
pub client: Client,
|
||||||
pub custom_request: CustomRequester,
|
pub custom_request: CustomRequester,
|
||||||
pub k2v: K2VContext,
|
pub k2v: K2VContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct K2VContext {
|
pub struct K2VContext {
|
||||||
pub request: CustomRequester,
|
pub request: CustomRequester,
|
||||||
}
|
}
|
||||||
@@ -30,15 +27,13 @@ pub struct K2VContext {
|
|||||||
impl Context {
|
impl Context {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let garage = garage::instance();
|
let garage = garage::instance();
|
||||||
let key = garage.key(None);
|
let client = client::build_client(garage);
|
||||||
let client = client::build_client(garage, &key);
|
let custom_request = CustomRequester::new_s3(garage);
|
||||||
let custom_request = CustomRequester::new_s3(garage, &key);
|
let k2v_request = CustomRequester::new_k2v(garage);
|
||||||
let k2v_request = CustomRequester::new_k2v(garage, &key);
|
|
||||||
|
|
||||||
Context {
|
Context {
|
||||||
garage,
|
garage,
|
||||||
client,
|
client,
|
||||||
key,
|
|
||||||
custom_request,
|
custom_request,
|
||||||
k2v: K2VContext {
|
k2v: K2VContext {
|
||||||
request: k2v_request,
|
request: k2v_request,
|
||||||
@@ -62,7 +57,7 @@ impl Context {
|
|||||||
.args(["bucket", "allow"])
|
.args(["bucket", "allow"])
|
||||||
.args(["--owner", "--read", "--write"])
|
.args(["--owner", "--read", "--write"])
|
||||||
.arg(&bucket_name)
|
.arg(&bucket_name)
|
||||||
.args(["--key", &self.key.id])
|
.args(["--key", &self.garage.key.name])
|
||||||
.quiet()
|
.quiet()
|
||||||
.expect_success_status("Could not allow key for bucket");
|
.expect_success_status("Could not allow key for bucket");
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ async fn test_poll_item() {
|
|||||||
let poll = {
|
let poll = {
|
||||||
let bucket = bucket.clone();
|
let bucket = bucket.clone();
|
||||||
let ct = ct.clone();
|
let ct = ct.clone();
|
||||||
let ctx = ctx.clone();
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
let ctx = common::context();
|
||||||
ctx.k2v
|
ctx.k2v
|
||||||
.request
|
.request
|
||||||
.builder(bucket.clone())
|
.builder(bucket.clone())
|
||||||
@@ -171,8 +171,8 @@ async fn test_poll_range() {
|
|||||||
// Second poll range, which will complete later
|
// Second poll range, which will complete later
|
||||||
let poll = {
|
let poll = {
|
||||||
let bucket = bucket.clone();
|
let bucket = bucket.clone();
|
||||||
let ctx = ctx.clone();
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
let ctx = common::context();
|
||||||
ctx.k2v
|
ctx.k2v
|
||||||
.request
|
.request
|
||||||
.builder(bucket.clone())
|
.builder(bucket.clone())
|
||||||
@@ -220,8 +220,8 @@ async fn test_poll_range() {
|
|||||||
// Start a new poll operation
|
// Start a new poll operation
|
||||||
let poll = {
|
let poll = {
|
||||||
let bucket = bucket.clone();
|
let bucket = bucket.clone();
|
||||||
let ctx = ctx.clone();
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
let ctx = common::context();
|
||||||
ctx.k2v
|
ctx.k2v
|
||||||
.request
|
.request
|
||||||
.builder(bucket.clone())
|
.builder(bucket.clone())
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ async fn test_create_bucket_streaming() {
|
|||||||
ctx.garage
|
ctx.garage
|
||||||
.command()
|
.command()
|
||||||
.args(["key", "allow"])
|
.args(["key", "allow"])
|
||||||
.args(["--create-bucket", &ctx.key.id])
|
.args(["--create-bucket", &ctx.garage.key.id])
|
||||||
.quiet()
|
.quiet()
|
||||||
.expect_success_output("Could not allow key to create buckets");
|
.expect_success_output("Could not allow key to create buckets");
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ tokio = "1.24"
|
|||||||
|
|
||||||
# cli deps
|
# cli deps
|
||||||
clap = { version = "4.1", optional = true, features = ["derive", "env"] }
|
clap = { version = "4.1", optional = true, features = ["derive", "env"] }
|
||||||
garage_util = { version = "0.8.2", path = "../util", optional = true }
|
garage_util = { version = "0.8.1", path = "../util", optional = true }
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garage_model"
|
name = "garage_model"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
authors = ["Alex Auvolat <alex@adnab.me>"]
|
authors = ["Alex Auvolat <alex@adnab.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
@@ -14,11 +14,11 @@ path = "lib.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
garage_db = { version = "0.8.2", default-features = false, path = "../db" }
|
garage_db = { version = "0.8.1", default-features = false, path = "../db" }
|
||||||
garage_rpc = { version = "0.8.2", path = "../rpc" }
|
garage_rpc = { version = "0.8.1", path = "../rpc" }
|
||||||
garage_table = { version = "0.8.2", path = "../table" }
|
garage_table = { version = "0.8.1", path = "../table" }
|
||||||
garage_block = { version = "0.8.2", path = "../block" }
|
garage_block = { version = "0.8.1", path = "../block" }
|
||||||
garage_util = { version = "0.8.2", path = "../util" }
|
garage_util = { version = "0.8.1", path = "../util" }
|
||||||
|
|
||||||
async-trait = "0.1.7"
|
async-trait = "0.1.7"
|
||||||
arc-swap = "1.0"
|
arc-swap = "1.0"
|
||||||
|
|||||||
+3
-10
@@ -136,16 +136,9 @@ impl Garage {
|
|||||||
env_builder.flag(heed::flags::Flags::MdbNoSync);
|
env_builder.flag(heed::flags::Flags::MdbNoSync);
|
||||||
env_builder.flag(heed::flags::Flags::MdbNoMetaSync);
|
env_builder.flag(heed::flags::Flags::MdbNoMetaSync);
|
||||||
}
|
}
|
||||||
let db = match env_builder.open(&db_path) {
|
let db = env_builder
|
||||||
Err(heed::Error::Io(e)) if e.kind() == std::io::ErrorKind::OutOfMemory => {
|
.open(&db_path)
|
||||||
return Err(Error::Message(
|
.ok_or_message("Unable to open LMDB DB")?;
|
||||||
"OutOfMemory error while trying to open LMDB database. This can happen \
|
|
||||||
if your operating system is not allowing you to use sufficient virtual \
|
|
||||||
memory address space. Please check that no limit is set (ulimit -v). \
|
|
||||||
On 32-bit machines, you should probably switch to another database engine.".into()))
|
|
||||||
}
|
|
||||||
x => x.ok_or_message("Unable to open LMDB DB")?,
|
|
||||||
};
|
|
||||||
db::lmdb_adapter::LmdbDb::init(db)
|
db::lmdb_adapter::LmdbDb::init(db)
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "lmdb"))]
|
#[cfg(not(feature = "lmdb"))]
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ impl CountedItem for K2VItem {
|
|||||||
&self.partition.partition_key
|
&self.partition.partition_key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::bool_to_int_with_if)]
|
||||||
fn counts(&self) -> Vec<(&'static str, i64)> {
|
fn counts(&self) -> Vec<(&'static str, i64)> {
|
||||||
let values = self.values();
|
let values = self.values();
|
||||||
|
|
||||||
|
|||||||
@@ -355,6 +355,7 @@ impl CountedItem for Object {
|
|||||||
|
|
||||||
fn counts(&self) -> Vec<(&'static str, i64)> {
|
fn counts(&self) -> Vec<(&'static str, i64)> {
|
||||||
let versions = self.versions();
|
let versions = self.versions();
|
||||||
|
#[allow(clippy::bool_to_int_with_if)]
|
||||||
let n_objects = if versions.iter().any(|v| v.is_data()) {
|
let n_objects = if versions.iter().any(|v| v.is_data()) {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garage_rpc"
|
name = "garage_rpc"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
authors = ["Alex Auvolat <alex@adnab.me>"]
|
authors = ["Alex Auvolat <alex@adnab.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
@@ -14,7 +14,7 @@ path = "lib.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
garage_util = { version = "0.8.2", path = "../util" }
|
garage_util = { version = "0.8.1", path = "../util" }
|
||||||
|
|
||||||
arc-swap = "1.0"
|
arc-swap = "1.0"
|
||||||
bytes = "1.0"
|
bytes = "1.0"
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ impl SystemMetrics {
|
|||||||
.u64_value_observer("garage_build_info", move |observer| {
|
.u64_value_observer("garage_build_info", move |observer| {
|
||||||
observer.observe(
|
observer.observe(
|
||||||
1,
|
1,
|
||||||
&[
|
&[KeyValue::new(
|
||||||
KeyValue::new("rustversion", garage_util::version::rust_version()),
|
"version",
|
||||||
KeyValue::new("version", garage_util::version::garage_version()),
|
garage_util::version::garage_version(),
|
||||||
],
|
)],
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.with_description("Garage build info")
|
.with_description("Garage build info")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garage_table"
|
name = "garage_table"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
authors = ["Alex Auvolat <alex@adnab.me>"]
|
authors = ["Alex Auvolat <alex@adnab.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
@@ -14,9 +14,9 @@ path = "lib.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
garage_db = { version = "0.8.2", path = "../db" }
|
garage_db = { version = "0.8.1", path = "../db" }
|
||||||
garage_rpc = { version = "0.8.2", path = "../rpc" }
|
garage_rpc = { version = "0.8.1", path = "../rpc" }
|
||||||
garage_util = { version = "0.8.2", path = "../util" }
|
garage_util = { version = "0.8.1", path = "../util" }
|
||||||
|
|
||||||
opentelemetry = "0.17"
|
opentelemetry = "0.17"
|
||||||
|
|
||||||
|
|||||||
+2
-5
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garage_util"
|
name = "garage_util"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
authors = ["Alex Auvolat <alex@adnab.me>"]
|
authors = ["Alex Auvolat <alex@adnab.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
@@ -14,7 +14,7 @@ path = "lib.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
garage_db = { version = "0.8.2", path = "../db" }
|
garage_db = { version = "0.8.1", path = "../db" }
|
||||||
|
|
||||||
arc-swap = "1.0"
|
arc-swap = "1.0"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
@@ -47,9 +47,6 @@ hyper = "0.14"
|
|||||||
|
|
||||||
opentelemetry = { version = "0.17", features = [ "rt-tokio", "metrics", "trace" ] }
|
opentelemetry = { version = "0.17", features = [ "rt-tokio", "metrics", "trace" ] }
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
rustc_version = "0.4.0"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
mktemp = "0.5"
|
mktemp = "0.5"
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
use rustc_version::version;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// Acquire the version of Rust used to compile, this is added as a label to
|
|
||||||
// the garage_build_info metric.
|
|
||||||
let v = version().unwrap();
|
|
||||||
println!("cargo:rustc-env=RUSTC_VERSION={v}");
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
use http::{HeaderMap, HeaderValue};
|
|
||||||
use std::net::IpAddr;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use crate::error::{Error, OkOrMessage};
|
|
||||||
|
|
||||||
pub fn handle_forwarded_for_headers(headers: &HeaderMap<HeaderValue>) -> Result<String, Error> {
|
|
||||||
let forwarded_for_header = headers
|
|
||||||
.get("x-forwarded-for")
|
|
||||||
.ok_or_message("X-Forwarded-For header not provided")?;
|
|
||||||
|
|
||||||
let forwarded_for_ip_str = forwarded_for_header
|
|
||||||
.to_str()
|
|
||||||
.ok_or_message("Error parsing X-Forwarded-For header")?;
|
|
||||||
|
|
||||||
let client_ip = IpAddr::from_str(&forwarded_for_ip_str)
|
|
||||||
.ok_or_message("Valid IP address not found in X-Forwarded-For header")?;
|
|
||||||
|
|
||||||
Ok(client_ip.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_handle_forwarded_for_headers_ipv4_client() {
|
|
||||||
let mut test_headers = HeaderMap::new();
|
|
||||||
test_headers.insert("X-Forwarded-For", "192.0.2.100".parse().unwrap());
|
|
||||||
|
|
||||||
if let Ok(forwarded_ip) = handle_forwarded_for_headers(&test_headers) {
|
|
||||||
assert_eq!(forwarded_ip, "192.0.2.100");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_handle_forwarded_for_headers_ipv6_client() {
|
|
||||||
let mut test_headers = HeaderMap::new();
|
|
||||||
test_headers.insert("X-Forwarded-For", "2001:db8::f00d:cafe".parse().unwrap());
|
|
||||||
|
|
||||||
if let Ok(forwarded_ip) = handle_forwarded_for_headers(&test_headers) {
|
|
||||||
assert_eq!(forwarded_ip, "2001:db8::f00d:cafe");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_handle_forwarded_for_headers_invalid_ip() {
|
|
||||||
let mut test_headers = HeaderMap::new();
|
|
||||||
test_headers.insert("X-Forwarded-For", "www.example.com".parse().unwrap());
|
|
||||||
|
|
||||||
let result = handle_forwarded_for_headers(&test_headers);
|
|
||||||
assert!(result.is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_handle_forwarded_for_headers_missing() {
|
|
||||||
let mut test_headers = HeaderMap::new();
|
|
||||||
test_headers.insert("Host", "www.deuxfleurs.fr".parse().unwrap());
|
|
||||||
|
|
||||||
let result = handle_forwarded_for_headers(&test_headers);
|
|
||||||
assert!(result.is_err());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,6 @@ pub mod data;
|
|||||||
pub mod encode;
|
pub mod encode;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod formater;
|
pub mod formater;
|
||||||
pub mod forwarded_headers;
|
|
||||||
pub mod metrics;
|
pub mod metrics;
|
||||||
pub mod migrate;
|
pub mod migrate;
|
||||||
pub mod persister;
|
pub mod persister;
|
||||||
|
|||||||
@@ -26,7 +26,3 @@ pub fn init_version(version: &'static str) {
|
|||||||
pub fn init_features(features: &'static [&'static str]) {
|
pub fn init_features(features: &'static [&'static str]) {
|
||||||
FEATURES.store(Some(Arc::new(features)));
|
FEATURES.store(Some(Arc::new(features)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rust_version() -> &'static str {
|
|
||||||
env!("RUSTC_VERSION")
|
|
||||||
}
|
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "garage_web"
|
name = "garage_web"
|
||||||
version = "0.8.2"
|
version = "0.8.1"
|
||||||
authors = ["Alex Auvolat <alex@adnab.me>", "Quentin Dufour <quentin@dufour.io>"]
|
authors = ["Alex Auvolat <alex@adnab.me>", "Quentin Dufour <quentin@dufour.io>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
@@ -14,10 +14,10 @@ path = "lib.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
garage_api = { version = "0.8.2", path = "../api" }
|
garage_api = { version = "0.8.1", path = "../api" }
|
||||||
garage_model = { version = "0.8.2", path = "../model" }
|
garage_model = { version = "0.8.1", path = "../model" }
|
||||||
garage_util = { version = "0.8.2", path = "../util" }
|
garage_util = { version = "0.8.1", path = "../util" }
|
||||||
garage_table = { version = "0.8.2", path = "../table" }
|
garage_table = { version = "0.8.1", path = "../table" }
|
||||||
|
|
||||||
err-derive = "0.3"
|
err-derive = "0.3"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|||||||
+1
-14
@@ -29,7 +29,6 @@ use garage_model::garage::Garage;
|
|||||||
|
|
||||||
use garage_table::*;
|
use garage_table::*;
|
||||||
use garage_util::error::Error as GarageError;
|
use garage_util::error::Error as GarageError;
|
||||||
use garage_util::forwarded_headers;
|
|
||||||
use garage_util::metrics::{gen_trace_id, RecordDuration};
|
use garage_util::metrics::{gen_trace_id, RecordDuration};
|
||||||
|
|
||||||
struct WebMetrics {
|
struct WebMetrics {
|
||||||
@@ -105,19 +104,7 @@ impl WebServer {
|
|||||||
req: Request<Body>,
|
req: Request<Body>,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
) -> Result<Response<Body>, Infallible> {
|
) -> Result<Response<Body>, Infallible> {
|
||||||
if let Ok(forwarded_for_ip_addr) =
|
info!("{} {} {}", addr, req.method(), req.uri());
|
||||||
forwarded_headers::handle_forwarded_for_headers(&req.headers())
|
|
||||||
{
|
|
||||||
info!(
|
|
||||||
"{} (via {}) {} {}",
|
|
||||||
forwarded_for_ip_addr,
|
|
||||||
addr,
|
|
||||||
req.method(),
|
|
||||||
req.uri()
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
info!("{} {} {}", addr, req.method(), req.uri());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lots of instrumentation
|
// Lots of instrumentation
|
||||||
let tracer = opentelemetry::global::tracer("garage");
|
let tracer = opentelemetry::global::tracer("garage");
|
||||||
|
|||||||
Reference in New Issue
Block a user