From 8a73d93aac433cbc9ee343e657e28459f98cb513 Mon Sep 17 00:00:00 2001 From: John Livingston Date: Wed, 14 Apr 2021 17:10:22 +0200 Subject: [PATCH] WIP on prosody spawning. --- server/lib/prosody/config.ts | 56 ++++++++++++++++++++++++++++-------- server/lib/prosody/ctl.ts | 44 +++++++++++++++++++++------- 2 files changed, 78 insertions(+), 22 deletions(-) diff --git a/server/lib/prosody/config.ts b/server/lib/prosody/config.ts index fd18d1f7..888e9d4f 100644 --- a/server/lib/prosody/config.ts +++ b/server/lib/prosody/config.ts @@ -4,15 +4,11 @@ import { pluginName } from '../helpers' type LogMode = 'debug' | 'info' -/** - * Creates the working dir if needed, and returns it. - * NB: for now, I try to create a directory in /tmp/. - * To ensure that there is no conflict with another peertube instance, - * I used a randomly generated id that will be stored in database. - */ async function getWorkingDir ({ peertubeHelpers, storageManager }: RegisterServerOptions): Promise { + const logger = peertubeHelpers.logger + logger.debug('Calling getWorkingDir') + const tmpBaseDir = '/tmp/' - await fs.promises.access(tmpBaseDir, fs.constants.W_OK) // will throw an error if no access let value: string = await storageManager.getData('tempDirId') function getPath (value: string): string { @@ -31,12 +27,31 @@ async function getWorkingDir ({ peertubeHelpers, storageManager }: RegisterServe await storageManager.storeData('tempDirId', value) } - const name = getPath(value) - if (!fs.existsSync(name)) { - await fs.promises.mkdir(name) + const dir = getPath(value) + logger.debug('getWorkingDir will return ' + dir) + return dir +} + +/** + * Creates the working dir if needed, and returns it. + * NB: for now, I try to create a directory in /tmp/. + * To ensure that there is no conflict with another peertube instance, + * I used a randomly generated id that will be stored in database. + */ +async function ensureWorkingDir (options: RegisterServerOptions): Promise { + const logger = options.peertubeHelpers.logger + logger.debug('Calling ensureworkingDir') + + const dir = await getWorkingDir(options) + if (!fs.existsSync(dir)) { + logger.info(`The working dir ${dir} does not exists, trying to create it`) + await fs.promises.mkdir(dir) + logger.debug(`Working dir ${dir} was created`) } - await fs.promises.access(name, fs.constants.W_OK) // will throw an error if no access - return name + logger.debug(`Testing write access on ${dir}`) + await fs.promises.access(dir, fs.constants.W_OK) // will throw an error if no access + logger.debug(`Write access ok on ${dir}`) + return dir } interface ProsodyFilePaths { @@ -47,6 +62,9 @@ interface ProsodyFilePaths { config: string } async function getProsodyFilePaths (options: RegisterServerOptions): Promise { + const logger = options.peertubeHelpers.logger + logger.debug('Calling getProsodyFilePaths') + const dir = await getWorkingDir(options) return { dir: dir, @@ -58,6 +76,9 @@ async function getProsodyFilePaths (options: RegisterServerOptions): Promise { + const logger = options.peertubeHelpers.logger + logger.debug('Calling getProsodyConfigContent') + const peertubeDomain = 'localhost' const paths = await getProsodyFilePaths(options) const logMode: LogMode = 'debug' @@ -135,21 +156,32 @@ Component "room.localhost" "muc" } async function getProsodyConfigPath (options: RegisterServerOptions): Promise { + const logger = options.peertubeHelpers.logger + logger.debug('Calling getProsodyConfigPath') + const paths = await getProsodyFilePaths(options) return paths.config } async function writeProsodyConfig (options: RegisterServerOptions): Promise { const logger = options.peertubeHelpers.logger + logger.debug('Calling writeProsodyConfig') + + logger.debug('Ensuring that the working dir exists') + await ensureWorkingDir(options) + logger.debug('Computing the Prosody config content') const content = await getProsodyConfigContent(options) + const fileName = await getProsodyConfigPath(options) logger.info(`Writing prosody configuration file to ${fileName}`) await fs.promises.writeFile(fileName, content) + logger.debug('Prosody configuration file writen') } export { getProsodyConfigContent, getWorkingDir, + ensureWorkingDir, getProsodyFilePaths, getProsodyConfigPath, writeProsodyConfig diff --git a/server/lib/prosody/ctl.ts b/server/lib/prosody/ctl.ts index 35636b9e..8bb55e43 100644 --- a/server/lib/prosody/ctl.ts +++ b/server/lib/prosody/ctl.ts @@ -10,7 +10,10 @@ interface ProsodyRunning { messages: string[] } -async function prosodyCtl (options: RegisterServerOptions, command: string): Promise { +async function prosodyCtl (options: RegisterServerOptions, command: string, failOnError: boolean): Promise { + const logger = options.peertubeHelpers.logger + logger.debug('Calling prosodyCtl with command ' + command) + const filePaths = await getProsodyFilePaths(options) if (!/^\w+$/.test(command)) { throw new Error(`Invalid prosodyctl command '${command}'`) @@ -37,9 +40,10 @@ async function prosodyCtl (options: RegisterServerOptions, command: string): Pro e += data as string }) spawned.on('close', (code) => { - if (code !== 0) { + if (code !== 0 && failOnError) { reject(e) } else { + if (e !== '') { d += e } resolve(d) } }) @@ -47,12 +51,14 @@ async function prosodyCtl (options: RegisterServerOptions, command: string): Pro } async function getProsodyAbout (options: RegisterServerOptions): Promise { - return prosodyCtl(options, 'about') + return prosodyCtl(options, 'about', true) } async function testProsodyRunning (options: RegisterServerOptions): Promise { const { peertubeHelpers } = options - peertubeHelpers.logger.info('Checking if Prosody is running') + const logger = peertubeHelpers.logger + logger.info('Checking if Prosody is running') + const result: ProsodyRunning = { ok: false, messages: [] @@ -60,9 +66,11 @@ async function testProsodyRunning (options: RegisterServerOptions): Promise { const { peertubeHelpers, settingsManager } = options const logger = peertubeHelpers.logger + logger.debug('Calling ensureProsodyRunning') + logger.debug('Checking if prosody should be active') const setting = await settingsManager.getSetting('chat-use-prosody') if (!setting) { logger.info('Prosody is not activated, we wont launch it') @@ -97,21 +107,24 @@ async function ensureProsodyRunning (options: RegisterServerOptions): Promise logger.debug(m)) logger.info('Prosody is already running correctly') + // Stop here. Nothing to change. return } logger.info('Prosody is not running correctly: ') r.messages.forEach(m => logger.info(m)) // Shutting down... + logger.debug('Shutting down prosody') await ensureProsodyNotRunning(options) // writing the configuration file + logger.debug('Writing the configuration file') await writeProsodyConfig(options) const filePaths = await getProsodyFilePaths(options) // launch prosody - logger.info('Going to launch prosody...') + logger.info('Going to launch prosody') await exec('prosody', { cwd: filePaths.dir, env: { @@ -119,16 +132,27 @@ async function ensureProsodyRunning (options: RegisterServerOptions): Promise { const { peertubeHelpers } = options - peertubeHelpers.logger.info('Checking if Prosody is running, and shutting it down if so') + const logger = peertubeHelpers.logger + logger.info('Checking if Prosody is running, and shutting it down if so') - // TODO: implement this. - peertubeHelpers.logger.error('ensureProsodyNotRunning not implemented yet.') + // NB: this function is called on plugin unregister, even if prosody is not used + // so we must avoid creating the working dir now + const filePaths = await getProsodyFilePaths(options) + if (!fs.existsSync(filePaths.dir)) { + logger.info(`The working dir ${filePaths.dir} does not exist, assuming there is no prosody on this server`) + return + } + + logger.debug('Calling prosodyctl to stop the process') + const m = await prosodyCtl(options, 'stop', false) + logger.info(`ProsodyCtl command returned: ${m}`) } export {