plc-checkweigher 1.35.0 → 1.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -321,6 +321,45 @@ for k,d in failed: print(' [FAIL] ', k, '-', d)
321
321
  esac
322
322
  ;;
323
323
 
324
+ # ── Backup / restore ──────────────────────────────────────────────────────────
325
+ backup)
326
+ banner "Configuration Backup"
327
+ echo ""
328
+ spin_start "Snapshotting durable configuration"
329
+ "${PYTHON}" -c "
330
+ import sys; sys.path.insert(0, '${INSTALL_DIR}')
331
+ import selfheal, os
332
+ d = selfheal.backup_state()
333
+ print('OK', os.path.basename(d)) if d else print('NOTHING')
334
+ " 2>/dev/null | { read -r _r _n; \
335
+ if [[ "$_r" == "OK" ]]; then spin_ok "Snapshot written: ${_n}"; \
336
+ else spin_warn "Nothing to back up yet"; fi; }
337
+ echo ""
338
+ info "Snapshots: ${INSTALL_DIR}/data/backups/ (latest = snapshot_latest.tar.gz)"
339
+ ls -1t "${INSTALL_DIR}/data/backups/"snapshot_2*.tar.gz 2>/dev/null | head -5 | sed 's/^/ /' || true
340
+ echo ""
341
+ ;;
342
+ restore)
343
+ banner "Configuration Restore"
344
+ need_sudo
345
+ echo ""
346
+ info "Restores lost/corrupt config (SMB creds, register map, console code)"
347
+ info "from the latest snapshot. Live batch data is never overwritten."
348
+ echo ""
349
+ spin_start "Checking configuration integrity"
350
+ sudo "${PYTHON}" -c "
351
+ import sys; sys.path.insert(0, '${INSTALL_DIR}')
352
+ import selfheal
353
+ res = selfheal.restore_check()
354
+ if res:
355
+ k, st, d = res
356
+ print(f'[{st}] {d}')
357
+ else:
358
+ print('INTACT')
359
+ " && spin_ok "Integrity check complete" || spin_warn "Restore check hit an error"
360
+ echo ""
361
+ ;;
362
+
324
363
  # ── Push test ─────────────────────────────────────────────────────────────────
325
364
  push-test)
326
365
  banner "SMB Push Test"
@@ -1398,6 +1437,14 @@ update)
1398
1437
  # Keep data/ writable by pi
1399
1438
  sudo chown -R pi:pi "${DATA_DIR}" 2>/dev/null || true
1400
1439
  sudo chmod 755 "${DATA_DIR}" 2>/dev/null || true
1440
+ # Event journal must stay writable by BOTH pi (watcher/web) and root
1441
+ # (selfheal) — it is the shared transmission/event log. Backups dir is
1442
+ # pi-owned so snapshots and pruning work without sudo.
1443
+ sudo touch "${DATA_DIR}/event_journal.jsonl" 2>/dev/null || true
1444
+ sudo chown pi:pi "${DATA_DIR}/event_journal.jsonl" 2>/dev/null || true
1445
+ sudo chmod 666 "${DATA_DIR}/event_journal.jsonl" 2>/dev/null || true
1446
+ sudo mkdir -p "${DATA_DIR}/backups" 2>/dev/null || true
1447
+ sudo chown pi:pi "${DATA_DIR}/backups" 2>/dev/null || true
1401
1448
  spin_ok "Source files locked (root:root 644)"
1402
1449
 
1403
1450
  # ── Install updated CLI to /usr/local/bin/ ────────────────────────────────
@@ -1663,13 +1710,13 @@ PYEOF
1663
1710
  # 9b. Web maintenance sudoers rule (dashboard terminal)
1664
1711
  spin_start "Web maintenance sudoers rule"
1665
1712
  _SUDOERS_F="/etc/sudoers.d/010_plc-web-fix"
1666
- # Content-aware: rewrite if missing OR still the old fix-only version
1713
+ # Content-aware: rewrite if missing OR not yet upgraded to the current set
1667
1714
  if [[ ! -f "$_SUDOERS_F" ]] \
1668
- || ! sudo grep -q "plc_checkweigher update" "$_SUDOERS_F" 2>/dev/null; then
1715
+ || ! sudo grep -q "plc_checkweigher restore" "$_SUDOERS_F" 2>/dev/null; then
1669
1716
  cat > /tmp/010_plc-web-fix << 'SUDOEOF'
1670
1717
  # Web dashboard maintenance terminal — allows the locked, root-owned CLI
1671
1718
  # to run whitelisted maintenance subcommands from plc_web (User=pi).
1672
- pi ALL=(root) NOPASSWD: /usr/local/bin/plc_checkweigher fix, /usr/local/bin/plc_checkweigher fix *, /usr/local/bin/plc_checkweigher status, /usr/local/bin/plc_checkweigher restart, /usr/local/bin/plc_checkweigher start, /usr/local/bin/plc_checkweigher stop, /usr/local/bin/plc_checkweigher update
1719
+ pi ALL=(root) NOPASSWD: /usr/local/bin/plc_checkweigher fix, /usr/local/bin/plc_checkweigher fix *, /usr/local/bin/plc_checkweigher status, /usr/local/bin/plc_checkweigher restart, /usr/local/bin/plc_checkweigher start, /usr/local/bin/plc_checkweigher stop, /usr/local/bin/plc_checkweigher update, /usr/local/bin/plc_checkweigher restore
1673
1720
  SUDOEOF
1674
1721
  if sudo visudo -c -f /tmp/010_plc-web-fix &>/dev/null; then
1675
1722
  sudo cp /tmp/010_plc-web-fix "$_SUDOERS_F"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plc-checkweigher",
3
- "version": "1.35.0",
3
+ "version": "1.37.1",
4
4
  "description": "One-command installer for the PLC Check-Weigher system on Raspberry Pi (PREEMPT_RT kernel, Python stack, WiFi, SMB, systemd RT services)",
5
5
  "scripts": {
6
6
  "postinstall": "node bin/cli.js"
package/setup.sh CHANGED
@@ -176,7 +176,7 @@ install_cli() {
176
176
  cat > /tmp/010_plc-web-fix << 'EOF'
177
177
  # Web dashboard maintenance terminal — allows the locked, root-owned CLI
178
178
  # to run whitelisted maintenance subcommands from plc_web (User=pi).
179
- pi ALL=(root) NOPASSWD: /usr/local/bin/plc_checkweigher fix, /usr/local/bin/plc_checkweigher fix *, /usr/local/bin/plc_checkweigher status, /usr/local/bin/plc_checkweigher restart, /usr/local/bin/plc_checkweigher start, /usr/local/bin/plc_checkweigher stop, /usr/local/bin/plc_checkweigher update
179
+ pi ALL=(root) NOPASSWD: /usr/local/bin/plc_checkweigher fix, /usr/local/bin/plc_checkweigher fix *, /usr/local/bin/plc_checkweigher status, /usr/local/bin/plc_checkweigher restart, /usr/local/bin/plc_checkweigher start, /usr/local/bin/plc_checkweigher stop, /usr/local/bin/plc_checkweigher update, /usr/local/bin/plc_checkweigher restore
180
180
  EOF
181
181
  if visudo -c -f /tmp/010_plc-web-fix &>/dev/null; then
182
182
  cp /tmp/010_plc-web-fix /etc/sudoers.d/010_plc-web-fix