Config: preparing the arrival of new config files (for bots). Code refactoring.

This commit is contained in:
John Livingston 2021-12-07 11:59:32 +01:00
parent 2244ae22c2
commit f8ce4e6583
No known key found for this signature in database
GPG Key ID: B17B5640CE66CDBC
4 changed files with 102 additions and 68 deletions

View File

@ -1,4 +1,4 @@
import { getProsodyConfig, getProsodyConfigContentForDiagnostic, getWorkingDir } from '../prosody/config' import { getProsodyConfig, getWorkingDir } from '../prosody/config'
import { getProsodyAbout, testProsodyCorrectlyRunning } from '../prosody/ctl' import { getProsodyAbout, testProsodyCorrectlyRunning } from '../prosody/ctl'
import { newResult, TestResult } from './utils' import { newResult, TestResult } from './utils'
import { getAPIKey } from '../apikey' import { getAPIKey } from '../apikey'
@ -24,7 +24,6 @@ export async function diagProsody (test: string, options: RegisterServerOptions)
let prosodyHost: string let prosodyHost: string
try { try {
const wantedConfig = await getProsodyConfig(options) const wantedConfig = await getProsodyConfig(options)
const filePath = wantedConfig.paths.config
result.messages.push(`Prosody will run on port '${wantedConfig.port}'`) result.messages.push(`Prosody will run on port '${wantedConfig.port}'`)
prosodyPort = wantedConfig.port prosodyPort = wantedConfig.port
@ -54,34 +53,40 @@ export async function diagProsody (test: string, options: RegisterServerOptions)
result.messages.push(`The Demo bot is active for videos: ${wantedConfig.bots.demo.join(', ')}`) result.messages.push(`The Demo bot is active for videos: ${wantedConfig.bots.demo.join(', ')}`)
} }
await fs.promises.access(filePath, fs.constants.R_OK) // throw an error if file does not exist. const configFiles = wantedConfig.getConfigFiles()
result.messages.push(`The prosody configuration file (${filePath}) exists`) for (const configFile of configFiles) {
const actualContent = await fs.promises.readFile(filePath, { const filePath = configFile.path
encoding: 'utf-8' const configFileKey = configFile.key
})
result.debug.push({ await fs.promises.access(filePath, fs.constants.R_OK) // throw an error if file does not exist.
title: 'Current prosody configuration', result.messages.push(`The prosody '${configFileKey}' configuration file (${filePath}) exists`)
// we have to hide secret keys and other values. const actualContent = await fs.promises.readFile(filePath, {
// But here, we haven't them for actualContent. encoding: 'utf-8'
// So we will use values in wantedConfig, hopping it is enough.
message: getProsodyConfigContentForDiagnostic(wantedConfig, actualContent)
})
const wantedContent = wantedConfig.content
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',
// we have to hide secret keys and other values:
message: getProsodyConfigContentForDiagnostic(wantedConfig)
}) })
return result
result.debug.push({
title: `Current prosody '${configFileKey}' configuration`,
// we have to hide secret keys and other values.
// But here, we haven't them for actualContent.
// So we will use values in wantedConfig, hopping it is enough.
message: wantedConfig.contentForDiagnostic(actualContent)
})
const wantedContent = configFile.content
if (actualContent === wantedContent) {
result.messages.push(`Prosody configuration file '${configFileKey}' content is correct.`)
} else {
result.messages.push(`Prosody configuration file '${configFileKey}'' content is not correct.`)
result.debug.push({
title: `Prosody configuration '${configFileKey}' should be`,
// we have to hide secret keys and other values:
message: wantedConfig.contentForDiagnostic(wantedContent)
})
return result
}
} }
} catch (error) { } catch (error) {
result.messages.push('Error when requiring the prosody config file: ' + (error as string)) result.messages.push('Error when testing the prosody config: ' + (error as string))
return result return result
} }

View File

@ -60,6 +60,7 @@ async function getProsodyFilePaths (options: RegisterServerOptions): Promise<Pro
log: path.resolve(dir, 'prosody.log'), log: path.resolve(dir, 'prosody.log'),
config: path.resolve(dir, 'prosody.cfg.lua'), config: path.resolve(dir, 'prosody.cfg.lua'),
data: path.resolve(dir, 'data'), data: path.resolve(dir, 'data'),
bots: path.resolve(dir, 'bots'),
modules: path.resolve(__dirname, '../../prosody-modules') modules: path.resolve(__dirname, '../../prosody-modules')
} }
} }
@ -67,18 +68,42 @@ async function getProsodyFilePaths (options: RegisterServerOptions): Promise<Pro
interface ProsodyConfigBots { interface ProsodyConfigBots {
demo?: string[] // if the demo bot is activated, here are the video UUIDS where it will be. demo?: string[] // if the demo bot is activated, here are the video UUIDS where it will be.
} }
interface ProsodyConfig {
type ProsodyConfigFilesKey = 'prosody'
type ProsodyConfigFiles = Array<{
key: ProsodyConfigFilesKey
path: string
content: string content: string
paths: ProsodyFilePaths }>
host: string
port: string class ProsodyConfig {
baseApiUrl: string constructor (
roomType: 'video' | 'channel' private readonly configFiles: ProsodyConfigFiles,
logByDefault: boolean public paths: ProsodyFilePaths,
logExpiration: ConfigLogExpiration public host: string,
bots: ProsodyConfigBots public port: string,
valuesToHideInDiagnostic: {[key: string]: string} public baseApiUrl: string,
public roomType: 'video' | 'channel',
public logByDefault: boolean,
public logExpiration: ConfigLogExpiration,
public bots: ProsodyConfigBots,
public valuesToHideInDiagnostic: {[key: string]: string}
) {}
public getConfigFiles (): ProsodyConfigFiles {
return this.configFiles
}
public contentForDiagnostic (content: string): string {
let r: string = content
for (const key in this.valuesToHideInDiagnostic) {
// replaceAll not available, using trick:
r = r.split(this.valuesToHideInDiagnostic[key]).join(`***${key}***`)
}
return r
}
} }
async function getProsodyConfig (options: RegisterServerOptions): Promise<ProsodyConfig> { async function getProsodyConfig (options: RegisterServerOptions): Promise<ProsodyConfig> {
const logger = options.peertubeHelpers.logger const logger = options.peertubeHelpers.logger
logger.debug('Calling getProsodyConfig') logger.debug('Calling getProsodyConfig')
@ -182,18 +207,24 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
const content = config.write() const content = config.write()
return { return new ProsodyConfig(
content, [
{
key: 'prosody',
path: paths.config,
content: content
}
],
paths, paths,
prosodyDomain,
port, port,
baseApiUrl, baseApiUrl,
host: prosodyDomain,
roomType, roomType,
logByDefault, logByDefault,
logExpiration, logExpiration,
bots, bots,
valuesToHideInDiagnostic valuesToHideInDiagnostic
} )
} }
async function writeProsodyConfig (options: RegisterServerOptions): Promise<ProsodyConfig> { async function writeProsodyConfig (options: RegisterServerOptions): Promise<ProsodyConfig> {
@ -204,12 +235,16 @@ async function writeProsodyConfig (options: RegisterServerOptions): Promise<Pros
await ensureWorkingDir(options) await ensureWorkingDir(options)
logger.debug('Computing the Prosody config content') logger.debug('Computing the Prosody config content')
const config = await getProsodyConfig(options) const config = await getProsodyConfig(options)
const content = config.content
const fileName = config.paths.config
logger.info(`Writing prosody configuration file to ${fileName}`) const configFiles = config.getConfigFiles()
await fs.promises.writeFile(fileName, content) for (const configFile of configFiles) {
logger.debug('Prosody configuration file writen') const content = configFile.content
const fileName = configFile.path
logger.info(`Writing prosody configuration file '${configFile.key}' to ${fileName}.`)
await fs.promises.writeFile(fileName, content)
logger.debug(`Prosody configuration file '${configFile.key}' writen.`)
}
return config return config
} }
@ -265,20 +300,10 @@ function readLogExpiration (options: RegisterServerOptions, logExpiration: strin
} }
} }
function getProsodyConfigContentForDiagnostic (config: ProsodyConfig, content?: string): string {
let r: string = content ?? config.content
for (const key in config.valuesToHideInDiagnostic) {
// replaceAll not available, using trick:
r = r.split(config.valuesToHideInDiagnostic[key]).join(`***${key}***`)
}
return r
}
export { export {
getProsodyConfig, getProsodyConfig,
getWorkingDir, getWorkingDir,
ensureWorkingDir, ensureWorkingDir,
getProsodyFilePaths, getProsodyFilePaths,
writeProsodyConfig, writeProsodyConfig
getProsodyConfigContentForDiagnostic
} }

View File

@ -5,6 +5,7 @@ interface ProsodyFilePaths {
log: string log: string
config: string config: string
data: string data: string
bots: string
modules: string modules: string
} }

View File

@ -113,20 +113,23 @@ async function testProsodyCorrectlyRunning (options: RegisterServerOptions): Pro
try { try {
const wantedConfig = await getProsodyConfig(options) const wantedConfig = await getProsodyConfig(options)
const filePath = wantedConfig.paths.config const configFiles = wantedConfig.getConfigFiles()
for (const configFile of configFiles) {
const filePath = configFile.path
await fs.promises.access(filePath, fs.constants.R_OK) // throw an error if file does not exist. await fs.promises.access(filePath, fs.constants.R_OK) // throw an error if file does not exist.
result.messages.push(`The prosody configuration file (${filePath}) exists`) result.messages.push(`The prosody configuration file (${configFile.key}: ${filePath}) exists`)
const actualContent = await fs.promises.readFile(filePath, { const actualContent = await fs.promises.readFile(filePath, {
encoding: 'utf-8' encoding: 'utf-8'
}) })
const wantedContent = wantedConfig.content const wantedContent = configFile.content
if (actualContent === wantedContent) { if (actualContent === wantedContent) {
result.messages.push('Prosody configuration file content is correct.') result.messages.push(`Prosody configuration file '${configFile.key}' content is correct.`)
} else { } else {
result.messages.push('Prosody configuration file content is not correct.') result.messages.push(`Prosody configuration file '${configFile.key}' content is not correct.`)
return result return result
}
} }
} catch (error) { } catch (error) {
result.messages.push('Error when requiring the prosody config file: ' + (error as string)) result.messages.push('Error when requiring the prosody config file: ' + (error as string))