Skip to content

feat: Make OPENSEARCH_HOME and OPENSEARCH_PATH_CONF overridable #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ All notable changes to this project will be documented in this file.
- PodDisruptionBudgets
- Replicas
- Add Listener support ([#17]).
- Make the environment variables `OPENSEARCH_HOME` and `OPENSEARCH_PATH_CONF` overridable, so that
images can be used which have a different directory structure than the Stackable image ([#18]).

[#10]: https://github.com/stackabletech/opensearch-operator/pull/10
[#17]: https://github.com/stackabletech/opensearch-operator/pull/17
[#18]: https://github.com/stackabletech/opensearch-operator/pull/18
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ nodes:
default:
config: {}
envOverrides:
OPENSEARCH_PATH_CONF: /etc/opensearch
OPENSEARCH_HOME: /usr/share/opensearch
----

or per role:
Expand All @@ -140,12 +140,21 @@ or per role:
----
nodes:
envOverrides:
OPENSEARCH_PATH_CONF: /etc/opensearch
OPENSEARCH_HOME: /usr/share/opensearch
roleGroups:
default:
config: {}
----

The environment variables `OPENSEARCH_HOME` and `OPENSEARCH_PATH_CONF` are worth mentioning.
`OPENSEARCH_HOME` contains the path in the image where OpenSearch is installed.
`OPENSEARCH_PATH_CONF` contains the path with the OpenSearch configuration files.
They are usually set in the image.
In the Stackable image, `OPENSEARCH_HOME` is set to `/stackable/opensearch` and `OPENSEARCH_PATH_CONF` to `$\{OPENSEARCH_HOME}/config`.
The operator must also know the values of these environment variables to mount volumes to the correct paths.
Since the operator cannot read the values from the image, it assumes the ones from the Stackable image.
If you use a custom image with different paths, you can override one or both of these environment variables as shown in the example above.

== CLI parameters

CLI parameters can be set with `cliOverrides` per role group:
Expand Down
25 changes: 19 additions & 6 deletions rust/operator-binary/src/controller/build/role_group_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ const DATA_VOLUME_NAME: &str = "data";
const LISTENER_VOLUME_NAME: &str = "listener";
const LISTENER_VOLUME_DIR: &str = "/stackable/listener";

// Path in opensearchproject/opensearch:3.0.0
const OPENSEARCH_BASE_PATH: &str = "/stackable/opensearch";
const DEFAULT_OPENSEARCH_HOME: &str = "/stackable/opensearch";

pub struct RoleGroupBuilder<'a> {
service_account_name: String,
Expand Down Expand Up @@ -271,26 +270,40 @@ impl<'a> RoleGroupBuilder<'a> {
..Probe::default()
};

let env_vars = self.node_config.environment_variables();

// Use `OPENSEARCH_HOME` from envOverrides or default to `DEFAULT_OPENSEARCH_HOME`.
let opensearch_home = env_vars
.get_env_var("OPENSEARCH_HOME")
.and_then(|env_var| env_var.value.clone())
.unwrap_or(DEFAULT_OPENSEARCH_HOME.to_owned());
// Use `OPENSEARCH_PATH_CONF` from envOverrides or default to `{OPENSEARCH_HOME}/config`,
// i.e. depend on `OPENSEARCH_HOME`.
let opensearch_path_conf = env_vars
.get_env_var("OPENSEARCH_PATH_CONF")
.and_then(|env_var| env_var.value.clone())
.unwrap_or(format!("{opensearch_home}/config"));

ContainerBuilder::new("opensearch")
.expect("should be a valid container name")
.image_from_product_image(&product_image)
.command(vec![format!(
"{OPENSEARCH_BASE_PATH}/opensearch-docker-entrypoint.sh"
"{opensearch_home}/opensearch-docker-entrypoint.sh"
)])
.args(role_group_config.cli_overrides_to_vec())
.add_env_vars(self.node_config.environment_variables().into())
.add_env_vars(env_vars.into())
.add_volume_mounts([
VolumeMount {
mount_path: format!(
"{OPENSEARCH_BASE_PATH}/config/{CONFIGURATION_FILE_OPENSEARCH_YML}"
"{opensearch_path_conf}/{CONFIGURATION_FILE_OPENSEARCH_YML}"
),
name: CONFIG_VOLUME_NAME.to_owned(),
read_only: Some(true),
sub_path: Some(CONFIGURATION_FILE_OPENSEARCH_YML.to_owned()),
..VolumeMount::default()
},
VolumeMount {
mount_path: format!("{OPENSEARCH_BASE_PATH}/data"),
mount_path: format!("{opensearch_home}/data"),
name: DATA_VOLUME_NAME.to_owned(),
..VolumeMount::default()
},
Expand Down
16 changes: 16 additions & 0 deletions rust/operator-binary/src/framework/builder/pod/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@ impl EnvVarSet {
Self::default()
}

pub fn get_env_var(&self, env_var_name: impl Into<EnvVarName>) -> Option<&EnvVar> {
self.0.get(&env_var_name.into())
}

pub fn add_env_var(mut self, env_var: EnvVar) -> Self {
self.0.insert(env_var.name.clone(), env_var);

self
}

pub fn merge(mut self, mut env_var_set: EnvVarSet) -> Self {
self.0.append(&mut env_var_set.0);

self
}

pub fn with_values<I, K, V>(self, env_vars: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
Expand Down
25 changes: 16 additions & 9 deletions tests/templates/kuttl/external-access/opensearch.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ metadata:
name: opensearch
spec:
image:
productVersion: 3.1.0
{% if test_scenario['values']['opensearch'].find(",") > 0 %}
custom: "{{ test_scenario['values']['opensearch'].split(',')[1] }}"
productVersion: "{{ test_scenario['values']['opensearch'].split(',')[0] }}"
{% else %}
productVersion: "{{ test_scenario['values']['opensearch'] }}"
{% endif %}
pullPolicy: IfNotPresent
nodes:
roleGroups:
Expand Down Expand Up @@ -57,6 +62,7 @@ spec:
envOverrides:
# TODO Make these the defaults in the image
DISABLE_INSTALL_DEMO_CONFIG: "true"
OPENSEARCH_HOME: {{ test_scenario['values']['opensearch_home'] }}
configOverrides:
# TODO Add the required options to the operator
opensearch.yml:
Expand All @@ -66,24 +72,25 @@ spec:
# TODO Check that this is safe despite the warning in the documentation
plugins.security.allow_default_init_securityindex: "true"
plugins.security.ssl.transport.enabled: "true"
plugins.security.ssl.transport.pemcert_filepath: /stackable/opensearch/config/tls/tls.crt
plugins.security.ssl.transport.pemkey_filepath: /stackable/opensearch/config/tls/tls.key
plugins.security.ssl.transport.pemtrustedcas_filepath: /stackable/opensearch/config/tls/ca.crt
plugins.security.ssl.transport.pemcert_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/tls.crt
plugins.security.ssl.transport.pemkey_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/tls.key
plugins.security.ssl.transport.pemtrustedcas_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/ca.crt
plugins.security.ssl.http.enabled: "true"
plugins.security.ssl.http.pemcert_filepath: /stackable/opensearch/config/tls/tls.crt
plugins.security.ssl.http.pemkey_filepath: /stackable/opensearch/config/tls/tls.key
plugins.security.ssl.http.pemtrustedcas_filepath: /stackable/opensearch/config/tls/ca.crt
plugins.security.ssl.http.pemcert_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/tls.crt
plugins.security.ssl.http.pemkey_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/tls.key
plugins.security.ssl.http.pemtrustedcas_filepath: {{ test_scenario['values']['opensearch_home'] }}/config/tls/ca.crt
plugins.security.authcz.admin_dn: "CN=generated certificate for pod"
podOverrides:
spec:
containers:
- name: opensearch
volumeMounts:
- name: security-config
mountPath: /stackable/opensearch/config/opensearch-security
mountPath: {{ test_scenario['values']['opensearch_home'] }}/config/opensearch-security
readOnly: true
- name: tls
mountPath: /stackable/opensearch/config/tls
# The Java policy allows reading from ${OPENSEARCH_HOME}/config.
mountPath: {{ test_scenario['values']['opensearch_home'] }}/config/tls
readOnly: true
securityContext:
fsGroup: 1000
Expand Down
Loading