From 6be17b7b85c2beab59b9fa463ab34c6f5cd981fe Mon Sep 17 00:00:00 2001 From: Janaina Senna Date: Sat, 19 Sep 2026 02:25:18 +0000 Subject: [PATCH 1/3] feat: update omega script to verify if the launcher and the Docker image have the same version --- README.md | 6 +++ scripts/omega | 72 ++++++++++++++++++++++++++++++++ tests/test_omegaclaw_launcher.py | 65 ++++++++++++++++++++++++---- 3 files changed, 135 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0886643b..2e695133 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,12 @@ python3 -m pip install -r ./repos/Omega/requirements.txt Ensure that you have [Docker installed](https://docs.docker.com/engine/install/) +The `scripts/omega` launcher and the Docker image must be the same version. +`scripts/omega start` (and the interactive bootstrap) compare the host script +version with the version baked into the image and abort if they differ. Use the +same git tag for both, for example `scripts/omega` from `v0.1.19` with +`singularitynet/omega:v0.1.19`. + Run Omega using the next command: ``` curl -fsSL https://github.com/singnet/Omega/raw/refs/tags/v0.1.19/scripts/omegaclaw | bash -s -- singularitynet/omega:v0.1.19 diff --git a/scripts/omega b/scripts/omega index bcd67b7b..50d52e39 100755 --- a/scripts/omega +++ b/scripts/omega @@ -522,6 +522,77 @@ version() { ) } +_trim() { + local value="${1-}" + value="${value#"${value%%[![:space:]]*}"}" + value="${value%"${value##*[![:space:]]}"}" + printf '%s' "$value" +} + +normalize_omega_version() { + local version + version="$(_trim "${1-}")" + version="${version%$'\r'}" + if [ -z "$version" ]; then + return 1 + fi + if [[ "$version" == "Omega version="* ]]; then + : + elif [[ "$version" == "Omega "* ]]; then + version="Omega version=${version#Omega }" + else + version="Omega version=${version}" + fi + if [[ "$version" == *-dirty ]]; then + version="${version%-dirty}" + fi + printf '%s' "$version" +} + +omega_version_is_unknown() { + local version="${1-}" + [[ -z "$version" || "$version" == "Omega unknown" || "$version" == "Omega version=unknown" ]] +} + +read_image_omega_version() { + local raw="" + raw="$(docker run --rm --entrypoint cat "${image}" /PeTTa/repos/Omega/version 2>/dev/null || true)" + if omega_version_is_unknown "$(_trim "$raw")"; then + raw="$(docker run --rm --entrypoint /PeTTa/repos/Omega/scripts/omega "${image}" --version 2>/dev/null || true)" + fi + printf '%s' "$raw" +} + +ensure_launcher_matches_image() { + local script_raw script_version image_raw image_version + script_raw="$(version 2>/dev/null || true)" + if ! script_version="$(normalize_omega_version "$script_raw")" || omega_version_is_unknown "$script_version"; then + echo "Could not determine the launcher script version; skipping version check." >&2 + echo "Use the same tag for scripts/omega and the Docker image." >&2 + return 0 + fi + + image_raw="$(read_image_omega_version)" + if ! image_version="$(normalize_omega_version "$image_raw")" || omega_version_is_unknown "$image_version"; then + echo "Could not determine the Docker image version; skipping version check." >&2 + echo "Use the same tag for scripts/omega and the Docker image." >&2 + return 0 + fi + + if [[ "$script_version" != "$image_version" ]]; then + cat >&2 </scripts/omega | bash -s -- singularitynet/omega: + ./scripts/omega start -d singularitynet/omega: +EOF + return 1 + fi +} + help() { echo -e "Usage: ${0} [ | command [options]]" echo @@ -748,6 +819,7 @@ options() { start() { docker pull "${image}" 2>/dev/null || true + ensure_launcher_matches_image || return 1 container_log_config_path="" log_config_volume=() diff --git a/tests/test_omegaclaw_launcher.py b/tests/test_omegaclaw_launcher.py index 655a3b18..67b40642 100644 --- a/tests/test_omegaclaw_launcher.py +++ b/tests/test_omegaclaw_launcher.py @@ -7,27 +7,57 @@ REPO_ROOT = Path(__file__).resolve().parents[1] LAUNCHER = REPO_ROOT / "scripts" / "omega" +FAKE_DOCKER = """\ +#!/bin/sh +is_version_probe=0 +for arg in "$@"; do + case "$arg" in + /PeTTa/repos/Omega/version|--version) + is_version_probe=1 + ;; + esac +done +if [ "$is_version_probe" -eq 1 ]; then + printf '%s\\n' "${OMEGA_TEST_IMAGE_VERSION}" + exit 0 +fi +printf 'docker' +printf ' <%s>' "$@" +printf '\\n' +""" + + +def _host_omega_version() -> str: + result = subprocess.run( + [str(LAUNCHER), "--version"], + cwd=REPO_ROOT, + capture_output=True, + text=True, + check=True, + ) + return result.stdout.strip() -def _run_launcher(tmp_path: Path, *component_options: str) -> subprocess.CompletedProcess: +def _run_launcher( + tmp_path: Path, + *component_options: str, + image_version: str | None = None, +) -> subprocess.CompletedProcess: archive = tmp_path / "memory.tar.gz" archive.touch() bin_dir = tmp_path / "bin" bin_dir.mkdir() docker = bin_dir / "docker" - docker.write_text( - "#!/bin/sh\n" - "printf 'docker'\n" - "printf ' <%s>' \"$@\"\n" - "printf '\\n'\n", - encoding="utf-8", - ) + docker.write_text(FAKE_DOCKER, encoding="utf-8") docker.chmod(0o755) environment = os.environ.copy() environment["ASI_API_KEY"] = "test-token" environment["PATH"] = f"{bin_dir}{os.pathsep}{environment['PATH']}" + environment["OMEGA_TEST_IMAGE_VERSION"] = ( + image_version if image_version is not None else _host_omega_version() + ) return subprocess.run( [ @@ -81,3 +111,22 @@ def test_removed_component_options_are_rejected(tmp_path, removed_option): assert result.returncode != 0 assert "Usage:" in result.stdout assert "docker <" not in result.stdout + + +def test_matching_image_version_allows_start(tmp_path): + result = _run_launcher(tmp_path) + + assert result.returncode == 0, result.stderr + assert "docker " in result.stdout + assert "docker " in result.stdout + assert "The launcher script and Docker image versions do not match." not in result.stderr + + +def test_mismatched_image_version_aborts_before_container_replace(tmp_path): + result = _run_launcher(tmp_path, image_version="Omega version=v0.0.0-test") + + assert result.returncode != 0 + assert "The launcher script and Docker image versions do not match." in result.stderr + assert "Omega version=v0.0.0-test" in result.stderr + assert "docker " not in result.stdout + assert "<--name>" not in result.stdout From e2c3a0b2bb3aae2c77a5f1f3ded820d908eccb1a Mon Sep 17 00:00:00 2001 From: Janaina Senna Date: Fri, 25 Sep 2026 00:12:00 +0000 Subject: [PATCH 2/3] feat: fix mismatch message --- scripts/omega | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/omega b/scripts/omega index 50d52e39..48941a9f 100755 --- a/scripts/omega +++ b/scripts/omega @@ -587,7 +587,6 @@ The launcher script and Docker image versions do not match. Update the script or the image so both are the same tag/commit. For example: curl -fsSL https://github.com/singnet/Omega/raw/refs/tags//scripts/omega | bash -s -- singularitynet/omega: - ./scripts/omega start -d singularitynet/omega: EOF return 1 fi From 8ee46ccf77cce2203b5bab3e01af2af3830a470a Mon Sep 17 00:00:00 2001 From: Janaina Senna Date: Fri, 25 Sep 2026 12:38:45 +0000 Subject: [PATCH 3/3] feat: use bare version from python omega_version function --- scripts/omega | 64 +++++++++++++++----------------- src/helper.py | 32 ++++------------ tests/test_memory_export.py | 6 +-- tests/test_omegaclaw_launcher.py | 8 +++- 4 files changed, 47 insertions(+), 63 deletions(-) diff --git a/scripts/omega b/scripts/omega index 48941a9f..607ba82f 100755 --- a/scripts/omega +++ b/scripts/omega @@ -510,7 +510,14 @@ start } -version() { +_trim() { + local value="${1-}" + value="${value#"${value%%[![:space:]]*}"}" + value="${value%"${value##*[![:space:]]}"}" + printf '%s' "$value" +} + +bare_omega_version() { local script_dir local repo_root @@ -522,58 +529,47 @@ version() { ) } -_trim() { - local value="${1-}" - value="${value#"${value%%[![:space:]]*}"}" - value="${value%"${value##*[![:space:]]}"}" - printf '%s' "$value" -} - -normalize_omega_version() { - local version - version="$(_trim "${1-}")" - version="${version%$'\r'}" - if [ -z "$version" ]; then - return 1 - fi - if [[ "$version" == "Omega version="* ]]; then - : - elif [[ "$version" == "Omega "* ]]; then - version="Omega version=${version#Omega }" +version() { + local bare + bare="$(_trim "$(bare_omega_version 2>/dev/null || true)")" + if [ -z "$bare" ]; then + printf '%s\n' "Omega unknown" else - version="Omega version=${version}" + printf 'Omega version=%s\n' "$bare" fi +} + +strip_dirty_suffix() { + local version="$1" if [[ "$version" == *-dirty ]]; then version="${version%-dirty}" fi printf '%s' "$version" } -omega_version_is_unknown() { - local version="${1-}" - [[ -z "$version" || "$version" == "Omega unknown" || "$version" == "Omega version=unknown" ]] -} - read_image_omega_version() { local raw="" raw="$(docker run --rm --entrypoint cat "${image}" /PeTTa/repos/Omega/version 2>/dev/null || true)" - if omega_version_is_unknown "$(_trim "$raw")"; then - raw="$(docker run --rm --entrypoint /PeTTa/repos/Omega/scripts/omega "${image}" --version 2>/dev/null || true)" + raw="$(_trim "$raw")" + if [ -z "$raw" ]; then + raw="$(docker run --rm --workdir /PeTTa/repos/Omega --entrypoint python3 "${image}" \ + -c 'from src.helper import omega_version; print(omega_version())' 2>/dev/null || true)" + raw="$(_trim "$raw")" fi printf '%s' "$raw" } ensure_launcher_matches_image() { - local script_raw script_version image_raw image_version - script_raw="$(version 2>/dev/null || true)" - if ! script_version="$(normalize_omega_version "$script_raw")" || omega_version_is_unknown "$script_version"; then + local script_version image_version + script_version="$(strip_dirty_suffix "$(_trim "$(bare_omega_version 2>/dev/null || true)")")" + if [ -z "$script_version" ]; then echo "Could not determine the launcher script version; skipping version check." >&2 echo "Use the same tag for scripts/omega and the Docker image." >&2 return 0 fi - image_raw="$(read_image_omega_version)" - if ! image_version="$(normalize_omega_version "$image_raw")" || omega_version_is_unknown "$image_version"; then + image_version="$(strip_dirty_suffix "$(read_image_omega_version)")" + if [ -z "$image_version" ]; then echo "Could not determine the Docker image version; skipping version check." >&2 echo "Use the same tag for scripts/omega and the Docker image." >&2 return 0 @@ -582,8 +578,8 @@ ensure_launcher_matches_image() { if [[ "$script_version" != "$image_version" ]]; then cat >&2 </scripts/omega | bash -s -- singularitynet/omega: diff --git a/src/helper.py b/src/helper.py index a28ad313..dae73a40 100644 --- a/src/helper.py +++ b/src/helper.py @@ -207,19 +207,8 @@ def projectRootDirectory(): return os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -def _format_omega_version(version: str) -> str | None: - version = version.strip() - if not version: - return None - if version.startswith("Omega version="): - return version - if version.startswith("Omega "): - version = version[len("Omega "):] - return f"Omega version={version}" - - def omega_version(repo_root: str | os.PathLike | None = None) -> str: - """Return the checkout version, falling back to the baked version file.""" + """Return the bare checkout version, or an empty string when unknown.""" root = Path(repo_root) if repo_root is not None else Path(projectRootDirectory()) try: @@ -236,34 +225,29 @@ def omega_version(repo_root: str | os.PathLike | None = None) -> str: timeout=3, ) if result.returncode == 0: - version = _format_omega_version(result.stdout) - if version is not None: + version = result.stdout.strip() + if version: return version except (OSError, subprocess.TimeoutExpired): pass try: - version = _format_omega_version( - (root / "version").read_text(encoding="utf-8") - ) - if version is not None: + version = (root / "version").read_text(encoding="utf-8").strip() + if version: return version except OSError: pass - return "Omega unknown" + return "" def test_omega_version(): with TemporaryDirectory() as directory: root = Path(directory) - assert omega_version(root) == "Omega unknown" + assert omega_version(root) == "" (root / "version").write_text("v1.2.3-4-g1234567\n", encoding="utf-8") - assert omega_version(root) == "Omega version=v1.2.3-4-g1234567" - - (root / "version").write_text("Omega v1.2.3\n", encoding="utf-8") - assert omega_version(root) == "Omega version=v1.2.3" + assert omega_version(root) == "v1.2.3-4-g1234567" def test_balance_parenthesis(): diff --git a/tests/test_memory_export.py b/tests/test_memory_export.py index dd47d95b..b5f94844 100644 --- a/tests/test_memory_export.py +++ b/tests/test_memory_export.py @@ -150,7 +150,7 @@ def __init__(self, **kwargs): package.MemoryTransfer = FakeTransfer monkeypatch.setitem(sys.modules, "memory_portability", package) monkeypatch.setattr(handler, "create_memory_store", lambda: "configured-store") - monkeypatch.setattr(handler, "omega_version", lambda: "Omega version=v1.2.3") + monkeypatch.setattr(handler, "omega_version", lambda: "v1.2.3") handler._transfer = None transfer = handler._get_transfer() @@ -159,7 +159,7 @@ def __init__(self, **kwargs): assert created == [{ "transfer_dir": handler._TRANSFER_DIR, "store": "configured-store", - "omega_version": "Omega version=v1.2.3", + "omega_version": "v1.2.3", }] @@ -352,7 +352,7 @@ def test_export_is_allowed_for_asicloud_embeddings(handler, monkeypatch): monkeypatch.setitem(sys.modules, "memory_portability", package) monkeypatch.setenv("EMBEDDING_PROVIDER", "Local") monkeypatch.setenv("OMEGA_VERSION", "unset") - monkeypatch.setattr(handler, "omega_version", lambda: "Omega version=test") + monkeypatch.setattr(handler, "omega_version", lambda: "test") monkeypatch.setattr(handler, "create_memory_store", lambda: "configured-store") monkeypatch.setattr( handler, diff --git a/tests/test_omegaclaw_launcher.py b/tests/test_omegaclaw_launcher.py index 67b40642..5c262583 100644 --- a/tests/test_omegaclaw_launcher.py +++ b/tests/test_omegaclaw_launcher.py @@ -29,7 +29,11 @@ def _host_omega_version() -> str: result = subprocess.run( - [str(LAUNCHER), "--version"], + [ + "python3", + "-c", + "from src.helper import omega_version; print(omega_version())", + ], cwd=REPO_ROOT, capture_output=True, text=True, @@ -123,7 +127,7 @@ def test_matching_image_version_allows_start(tmp_path): def test_mismatched_image_version_aborts_before_container_replace(tmp_path): - result = _run_launcher(tmp_path, image_version="Omega version=v0.0.0-test") + result = _run_launcher(tmp_path, image_version="v0.0.0-test") assert result.returncode != 0 assert "The launcher script and Docker image versions do not match." in result.stderr