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
No known key found for this signature in database
GPG Key ID: B17B5640CE66CDBC
8 changed files with 157 additions and 63 deletions

View File

@ -14,6 +14,7 @@ TODO: write the new prosody modules README.
TODO: mod_s2s_peertubelivechat: dont allow to connect to remote server that are not Peertube servers.
TODO: when sanitizing remote chat endpoint, check that the domain is the same as the video domain (or is room.videodomain.tld).
TODO: get remote server chat informations if missing (for now, it can be missing if there is no known remote video from that server).
TODO: outgoing s2s connection have a session.secure=true hardcoded. Should not.
### Minor changes and fixes
@ -21,6 +22,7 @@ TODO: get remote server chat informations if missing (for now, it can be missing
* Using process.spawn instead of process.exec to launch Prosody (safer, and more optimal).
* Prosody AppImage: fix path mapping: we only map necessary /etc/ subdir, so that the AppImage can access to /etc/resolv.conf, /etc/hosts, ...
* Prosody AppImage: hidden debug mode to disable lua-unbound, that seems broken in some docker dev environments.
* Debug Mode: can change some parameters.
## 6.3.0

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.

View File

@ -79,6 +79,8 @@ The simple existence of this file is sufficient to trigger the debug mode.
To make sure it's taken into account, you can restart your Peertube instance.
This file can contain some JSON to enable more advances options.
To have a list of existing parameters, check `server/lib/debug.ts`.
Restart Peertube after each content modification.
{{% notice warning %}}
Don't enable this mode on a production server, neither on a public server.

View File

@ -81,6 +81,8 @@ The simple existence of this file is sufficient to trigger the debug mode.
To make sure it's taken into account, you can restart your Peertube instance.
This file can contain some JSON to enable more advances options.
To have a list of existing parameters, check `server/lib/debug.ts`.
Restart Peertube after each content modification.
{{% notice warning %}}
Don't enable this mode on a production server, neither on a public server.

View File

@ -80,6 +80,8 @@ La simple existance de ce fichier suffit à déclencher le mode debug.
Pour être sûr qu'il est pris en compte, vous pouvez redémarrer votre instance Peertube.
Ce fichier peut également contenir du JSON qui pourra activer d'autres options.
Pour en avoir la liste, vous pouvez regarder le code de `server/lib/debug.ts`.
Redémarrez Peertube après chaque modification de son contenu.
{{% notice warning %}}
N'activer jamais ce mode sur un serveur de production, ni même sur un serveur public.