fix(cv-import): bound source retention and guard worker recovery

This commit is contained in:
cesnimda
2026-10-26 14:41:53 +01:00
parent e8f76a9dea
commit 9e1726c61d
14 changed files with 115 additions and 9 deletions
+18
View File
@@ -0,0 +1,18 @@
# Isolated development image only. Supply an explicitly inspected existing runtime image ID.
ARG CV_IMPORT_BASE_IMAGE=jobtracker-cv-import-legacy:required
FROM ${CV_IMPORT_BASE_IMAGE}
USER root
COPY requirements-cv-import.lock /tmp/cv-import.lock
COPY wheels/ /tmp/cv-import-wheels/
RUN python -m venv /opt/cv-import && /opt/cv-import/bin/python -m pip install --no-index --find-links=/tmp/cv-import-wheels --require-hashes -r /tmp/cv-import.lock
COPY app.py parser_child.py cv_import_ai.py /app/
ENV CV_IMPORT_PYTHON=/opt/cv-import/bin/python \
CV_IMPORT_AI_ENABLED=false \
SKIP_MODEL_LOAD=1 \
AI_SERVICE_SKIP_MODEL_LOAD=1 \
HF_HUB_OFFLINE=1 \
TRANSFORMERS_OFFLINE=1 \
PYTHONDONTWRITEBYTECODE=1
WORKDIR /app
USER 10001
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8001"]
+2
View File
@@ -1222,6 +1222,8 @@ def _parser_environment(temp_root: str) -> dict[str, str]:
"TMPDIR": temp_root,
"TEMP": temp_root,
"TMP": temp_root,
"HOME": temp_root,
"USERPROFILE": temp_root,
})
return environment
+7 -2
View File
@@ -5,7 +5,7 @@ import json
import os
import re
from urllib.parse import urlsplit
from urllib.request import Request, urlopen
from urllib.request import Request, build_opener, HTTPRedirectHandler, ProxyHandler
@dataclass(frozen=True)
@@ -51,10 +51,15 @@ def _validate_config(config):
raise ValueError("Only local provider addresses are supported.")
class _NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
raise ValueError("Local inference redirects are not allowed.")
def _ollama(config, payload):
request = Request(config.base_url.rstrip("/") + "/api/generate", data=json.dumps(payload).encode(), headers={"Content-Type": "application/json"})
# The application adapter never installs/pulls models or changes a model cache.
with urlopen(request, timeout=config.timeout_seconds) as response:
with build_opener(ProxyHandler({}), _NoRedirect()).open(request, timeout=config.timeout_seconds) as response:
body = response.read(256 * 1024 + 1)
if len(body) > 256 * 1024:
raise ValueError("Model output exceeded its bound.")
+3
View File
@@ -377,6 +377,9 @@ def main() -> int:
data = Path(args.input).read_bytes()
if args.mode == "document":
os.environ.update({"HF_HUB_OFFLINE": "1", "HF_HUB_DISABLE_TELEMETRY": "1", "TRANSFORMERS_OFFLINE": "1"})
# Cache trusted platform metadata before the document sandbox denies Linux uname.
import platform
platform.platform()
sys.addaudithook(_deny_import_side_effects)
result = extract_document(args.extension.lower(), data)
else:
+7
View File
@@ -924,3 +924,10 @@ def test_endpoints_stay_open_when_no_token_is_configured(monkeypatch):
response = client.post("/summarize", json={"text": "Platform engineering role."})
assert response.status_code == 503
def test_parser_home_is_private_work_directory_not_host_model_cache(monkeypatch):
module = load_app_module(monkeypatch)
environment = module._parser_environment("private-parser-work")
assert environment.get("HOME") == "private-parser-work"
assert environment.get("USERPROFILE") == "private-parser-work"