From a5cfe997b6ab4be83d3a2fdd8982adaf4ab9ed02 Mon Sep 17 00:00:00 2001 From: louispaulb Date: Mon, 4 May 2026 10:34:36 -0400 Subject: [PATCH] chore(hub): gate Oktopus integration behind OKTOPUS_DISABLED flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Oktopus TR-069 stack is being decommissioned (broker + ACS + Mongo + NATS + adapters). Its MQTT broker was running with debug logging and spammed 75 GB of "failed publishing packet" lines into a single Docker log over 13 days — that's what just took ERPNext down for 4 days when /dev/sdb hit 100 %. Surface here: hub no longer pulls in the oktopus / oktopus-mqtt modules when OKTOPUS_DISABLED is set (default = disabled). Keeps the modules in the tree so we can re-enable later by flipping the env var to 0, but stops them attempting reconnects to a stack that no longer exists. • server.js: late-load oktopus + oktopus-mqtt only when enabled. Routes /oktopus/* now return 410 Gone with a clear message. • provision.js: same gate. The on-scan handler already had a soft `if (oktopus && ...)` guard so it naturally no-ops when the module isn't loaded — no logic change needed there. Server-side env (set in /opt/targo-hub/.env on prod): OKTOPUS_DISABLED=1 --- services/targo-hub/lib/provision.js | 12 ++++++++++-- services/targo-hub/server.js | 24 ++++++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/services/targo-hub/lib/provision.js b/services/targo-hub/lib/provision.js index d6de080..390b354 100644 --- a/services/targo-hub/lib/provision.js +++ b/services/targo-hub/lib/provision.js @@ -1,8 +1,16 @@ 'use strict' const { log, json, parseBody, erpRequest } = require('./helpers') const { broadcast } = require('./sse') -let oktopus -try { oktopus = require('./oktopus') } catch (e) { log('Oktopus module not loaded:', e.message) } +// Oktopus auto-provision was a "best effort" extra step on /on-scan; with the +// stack gone we leave the rest of the provision flow (ERPNext sync, +// equipment swap, etc.) intact and just no-op the oktopus calls. Any caller +// that still expects oktopus_provisioned will see the action recorded as +// "oktopus_skipped" instead. +const OKTOPUS_DISABLED = process.env.OKTOPUS_DISABLED !== '0' +let oktopus = null +if (!OKTOPUS_DISABLED) { + try { oktopus = require('./oktopus') } catch (e) { log('Oktopus module not loaded:', e.message) } +} async function handle (req, res, method, path) { try { diff --git a/services/targo-hub/server.js b/services/targo-hub/server.js index 10fbabf..fc977e2 100644 --- a/services/targo-hub/server.js +++ b/services/targo-hub/server.js @@ -13,13 +13,25 @@ const auth = require('./lib/auth') const conversation = require('./lib/conversation') const traccar = require('./lib/traccar') const dispatch = require('./lib/dispatch') -const oktopus = require('./lib/oktopus') const ical = require('./lib/ical') const vision = require('./lib/vision') let voiceAgent try { voiceAgent = require('./lib/voice-agent') } catch (e) { voiceAgent = null; console.log('Voice agent module not loaded:', e.message) } -let oktopusMqtt -try { oktopusMqtt = require('./lib/oktopus-mqtt') } catch (e) { oktopusMqtt = null; console.log('Oktopus MQTT monitor not loaded:', e.message) } +// Oktopus stack is decommissioned. Set OKTOPUS_DISABLED=1 (default) to skip +// loading the module and the MQTT monitor — both would otherwise attempt +// connections to a dead broker and spam reconnect errors into stdout. The +// Mongo `devices` collection updates from MQTT heartbeats are no longer +// produced; nothing in ops or the field app reads from that collection. +// Re-enable by setting OKTOPUS_DISABLED=0 in the hub env. +const OKTOPUS_DISABLED = process.env.OKTOPUS_DISABLED !== '0' +let oktopus = null +let oktopusMqtt = null +if (!OKTOPUS_DISABLED) { + try { oktopus = require('./lib/oktopus') } catch (e) { console.log('Oktopus module not loaded:', e.message) } + try { oktopusMqtt = require('./lib/oktopus-mqtt') } catch (e) { console.log('Oktopus MQTT monitor not loaded:', e.message) } +} else { + console.log('Oktopus integration disabled (OKTOPUS_DISABLED=1)') +} const server = http.createServer(async (req, res) => { const url = new URL(req.url, `http://localhost:${cfg.PORT}`) @@ -79,7 +91,10 @@ const server = http.createServer(async (req, res) => { if (path.startsWith('/devices')) return devices.handle(req, res, method, path, url) if (path.startsWith('/acs/')) return devices.handleACSConfig(req, res, method, path, url) if (path.startsWith('/provision/')) return provision.handle(req, res, method, path) - if (path.startsWith('/oktopus/')) return oktopus.handle(req, res, method, path) + if (path.startsWith('/oktopus/')) { + if (!oktopus) return require('./lib/helpers').json(res, 410, { error: 'Oktopus integration removed' }) + return oktopus.handle(req, res, method, path) + } if (path.startsWith('/auth/')) return auth.handle(req, res, method, path, url) if (path.startsWith('/conversations')) return conversation.handle(req, res, method, path, url) if (path.startsWith('/traccar')) return traccar.handle(req, res, method, path) @@ -183,6 +198,7 @@ server.listen(cfg.PORT, '0.0.0.0', () => { try { require('./lib/olt-snmp').startOltPoller() } catch (e) { log('OLT SNMP poller failed to start:', e.message) } if (oktopusMqtt) oktopusMqtt.start() + else log('Oktopus MQTT monitor: skipped (disabled)') // Start PPA (pre-authorized payment) cron scheduler try { require('./lib/payments').startPPACron() } catch (e) { log('PPA cron failed to start:', e.message) }