Skip to content
Open
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
69 changes: 68 additions & 1 deletion scripts/omega
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -522,6 +529,65 @@ version() {
)
}

version() {
local bare
bare="$(_trim "$(bare_omega_version 2>/dev/null || true)")"
if [ -z "$bare" ]; then
printf '%s\n' "Omega unknown"
else
printf 'Omega version=%s\n' "$bare"
fi
}

strip_dirty_suffix() {
local version="$1"
if [[ "$version" == *-dirty ]]; then
version="${version%-dirty}"
fi
printf '%s' "$version"
}

read_image_omega_version() {
local raw=""
raw="$(docker run --rm --entrypoint cat "${image}" /PeTTa/repos/Omega/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_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_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
fi

if [[ "$script_version" != "$image_version" ]]; then
cat >&2 <<EOF
The launcher script and Docker image versions do not match.
Script: Omega version=${script_version}
Image (${image}): Omega version=${image_version}

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/<tag>/scripts/omega | bash -s -- singularitynet/omega:<tag>
EOF
return 1
fi
}

help() {
echo -e "Usage: ${0} [<image tag> | command [options]]"
echo
Expand Down Expand Up @@ -748,6 +814,7 @@ options() {

start() {
docker pull "${image}" 2>/dev/null || true
ensure_launcher_matches_image || return 1

container_log_config_path=""
log_config_volume=()
Expand Down
32 changes: 8 additions & 24 deletions src/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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():
Expand Down
6 changes: 3 additions & 3 deletions tests/test_memory_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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",
}]


Expand Down Expand Up @@ -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,
Expand Down
69 changes: 61 additions & 8 deletions tests/test_omegaclaw_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,61 @@

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(
[
"python3",
"-c",
"from src.helper import omega_version; print(omega_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(
[
Expand Down Expand Up @@ -81,3 +115,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 <rm>" in result.stdout
assert "docker <run>" 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="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 <rm>" not in result.stdout
assert "<--name>" not in result.stdout
Loading