aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock179
-rw-r--r--Cargo.toml10
-rw-r--r--src/api/admin/Cargo.toml71
-rw-r--r--src/api/admin/api_server.rs18
-rw-r--r--src/api/admin/bucket.rs10
-rw-r--r--src/api/admin/cluster.rs6
-rw-r--r--src/api/admin/error.rs10
-rw-r--r--src/api/admin/key.rs6
-rw-r--r--src/api/admin/lib.rs (renamed from src/api/admin/mod.rs)3
-rw-r--r--src/api/admin/router_v0.rs4
-rw-r--r--src/api/admin/router_v1.rs6
-rw-r--r--src/api/common/Cargo.toml (renamed from src/api/Cargo.toml)3
-rw-r--r--src/api/common/common_error.rs (renamed from src/api/common_error.rs)4
-rw-r--r--src/api/common/encoding.rs (renamed from src/api/encoding.rs)0
-rw-r--r--src/api/common/generic_server.rs (renamed from src/api/generic_server.rs)6
-rw-r--r--src/api/common/helpers.rs (renamed from src/api/helpers.rs)10
-rw-r--r--src/api/common/lib.rs (renamed from src/api/lib.rs)9
-rw-r--r--src/api/common/router_macros.rs (renamed from src/api/router_macros.rs)6
-rw-r--r--src/api/common/signature/error.rs (renamed from src/api/signature/error.rs)0
-rw-r--r--src/api/common/signature/mod.rs (renamed from src/api/signature/mod.rs)0
-rw-r--r--src/api/common/signature/payload.rs (renamed from src/api/signature/payload.rs)2
-rw-r--r--src/api/common/signature/streaming.rs (renamed from src/api/signature/streaming.rs)0
-rw-r--r--src/api/k2v/Cargo.toml75
-rw-r--r--src/api/k2v/api_server.rs20
-rw-r--r--src/api/k2v/batch.rs2
-rw-r--r--src/api/k2v/error.rs14
-rw-r--r--src/api/k2v/index.rs8
-rw-r--r--src/api/k2v/item.rs6
-rw-r--r--src/api/k2v/lib.rs (renamed from src/api/k2v/mod.rs)3
-rw-r--r--src/api/k2v/range.rs4
-rw-r--r--src/api/k2v/router.rs6
-rw-r--r--src/api/s3/Cargo.toml71
-rw-r--r--src/api/s3/api_server.rs40
-rw-r--r--src/api/s3/bucket.rs12
-rw-r--r--src/api/s3/checksum.rs2
-rw-r--r--src/api/s3/copy.rs18
-rw-r--r--src/api/s3/cors.rs12
-rw-r--r--src/api/s3/delete.rs12
-rw-r--r--src/api/s3/encryption.rs6
-rw-r--r--src/api/s3/error.rs19
-rw-r--r--src/api/s3/get.rs10
-rw-r--r--src/api/s3/lib.rs (renamed from src/api/s3/mod.rs)3
-rw-r--r--src/api/s3/lifecycle.rs10
-rw-r--r--src/api/s3/list.rs14
-rw-r--r--src/api/s3/multipart.rs16
-rw-r--r--src/api/s3/post_object.rs18
-rw-r--r--src/api/s3/put.rs10
-rw-r--r--src/api/s3/router.rs6
-rw-r--r--src/api/s3/website.rs10
-rw-r--r--src/api/s3/xml.rs2
-rw-r--r--src/garage/Cargo.toml9
-rw-r--r--src/web/Cargo.toml3
52 files changed, 609 insertions, 195 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0d3f70f0..ebe318a3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1324,7 +1324,10 @@ dependencies = [
"format_table",
"futures",
"futures-util",
- "garage_api",
+ "garage_api_admin",
+ "garage_api_common",
+ "garage_api_k2v",
+ "garage_api_s3",
"garage_block",
"garage_db",
"garage_model",
@@ -1365,7 +1368,7 @@ dependencies = [
]
[[package]]
-name = "garage_api"
+name = "garage_api_admin"
version = "1.0.1"
dependencies = [
"aes-gcm",
@@ -1382,6 +1385,175 @@ dependencies = [
"form_urlencoded",
"futures",
"futures-util",
+ "garage_api_common",
+ "garage_block",
+ "garage_model",
+ "garage_net",
+ "garage_rpc",
+ "garage_table",
+ "garage_util",
+ "hex",
+ "hmac",
+ "http 1.0.0",
+ "http-body-util",
+ "http-range",
+ "httpdate",
+ "hyper 1.1.0",
+ "hyper-util",
+ "idna",
+ "md-5",
+ "multer",
+ "nom",
+ "opentelemetry",
+ "opentelemetry-prometheus",
+ "percent-encoding",
+ "pin-project",
+ "prometheus",
+ "quick-xml",
+ "roxmltree",
+ "serde",
+ "serde_bytes",
+ "serde_json",
+ "sha1",
+ "sha2",
+ "tokio",
+ "tokio-stream",
+ "tokio-util 0.7.10",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "garage_api_common"
+version = "1.0.1"
+dependencies = [
+ "aes-gcm",
+ "argon2",
+ "async-compression",
+ "async-trait",
+ "base64 0.21.7",
+ "bytes",
+ "chrono",
+ "crc32c",
+ "crc32fast",
+ "crypto-common",
+ "err-derive",
+ "form_urlencoded",
+ "futures",
+ "futures-util",
+ "garage_block",
+ "garage_model",
+ "garage_net",
+ "garage_rpc",
+ "garage_table",
+ "garage_util",
+ "hex",
+ "hmac",
+ "http 1.0.0",
+ "http-body-util",
+ "http-range",
+ "httpdate",
+ "hyper 1.1.0",
+ "hyper-util",
+ "idna",
+ "md-5",
+ "multer",
+ "nom",
+ "opentelemetry",
+ "opentelemetry-prometheus",
+ "percent-encoding",
+ "pin-project",
+ "prometheus",
+ "quick-xml",
+ "roxmltree",
+ "serde",
+ "serde_bytes",
+ "serde_json",
+ "sha1",
+ "sha2",
+ "tokio",
+ "tokio-stream",
+ "tokio-util 0.7.10",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "garage_api_k2v"
+version = "1.0.1"
+dependencies = [
+ "aes-gcm",
+ "argon2",
+ "async-compression",
+ "async-trait",
+ "base64 0.21.7",
+ "bytes",
+ "chrono",
+ "crc32c",
+ "crc32fast",
+ "crypto-common",
+ "err-derive",
+ "form_urlencoded",
+ "futures",
+ "futures-util",
+ "garage_api_common",
+ "garage_api_s3",
+ "garage_block",
+ "garage_model",
+ "garage_net",
+ "garage_rpc",
+ "garage_table",
+ "garage_util",
+ "hex",
+ "hmac",
+ "http 1.0.0",
+ "http-body-util",
+ "http-range",
+ "httpdate",
+ "hyper 1.1.0",
+ "hyper-util",
+ "idna",
+ "md-5",
+ "multer",
+ "nom",
+ "opentelemetry",
+ "opentelemetry-prometheus",
+ "percent-encoding",
+ "pin-project",
+ "prometheus",
+ "quick-xml",
+ "roxmltree",
+ "serde",
+ "serde_bytes",
+ "serde_json",
+ "sha1",
+ "sha2",
+ "tokio",
+ "tokio-stream",
+ "tokio-util 0.7.10",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "garage_api_s3"
+version = "1.0.1"
+dependencies = [
+ "aes-gcm",
+ "argon2",
+ "async-compression",
+ "async-trait",
+ "base64 0.21.7",
+ "bytes",
+ "chrono",
+ "crc32c",
+ "crc32fast",
+ "crypto-common",
+ "err-derive",
+ "form_urlencoded",
+ "futures",
+ "futures-util",
+ "garage_api_common",
"garage_block",
"garage_model",
"garage_net",
@@ -1614,7 +1786,8 @@ version = "1.0.1"
dependencies = [
"err-derive",
"futures",
- "garage_api",
+ "garage_api_common",
+ "garage_api_s3",
"garage_model",
"garage_table",
"garage_util",
diff --git a/Cargo.toml b/Cargo.toml
index 5ff0ec42..ae149ae0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,7 +8,10 @@ members = [
"src/table",
"src/block",
"src/model",
- "src/api",
+ "src/api/common",
+ "src/api/s3",
+ "src/api/k2v",
+ "src/api/admin",
"src/web",
"src/garage",
"src/k2v-client",
@@ -21,7 +24,10 @@ default-members = ["src/garage"]
# Internal Garage crates
format_table = { version = "0.1.1", path = "src/format-table" }
-garage_api = { version = "1.0.1", path = "src/api" }
+garage_api_common = { version = "1.0.1", path = "src/api/common" }
+garage_api_admin = { version = "1.0.1", path = "src/api/admin" }
+garage_api_s3 = { version = "1.0.1", path = "src/api/s3" }
+garage_api_k2v = { version = "1.0.1", path = "src/api/k2v" }
garage_block = { version = "1.0.1", path = "src/block" }
garage_db = { version = "1.0.1", path = "src/db", default-features = false }
garage_model = { version = "1.0.1", path = "src/model", default-features = false }
diff --git a/src/api/admin/Cargo.toml b/src/api/admin/Cargo.toml
new file mode 100644
index 00000000..02cbfc3d
--- /dev/null
+++ b/src/api/admin/Cargo.toml
@@ -0,0 +1,71 @@
+[package]
+name = "garage_api_admin"
+version = "1.0.1"
+authors = ["Alex Auvolat <alex@adnab.me>"]
+edition = "2018"
+license = "AGPL-3.0"
+description = "S3 API server crate for the Garage object store"
+repository = "https://git.deuxfleurs.fr/Deuxfleurs/garage"
+readme = "../../README.md"
+
+[lib]
+path = "lib.rs"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+garage_model.workspace = true
+garage_table.workspace = true
+garage_block.workspace = true
+garage_net.workspace = true
+garage_util.workspace = true
+garage_rpc.workspace = true
+garage_api_common.workspace = true
+
+aes-gcm.workspace = true
+argon2.workspace = true
+async-compression.workspace = true
+async-trait.workspace = true
+base64.workspace = true
+bytes.workspace = true
+chrono.workspace = true
+crc32fast.workspace = true
+crc32c.workspace = true
+crypto-common.workspace = true
+err-derive.workspace = true
+hex.workspace = true
+hmac.workspace = true
+idna.workspace = true
+tracing.workspace = true
+md-5.workspace = true
+nom.workspace = true
+pin-project.workspace = true
+sha1.workspace = true
+sha2.workspace = true
+
+futures.workspace = true
+futures-util.workspace = true
+tokio.workspace = true
+tokio-stream.workspace = true
+tokio-util.workspace = true
+
+form_urlencoded.workspace = true
+http.workspace = true
+httpdate.workspace = true
+http-range.workspace = true
+http-body-util.workspace = true
+hyper = { workspace = true, default-features = false, features = ["server", "http1"] }
+hyper-util.workspace = true
+multer.workspace = true
+percent-encoding.workspace = true
+roxmltree.workspace = true
+url.workspace = true
+
+serde.workspace = true
+serde_bytes.workspace = true
+serde_json.workspace = true
+quick-xml.workspace = true
+
+opentelemetry.workspace = true
+opentelemetry-prometheus = { workspace = true, optional = true }
+prometheus = { workspace = true, optional = true }
diff --git a/src/api/admin/api_server.rs b/src/api/admin/api_server.rs
index 0e4565bb..7f8a51a6 100644
--- a/src/api/admin/api_server.rs
+++ b/src/api/admin/api_server.rs
@@ -20,15 +20,15 @@ use garage_rpc::system::ClusterHealthStatus;
use garage_util::error::Error as GarageError;
use garage_util::socket_address::UnixOrTCPSocketAddress;
-use crate::generic_server::*;
-
-use crate::admin::bucket::*;
-use crate::admin::cluster::*;
-use crate::admin::error::*;
-use crate::admin::key::*;
-use crate::admin::router_v0;
-use crate::admin::router_v1::{Authorization, Endpoint};
-use crate::helpers::*;
+use garage_api_common::generic_server::*;
+
+use crate::bucket::*;
+use crate::cluster::*;
+use crate::error::*;
+use crate::key::*;
+use crate::router_v0;
+use crate::router_v1::{Authorization, Endpoint};
+use garage_api_common::helpers::*;
pub type ResBody = BoxBody<Error>;
diff --git a/src/api/admin/bucket.rs b/src/api/admin/bucket.rs
index ac3cba00..3afed694 100644
--- a/src/api/admin/bucket.rs
+++ b/src/api/admin/bucket.rs
@@ -17,11 +17,11 @@ use garage_model::permission::*;
use garage_model::s3::mpu_table;
use garage_model::s3::object_table::*;
-use crate::admin::api_server::ResBody;
-use crate::admin::error::*;
-use crate::admin::key::ApiBucketKeyPerm;
-use crate::common_error::CommonError;
-use crate::helpers::*;
+use crate::api_server::ResBody;
+use crate::error::*;
+use crate::key::ApiBucketKeyPerm;
+use garage_api_common::common_error::CommonError;
+use garage_api_common::helpers::*;
pub async fn handle_list_buckets(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> {
let buckets = garage
diff --git a/src/api/admin/cluster.rs b/src/api/admin/cluster.rs
index 357ac600..d4a645a2 100644
--- a/src/api/admin/cluster.rs
+++ b/src/api/admin/cluster.rs
@@ -12,9 +12,9 @@ use garage_rpc::layout;
use garage_model::garage::Garage;
-use crate::admin::api_server::ResBody;
-use crate::admin::error::*;
-use crate::helpers::{json_ok_response, parse_json_body};
+use crate::api_server::ResBody;
+use crate::error::*;
+use garage_api_common::helpers::{json_ok_response, parse_json_body};
pub async fn handle_get_cluster_status(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> {
let layout = garage.system.cluster_layout();
diff --git a/src/api/admin/error.rs b/src/api/admin/error.rs
index 40d686e3..1c962776 100644
--- a/src/api/admin/error.rs
+++ b/src/api/admin/error.rs
@@ -6,10 +6,12 @@ use hyper::{HeaderMap, StatusCode};
pub use garage_model::helper::error::Error as HelperError;
-use crate::common_error::CommonError;
-pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInternalError};
-use crate::generic_server::ApiError;
-use crate::helpers::*;
+use garage_api_common::common_error::CommonError;
+pub use garage_api_common::common_error::{
+ CommonErrorDerivative, OkOrBadRequest, OkOrInternalError,
+};
+use garage_api_common::generic_server::ApiError;
+use garage_api_common::helpers::*;
/// Errors of this crate
#[derive(Debug, Error)]
diff --git a/src/api/admin/key.rs b/src/api/admin/key.rs
index 291b6d54..0c017a26 100644
--- a/src/api/admin/key.rs
+++ b/src/api/admin/key.rs
@@ -9,9 +9,9 @@ use garage_table::*;
use garage_model::garage::Garage;
use garage_model::key_table::*;
-use crate::admin::api_server::ResBody;
-use crate::admin::error::*;
-use crate::helpers::*;
+use crate::api_server::ResBody;
+use crate::error::*;
+use garage_api_common::helpers::*;
pub async fn handle_list_keys(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> {
let res = garage
diff --git a/src/api/admin/mod.rs b/src/api/admin/lib.rs
index 43a8c59c..599e9b44 100644
--- a/src/api/admin/mod.rs
+++ b/src/api/admin/lib.rs
@@ -1,3 +1,6 @@
+#[macro_use]
+extern crate tracing;
+
pub mod api_server;
mod error;
mod router_v0;
diff --git a/src/api/admin/router_v0.rs b/src/api/admin/router_v0.rs
index 68676445..0c832fe1 100644
--- a/src/api/admin/router_v0.rs
+++ b/src/api/admin/router_v0.rs
@@ -2,8 +2,8 @@ use std::borrow::Cow;
use hyper::{Method, Request};
-use crate::admin::error::*;
-use crate::router_macros::*;
+use crate::error::*;
+use garage_api_common::router_macros::*;
router_match! {@func
diff --git a/src/api/admin/router_v1.rs b/src/api/admin/router_v1.rs
index cc5ff2ec..d9febd34 100644
--- a/src/api/admin/router_v1.rs
+++ b/src/api/admin/router_v1.rs
@@ -2,9 +2,9 @@ use std::borrow::Cow;
use hyper::{Method, Request};
-use crate::admin::error::*;
-use crate::admin::router_v0;
-use crate::router_macros::*;
+use crate::error::*;
+use crate::router_v0;
+use garage_api_common::router_macros::*;
pub enum Authorization {
None,
diff --git a/src/api/Cargo.toml b/src/api/common/Cargo.toml
index 85b78a5b..e5dc57d4 100644
--- a/src/api/Cargo.toml
+++ b/src/api/common/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "garage_api"
+name = "garage_api_common"
version = "1.0.1"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
@@ -70,5 +70,4 @@ opentelemetry-prometheus = { workspace = true, optional = true }
prometheus = { workspace = true, optional = true }
[features]
-k2v = [ "garage_util/k2v", "garage_model/k2v" ]
metrics = [ "opentelemetry-prometheus", "prometheus" ]
diff --git a/src/api/common_error.rs b/src/api/common/common_error.rs
index 0c8006dc..1e3f9feb 100644
--- a/src/api/common_error.rs
+++ b/src/api/common/common_error.rs
@@ -118,14 +118,14 @@ impl TryFrom<HelperError> for CommonError {
/// This is used for helper functions that might return InvalidBucketName
/// or NoSuchBucket for instance, and we want to pass that error
/// up to our caller.
-pub(crate) fn pass_helper_error(err: HelperError) -> CommonError {
+pub fn pass_helper_error(err: HelperError) -> CommonError {
match CommonError::try_from(err) {
Ok(e) => e,
Err(e) => panic!("Helper error `{}` should hot have happenned here", e),
}
}
-pub(crate) fn helper_error_as_internal(err: HelperError) -> CommonError {
+pub fn helper_error_as_internal(err: HelperError) -> CommonError {
match err {
HelperError::Internal(e) => CommonError::InternalError(e),
e => CommonError::InternalError(GarageError::Message(e.to_string())),
diff --git a/src/api/encoding.rs b/src/api/common/encoding.rs
index e286a784..e286a784 100644
--- a/src/api/encoding.rs
+++ b/src/api/common/encoding.rs
diff --git a/src/api/generic_server.rs b/src/api/common/generic_server.rs
index 283abdd4..d92a3465 100644
--- a/src/api/generic_server.rs
+++ b/src/api/common/generic_server.rs
@@ -36,7 +36,7 @@ use garage_util::socket_address::UnixOrTCPSocketAddress;
use crate::helpers::{BoxBody, ErrorBody};
-pub(crate) trait ApiEndpoint: Send + Sync + 'static {
+pub trait ApiEndpoint: Send + Sync + 'static {
fn name(&self) -> &'static str;
fn add_span_attributes(&self, span: SpanRef<'_>);
}
@@ -48,7 +48,7 @@ pub trait ApiError: std::error::Error + Send + Sync + 'static {
}
#[async_trait]
-pub(crate) trait ApiHandler: Send + Sync + 'static {
+pub trait ApiHandler: Send + Sync + 'static {
const API_NAME: &'static str;
const API_NAME_DISPLAY: &'static str;
@@ -63,7 +63,7 @@ pub(crate) trait ApiHandler: Send + Sync + 'static {
) -> Result<Response<BoxBody<Self::Error>>, Self::Error>;
}
-pub(crate) struct ApiServer<A: ApiHandler> {
+pub struct ApiServer<A: ApiHandler> {
region: String,
api_handler: A,
diff --git a/src/api/helpers.rs b/src/api/common/helpers.rs
index cf60005d..c8586de4 100644
--- a/src/api/helpers.rs
+++ b/src/api/common/helpers.rs
@@ -363,9 +363,9 @@ mod tests {
}
#[derive(Serialize)]
-pub(crate) struct CustomApiErrorBody {
- pub(crate) code: String,
- pub(crate) message: String,
- pub(crate) region: String,
- pub(crate) path: String,
+pub struct CustomApiErrorBody {
+ pub code: String,
+ pub message: String,
+ pub region: String,
+ pub path: String,
}
diff --git a/src/api/lib.rs b/src/api/common/lib.rs
index 370dfd7a..49d463d7 100644
--- a/src/api/lib.rs
+++ b/src/api/common/lib.rs
@@ -4,14 +4,9 @@ extern crate tracing;
pub mod common_error;
-mod encoding;
+pub mod encoding;
pub mod generic_server;
pub mod helpers;
-mod router_macros;
+pub mod router_macros;
/// This mode is public only to help testing. Don't expect stability here
pub mod signature;
-
-pub mod admin;
-#[cfg(feature = "k2v")]
-pub mod k2v;
-pub mod s3;
diff --git a/src/api/router_macros.rs b/src/api/common/router_macros.rs
index 8f10a4f5..d9fe86db 100644
--- a/src/api/router_macros.rs
+++ b/src/api/common/router_macros.rs
@@ -1,5 +1,6 @@
/// This macro is used to generate very repetitive match {} blocks in this module
/// It is _not_ made to be used anywhere else
+#[macro_export]
macro_rules! router_match {
(@match $enum:expr , [ $($endpoint:ident,)* ]) => {{
// usage: router_match {@match my_enum, [ VariantWithField1, VariantWithField2 ..] }
@@ -133,6 +134,7 @@ macro_rules! router_match {
/// This macro is used to generate part of the code in this module. It must be called only one, and
/// is useless outside of this module.
+#[macro_export]
macro_rules! generateQueryParameters {
(
keywords: [ $($kw_param:expr => $kw_name: ident),* ],
@@ -220,5 +222,5 @@ macro_rules! generateQueryParameters {
}
}
-pub(crate) use generateQueryParameters;
-pub(crate) use router_match;
+pub use generateQueryParameters;
+pub use router_match;
diff --git a/src/api/signature/error.rs b/src/api/common/signature/error.rs
index 2d92a072..2d92a072 100644
--- a/src/api/signature/error.rs
+++ b/src/api/common/signature/error.rs
diff --git a/src/api/signature/mod.rs b/src/api/common/signature/mod.rs
index 6514da43..6514da43 100644
--- a/src/api/signature/mod.rs
+++ b/src/api/common/signature/mod.rs
diff --git a/src/api/signature/payload.rs b/src/api/common/signature/payload.rs
index 9e5a6043..81541e4a 100644
--- a/src/api/signature/payload.rs
+++ b/src/api/common/signature/payload.rs
@@ -518,7 +518,7 @@ impl Authorization {
})
}
- pub(crate) fn parse_form(params: &HeaderMap) -> Result<Self, Error> {
+ pub fn parse_form(params: &HeaderMap) -> Result<Self, Error> {
let algorithm = params
.get(X_AMZ_ALGORITHM)
.ok_or_bad_request("Missing X-Amz-Algorithm header")?
diff --git a/src/api/signature/streaming.rs b/src/api/common/signature/streaming.rs
index e223d1b1..e223d1b1 100644
--- a/src/api/signature/streaming.rs
+++ b/src/api/common/signature/streaming.rs
diff --git a/src/api/k2v/Cargo.toml b/src/api/k2v/Cargo.toml
new file mode 100644
index 00000000..86d12c2d
--- /dev/null
+++ b/src/api/k2v/Cargo.toml
@@ -0,0 +1,75 @@
+[package]
+name = "garage_api_k2v"
+version = "1.0.1"
+authors = ["Alex Auvolat <alex@adnab.me>"]
+edition = "2018"
+license = "AGPL-3.0"
+description = "S3 API server crate for the Garage object store"
+repository = "https://git.deuxfleurs.fr/Deuxfleurs/garage"
+readme = "../../README.md"
+
+[lib]
+path = "lib.rs"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+garage_model.workspace = true
+garage_table.workspace = true
+garage_block.workspace = true
+garage_net.workspace = true
+garage_util.workspace = true
+garage_rpc.workspace = true
+garage_api_common.workspace = true
+garage_api_s3.workspace = true
+
+aes-gcm.workspace = true
+argon2.workspace = true
+async-compression.workspace = true
+async-trait.workspace = true
+base64.workspace = true
+bytes.workspace = true
+chrono.workspace = true
+crc32fast.workspace = true
+crc32c.workspace = true
+crypto-common.workspace = true
+err-derive.workspace = true
+hex.workspace = true
+hmac.workspace = true
+idna.workspace = true
+tracing.workspace = true
+md-5.workspace = true
+nom.workspace = true
+pin-project.workspace = true
+sha1.workspace = true
+sha2.workspace = true
+
+futures.workspace = true
+futures-util.workspace = true
+tokio.workspace = true
+tokio-stream.workspace = true
+tokio-util.workspace = true
+
+form_urlencoded.workspace = true
+http.workspace = true
+httpdate.workspace = true
+http-range.workspace = true
+http-body-util.workspace = true
+hyper = { workspace = true, default-features = false, features = ["server", "http1"] }
+hyper-util.workspace = true
+multer.workspace = true
+percent-encoding.workspace = true
+roxmltree.workspace = true
+url.workspace = true
+
+serde.workspace = true
+serde_bytes.workspace = true
+serde_json.workspace = true
+quick-xml.workspace = true
+
+opentelemetry.workspace = true
+opentelemetry-prometheus = { workspace = true, optional = true }
+prometheus = { workspace = true, optional = true }
+
+[features]
+default = [ "garage_util/k2v", "garage_model/k2v" ]
diff --git a/src/api/k2v/api_server.rs b/src/api/k2v/api_server.rs
index de6e5f06..1fc512f9 100644
--- a/src/api/k2v/api_server.rs
+++ b/src/api/k2v/api_server.rs
@@ -12,19 +12,19 @@ use garage_util::socket_address::UnixOrTCPSocketAddress;
use garage_model::garage::Garage;
-use crate::generic_server::*;
-use crate::k2v::error::*;
+use crate::error::*;
+use garage_api_common::generic_server::*;
-use crate::signature::verify_request;
+use garage_api_common::signature::verify_request;
-use crate::helpers::*;
-use crate::k2v::batch::*;
-use crate::k2v::index::*;
-use crate::k2v::item::*;
-use crate::k2v::router::Endpoint;
-use crate::s3::cors::*;
+use crate::batch::*;
+use crate::index::*;
+use crate::item::*;
+use crate::router::Endpoint;
+use garage_api_common::helpers::*;
+use garage_api_s3::cors::*;
-pub use crate::signature::streaming::ReqBody;
+pub use garage_api_common::signature::streaming::ReqBody;
pub type ResBody = BoxBody<Error>;
pub struct K2VApiServer {
diff --git a/src/api/k2v/batch.rs b/src/api/k2v/batch.rs
index e4d0b0e5..1dd90456 100644
--- a/src/api/k2v/batch.rs
+++ b/src/api/k2v/batch.rs
@@ -6,11 +6,11 @@ use garage_table::{EnumerationOrder, TableSchema};
use garage_model::k2v::item_table::*;
-use crate::helpers::*;
use crate::k2v::api_server::{ReqBody, ResBody};
use crate::k2v::error::*;
use crate::k2v::item::parse_causality_token;
use crate::k2v::range::read_range;
+use garage_api_common::helpers::*;
pub async fn handle_insert_batch(
ctx: ReqCtx,
diff --git a/src/api/k2v/error.rs b/src/api/k2v/error.rs
index dbe4be2c..a4d3be1c 100644
--- a/src/api/k2v/error.rs
+++ b/src/api/k2v/error.rs
@@ -2,12 +2,14 @@ use err_derive::Error;
use hyper::header::HeaderValue;
use hyper::{HeaderMap, StatusCode};
-use crate::common_error::CommonError;
-pub(crate) use crate::common_error::{helper_error_as_internal, pass_helper_error};
-pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInternalError};
-use crate::generic_server::ApiError;
-use crate::helpers::*;
-use crate::signature::error::Error as SignatureError;
+use garage_api_common::common_error::CommonError;
+pub(crate) use garage_api_common::common_error::{helper_error_as_internal, pass_helper_error};
+pub use garage_api_common::common_error::{
+ CommonErrorDerivative, OkOrBadRequest, OkOrInternalError,
+};
+use garage_api_common::generic_server::ApiError;
+use garage_api_common::helpers::*;
+use garage_api_common::signature::error::Error as SignatureError;
/// Errors of this crate
#[derive(Debug, Error)]
diff --git a/src/api/k2v/index.rs b/src/api/k2v/index.rs
index e3397238..423c1f97 100644
--- a/src/api/k2v/index.rs
+++ b/src/api/k2v/index.rs
@@ -5,10 +5,10 @@ use garage_table::util::*;
use garage_model::k2v::item_table::{BYTES, CONFLICTS, ENTRIES, VALUES};
-use crate::helpers::*;
-use crate::k2v::api_server::ResBody;
-use crate::k2v::error::*;
-use crate::k2v::range::read_range;
+use crate::api_server::ResBody;
+use crate::error::*;
+use crate::range::read_range;
+use garage_api_common::helpers::*;
pub async fn handle_read_index(
ctx: ReqCtx,
diff --git a/src/api/k2v/item.rs b/src/api/k2v/item.rs
index 87371727..315f647c 100644
--- a/src/api/k2v/item.rs
+++ b/src/api/k2v/item.rs
@@ -6,9 +6,9 @@ use hyper::{Request, Response, StatusCode};
use garage_model::k2v::causality::*;
use garage_model::k2v::item_table::*;
-use crate::helpers::*;
-use crate::k2v::api_server::{ReqBody, ResBody};
-use crate::k2v::error::*;
+use crate::api_server::{ReqBody, ResBody};
+use crate::error::*;
+use garage_api_common::helpers::*;
pub const X_GARAGE_CAUSALITY_TOKEN: &str = "X-Garage-Causality-Token";
diff --git a/src/api/k2v/mod.rs b/src/api/k2v/lib.rs
index b6a8c5cf..334ae46b 100644
--- a/src/api/k2v/mod.rs
+++ b/src/api/k2v/lib.rs
@@ -1,3 +1,6 @@
+#[macro_use]
+extern crate tracing;
+
pub mod api_server;
mod error;
mod router;
diff --git a/src/api/k2v/range.rs b/src/api/k2v/range.rs
index bb9d3be5..fdb17e22 100644
--- a/src/api/k2v/range.rs
+++ b/src/api/k2v/range.rs
@@ -7,8 +7,8 @@ use std::sync::Arc;
use garage_table::replication::TableShardedReplication;
use garage_table::*;
-use crate::helpers::key_after_prefix;
-use crate::k2v::error::*;
+use crate::error::*;
+use garage_api_common::helpers::key_after_prefix;
/// Read range in a Garage table.
/// Returns (entries, more?, nextStart)
diff --git a/src/api/k2v/router.rs b/src/api/k2v/router.rs
index 1cc58be5..a04b0f81 100644
--- a/src/api/k2v/router.rs
+++ b/src/api/k2v/router.rs
@@ -1,11 +1,11 @@
-use crate::k2v::error::*;
+use crate::error::*;
use std::borrow::Cow;
use hyper::{Method, Request};
-use crate::helpers::Authorization;
-use crate::router_macros::{generateQueryParameters, router_match};
+use garage_api_common::helpers::Authorization;
+use garage_api_common::router_macros::{generateQueryParameters, router_match};
router_match! {@func
diff --git a/src/api/s3/Cargo.toml b/src/api/s3/Cargo.toml
new file mode 100644
index 00000000..c610b43a
--- /dev/null
+++ b/src/api/s3/Cargo.toml
@@ -0,0 +1,71 @@
+[package]
+name = "garage_api_s3"
+version = "1.0.1"
+authors = ["Alex Auvolat <alex@adnab.me>"]
+edition = "2018"
+license = "AGPL-3.0"
+description = "S3 API server crate for the Garage object store"
+repository = "https://git.deuxfleurs.fr/Deuxfleurs/garage"
+readme = "../../README.md"
+
+[lib]
+path = "lib.rs"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+garage_model.workspace = true
+garage_table.workspace = true
+garage_block.workspace = true
+garage_net.workspace = true
+garage_util.workspace = true
+garage_rpc.workspace = true
+garage_api_common.workspace = true
+
+aes-gcm.workspace = true
+argon2.workspace = true
+async-compression.workspace = true
+async-trait.workspace = true
+base64.workspace = true
+bytes.workspace = true
+chrono.workspace = true
+crc32fast.workspace = true
+crc32c.workspace = true
+crypto-common.workspace = true
+err-derive.workspace = true
+hex.workspace = true
+hmac.workspace = true
+idna.workspace = true
+tracing.workspace = true
+md-5.workspace = true
+nom.workspace = true
+pin-project.workspace = true
+sha1.workspace = true
+sha2.workspace = true
+
+futures.workspace = true
+futures-util.workspace = true
+tokio.workspace = true
+tokio-stream.workspace = true
+tokio-util.workspace = true
+
+form_urlencoded.workspace = true
+http.workspace = true
+httpdate.workspace = true
+http-range.workspace = true
+http-body-util.workspace = true
+hyper = { workspace = true, default-features = false, features = ["server", "http1"] }
+hyper-util.workspace = true
+multer.workspace = true
+percent-encoding.workspace = true
+roxmltree.workspace = true
+url.workspace = true
+
+serde.workspace = true
+serde_bytes.workspace = true
+serde_json.workspace = true
+quick-xml.workspace = true
+
+opentelemetry.workspace = true
+opentelemetry-prometheus = { workspace = true, optional = true }
+prometheus = { workspace = true, optional = true }
diff --git a/src/api/s3/api_server.rs b/src/api/s3/api_server.rs
index f9dafa10..d24f6a0c 100644
--- a/src/api/s3/api_server.rs
+++ b/src/api/s3/api_server.rs
@@ -14,26 +14,26 @@ use garage_util::socket_address::UnixOrTCPSocketAddress;
use garage_model::garage::Garage;
use garage_model::key_table::Key;
-use crate::generic_server::*;
-use crate::s3::error::*;
-
-use crate::signature::verify_request;
-
-use crate::helpers::*;
-use crate::s3::bucket::*;
-use crate::s3::copy::*;
-use crate::s3::cors::*;
-use crate::s3::delete::*;
-use crate::s3::get::*;
-use crate::s3::lifecycle::*;
-use crate::s3::list::*;
-use crate::s3::multipart::*;
-use crate::s3::post_object::handle_post_object;
-use crate::s3::put::*;
-use crate::s3::router::Endpoint;
-use crate::s3::website::*;
-
-pub use crate::signature::streaming::ReqBody;
+use crate::error::*;
+use garage_api_common::generic_server::*;
+
+use garage_api_common::signature::verify_request;
+
+use crate::bucket::*;
+use crate::copy::*;
+use crate::cors::*;
+use crate::delete::*;
+use crate::get::*;
+use crate::lifecycle::*;
+use crate::list::*;
+use crate::multipart::*;
+use crate::post_object::handle_post_object;
+use crate::put::*;
+use crate::router::Endpoint;
+use crate::website::*;
+use garage_api_common::helpers::*;
+
+pub use garage_api_common::signature::streaming::ReqBody;
pub type ResBody = BoxBody<Error>;
pub struct S3ApiServer {
diff --git a/src/api/s3/bucket.rs b/src/api/s3/bucket.rs
index 6a12aa9c..09c5742b 100644
--- a/src/api/s3/bucket.rs
+++ b/src/api/s3/bucket.rs
@@ -13,12 +13,12 @@ use garage_util::crdt::*;
use garage_util::data::*;
use garage_util::time::*;
-use crate::common_error::CommonError;
-use crate::helpers::*;
-use crate::s3::api_server::{ReqBody, ResBody};
-use crate::s3::error::*;
-use crate::s3::xml as s3_xml;
-use crate::signature::verify_signed_content;
+use crate::api_server::{ReqBody, ResBody};
+use crate::error::*;
+use crate::xml as s3_xml;
+use garage_api_common::common_error::CommonError;
+use garage_api_common::helpers::*;
+use garage_api_common::signature::verify_signed_content;
pub fn handle_get_bucket_location(ctx: ReqCtx) -> Result<Response<ResBody>, Error> {
let ReqCtx { garage, .. } = ctx;
diff --git a/src/api/s3/checksum.rs b/src/api/s3/checksum.rs
index c7527163..02fb55ec 100644
--- a/src/api/s3/checksum.rs
+++ b/src/api/s3/checksum.rs
@@ -15,7 +15,7 @@ use garage_util::error::OkOrMessage;
use garage_model::s3::object_table::*;
-use crate::s3::error::*;
+use crate::error::*;
pub const X_AMZ_CHECKSUM_ALGORITHM: HeaderName =
HeaderName::from_static("x-amz-checksum-algorithm");
diff --git a/src/api/s3/copy.rs b/src/api/s3/copy.rs
index b67ace88..1a474fd0 100644
--- a/src/api/s3/copy.rs
+++ b/src/api/s3/copy.rs
@@ -20,15 +20,15 @@ use garage_model::s3::mpu_table::*;
use garage_model::s3::object_table::*;
use garage_model::s3::version_table::*;
-use crate::helpers::*;
-use crate::s3::api_server::{ReqBody, ResBody};
-use crate::s3::checksum::*;
-use crate::s3::encryption::EncryptionParams;
-use crate::s3::error::*;
-use crate::s3::get::full_object_byte_stream;
-use crate::s3::multipart;
-use crate::s3::put::{get_headers, save_stream, ChecksumMode, SaveStreamResult};
-use crate::s3::xml::{self as s3_xml, xmlns_tag};
+use crate::api_server::{ReqBody, ResBody};
+use crate::checksum::*;
+use crate::encryption::EncryptionParams;
+use crate::error::*;
+use crate::get::full_object_byte_stream;
+use crate::multipart;
+use crate::put::{get_headers, save_stream, ChecksumMode, SaveStreamResult};
+use crate::xml::{self as s3_xml, xmlns_tag};
+use garage_api_common::helpers::*;
// -------- CopyObject ---------
diff --git a/src/api/s3/cors.rs b/src/api/s3/cors.rs
index 32dcc0d5..ae8352c3 100644
--- a/src/api/s3/cors.rs
+++ b/src/api/s3/cors.rs
@@ -15,12 +15,12 @@ use http_body_util::BodyExt;
use serde::{Deserialize, Serialize};
-use crate::common_error::{helper_error_as_internal, CommonError};
-use crate::helpers::*;
-use crate::s3::api_server::{ReqBody, ResBody};
-use crate::s3::error::*;
-use crate::s3::xml::{to_xml_with_header, xmlns_tag, IntValue, Value};
-use crate::signature::verify_signed_content;
+use crate::api_server::{ReqBody, ResBody};
+use crate::error::*;
+use crate::xml::{to_xml_with_header, xmlns_tag, IntValue, Value};
+use garage_api_common::common_error::{helper_error_as_internal, CommonError};
+use garage_api_common::helpers::*;
+use garage_api_common::signature::verify_signed_content;
use garage_model::bucket_table::{Bucket, BucketParams, CorsRule as GarageCorsRule};
use garage_model::garage::Garage;
diff --git a/src/api/s3/delete.rs b/src/api/s3/delete.rs
index 57f6f948..1711a9b4 100644
--- a/src/api/s3/delete.rs
+++ b/src/api/s3/delete.rs
@@ -5,12 +5,12 @@ use garage_util::data::*;
use garage_model::s3::object_table::*;
-use crate::helpers::*;
-use crate::s3::api_server::{ReqBody, ResBody};
-use crate::s3::error::*;
-use crate::s3::put::next_timestamp;
-use crate::s3::xml as s3_xml;
-use crate::signature::verify_signed_content;
+use crate::api_server::{ReqBody, ResBody};
+use crate::error::*;
+use crate::put::next_timestamp;
+use crate::xml as s3_xml;
+use garage_api_common::helpers::*;
+use garage_api_common::signature::verify_signed_content;
async fn handle_delete_internal(ctx: &ReqCtx, key: &str) -> Result<(Uuid, Uuid), Error> {
let ReqCtx {
diff --git a/src/api/s3/encryption.rs b/src/api/s3/encryption.rs
index 2e6ed65c..c54d487b 100644
--- a/src/api/s3/encryption.rs
+++ b/src/api/s3/encryption.rs
@@ -28,9 +28,9 @@ use garage_util::migrate::Migrate;
use garage_model::garage::Garage;
use garage_model::s3::object_table::{ObjectVersionEncryption, ObjectVersionMetaInner};
-use crate::common_error::*;
-use crate::s3::checksum::Md5Checksum;
-use crate::s3::error::Error;
+use crate::checksum::Md5Checksum;
+use crate::error::Error;
+use garage_api_common::common_error::*;
const X_AMZ_SERVER_SIDE_ENCRYPTION_CUSTOMER_ALGORITHM: HeaderName =
HeaderName::from_static("x-amz-server-side-encryption-customer-algorithm");
diff --git a/src/api/s3/error.rs b/src/api/s3/error.rs
index 22d2fe14..77dc07c8 100644
--- a/src/api/s3/error.rs
+++ b/src/api/s3/error.rs
@@ -6,13 +6,18 @@ use hyper::{HeaderMap, StatusCode};
use garage_model::helper::error::Error as HelperError;
-pub(crate) use crate::common_error::pass_helper_error;
-use crate::common_error::{helper_error_as_internal, CommonError};
-pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInternalError};
-use crate::generic_server::ApiError;
-use crate::helpers::*;
-use crate::s3::xml as s3_xml;
-use crate::signature::error::Error as SignatureError;
+pub(crate) use garage_api_common::common_error::pass_helper_error;
+
+use garage_api_common::common_error::{helper_error_as_internal, CommonError};
+
+pub use garage_api_common::common_error::{
+ CommonErrorDerivative, OkOrBadRequest, OkOrInternalError,
+};
+
+use crate::xml as s3_xml;
+use garage_api_common::generic_server::ApiError;
+use garage_api_common::helpers::*;
+use garage_api_common::signature::error::Error as SignatureError;
/// Errors of this crate
#[derive(Debug, Error)]
diff --git a/src/api/s3/get.rs b/src/api/s3/get.rs
index f61aae11..c4cd9d48 100644
--- a/src/api/s3/get.rs
+++ b/src/api/s3/get.rs
@@ -25,11 +25,11 @@ use garage_model::garage::Garage;
use garage_model::s3::object_table::*;
use garage_model::s3::version_table::*;
-use crate::helpers::*;
-use crate::s3::api_server::ResBody;
-use crate::s3::checksum::{add_checksum_response_headers, X_AMZ_CHECKSUM_MODE};
-use crate::s3::encryption::EncryptionParams;
-use crate::s3::error::*;
+use crate::api_server::ResBody;
+use crate::checksum::{add_checksum_response_headers, X_AMZ_CHECKSUM_MODE};
+use crate::encryption::EncryptionParams;
+use crate::error::*;
+use garage_api_common::helpers::*;
const X_AMZ_MP_PARTS_COUNT: &str = "x-amz-mp-parts-count";
diff --git a/src/api/s3/mod.rs b/src/api/s3/lib.rs
index b9bb1a6f..fd99b443 100644
--- a/src/api/s3/mod.rs
+++ b/src/api/s3/lib.rs
@@ -1,3 +1,6 @@
+#[macro_use]
+extern crate tracing;
+
pub mod api_server;
pub mod error;
diff --git a/src/api/s3/lifecycle.rs b/src/api/s3/lifecycle.rs
index 7eb1c2cb..da211585 100644
--- a/src/api/s3/lifecycle.rs
+++ b/src/api/s3/lifecycle.rs
@@ -5,11 +5,11 @@ use hyper::{Request, Response, StatusCode};
use serde::{Deserialize, Serialize};
-use crate::helpers::*;
-use crate::s3::api_server::{ReqBody, ResBody};
-use crate::s3::error::*;
-use crate::s3::xml::{to_xml_with_header, xmlns_tag, IntValue, Value};
-use crate::signature::verify_signed_content;
+use crate::api_server::{ReqBody, ResBody};
+use crate::error::*;
+use crate::xml::{to_xml_with_header, xmlns_tag, IntValue, Value};
+use garage_api_common::helpers::*;
+use garage_api_common::signature::verify_signed_content;
use garage_model::bucket_table::{
parse_lifecycle_date, Bucket, LifecycleExpiration as GarageLifecycleExpiration,
diff --git a/src/api/s3/list.rs b/src/api/s3/list.rs
index 68d6cbe6..de808c32 100644
--- a/src/api/s3/list.rs
+++ b/src/api/s3/list.rs
@@ -13,13 +13,13 @@ use garage_model::s3::object_table::*;
use garage_table::EnumerationOrder;
-use crate::encoding::*;
-use crate::helpers::*;
-use crate::s3::api_server::{ReqBody, ResBody};
-use crate::s3::encryption::EncryptionParams;
-use crate::s3::error::*;
-use crate::s3::multipart as s3_multipart;
-use crate::s3::xml as s3_xml;
+use crate::api_server::{ReqBody, ResBody};
+use crate::encryption::EncryptionParams;
+use crate::error::*;
+use crate::multipart as s3_multipart;
+use crate::xml as s3_xml;
+use garage_api_common::encoding::*;
+use garage_api_common::helpers::*;
const DUMMY_NAME: &str = "Dummy Key";
const DUMMY_KEY: &str = "GKDummyKey";
diff --git a/src/api/s3/multipart.rs b/src/api/s3/multipart.rs
index 3db3e8aa..047ed06a 100644
--- a/src/api/s3/multipart.rs
+++ b/src/api/s3/multipart.rs
@@ -15,14 +15,14 @@ use garage_model::s3::mpu_table::*;
use garage_model::s3::object_table::*;
use garage_model::s3::version_table::*;
-use crate::helpers::*;
-use crate::s3::api_server::{ReqBody, ResBody};
-use crate::s3::checksum::*;
-use crate::s3::encryption::EncryptionParams;
-use crate::s3::error::*;
-use crate::s3::put::*;
-use crate::s3::xml as s3_xml;
-use crate::signature::verify_signed_content;
+use crate::api_server::{ReqBody, ResBody};
+use crate::checksum::*;
+use crate::encryption::EncryptionParams;
+use crate::error::*;
+use crate::put::*;
+use crate::xml as s3_xml;
+use garage_api_common::helpers::*;
+use garage_api_common::signature::verify_signed_content;
// ----
diff --git a/src/api/s3/post_object.rs b/src/api/s3/post_object.rs
index 5279ec6a..6416c523 100644
--- a/src/api/s3/post_object.rs
+++ b/src/api/s3/post_object.rs
@@ -16,15 +16,15 @@ use serde::Deserialize;
use garage_model::garage::Garage;
use garage_model::s3::object_table::*;
-use crate::helpers::*;
-use crate::s3::api_server::ResBody;
-use crate::s3::checksum::*;
-use crate::s3::cors::*;
-use crate::s3::encryption::EncryptionParams;
-use crate::s3::error::*;
-use crate::s3::put::{get_headers, save_stream, ChecksumMode};
-use crate::s3::xml as s3_xml;
-use crate::signature::payload::{verify_v4, Authorization};
+use crate::api_server::ResBody;
+use crate::checksum::*;
+use crate::cors::*;
+use crate::encryption::EncryptionParams;
+use crate::error::*;
+use crate::put::{get_headers, save_stream, ChecksumMode};
+use crate::xml as s3_xml;
+use garage_api_common::helpers::*;
+use garage_api_common::signature::payload::{verify_v4, Authorization};
pub async fn handle_post_object(
garage: Arc<Garage>,
diff --git a/src/api/s3/put.rs b/src/api/s3/put.rs
index bfb0dc9b..47dcb8f7 100644
--- a/src/api/s3/put.rs
+++ b/src/api/s3/put.rs
@@ -30,11 +30,11 @@ use garage_model::s3::block_ref_table::*;
use garage_model::s3::object_table::*;
use garage_model::s3::version_table::*;
-use crate::helpers::*;
-use crate::s3::api_server::{ReqBody, ResBody};
-use crate::s3::checksum::*;
-use crate::s3::encryption::EncryptionParams;
-use crate::s3::error::*;
+use crate::api_server::{ReqBody, ResBody};
+use crate::checksum::*;
+use crate::encryption::EncryptionParams;
+use crate::error::*;
+use garage_api_common::helpers::*;
const PUT_BLOCKS_MAX_PARALLEL: usize = 3;
diff --git a/src/api/s3/router.rs b/src/api/s3/router.rs
index e7ac1d77..94951e80 100644
--- a/src/api/s3/router.rs
+++ b/src/api/s3/router.rs
@@ -3,9 +3,9 @@ use std::borrow::Cow;
use hyper::header::HeaderValue;
use hyper::{HeaderMap, Method, Request};
-use crate::helpers::Authorization;
-use crate::router_macros::{generateQueryParameters, router_match};
-use crate::s3::error::*;
+use crate::error::*;
+use garage_api_common::helpers::Authorization;
+use garage_api_common::router_macros::{generateQueryParameters, router_match};
router_match! {@func
diff --git a/src/api/s3/website.rs b/src/api/s3/website.rs
index fa36bc32..46decccf 100644
--- a/src/api/s3/website.rs
+++ b/src/api/s3/website.rs
@@ -4,11 +4,11 @@ use http_body_util::BodyExt;
use hyper::{Request, Response, StatusCode};
use serde::{Deserialize, Serialize};
-use crate::helpers::*;
-use crate::s3::api_server::{ReqBody, ResBody};
-use crate::s3::error::*;
-use crate::s3::xml::{to_xml_with_header, xmlns_tag, IntValue, Value};
-use crate::signature::verify_signed_content;
+use crate::api_server::{ReqBody, ResBody};
+use crate::error::*;
+use crate::xml::{to_xml_with_header, xmlns_tag, IntValue, Value};
+use garage_api_common::helpers::*;
+use garage_api_common::signature::verify_signed_content;
use garage_model::bucket_table::*;
use garage_util::data::*;
diff --git a/src/api/s3/xml.rs b/src/api/s3/xml.rs
index 1e569ade..e8af3ec0 100644
--- a/src/api/s3/xml.rs
+++ b/src/api/s3/xml.rs
@@ -1,7 +1,7 @@
use quick_xml::se::to_string;
use serde::{Deserialize, Serialize, Serializer};
-use crate::s3::error::Error as ApiError;
+use crate::error::Error as ApiError;
pub fn to_xml_with_header<T: Serialize>(x: &T) -> Result<String, ApiError> {
let mut xml = r#"<?xml version="1.0" encoding="UTF-8"?>"#.to_string();
diff --git a/src/garage/Cargo.toml b/src/garage/Cargo.toml
index 483e33c0..6782b142 100644
--- a/src/garage/Cargo.toml
+++ b/src/garage/Cargo.toml
@@ -23,7 +23,10 @@ path = "tests/lib.rs"
[dependencies]
format_table.workspace = true
garage_db.workspace = true
-garage_api.workspace = true
+garage_api_common.workspace = true
+garage_api_admin.workspace = true
+garage_api_s3.workspace = true
+garage_api_k2v = { workspace = true, optional = true }
garage_block.workspace = true
garage_model.workspace = true
garage_net.workspace = true
@@ -84,7 +87,7 @@ k2v-client.workspace = true
[features]
default = [ "bundled-libs", "metrics", "lmdb", "sqlite", "k2v" ]
-k2v = [ "garage_util/k2v", "garage_api/k2v" ]
+k2v = [ "garage_util/k2v", "garage_api_k2v" ]
# Database engines
lmdb = [ "garage_model/lmdb" ]
@@ -95,7 +98,7 @@ consul-discovery = [ "garage_rpc/consul-discovery" ]
# Automatic registration and discovery via Kubernetes API
kubernetes-discovery = [ "garage_rpc/kubernetes-discovery" ]
# Prometheus exporter (/metrics endpoint).
-metrics = [ "garage_api/metrics", "opentelemetry-prometheus", "prometheus" ]
+metrics = [ "garage_api_common/metrics", "opentelemetry-prometheus", "prometheus" ]
# Exporter for the OpenTelemetry Collector.
telemetry-otlp = [ "opentelemetry-otlp" ]
# Logging to syslog
diff --git a/src/web/Cargo.toml b/src/web/Cargo.toml
index d810d6f9..3f1c2470 100644
--- a/src/web/Cargo.toml
+++ b/src/web/Cargo.toml
@@ -14,7 +14,8 @@ path = "lib.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-garage_api.workspace = true
+garage_api_common.workspace = true
+garage_api_s3.workspace = true
garage_model.workspace = true
garage_util.workspace = true
garage_table.workspace = true