Skip to content

Commit 61fa7e5

Browse files
committed
Merge remote-tracking branch 'origin/main' into refactor/remove-product-config
2 parents d3587d1 + ecea5fc commit 61fa7e5

5 files changed

Lines changed: 111 additions & 32 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ All notable changes to this project will be documented in this file.
77
### Added
88

99
- BREAKING: Add required CLI argument and env var to set the image repository used to construct final product image names: `IMAGE_REPOSITORY` (`--image-repository`), eg. `oci.example.org/my/namespace` ([#818]).
10-
- Support OIDC `clientAuthenticationMethod` configuration ([#813]).
10+
- Add support for OIDC `clientAuthenticationMethod` configuration ([#813]).
11+
- Add support for Druid 37.0.0 ([#832]).
1112

1213
### Changed
1314

@@ -23,7 +24,8 @@ All notable changes to this project will be documented in this file.
2324

2425
### Deleted
2526

26-
- Removed all metadata storage related properties from product config ([#814]).
27+
- Remove all metadata storage related properties from product config ([#814]).
28+
- Remove support for Druid 34.0.0 ([#832]).
2729

2830
[#810]: https://github.com/stackabletech/druid-operator/pull/810
2931
[#813]: https://github.com/stackabletech/druid-operator/pull/813
@@ -32,6 +34,7 @@ All notable changes to this project will be documented in this file.
3234
[#824]: https://github.com/stackabletech/druid-operator/pull/824
3335
[#826]: https://github.com/stackabletech/druid-operator/pull/826
3436
[#830]: https://github.com/stackabletech/druid-operator/pull/830
37+
[#832]: https://github.com/stackabletech/druid-operator/pull/832
3538

3639
## [26.3.0] - 2026-03-16
3740

docs/modules/druid/partials/supported-versions.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
// This is a separate file, since it is used by both the direct Druid documentation, and the overarching
33
// Stackable Platform documentation.
44

5-
- 35.0.1
6-
- 34.0.0 (deprecated)
7-
- 30.0.1 (LTS)
5+
- 37.0.0 (LTS)
6+
- 35.0.1 (Deprecated)
7+
- 30.0.1 (Deprecated)

rust/operator-binary/src/controller/build/jvm.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use semver::Version;
12
use snafu::{ResultExt, Snafu};
23
use stackable_operator::{
3-
memory::MemoryQuantity, v2::jvm_argument_overrides::JvmArgumentOverrides,
4+
crd::s3::v1alpha1::ConnectionSpec, memory::MemoryQuantity,
5+
v2::jvm_argument_overrides::JvmArgumentOverrides,
46
};
57

68
use super::properties::ConfigFileName;
@@ -12,6 +14,11 @@ use crate::crd::{
1214
/// The Derby error log file, written by the Coordinator's embedded Derby (default metadata store).
1315
const DERBY_LOG_FILE: &str = "/stackable/var/druid/derby.log";
1416

17+
/// AWS Region JVM system property, passed to the AWS SDK v2 (used by Druid >= 37.0.0).
18+
/// Rendered both into `jvm.config` and into the MiddleManager Peon JVM opts.
19+
/// See: <https://druid.apache.org/docs/latest/development/extensions-core/s3/#aws-region>
20+
pub(crate) const AWS_REGION: &str = "aws.region";
21+
1522
#[derive(Snafu, Debug)]
1623
pub enum Error {
1724
#[snafu(display("failed to format memory quantity {value:?} for Java"))]
@@ -28,6 +35,9 @@ pub fn construct_jvm_args(
2835
jvm_argument_overrides: &JvmArgumentOverrides,
2936
heap: MemoryQuantity,
3037
direct_memory: Option<MemoryQuantity>,
38+
s3_conn: Option<&ConnectionSpec>,
39+
// TODO (@NickLarsenNZ): Remove this once we don't support Druid less than 37.0.0
40+
druid_version: Result<Version, semver::Error>,
3141
) -> Result<String, Error> {
3242
let heap_str = heap
3343
.format_for_java()
@@ -67,6 +77,18 @@ pub fn construct_jvm_args(
6777
if druid_role == &DruidRole::Coordinator {
6878
jvm_args.push(format!("-Dderby.stream.error.file={DERBY_LOG_FILE}"));
6979
}
80+
// TODO (@NickLarsenNZ): Remove the condition (keep the body) once we no longer support Druid
81+
// less than 37.0.0
82+
// Druid >= 37.0.0 uses the AWS SDK v2, which requires a region to be set via the JVM system
83+
// property `aws.region`.
84+
if matches!(&druid_version, Ok(v) if *v >= Version::new(37, 0, 0))
85+
&& let Some(s3) = s3_conn
86+
{
87+
jvm_args.push(format!(
88+
"-D{AWS_REGION}={region_name}",
89+
region_name = s3.region.name
90+
));
91+
}
7092

7193
Ok(jvm_argument_overrides.apply_to(jvm_args).join("\n"))
7294
}
@@ -258,6 +280,10 @@ mod tests {
258280
&rg.product_specific_common_config.jvm_argument_overrides,
259281
heap,
260282
direct,
283+
// No S3 connection in these tests, so the region (and the version gating it) is never
284+
// rendered into the JVM args.
285+
None,
286+
Version::parse("37.0.0"),
261287
)
262288
.unwrap()
263289
}

rust/operator-binary/src/controller/build/resource/config_map.rs

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
1414
use std::collections::BTreeMap;
1515

16+
use semver::Version;
1617
use snafu::{ResultExt, Snafu};
1718
use stackable_operator::{
1819
builder::configmap::ConfigMapBuilder,
@@ -26,7 +27,7 @@ use crate::{
2627
controller::{
2728
build::{
2829
authentication::generate_runtime_properties_config as generate_auth_runtime_properties,
29-
jvm::construct_jvm_args,
30+
jvm::{AWS_REGION, construct_jvm_args},
3031
properties::{
3132
ConfigFileName,
3233
extensions::get_extension_list,
@@ -51,6 +52,7 @@ const S3_ENDPOINT_URL: &str = "druid.s3.endpoint.url";
5152
const S3_ACCESS_KEY: &str = "druid.s3.accessKey";
5253
const S3_SECRET_KEY: &str = "druid.s3.secretKey";
5354
const S3_PATH_STYLE_ACCESS: &str = "druid.s3.enablePathStyleAccess";
55+
const S3_USE_TRANSFER_MANAGER: &str = "druid.storage.transfer.useTransferManager";
5456
const AUTH_AUTHORIZER_OPA_URI: &str = "druid.auth.authorizer.OpaAuthorizer.opaUri";
5557

5658
#[derive(Snafu, Debug)]
@@ -101,15 +103,30 @@ const INDEXER_JAVA_OPTS: &str = "druid.indexer.runner.javaOptsArray";
101103

102104
/// The `druid.indexer.runner.javaOptsArray` entry that must be present in *every* rendered file
103105
/// (runtime.properties and security.properties) for MiddleManagers.
104-
fn middlemanager_indexer_java_opts() -> (String, String) {
105-
(
106-
INDEXER_JAVA_OPTS.to_string(),
107-
build_string_list(&[
108-
format!("-Djavax.net.ssl.trustStore={STACKABLE_TRUST_STORE}"),
109-
format!("-Djavax.net.ssl.trustStorePassword={STACKABLE_TRUST_STORE_PASSWORD}"),
110-
format!("-Djavax.net.ssl.trustStoreType={STACKABLE_TRUST_STORE_TYPE}"),
111-
]),
112-
)
106+
fn middlemanager_indexer_java_opts(
107+
s3_conn: Option<&s3::v1alpha1::ConnectionSpec>,
108+
druid_version: &Result<Version, semver::Error>,
109+
) -> (String, String) {
110+
let mut java_opts = vec![
111+
format!("-Djavax.net.ssl.trustStore={STACKABLE_TRUST_STORE}"),
112+
format!("-Djavax.net.ssl.trustStorePassword={STACKABLE_TRUST_STORE_PASSWORD}"),
113+
format!("-Djavax.net.ssl.trustStoreType={STACKABLE_TRUST_STORE_TYPE}"),
114+
];
115+
116+
// TODO (@NickLarsenNZ): Remove the condition (keep the body) once we no longer support Druid
117+
// less than 37.0.0.
118+
// Druid >= 37.0.0 uses the AWS SDK v2, which requires a region to be set via the JVM system
119+
// property `aws.region` for the Peon processes spawned by the MiddleManager.
120+
if matches!(druid_version, Ok(v) if *v >= Version::new(37, 0, 0))
121+
&& let Some(s3) = s3_conn
122+
{
123+
java_opts.push(format!(
124+
"-D{AWS_REGION}={region_name}",
125+
region_name = s3.region.name
126+
));
127+
}
128+
129+
(INDEXER_JAVA_OPTS.to_string(), build_string_list(&java_opts))
113130
}
114131

115132
/// Returns the user-supplied key/value overrides for the given config file from a
@@ -142,6 +159,8 @@ pub fn build_rolegroup_config_map(
142159
let opa_connstr = cluster_config.opa_connection_string.as_deref();
143160
let s3_conn = cluster_config.s3_connection.as_ref();
144161
let deep_storage_bucket_name = cluster_config.deep_storage_bucket_name.as_deref();
162+
// TODO (@NickLarsenNZ): Remove this once we don't support Druid less than 37.0.0
163+
let druid_version = Version::parse(&cluster.image.product_version);
145164

146165
let mut cm_conf_data = BTreeMap::new(); // filename -> filecontent
147166
let metadata_database_connection_details = &cluster_config.metadata_db_connection;
@@ -220,15 +239,39 @@ pub fn build_rolegroup_config_map(
220239
}
221240

222241
if let Some(s3) = s3_conn {
223-
if !s3.region.is_default_config() {
224-
// Raising this as warning instead of returning an error, better safe than sorry.
225-
// It might still work out for the user.
226-
tracing::warn!(
227-
region = ?s3.region,
228-
"You configured a non-default region on the S3Connection.
229-
The S3Connection region field is ignored because Druid uses the AWS SDK v1, which ignores the region if the endpoint is set. \
230-
The host is a required field, therefore the endpoint will always be set."
231-
)
242+
// TODO (@NickLarsenNZ): Remove the version condition once we no longer support Druid
243+
// less than 37.0.0.
244+
// Druid >= 37.0.0 uses the AWS SDK v2, which requires a region (set via the JVM system
245+
// property `-Daws.region` in the jvm.config section below). Older versions use the AWS
246+
// SDK v1, which ignores the region when an endpoint is set (and the endpoint is always
247+
// set because `host` is a required field on the S3Connection).
248+
match &druid_version {
249+
Ok(v) if *v < Version::new(37, 0, 0) => {
250+
if !s3.region.is_default_config() {
251+
// Raising this as warning instead of returning an error, better safe than
252+
// sorry. It might still work out for the user.
253+
tracing::warn!(
254+
region = ?s3.region,
255+
"You configured a non-default region on the S3Connection. \
256+
The S3Connection region field is ignored because this Druid version uses the AWS SDK v1, which ignores the region if the endpoint is set. \
257+
The host is a required field, therefore the endpoint will always be set."
258+
);
259+
}
260+
}
261+
Err(err) => {
262+
tracing::warn!(
263+
%err,
264+
version = %cluster.image.product_version,
265+
"Failed to parse Druid product version, skipping S3 region configuration"
266+
);
267+
}
268+
// For Druid >= 37.0.0 the region is set via the JVM system property `-Daws.region`
269+
// in the jvm.config section below.
270+
Ok(_) => {
271+
// Disable the S3 Transfer Manager to avoid the AWS CRT async HTTP client, which
272+
// fails against non-AWS S3 endpoints.
273+
conf.insert(S3_USE_TRANSFER_MANAGER.to_string(), "false".to_string());
274+
}
232275
}
233276

234277
conf.insert(
@@ -271,7 +314,7 @@ pub fn build_rolegroup_config_map(
271314
cluster_config.opa_connection_string.is_some(),
272315
));
273316
if *role == DruidRole::MiddleManager {
274-
let (k, v) = middlemanager_indexer_java_opts();
317+
let (k, v) = middlemanager_indexer_java_opts(s3_conn, &druid_version);
275318
conf.insert(k, v);
276319
}
277320
conf.extend(runtime_properties::defaults(role));
@@ -300,6 +343,10 @@ pub fn build_rolegroup_config_map(
300343
&rg.product_specific_common_config.jvm_argument_overrides,
301344
heap,
302345
direct,
346+
s3_conn,
347+
// `construct_jvm_args` takes the version by value and `semver::Error` is not `Clone`,
348+
// so re-parse here rather than cloning the `druid_version` used by reference above.
349+
Version::parse(&cluster.image.product_version),
303350
)
304351
.context(GetJvmConfigSnafu)?;
305352
cm_conf_data.insert(ConfigFileName::JvmConfig.to_string(), jvm_config);
@@ -309,7 +356,7 @@ pub fn build_rolegroup_config_map(
309356
{
310357
let mut security_config: BTreeMap<String, String> = BTreeMap::new();
311358
if *role == DruidRole::MiddleManager {
312-
let (k, v) = middlemanager_indexer_java_opts();
359+
let (k, v) = middlemanager_indexer_java_opts(s3_conn, &druid_version);
313360
security_config.insert(k, v);
314361
}
315362
let security_overrides =

tests/test-definition.yaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ dimensions:
1414
- name: druid
1515
values:
1616
- 30.0.1
17-
- 34.0.0
1817
- 35.0.1
18+
- 37.0.0
1919
# To use a custom image, add a comma and the full name after the product version
2020
# - 30.0.0,oci.stackable.tech/sdp/druid:30.0.0-stackable0.0.0-dev
2121
- name: druid-latest
2222
values:
23-
- 35.0.1
23+
- 37.0.0
2424
# To use a custom image, add a comma and the full name after the product version
2525
# - 30.0.0,oci.stackable.tech/sdp/druid:30.0.0-stackable0.0.0-dev
2626
- name: zookeeper
@@ -35,14 +35,17 @@ dimensions:
3535
- 1.16.2
3636
- name: hadoop
3737
values:
38-
- 3.4.2
38+
- 3.4.3
39+
- 3.5.0
3940
- name: hadoop-latest
4041
values:
41-
- 3.4.2
42+
- 3.5.0
4243
- name: s3-use-tls
4344
values:
4445
- "true"
45-
- "false"
46+
# Druid >= 37.0.0 (AWS SDK v2) does not support non-TLS S3 endpoints
47+
# due to SigV4 signing mismatches over HTTP.
48+
# - "false"
4649
- name: tls-mode
4750
values:
4851
- "no-tls"

0 commit comments

Comments
 (0)