45 lines
2.5 KiB
Markdown
45 lines
2.5 KiB
Markdown
# Fix: Python Sensor "Permission Denied" — Stale Runtime Assignment
|
|
|
|
**Date**: 2026-02-20
|
|
|
|
## Problem
|
|
|
|
Python-based sensors failed to start with `Permission denied (os error 13)`.
|
|
|
|
## Root Cause
|
|
|
|
The sensor's runtime in the database pointed to `core.builtin` (empty `execution_config`) instead of `core.python`. This caused `is_native=true`, making the sensor manager try to execute the `.py` script directly — which fails without the execute bit.
|
|
|
|
The stale assignment persisted because the pack component loader **skipped** existing sensors on re-registration instead of updating them. Once a sensor was created with the wrong runtime, there was no way to correct it short of deleting the pack entirely.
|
|
|
|
**DB evidence**: `SELECT runtime, runtime_ref FROM sensor` → `runtime=4, runtime_ref=core.builtin` (should be `runtime=3, runtime_ref=core.python`).
|
|
|
|
## Changes
|
|
|
|
### 1. Sensor upsert on re-registration (`crates/common/src/pack_registry/loader.rs`)
|
|
- Changed `load_sensors` from skip-if-exists to upsert: existing sensors are updated with fresh metadata from the YAML (runtime, entrypoint, trigger, config, etc.)
|
|
- Re-registering a pack now corrects stale runtime assignments
|
|
|
|
### 2. `UpdateSensorInput` extended (`crates/common/src/repositories/trigger.rs`)
|
|
- Added `runtime`, `runtime_ref`, `trigger`, `trigger_ref`, and `config` fields so the update path can correct all sensor metadata
|
|
- Updated all callsites in `crates/api/src/routes/triggers.rs` and tests
|
|
|
|
### 3. Registration-time validation (`crates/common/src/pack_registry/loader.rs`)
|
|
- Warns if a non-native `runner_type` (e.g., `python`) resolves to runtime ID 0 (not found)
|
|
- Warns if the resolved runtime has empty/missing `execution_config`
|
|
|
|
### 4. Sensor manager diagnostics (`crates/sensor/src/sensor_manager.rs`)
|
|
- Logs full runtime details (id, ref, name, raw `execution_config` JSON)
|
|
- Logs `env_dir_exists` status and resolved interpreter path
|
|
- Pre-flight check: verifies binary exists and has execute permission before spawn
|
|
- Error message includes binary path, `is_native` flag, and runtime ref
|
|
|
|
### 5. Python loader consistency (`scripts/load_core_pack.py`)
|
|
- Added `runtime` and `runtime_ref` to sensor `ON CONFLICT DO UPDATE` clause
|
|
|
|
## Verification
|
|
|
|
After rebuilding and re-registering the pack with `force=true`:
|
|
- Sensor runtime corrected: `core.builtin` → `core.python`
|
|
- Sensor started successfully with venv interpreter at `/opt/attune/runtime_envs/python_example/python/bin/python3`
|
|
- Counter sensor fully operational (RabbitMQ connected, rules bootstrapped) |