Complete roadmap optionals: Holesail, Swarm UI, GitOps, virtualization.
CI / test (push) Successful in 9m58s

Add tunnel persistence and container one-click tunnels with local
Holesail client bind, Swarm services/nodes/tasks view, GitOps stack
sync from git, deploy wizard step chrome, virtualized container lists,
and structure regression tests. Mark Tracks A–D and optional future done.
This commit is contained in:
2026-07-10 22:53:30 -04:00
parent 573298b836
commit 02f25e0981
26 changed files with 2458 additions and 121 deletions
+26
View File
@@ -16,6 +16,12 @@ import { startDockerEventStream, stopDockerEventStream } from './services/events
import { startStatsBroadcast, stopStatsBroadcast } from './services/stats.js'
import { isPeerRevoked } from './core/peer-policy.js'
import { recordPeerConnect, recordPeerDisconnect } from './services/metrics.js'
import {
closeAllTunnels,
isHolesailEnabled,
holesailStatus,
restoreTunnelsFromDisk,
} from './services/holesail-tunnels.js'
import logger from './utils/logger.js'
const { keyPair, publicKeyHex } = loadOrCreateKeyPair()
@@ -64,16 +70,36 @@ console.log('══════════════════════
console.log(' peardock server ready')
console.log(` Public key (paste into the client):`)
console.log(` ${publicKeyHex}`)
if (isHolesailEnabled()) {
const hs = holesailStatus()
console.log(
` Holesail tunnels: ${hs.available ? 'enabled' : 'enabled but package missing'} (max ${hs.max})`
)
} else {
console.log(' Holesail tunnels: off (set ENABLE_HOLESAIL=1 to enable)')
}
console.log('═══════════════════════════════════════════════════════════')
console.log('')
startDockerEventStream()
startStatsBroadcast()
// Recreate persisted Holesail tunnels (same hs:// keys when possible)
if (isHolesailEnabled()) {
restoreTunnelsFromDisk().catch((err) => {
logger.warn('Tunnel restore failed', { error: err.message })
})
}
async function shutdown() {
console.log('[INFO] Server shutting down…')
stopStatsBroadcast()
stopDockerEventStream()
try {
await closeAllTunnels()
} catch {
// ignore
}
peers.clear()
try {
await server.close()