WIP on Prosody diagnostic.

This commit is contained in:
John Livingston 2021-04-14 16:14:56 +02:00
parent f5b438d587
commit a018ef5293
4 changed files with 100 additions and 4 deletions

View File

@ -1,6 +1,10 @@
interface Result { interface Result {
label?: string label?: string
messages: string[] messages: string[]
debug?: Array<{
title: string
message: string
}>
next?: string | ((r: Result) => void) next?: string | ((r: Result) => void)
ok: boolean ok: boolean
test: string test: string
@ -15,8 +19,12 @@ function launchTests (): void {
if (!container) { if (!container) {
throw new Error('Cant find main container') throw new Error('Cant find main container')
} }
const ul = document.createElement('ul')
container.innerHTML = '' container.innerHTML = ''
const title = document.createElement('h1')
title.textContent = 'Diagnostic'
container.append(title)
const ul = document.createElement('ul')
container.append(ul) container.append(ul)
function appendMessages (result: Result): void { function appendMessages (result: Result): void {
@ -49,6 +57,28 @@ function launchTests (): void {
ul.append(li) 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 { function testBrowser (): Result {
const r: Result = { const r: Result = {
ok: false, ok: false,
@ -117,6 +147,7 @@ function launchTests (): void {
async function machine (result: Result): Promise<void> { async function machine (result: Result): Promise<void> {
appendMessages(result) appendMessages(result)
appendDebug(result)
if (!result.ok) { if (!result.ok) {
return return
} }

View File

@ -1,5 +1,5 @@
import { getProsodyConfigContent, getProsodyConfigPath, getWorkingDir } from '../prosody/config' import { getProsodyConfigContent, getProsodyConfigPath, getWorkingDir } from '../prosody/config'
import { testProsodyCorrectlyRunning } from '../prosody/ctl' import { getProsodyAbout, testProsodyCorrectlyRunning } from '../prosody/ctl'
import { newResult, TestResult } from './utils' import { newResult, TestResult } from './utils'
import * as fs from 'fs' import * as fs from 'fs'
@ -15,7 +15,7 @@ export async function diagProsody (test: string, options: RegisterServerOptions)
return result 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. // Testing the prosody config file.
try { try {
const filePath = await getProsodyConfigPath(options) const filePath = await getProsodyConfigPath(options)
@ -24,11 +24,21 @@ export async function diagProsody (test: string, options: RegisterServerOptions)
const actualContent = await fs.promises.readFile(filePath, { const actualContent = await fs.promises.readFile(filePath, {
encoding: 'utf-8' encoding: 'utf-8'
}) })
result.debug.push({
title: 'Current prosody configuration',
message: actualContent
})
const wantedContent = await getProsodyConfigContent(options) const wantedContent = await getProsodyConfigContent(options)
if (actualContent === wantedContent) { if (actualContent === wantedContent) {
result.messages.push('Prosody configuration file content is correct.') result.messages.push('Prosody configuration file content is correct.')
} else { } else {
result.messages.push('Prosody configuration file content is not correct.') result.messages.push('Prosody configuration file content is not correct.')
result.debug.push({
title: 'Prosody configuration should be',
message: wantedContent
})
return result return result
} }
} catch (error) { } catch (error) {
@ -40,6 +50,13 @@ export async function diagProsody (test: string, options: RegisterServerOptions)
if (isCorrectlyRunning.messages.length) { if (isCorrectlyRunning.messages.length) {
result.messages.push(...isCorrectlyRunning.messages) result.messages.push(...isCorrectlyRunning.messages)
} }
const about = await getProsodyAbout(options)
result.debug.push({
title: 'Prosody version',
message: about
})
if (!isCorrectlyRunning.ok) { if (!isCorrectlyRunning.ok) {
return result return result
} }

View File

@ -3,6 +3,10 @@ type nextValue = 'backend' | 'webchat-video' | 'webchat-type' | 'prosody' | 'con
export interface TestResult { export interface TestResult {
label?: string label?: string
messages: string[] messages: string[]
debug: Array<{
title: string
message: string
}>
next: nextValue | null next: nextValue | null
ok: boolean ok: boolean
test: string test: string
@ -13,6 +17,7 @@ export function newResult (test: string): TestResult {
test: test, test: test,
ok: false, ok: false,
messages: [], messages: [],
debug: [],
next: null next: null
} }
} }

View File

@ -1,14 +1,55 @@
import { getProsodyFilePaths, writeProsodyConfig } from './config' import { getProsodyFilePaths, writeProsodyConfig } from './config'
import * as fs from 'fs' import * as fs from 'fs'
import * as util from 'util' 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 { interface ProsodyRunning {
ok: boolean ok: boolean
messages: string[] messages: string[]
} }
async function prosodyCtl (options: RegisterServerOptions, command: string): Promise<string> {
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<string> {
return prosodyCtl(options, 'about')
}
async function testProsodyRunning (options: RegisterServerOptions): Promise<ProsodyRunning> { async function testProsodyRunning (options: RegisterServerOptions): Promise<ProsodyRunning> {
const { peertubeHelpers } = options const { peertubeHelpers } = options
peertubeHelpers.logger.info('Checking if Prosody is running') peertubeHelpers.logger.info('Checking if Prosody is running')
@ -20,6 +61,7 @@ async function testProsodyRunning (options: RegisterServerOptions): Promise<Pros
const filePaths = await getProsodyFilePaths(options) const filePaths = await getProsodyFilePaths(options)
try { try {
await fs.promises.access(filePaths.pid, fs.constants.R_OK) await fs.promises.access(filePaths.pid, fs.constants.R_OK)
result.messages.push(`Pid file ${filePaths.pid} found`)
} catch (error) { } catch (error) {
result.messages.push(`Pid file ${filePaths.pid} not found`) result.messages.push(`Pid file ${filePaths.pid} not found`)
return result return result
@ -90,6 +132,7 @@ async function ensureProsodyNotRunning (options: RegisterServerOptions): Promise
} }
export { export {
getProsodyAbout,
testProsodyRunning, testProsodyRunning,
testProsodyCorrectlyRunning, testProsodyCorrectlyRunning,
ensureProsodyRunning, ensureProsodyRunning,