Refactoring the debug mode code, and adding some options.

This commit is contained in:
John Livingston
2023-05-23 12:39:05 +02:00
parent b525c203da
commit 8fe48a068f
8 changed files with 157 additions and 63 deletions

View File

@ -2,72 +2,121 @@ import type { RegisterServerOptions } from '@peertube/peertube-types'
import * as path from 'path'
import * as fs from 'fs'
/**
* Check if debug mode is enabled
* @param options server options
* @returns true if debug mode enabled
*/
export function isDebugMode (options: RegisterServerOptions): boolean {
const peertubeHelpers = options.peertubeHelpers
const logger = peertubeHelpers.logger
if (!peertubeHelpers.plugin) {
return false
}
const filepath = path.resolve(peertubeHelpers.plugin.getDataDirectoryPath(), 'debug_mode')
logger.debug('Testing debug mode by testing if file exists: ' + filepath)
if (fs.existsSync(filepath)) {
logger.info('Plugin livechat Debug mode is on.')
return true
}
return false
}
interface ProsodyDebuggerOptions {
mobdebugPath: string
mobdebugHost: string
mobdebugPort: string
}
interface DebugContent {
renewCertCheckInterval?: number
renewSelfSignedCertInterval?: number
logRotateCheckInterval?: number
logRotateEvery?: number
prosodyDebuggerOptions?: ProsodyDebuggerOptions
}
type DebugNumericValue = 'renewCertCheckInterval'
| 'renewSelfSignedCertInterval'
| 'logRotateEvery'
| 'logRotateCheckInterval'
let debugContent: DebugContent | null | false = null
function _readDebugFile (options: RegisterServerOptions): DebugContent | false {
if (debugContent !== null) { return debugContent }
const peertubeHelpers = options.peertubeHelpers
const logger = peertubeHelpers.logger
if (!peertubeHelpers.plugin) {
return false
}
const filepath = path.resolve(peertubeHelpers.plugin.getDataDirectoryPath(), 'debug_mode')
logger.debug('Testing debug mode by testing if file exists: ' + filepath)
if (!fs.existsSync(filepath)) {
debugContent = false
return false
}
logger.info('Plugin livechat Debug mode is on.')
debugContent = {}
try {
// content is optional, the file can be empty!
const content = fs.readFileSync(filepath).toString()
let json: any = !content ? {} : JSON.parse(content)
if (!json || (typeof json !== 'object')) { json = {} }
debugContent.prosodyDebuggerOptions = _getProsodyDebuggerOptions(options, json)
debugContent.logRotateCheckInterval = _getNumericOptions(options, json, 'log_rotate_check_interval')
debugContent.logRotateEvery = _getNumericOptions(options, json, 'log_rotate_every')
debugContent.renewCertCheckInterval = _getNumericOptions(options, json, 'renew_cert_check_interval')
debugContent.renewSelfSignedCertInterval = _getNumericOptions(options, json, 'renew_self_signed_cert_interval')
} catch (err) {
logger.error('Failed to read the debug_mode file content:', err)
}
return debugContent
}
function _getProsodyDebuggerOptions (options: RegisterServerOptions, json: any): ProsodyDebuggerOptions | undefined {
if (!json) { return undefined }
if (typeof json !== 'object') { return undefined }
if (!json.debug_prosody) { return undefined }
if (typeof json.debug_prosody !== 'object') { return undefined }
if (!json.debug_prosody.debugger_path) { return undefined }
if (typeof json.debug_prosody.debugger_path !== 'string') { return undefined }
const mobdebugPath = json.debug_prosody.debugger_path
if (!fs.statSync(mobdebugPath).isDirectory()) {
options.peertubeHelpers.logger.error('There should be a debugger, but cant find it. Path should be: ', mobdebugPath)
return undefined
}
const mobdebugHost = json.debug_prosody.host?.toString() || 'localhost'
const mobdebugPort = json.debug_prosody.port?.toString() || '8172'
return {
mobdebugPath,
mobdebugHost,
mobdebugPort
}
}
function _getNumericOptions (options: RegisterServerOptions, json: any, name: string): number | undefined {
if (!(name in json)) { return undefined }
const v = json[name]
if (typeof v !== 'number') { return undefined }
return json[name]
}
function unloadDebugMode (): void {
debugContent = null
}
/**
* Check if debug mode is enabled
* @param options server options
* @returns true if debug mode enabled
*/
function isDebugMode (options: RegisterServerOptions): boolean {
const debugContent = _readDebugFile(options)
return !!debugContent
}
/**
* On dev environnement, it is possible to enable a Lua debugger.
* @param options server options
* @returns false if we dont use the Prosody debugger. Else the need information to launch the debugger.
*/
export function prosodyDebuggerOptions (options: RegisterServerOptions): false | ProsodyDebuggerOptions {
function prosodyDebuggerOptions (options: RegisterServerOptions): false | ProsodyDebuggerOptions {
// Additional security: testing NODE_ENV.
// It should absolutly not be possible to enable Prosody debugger on production ev.
if (process.env.NODE_ENV !== 'dev') { return false }
if (!isDebugMode(options)) { return false }
const peertubeHelpers = options.peertubeHelpers
const logger = peertubeHelpers.logger
try {
const filepath = path.resolve(peertubeHelpers.plugin.getDataDirectoryPath(), 'debug_mode')
const content = fs.readFileSync(filepath).toString()
if (!content) { return false }
const json = JSON.parse(content)
if (!json) { return false }
if (typeof json !== 'object') { return false }
if (!json.debug_prosody) { return false }
if (typeof json.debug_prosody !== 'object') { return false }
if (!json.debug_prosody.debugger_path) { return false }
if (typeof json.debug_prosody.debugger_path !== 'string') { return false }
const mobdebugPath = json.debug_prosody.debugger_path
if (!fs.statSync(mobdebugPath).isDirectory()) {
logger.error('The should be a debugger, but cant find it. Path should be: ', mobdebugPath)
return false
}
const mobdebugHost = json.debug_prosody.host?.toString() || 'localhost'
const mobdebugPort = json.debug_prosody.port?.toString() || '8172'
return {
mobdebugPath,
mobdebugHost,
mobdebugPort
}
} catch (err) {
logger.error('Failed to read the debug_mode file content:', err)
return false
}
const debugContent = _readDebugFile(options)
if (debugContent === false) { return false }
if (!debugContent.prosodyDebuggerOptions) { return false }
return debugContent.prosodyDebuggerOptions
}
/**
@ -79,7 +128,7 @@ export function prosodyDebuggerOptions (options: RegisterServerOptions): false |
* @param options server options
* @param squashfsPath the folder where the AppImage is extracted
*/
export function disableLuaUnboundIfNeeded (options: RegisterServerOptions, squashfsPath: string): void {
function disableLuaUnboundIfNeeded (options: RegisterServerOptions, squashfsPath: string): void {
const peertubeHelpers = options.peertubeHelpers
const logger = peertubeHelpers.logger
@ -103,3 +152,37 @@ export function disableLuaUnboundIfNeeded (options: RegisterServerOptions, squas
logger.error(err)
}
}
/**
* Get a numerical parameter value. There are 3 kind of values:
* - classic production value
* - value when debug mode is activated
* - value when debut mode is activated, and the debug_mode file overrides it
* @param options server options
* @param name name of the wanted value
* @param defaultDebug default value when debug is activated
* @param defaultValue default value when debug is disabled
*
*/
function debugNumericParameter (
options: RegisterServerOptions,
name: DebugNumericValue,
defaultDebug: number,
defaultValue: number
): number {
const debugContent = _readDebugFile(options)
if (!debugContent) { return defaultValue }
if (name in debugContent) {
const v: any = debugContent[name]
if (typeof v === 'number') { return v }
}
return defaultDebug
}
export {
unloadDebugMode,
isDebugMode,
prosodyDebuggerOptions,
disableLuaUnboundIfNeeded,
debugNumericParameter
}

View File

@ -1,6 +1,6 @@
import type { RegisterServerOptions } from '@peertube/peertube-types'
import type { ProsodyConfig } from './config'
import { isDebugMode } from '../debug'
import { debugNumericParameter } from '../debug'
import { prosodyCtl, reloadProsody } from './ctl'
import * as path from 'path'
import * as fs from 'fs'
@ -18,9 +18,8 @@ function startProsodyCertificatesRenewCheck (options: RegisterServerOptions, con
return
}
const debugMode = isDebugMode(options)
// check every day (or every minutes in debug mode)
const checkInterval = debugMode ? 60000 : 3600000 * 24
const checkInterval = debugNumericParameter(options, 'renewCertCheckInterval', 60000, 3600000 * 24)
if (renew) {
stopProsodyCertificatesRenewCheck(options)
@ -91,8 +90,8 @@ async function renewCheckSelfSigned (options: RegisterServerOptions, config: Pro
// We have to check if the self signed certificate is still valid.
// Prosodyctl generated certificates are valid 365 days.
// We will renew it every 10 months (and every X minutes in debug mode)
const renewEvery = debugNumericParameter(options, 'renewSelfSignedCertInterval', 5 * 60000, 3600000 * 24 * 30 * 10)
const renewEvery = isDebugMode(options) ? 5 * 60000 : 3600000 * 24 * 30 * 10
// getting the file date...
const filepath = _filePathToTest(options, config)
if (!filepath) { return }

View File

@ -1,6 +1,6 @@
import type { RegisterServerOptions } from '@peertube/peertube-types'
import type { ProsodyFilePaths } from './config/paths'
import { isDebugMode } from '../debug'
import { debugNumericParameter } from '../debug'
import { reloadProsody } from './ctl'
type Rotate = (file: string, options: {
@ -33,9 +33,10 @@ async function _rotate (options: RegisterServerOptions, path: string): Promise<v
function startProsodyLogRotate (options: RegisterServerOptions, paths: ProsodyFilePaths): void {
const logger = options.peertubeHelpers.logger
const debugMode = isDebugMode(options)
const checkInterval = debugMode ? 60 * 1000 : 60 * 60 * 1000 // check every hour
const rotateEvery = debugMode ? 2 * 60 * 1000 : 24 * 60 * 60 * 1000 // rotate every 24hour
// check every hour
const checkInterval = debugNumericParameter(options, 'logRotateCheckInterval', 60 * 1000, 60 * 60 * 1000)
// rotate every 24hour
const rotateEvery = debugNumericParameter(options, 'logRotateEvery', 2 * 60 * 1000, 24 * 60 * 60 * 1000)
// TODO: also rotate when file is too big
if (logRotate) {

View File

@ -5,6 +5,7 @@ import { initCustomFields } from './lib/custom-fields'
import { initRouters } from './lib/routers/index'
import { initFederation } from './lib/federation/init'
import { prepareProsody, ensureProsodyRunning, ensureProsodyNotRunning } from './lib/prosody/ctl'
import { unloadDebugMode } from './lib/debug'
import decache from 'decache'
// FIXME: Peertube unregister don't have any parameter.
@ -43,6 +44,8 @@ async function unregister (): Promise<any> {
}
}
unloadDebugMode()
const module = __filename
OPTIONS?.peertubeHelpers.logger.info(`Unloading module ${module}...`)
// Peertube calls decache(plugin) on register, not unregister.