0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-30 22:34:10 -05:00

feat: handle kill signals nicely (#2130)

* feat: handle kill signals nicely

* chore: add docs and rename variable

Co-authored-by: edward kim <edward.kim@lendi.com.au>
This commit is contained in:
Juan Picado 2021-03-17 07:29:07 +01:00 committed by GitHub
parent 93468211d6
commit 7b6fbae6ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 44 deletions

10
docs/env.variables.md Normal file
View file

@ -0,0 +1,10 @@
# Environment variables
A full list of available environment variables that allow override
internal features.
#### VERDACCIO_HANDLE_KILL_SIGNALS
Enables gracefully shutdown, more info [here](https://github.com/verdaccio/verdaccio/pull/2121).
This will be enable by default on Verdaccio 5.

View file

@ -17,13 +17,9 @@ const logger = require('./logger');
function displayExperimentsInfoBox(experiments) { function displayExperimentsInfoBox(experiments) {
const experimentList = Object.keys(experiments); const experimentList = Object.keys(experiments);
if (experimentList.length >= 1) { if (experimentList.length >= 1) {
logger.logger.warn( logger.logger.warn('⚠️ experiments are enabled, we recommend do not use experiments in production, comment out this section to disable it');
'⚠️ experiments are enabled, we recommend do not use experiments in production, comment out this section to disable it'
);
experimentList.forEach((experiment) => { experimentList.forEach((experiment) => {
logger.logger.warn( logger.logger.warn(` - support for ${experiment} ${experiments[experiment] ? 'is enabled' : ' is disabled'}`);
` - support for ${experiment} ${experiments[experiment] ? 'is enabled' : ' is disabled'}`
);
}); });
} }
} }
@ -36,14 +32,7 @@ function displayExperimentsInfoBox(experiments) {
* @param {String} pkgVersion * @param {String} pkgVersion
* @param {String} pkgName * @param {String} pkgName
*/ */
function startVerdaccio( function startVerdaccio(config: any, cliListen: string, configPath: string, pkgVersion: string, pkgName: string, callback: Callback): void {
config: any,
cliListen: string,
configPath: string,
pkgVersion: string,
pkgName: string,
callback: Callback
): void {
if (isObject(config) === false) { if (isObject(config) === false) {
throw new Error(API_ERROR.CONFIG_BAD_FORMAT); throw new Error(API_ERROR.CONFIG_BAD_FORMAT);
} }
@ -63,11 +52,7 @@ function startVerdaccio(
// http // http
webServer = http.createServer(app); webServer = http.createServer(app);
} }
if ( if (config.server && typeof config.server.keepAliveTimeout !== 'undefined' && config.server.keepAliveTimeout !== 'null') {
config.server &&
typeof config.server.keepAliveTimeout !== 'undefined' &&
config.server.keepAliveTimeout !== 'null'
) {
// library definition for node is not up to date (doesn't contain recent 8.0 changes) // library definition for node is not up to date (doesn't contain recent 8.0 changes)
webServer.keepAliveTimeout = config.server.keepAliveTimeout * 1000; webServer.keepAliveTimeout = config.server.keepAliveTimeout * 1000;
} }
@ -95,10 +80,7 @@ function logHTTPSWarning(storageLocation) {
// commands are borrowed from node.js docs // commands are borrowed from node.js docs
'To quickly create self-signed certificate, use:', 'To quickly create self-signed certificate, use:',
' $ openssl genrsa -out ' + resolveConfigPath(storageLocation, keyPem) + ' 2048', ' $ openssl genrsa -out ' + resolveConfigPath(storageLocation, keyPem) + ' 2048',
' $ openssl req -new -sha256 -key ' + ' $ openssl req -new -sha256 -key ' + resolveConfigPath(storageLocation, keyPem) + ' -out ' + resolveConfigPath(storageLocation, csrPem),
resolveConfigPath(storageLocation, keyPem) +
' -out ' +
resolveConfigPath(storageLocation, csrPem),
' $ openssl x509 -req -in ' + ' $ openssl x509 -req -in ' +
resolveConfigPath(storageLocation, csrPem) + resolveConfigPath(storageLocation, csrPem) +
' -signkey ' + ' -signkey ' +
@ -109,20 +91,16 @@ function logHTTPSWarning(storageLocation) {
'And then add to config file (' + storageLocation + '):', 'And then add to config file (' + storageLocation + '):',
' https:', ' https:',
` key: ${resolveConfigPath(storageLocation, keyPem)}`, ` key: ${resolveConfigPath(storageLocation, keyPem)}`,
` cert: ${resolveConfigPath(storageLocation, certPem)}` ` cert: ${resolveConfigPath(storageLocation, certPem)}`,
].join('\n') ].join('\n')
); );
process.exit(2); process.exit(2);
} }
function handleHTTPS( function handleHTTPS(app: express.Application, configPath: string, config: ConfigWithHttps): https.Server {
app: express.Application,
configPath: string,
config: ConfigWithHttps
): https.Server {
try { try {
let httpsOptions = { let httpsOptions = {
secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 // disable insecure SSLv2 and SSLv3 secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3, // disable insecure SSLv2 and SSLv3
}; };
const keyCertConfig = config.https as HttpsConfKeyCert; const keyCertConfig = config.https as HttpsConfKeyCert;
@ -137,7 +115,7 @@ function handleHTTPS(
const { pfx, passphrase } = pfxConfig; const { pfx, passphrase } = pfxConfig;
httpsOptions = assign(httpsOptions, { httpsOptions = assign(httpsOptions, {
pfx: fs.readFileSync(pfx), pfx: fs.readFileSync(pfx),
passphrase: passphrase || '' passphrase: passphrase || '',
}); });
} else { } else {
const { key, cert, ca } = keyCertConfig; const { key, cert, ca } = keyCertConfig;
@ -145,8 +123,8 @@ function handleHTTPS(
key: fs.readFileSync(key), key: fs.readFileSync(key),
cert: fs.readFileSync(cert), cert: fs.readFileSync(cert),
...(ca && { ...(ca && {
ca: fs.readFileSync(ca) ca: fs.readFileSync(ca),
}) }),
}); });
} }
return https.createServer(httpsOptions, app); return https.createServer(httpsOptions, app);
@ -157,18 +135,13 @@ function handleHTTPS(
} }
} }
function listenDefaultCallback( function listenDefaultCallback(webServer: Application, addr: any, pkgName: string, pkgVersion: string): void {
webServer: Application, const server = webServer
addr: any,
pkgName: string,
pkgVersion: string
): void {
webServer
.listen(addr.port || addr.path, addr.host, (): void => { .listen(addr.port || addr.path, addr.host, (): void => {
// send a message for tests // send a message for tests
if (isFunction(process.send)) { if (isFunction(process.send)) {
process.send({ process.send({
verdaccio_started: true verdaccio_started: true,
}); });
} }
}) })
@ -177,20 +150,35 @@ function listenDefaultCallback(
process.exit(2); process.exit(2);
}); });
function handleShutdownGracefully() {
logger.logger.fatal('received shutdown signal - closing server gracefully...');
server.close(() => {
logger.logger.info('server closed.');
process.exit(0);
});
}
// handle shutdown signals nicely when environment says so
if (process.env.VERDACCIO_HANDLE_KILL_SIGNALS === 'true') {
process.on('SIGINT', handleShutdownGracefully);
process.on('SIGTERM', handleShutdownGracefully);
process.on('SIGHUP', handleShutdownGracefully);
}
logger.logger.warn( logger.logger.warn(
{ {
addr: addr.path addr: addr.path
? URL.format({ ? URL.format({
protocol: 'unix', protocol: 'unix',
pathname: addr.path pathname: addr.path,
}) })
: URL.format({ : URL.format({
protocol: addr.proto, protocol: addr.proto,
hostname: addr.host, hostname: addr.host,
port: addr.port, port: addr.port,
pathname: '/' pathname: '/',
}), }),
version: pkgName + '/' + pkgVersion version: pkgName + '/' + pkgVersion,
}, },
'http address - @{addr} - @{version}' 'http address - @{addr} - @{version}'
); );