aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/s3/post_object.rs22
-rw-r--r--src/db/open.rs1
-rw-r--r--src/garage/cli/structs.rs2
-rw-r--r--src/model/garage.rs2
-rw-r--r--src/rpc/Cargo.toml1
-rw-r--r--src/rpc/system.rs41
-rw-r--r--src/util/config.rs4
7 files changed, 50 insertions, 23 deletions
diff --git a/src/api/s3/post_object.rs b/src/api/s3/post_object.rs
index 2c106b3b..ff2361f1 100644
--- a/src/api/s3/post_object.rs
+++ b/src/api/s3/post_object.rs
@@ -71,21 +71,11 @@ pub async fn handle_post_object(
}
if let Ok(content) = HeaderValue::from_str(&field.text().await?) {
- match name.as_str() {
- "tag" => (/* tag need to be reencoded, but we don't support them yet anyway */),
- "acl" => {
- if params.insert("x-amz-acl", content).is_some() {
- return Err(Error::bad_request("Field 'acl' provided more than once"));
- }
- }
- _ => {
- if params.insert(&name, content).is_some() {
- return Err(Error::bad_request(format!(
- "Field '{}' provided more than once",
- name
- )));
- }
- }
+ if params.insert(&name, content).is_some() {
+ return Err(Error::bad_request(format!(
+ "Field '{}' provided more than once",
+ name
+ )));
}
}
};
@@ -222,6 +212,8 @@ pub async fn handle_post_object(
)));
}
+ // if we ever start supporting ACLs, we likely want to map "acl" to x-amz-acl" somewhere
+ // arround here to make sure the rest of the machinery takes our acl into account.
let headers = get_headers(&params)?;
let expected_checksums = ExpectedChecksums {
diff --git a/src/db/open.rs b/src/db/open.rs
index b8de3cd7..ff3bc830 100644
--- a/src/db/open.rs
+++ b/src/db/open.rs
@@ -92,6 +92,7 @@ pub fn open_db(path: &PathBuf, engine: Engine, opt: &OpenOpt) -> Result<Db> {
env_builder.map_size(map_size);
env_builder.max_readers(2048);
unsafe {
+ env_builder.flag(crate::lmdb_adapter::heed::flags::Flags::MdbNoRdAhead);
env_builder.flag(crate::lmdb_adapter::heed::flags::Flags::MdbNoMetaSync);
if !opt.fsync {
env_builder.flag(heed::flags::Flags::MdbNoSync);
diff --git a/src/garage/cli/structs.rs b/src/garage/cli/structs.rs
index 8380b5e2..6a9e6bfb 100644
--- a/src/garage/cli/structs.rs
+++ b/src/garage/cli/structs.rs
@@ -48,7 +48,7 @@ pub enum Command {
#[structopt(name = "worker", version = garage_version())]
Worker(WorkerOperation),
- /// Low-level debug operations on data blocks
+ /// Low-level node-local debug operations on data blocks
#[structopt(name = "block", version = garage_version())]
Block(BlockOperation),
diff --git a/src/model/garage.rs b/src/model/garage.rs
index 273690db..363b02dd 100644
--- a/src/model/garage.rs
+++ b/src/model/garage.rs
@@ -141,7 +141,7 @@ impl Garage {
)?)
.ok()
.and_then(|x| NetworkKey::from_slice(&x))
- .ok_or_message("Invalid RPC secret key")?;
+ .ok_or_message("Invalid RPC secret key: expected 32 bits of entropy, please check the documentation for requirements")?;
let (replication_factor, consistency_mode) = parse_replication_mode(&config)?;
diff --git a/src/rpc/Cargo.toml b/src/rpc/Cargo.toml
index 43d5568e..4c8cafd9 100644
--- a/src/rpc/Cargo.toml
+++ b/src/rpc/Cargo.toml
@@ -24,6 +24,7 @@ bytes.workspace = true
bytesize.workspace = true
gethostname.workspace = true
hex.workspace = true
+ipnet.workspace = true
tracing.workspace = true
rand.workspace = true
itertools.workspace = true
diff --git a/src/rpc/system.rs b/src/rpc/system.rs
index 0e78060b..d94d4eec 100644
--- a/src/rpc/system.rs
+++ b/src/rpc/system.rs
@@ -844,12 +844,20 @@ impl NodeStatus {
}
}
-fn get_default_ip() -> Option<IpAddr> {
+/// Obtain the list of currently available IP addresses on all non-loopback
+/// interfaces, optionally filtering them to be inside a given IpNet.
+fn get_default_ip(filter_ipnet: Option<ipnet::IpNet>) -> Option<IpAddr> {
pnet_datalink::interfaces()
- .iter()
- .find(|e| e.is_up() && !e.is_loopback() && !e.ips.is_empty())
- .and_then(|e| e.ips.first())
- .map(|a| a.ip())
+ .into_iter()
+ // filter down and loopback interfaces
+ .filter(|i| i.is_up() && !i.is_loopback())
+ // get all IPs
+ .flat_map(|e| e.ips)
+ // optionally, filter to be inside filter_ipnet
+ .find(|ipn| {
+ filter_ipnet.is_some_and(|ipnet| ipnet.contains(&ipn.ip())) || filter_ipnet.is_none()
+ })
+ .map(|ipn| ipn.ip())
}
fn get_rpc_public_addr(config: &Config) -> Option<SocketAddr> {
@@ -877,7 +885,28 @@ fn get_rpc_public_addr(config: &Config) -> Option<SocketAddr> {
}
}
None => {
- let addr = get_default_ip().map(|ip| SocketAddr::new(ip, config.rpc_bind_addr.port()));
+ // `No rpc_public_addr` specified, try to discover one, optionally filtering by `rpc_public_addr_subnet`.
+ let filter_subnet: Option<ipnet::IpNet> = config
+ .rpc_public_addr_subnet
+ .as_ref()
+ .and_then(|filter_subnet_str| match filter_subnet_str.parse::<ipnet::IpNet>() {
+ Ok(filter_subnet) => {
+ let filter_subnet_trunc = filter_subnet.trunc();
+ if filter_subnet_trunc != filter_subnet {
+ warn!("`rpc_public_addr_subnet` changed after applying netmask, continuing with {}", filter_subnet.trunc());
+ }
+ Some(filter_subnet_trunc)
+ }
+ Err(e) => {
+ panic!(
+ "Cannot parse rpc_public_addr_subnet {} from config file: {}. Bailing out.",
+ filter_subnet_str, e
+ );
+ }
+ });
+
+ let addr = get_default_ip(filter_subnet)
+ .map(|ip| SocketAddr::new(ip, config.rpc_bind_addr.port()));
if let Some(a) = addr {
warn!("Using autodetected rpc_public_addr: {}. Consider specifying it explicitly in configuration file if possible.", a);
}
diff --git a/src/util/config.rs b/src/util/config.rs
index 028f8c68..59329c0b 100644
--- a/src/util/config.rs
+++ b/src/util/config.rs
@@ -85,6 +85,10 @@ pub struct Config {
/// Public IP address of this node
pub rpc_public_addr: Option<String>,
+ /// In case `rpc_public_addr` was not set, this can filter
+ /// the addresses announced to other peers to a specific subnet.
+ pub rpc_public_addr_subnet: Option<String>,
+
/// Timeout for Netapp's ping messagess
pub rpc_ping_timeout_msec: Option<u64>,
/// Timeout for Netapp RPC calls