171 lines
7.6 KiB
Markdown
171 lines
7.6 KiB
Markdown
# NUPST Project Hints
|
|
|
|
## Recent Refactoring (January 2026)
|
|
|
|
### Phase 1 - Quick Wins
|
|
|
|
1. **Prompt Utility (`ts/helpers/prompt.ts`)**
|
|
- Extracted readline/prompt pattern from all CLI handlers
|
|
- Provides `createPrompt()` and `withPrompt()` helper functions
|
|
- Used in: `ups-handler.ts`, `group-handler.ts`, `service-handler.ts`, `action-handler.ts`,
|
|
`feature-handler.ts`
|
|
|
|
2. **Constants File (`ts/constants.ts`)**
|
|
- Centralized all magic numbers (timeouts, intervals, thresholds)
|
|
- Contains: `TIMING`, `SNMP`, `THRESHOLDS`, `WEBHOOK`, `SCRIPT`, `SHUTDOWN`, `HTTP_SERVER`, `UI`,
|
|
`NETWORK`, `UPSD`, `PAUSE`, `PROXMOX`
|
|
- Used in: `daemon.ts`, `snmp/manager.ts`, `actions/*.ts`, `upsd/client.ts`
|
|
|
|
3. **Logger Consistency**
|
|
- Replaced all `console.log/console.error` in `snmp/manager.ts` with proper `logger.*` calls
|
|
- Debug output uses `logger.dim()` for less intrusive output
|
|
|
|
### Phase 2 - Type Safety
|
|
|
|
4. **Circular Dependency Fix (`ts/interfaces/nupst-accessor.ts`)**
|
|
- Created `INupstAccessor` interface to break the circular dependency between `Nupst` and
|
|
`NupstSnmp`
|
|
- `NupstSnmp.nupst` property now uses the interface instead of `any`
|
|
|
|
5. **Webhook Payload Interface (`ts/actions/webhook-action.ts`)**
|
|
- Added `IWebhookPayload` interface for webhook action payloads
|
|
- Exported from `ts/actions/index.ts`
|
|
|
|
6. **CLI Handler Type Safety**
|
|
- Replaced `any` types in `ups-handler.ts` and `group-handler.ts` with proper interfaces
|
|
- Uses: `IUpsConfig`, `INupstConfig`, `ISnmpConfig`, `IActionConfig`, `IThresholds`,
|
|
`ISnmpUpsStatus`
|
|
|
|
7. **SNMP Manager Boundary Types (`ts/snmp/manager.ts`)**
|
|
- Added local wrapper interfaces for the untyped `net-snmp` package surface used by NUPST
|
|
- SNMP metric reads now coerce values explicitly instead of relying on `any`-typed responses
|
|
|
|
## Features Added (February 2026)
|
|
|
|
### Network Loss Handling
|
|
|
|
- `TPowerStatus` extended with `'unreachable'` state
|
|
- `IUpsStatus` has `consecutiveFailures` and `unreachableSince` tracking
|
|
- After `NETWORK.CONSECUTIVE_FAILURE_THRESHOLD` (3) failures, UPS transitions to `unreachable`
|
|
- Shutdown action explicitly won't fire on `unreachable` (prevents false shutdowns)
|
|
- Recovery is logged when UPS comes back from unreachable
|
|
|
|
### UPSD/NIS Protocol Support
|
|
|
|
- New `ts/upsd/` directory with TCP client for NUT (Network UPS Tools) servers
|
|
- `ts/protocol/` directory with `ProtocolResolver` for protocol-agnostic status queries
|
|
- `IUpsConfig.protocol` field: `'snmp'` (default) or `'upsd'`
|
|
- `IUpsConfig.snmp` is now optional (not needed for UPSD devices)
|
|
- CLI supports protocol selection during `nupst ups add`
|
|
- Config version is now `4.3`, including the `4.2` -> `4.3` runtime unit migration
|
|
|
|
### Pause/Resume Command
|
|
|
|
- File-based signaling via `/etc/nupst/pause` JSON file
|
|
- `nupst pause [--duration 30m|2h|1d]` creates pause file
|
|
- `nupst resume` deletes pause file
|
|
- `ts/pause-state.ts` owns pause snapshot parsing and transition detection for daemon polling
|
|
- Daemon polls continue but actions are suppressed while paused
|
|
- Auto-resume after duration expires
|
|
- HTTP API includes pause state in response
|
|
|
|
### Shutdown Orchestration
|
|
|
|
- `ts/shutdown-executor.ts` owns command discovery and fallback execution for delayed and emergency
|
|
shutdowns
|
|
- `ts/daemon.ts` now delegates OS shutdown execution instead of embedding command lookup logic
|
|
inline
|
|
|
|
### Config Watch Handling
|
|
|
|
- `ts/config-watch.ts` owns file-watch event matching and config-reload transition analysis
|
|
- `ts/daemon.ts` now delegates config/pause watch event classification and reload messaging
|
|
decisions
|
|
|
|
### UPS Status Tracking
|
|
|
|
- `ts/ups-status.ts` owns the daemon UPS status shape and default status factory
|
|
- `ts/daemon.ts` now reuses a shared initializer instead of duplicating the default UPS status
|
|
object
|
|
|
|
### UPS Monitoring Transitions
|
|
|
|
- `ts/ups-monitoring.ts` owns pure UPS poll success/failure transition logic and threshold detection
|
|
- `ts/daemon.ts` now orchestrates protocol calls and logging while delegating state transitions
|
|
|
|
### Action Orchestration
|
|
|
|
- `ts/action-orchestration.ts` owns action context construction and action execution decisions
|
|
- `ts/daemon.ts` now delegates pause suppression, legacy shutdown fallback, and action context
|
|
building
|
|
|
|
### Shutdown Monitoring
|
|
|
|
- `ts/shutdown-monitoring.ts` owns shutdown-loop row building and emergency candidate selection
|
|
- `ts/daemon.ts` now keeps the shutdown loop orchestration while delegating row/emergency decisions
|
|
|
|
### Proxmox VM Shutdown Action
|
|
|
|
- New action type `'proxmox'` in `ts/actions/proxmox-action.ts`
|
|
- Uses Proxmox REST API with PVEAPIToken authentication
|
|
- Shuts down QEMU VMs and LXC containers before host shutdown
|
|
- Supports: exclude IDs, configurable timeout, force-stop, TLS skip for self-signed certs
|
|
- Should be placed BEFORE shutdown actions in the action chain
|
|
|
|
## Architecture Notes
|
|
|
|
- **SNMP Manager**: Uses `INupstAccessor` interface (not direct `Nupst` reference) to avoid circular
|
|
imports
|
|
- **Protocol Resolver**: Routes to SNMP or UPSD based on `IUpsConfig.protocol`
|
|
- **CLI Handlers**: All use the `helpers.withPrompt()` utility for interactive input
|
|
- **Constants**: All timing values should be referenced from `ts/constants.ts`
|
|
- **Actions**: Use `IActionConfig` from `ts/actions/base-action.ts` for action configuration
|
|
- **Action orchestration**: Use helpers from `ts/action-orchestration.ts` for action context and
|
|
execution decisions
|
|
- **Config watch logic**: Use helpers from `ts/config-watch.ts` for file event filtering and reload
|
|
transitions
|
|
- **Pause state**: Use `loadPauseSnapshot()` and `IPauseState` from `ts/pause-state.ts`
|
|
- **Shutdown execution**: Use `ShutdownExecutor` for OS-level shutdown command lookup and fallbacks
|
|
- **Shutdown monitoring**: Use helpers from `ts/shutdown-monitoring.ts` for emergency loop rows and
|
|
candidate selection
|
|
- **UPS status state**: Use `IUpsStatus` and `createInitialUpsStatus()` from `ts/ups-status.ts`
|
|
- **UPS poll transitions**: Use helpers from `ts/ups-monitoring.ts` for success/failure updates
|
|
- **Config version**: Currently `4.3`, migrations run automatically
|
|
|
|
## File Organization
|
|
|
|
```
|
|
ts/
|
|
├── constants.ts # All timing/threshold constants
|
|
├── action-orchestration.ts # Action context and execution decisions
|
|
├── config-watch.ts # File watch filters and config reload transitions
|
|
├── shutdown-monitoring.ts # Shutdown loop rows and emergency selection
|
|
├── ups-monitoring.ts # Pure UPS poll transition and threshold helpers
|
|
├── pause-state.ts # Shared pause state types and transition detection
|
|
├── shutdown-executor.ts # Delayed/emergency shutdown command execution
|
|
├── ups-status.ts # Daemon UPS status shape and initializer
|
|
├── interfaces/
|
|
│ └── nupst-accessor.ts # Interface to break circular deps
|
|
├── helpers/
|
|
│ ├── prompt.ts # Readline utility
|
|
│ └── shortid.ts # ID generation
|
|
├── actions/
|
|
│ ├── base-action.ts # Base action class, IActionConfig, TPowerStatus
|
|
│ ├── webhook-action.ts # Includes IWebhookPayload
|
|
│ ├── proxmox-action.ts # Proxmox VM/LXC shutdown
|
|
│ └── ...
|
|
├── upsd/
|
|
│ ├── types.ts # IUpsdConfig
|
|
│ ├── client.ts # NupstUpsd TCP client
|
|
│ └── index.ts
|
|
├── protocol/
|
|
│ ├── types.ts # TProtocol = 'snmp' | 'upsd'
|
|
│ ├── resolver.ts # ProtocolResolver
|
|
│ └── index.ts
|
|
├── migrations/
|
|
│ ├── migration-runner.ts
|
|
│ └── migration-v4.2-to-v4.3.ts # Adds SNMP runtimeUnit defaults
|
|
└── cli/
|
|
└── ... # All handlers use helpers.withPrompt()
|
|
```
|