Files
truf-server/tests/packaged_worker_e2e_server.py
T
2026-09-30 20:30:56 +03:00

627 lines
26 KiB
Python

"""Isolated HTTPS/PostgreSQL harness for real packaged worker clients."""
import sys
sys.dont_write_bytecode = True
import hashlib
import json
import os
from pathlib import Path
import runpy
import signal
import stat
import subprocess
import threading
import time
from types import SimpleNamespace
from urllib.parse import urlsplit
APP = Path('/opt/truf/app')
DATA = Path('/data')
CONTROL = DATA / 'control'
POSTGRES = DATA / 'postgres'
SOCKET = DATA / 'postgres-socket'
BUNDLES = DATA / 'bundles'
FIXTURE = Path('/fixture')
PORT = 8443
DB_PORT = 55432
DB_URL = f'postgresql://truf@127.0.0.1:{DB_PORT}/packaged_worker_e2e'
MAX_CONTROL_BYTES = 1024 * 1024
COMPLETION_REQUIREMENTS = frozenset((
'normalized row counts', 'queue completion', 'remote reservation completion',
'bundle completion', 'scan completion', 'native findings', 'candidate routing',
'exact fixture commits', 'server bundle spool cleanup', 'bundle capacity release',
'source coverage', 'direct assignment planning', 'exact fixture targets',
))
def fail(message):
raise RuntimeError('packaged worker E2E: ' + message)
def require(condition, message):
if not condition:
fail(message)
def private_directory(path, create=False):
path = Path(path)
if create:
path.mkdir(mode=0o700, parents=True, exist_ok=True)
os.chmod(path, 0o700)
details = path.stat(follow_symlinks=False)
require(stat.S_ISDIR(details.st_mode) and details.st_uid == os.getuid(), 'private directory')
require(stat.S_IMODE(details.st_mode) == 0o700, 'private directory mode')
return path
def write_json(path, value):
payload = json.dumps(
value, ensure_ascii=True, sort_keys=True, separators=(',', ':'),
).encode('ascii')
require(len(payload) <= MAX_CONTROL_BYTES, 'control payload bound')
temporary = Path(str(path) + '.tmp')
try:
temporary.unlink()
except FileNotFoundError:
pass
descriptor = os.open(temporary, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
with os.fdopen(descriptor, 'wb') as handle:
handle.write(payload)
handle.flush()
os.fsync(handle.fileno())
os.replace(temporary, path)
def read_json(path):
details = Path(path).stat(follow_symlinks=False)
require(stat.S_ISREG(details.st_mode) and details.st_size <= MAX_CONTROL_BYTES, 'fixture JSON bound')
with open(path, 'rb') as handle:
payload = handle.read(MAX_CONTROL_BYTES + 1)
require(len(payload) <= MAX_CONTROL_BYTES, 'fixture JSON bound')
value = json.loads(payload.decode('ascii'))
require(isinstance(value, dict), 'fixture JSON shape')
return value
def run(command, timeout=60):
completed = subprocess.run(
command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, timeout=timeout, check=False,
env={
'PATH': '/usr/lib/postgresql/16/bin:/usr/local/bin:/usr/bin:/bin',
'HOME': str(DATA / 'home'), 'LANG': 'C.UTF-8', 'LC_ALL': 'C.UTF-8',
},
)
if completed.returncode:
fail('native command failed: ' + Path(command[0]).name)
require(len(completed.stdout) <= MAX_CONTROL_BYTES and len(completed.stderr) <= MAX_CONTROL_BYTES,
'native command output bound')
return completed
def start_postgres():
private_directory(DATA)
for path in (CONTROL, SOCKET, BUNDLES, DATA / 'home'):
private_directory(path, create=True)
first = not (POSTGRES / 'PG_VERSION').exists()
if first:
private_directory(POSTGRES, create=True)
run([
'/usr/lib/postgresql/16/bin/initdb', '--pgdata', str(POSTGRES),
'--username=truf', '--auth=trust', '--encoding=UTF8', '--no-locale',
])
run([
'/usr/lib/postgresql/16/bin/pg_ctl', '-D', str(POSTGRES), '-w', 'start',
'-l', str(DATA / 'postgres.log'),
'-o', f'-k {SOCKET} -h 127.0.0.1 -p {DB_PORT}',
])
if first:
run([
'/usr/lib/postgresql/16/bin/createdb', '-h', str(SOCKET),
'-p', str(DB_PORT), '-U', 'truf', 'packaged_worker_e2e',
])
return first
def stop_postgres():
if (POSTGRES / 'postmaster.pid').exists():
try:
run([
'/usr/lib/postgresql/16/bin/pg_ctl', '-D', str(POSTGRES),
'-w', '-m', 'fast', 'stop',
], timeout=30)
except Exception:
pass
def source_args(platform):
return SimpleNamespace(
platform=platform, exact_git_planning_enabled=platform == 'gitlab',
workers=2, timeout=240, save_dir=str(DATA), detectors='OpenAI',
exclude_detectors='', drop_detectors='', no_verification=True,
trufflehog_config=str(APP / 'trufflehog-custom-detectors.yaml'),
token='', scan_full_history=False, max_depth=25, git_baseline_depth=25,
max_commit_age_days=0, commit_lookup_pages=1,
skip_if_commit_lookup_fails=True, result_bundle_max_event_bytes=1 << 20,
result_bundle_max_items=20, result_bundle_max_total_bytes=32 << 20,
projection_backlog_max_items=20, projection_backlog_max_bytes=32 << 20,
projection_backlog_headroom_bytes=2 << 20, keycheck_queue_max_items=200,
keycheck_queue_max_bytes=8 << 20, pipeline_quarantine_max_items=20,
pipeline_quarantine_max_bytes=8 << 20, keycheck_candidates_per_event=50,
keycheck_candidate_bytes_per_event=1 << 20, target_retry_max_attempts=3,
target_retry_base_delay_sec=60, target_retry_max_delay_sec=600,
target_timeout_retry_delay_sec=300, max_active_scans=2,
admission_resolution_attempts=2, admission_resolution_seconds=1,
admission_resolution_retry_delay_sec=0.01, target_claim_order='oldest',
git_ref_resolution_attempts=1, git_ref_resolution_timeout_sec=1,
git_ref_resolution_max_bytes=1 << 20,
)
class Harness:
def __init__(self, fixture):
self.fixture = fixture
self.targets = tuple(fixture.get('targets') or ())
self.repositories = dict(fixture.get('repositories') or {})
require(len(self.targets) == 2 and set(self.targets) == set(self.repositories),
'exactly two fixture targets required')
self.direct_targets = dict(fixture.get('direct_targets') or {})
require(
set(self.direct_targets) == {'dockerhub', 'huggingface'}
and all(isinstance(value, str) and value for value in self.direct_targets.values()),
'direct fixture targets required',
)
self.token = str(os.environ.get('TRUF_WORKER_E2E_TOKEN') or '')
self.phase = str(os.environ.get('TRUF_WORKER_E2E_PHASE') or '')
require(16 <= len(self.token) <= 512 and self.phase in ('windows', 'linux'),
'phase credentials')
self.stop = threading.Event()
self.ingester_ready = threading.Event()
self.ingester_error = []
self.claims = 0
self.status_checks = 0
self.git_reservation_ids = frozenset()
self.claim_lock = threading.Lock()
self.server = None
def planner(self, args, db_url, source, claim, scan_kwargs, remote_credential=None):
from scanner_db import ScannerDB
target = str(claim['target'])
repository = dict(self.repositories.get(target) or {})
parsed = urlsplit(target)
repo_path = parsed.path.removeprefix('/').removesuffix('.git')
resolution = {
'provider': 'gitlab', 'repo_url': target, 'repo_path': repo_path,
'branch': 'main', 'ref': 'refs/heads/main',
'head_sha': str(repository.get('head_sha') or ''),
'ref_source': 'provider_default',
}
db = ScannerDB(db_url=db_url, initialize=False)
try:
return db.bind_git_scan_plan(
claim['reservation_id'], claim['claim_lease_token'], resolution,
25, remote_credential=remote_credential,
)
finally:
db.close()
def initialize_database(self, first):
from scanner_db import ScannerDB, migrate_runtime_safety_schema
db = ScannerDB(db_url=DB_URL, initialize=False)
require(db.enabled and db.conn.is_postgres, 'PostgreSQL connection')
try:
if first:
migrate_runtime_safety_schema(db, initialize_base=True)
db.record_final_cutover({'fixture': 'packaged-worker-e2e-v1'})
provisioned = db.provision_remote_worker_device(
'packaged-worker-e2e-' + self.phase,
'packaged-worker-e2e-' + self.phase,
hashlib.sha256(self.token.encode('utf-8')).hexdigest(), 2,
)
require(provisioned['active_assignment_cap'] == 2, 'device capacity')
require(db.enqueue_targets(
'gitlab', 'gitlab', 'packaged-worker-e2e', self.targets,
) == 2, 'target enqueue')
write_json(CONTROL / 'prepared.json', {
'schema': 1, 'phase': self.phase, 'target_count': 2,
})
else:
db.require_runtime_safety_schema()
db.require_final_cutover()
marker = read_json(CONTROL / 'prepared.json')
require(marker == {'schema': 1, 'phase': self.phase, 'target_count': 2},
'prepared marker')
finally:
db.close()
def assignment_builder(self):
from worker_assignment import RemoteGitAssignmentBuilder
return RemoteGitAssignmentBuilder(
DB_URL, str(BUNDLES), {
'gitlab': source_args('gitlab'),
'dockerhub': source_args('docker'),
'huggingface': source_args('huggingface'),
},
{
'windows': {
'package_manifest': FIXTURE / 'windows-manifest.json',
'sources': ['gitlab', 'dockerhub', 'huggingface'],
},
'linux': {
'package_manifest': FIXTURE / 'linux-manifest.json',
'sources': ['gitlab', 'dockerhub', 'huggingface'],
},
},
'packaged-worker-e2e-' + self.phase,
assignment_ttl_seconds=600, planner=self.planner,
)
def enqueue_direct_targets(self):
from scanner_db import ScannerDB
db = ScannerDB(db_url=DB_URL, initialize=False)
try:
rows = db.conn.execute(
'SELECT id FROM result_reservations ORDER BY id'
).fetchall()
self.git_reservation_ids = frozenset(int(row['id']) for row in rows)
require(len(self.git_reservation_ids) == 2, 'initial Git reservations')
require(db.enqueue_targets(
'dockerhub', 'docker', 'packaged-worker-e2e',
[self.direct_targets['dockerhub']],
) == 1, 'Docker target enqueue')
require(db.enqueue_targets(
'huggingface', 'huggingface', 'packaged-worker-e2e',
[self.direct_targets['huggingface']],
) == 1, 'HuggingFace target enqueue')
finally:
db.close()
def ingester_loop(self):
from result_ingester import ResultIngester
from scanner_db import ScannerDB
db = ScannerDB(db_url=DB_URL, initialize=False)
ingester = None
try:
ingester = ResultIngester(
db, str(BUNDLES), 'packaged-worker-e2e-' + self.phase,
lease_seconds=30,
).start()
self.ingester_ready.set()
heartbeat = time.monotonic()
while not self.stop.is_set():
progressed = ingester.process_one()
if time.monotonic() - heartbeat >= 5:
require(ingester.heartbeat(), 'ingester heartbeat')
heartbeat = time.monotonic()
if not progressed:
self.stop.wait(0.05)
except Exception as exc:
self.ingester_error.append(type(exc).__name__)
self.ingester_ready.set()
self.stop.set()
finally:
if ingester is not None:
ingester.stop('harness stopping' if self.ingester_error else '')
db.close()
def claim_complete(self):
with self.claim_lock:
self.claims += 1
def status_complete(self):
with self.claim_lock:
self.status_checks += 1
if self.status_checks != 2:
return
require(self.claims == 2, 'status fencing before both claims')
write_json(CONTROL / 'outage.json', {
'schema': 1, 'claim_count': 2, 'phase': self.phase,
})
if self.server is not None:
self.server.should_exit = True
def app(self, stop_after_claims):
from worker_api import WorkerService, create_worker_app
service = WorkerService(
DB_URL, str(BUNDLES), self.assignment_builder(),
max_bundle_bytes=32 << 20, claim_retry_after_seconds=1,
)
app = create_worker_app(service, reaper_interval_seconds=10)
if not stop_after_claims:
harness = self
class DirectStatusFence:
async def __call__(self, scope, receive, send):
path = str(scope.get('path') or '')
parts = path.split('/')
reservation_id = 0
if (
scope.get('type') == 'http'
and scope.get('method') == 'GET'
and len(parts) == 6
and parts[1:5] == ['api', 'v1', 'worker', 'assignments']
):
try:
reservation_id = int(parts[5])
except ValueError:
reservation_id = 0
if (
reservation_id > 0
and reservation_id not in harness.git_reservation_ids
and not (CONTROL / 'direct-ready').is_file()
):
body = b'{"code":"fixture_not_ready"}'
await send({
'type': 'http.response.start', 'status': 503,
'headers': [
(b'content-type', b'application/json'),
(b'content-length', str(len(body)).encode('ascii')),
],
})
await send({'type': 'http.response.body', 'body': body})
return
await app(scope, receive, send)
return DirectStatusFence()
harness = self
class StopAfterClaims:
async def __call__(self, scope, receive, send):
status = None
async def wrapped(message):
nonlocal status
if message['type'] == 'http.response.start':
status = int(message['status'])
await send(message)
if message['type'] != 'http.response.body' or message.get('more_body'):
return
path = str(scope.get('path') or '')
if path == '/api/v1/worker/claim' and status == 201:
harness.claim_complete()
elif (
scope.get('method') == 'GET' and status == 200
and path.startswith('/api/v1/worker/assignments/')
and path.count('/') == 5
):
harness.status_complete()
await app(scope, receive, wrapped)
return StopAfterClaims()
def evidence(self):
from scanner_db import ScannerDB
db = ScannerDB(db_url=DB_URL, initialize=False)
try:
def rows(statement, values=()):
return [dict(row) for row in db.conn.execute(statement, values).fetchall()]
counts = {
table: int(rows(f'SELECT COUNT(*) AS count FROM {table}')[0]['count'])
for table in (
'target_queue', 'result_reservations', 'result_bundles',
'target_scans', 'scan_result_compat', 'findings',
'finding_compat_payloads', 'finding_uid_map',
'keycheck_candidates', 'keycheck_credentials', 'errors',
'pipeline_quarantine',
)
}
expected = {
name: (4 if name in {
'target_queue', 'result_reservations', 'result_bundles',
'target_scans', 'scan_result_compat',
} else 2)
for name in counts
}
expected.update({'errors': 0, 'pipeline_quarantine': 0})
require(counts == expected, 'normalized row counts')
queue = rows('SELECT * FROM target_queue ORDER BY target')
reservations = rows('SELECT * FROM result_reservations ORDER BY id')
bundles = rows('SELECT * FROM result_bundles ORDER BY reservation_id')
scans = rows('SELECT * FROM target_scans ORDER BY target')
findings = rows('SELECT * FROM findings ORDER BY target')
candidates = rows('SELECT * FROM keycheck_candidates ORDER BY target')
require(
all(row['status'] == 'done' and row['attempts'] == 1
and row['lease_token'] is None
and row['current_result_reservation_id'] is None for row in queue),
'queue completion',
)
require(
{(row['source'], row['target']) for row in queue} == {
*(('gitlab', target) for target in self.targets),
('dockerhub', self.direct_targets['dockerhub']),
('huggingface', self.direct_targets['huggingface']),
},
'exact fixture targets',
)
require(
all(row['state'] == 'acknowledged'
and row['assignment_kind'] == 'remote'
and row['remote_resolution_kind'] == 'bundle_accepted'
and row['bundle_credit_released'] == 1 for row in reservations),
'remote reservation completion',
)
reservation_by_id = {int(row['id']): row for row in reservations}
for row in bundles:
source = reservation_by_id[int(row['reservation_id'])]['source']
expected_findings = 1 if source == 'gitlab' else 0
require(
row['state'] == 'acknowledged' and row['actual_bytes'] > 0
and row['finding_count'] == row['candidate_count'] == expected_findings
and row['error_count'] == 0,
'bundle completion',
)
scan_contract = {
'gitlab': ('gitlab', 'found', 1),
'dockerhub': ('docker', 'clean', 0),
'huggingface': ('huggingface', 'clean', 0),
}
for row in scans:
scan_type, status, finding_count = scan_contract.get(row['source'], (None, None, None))
require(
row['scan_type'] == scan_type and row['status'] == status
and row['findings_count'] == finding_count and row['error_count'] == 0
and row['queue_completion_applied'] == 1,
'scan completion',
)
require(all(row['detector_name'] == 'OpenAI' and not row['verified']
and row['file_path'] == 'synthetic.env' for row in findings),
'native findings')
require(all(row['service'] == row['routed_service'] == 'openai'
and row['state'] == 'pending' for row in candidates),
'candidate routing')
expected_heads = {
target: str(self.repositories[target]['head_sha']) for target in self.targets
}
require({row['target']: row['commit_hash'] for row in findings} == expected_heads,
'exact fixture commits')
source_counts = {
source: sum(row['source'] == source for row in reservations)
for source in ('gitlab', 'dockerhub', 'huggingface')
}
require(
source_counts == {'gitlab': 2, 'dockerhub': 1, 'huggingface': 1},
'source coverage',
)
planning_counts = {}
expected_planning = {
'gitlab': 'exact_git_v1',
'dockerhub': 'docker_direct_v1',
'huggingface': 'huggingface_space_v1',
}
for row in reservations:
snapshot = json.loads(row['remote_execution_snapshot_json'])
source = row['source']
planning = snapshot['planning']['kind']
require(planning == expected_planning[source], 'direct assignment planning')
if source != 'gitlab':
require(
snapshot['credential_ref'] == {
'source': source, 'auth_entry': '',
},
'direct assignment planning',
)
planning_counts[planning] = planning_counts.get(planning, 0) + 1
require(not any(BUNDLES.rglob('*.trb')), 'server bundle spool cleanup')
capacity = db.pipeline_capacity_snapshot()
require(capacity['bundle_items'] == capacity['bundle_bytes'] == 0,
'bundle capacity release')
return {
'schema': 1, 'phase': self.phase, 'counts': counts,
'claim_count': len(reservations),
'detectors': sorted({row['detector_name'] for row in findings}),
'candidate_services': sorted({row['service'] for row in candidates}),
'secret_hashes': sorted(row['secret_hash'] for row in findings),
'commit_hashes': sorted(row['commit_hash'] for row in findings),
'receipt_count': len({row['remote_receipt_id'] for row in reservations}),
'source_counts': source_counts,
'planning_counts': planning_counts,
'capacity': {
'bundle_items': capacity['bundle_items'],
'bundle_bytes': capacity['bundle_bytes'],
'keycheck_items': capacity['keycheck_items'],
},
}
finally:
db.close()
def monitor_completion(self):
while not self.stop.wait(0.1):
if self.ingester_error:
return
try:
evidence = self.evidence()
except Exception as exc:
reason = type(exc).__name__
message = str(exc)
prefix = 'packaged worker E2E: '
if (
isinstance(exc, RuntimeError) and message.startswith(prefix)
and message[len(prefix):] in COMPLETION_REQUIREMENTS
):
reason = message[len(prefix):]
write_json(CONTROL / 'completion-wait.json', {
'schema': 1, 'phase': self.phase, 'reason': reason,
})
continue
try:
(CONTROL / 'completion-wait.json').unlink()
except FileNotFoundError:
pass
write_json(CONTROL / 'completed.json', evidence)
return
def serve(self, stop_after_claims):
import uvicorn
server = uvicorn.Server(uvicorn.Config(
self.app(stop_after_claims), host='0.0.0.0', port=PORT,
ssl_certfile=str(FIXTURE / 'worker_tls_cert.pem'),
ssl_keyfile=str(FIXTURE / 'worker_tls_key.pem'),
access_log=False, log_level='warning', server_header=False,
))
self.server = server
server.run()
self.server = None
def run(self, first):
self.initialize_database(first)
thread = threading.Thread(target=self.ingester_loop, name='result-ingester', daemon=True)
thread.start()
require(self.ingester_ready.wait(30) and not self.ingester_error, 'ingester startup')
self.serve(stop_after_claims=first)
require(first and (CONTROL / 'outage.json').is_file(), 'planned API outage')
while not (CONTROL / 'restore').is_file():
require(not self.stop.wait(0.1), 'harness stopped before restore')
self.enqueue_direct_targets()
monitor = threading.Thread(target=self.monitor_completion, name='completion-monitor', daemon=True)
monitor.start()
self.serve(stop_after_claims=False)
self.stop.set()
thread.join(10)
monitor.join(2)
require(not self.ingester_error, 'result ingester failure')
def main():
require(sys.platform == 'linux' and os.getuid() == os.getgid() == 10001,
'Linux UID 10001 required')
require(sys.flags.isolated and sys.flags.no_site and sys.flags.dont_write_bytecode,
'isolated Python required')
os.umask(0o077)
sys.path.insert(0, str(APP))
bootstrap = runpy.run_path(str(APP / 'child_bootstrap.py'))
bootstrap['_enable_dependency_paths']('supervisor')
fixture = read_json(FIXTURE / 'fixture.json')
first = start_postgres()
harness = Harness(fixture)
def terminate(_signum, _frame):
if harness.server is not None:
harness.server.should_exit = True
harness.stop.set()
signal.signal(signal.SIGTERM, terminate)
signal.signal(signal.SIGINT, terminate)
try:
harness.run(first)
finally:
harness.stop.set()
stop_postgres()
if __name__ == '__main__':
main()