From a018ef529312aac078f74156e8ad461e73e3fa61 Mon Sep 17 00:00:00 2001 From: John Livingston Date: Wed, 14 Apr 2021 16:14:56 +0200 Subject: [PATCH] WIP on Prosody diagnostic. --- client/settings.ts | 33 ++++++++++++++++++++++- server/lib/diagnostic/prosody.ts | 21 +++++++++++++-- server/lib/diagnostic/utils.ts | 5 ++++ server/lib/prosody/ctl.ts | 45 +++++++++++++++++++++++++++++++- 4 files changed, 100 insertions(+), 4 deletions(-) diff --git a/client/settings.ts b/client/settings.ts index 289cea79..8e3d3b87 100644 --- a/client/settings.ts +++ b/client/settings.ts @@ -1,6 +1,10 @@ interface Result { label?: string messages: string[] + debug?: Array<{ + title: string + message: string + }> next?: string | ((r: Result) => void) ok: boolean test: string @@ -15,8 +19,12 @@ function launchTests (): void { if (!container) { throw new Error('Cant find main container') } - const ul = document.createElement('ul') container.innerHTML = '' + + const title = document.createElement('h1') + title.textContent = 'Diagnostic' + container.append(title) + const ul = document.createElement('ul') container.append(ul) function appendMessages (result: Result): void { @@ -49,6 +57,28 @@ function launchTests (): void { ul.append(li) } + let debugContainer: HTMLElement + function appendDebug (result: Result): void { + if (!result.debug?.length) { return } + if (!debugContainer) { + debugContainer = document.createElement('div') + const title = document.createElement('h2') + title.textContent = 'Additional debugging information' + debugContainer.append(title) + container?.append(debugContainer) + } + for (let i = 0; i < result.debug.length; i++) { + const debug = result.debug[i] + const title = document.createElement('h3') + title.textContent = debug.title + debugContainer.append(title) + const message = document.createElement('div') + message.setAttribute('style', 'white-space: pre;') + message.textContent = debug.message + debugContainer.append(message) + } + } + function testBrowser (): Result { const r: Result = { ok: false, @@ -117,6 +147,7 @@ function launchTests (): void { async function machine (result: Result): Promise { appendMessages(result) + appendDebug(result) if (!result.ok) { return } diff --git a/server/lib/diagnostic/prosody.ts b/server/lib/diagnostic/prosody.ts index f14859b2..71f79912 100644 --- a/server/lib/diagnostic/prosody.ts +++ b/server/lib/diagnostic/prosody.ts @@ -1,5 +1,5 @@ import { getProsodyConfigContent, getProsodyConfigPath, getWorkingDir } from '../prosody/config' -import { testProsodyCorrectlyRunning } from '../prosody/ctl' +import { getProsodyAbout, testProsodyCorrectlyRunning } from '../prosody/ctl' import { newResult, TestResult } from './utils' import * as fs from 'fs' @@ -15,7 +15,7 @@ export async function diagProsody (test: string, options: RegisterServerOptions) return result } - // FIXME: these tests should also be in testProsodyCorrectlyRunning + // FIXME: these tests should also be in testProsodyCorrectlyRunning. Remove from here? // Testing the prosody config file. try { const filePath = await getProsodyConfigPath(options) @@ -24,11 +24,21 @@ export async function diagProsody (test: string, options: RegisterServerOptions) const actualContent = await fs.promises.readFile(filePath, { encoding: 'utf-8' }) + + result.debug.push({ + title: 'Current prosody configuration', + message: actualContent + }) + const wantedContent = await getProsodyConfigContent(options) if (actualContent === wantedContent) { result.messages.push('Prosody configuration file content is correct.') } else { result.messages.push('Prosody configuration file content is not correct.') + result.debug.push({ + title: 'Prosody configuration should be', + message: wantedContent + }) return result } } catch (error) { @@ -40,6 +50,13 @@ export async function diagProsody (test: string, options: RegisterServerOptions) if (isCorrectlyRunning.messages.length) { result.messages.push(...isCorrectlyRunning.messages) } + + const about = await getProsodyAbout(options) + result.debug.push({ + title: 'Prosody version', + message: about + }) + if (!isCorrectlyRunning.ok) { return result } diff --git a/server/lib/diagnostic/utils.ts b/server/lib/diagnostic/utils.ts index f49cd977..333d5550 100644 --- a/server/lib/diagnostic/utils.ts +++ b/server/lib/diagnostic/utils.ts @@ -3,6 +3,10 @@ type nextValue = 'backend' | 'webchat-video' | 'webchat-type' | 'prosody' | 'con export interface TestResult { label?: string messages: string[] + debug: Array<{ + title: string + message: string + }> next: nextValue | null ok: boolean test: string @@ -13,6 +17,7 @@ export function newResult (test: string): TestResult { test: test, ok: false, messages: [], + debug: [], next: null } } diff --git a/server/lib/prosody/ctl.ts b/server/lib/prosody/ctl.ts index 8caa9b45..35636b9e 100644 --- a/server/lib/prosody/ctl.ts +++ b/server/lib/prosody/ctl.ts @@ -1,14 +1,55 @@ import { getProsodyFilePaths, writeProsodyConfig } from './config' import * as fs from 'fs' import * as util from 'util' +import * as child_process from 'child_process' -const exec = util.promisify(require('child_process').exec) +const exec = util.promisify(child_process.exec) interface ProsodyRunning { ok: boolean messages: string[] } +async function prosodyCtl (options: RegisterServerOptions, command: string): Promise { + const filePaths = await getProsodyFilePaths(options) + if (!/^\w+$/.test(command)) { + throw new Error(`Invalid prosodyctl command '${command}'`) + } + return new Promise((resolve, reject) => { + let d: string = '' + let e: string = '' + const spawned = child_process.spawn('prosodyctl', [ + '--config', + filePaths.config, + command + ], { + cwd: filePaths.dir, + env: { + ...process.env, + PROSODY_CONFIG: filePaths.config + } + }) + spawned.stdout.on('data', (data) => { + d += data as string + }) + spawned.stderr.on('data', (data) => { + options.peertubeHelpers.logger.error(`Spawned command ${command} has errors: ${data as string}`) + e += data as string + }) + spawned.on('close', (code) => { + if (code !== 0) { + reject(e) + } else { + resolve(d) + } + }) + }) +} + +async function getProsodyAbout (options: RegisterServerOptions): Promise { + return prosodyCtl(options, 'about') +} + async function testProsodyRunning (options: RegisterServerOptions): Promise { const { peertubeHelpers } = options peertubeHelpers.logger.info('Checking if Prosody is running') @@ -20,6 +61,7 @@ async function testProsodyRunning (options: RegisterServerOptions): Promise