#!/usr/bin/env node 'use strict'; // Same IPC protocol/library as the official runner 0.2.0; Windows named-pipe variant // of infra/peertube-workers/ipc.cjs. Registration secret comes from stdin, never argv. // // Pipe-name derivation (verified in the shipped 0.2.0 bundle): // ConfigManager id defaults to "default"; socket path is // join(envPaths("peertube-runner", suffix "nodejs").data, id, "peertube-runner.sock") // = %LOCALAPPDATA%\peertube-runner-nodejs\Data\default\peertube-runner.sock // The bundled @peertube/net-ipc rewrites any path on win32: // `\\\\.\\pipe\\${path.replace(/^\//, "").replace(/\//g, "-")}` // so we pass the RAW Windows path and never build the \\.\pipe\ prefix ourselves. const { Client } = require('./runtime/node_modules/@peertube/net-ipc'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const action = process.argv[2]; const base = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'); const id = process.env.PT_RUNNER_ID || 'default'; const sock = path.join(base, 'peertube-runner-nodejs', 'Data', id, 'peertube-runner.sock'); const client = new Client({ path: sock, reconnect: false }); const deadline = setTimeout(() => { client.destroy(); process.exit(1); }, 15000); (async () => { try { await client.connect(); let request = { type: action }; if (action === 'register') { const cfg = JSON.parse(fs.readFileSync(process.env.PT_WORKER_CONFIG || 'C:\\pt-worker\\state\\worker.json', 'utf8')); const registrationToken = fs.readFileSync(0, 'utf8').trim(); if (!registrationToken.startsWith('ptrrt-')) throw new Error('bad token'); request = { type: 'register', url: cfg.peertube_url, runnerName: cfg.name, registrationToken, runnerDescription: 'VOD only; QSV required; admission controlled' }; } else if (!['list-jobs', 'list-registered', 'graceful-shutdown'].includes(action)) throw new Error('bad action'); const result = await client.request(request); if (!result.success) throw new Error('IPC failed'); if (action === 'list-jobs') { // Drop payloads (can contain URLs); status consumers only need counts. console.log(JSON.stringify({ concurrency: result.data.concurrency, active_jobs: result.data.processingJobs.length })); } else if (action === 'list-registered') console.log(JSON.stringify(result.data)); else console.log(JSON.stringify({ success: true })); } catch { console.error('Runner IPC failed; inspect local service health'); process.exitCode = 1; } finally { clearTimeout(deadline); client.destroy(); } })();