WIP on prosody spawning.

This commit is contained in:
John Livingston 2021-04-14 17:10:22 +02:00
parent a018ef5293
commit 8a73d93aac
2 changed files with 78 additions and 22 deletions

View File

@ -4,15 +4,11 @@ import { pluginName } from '../helpers'
type LogMode = 'debug' | 'info' 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<string> { async function getWorkingDir ({ peertubeHelpers, storageManager }: RegisterServerOptions): Promise<string> {
const logger = peertubeHelpers.logger
logger.debug('Calling getWorkingDir')
const tmpBaseDir = '/tmp/' 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') let value: string = await storageManager.getData('tempDirId')
function getPath (value: string): string { function getPath (value: string): string {
@ -31,12 +27,31 @@ async function getWorkingDir ({ peertubeHelpers, storageManager }: RegisterServe
await storageManager.storeData('tempDirId', value) await storageManager.storeData('tempDirId', value)
} }
const name = getPath(value) const dir = getPath(value)
if (!fs.existsSync(name)) { logger.debug('getWorkingDir will return ' + dir)
await fs.promises.mkdir(name) 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<string> {
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 logger.debug(`Testing write access on ${dir}`)
return name 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 { interface ProsodyFilePaths {
@ -47,6 +62,9 @@ interface ProsodyFilePaths {
config: string config: string
} }
async function getProsodyFilePaths (options: RegisterServerOptions): Promise<ProsodyFilePaths> { async function getProsodyFilePaths (options: RegisterServerOptions): Promise<ProsodyFilePaths> {
const logger = options.peertubeHelpers.logger
logger.debug('Calling getProsodyFilePaths')
const dir = await getWorkingDir(options) const dir = await getWorkingDir(options)
return { return {
dir: dir, dir: dir,
@ -58,6 +76,9 @@ async function getProsodyFilePaths (options: RegisterServerOptions): Promise<Pro
} }
async function getProsodyConfigContent (options: RegisterServerOptions): Promise<string> { async function getProsodyConfigContent (options: RegisterServerOptions): Promise<string> {
const logger = options.peertubeHelpers.logger
logger.debug('Calling getProsodyConfigContent')
const peertubeDomain = 'localhost' const peertubeDomain = 'localhost'
const paths = await getProsodyFilePaths(options) const paths = await getProsodyFilePaths(options)
const logMode: LogMode = 'debug' const logMode: LogMode = 'debug'
@ -135,21 +156,32 @@ Component "room.localhost" "muc"
} }
async function getProsodyConfigPath (options: RegisterServerOptions): Promise<string> { async function getProsodyConfigPath (options: RegisterServerOptions): Promise<string> {
const logger = options.peertubeHelpers.logger
logger.debug('Calling getProsodyConfigPath')
const paths = await getProsodyFilePaths(options) const paths = await getProsodyFilePaths(options)
return paths.config return paths.config
} }
async function writeProsodyConfig (options: RegisterServerOptions): Promise<void> { async function writeProsodyConfig (options: RegisterServerOptions): Promise<void> {
const logger = options.peertubeHelpers.logger 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 content = await getProsodyConfigContent(options)
const fileName = await getProsodyConfigPath(options) const fileName = await getProsodyConfigPath(options)
logger.info(`Writing prosody configuration file to ${fileName}`) logger.info(`Writing prosody configuration file to ${fileName}`)
await fs.promises.writeFile(fileName, content) await fs.promises.writeFile(fileName, content)
logger.debug('Prosody configuration file writen')
} }
export { export {
getProsodyConfigContent, getProsodyConfigContent,
getWorkingDir, getWorkingDir,
ensureWorkingDir,
getProsodyFilePaths, getProsodyFilePaths,
getProsodyConfigPath, getProsodyConfigPath,
writeProsodyConfig writeProsodyConfig

View File

@ -10,7 +10,10 @@ interface ProsodyRunning {
messages: string[] messages: string[]
} }
async function prosodyCtl (options: RegisterServerOptions, command: string): Promise<string> { async function prosodyCtl (options: RegisterServerOptions, command: string, failOnError: boolean): Promise<string> {
const logger = options.peertubeHelpers.logger
logger.debug('Calling prosodyCtl with command ' + command)
const filePaths = await getProsodyFilePaths(options) const filePaths = await getProsodyFilePaths(options)
if (!/^\w+$/.test(command)) { if (!/^\w+$/.test(command)) {
throw new Error(`Invalid prosodyctl command '${command}'`) throw new Error(`Invalid prosodyctl command '${command}'`)
@ -37,9 +40,10 @@ async function prosodyCtl (options: RegisterServerOptions, command: string): Pro
e += data as string e += data as string
}) })
spawned.on('close', (code) => { spawned.on('close', (code) => {
if (code !== 0) { if (code !== 0 && failOnError) {
reject(e) reject(e)
} else { } else {
if (e !== '') { d += e }
resolve(d) resolve(d)
} }
}) })
@ -47,12 +51,14 @@ async function prosodyCtl (options: RegisterServerOptions, command: string): Pro
} }
async function getProsodyAbout (options: RegisterServerOptions): Promise<string> { async function getProsodyAbout (options: RegisterServerOptions): Promise<string> {
return prosodyCtl(options, 'about') return prosodyCtl(options, 'about', true)
} }
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') const logger = peertubeHelpers.logger
logger.info('Checking if Prosody is running')
const result: ProsodyRunning = { const result: ProsodyRunning = {
ok: false, ok: false,
messages: [] messages: []
@ -60,9 +66,11 @@ async function testProsodyRunning (options: RegisterServerOptions): Promise<Pros
const filePaths = await getProsodyFilePaths(options) const filePaths = await getProsodyFilePaths(options)
try { try {
logger.debug('Trying to access the pid file')
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`) result.messages.push(`Pid file ${filePaths.pid} found`)
} catch (error) { } catch (error) {
logger.debug(`Failed to access pid file: ${error as string}`)
result.messages.push(`Pid file ${filePaths.pid} not found`) result.messages.push(`Pid file ${filePaths.pid} not found`)
return result return result
} }
@ -86,7 +94,9 @@ async function testProsodyCorrectlyRunning (options: RegisterServerOptions): Pro
async function ensureProsodyRunning (options: RegisterServerOptions): Promise<void> { async function ensureProsodyRunning (options: RegisterServerOptions): Promise<void> {
const { peertubeHelpers, settingsManager } = options const { peertubeHelpers, settingsManager } = options
const logger = peertubeHelpers.logger const logger = peertubeHelpers.logger
logger.debug('Calling ensureProsodyRunning')
logger.debug('Checking if prosody should be active')
const setting = await settingsManager.getSetting('chat-use-prosody') const setting = await settingsManager.getSetting('chat-use-prosody')
if (!setting) { if (!setting) {
logger.info('Prosody is not activated, we wont launch it') logger.info('Prosody is not activated, we wont launch it')
@ -97,21 +107,24 @@ async function ensureProsodyRunning (options: RegisterServerOptions): Promise<vo
if (r.ok) { if (r.ok) {
r.messages.forEach(m => logger.debug(m)) r.messages.forEach(m => logger.debug(m))
logger.info('Prosody is already running correctly') logger.info('Prosody is already running correctly')
// Stop here. Nothing to change.
return return
} }
logger.info('Prosody is not running correctly: ') logger.info('Prosody is not running correctly: ')
r.messages.forEach(m => logger.info(m)) r.messages.forEach(m => logger.info(m))
// Shutting down... // Shutting down...
logger.debug('Shutting down prosody')
await ensureProsodyNotRunning(options) await ensureProsodyNotRunning(options)
// writing the configuration file // writing the configuration file
logger.debug('Writing the configuration file')
await writeProsodyConfig(options) await writeProsodyConfig(options)
const filePaths = await getProsodyFilePaths(options) const filePaths = await getProsodyFilePaths(options)
// launch prosody // launch prosody
logger.info('Going to launch prosody...') logger.info('Going to launch prosody')
await exec('prosody', { await exec('prosody', {
cwd: filePaths.dir, cwd: filePaths.dir,
env: { env: {
@ -119,16 +132,27 @@ async function ensureProsodyRunning (options: RegisterServerOptions): Promise<vo
PROSODY_CONFIG: filePaths.config PROSODY_CONFIG: filePaths.config
} }
}) })
logger.info('Verifying prosody is launched')
// TODO: listen for kill signal and kill prosody? const status = await prosodyCtl(options, 'status', true)
logger.info(`Prosody status: ${status}`)
} }
async function ensureProsodyNotRunning (options: RegisterServerOptions): Promise<void> { async function ensureProsodyNotRunning (options: RegisterServerOptions): Promise<void> {
const { peertubeHelpers } = options 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. // NB: this function is called on plugin unregister, even if prosody is not used
peertubeHelpers.logger.error('ensureProsodyNotRunning not implemented yet.') // 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 { export {