This is an automated email from the ASF dual-hosted git repository.
ssulav pushed a commit to branch HDDS-14679
in repository https://gitbox.apache.org/repos/asf/ozone-installer.git
The following commit(s) were added to refs/heads/HDDS-14679 by this push:
new da07ed3 HDDS-14679. Separate out data and metadata base path
da07ed3 is described below
commit da07ed30642ef1eb0c08e6d74921f3b67c101a85
Author: Soumitra Sulav <[email protected]>
AuthorDate: Fri Feb 20 16:24:02 2026 +0530
HDDS-14679. Separate out data and metadata base path
---
README.md | 6 ++++--
ozone_installer.py | 15 +++++++++++----
playbooks/cluster.yml | 4 ++++
playbooks/stop_and_clean.yml | 4 ++++
roles/ozone_cleanup/tasks/main.yml | 4 ++--
roles/ozone_config/templates/ozone-site.xml.j2 | 15 ++++++++-------
roles/ozone_layout/tasks/main.yml | 9 +++++++--
7 files changed, 40 insertions(+), 17 deletions(-)
diff --git a/README.md b/README.md
index 07ef806..64ecb0c 100644
--- a/README.md
+++ b/README.md
@@ -270,7 +270,8 @@ ANSIBLE_CONFIG=ansible.cfg ansible-playbook -i
inventories/dev/hosts.ini playboo
### Directories
- Install base (`install_base`, default `/opt/ozone`): where Ozone binaries
and configs live. A `current` symlink points to the active version directory.
-- Data base (`data_base`, default `/data/ozone`): where Ozone writes on‑disk
metadata and Datanode data (e.g., `ozone.metadata.dirs`, `hdds.datanode.dir`).
Supports comma-separated multiple directories (e.g.
`/data/ozone1,/data/ozone2`) or brace expansion (e.g. `/data/ozone{1..3}` →
`/data/ozone1,/data/ozone2,/data/ozone3`); each path gets `dn`, `meta`,
`data/om`, etc. subdirs in `ozone-site.xml`.
+- Data base (`data_base`, `-dd`/`--data-dir`, default `/data/ozone`): Datanode
block storage; maps to `hdds.datanode.dir`. Supports comma-separated multiple
directories (e.g. `/data/ozone1,/data/ozone2`) or brace expansion (e.g.
`/data/ozone{1..3}`); each path gets a `dn` subdir.
+- Metadata base (`metadata_base`, `-md`/`--metadata-dir`, default: same as
`data_base`): Metadata storage for `ozone.metadata.dirs`, `ozone.om.db.dirs`,
`ozone.scm.db.dirs`, etc. Supports comma-separated dirs or brace expansion;
each path gets `meta`, `data/om`, `data/scm`, etc. subdirs.
## Components and config mapping
@@ -279,7 +280,8 @@ ANSIBLE_CONFIG=ansible.cfg ansible-playbook -i
inventories/dev/hosts.ini playboo
- **Legacy mode** (`-H`/`-F`): Non‑HA: first host runs OM+SCM+Recon; all
hosts are DNs. HA: first three hosts serve as OM and SCM sets; all hosts are
DNs; first host is Recon.
- `ozone-site.xml` is rendered from templates based on inventory groups:
- `ozone.scm.names`, `ozone.scm.client.address`, `ozone.om.address` or HA
service IDs
- - `ozone.metadata.dirs`, `hdds.datanode.dir`, and related paths map to
`data_base` (comma-separated dirs are expanded per property)
+ - `hdds.datanode.dir` maps to `data_base` (comma-separated dirs expanded per
path)
+ - `ozone.metadata.dirs`, `ozone.om.db.dirs`, `ozone.scm.db.dirs`, and
related paths map to `metadata_base` (defaults to `data_base` when not
specified)
- Replication is set to ONE if DN count < 3, otherwise THREE
## Optional: S3 Gateway (S3G) and smoke
diff --git a/ozone_installer.py b/ozone_installer.py
index 15b9ef5..f512e6f 100755
--- a/ozone_installer.py
+++ b/ozone_installer.py
@@ -95,7 +95,8 @@ def parse_args(argv: List[str]) -> argparse.Namespace:
p.add_argument("-k", "--keyfile", help="SSH private key file (for
--auth-method=key)")
p.add_argument("-v", "--version", help="Ozone version (e.g., 2.0.0) or
'local'")
p.add_argument("-i", "--install-dir", help=f"Install root (default:
{DEFAULTS['install_base']})")
- p.add_argument("-d", "--data-dir", help=f"Data root(s), comma-separated or
brace expansion e.g. /data/ozone{{1..3}} (default: {DEFAULTS['data_base']})")
+ p.add_argument("-dd", "--data-dir", help=f"Datanode block storage dir(s),
maps to hdds.datanode.dir; comma-separated or brace expansion e.g.
/data/ozone{{1..3}} (default: {DEFAULTS['data_base']})")
+ p.add_argument("-md", "--metadata-dir", help=f"Metadata dir(s) for
ozone.metadata.dirs, ozone.om.db.dirs, etc.; comma-separated or brace expansion
(default: same as --data-dir)")
p.add_argument("-s", "--start", action="store_true", help="Initialize and
start after install")
p.add_argument("-M", "--cluster-mode", choices=["non-ha", "ha"],
help="Force cluster mode (default: auto by host count)")
p.add_argument("-r", "--role-file", help="Role file (YAML) for HA mapping
(optional)")
@@ -602,8 +603,10 @@ def main(argv: List[str]) -> int:
install_base = args.install_dir or (last_cfg.get("install_base") if
last_cfg else None) or prompt("Install directory to remove",
default=DEFAULTS["install_base"], yes_mode=yes)
data_base_raw = args.data_dir or (last_cfg.get("data_base") if
last_cfg else None) or prompt("Data directory to remove",
default=DEFAULTS["data_base"], yes_mode=yes)
data_base = parse_data_dirs(data_base_raw) if data_base_raw else
(data_base_raw or DEFAULTS["data_base"])
+ metadata_base_raw = getattr(args, "metadata_dir", None) or
(last_cfg.get("metadata_base") if last_cfg else None) or data_base
+ metadata_base = parse_data_dirs(metadata_base_raw) if
metadata_base_raw else (metadata_base_raw or data_base)
playbook = PLAYBOOKS_DIR / "stop_and_clean.yml"
- extra_vars = {"cluster_mode": cluster_mode, "ssh_user": ssh_user,
"install_base": install_base, "data_base": data_base, "controller_logs_dir":
str(LOGS_DIR)}
+ extra_vars = {"cluster_mode": cluster_mode, "ssh_user": ssh_user,
"install_base": install_base, "data_base": data_base, "metadata_base":
metadata_base, "controller_logs_dir": str(LOGS_DIR)}
logger.info("Running stop and clean on cluster...")
else:
# Full install: resolve version, paths, service config, etc.
@@ -631,8 +634,10 @@ def main(argv: List[str]) -> int:
install_base = args.install_dir or (last_cfg.get("install_base") if
last_cfg else None) \
or prompt("Install directory (base directory path to store ozone
binaries, configs and logs)", default=DEFAULTS["install_base"], yes_mode=yes)
data_base_raw = args.data_dir or (last_cfg.get("data_base") if
last_cfg else None) \
- or prompt("Data directory (base path(s), comma-separated or brace
expansion e.g. /data/ozone{1..3})", default=DEFAULTS["data_base"], yes_mode=yes)
+ or prompt("Data directory (hdds.datanode.dir; base path(s),
comma-separated or brace expansion e.g. /data/ozone{1..3})",
default=DEFAULTS["data_base"], yes_mode=yes)
data_base = parse_data_dirs(data_base_raw) if data_base_raw else
(data_base_raw or DEFAULTS["data_base"])
+ metadata_base_raw = getattr(args, "metadata_dir", None) or
(last_cfg.get("metadata_base") if last_cfg else None) or data_base
+ metadata_base = parse_data_dirs(metadata_base_raw) if
metadata_base_raw else (metadata_base_raw or data_base)
service_user = args.service_user or (last_cfg.get("service_user") if
last_cfg else None) \
or prompt("Service user name ", default=DEFAULTS["service_user"],
yes_mode=yes)
@@ -694,7 +699,8 @@ def main(argv: List[str]) -> int:
("Ozone version", str(ozone_version)),
("JDK major", str(jdk_major)),
("Install directory", str(install_base)),
- ("Data directory", str(data_base)),
+ ("Data directory (hdds.datanode.dir)", str(data_base)),
+ ("Metadata directory (ozone.metadata.dirs, etc.)",
str(metadata_base)),
("SSH user", str(ssh_user)),
("SSH auth method", str(auth_method))
]
@@ -730,6 +736,7 @@ def main(argv: List[str]) -> int:
"cluster_mode": cluster_mode,
"install_base": install_base,
"data_base": data_base,
+ "metadata_base": metadata_base,
"jdk_major": jdk_major,
"service_user": service_user,
"service_group": service_group,
diff --git a/playbooks/cluster.yml b/playbooks/cluster.yml
index fd0389c..1420f1b 100644
--- a/playbooks/cluster.yml
+++ b/playbooks/cluster.yml
@@ -28,6 +28,10 @@
set_fact:
data_base_list: "{{ ((data_base | default('')).split(',') |
map('trim') | select | list) | default([data_base | default('/data/ozone')],
true) }}"
+ - name: "Pre-install: Parse metadata_base into list (supports
comma-separated dirs)"
+ set_fact:
+ metadata_base_list: "{{ ((metadata_base | default(data_base) |
default('')).split(',') | map('trim') | select | list) | default([metadata_base
| default(data_base) | default('/data/ozone')], true) }}"
+
- name: "Pre-install: Gather facts"
setup:
diff --git a/playbooks/stop_and_clean.yml b/playbooks/stop_and_clean.yml
index 2c77a6a..1920614 100644
--- a/playbooks/stop_and_clean.yml
+++ b/playbooks/stop_and_clean.yml
@@ -22,6 +22,10 @@
set_fact:
data_base_list: "{{ ((data_base | default('')).split(',') |
map('trim') | select | list) | default([data_base | default('/data/ozone')],
true) }}"
+ - name: "Parse metadata_base into list"
+ set_fact:
+ metadata_base_list: "{{ ((metadata_base | default(data_base) |
default('')).split(',') | map('trim') | select | list) | default([metadata_base
| default(data_base) | default('/data/ozone')], true) }}"
+
- name: "Gather facts"
setup:
diff --git a/roles/ozone_cleanup/tasks/main.yml
b/roles/ozone_cleanup/tasks/main.yml
index 9a0095e..c190ac7 100644
--- a/roles/ozone_cleanup/tasks/main.yml
+++ b/roles/ozone_cleanup/tasks/main.yml
@@ -39,11 +39,11 @@
state: absent
become: true
- - name: "Remove data directories"
+ - name: "Remove data and metadata directories"
file:
path: "{{ item }}"
state: absent
- loop: "{{ data_base_list | default([data_base | default('/data/ozone')])
}}"
+ loop: "{{ ((data_base_list | default([data_base |
default('/data/ozone')])) + (metadata_base_list | default([metadata_base |
default(data_base) | default('/data/ozone')]))) | unique }}"
become: true
diff --git a/roles/ozone_config/templates/ozone-site.xml.j2
b/roles/ozone_config/templates/ozone-site.xml.j2
index db8d458..3b8b967 100644
--- a/roles/ozone_config/templates/ozone-site.xml.j2
+++ b/roles/ozone_config/templates/ozone-site.xml.j2
@@ -17,7 +17,8 @@
<configuration>
<!-- Minimal Ozone site config; extend via group_vars if needed -->
{% set _data_bases = data_base_list | default([data_base |
default('/data/ozone')]) %}
-{% set _first_disk = _data_bases | first %}
+{% set _metadata_bases = metadata_base_list | default([metadata_base |
default(data_base) | default('/data/ozone')]) %}
+{% set _first_metadata = _metadata_bases | first %}
{% set _om_all = groups.get('om', [])| list %}
{% set _scm_all = groups.get('scm', []) | list %}
{% set _all_dn_count = groups.get('datanodes', []) | list | length %}
@@ -103,7 +104,7 @@
{% endif %}
<property>
<name>ozone.metadata.dirs</name>
- <value>{{ _first_disk }}/meta</value>
+ <value>{{ _first_metadata }}/meta</value>
</property>
<property>
<name>hdds.datanode.dir</name>
@@ -111,23 +112,23 @@
</property>
<property>
<name>dfs.container.ratis.datanode.storage.dir</name>
- <value>{{ _first_disk }}/meta/dn</value>
+ <value>{{ _first_metadata }}/meta/dn</value>
</property>
<property>
<name>ozone.om.db.dirs</name>
- <value>{{ _first_disk }}/data/om</value>
+ <value>{{ _first_metadata }}/data/om</value>
</property>
<property>
<name>ozone.om.ratis.snapshot.dir</name>
- <value>{{ _first_disk }}/meta/om</value>
+ <value>{{ _first_metadata }}/meta/om</value>
</property>
<property>
<name>ozone.scm.db.dirs</name>
- <value>{{ _first_disk }}/data/scm</value>
+ <value>{{ _first_metadata }}/data/scm</value>
</property>
<property>
<name>ozone.scm.datanode.id.dir</name>
- <value>{{ _first_disk }}/meta/scm</value>
+ <value>{{ _first_metadata }}/meta/scm</value>
</property>
<property>
<name>ozone.scm.skip.bootstrap.validation</name>
diff --git a/roles/ozone_layout/tasks/main.yml
b/roles/ozone_layout/tasks/main.yml
index 43c5c44..4ca880c 100644
--- a/roles/ozone_layout/tasks/main.yml
+++ b/roles/ozone_layout/tasks/main.yml
@@ -14,14 +14,19 @@
# limitations under the License.
---
-- name: "Create install and data directories"
+- name: "Create install, data (hdds.datanode.dir) and metadata directories"
file:
path: "{{ item }}"
state: directory
owner: "{{ service_user }}"
group: "{{ service_group }}"
mode: "0755"
- loop: "{{ [install_base] + (data_base_list | default([data_base |
default('/data/ozone')]) | product(['', '/dn', '/meta']) | map('join', '') |
list) }}"
+ loop: >-
+ {{
+ [install_base]
+ + (data_base_list | default([data_base | default('/data/ozone')]) |
map('regex_replace', '$', '/dn') | list)
+ + (metadata_base_list | default([metadata_base | default(data_base) |
default('/data/ozone')]) | product(['/meta', '/meta/dn', '/data/om',
'/meta/om', '/data/scm', '/meta/scm']) | map('join') | list)
+ }}
become: true
- name: "Ensure OZONE_HOME and PATH are in profile.d/ozone.sh"
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]