|
| 1 | +# Copilot Instructions for sonic-platform-daemons |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +sonic-platform-daemons contains the platform monitoring daemons for SONiC. These daemons run as services on the switch, continuously monitoring hardware components (fans, PSUs, thermals, transceivers, LEDs, PCIe, storage) and publishing their state to the SONiC Redis databases. They consume the platform APIs defined in sonic-platform-common. |
| 6 | + |
| 7 | +## Architecture |
| 8 | + |
| 9 | +``` |
| 10 | +sonic-platform-daemons/ |
| 11 | +├── sonic-xcvrd/ # Transceiver daemon (SFP/QSFP monitoring) |
| 12 | +│ ├── xcvrd/ |
| 13 | +│ │ ├── xcvrd.py # Main transceiver monitoring daemon |
| 14 | +│ │ └── ... |
| 15 | +│ ├── tests/ # xcvrd tests |
| 16 | +│ └── setup.py |
| 17 | +├── sonic-psud/ # PSU daemon (power supply monitoring) |
| 18 | +│ ├── scripts/psud |
| 19 | +│ ├── tests/ |
| 20 | +│ └── setup.py |
| 21 | +├── sonic-thermalctld/ # Thermal control daemon |
| 22 | +│ ├── scripts/thermalctld |
| 23 | +│ ├── tests/ |
| 24 | +│ └── setup.py |
| 25 | +├── sonic-ledd/ # LED daemon |
| 26 | +│ ├── scripts/ledd |
| 27 | +│ ├── tests/ |
| 28 | +│ └── setup.py |
| 29 | +├── sonic-pcied/ # PCIe monitoring daemon |
| 30 | +│ ├── scripts/pcied |
| 31 | +│ ├── tests/ |
| 32 | +│ └── setup.py |
| 33 | +├── sonic-syseepromd/ # System EEPROM daemon |
| 34 | +│ ├── scripts/syseepromd |
| 35 | +│ ├── tests/ |
| 36 | +│ └── setup.py |
| 37 | +├── sonic-chassisd/ # Chassis daemon (modular chassis) |
| 38 | +│ ├── scripts/chassisd |
| 39 | +│ ├── tests/ |
| 40 | +│ └── setup.py |
| 41 | +├── sonic-ycabled/ # Y-cable daemon (dual-ToR) |
| 42 | +│ ├── ycable/ |
| 43 | +│ ├── tests/ |
| 44 | +│ └── setup.py |
| 45 | +├── sonic-sensormond/ # Sensor monitoring daemon |
| 46 | +├── sonic-stormond/ # Storage monitoring daemon |
| 47 | +└── .github/ # GitHub configuration |
| 48 | +``` |
| 49 | + |
| 50 | +### Key Concepts |
| 51 | +- **Each daemon is a standalone Python package** with its own `setup.py` and tests |
| 52 | +- **Platform API consumer**: Daemons call `sonic-platform-common` base class methods |
| 53 | +- **DB publishers**: Daemons write hardware state to STATE_DB, update COUNTERS_DB |
| 54 | +- **Event-driven monitoring**: Daemons poll hardware at intervals, detect state changes |
| 55 | + |
| 56 | +## Language & Style |
| 57 | + |
| 58 | +- **Primary language**: Python 3 |
| 59 | +- **Indentation**: 4 spaces |
| 60 | +- **Naming conventions**: |
| 61 | + - Daemon scripts: lowercase (e.g., `psud`, `thermalctld`, `xcvrd`) |
| 62 | + - Functions: `snake_case` |
| 63 | + - Classes: `PascalCase` |
| 64 | + - Constants: `UPPER_CASE` |
| 65 | +- **Logging**: Use `sonic_py_common.daemon_base.Logger` |
| 66 | +- **Docstrings**: Required for public methods |
| 67 | + |
| 68 | +## Build Instructions |
| 69 | + |
| 70 | +```bash |
| 71 | +# Each daemon is a separate Python package |
| 72 | +cd sonic-xcvrd |
| 73 | +python3 setup.py bdist_wheel |
| 74 | + |
| 75 | +cd sonic-psud |
| 76 | +python3 setup.py bdist_wheel |
| 77 | +# etc. |
| 78 | +``` |
| 79 | + |
| 80 | +## Testing |
| 81 | + |
| 82 | +```bash |
| 83 | +# Run tests for a specific daemon |
| 84 | +cd sonic-xcvrd |
| 85 | +pytest tests/ -v |
| 86 | + |
| 87 | +cd sonic-psud |
| 88 | +pytest tests/ -v |
| 89 | + |
| 90 | +# Run with coverage |
| 91 | +pytest tests/ --cov --cov-report=term-missing |
| 92 | +``` |
| 93 | + |
| 94 | +- Each daemon has its own `tests/` directory |
| 95 | +- Tests use **pytest** with mock objects |
| 96 | +- Platform APIs are mocked (no real hardware needed) |
| 97 | +- Tests verify state machine logic, DB updates, and error handling |
| 98 | + |
| 99 | +## PR Guidelines |
| 100 | + |
| 101 | +- **Commit format**: `[daemon]: Description` (e.g., `[xcvrd]: Add DOM monitoring support`) |
| 102 | +- **Signed-off-by**: REQUIRED (`git commit -s`) |
| 103 | +- **CLA**: Sign Linux Foundation EasyCLA |
| 104 | +- **Testing**: All changes must include or update unit tests |
| 105 | +- **Platform compatibility**: Changes must not break any vendor platform |
| 106 | +- **DB schema**: Document any STATE_DB table changes |
| 107 | + |
| 108 | +## Common Patterns |
| 109 | + |
| 110 | +### Daemon Structure |
| 111 | +```python |
| 112 | +from sonic_py_common.daemon_base import DaemonBase |
| 113 | + |
| 114 | +class MyDaemon(DaemonBase): |
| 115 | + def __init__(self): |
| 116 | + super().__init__('mydaemon') |
| 117 | + self.platform_chassis = load_platform_chassis() |
| 118 | + |
| 119 | + def run(self): |
| 120 | + while True: |
| 121 | + # Monitor hardware |
| 122 | + status = self.platform_chassis.get_fan(0).get_status() |
| 123 | + # Update DB |
| 124 | + self.state_db.set('FAN_INFO|FAN0', {'status': str(status)}) |
| 125 | + time.sleep(self.polling_interval) |
| 126 | +``` |
| 127 | + |
| 128 | +### DB Update Pattern |
| 129 | +```python |
| 130 | +# Daemons typically write to STATE_DB |
| 131 | +# Table format: TABLE_NAME|KEY |
| 132 | +# Fields: key-value pairs representing hardware state |
| 133 | +fvs = swsscommon.FieldValuePairs([ |
| 134 | + ('status', 'OK'), |
| 135 | + ('speed', '12000'), |
| 136 | + ('temperature', '35.0') |
| 137 | +]) |
| 138 | +tbl.set(key, fvs) |
| 139 | +``` |
| 140 | + |
| 141 | +## Dependencies |
| 142 | + |
| 143 | +- **sonic-platform-common**: Platform base classes (sonic_platform_base) |
| 144 | +- **sonic-py-common**: Common Python utilities, DaemonBase |
| 145 | +- **python-swsscommon**: Redis database bindings |
| 146 | +- **sonic-buildimage**: Packages are built within the buildimage system |
| 147 | + |
| 148 | +## Gotchas |
| 149 | + |
| 150 | +- **Platform plugin loading**: Daemons dynamically load vendor platform plugins — handle `ImportError` gracefully |
| 151 | +- **Polling intervals**: Too-frequent polling wastes CPU; too-infrequent misses events |
| 152 | +- **Error resilience**: Daemons must not crash on platform API errors — catch, log, continue |
| 153 | +- **Signal handling**: Daemons must handle SIGTERM/SIGINT for clean shutdown |
| 154 | +- **Multi-ASIC**: xcvrd and other daemons must be namespace-aware for multi-ASIC platforms |
| 155 | +- **DB consistency**: Always update all related fields atomically |
| 156 | +- **Warm restart**: Consider state preservation during warm restart scenarios |
| 157 | +- **Resource leaks**: Ensure file handles and DB connections are properly closed |
0 commit comments