diff --git a/keyserver/src/cron/backups.js b/keyserver/src/cron/backups.js --- a/keyserver/src/cron/backups.js +++ b/keyserver/src/cron/backups.js @@ -9,7 +9,7 @@ import { promisify } from 'util'; import zlib from 'zlib'; -import dbConfig from '../../secrets/db_config'; +import { getDBConfig, type DBConfig } from '../database/db-config'; import { importJSON } from '../utils/import-json'; const readdir = promisify(fs.readdir); @@ -17,7 +17,11 @@ const unlink = promisify(fs.unlink); async function backupDB() { - const backupConfig = await importJSON('facts/backups'); + const [backupConfig, dbConfig] = await Promise.all([ + importJSON('facts/backups'), + getDBConfig(), + ]); + if (!backupConfig || !backupConfig.enabled) { return; } @@ -29,11 +33,16 @@ const rawStream = new PassThrough(); (async () => { try { - await mysqldump(filename, rawStream, ['--no-data'], { end: false }); + await mysqldump(dbConfig, filename, rawStream, ['--no-data'], { + end: false, + }); } catch {} try { const ignoreReports = `--ignore-table=${dbConfig.database}.reports`; - await mysqldump(filename, rawStream, ['--no-create-info', ignoreReports]); + await mysqldump(dbConfig, filename, rawStream, [ + '--no-create-info', + ignoreReports, + ]); } catch { rawStream.end(); } @@ -59,6 +68,7 @@ } function mysqldump( + dbConfig: DBConfig, filename: string, rawStream: PassThrough, extraParams: $ReadOnlyArray, diff --git a/keyserver/src/database/database.js b/keyserver/src/database/database.js --- a/keyserver/src/database/database.js +++ b/keyserver/src/database/database.js @@ -5,20 +5,21 @@ import mysqlPromise from 'mysql2/promise'; import SQL from 'sql-template-strings'; -import dbConfig from '../../secrets/db_config'; import { getScriptContext } from '../scripts/script-context'; import { connectionLimit, queryWarnTime } from './consts'; +import { getDBConfig } from './db-config'; import DatabaseMonitor from './monitor'; import type { Pool, SQLOrString, SQLStatementType } from './types'; const SQLStatement: SQLStatementType = SQL.SQLStatement; let pool, databaseMonitor; -function getPool(): Pool { +async function loadPool(): Promise { if (pool) { return pool; } const scriptContext = getScriptContext(); + const dbConfig = await getDBConfig(); pool = mysqlPromise.createPool({ ...dbConfig, connectionLimit, @@ -30,6 +31,10 @@ return pool; } +function endPool() { + pool?.end(); +} + function appendSQLArray( sql: SQLStatementType, sqlArray: $ReadOnlyArray, @@ -95,7 +100,7 @@ connection = await getMultipleStatementsConnection(); } if (!connection) { - connection = getPool(); + connection = await loadPool(); } const timeoutID = setTimeout( @@ -136,6 +141,7 @@ } async function getMultipleStatementsConnection() { + const dbConfig = await getDBConfig(); return await mysqlPromise.createConnection({ ...dbConfig, multipleStatements: true, @@ -143,7 +149,7 @@ } export { - getPool, + endPool, SQL, SQLStatement, appendSQLArray, diff --git a/keyserver/src/database/db-config.js b/keyserver/src/database/db-config.js new file mode 100644 --- /dev/null +++ b/keyserver/src/database/db-config.js @@ -0,0 +1,38 @@ +// @flow + +import invariant from 'invariant'; + +import { importJSON } from '../utils/import-json'; + +export type DBConfig = { + +host: string, + +user: string, + +password: string, + +database: string, +}; + +let dbConfig; +async function getDBConfig(): Promise { + if (dbConfig !== undefined) { + return dbConfig; + } + if ( + process.env.COMM_MYSQL_DATABASE && + process.env.COMM_MYSQL_USER && + process.env.COMM_MYSQL_PASSWORD + ) { + dbConfig = { + host: process.env.COMM_MYSQL_HOST || 'localhost', + user: process.env.COMM_MYSQL_USER, + password: process.env.COMM_MYSQL_PASSWORD, + database: process.env.COMM_MYSQL_DATABASE, + }; + } else { + const importedDBConfig = await importJSON('secrets/db_config'); + invariant(importedDBConfig, 'DB config missing'); + dbConfig = importedDBConfig; + } + return dbConfig; +} + +export { getDBConfig }; diff --git a/keyserver/src/scripts/utils.js b/keyserver/src/scripts/utils.js --- a/keyserver/src/scripts/utils.js +++ b/keyserver/src/scripts/utils.js @@ -1,11 +1,11 @@ // @flow -import { getPool } from '../database/database'; +import { endPool } from '../database/database'; import { endFirebase, endAPNs } from '../push/providers'; import { publisher } from '../socket/redis'; function endScript() { - getPool().end(); + endPool(); publisher.end(); endFirebase(); endAPNs();