Compare commits

..

36 Commits

Author SHA1 Message Date
Alex Auvolat a1cec2cd60 Split format_table into separate crate and reduce k2v-client dependencies 2023-05-17 13:01:37 +02:00
Alex b66f247580 Merge pull request 'fixes to K2V client' (#571) from k2v-client-fixes into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/571
2023-05-16 20:20:31 +00:00
Alex Auvolat 16f2a32bb7 cargo fmt 2023-05-16 19:46:57 +02:00
Alex Auvolat 472444ed8e k2v-client 0.0.2 2023-05-16 19:46:57 +02:00
Alex Auvolat bb03805b58 k2v-cli: fix sort_key being partition_key and specify which key 2023-05-16 19:46:57 +02:00
Alex Auvolat e4f955d672 fix base64 uses 2023-05-16 19:46:56 +02:00
Alex ea9b15f669 Merge pull request 'cargo: tokio-1.28 and hyper-0.14.26 update' (#569) from jpds/garage:tokio-1.28 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/569
2023-05-11 10:16:33 +00:00
Alex Auvolat 2e6bb3f766 update Cargo.nix 2023-05-11 11:34:18 +02:00
Alex 375270afd1 Merge pull request '*: apply clippy recommendations.' (#570) from jpds/garage:clippy-fixes into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/570
2023-05-11 09:33:03 +00:00
Jonathan Davies c783194e8b *: apply clippy recommendations. 2023-05-09 20:49:34 +01:00
Jonathan Davies fdcd7dee5a Cargo.lock: Updated for:
* tokio 1.28
 * hyper 0.14.26
2023-05-09 14:43:52 +01:00
Jonathan Davies 0f0795103d block/Cargo.toml: Bump tokio-util to 0.7. 2023-05-09 14:33:21 +01:00
Jonathan Davies c9d26e8c50 k2v-client/Cargo.toml: Make tokio dep match other packages. 2023-05-09 14:33:00 +01:00
Alex b925f53dc3 Merge pull request 'move git-version dependency to main crate to reduce rebuilds' (#568) from move-git-version into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/568
2023-05-09 09:53:33 +00:00
Alex 2f495575d8 Merge pull request 'block/manager.rs: Prioritize raw blocks when no compression configured' (#566) from jpds/garage:skip-compressed-blocks-scrub-no-compression into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/566
2023-05-09 09:39:48 +00:00
Alex Auvolat 9e0a9c1c15 move git-version dependency to main crate to reduce rebuilds 2023-05-09 11:35:32 +02:00
Jonathan Davies 9c788059e2 block/manager.rs: In is_block_compressed - check which compression_level
is configured on a node and check for raw block first if compression is
disabled (to help reduce syscalls during a scrub).
2023-05-09 10:28:19 +01:00
Alex 5684e1990c Merge pull request 'Really allow to disable sled feature' (#563) from jirutka/garage:workspace-deps into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/563
2023-05-09 09:08:35 +00:00
Alex 14c50f2f84 Merge pull request 'Fix undefined macro warn! on 32-bit' (#562) from jirutka/garage:fix-undefined-warn into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/562
2023-05-09 08:52:11 +00:00
Alex 0fab9c3b8c Merge pull request 'Helm: Include newer config parameters as values' (#565) from jonatan/garage:main into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/565
2023-05-09 08:49:00 +00:00
Jakub Jirutka 75759a163c Allow to really disable sled feature 2023-05-09 08:46:15 +00:00
Jakub Jirutka d2deee0b8b Declare garage crates using workspace.dependencies
This will allow to really disable "sled" feature without declaring
`default-features = false` in every Cargo.toml where garage_db and
garage_model is used.

See https://doc.rust-lang.org/cargo/reference/workspaces.html#the-dependencies-table
2023-05-09 08:46:15 +00:00
Alex 8499cd5c21 Merge pull request 'Remove unnecessary/unused "timeago" features' (#559) from jirutka/garage:timeago-features into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/559
2023-05-09 08:44:22 +00:00
Jonatan Steuernagel 4ea7983093 Helm: Increment patch version 2023-05-08 08:03:21 +02:00
Jonatan Steuernagel d5e39d11eb Helm: Include newer config parameters as values
Add all missing parameters from the reference manual.
Primarily to enable the use of the new lmdb engine
2023-05-08 07:47:31 +02:00
Jakub Jirutka 6d3ace1ea9 Fix undefined macro warn! on 32-bit
Compiling garage_db v0.8.2 (garage-0.8.2/src/db)
    error: cannot find macro `warn` in this scope
       --> src/db/lmdb_adapter.rs:352:2
        |
    352 |     warn!("LMDB is not recommended on 32-bit systems, database size will be limited");
        |     ^^^^
        |
        = help: consider importing this macro:
                tracing::warn
        = note: `warn` is in scope, but it is an attribute: `#[warn]`
    error: could not compile `garage_db` due to previous error
2023-05-07 17:01:44 +02:00
Jakub Jirutka 833cf082da Remove unnecessary/unused "timeago" features
To decrease dependency bloat and binary size.
2023-05-07 01:03:54 +02:00
Alex 1ecd88c01f Merge pull request 'Update rust toolchain to 1.68 and simplify Nix stuff' (#554) from nix-update-simplify into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/554
2023-04-25 14:56:49 +00:00
Alex Auvolat 5efcdc0de3 Update rust toolchain to 1.68 and simplify Nix stuff 2023-04-25 14:46:47 +02:00
Alex a16eb7e4b8 Merge pull request 'api/Cargo.toml: Bumped quick-xml to version 0.26.' (#552) from jpds/garage:quick-xml-0.26 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/552
2023-04-24 09:00:00 +00:00
Alex 6742070517 Merge pull request 'block/repair.rs: Added log entries for scrub start/finish.' (#551) from jpds/garage:scrub-log into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/551
2023-04-24 08:29:36 +00:00
Alex Auvolat 6894878146 update cargo.nix 2023-04-24 10:26:14 +02:00
Alex 02b0ba5f44 Merge pull request 'cookbook/real-world: fix typo' (#549) from yuka/garage:main into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/549
2023-04-24 08:24:55 +00:00
Jonathan Davies fb3bd11dce block/repair.rs: Added log entries for scrub start/finish. 2023-04-23 22:22:26 +01:00
Jonathan Davies c168383113 api/Cargo.toml: Bumped quick-xml to version 0.26. 2023-04-23 20:14:28 +01:00
yuka 04a0063df9 cookbook/real-world: fix typo 2023-04-21 16:46:58 +00:00
48 changed files with 1508 additions and 1051 deletions
Generated
+332 -198
View File
File diff suppressed because it is too large Load Diff
+840 -643
View File
File diff suppressed because it is too large Load Diff
+12
View File
@@ -11,10 +11,22 @@ members = [
"src/web", "src/web",
"src/garage", "src/garage",
"src/k2v-client", "src/k2v-client",
"src/format-table",
] ]
default-members = ["src/garage"] default-members = ["src/garage"]
[workspace.dependencies]
format_table = { version = "0.1.0", path = "src/format-table" }
garage_api = { version = "0.8.2", path = "src/api" }
garage_block = { version = "0.8.2", path = "src/block" }
garage_db = { version = "0.8.2", path = "src/db", default-features = false }
garage_model = { version = "0.8.2", path = "src/model", default-features = false }
garage_rpc = { version = "0.8.2", path = "src/rpc" }
garage_table = { version = "0.8.2", path = "src/table" }
garage_util = { version = "0.8.2", path = "src/util" }
garage_web = { version = "0.8.2", path = "src/web" }
[profile.dev] [profile.dev]
lto = "off" lto = "off"
+1 -1
View File
@@ -349,5 +349,5 @@ and is covered in the [quick start guide](@/documentation/quick-start/_index.md)
Remember also that the CLI is self-documented thanks to the `--help` flag and Remember also that the CLI is self-documented thanks to the `--help` flag and
the `help` subcommand (e.g. `garage help`, `garage key --help`). the `help` subcommand (e.g. `garage help`, `garage key --help`).
Configuring S3-compatible applicatiosn to interact with Garage Configuring S3-compatible applications to interact with Garage
is covered in the [Integrations](@/documentation/connect/_index.md) section. is covered in the [Integrations](@/documentation/connect/_index.md) section.
Generated
+76 -23
View File
@@ -41,12 +41,15 @@
} }
}, },
"flake-utils": { "flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": { "locked": {
"lastModified": 1659877975, "lastModified": 1681202837,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -56,12 +59,15 @@
} }
}, },
"flake-utils_2": { "flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": { "locked": {
"lastModified": 1667395993, "lastModified": 1681202837,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -72,44 +78,61 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1665657542, "lastModified": 1682109806,
"narHash": "sha256-mojxNyzbvmp8NtVtxqiHGhRfjCALLfk9i/Uup68Y5q8=", "narHash": "sha256-d9g7RKNShMLboTWwukM+RObDWWpHKaqTYXB48clBWXI=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a3073c49bc0163fea6a121c276f526837672b555", "rev": "2362848adf8def2866fabbffc50462e929d7fffb",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1682423271,
"narHash": "sha256-WHhl1GiOij1ob4cTLL+yhqr+vFOUH8E5wAX8Ir8fvjE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "94517a501434a627c5d9e72ac6e7f26174b978d3",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a3073c49bc0163fea6a121c276f526837672b555", "rev": "94517a501434a627c5d9e72ac6e7f26174b978d3",
"type": "github" "type": "github"
} }
}, },
"root": { "root": {
"inputs": { "inputs": {
"cargo2nix": "cargo2nix", "cargo2nix": "cargo2nix",
"flake-utils": "flake-utils_2", "flake-compat": [
"nixpkgs": "nixpkgs" "cargo2nix",
} "flake-compat"
}, ],
"rust-overlay": {
"inputs": {
"flake-utils": [ "flake-utils": [
"cargo2nix", "cargo2nix",
"flake-utils" "flake-utils"
], ],
"nixpkgs": [ "nixpkgs": "nixpkgs_2"
"cargo2nix", }
"nixpkgs" },
] "rust-overlay": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1664247556, "lastModified": 1682389182,
"narHash": "sha256-J4vazHU3609ekn7dr+3wfqPo5WGlZVAgV7jfux352L0=", "narHash": "sha256-8t2nmFnH+8V48+IJsf8AK51ebXNlVbOSVYOpiqJKvJE=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "524db9c9ea7bc7743bb74cdd45b6d46ea3fcc2ab", "rev": "74f1a64dd28faeeb85ef081f32cad2989850322c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -117,6 +140,36 @@
"repo": "rust-overlay", "repo": "rust-overlay",
"type": "github" "type": "github"
} }
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",
+17 -3
View File
@@ -2,16 +2,30 @@
description = description =
"Garage, an S3-compatible distributed object store for self-hosted deployments"; "Garage, an S3-compatible distributed object store for self-hosted deployments";
# Nixpkgs unstable as of 2023-04-25, has rustc v1.68
inputs.nixpkgs.url = inputs.nixpkgs.url =
"github:NixOS/nixpkgs/a3073c49bc0163fea6a121c276f526837672b555"; "github:NixOS/nixpkgs/94517a501434a627c5d9e72ac6e7f26174b978d3";
inputs.cargo2nix = { inputs.cargo2nix = {
# As of 2022-10-18: two small patches over unstable branch, one for clippy and one to fix feature detection # As of 2022-10-18: two small patches over unstable branch, one for clippy and one to fix feature detection
url = "github:Alexis211/cargo2nix/a7a61179b66054904ef6a195d8da736eaaa06c36"; url = "github:Alexis211/cargo2nix/a7a61179b66054904ef6a195d8da736eaaa06c36";
# As of 2023-04-25:
# - my two patches were merged into unstable (one for clippy and one to "fix" feature detection)
# - rustc v1.66
# url = "github:cargo2nix/cargo2nix/8fb57a670f7993bfc24099c33eb9c5abb51f29a2";
# Rust overlay as of 2023-04-25
inputs.rust-overlay.url =
"github:oxalica/rust-overlay/74f1a64dd28faeeb85ef081f32cad2989850322c";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, cargo2nix, flake-utils }: inputs.flake-utils.follows = "cargo2nix/flake-utils";
inputs.flake-compat.follows = "cargo2nix/flake-compat";
outputs = { self, nixpkgs, cargo2nix, flake-utils, ... }:
let let
git_version = self.lastModifiedDate; git_version = self.lastModifiedDate;
compile = import ./nix/compile.nix; compile = import ./nix/compile.nix;
+10 -15
View File
@@ -1,19 +1,14 @@
rec { let
# * Fixed dependencies lock = builtins.fromJSON (builtins.readFile ../flake.lock);
pkgsSrc = fetchTarball { flakeCompatRev = lock.nodes.flake-compat.locked.rev;
# As of 2022-10-13 flakeCompat = fetchTarball {
url = url =
"https://github.com/NixOS/nixpkgs/archive/a3073c49bc0163fea6a121c276f526837672b555.zip"; "https://github.com/edolstra/flake-compat/archive/${flakeCompatRev}.tar.gz";
sha256 = "1bz632psfbpmicyzjb8b4265y50shylccvfm6ry6mgnv5hvz324s"; sha256 = lock.nodes.flake-compat.locked.narHash;
}; };
cargo2nixSrc = fetchGit { flake = ((import flakeCompat) { src = ../.; }).defaultNix;
# As of 2022-10-18: two small patches over unstable branch, one for clippy and one to fix feature detection in rec {
url = "https://github.com/Alexis211/cargo2nix"; pkgsSrc = flake.inputs.nixpkgs;
ref = "custom_unstable"; cargo2nix = flake.inputs.cargo2nix;
rev = "a7a61179b66054904ef6a195d8da736eaaa06c36";
};
# * Shared objects
cargo2nix = import cargo2nixSrc;
cargo2nixOverlay = cargo2nix.overlays.default; cargo2nixOverlay = cargo2nix.overlays.default;
} }
+1 -1
View File
@@ -32,7 +32,7 @@ let
*/ */
toolchainOptions = if target == null || target == "x86_64-unknown-linux-musl" toolchainOptions = if target == null || target == "x86_64-unknown-linux-musl"
|| target == "aarch64-unknown-linux-musl" then { || target == "aarch64-unknown-linux-musl" then {
rustVersion = "1.63.0"; rustVersion = "1.68.0";
extraRustComponents = [ "clippy" ]; extraRustComponents = [ "clippy" ];
} else { } else {
rustToolchain = pkgs.symlinkJoin { rustToolchain = pkgs.symlinkJoin {
+2 -2
View File
@@ -1,13 +1,13 @@
pkgs: pkgs:
pkgs.buildGoModule rec { pkgs.buildGoModule rec {
pname = "kaniko"; pname = "kaniko";
version = "1.6.0"; version = "1.9.2";
src = pkgs.fetchFromGitHub { src = pkgs.fetchFromGitHub {
owner = "GoogleContainerTools"; owner = "GoogleContainerTools";
repo = "kaniko"; repo = "kaniko";
rev = "v${version}"; rev = "v${version}";
sha256 = "1fnclr556avxay6pvgw5ya3xbxfnf2gv4njq2hr4fd6fcjyslq5h"; sha256 = "dXQ0/o1qISv+sjNVIpfF85bkbM9sGOGwqVbWZpMWfMY=";
}; };
vendorSha256 = null; vendorSha256 = null;
+1 -1
View File
@@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes # This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version. # to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/) # Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.4.0 version: 0.4.1
# This is the version number of the application being deployed. This version number should be # This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to # incremented each time you make changes to the application. Versions are not expected to
+31 -1
View File
@@ -4,9 +4,28 @@
# Garage configuration. These values go to garage.toml # Garage configuration. These values go to garage.toml
garage: garage:
# Can be changed for better performance on certain systems
# https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#db-engine-since-v0-8-0
dbEngine: "sled"
# Defaults is 1MB
# An increase can result in better performance in certain scenarios
# https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#block-size
blockSize: "1048576"
# Tuning parameters for the sled DB engine
# https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#sled-cache-capacity
sledCacheCapacity: "134217728"
sledFlushEveryMs: "2000"
# Default to 3 replicas, see the replication_mode section at # Default to 3 replicas, see the replication_mode section at
# https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/ # https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#replication-mode
replicationMode: "3" replicationMode: "3"
# zstd compression level of stored blocks
# https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#compression-level
compressionLevel: "1"
rpcBindAddr: "[::]:3901" rpcBindAddr: "[::]:3901"
# If not given, a random secret will be generated and stored in a Secret object # If not given, a random secret will be generated and stored in a Secret object
rpcSecret: "" rpcSecret: ""
@@ -27,8 +46,19 @@ garage:
metadata_dir = "/mnt/meta" metadata_dir = "/mnt/meta"
data_dir = "/mnt/data" data_dir = "/mnt/data"
db_engine = "{{ .Values.garage.dbEngine }}"
block_size = {{ .Values.garage.blockSize }}
{{- if eq .Values.garage.dbEngine "sled"}}
sled_cache_capacity = {{ .Values.garage.sledCacheCapacity }}
sled_flush_every_ms = {{ .Values.garage.sledFlushEveryMs }}
{{- end }}
replication_mode = "{{ .Values.garage.replicationMode }}" replication_mode = "{{ .Values.garage.replicationMode }}"
compression_level = {{ .Values.garage.compressionLevel }}
rpc_bind_addr = "{{ .Values.garage.rpcBindAddr }}" rpc_bind_addr = "{{ .Values.garage.rpcBindAddr }}"
# rpc_secret will be populated by the init container from a k8s secret object # rpc_secret will be populated by the init container from a k8s secret object
rpc_secret = "__RPC_SECRET_REPLACE__" rpc_secret = "__RPC_SECRET_REPLACE__"
+6 -6
View File
@@ -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.workspace = true
garage_table = { version = "0.8.2", path = "../table" } garage_table.workspace = true
garage_block = { version = "0.8.2", path = "../block" } garage_block.workspace = true
garage_util = { version = "0.8.2", path = "../util" } garage_util.workspace = true
garage_rpc = { version = "0.8.2", path = "../rpc" } garage_rpc.workspace = true
async-trait = "0.1.7" async-trait = "0.1.7"
base64 = "0.21" base64 = "0.21"
@@ -51,7 +51,7 @@ roxmltree = "0.14"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_bytes = "0.11" serde_bytes = "0.11"
serde_json = "1.0" serde_json = "1.0"
quick-xml = { version = "0.21", features = [ "serialize" ] } quick-xml = { version = "0.26", features = [ "serialize" ] }
url = "2.3" url = "2.3"
opentelemetry = "0.17" opentelemetry = "0.17"
+1 -1
View File
@@ -105,7 +105,7 @@ impl AdminApiServer {
let bucket_id = self let bucket_id = self
.garage .garage
.bucket_helper() .bucket_helper()
.resolve_global_bucket_name(&domain) .resolve_global_bucket_name(domain)
.await? .await?
.ok_or(HelperError::NoSuchBucket(domain.to_string()))?; .ok_or(HelperError::NoSuchBucket(domain.to_string()))?;
+2 -2
View File
@@ -183,8 +183,8 @@ async fn bucket_info_results(
} }
}), }),
keys: relevant_keys keys: relevant_keys
.into_iter() .into_values()
.map(|(_, key)| { .map(|key| {
let p = key.state.as_option().unwrap(); let p = key.state.as_option().unwrap();
GetBucketInfoKey { GetBucketInfoKey {
access_key_id: key.key_id, access_key_id: key.key_id,
+2 -2
View File
@@ -183,8 +183,8 @@ async fn key_info_results(garage: &Arc<Garage>, key: Key) -> Result<Response<Bod
create_bucket: *key_state.allow_create_bucket.get(), create_bucket: *key_state.allow_create_bucket.get(),
}, },
buckets: relevant_buckets buckets: relevant_buckets
.into_iter() .into_values()
.map(|(_, bucket)| { .map(|bucket| {
let state = bucket.state.as_option().unwrap(); let state = bucket.state.as_option().unwrap();
KeyInfoBucketResult { KeyInfoBucketResult {
id: hex::encode(bucket.id), id: hex::encode(bucket.id),
+1 -1
View File
@@ -128,7 +128,7 @@ impl<A: ApiHandler> ApiServer<A> {
let uri = req.uri().clone(); let uri = req.uri().clone();
if let Ok(forwarded_for_ip_addr) = if let Ok(forwarded_for_ip_addr) =
forwarded_headers::handle_forwarded_for_headers(&req.headers()) forwarded_headers::handle_forwarded_for_headers(req.headers())
{ {
info!( info!(
"{} (via {}) {} {}", "{} (via {}) {} {}",
+2 -2
View File
@@ -282,8 +282,8 @@ pub(crate) async fn handle_poll_range(
if let Some((items, seen_marker)) = resp { if let Some((items, seen_marker)) = resp {
let resp = PollRangeResponse { let resp = PollRangeResponse {
items: items items: items
.into_iter() .into_values()
.map(|(_k, i)| ReadBatchResponseItem::from(i)) .map(ReadBatchResponseItem::from)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
seen_marker, seen_marker,
}; };
+2 -2
View File
@@ -443,7 +443,7 @@ fn body_from_blocks_range(
// block.part_number, which is not the same in the case of a multipart upload) // block.part_number, which is not the same in the case of a multipart upload)
let mut blocks: Vec<(VersionBlock, u64)> = Vec::with_capacity(std::cmp::min( let mut blocks: Vec<(VersionBlock, u64)> = Vec::with_capacity(std::cmp::min(
all_blocks.len(), all_blocks.len(),
4 + ((end - begin) / std::cmp::max(all_blocks[0].1.size as u64, 1024)) as usize, 4 + ((end - begin) / std::cmp::max(all_blocks[0].1.size, 1024)) as usize,
)); ));
let mut block_offset: u64 = 0; let mut block_offset: u64 = 0;
for (_, b) in all_blocks.iter() { for (_, b) in all_blocks.iter() {
@@ -454,7 +454,7 @@ fn body_from_blocks_range(
if block_offset < end && block_offset + b.size > begin { if block_offset < end && block_offset + b.size > begin {
blocks.push((*b, block_offset)); blocks.push((*b, block_offset));
} }
block_offset += b.size as u64; block_offset += b.size;
} }
let order_stream = OrderTag::stream(); let order_stream = OrderTag::stream();
+5 -5
View File
@@ -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.workspace = true
garage_rpc = { version = "0.8.2", path = "../rpc" } garage_rpc.workspace = true
garage_util = { version = "0.8.2", path = "../util" } garage_util.workspace = true
garage_table = { version = "0.8.2", path = "../table" } garage_table.workspace = true
opentelemetry = "0.17" opentelemetry = "0.17"
@@ -37,7 +37,7 @@ serde_bytes = "0.11"
futures = "0.3" futures = "0.3"
futures-util = "0.3" futures-util = "0.3"
tokio = { version = "1.0", default-features = false, features = ["rt", "rt-multi-thread", "io-util", "net", "time", "macros", "sync", "signal", "fs"] } tokio = { version = "1.0", default-features = false, features = ["rt", "rt-multi-thread", "io-util", "net", "time", "macros", "sync", "signal", "fs"] }
tokio-util = { version = "0.6", features = ["io"] } tokio-util = { version = "0.7", features = ["io"] }
[features] [features]
system-libs = [ "zstd/pkg-config" ] system-libs = [ "zstd/pkg-config" ]
+25 -5
View File
@@ -600,12 +600,32 @@ impl BlockManager {
/// Utility: check if block is stored compressed. Error if block is not stored /// Utility: check if block is stored compressed. Error if block is not stored
async fn is_block_compressed(&self, hash: &Hash) -> Result<bool, Error> { async fn is_block_compressed(&self, hash: &Hash) -> Result<bool, Error> {
let mut path = self.block_path(hash); let mut path = self.block_path(hash);
path.set_extension("zst");
if fs::metadata(&path).await.is_ok() { // If compression is disabled on node - check for the raw block
return Ok(true); // first and then a compressed one (as compression may have been
// previously enabled).
match self.compression_level {
None => {
if fs::metadata(&path).await.is_ok() {
return Ok(false);
}
path.set_extension("zst");
fs::metadata(&path).await.map(|_| true).map_err(Into::into)
}
_ => {
path.set_extension("zst");
if fs::metadata(&path).await.is_ok() {
return Ok(true);
}
path.set_extension("");
fs::metadata(&path).await.map(|_| false).map_err(Into::into)
}
} }
path.set_extension("");
fs::metadata(&path).await.map(|_| false).map_err(Into::into)
} }
async fn lock_mutate(&self, hash: &Hash) -> MutexGuard<'_, BlockManagerLocked> { async fn lock_mutate(&self, hash: &Hash) -> MutexGuard<'_, BlockManagerLocked> {
+16 -12
View File
@@ -220,14 +220,12 @@ fn randomize_next_scrub_run_time(timestamp: u64) -> u64 {
// Take SCRUB_INTERVAL and mix in a random interval of 10 days to attempt to // Take SCRUB_INTERVAL and mix in a random interval of 10 days to attempt to
// balance scrub load across different cluster nodes. // balance scrub load across different cluster nodes.
let next_run_timestamp = timestamp timestamp
+ SCRUB_INTERVAL + SCRUB_INTERVAL
.saturating_add(Duration::from_secs( .saturating_add(Duration::from_secs(
rand::thread_rng().gen_range(0..3600 * 24 * 10), rand::thread_rng().gen_range(0..3600 * 24 * 10),
)) ))
.as_millis() as u64; .as_millis() as u64
next_run_timestamp
} }
impl Default for ScrubWorkerPersisted { impl Default for ScrubWorkerPersisted {
@@ -241,18 +239,14 @@ impl Default for ScrubWorkerPersisted {
} }
} }
#[derive(Default)]
enum ScrubWorkerState { enum ScrubWorkerState {
Running(BlockStoreIterator), Running(BlockStoreIterator),
Paused(BlockStoreIterator, u64), // u64 = time when to resume scrub Paused(BlockStoreIterator, u64), // u64 = time when to resume scrub
#[default]
Finished, Finished,
} }
impl Default for ScrubWorkerState {
fn default() -> Self {
ScrubWorkerState::Finished
}
}
#[derive(Debug)] #[derive(Debug)]
pub enum ScrubWorkerCommand { pub enum ScrubWorkerCommand {
Start, Start,
@@ -281,6 +275,7 @@ impl ScrubWorker {
ScrubWorkerCommand::Start => { ScrubWorkerCommand::Start => {
self.work = match std::mem::take(&mut self.work) { self.work = match std::mem::take(&mut self.work) {
ScrubWorkerState::Finished => { ScrubWorkerState::Finished => {
info!("Scrub worker initializing, now performing datastore scrub");
let iterator = BlockStoreIterator::new(&self.manager); let iterator = BlockStoreIterator::new(&self.manager);
ScrubWorkerState::Running(iterator) ScrubWorkerState::Running(iterator)
} }
@@ -394,12 +389,21 @@ 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 {
let now = now_msec();
let next_scrub_timestamp = randomize_next_scrub_run_time(now);
self.persister.set_with(|p| { self.persister.set_with(|p| {
p.time_last_complete_scrub = now_msec(); p.time_last_complete_scrub = now;
p.time_next_run_scrub = randomize_next_scrub_run_time(now_msec()); p.time_next_run_scrub = next_scrub_timestamp;
})?; })?;
self.work = ScrubWorkerState::Finished; self.work = ScrubWorkerState::Finished;
self.tranquilizer.clear(); self.tranquilizer.clear();
info!(
"Datastore scrub completed, next scrub scheduled for {}",
msec_to_rfc3339(next_scrub_timestamp)
);
Ok(WorkerState::Idle) Ok(WorkerState::Idle)
} }
} }
+1 -1
View File
@@ -349,6 +349,6 @@ pub fn recommended_map_size() -> usize {
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
pub fn recommended_map_size() -> usize { pub fn recommended_map_size() -> usize {
warn!("LMDB is not recommended on 32-bit systems, database size will be limited"); tracing::warn!("LMDB is not recommended on 32-bit systems, database size will be limited");
1usize << 30 1usize << 30
} }
+12
View File
@@ -0,0 +1,12 @@
[package]
name = "format_table"
version = "0.1.0"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
description = "Format tables with a stupid API"
repository = "https://git.deuxfleurs.fr/Deuxfleurs/garage"
readme = "README.md"
[lib]
path = "lib.rs"
+13
View File
@@ -0,0 +1,13 @@
# `format_table`
Format tables with a stupid API. [Documentation](https://docs.rs/format_table).
Example:
```rust
let mut table = vec!["product\tquantity\tprice".to_string()];
for (p, q, r) in [("tomato", 12, 15), ("potato", 10, 20), ("rice", 5, 12)] {
table.push(format!("{}\t{}\t{}", p, q, r));
}
format_table::format_table(table);
```
@@ -1,3 +1,19 @@
//! Format tables with a stupid API.
//!
//! Example:
//!
//! ```rust
//! let mut table = vec!["product\tquantity\tprice".to_string()];
//! for (p, q, r) in [("tomato", 12, 15), ("potato", 10, 20), ("rice", 5, 12)] {
//! table.push(format!("{}\t{}\t{}", p, q, r));
//! }
//! format_table::format_table(table);
//! ```
//!
//! A table to be formatted is a `Vec<String>`, containing one string per line.
//! Table columns in each line are separated by a `\t` character.
/// Format a table and return the result as a string.
pub fn format_table_to_string(data: Vec<String>) -> String { pub fn format_table_to_string(data: Vec<String>) -> String {
let data = data let data = data
.iter() .iter()
@@ -27,6 +43,7 @@ pub fn format_table_to_string(data: Vec<String>) -> String {
out out
} }
/// Format a table and print the result to stdout.
pub fn format_table(data: Vec<String>) { pub fn format_table(data: Vec<String>) {
print!("{}", format_table_to_string(data)); print!("{}", format_table_to_string(data));
} }
+11 -9
View File
@@ -21,19 +21,20 @@ 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" } format_table.workspace = true
garage_api = { version = "0.8.2", path = "../api" } garage_db.workspace = true
garage_block = { version = "0.8.2", path = "../block" } garage_api.workspace = true
garage_model = { version = "0.8.2", path = "../model" } garage_block.workspace = true
garage_rpc = { version = "0.8.2", path = "../rpc" } garage_model.workspace = true
garage_table = { version = "0.8.2", path = "../table" } garage_rpc.workspace = true
garage_util = { version = "0.8.2", path = "../util" } garage_table.workspace = true
garage_web = { version = "0.8.2", path = "../web" } garage_util.workspace = true
garage_web.workspace = true
backtrace = "0.3" backtrace = "0.3"
bytes = "1.0" bytes = "1.0"
bytesize = "1.1" bytesize = "1.1"
timeago = "0.4" timeago = { version = "0.4", default-features = false }
parse_duration = "2.1" parse_duration = "2.1"
hex = "0.4" hex = "0.4"
tracing = { version = "0.1" } tracing = { version = "0.1" }
@@ -41,6 +42,7 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
rand = "0.8" rand = "0.8"
async-trait = "0.1.7" async-trait = "0.1.7"
sodiumoxide = { version = "0.2.5-0", package = "kuska-sodiumoxide" } sodiumoxide = { version = "0.2.5-0", package = "kuska-sodiumoxide" }
git-version = "0.3.4"
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] } serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
serde_bytes = "0.11" serde_bytes = "0.11"
+1 -1
View File
@@ -5,11 +5,11 @@ use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use format_table::format_table_to_string;
use garage_util::background::BackgroundRunner; use garage_util::background::BackgroundRunner;
use garage_util::crdt::*; use garage_util::crdt::*;
use garage_util::data::*; use garage_util::data::*;
use garage_util::error::Error as GarageError; use garage_util::error::Error as GarageError;
use garage_util::formater::format_table_to_string;
use garage_util::time::*; use garage_util::time::*;
use garage_table::replication::*; use garage_table::replication::*;
+1 -1
View File
@@ -1,8 +1,8 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::time::Duration; use std::time::Duration;
use format_table::format_table;
use garage_util::error::*; use garage_util::error::*;
use garage_util::formater::format_table;
use garage_rpc::layout::*; use garage_rpc::layout::*;
use garage_rpc::system::*; use garage_rpc::system::*;
+1 -1
View File
@@ -1,6 +1,6 @@
use format_table::format_table;
use garage_util::crdt::Crdt; use garage_util::crdt::Crdt;
use garage_util::error::*; use garage_util::error::*;
use garage_util::formater::format_table;
use garage_rpc::layout::*; use garage_rpc::layout::*;
use garage_rpc::system::*; use garage_rpc::system::*;
+1 -1
View File
@@ -1,11 +1,11 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::time::Duration; use std::time::Duration;
use format_table::format_table;
use garage_util::background::*; use garage_util::background::*;
use garage_util::crdt::*; use garage_util::crdt::*;
use garage_util::data::*; use garage_util::data::*;
use garage_util::error::*; use garage_util::error::*;
use garage_util::formater::format_table;
use garage_util::time::*; use garage_util::time::*;
use garage_block::manager::BlockResyncErrorInfo; use garage_block::manager::BlockResyncErrorInfo;
+6
View File
@@ -108,6 +108,12 @@ async fn main() {
][..]; ][..];
if let Some(git_version) = option_env!("GIT_VERSION") { if let Some(git_version) = option_env!("GIT_VERSION") {
garage_util::version::init_version(git_version); garage_util::version::init_version(git_version);
} else {
garage_util::version::init_version(git_version::git_version!(
prefix = "git:",
cargo_prefix = "cargo:",
fallback = "unknown"
));
} }
garage_util::version::init_features(features); garage_util::version::init_features(features);
+4 -4
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "k2v-client" name = "k2v-client"
version = "0.1.1" version = "0.0.2"
authors = ["Trinity Pointard <trinity.pointard@gmail.com>", "Alex Auvolat <alex@adnab.me>"] authors = ["Trinity Pointard <trinity.pointard@gmail.com>", "Alex Auvolat <alex@adnab.me>"]
edition = "2018" edition = "2018"
license = "AGPL-3.0" license = "AGPL-3.0"
@@ -19,15 +19,15 @@ hyper-rustls = { version = "0.23", default-features = false, features = [ "http1
serde = "1.0" serde = "1.0"
serde_json = "1.0" serde_json = "1.0"
thiserror = "1.0" thiserror = "1.0"
tokio = "1.24" tokio = { version = "1.0", default-features = false, features = ["rt", "rt-multi-thread", "io-util", "net", "time", "macros", "sync", "signal", "fs"] }
# 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 } format_table = { workspace = true, optional = true }
[features] [features]
cli = ["clap", "tokio/fs", "tokio/io-std", "garage_util"] cli = ["clap", "tokio/fs", "tokio/io-std", "format_table"]
[lib] [lib]
path = "lib.rs" path = "lib.rs"
+12 -8
View File
@@ -2,9 +2,11 @@ use std::collections::BTreeMap;
use std::process::exit; use std::process::exit;
use std::time::Duration; use std::time::Duration;
use base64::prelude::*;
use k2v_client::*; use k2v_client::*;
use garage_util::formater::format_table; use format_table::format_table;
use rusoto_core::credential::AwsCredentials; use rusoto_core::credential::AwsCredentials;
use rusoto_core::Region; use rusoto_core::Region;
@@ -155,7 +157,9 @@ impl Value {
if let Some(ref text) = self.text { if let Some(ref text) = self.text {
Ok(text.as_bytes().to_vec()) Ok(text.as_bytes().to_vec())
} else if let Some(ref b64) = self.b64 { } else if let Some(ref b64) = self.b64 {
base64::decode(b64).map_err(|_| Error::Message("invalid base64 input".into())) BASE64_STANDARD
.decode(b64)
.map_err(|_| Error::Message("invalid base64 input".into()))
} else if let Some(ref path) = self.file { } else if let Some(ref path) = self.file {
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
if path == "-" { if path == "-" {
@@ -230,7 +234,7 @@ impl ReadOutputKind {
for val in val.value { for val in val.value {
match val { match val {
K2vValue::Value(v) => { K2vValue::Value(v) => {
println!("{}", base64::encode(&v)) println!("{}", BASE64_STANDARD.encode(&v))
} }
K2vValue::Tombstone => { K2vValue::Tombstone => {
println!(); println!();
@@ -249,7 +253,7 @@ impl ReadOutputKind {
if let Ok(string) = std::str::from_utf8(&v) { if let Ok(string) = std::str::from_utf8(&v) {
println!(" utf-8: {}", string); println!(" utf-8: {}", string);
} else { } else {
println!(" base64: {}", base64::encode(&v)); println!(" base64: {}", BASE64_STANDARD.encode(&v));
} }
} }
K2vValue::Tombstone => { K2vValue::Tombstone => {
@@ -275,7 +279,7 @@ struct BatchOutputKind {
impl BatchOutputKind { impl BatchOutputKind {
fn display_human_output(&self, values: BTreeMap<String, CausalValue>) -> ! { fn display_human_output(&self, values: BTreeMap<String, CausalValue>) -> ! {
for (key, values) in values { for (key, values) in values {
println!("key: {}", key); println!("sort_key: {}", key);
let causality: String = values.causality.into(); let causality: String = values.causality.into();
println!("causality: {}", causality); println!("causality: {}", causality);
for value in values.value { for value in values.value {
@@ -284,7 +288,7 @@ impl BatchOutputKind {
if let Ok(string) = std::str::from_utf8(&v) { if let Ok(string) = std::str::from_utf8(&v) {
println!(" value(utf-8): {}", string); println!(" value(utf-8): {}", string);
} else { } else {
println!(" value(base64): {}", base64::encode(&v)); println!(" value(base64): {}", BASE64_STANDARD.encode(&v));
} }
} }
K2vValue::Tombstone => { K2vValue::Tombstone => {
@@ -520,7 +524,7 @@ async fn main() -> Result<(), Error> {
value value
.as_object_mut() .as_object_mut()
.unwrap() .unwrap()
.insert("sort_key".to_owned(), k.into()); .insert("partition_key".to_owned(), k.into());
value value
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@@ -537,7 +541,7 @@ async fn main() -> Result<(), Error> {
} }
let mut to_print = Vec::new(); let mut to_print = Vec::new();
to_print.push(format!("key:\tentries\tconflicts\tvalues\tbytes")); to_print.push(format!("partition_key\tentries\tconflicts\tvalues\tbytes"));
for (k, v) in res.items { for (k, v) in res.items {
to_print.push(format!( to_print.push(format!(
"{}\t{}\t{}\t{}\t{}", "{}\t{}\t{}\t{}\t{}",
+9 -6
View File
@@ -1,6 +1,7 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::time::Duration; use std::time::Duration;
use base64::prelude::*;
use http::header::{ACCEPT, CONTENT_LENGTH, CONTENT_TYPE}; use http::header::{ACCEPT, CONTENT_LENGTH, CONTENT_TYPE};
use http::status::StatusCode; use http::status::StatusCode;
use http::HeaderMap; use http::HeaderMap;
@@ -375,7 +376,7 @@ impl K2vClient {
.unwrap_or_default(); .unwrap_or_default();
let err_body_str = std::str::from_utf8(&err_body) let err_body_str = std::str::from_utf8(&err_body)
.map(String::from) .map(String::from)
.unwrap_or_else(|_| base64::encode(&err_body)); .unwrap_or_else(|_| BASE64_STANDARD.encode(&err_body));
if s.is_client_error() || s.is_server_error() { if s.is_client_error() || s.is_server_error() {
error!("Error response {}: {}", res.status, err_body_str); error!("Error response {}: {}", res.status, err_body_str);
@@ -408,7 +409,7 @@ impl K2vClient {
"Response body: {}", "Response body: {}",
std::str::from_utf8(&body) std::str::from_utf8(&body)
.map(String::from) .map(String::from)
.unwrap_or_else(|_| base64::encode(&body)) .unwrap_or_else(|_| BASE64_STANDARD.encode(&body))
); );
Ok(Response { Ok(Response {
@@ -482,9 +483,11 @@ impl<'de> Deserialize<'de> for K2vValue {
{ {
let val: Option<&str> = Option::deserialize(d)?; let val: Option<&str> = Option::deserialize(d)?;
Ok(match val { Ok(match val {
Some(s) => { Some(s) => K2vValue::Value(
K2vValue::Value(base64::decode(s).map_err(|_| DeError::custom("invalid base64"))?) BASE64_STANDARD
} .decode(s)
.map_err(|_| DeError::custom("invalid base64"))?,
),
None => K2vValue::Tombstone, None => K2vValue::Tombstone,
}) })
} }
@@ -498,7 +501,7 @@ impl Serialize for K2vValue {
match self { match self {
K2vValue::Tombstone => serializer.serialize_none(), K2vValue::Tombstone => serializer.serialize_none(),
K2vValue::Value(v) => { K2vValue::Value(v) => {
let b64 = base64::encode(v); let b64 = BASE64_STANDARD.encode(v);
serializer.serialize_str(&b64) serializer.serialize_str(&b64)
} }
} }
+5 -5
View File
@@ -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.workspace = true
garage_rpc = { version = "0.8.2", path = "../rpc" } garage_rpc.workspace = true
garage_table = { version = "0.8.2", path = "../table" } garage_table.workspace = true
garage_block = { version = "0.8.2", path = "../block" } garage_block.workspace = true
garage_util = { version = "0.8.2", path = "../util" } garage_util.workspace = true
async-trait = "0.1.7" async-trait = "0.1.7"
arc-swap = "1.0" arc-swap = "1.0"
-48
View File
@@ -57,56 +57,8 @@ mod v08 {
pub struct WebsiteConfig { pub struct WebsiteConfig {
pub index_document: String, pub index_document: String,
pub error_document: Option<String>, pub error_document: Option<String>,
pub redirect_all_requests_to: Option<RedirectTarget>,
pub routing_rules: Vec<RoutingRule>,
} }
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct RedirectTarget {
/// Name of the host where requests are redirected.
pub hostname: String,
/// Protocol to use when redirecting requests. The default is the protocol that is used in the original request.
/// Valid Values: http | https
pub protocol: Option<String>,
}
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct RoutingRule {
/// A container for describing a condition that must be met for the specified redirect to apply. For example, 1. If request is for pages in the /docs folder, redirect to the /documents folder. 2. If request results in HTTP error 4xx, redirect request to another host where you might process the error.
pub condition: Option<RoutingCondition>,
/// Container for redirect information. You can redirect requests to another host, to another page, or with another protocol. In the event of an error, you can specify a different error code to return.
pub redirect: RedirectRule,
}
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct RoutingCondition {
/// The HTTP error code when the redirect is applied. In the event of an error, if the error code equals this value, then the specified redirect is applied. Required when parent element Condition is specified and sibling KeyPrefixEquals is not specified. If both are specified, then both must be true for the redirect to be applied.
pub http_error_code_returned_equals: Option<u16>,
/// The object key name prefix when the redirect is applied. For example, to redirect requests for ExamplePage.html, the key prefix will be ExamplePage.html. To redirect request for all pages with the prefix docs/, the key prefix will be /docs, which identifies all objects in the docs/ folder. Required when the parent element Condition is specified and sibling HttpErrorCodeReturnedEquals is not specified. If both conditions are specified, both must be true for the redirect to be applied.
pub key_prefix_equals: Option<String>,
}
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct RedirectRule {
/// The hostname to use in the redirect request.
pub hostname: Option<String>,
/// The HTTP redirect code to use on the response. Not required if one of the siblings is present.
pub http_redirect_code: Option<u16>,
/// Protocol to use when redirecting requests. The default is the protocol that is used in the original request.
/// Valid Values: http | https
pub protocol: Option<String>,
/// The object key prefix to use in the redirect request. For example, to redirect requests for all pages with prefix docs/ (objects in the docs/ folder) to documents/, you can set a condition block with KeyPrefixEquals set to docs/ and in the Redirect set ReplaceKeyPrefixWith to /documents. Not required if one of the siblings is present. Can be present only if ReplaceKeyWith is not provided.
pub replace_key_prefix_with: Option<String>,
/// The specific object key to use in the redirect request. For example, redirect request to error.html. Not required if one of the siblings is present. Can be present only if ReplaceKeyPrefixWith is not provided.
pub replace_key_with: Option<String>,
}
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)] #[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct CorsRule { pub struct CorsRule {
pub id: Option<String>, pub id: Option<String>,
+1 -1
View File
@@ -79,7 +79,7 @@ impl RangeSeenMarker {
let bytes = nonversioned_encode(&self)?; let bytes = nonversioned_encode(&self)?;
let bytes = zstd::stream::encode_all(&mut &bytes[..], zstd::DEFAULT_COMPRESSION_LEVEL)?; let bytes = zstd::stream::encode_all(&mut &bytes[..], zstd::DEFAULT_COMPRESSION_LEVEL)?;
Ok(BASE64_STANDARD.encode(&bytes)) Ok(BASE64_STANDARD.encode(bytes))
} }
/// Decode from msgpack+zstd+b64 representation, returns None on error. /// Decode from msgpack+zstd+b64 representation, returns None on error.
+1 -1
View File
@@ -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.workspace = true
arc-swap = "1.0" arc-swap = "1.0"
bytes = "1.0" bytes = "1.0"
+3 -3
View File
@@ -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.workspace = true
garage_rpc = { version = "0.8.2", path = "../rpc" } garage_rpc.workspace = true
garage_util = { version = "0.8.2", path = "../util" } garage_util.workspace = true
opentelemetry = "0.17" opentelemetry = "0.17"
+8 -8
View File
@@ -44,22 +44,22 @@ pub struct TableData<F: TableSchema, R: TableReplication> {
impl<F: TableSchema, R: TableReplication> TableData<F, R> { impl<F: TableSchema, R: TableReplication> TableData<F, R> {
pub fn new(system: Arc<System>, instance: F, replication: R, db: &db::Db) -> Arc<Self> { pub fn new(system: Arc<System>, instance: F, replication: R, db: &db::Db) -> Arc<Self> {
let store = db let store = db
.open_tree(&format!("{}:table", F::TABLE_NAME)) .open_tree(format!("{}:table", F::TABLE_NAME))
.expect("Unable to open DB tree"); .expect("Unable to open DB tree");
let merkle_tree = db let merkle_tree = db
.open_tree(&format!("{}:merkle_tree", F::TABLE_NAME)) .open_tree(format!("{}:merkle_tree", F::TABLE_NAME))
.expect("Unable to open DB Merkle tree tree"); .expect("Unable to open DB Merkle tree tree");
let merkle_todo = db let merkle_todo = db
.open_tree(&format!("{}:merkle_todo", F::TABLE_NAME)) .open_tree(format!("{}:merkle_todo", F::TABLE_NAME))
.expect("Unable to open DB Merkle TODO tree"); .expect("Unable to open DB Merkle TODO tree");
let insert_queue = db let insert_queue = db
.open_tree(&format!("{}:insert_queue", F::TABLE_NAME)) .open_tree(format!("{}:insert_queue", F::TABLE_NAME))
.expect("Unable to open insert queue DB tree"); .expect("Unable to open insert queue DB tree");
let gc_todo = db let gc_todo = db
.open_tree(&format!("{}:gc_todo_v2", F::TABLE_NAME)) .open_tree(format!("{}:gc_todo_v2", F::TABLE_NAME))
.expect("Unable to open GC DB tree"); .expect("Unable to open GC DB tree");
let gc_todo = CountedTree::new(gc_todo).expect("Cannot count gc_todo_v2"); let gc_todo = CountedTree::new(gc_todo).expect("Cannot count gc_todo_v2");
@@ -90,7 +90,7 @@ impl<F: TableSchema, R: TableReplication> TableData<F, R> {
pub fn read_entry(&self, p: &F::P, s: &F::S) -> Result<Option<ByteBuf>, Error> { pub fn read_entry(&self, p: &F::P, s: &F::S) -> Result<Option<ByteBuf>, Error> {
let tree_key = self.tree_key(p, s); let tree_key = self.tree_key(p, s);
if let Some(bytes) = self.store.get(&tree_key)? { if let Some(bytes) = self.store.get(tree_key)? {
Ok(Some(ByteBuf::from(bytes.to_vec()))) Ok(Some(ByteBuf::from(bytes.to_vec())))
} else { } else {
Ok(None) Ok(None)
@@ -132,10 +132,10 @@ impl<F: TableSchema, R: TableReplication> TableData<F, R> {
} }
} }
fn read_range_aux<'a>( fn read_range_aux(
&self, &self,
partition_hash: Hash, partition_hash: Hash,
range: db::ValueIter<'a>, range: db::ValueIter,
filter: &Option<F::Filter>, filter: &Option<F::Filter>,
limit: usize, limit: usize,
) -> Result<Vec<Arc<ByteBuf>>, Error> { ) -> Result<Vec<Arc<ByteBuf>>, Error> {
+2 -7
View File
@@ -34,8 +34,9 @@ impl DeletedFilter {
} }
} }
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
pub enum EnumerationOrder { pub enum EnumerationOrder {
#[default]
Forward, Forward,
Reverse, Reverse,
} }
@@ -49,9 +50,3 @@ impl EnumerationOrder {
} }
} }
} }
impl Default for EnumerationOrder {
fn default() -> Self {
EnumerationOrder::Forward
}
}
+1 -2
View File
@@ -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.workspace = true
arc-swap = "1.0" arc-swap = "1.0"
async-trait = "0.1" async-trait = "0.1"
@@ -22,7 +22,6 @@ blake2 = "0.10"
bytes = "1.0" bytes = "1.0"
digest = "0.10" digest = "0.10"
err-derive = "0.3" err-derive = "0.3"
git-version = "0.3.4"
hexdump = "0.1" hexdump = "0.1"
xxhash-rust = { version = "0.8", default-features = false, features = ["xxh3"] } xxhash-rust = { version = "0.8", default-features = false, features = ["xxh3"] }
hex = "0.4" hex = "0.4"
+1 -1
View File
@@ -223,7 +223,7 @@ fn secret_from_file(
#[cfg(unix)] #[cfg(unix)]
if std::env::var("GARAGE_ALLOW_WORLD_READABLE_SECRETS").as_deref() != Ok("true") { if std::env::var("GARAGE_ALLOW_WORLD_READABLE_SECRETS").as_deref() != Ok("true") {
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
let metadata = std::fs::metadata(&file_path)?; let metadata = std::fs::metadata(file_path)?;
if metadata.mode() & 0o077 != 0 { if metadata.mode() & 0o077 != 0 {
return Err(format!("File {} is world-readable! (mode: 0{:o}, expected 0600)\nRefusing to start until this is fixed, or environment variable GARAGE_ALLOW_WORLD_READABLE_SECRETS is set to true.", file_path, metadata.mode()).into()); return Err(format!("File {} is world-readable! (mode: 0{:o}, expected 0600)\nRefusing to start until this is fixed, or environment variable GARAGE_ALLOW_WORLD_READABLE_SECRETS is set to true.", file_path, metadata.mode()).into());
} }
+1 -1
View File
@@ -13,7 +13,7 @@ pub fn handle_forwarded_for_headers(headers: &HeaderMap<HeaderValue>) -> Result<
.to_str() .to_str()
.ok_or_message("Error parsing X-Forwarded-For header")?; .ok_or_message("Error parsing X-Forwarded-For header")?;
let client_ip = IpAddr::from_str(&forwarded_for_ip_str) let client_ip = IpAddr::from_str(forwarded_for_ip_str)
.ok_or_message("Valid IP address not found in X-Forwarded-For header")?; .ok_or_message("Valid IP address not found in X-Forwarded-For header")?;
Ok(client_ip.to_string()) Ok(client_ip.to_string())
-1
View File
@@ -10,7 +10,6 @@ pub mod crdt;
pub mod data; pub mod data;
pub mod encode; pub mod encode;
pub mod error; pub mod error;
pub mod formater;
pub mod forwarded_headers; pub mod forwarded_headers;
pub mod metrics; pub mod metrics;
pub mod migrate; pub mod migrate;
+4 -8
View File
@@ -1,18 +1,14 @@
use std::sync::Arc; use std::sync::Arc;
use arc_swap::{ArcSwap, ArcSwapOption}; use arc_swap::ArcSwapOption;
lazy_static::lazy_static! { lazy_static::lazy_static! {
static ref VERSION: ArcSwap<&'static str> = ArcSwap::new(Arc::new(git_version::git_version!( static ref VERSION: ArcSwapOption<&'static str> = ArcSwapOption::new(None);
prefix = "git:",
cargo_prefix = "cargo:",
fallback = "unknown"
)));
static ref FEATURES: ArcSwapOption<&'static [&'static str]> = ArcSwapOption::new(None); static ref FEATURES: ArcSwapOption<&'static [&'static str]> = ArcSwapOption::new(None);
} }
pub fn garage_version() -> &'static str { pub fn garage_version() -> &'static str {
&VERSION.load() VERSION.load().as_ref().unwrap()
} }
pub fn garage_features() -> Option<&'static [&'static str]> { pub fn garage_features() -> Option<&'static [&'static str]> {
@@ -20,7 +16,7 @@ pub fn garage_features() -> Option<&'static [&'static str]> {
} }
pub fn init_version(version: &'static str) { pub fn init_version(version: &'static str) {
VERSION.store(Arc::new(version)); VERSION.store(Some(Arc::new(version)));
} }
pub fn init_features(features: &'static [&'static str]) { pub fn init_features(features: &'static [&'static str]) {
+4 -4
View File
@@ -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.workspace = true
garage_model = { version = "0.8.2", path = "../model" } garage_model.workspace = true
garage_util = { version = "0.8.2", path = "../util" } garage_util.workspace = true
garage_table = { version = "0.8.2", path = "../table" } garage_table.workspace = true
err-derive = "0.3" err-derive = "0.3"
tracing = "0.1" tracing = "0.1"
+1 -1
View File
@@ -106,7 +106,7 @@ impl WebServer {
addr: SocketAddr, addr: SocketAddr,
) -> Result<Response<Body>, Infallible> { ) -> Result<Response<Body>, Infallible> {
if let Ok(forwarded_for_ip_addr) = if let Ok(forwarded_for_ip_addr) =
forwarded_headers::handle_forwarded_for_headers(&req.headers()) forwarded_headers::handle_forwarded_for_headers(req.headers())
{ {
info!( info!(
"{} (via {}) {} {}", "{} (via {}) {} {}",