From a3b9b4c0c3fc7cd7bb91b519f3d853e87196df42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriele=20Fronz=C3=A9?= Date: Mon, 10 Aug 2026 15:39:16 +0200 Subject: [PATCH 1/3] feat: centralize AtomOS filesystem path definitions Introduces `paths.json` to define all system and application-specific filesystem paths in a single location. `paths.py` provides a Python module to access these paths as attributes and helper functions for common path constructions. Unit tests (`test_paths.py`) ensure the consistency and accuracy of the defined paths against a frozen layout. This change improves maintainability, enhances consistency across the codebase, and lays the groundwork for future path remapping efforts, such as POSIX remapping. Relates to ATO-347. --- paths.json | 49 +++++++++++++++++++++++ paths.py | 69 +++++++++++++++++++++++++++++++++ test.py | 2 + test_paths.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 225 insertions(+) create mode 100644 paths.json create mode 100644 paths.py create mode 100644 test_paths.py diff --git a/paths.json b/paths.json new file mode 100644 index 0000000..1c2281f --- /dev/null +++ b/paths.json @@ -0,0 +1,49 @@ +{ + "HOST_ETC": "/etc", + "HOST_HOME": "/home", + "HOST_MNT": "/mnt", + "HOST_OPT": "/opt", + "HOST_RUN": "/run", + "HOST_TMP": "/tmp", + "HOST_USR": "/usr", + "HOST_VAR": "/var", + "APP_LOG_DIR": "logs", + "CONFIG_ROOT": "/etc/elemento", + "CERTS_DIR": "/etc/elemento/certs", + "CLUSTERING_DIR": "/etc/elemento/clustering", + "MAINTENANCE_FLAG": "/etc/elemento/maintenance_mode", + "PERMISSIONS_DIR": "/etc/elemento/permissions", + "TUNNEL_DIR": "/etc/elemento/tunnel", + "EXPORTER_SCRIPTS_DIR": "/home/scripts", + "VOLUME_MOUNT_GLOB_ONE": "/mnt/*", + "VOLUME_MOUNT_GLOB_ANY": "/mnt/**", + "BRICKS_MOUNT": "/mnt/bricks", + "VAULT_MOUNT": "/mnt/elemento-vault", + "REPOSITORY_MOUNT": "/mnt/repository", + "GUI_APP_DIR": "/opt/app", + "GUI_DAEMONS_DIR": "/opt/daemons", + "INSTALL_ROOT": "/opt/elemento", + "NUCLEUS_DIR": "/opt/elemento/.nucleus", + "DHCP_DATA_DIR": "/opt/elemento/docker-dhcp", + "DHCPD_DATA_DIR": "/opt/elemento/docker-dhcpd", + "MONOREPO_ROOT": "/opt/elemento/elemento-monorepo-server", + "HUGEPAGE_RESIZER": "/opt/elemento/hugepage_resizer.sh", + "KELVIM_DIR": "/opt/elemento/kelvim", + "TAILSCALE_DIR": "/opt/elemento/tailscale", + "VENV_DIR": "/opt/elemento/venv", + "HOMEBREW_PREFIX": "/opt/homebrew", + "OPENRC_RUN_DIR": "/run/openrc", + "SCRATCH_DIR": "/tmp/elemento", + "EXPORT_SCRATCH_DIR": "/tmp/elemento_exported", + "USR_BIN": "/usr/bin", + "USR_LIBEXEC": "/usr/libexec", + "USR_LOCAL": "/usr/local", + "USR_SHARE": "/usr/share", + "STATE_ROOT": "/var/elemento", + "EXPORTED_LINKS_DIR": "/var/elemento/exported", + "SCHEDULES_DIR": "/var/elemento/schedules", + "HOST_VAR_LIB": "/var/lib", + "HOST_VAR_LOG": "/var/log", + "SYSTEM_LOG_DIR": "/var/log/elemento", + "HOST_VAR_RUN": "/var/run" +} diff --git a/paths.py b/paths.py new file mode 100644 index 0000000..0505441 --- /dev/null +++ b/paths.py @@ -0,0 +1,69 @@ +# #******************************************************************************# +# # Copyright(c) 2019-2026, Elemento srl, All rights reserved # +# # Author: Elemento srl # +# # Contributors are mentioned in the code where appropriate. # +# # Permission to use and modify this software and its documentation strictly # +# # for personal purposes is hereby granted without fee, # +# # provided that the above copyright notice appears in all copies # +# # and that both the copyright notice and this permission notice appear in the # +# # supporting documentation. # +# # Modifications to this work are allowed for personal use. # +# # Such modifications have to be licensed under a # +# # Creative Commons BY-NC-ND 4.0 International License available at # +# # http://creativecommons.org/licenses/by-nc-nd/4.0/ and have to be made # +# # available to the Elemento user community # +# # through the original distribution channels. # +# # The authors make no claims about the suitability # +# # of this software for any purpose. # +# # It is provided "as is" without express or implied warranty. # +# #******************************************************************************# +# +# #------------------------------------------------------------------------------# +# #elemento-monorepo-server # +# #Authors: # +# #- Gabriele Gaetano Fronze' (gfronze at elemento.cloud) # +# #------------------------------------------------------------------------------# +# +# Central filesystem path prefixes for AtomOS. +# Names describe role/purpose; values live in paths.json (current on-disk layout). +# POSIX remapping will change JSON values only (not these names). +# + +from os.path import join, dirname, basename +from json import load + +data = open(join(dirname(__file__), basename(__file__).replace('.py', '.json').replace('.jsonc', '.json'))) +data_json = load(data) +globals().update(data_json) +del data_json +del data + + +def tailscale_bridge_dir(bridge_name: str) -> str: + """Per-bridge Tailscale state/compose directory.""" + return join(TAILSCALE_DIR, bridge_name) + + +def certs_for_addr(addr: str) -> str: + """Client certificate path for a peer address.""" + return join(CERTS_DIR, f"{addr}.crt") + + +def schedule_dir(frequency: str) -> str: + """Backup schedule scripts directory for a frequency.""" + return join(SCHEDULES_DIR, frequency) + + +def scratch_pool_dir(pool_name: str) -> str: + """Per-pool scratch mount directory.""" + return join(SCRATCH_DIR, pool_name) + + +def log_file(name: str) -> str: + """CWD-relative application log file path.""" + return join(APP_LOG_DIR, name) + + +def monorepo_server_dir(server_name: str) -> str: + """Checked-out server directory under the monorepo install root.""" + return join(MONOREPO_ROOT, server_name) diff --git a/test.py b/test.py index a62a1f7..3f9c76a 100644 --- a/test.py +++ b/test.py @@ -5,7 +5,9 @@ # fmt: off import networking import restkeys +import paths if __name__ == "__main__": print(networking.RETRIEVE_VMS_SERVER_PORT) print(restkeys.UNREGISTER_API_KEY) + print(paths.CERTS_DIR) diff --git a/test_paths.py b/test_paths.py new file mode 100644 index 0000000..746be21 --- /dev/null +++ b/test_paths.py @@ -0,0 +1,105 @@ +# #******************************************************************************# +# # Copyright(c) 2019-2026, Elemento srl, All rights reserved # +# #******************************************************************************# +# +# Frozen-layout tests for paths.json / paths.py. +# Source of truth: current on-disk AtomOS layout (absolute path strings below). +# + +import json +import unittest +from os.path import dirname, join + +import paths + +# Frozen current on-disk layout. Update together with paths.json on POSIX remap. +FROZEN_LAYOUT = { + "HOST_ETC": "/etc", + "HOST_HOME": "/home", + "HOST_MNT": "/mnt", + "HOST_OPT": "/opt", + "HOST_RUN": "/run", + "HOST_TMP": "/tmp", + "HOST_USR": "/usr", + "HOST_VAR": "/var", + "APP_LOG_DIR": "logs", + "CONFIG_ROOT": "/etc/elemento", + "CERTS_DIR": "/etc/elemento/certs", + "CLUSTERING_DIR": "/etc/elemento/clustering", + "MAINTENANCE_FLAG": "/etc/elemento/maintenance_mode", + "PERMISSIONS_DIR": "/etc/elemento/permissions", + "TUNNEL_DIR": "/etc/elemento/tunnel", + "EXPORTER_SCRIPTS_DIR": "/home/scripts", + "VOLUME_MOUNT_GLOB_ONE": "/mnt/*", + "VOLUME_MOUNT_GLOB_ANY": "/mnt/**", + "BRICKS_MOUNT": "/mnt/bricks", + "VAULT_MOUNT": "/mnt/elemento-vault", + "REPOSITORY_MOUNT": "/mnt/repository", + "GUI_APP_DIR": "/opt/app", + "GUI_DAEMONS_DIR": "/opt/daemons", + "INSTALL_ROOT": "/opt/elemento", + "NUCLEUS_DIR": "/opt/elemento/.nucleus", + "DHCP_DATA_DIR": "/opt/elemento/docker-dhcp", + "DHCPD_DATA_DIR": "/opt/elemento/docker-dhcpd", + "MONOREPO_ROOT": "/opt/elemento/elemento-monorepo-server", + "HUGEPAGE_RESIZER": "/opt/elemento/hugepage_resizer.sh", + "KELVIM_DIR": "/opt/elemento/kelvim", + "TAILSCALE_DIR": "/opt/elemento/tailscale", + "VENV_DIR": "/opt/elemento/venv", + "HOMEBREW_PREFIX": "/opt/homebrew", + "OPENRC_RUN_DIR": "/run/openrc", + "SCRATCH_DIR": "/tmp/elemento", + "EXPORT_SCRATCH_DIR": "/tmp/elemento_exported", + "USR_BIN": "/usr/bin", + "USR_LIBEXEC": "/usr/libexec", + "USR_LOCAL": "/usr/local", + "USR_SHARE": "/usr/share", + "STATE_ROOT": "/var/elemento", + "EXPORTED_LINKS_DIR": "/var/elemento/exported", + "SCHEDULES_DIR": "/var/elemento/schedules", + "HOST_VAR_LIB": "/var/lib", + "HOST_VAR_LOG": "/var/log", + "SYSTEM_LOG_DIR": "/var/log/elemento", + "HOST_VAR_RUN": "/var/run", +} + + +class TestPathsFrozenLayout(unittest.TestCase): + def test_module_attrs_match_frozen_layout(self): + for key, expected in FROZEN_LAYOUT.items(): + with self.subTest(key=key): + self.assertTrue(hasattr(paths, key), f"missing attribute {key}") + self.assertEqual(getattr(paths, key), expected) + + def test_json_matches_frozen_layout(self): + json_path = join(dirname(__file__), "paths.json") + with open(json_path, encoding="utf-8") as fh: + data = json.load(fh) + self.assertEqual(data, FROZEN_LAYOUT) + + def test_helpers_match_frozen_layout(self): + self.assertEqual( + paths.certs_for_addr("1.2.3.4"), + "/etc/elemento/certs/1.2.3.4.crt", + ) + self.assertEqual( + paths.tailscale_bridge_dir("br0"), + "/opt/elemento/tailscale/br0", + ) + self.assertEqual( + paths.schedule_dir("daily"), + "/var/elemento/schedules/daily", + ) + self.assertEqual( + paths.scratch_pool_dir("pool"), + "/tmp/elemento/pool", + ) + self.assertEqual(paths.log_file("x.log"), "logs/x.log") + self.assertEqual( + paths.monorepo_server_dir("elemento-matcher-server"), + "/opt/elemento/elemento-monorepo-server/elemento-matcher-server", + ) + + +if __name__ == "__main__": + unittest.main() From 3aaa9087116b037fde0ba7a96b6241ae048725f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriele=20Fronz=C3=A9?= Date: Mon, 10 Aug 2026 18:01:42 +0200 Subject: [PATCH 2/3] feat: remap AtomOS filesystem to FHS/POSIX immutable-ready layout This change realigns AtomOS paths to adhere to the Filesystem Hierarchy Standard (FHS) and POSIX guidelines, crucial for immutable operating system designs. It clearly separates: - Read-only application components under `/usr/libexec/elemento`. - Configuration under `/etc/elemento`. - Mutable persistent state under `/var/lib/elemento`. - Logs under `/var/log/elemento`. - Scratch data under `/var/tmp/elemento`. A new document, `PATHS_LAYOUT.md`, provides comprehensive guidance for operators on host directory creation and managing the transition from legacy `/opt/elemento` paths using symlinks. Relates to ATO-347. --- PATHS_LAYOUT.md | 65 ++++++++++++++++++++++++++++++ paths.json | 102 ++++++++++++++++++++++++++---------------------- paths.py | 9 +++-- test_paths.py | 50 ++++++++++++------------ 4 files changed, 150 insertions(+), 76 deletions(-) create mode 100644 PATHS_LAYOUT.md diff --git a/PATHS_LAYOUT.md b/PATHS_LAYOUT.md new file mode 100644 index 0000000..924dd29 --- /dev/null +++ b/PATHS_LAYOUT.md @@ -0,0 +1,65 @@ +# AtomOS filesystem layout (POSIX / immutable-ready) + +Role-named path constants live in [`paths.json`](paths.json) and are loaded by +[`paths.py`](paths.py). + +## Layout summary + +| Role | Location | +|------|----------| +| Image (read-only) | `/usr/libexec/elemento` | +| Config | `/etc/elemento` | +| Persistent state | `/var/lib/elemento` | +| Logs | `/var/log/elemento` | +| Scratch | `/var/tmp/elemento`, `/var/tmp/elemento_exported` | +| Runtime | `/run` (e.g. OpenRC under `/run/openrc`) | + +Container-internal paths (`GUI_APP_DIR` `/opt/app`, `GUI_DAEMONS_DIR` `/opt/daemons`) +and developer-only `HOMEBREW_PREFIX` are unchanged. + +## Host directories to create + +Before services start, ensure these exist with appropriate ownership (via image +`tmpfiles.d` / packaging — not via application code): + +- `/var/log/elemento` +- `/var/lib/elemento` (and children as needed: `exported`, `schedules`, `nucleus`, `docker-dhcp`, `docker-dhcpd`, `tailscale`, `permissions`, `clustering`) +- `/var/tmp/elemento` +- `/var/tmp/elemento_exported` +- `/etc/elemento` (certs, tunnel, maintenance flag as today) + +## Legacy → new symlinks (operators) + +Legacy AtomOS mixed install and state under `/opt/elemento`. After remapping, +**do not** replace the whole tree with a single `/opt/elemento` → `/usr/libexec/elemento` +link if mutable data still lives under the old prefix. Prefer **per-leaf** symlinks +so historical data remains reachable: + +| Legacy | New | +|--------|-----| +| `/opt/elemento/kelvim` | `/usr/libexec/elemento/kelvim` | +| `/opt/elemento/venv` | `/usr/libexec/elemento/venv` | +| `/opt/elemento/elemento-monorepo-server` | `/usr/libexec/elemento/elemento-monorepo-server` | +| `/opt/elemento/hugepage_resizer.sh` | `/usr/libexec/elemento/hugepage_resizer.sh` | +| `/opt/elemento/docker-dhcp` | `/var/lib/elemento/docker-dhcp` | +| `/opt/elemento/docker-dhcpd` | `/var/lib/elemento/docker-dhcpd` | +| `/opt/elemento/tailscale` | `/var/lib/elemento/tailscale` | +| `/opt/elemento/.nucleus` | `/var/lib/elemento/nucleus` | +| `/var/elemento/exported` | `/var/lib/elemento/exported` | +| `/var/elemento/schedules` | `/var/lib/elemento/schedules` | +| `/etc/elemento/permissions` | `/var/lib/elemento/permissions` | +| `/etc/elemento/clustering` | `/var/lib/elemento/clustering` | +| `/tmp/elemento` | `/var/tmp/elemento` | +| `/tmp/elemento_exported` | `/var/tmp/elemento_exported` | +| CWD-relative `logs/` (optional) | `/var/log/elemento` | + +Example (illustrative; run as root on the host, after moving or seeding data into the new locations): + +```bash +ln -sfn /usr/libexec/elemento/kelvim /opt/elemento/kelvim +ln -sfn /var/lib/elemento/docker-dhcpd /opt/elemento/docker-dhcpd +ln -sfn /var/log/elemento /path/to/old/cwd/logs # only if needed +``` + +Symlink creation is an **operator / image** responsibility; AtomOS application code +does not create these links. diff --git a/paths.json b/paths.json index 1c2281f..cd51ddf 100644 --- a/paths.json +++ b/paths.json @@ -1,49 +1,57 @@ { - "HOST_ETC": "/etc", - "HOST_HOME": "/home", - "HOST_MNT": "/mnt", - "HOST_OPT": "/opt", - "HOST_RUN": "/run", - "HOST_TMP": "/tmp", - "HOST_USR": "/usr", - "HOST_VAR": "/var", - "APP_LOG_DIR": "logs", - "CONFIG_ROOT": "/etc/elemento", - "CERTS_DIR": "/etc/elemento/certs", - "CLUSTERING_DIR": "/etc/elemento/clustering", - "MAINTENANCE_FLAG": "/etc/elemento/maintenance_mode", - "PERMISSIONS_DIR": "/etc/elemento/permissions", - "TUNNEL_DIR": "/etc/elemento/tunnel", - "EXPORTER_SCRIPTS_DIR": "/home/scripts", - "VOLUME_MOUNT_GLOB_ONE": "/mnt/*", - "VOLUME_MOUNT_GLOB_ANY": "/mnt/**", - "BRICKS_MOUNT": "/mnt/bricks", - "VAULT_MOUNT": "/mnt/elemento-vault", - "REPOSITORY_MOUNT": "/mnt/repository", - "GUI_APP_DIR": "/opt/app", - "GUI_DAEMONS_DIR": "/opt/daemons", - "INSTALL_ROOT": "/opt/elemento", - "NUCLEUS_DIR": "/opt/elemento/.nucleus", - "DHCP_DATA_DIR": "/opt/elemento/docker-dhcp", - "DHCPD_DATA_DIR": "/opt/elemento/docker-dhcpd", - "MONOREPO_ROOT": "/opt/elemento/elemento-monorepo-server", - "HUGEPAGE_RESIZER": "/opt/elemento/hugepage_resizer.sh", - "KELVIM_DIR": "/opt/elemento/kelvim", - "TAILSCALE_DIR": "/opt/elemento/tailscale", - "VENV_DIR": "/opt/elemento/venv", - "HOMEBREW_PREFIX": "/opt/homebrew", - "OPENRC_RUN_DIR": "/run/openrc", - "SCRATCH_DIR": "/tmp/elemento", - "EXPORT_SCRATCH_DIR": "/tmp/elemento_exported", - "USR_BIN": "/usr/bin", - "USR_LIBEXEC": "/usr/libexec", - "USR_LOCAL": "/usr/local", - "USR_SHARE": "/usr/share", - "STATE_ROOT": "/var/elemento", - "EXPORTED_LINKS_DIR": "/var/elemento/exported", - "SCHEDULES_DIR": "/var/elemento/schedules", - "HOST_VAR_LIB": "/var/lib", - "HOST_VAR_LOG": "/var/log", - "SYSTEM_LOG_DIR": "/var/log/elemento", - "HOST_VAR_RUN": "/var/run" + "HOST_ETC" : "/etc", + "HOST_HOME" : "/home", + "HOST_MNT" : "/mnt", + "HOST_OPT" : "/opt", + "HOST_RUN" : "/run", + "HOST_TMP" : "/tmp", + "HOST_USR" : "/usr", + "HOST_VAR" : "/var", + + "APP_LOG_DIR" : "/var/log/elemento", + + "CONFIG_ROOT" : "/etc/elemento", + "CERTS_DIR" : "/etc/elemento/certs", + "CLUSTERING_DIR" : "/var/lib/elemento/clustering", + "MAINTENANCE_FLAG" : "/etc/elemento/maintenance_mode", + "PERMISSIONS_DIR" : "/var/lib/elemento/permissions", + "TUNNEL_DIR" : "/etc/elemento/tunnel", + + "EXPORTER_SCRIPTS_DIR" : "/usr/libexec/elemento/scripts", + + "VOLUME_MOUNT_GLOB_ONE" : "/mnt/*", + "VOLUME_MOUNT_GLOB_ANY" : "/mnt/**", + "BRICKS_MOUNT" : "/mnt/bricks", + "VAULT_MOUNT" : "/mnt/elemento-vault", + "REPOSITORY_MOUNT" : "/mnt/repository", + + "GUI_APP_DIR" : "/opt/app", + "GUI_DAEMONS_DIR" : "/opt/daemons", + "INSTALL_ROOT" : "/usr/libexec/elemento", + "NUCLEUS_DIR" : "/var/lib/elemento/nucleus", + "DHCP_DATA_DIR" : "/var/lib/elemento/docker-dhcp", + "DHCPD_DATA_DIR" : "/var/lib/elemento/docker-dhcpd", + "MONOREPO_ROOT" : "/usr/libexec/elemento/elemento-monorepo-server", + "HUGEPAGE_RESIZER" : "/usr/libexec/elemento/hugepage_resizer.sh", + "KELVIM_DIR" : "/usr/libexec/elemento/kelvim", + "TAILSCALE_DIR" : "/var/lib/elemento/tailscale", + "VENV_DIR" : "/usr/libexec/elemento/venv", + "HOMEBREW_PREFIX" : "/opt/homebrew", + + "OPENRC_RUN_DIR" : "/run/openrc", + "SCRATCH_DIR" : "/var/tmp/elemento", + "EXPORT_SCRATCH_DIR" : "/var/tmp/elemento_exported", + + "USR_BIN" : "/usr/bin", + "USR_LIBEXEC" : "/usr/libexec", + "USR_LOCAL" : "/usr/local", + "USR_SHARE" : "/usr/share", + + "STATE_ROOT" : "/var/lib/elemento", + "EXPORTED_LINKS_DIR" : "/var/lib/elemento/exported", + "SCHEDULES_DIR" : "/var/lib/elemento/schedules", + "HOST_VAR_LIB" : "/var/lib", + "HOST_VAR_LOG" : "/var/log", + "SYSTEM_LOG_DIR" : "/var/log/elemento", + "HOST_VAR_RUN" : "/var/run" } diff --git a/paths.py b/paths.py index 0505441..ba09516 100644 --- a/paths.py +++ b/paths.py @@ -25,8 +25,9 @@ # #------------------------------------------------------------------------------# # # Central filesystem path prefixes for AtomOS. -# Names describe role/purpose; values live in paths.json (current on-disk layout). -# POSIX remapping will change JSON values only (not these names). +# Names describe role/purpose; values live in paths.json +# (immutable-ready FHS layout: image under /usr/libexec/elemento, +# state/logs/scratch under /var, config under /etc/elemento). # from os.path import join, dirname, basename @@ -60,10 +61,10 @@ def scratch_pool_dir(pool_name: str) -> str: def log_file(name: str) -> str: - """CWD-relative application log file path.""" + """Absolute application log file path under APP_LOG_DIR (/var/log/elemento).""" return join(APP_LOG_DIR, name) def monorepo_server_dir(server_name: str) -> str: - """Checked-out server directory under the monorepo install root.""" + """Packaged server directory under the monorepo install root.""" return join(MONOREPO_ROOT, server_name) diff --git a/test_paths.py b/test_paths.py index 746be21..c7ac438 100644 --- a/test_paths.py +++ b/test_paths.py @@ -3,7 +3,7 @@ # #******************************************************************************# # # Frozen-layout tests for paths.json / paths.py. -# Source of truth: current on-disk AtomOS layout (absolute path strings below). +# Source of truth: immutable-ready FHS AtomOS layout (absolute path strings below). # import json @@ -12,7 +12,7 @@ import paths -# Frozen current on-disk layout. Update together with paths.json on POSIX remap. +# Frozen layout. Update together with paths.json when the on-disk contract changes. FROZEN_LAYOUT = { "HOST_ETC": "/etc", "HOST_HOME": "/home", @@ -22,14 +22,14 @@ "HOST_TMP": "/tmp", "HOST_USR": "/usr", "HOST_VAR": "/var", - "APP_LOG_DIR": "logs", + "APP_LOG_DIR": "/var/log/elemento", "CONFIG_ROOT": "/etc/elemento", "CERTS_DIR": "/etc/elemento/certs", - "CLUSTERING_DIR": "/etc/elemento/clustering", + "CLUSTERING_DIR": "/var/lib/elemento/clustering", "MAINTENANCE_FLAG": "/etc/elemento/maintenance_mode", - "PERMISSIONS_DIR": "/etc/elemento/permissions", + "PERMISSIONS_DIR": "/var/lib/elemento/permissions", "TUNNEL_DIR": "/etc/elemento/tunnel", - "EXPORTER_SCRIPTS_DIR": "/home/scripts", + "EXPORTER_SCRIPTS_DIR": "/usr/libexec/elemento/scripts", "VOLUME_MOUNT_GLOB_ONE": "/mnt/*", "VOLUME_MOUNT_GLOB_ANY": "/mnt/**", "BRICKS_MOUNT": "/mnt/bricks", @@ -37,26 +37,26 @@ "REPOSITORY_MOUNT": "/mnt/repository", "GUI_APP_DIR": "/opt/app", "GUI_DAEMONS_DIR": "/opt/daemons", - "INSTALL_ROOT": "/opt/elemento", - "NUCLEUS_DIR": "/opt/elemento/.nucleus", - "DHCP_DATA_DIR": "/opt/elemento/docker-dhcp", - "DHCPD_DATA_DIR": "/opt/elemento/docker-dhcpd", - "MONOREPO_ROOT": "/opt/elemento/elemento-monorepo-server", - "HUGEPAGE_RESIZER": "/opt/elemento/hugepage_resizer.sh", - "KELVIM_DIR": "/opt/elemento/kelvim", - "TAILSCALE_DIR": "/opt/elemento/tailscale", - "VENV_DIR": "/opt/elemento/venv", + "INSTALL_ROOT": "/usr/libexec/elemento", + "NUCLEUS_DIR": "/var/lib/elemento/nucleus", + "DHCP_DATA_DIR": "/var/lib/elemento/docker-dhcp", + "DHCPD_DATA_DIR": "/var/lib/elemento/docker-dhcpd", + "MONOREPO_ROOT": "/usr/libexec/elemento/elemento-monorepo-server", + "HUGEPAGE_RESIZER": "/usr/libexec/elemento/hugepage_resizer.sh", + "KELVIM_DIR": "/usr/libexec/elemento/kelvim", + "TAILSCALE_DIR": "/var/lib/elemento/tailscale", + "VENV_DIR": "/usr/libexec/elemento/venv", "HOMEBREW_PREFIX": "/opt/homebrew", "OPENRC_RUN_DIR": "/run/openrc", - "SCRATCH_DIR": "/tmp/elemento", - "EXPORT_SCRATCH_DIR": "/tmp/elemento_exported", + "SCRATCH_DIR": "/var/tmp/elemento", + "EXPORT_SCRATCH_DIR": "/var/tmp/elemento_exported", "USR_BIN": "/usr/bin", "USR_LIBEXEC": "/usr/libexec", "USR_LOCAL": "/usr/local", "USR_SHARE": "/usr/share", - "STATE_ROOT": "/var/elemento", - "EXPORTED_LINKS_DIR": "/var/elemento/exported", - "SCHEDULES_DIR": "/var/elemento/schedules", + "STATE_ROOT": "/var/lib/elemento", + "EXPORTED_LINKS_DIR": "/var/lib/elemento/exported", + "SCHEDULES_DIR": "/var/lib/elemento/schedules", "HOST_VAR_LIB": "/var/lib", "HOST_VAR_LOG": "/var/log", "SYSTEM_LOG_DIR": "/var/log/elemento", @@ -84,20 +84,20 @@ def test_helpers_match_frozen_layout(self): ) self.assertEqual( paths.tailscale_bridge_dir("br0"), - "/opt/elemento/tailscale/br0", + "/var/lib/elemento/tailscale/br0", ) self.assertEqual( paths.schedule_dir("daily"), - "/var/elemento/schedules/daily", + "/var/lib/elemento/schedules/daily", ) self.assertEqual( paths.scratch_pool_dir("pool"), - "/tmp/elemento/pool", + "/var/tmp/elemento/pool", ) - self.assertEqual(paths.log_file("x.log"), "logs/x.log") + self.assertEqual(paths.log_file("x.log"), "/var/log/elemento/x.log") self.assertEqual( paths.monorepo_server_dir("elemento-matcher-server"), - "/opt/elemento/elemento-monorepo-server/elemento-matcher-server", + "/usr/libexec/elemento/elemento-monorepo-server/elemento-matcher-server", ) From 38af926948a434e1e17e46a58e36f05fa0d12728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriele=20Fronz=C3=A9?= Date: Mon, 10 Aug 2026 18:07:52 +0200 Subject: [PATCH 3/3] refactor: update paths.json and test_paths.py for improved filesystem structure This commit refines the filesystem path definitions in `paths.json` and updates the corresponding frozen layout in `test_paths.py`. The changes include reordering and reintroducing several path definitions to ensure consistency and adherence to the Filesystem Hierarchy Standard (FHS). This update enhances maintainability and prepares the codebase for future enhancements. Relates to ATO-347. --- paths.json | 51 +++++++++++++++++++++++++-------------------------- test_paths.py | 44 ++++++++++++++++++++++---------------------- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/paths.json b/paths.json index cd51ddf..f924b53 100644 --- a/paths.json +++ b/paths.json @@ -1,57 +1,56 @@ { "HOST_ETC" : "/etc", - "HOST_HOME" : "/home", - "HOST_MNT" : "/mnt", - "HOST_OPT" : "/opt", - "HOST_RUN" : "/run", - "HOST_TMP" : "/tmp", - "HOST_USR" : "/usr", - "HOST_VAR" : "/var", - - "APP_LOG_DIR" : "/var/log/elemento", - "CONFIG_ROOT" : "/etc/elemento", "CERTS_DIR" : "/etc/elemento/certs", - "CLUSTERING_DIR" : "/var/lib/elemento/clustering", "MAINTENANCE_FLAG" : "/etc/elemento/maintenance_mode", - "PERMISSIONS_DIR" : "/var/lib/elemento/permissions", "TUNNEL_DIR" : "/etc/elemento/tunnel", - "EXPORTER_SCRIPTS_DIR" : "/usr/libexec/elemento/scripts", + "HOST_HOME" : "/home", + "HOST_MNT" : "/mnt", "VOLUME_MOUNT_GLOB_ONE" : "/mnt/*", "VOLUME_MOUNT_GLOB_ANY" : "/mnt/**", "BRICKS_MOUNT" : "/mnt/bricks", "VAULT_MOUNT" : "/mnt/elemento-vault", "REPOSITORY_MOUNT" : "/mnt/repository", + "HOST_OPT" : "/opt", "GUI_APP_DIR" : "/opt/app", "GUI_DAEMONS_DIR" : "/opt/daemons", - "INSTALL_ROOT" : "/usr/libexec/elemento", - "NUCLEUS_DIR" : "/var/lib/elemento/nucleus", - "DHCP_DATA_DIR" : "/var/lib/elemento/docker-dhcp", - "DHCPD_DATA_DIR" : "/var/lib/elemento/docker-dhcpd", - "MONOREPO_ROOT" : "/usr/libexec/elemento/elemento-monorepo-server", - "HUGEPAGE_RESIZER" : "/usr/libexec/elemento/hugepage_resizer.sh", - "KELVIM_DIR" : "/usr/libexec/elemento/kelvim", - "TAILSCALE_DIR" : "/var/lib/elemento/tailscale", - "VENV_DIR" : "/usr/libexec/elemento/venv", "HOMEBREW_PREFIX" : "/opt/homebrew", + "HOST_RUN" : "/run", "OPENRC_RUN_DIR" : "/run/openrc", - "SCRATCH_DIR" : "/var/tmp/elemento", - "EXPORT_SCRATCH_DIR" : "/var/tmp/elemento_exported", + "HOST_TMP" : "/tmp", + + "HOST_USR" : "/usr", "USR_BIN" : "/usr/bin", "USR_LIBEXEC" : "/usr/libexec", + "INSTALL_ROOT" : "/usr/libexec/elemento", + "MONOREPO_ROOT" : "/usr/libexec/elemento/elemento-monorepo-server", + "HUGEPAGE_RESIZER" : "/usr/libexec/elemento/hugepage_resizer.sh", + "KELVIM_DIR" : "/usr/libexec/elemento/kelvim", + "EXPORTER_SCRIPTS_DIR" : "/usr/libexec/elemento/scripts", + "VENV_DIR" : "/usr/libexec/elemento/venv", "USR_LOCAL" : "/usr/local", "USR_SHARE" : "/usr/share", + "HOST_VAR" : "/var", + "HOST_VAR_LIB" : "/var/lib", "STATE_ROOT" : "/var/lib/elemento", + "CLUSTERING_DIR" : "/var/lib/elemento/clustering", + "DHCP_DATA_DIR" : "/var/lib/elemento/docker-dhcp", + "DHCPD_DATA_DIR" : "/var/lib/elemento/docker-dhcpd", "EXPORTED_LINKS_DIR" : "/var/lib/elemento/exported", + "NUCLEUS_DIR" : "/var/lib/elemento/nucleus", + "PERMISSIONS_DIR" : "/var/lib/elemento/permissions", "SCHEDULES_DIR" : "/var/lib/elemento/schedules", - "HOST_VAR_LIB" : "/var/lib", + "TAILSCALE_DIR" : "/var/lib/elemento/tailscale", "HOST_VAR_LOG" : "/var/log", + "APP_LOG_DIR" : "/var/log/elemento", "SYSTEM_LOG_DIR" : "/var/log/elemento", - "HOST_VAR_RUN" : "/var/run" + "HOST_VAR_RUN" : "/var/run", + "SCRATCH_DIR" : "/var/tmp/elemento", + "EXPORT_SCRATCH_DIR" : "/var/tmp/elemento_exported" } diff --git a/test_paths.py b/test_paths.py index c7ac438..a0199af 100644 --- a/test_paths.py +++ b/test_paths.py @@ -15,52 +15,52 @@ # Frozen layout. Update together with paths.json when the on-disk contract changes. FROZEN_LAYOUT = { "HOST_ETC": "/etc", - "HOST_HOME": "/home", - "HOST_MNT": "/mnt", - "HOST_OPT": "/opt", - "HOST_RUN": "/run", - "HOST_TMP": "/tmp", - "HOST_USR": "/usr", - "HOST_VAR": "/var", - "APP_LOG_DIR": "/var/log/elemento", "CONFIG_ROOT": "/etc/elemento", "CERTS_DIR": "/etc/elemento/certs", - "CLUSTERING_DIR": "/var/lib/elemento/clustering", "MAINTENANCE_FLAG": "/etc/elemento/maintenance_mode", - "PERMISSIONS_DIR": "/var/lib/elemento/permissions", "TUNNEL_DIR": "/etc/elemento/tunnel", - "EXPORTER_SCRIPTS_DIR": "/usr/libexec/elemento/scripts", + "HOST_HOME": "/home", + "HOST_MNT": "/mnt", "VOLUME_MOUNT_GLOB_ONE": "/mnt/*", "VOLUME_MOUNT_GLOB_ANY": "/mnt/**", "BRICKS_MOUNT": "/mnt/bricks", "VAULT_MOUNT": "/mnt/elemento-vault", "REPOSITORY_MOUNT": "/mnt/repository", + "HOST_OPT": "/opt", "GUI_APP_DIR": "/opt/app", "GUI_DAEMONS_DIR": "/opt/daemons", + "HOMEBREW_PREFIX": "/opt/homebrew", + "HOST_RUN": "/run", + "OPENRC_RUN_DIR": "/run/openrc", + "HOST_TMP": "/tmp", + "HOST_USR": "/usr", + "USR_BIN": "/usr/bin", + "USR_LIBEXEC": "/usr/libexec", "INSTALL_ROOT": "/usr/libexec/elemento", - "NUCLEUS_DIR": "/var/lib/elemento/nucleus", - "DHCP_DATA_DIR": "/var/lib/elemento/docker-dhcp", - "DHCPD_DATA_DIR": "/var/lib/elemento/docker-dhcpd", "MONOREPO_ROOT": "/usr/libexec/elemento/elemento-monorepo-server", "HUGEPAGE_RESIZER": "/usr/libexec/elemento/hugepage_resizer.sh", "KELVIM_DIR": "/usr/libexec/elemento/kelvim", - "TAILSCALE_DIR": "/var/lib/elemento/tailscale", + "EXPORTER_SCRIPTS_DIR": "/usr/libexec/elemento/scripts", "VENV_DIR": "/usr/libexec/elemento/venv", - "HOMEBREW_PREFIX": "/opt/homebrew", - "OPENRC_RUN_DIR": "/run/openrc", - "SCRATCH_DIR": "/var/tmp/elemento", - "EXPORT_SCRATCH_DIR": "/var/tmp/elemento_exported", - "USR_BIN": "/usr/bin", - "USR_LIBEXEC": "/usr/libexec", "USR_LOCAL": "/usr/local", "USR_SHARE": "/usr/share", + "HOST_VAR": "/var", + "HOST_VAR_LIB": "/var/lib", "STATE_ROOT": "/var/lib/elemento", + "CLUSTERING_DIR": "/var/lib/elemento/clustering", + "DHCP_DATA_DIR": "/var/lib/elemento/docker-dhcp", + "DHCPD_DATA_DIR": "/var/lib/elemento/docker-dhcpd", "EXPORTED_LINKS_DIR": "/var/lib/elemento/exported", + "NUCLEUS_DIR": "/var/lib/elemento/nucleus", + "PERMISSIONS_DIR": "/var/lib/elemento/permissions", "SCHEDULES_DIR": "/var/lib/elemento/schedules", - "HOST_VAR_LIB": "/var/lib", + "TAILSCALE_DIR": "/var/lib/elemento/tailscale", "HOST_VAR_LOG": "/var/log", + "APP_LOG_DIR": "/var/log/elemento", "SYSTEM_LOG_DIR": "/var/log/elemento", "HOST_VAR_RUN": "/var/run", + "SCRATCH_DIR": "/var/tmp/elemento", + "EXPORT_SCRATCH_DIR": "/var/tmp/elemento_exported", }