mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-07-15 12:58:04 +00:00
fix(cookbook): stop Ollama runner from executing the install one-liner (#3926)
The generated bash runner printed the missing-ollama hint with the install one-liner wrapped in backticks inside a double-quoted echo. Backticks in double quotes are command substitution, so on any serve target without ollama the script downloaded and ran the system-wide installer (including remote SSH hosts) instead of printing the hint. _validate_serve_cmd rejects backticks in user-supplied commands for exactly this reason; the app's own generated script never goes through that validator. Move the hint into OLLAMA_MISSING_HINT in cookbook_helpers (no substitution tokens) and emit it single-quoted via _bash_squote. Tests assert the hint has no expansion tokens, that no generated echo line carries backticks inside double quotes, and that bash prints the line literally. Fixes #3816
This commit is contained in:
committed by
GitHub
parent
dc3530b8fa
commit
e157f1e63d
@@ -558,6 +558,18 @@ def _bash_squote(v: str) -> str:
|
|||||||
return v.replace("'", "'\\''")
|
return v.replace("'", "'\\''")
|
||||||
|
|
||||||
|
|
||||||
|
# Shown by generated runner scripts when the ollama binary is missing on the
|
||||||
|
# target host. Must stay free of backticks/$( ) and be emitted single-quoted:
|
||||||
|
# an earlier version wrapped the install one-liner in backticks inside a
|
||||||
|
# double-quoted echo, which bash executed as command substitution and ran the
|
||||||
|
# system-wide installer (including on remote SSH hosts) instead of printing
|
||||||
|
# the hint.
|
||||||
|
OLLAMA_MISSING_HINT = (
|
||||||
|
"ERROR: Ollama not found on this server. Install it from "
|
||||||
|
"https://ollama.com/download or run: curl -fsSL https://ollama.com/install.sh | sh"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Allow-list of binaries permitted as the leading token of `req.cmd` for /api/model/serve.
|
# Allow-list of binaries permitted as the leading token of `req.cmd` for /api/model/serve.
|
||||||
# Anything else is rejected before the cmd is interpolated into a tmux/PowerShell wrapper.
|
# Anything else is rejected before the cmd is interpolated into a tmux/PowerShell wrapper.
|
||||||
_SERVE_CMD_ALLOWLIST = {
|
_SERVE_CMD_ALLOWLIST = {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ logger = logging.getLogger(__name__)
|
|||||||
from routes.cookbook_helpers import (
|
from routes.cookbook_helpers import (
|
||||||
_SESSION_ID_RE, _validate_repo_id, _validate_serve_model_id, _validate_include, _validate_token,
|
_SESSION_ID_RE, _validate_repo_id, _validate_serve_model_id, _validate_include, _validate_token,
|
||||||
_validate_local_dir, _validate_gpus, _shell_path,
|
_validate_local_dir, _validate_gpus, _shell_path,
|
||||||
_ps_squote, _bash_squote, _validate_serve_cmd, _parse_serve_phase,
|
_ps_squote, _bash_squote, _validate_serve_cmd, _parse_serve_phase, OLLAMA_MISSING_HINT,
|
||||||
_safe_env_prefix, _local_tooling_path_export, _append_serve_preflight_exit_lines,
|
_safe_env_prefix, _local_tooling_path_export, _append_serve_preflight_exit_lines,
|
||||||
_append_serve_exit_code_lines, _append_llama_cpp_linux_accel_build_lines, _cached_model_scan_script,
|
_append_serve_exit_code_lines, _append_llama_cpp_linux_accel_build_lines, _cached_model_scan_script,
|
||||||
load_stored_hf_token,
|
load_stored_hf_token,
|
||||||
@@ -1861,7 +1861,10 @@ def setup_cookbook_routes() -> APIRouter:
|
|||||||
runner_lines.append(' exec 3<&-; exec 3>&-')
|
runner_lines.append(' exec 3<&-; exec 3>&-')
|
||||||
runner_lines.append('done')
|
runner_lines.append('done')
|
||||||
runner_lines.append('if ! command -v ollama &>/dev/null; then')
|
runner_lines.append('if ! command -v ollama &>/dev/null; then')
|
||||||
runner_lines.append(' echo "ERROR: Ollama not found on this server. Install it from https://ollama.com/download or `curl -fsSL https://ollama.com/install.sh | sh`."')
|
# Single-quoted on purpose: backticks inside a double-quoted
|
||||||
|
# echo are command substitution, and this line used to run the
|
||||||
|
# curl|sh installer on the target host instead of printing it.
|
||||||
|
runner_lines.append(f" echo '{_bash_squote(OLLAMA_MISSING_HINT)}'")
|
||||||
runner_lines.append(' echo')
|
runner_lines.append(' echo')
|
||||||
runner_lines.append(' echo "=== Process exited with code 127 ==="')
|
runner_lines.append(' echo "=== Process exited with code 127 ==="')
|
||||||
runner_lines.append(' exec bash -i')
|
runner_lines.append(' exec bash -i')
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
"""The generated Ollama runner must print the install hint, not execute it.
|
||||||
|
|
||||||
|
The runner script emitted by /api/model/serve contained:
|
||||||
|
|
||||||
|
echo "ERROR: Ollama not found ... or `curl -fsSL .../install.sh | sh`."
|
||||||
|
|
||||||
|
Backticks inside double quotes are bash command substitution, so on any host
|
||||||
|
without ollama the script downloaded and ran the system-wide installer
|
||||||
|
(including remote SSH serve targets) instead of printing the hint. The hint
|
||||||
|
now lives in OLLAMA_MISSING_HINT, contains no substitution tokens, and is
|
||||||
|
emitted single-quoted.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from routes.cookbook_helpers import OLLAMA_MISSING_HINT, _bash_squote
|
||||||
|
|
||||||
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
|
||||||
|
def test_hint_has_no_shell_expansion_tokens():
|
||||||
|
assert "`" not in OLLAMA_MISSING_HINT
|
||||||
|
assert "$(" not in OLLAMA_MISSING_HINT
|
||||||
|
|
||||||
|
|
||||||
|
def test_hint_still_tells_the_user_how_to_install():
|
||||||
|
assert "https://ollama.com/download" in OLLAMA_MISSING_HINT
|
||||||
|
assert "install.sh" in OLLAMA_MISSING_HINT
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_runner_echo_line_uses_backticks_in_double_quotes():
|
||||||
|
# Source-level guard: generated-script echo lines must never carry
|
||||||
|
# backticks inside a double-quoted bash string again.
|
||||||
|
src = open(os.path.join(ROOT, "routes", "cookbook_routes.py"), encoding="utf-8").read()
|
||||||
|
offenders = [
|
||||||
|
line.strip()
|
||||||
|
for line in src.splitlines()
|
||||||
|
if "append(" in line and 'echo "' in line and "`" in line.split('echo "', 1)[1]
|
||||||
|
]
|
||||||
|
assert offenders == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_single_quoted_echo_prints_hint_literally():
|
||||||
|
bash = shutil.which("bash")
|
||||||
|
if not bash:
|
||||||
|
pytest.skip("bash not available")
|
||||||
|
out = subprocess.run(
|
||||||
|
[bash, "-c", f"echo '{_bash_squote(OLLAMA_MISSING_HINT)}'"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=30,
|
||||||
|
)
|
||||||
|
assert out.returncode == 0
|
||||||
|
assert out.stdout.strip() == OLLAMA_MISSING_HINT
|
||||||
Reference in New Issue
Block a user