mirror of
https://github.com/Graylog2/graylog2-server.git
synced 2026-03-13 09:32:21 +08:00
* Bump puppeteer from 21.9.0 to 22.0.0 in /graylog2-web-interface Bumps [puppeteer](https://github.com/puppeteer/puppeteer) from 21.9.0 to 22.0.0. - [Release notes](https://github.com/puppeteer/puppeteer/releases) - [Changelog](https://github.com/puppeteer/puppeteer/blob/main/release-please-config.json) - [Commits](https://github.com/puppeteer/puppeteer/compare/puppeteer-v21.9.0...puppeteer-v22.0.0) --- updated-dependencies: - dependency-name: puppeteer dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Adjusting console message logging. * Fixing up logging, adding route for favicon. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dennis Oelkers <dennis@graylog.com>
185 lines
5.6 KiB
JavaScript
185 lines
5.6 KiB
JavaScript
/*
|
|
* Copyright (C) 2020 Graylog, Inc.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the Server Side Public License, version 1,
|
|
* as published by MongoDB, Inc.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* Server Side Public License for more details.
|
|
*
|
|
* You should have received a copy of the Server Side Public License
|
|
* along with this program. If not, see
|
|
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
|
*/
|
|
/* eslint-disable no-console */
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const puppeteer = require('puppeteer');
|
|
const express = require('express');
|
|
const cors = require('cors');
|
|
|
|
const VENDORMODULE = 'vendor-module.json';
|
|
const BUILDMODULE = 'module.json';
|
|
|
|
function fatal(throwable) {
|
|
console.error(throwable);
|
|
process.exit(128);
|
|
}
|
|
|
|
function generateIndexHtml(assets) {
|
|
return `
|
|
<html>
|
|
<head>
|
|
</head>
|
|
<body>
|
|
<div id="app-root" />
|
|
${assets.map((asset) => `<script src="${asset}"></script>`).join('\n')}
|
|
</body>
|
|
<html>
|
|
`;
|
|
}
|
|
|
|
function bootstrapExpress(buildDir, config, pluginMounts, indexHtml = '<html><body></body></html>') {
|
|
const app = express();
|
|
app.get('/', (req, res) => res.send(indexHtml));
|
|
app.get('/assets/config.js', (req, res) => res.send(config));
|
|
app.use('/favicon.ico', express.static('public/images/favicon.png'));
|
|
app.use('/assets', express.static(buildDir));
|
|
|
|
Object.entries(pluginMounts)
|
|
.forEach(([name, pluginPath]) => app.use(`/assets/${name}`, express.static(pluginPath)));
|
|
|
|
const server = app.listen();
|
|
const { port } = server.address();
|
|
|
|
return { url: `http://localhost:${port}`, server };
|
|
}
|
|
|
|
function bootstrapApi(prefix = '/api/') {
|
|
const api = express();
|
|
api.use(cors());
|
|
|
|
const rootHandler = (req, res) => res.json({
|
|
cluster_id: 'deadbeef',
|
|
node_id: 'deadbeef',
|
|
version: '3.0.0',
|
|
tagline: 'Manage your logs in the dark and have lasers going and make it look like you\'re from space!',
|
|
});
|
|
api.get(prefix, rootHandler);
|
|
|
|
const sessionHandler = (req, res) => res.json({ session_id: null, username: null, is_valid: false });
|
|
api.get(`${prefix}system/sessions`, sessionHandler);
|
|
const authtypeHandler = (req, res) => res.json({ backend: 'okta' });
|
|
api.get(`${prefix}system/authentication/services/backends/active-backend/type`, authtypeHandler);
|
|
|
|
const server = api.listen();
|
|
const { port } = server.address();
|
|
|
|
return { url: `http://localhost:${port}${prefix}`, server };
|
|
}
|
|
|
|
process.setMaxListeners(0);
|
|
|
|
async function loadPage(url, handleError, handleConsole) {
|
|
try {
|
|
const options = {
|
|
headless: true,
|
|
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
};
|
|
const browser = await puppeteer.launch(options);
|
|
const page = await browser.newPage();
|
|
page.on('console', handleConsole);
|
|
page.on('pageerror', handleError);
|
|
|
|
await page.goto(url, { waitUntil: 'networkidle0', timeout: 30000 });
|
|
|
|
return { page, browser };
|
|
} catch (e) {
|
|
return fatal(e);
|
|
}
|
|
}
|
|
|
|
const buildDir = process.argv[2] || 'target/web/build';
|
|
const plugins = process.argv.slice(3);
|
|
|
|
const config = (url) => `
|
|
window.appConfig = {
|
|
gl2ServerUrl: '${url}',
|
|
gl2AppPathPrefix: '/',
|
|
rootTimeZone: 'UTC',
|
|
};
|
|
`;
|
|
|
|
function collectMounts(pluginModuleNames) {
|
|
return pluginModuleNames.map((pluginModuleName) => {
|
|
const pluginModule = JSON.parse(fs.readFileSync(pluginModuleName));
|
|
const name = Object.keys(pluginModule.files.chunks)[0];
|
|
|
|
return { [name]: path.dirname(pluginModuleName) };
|
|
}).reduce((prev, cur) => ({ ...prev, ...cur }), {});
|
|
}
|
|
|
|
function collectAssets(pluginModules) {
|
|
const vendorModule = JSON.parse(fs.readFileSync(`${buildDir}/${VENDORMODULE}`));
|
|
const buildModule = JSON.parse(fs.readFileSync(`${buildDir}/${BUILDMODULE}`));
|
|
const pluginAssets = pluginModules.flatMap((pluginModule) => pluginModule.files.js);
|
|
|
|
return [
|
|
'config.js',
|
|
...vendorModule.files.js,
|
|
...buildModule.files.js,
|
|
...pluginAssets,
|
|
].map((asset) => `/assets/${asset}`);
|
|
}
|
|
|
|
const pluginModules = plugins.map((plugin) => JSON.parse(fs.readFileSync(plugin)));
|
|
const assets = collectAssets(pluginModules);
|
|
const pluginMounts = collectMounts(plugins);
|
|
|
|
const api = bootstrapApi();
|
|
const { url, server } = bootstrapExpress(buildDir, config(api.url), pluginMounts, generateIndexHtml(assets));
|
|
|
|
const pageErrors = [];
|
|
const consoleLogs = [];
|
|
|
|
const trackEvent = (evt, arr) => {
|
|
const msg = { type: evt?.type(), message: evt?.text(), stack: JSON.stringify(evt?.stackTrace(), null, 2) };
|
|
arr.push(msg);
|
|
};
|
|
|
|
const formatLog = (msg) => `${msg.type}: ${msg.message}\n${msg.stack}`;
|
|
|
|
const pagePromise = loadPage(url, (msg) => trackEvent(msg, pageErrors), (msg) => trackEvent(msg, consoleLogs));
|
|
|
|
pagePromise
|
|
.catch((err) => {
|
|
console.error('Error: ', err.toString());
|
|
process.exitCode = 1;
|
|
})
|
|
.finally(() => {
|
|
const isSuccess = pageErrors.length === 0 && consoleLogs.length === 0;
|
|
|
|
if (pageErrors.length > 0) {
|
|
console.log('Errors:');
|
|
console.log(pageErrors.map(formatLog).join('\n'));
|
|
}
|
|
|
|
if (consoleLogs.length > 0) {
|
|
console.log('Console Logs:');
|
|
console.log(consoleLogs.map(formatLog).join('\n'));
|
|
}
|
|
|
|
console.log(`\n${isSuccess ? 'Success' : 'Failure'}: Encountered ${pageErrors.length} errors and ${consoleLogs.length} messages on the console during loading.`);
|
|
process.exitCode = isSuccess ? 0 : 1;
|
|
})
|
|
.finally(async () => {
|
|
const { browser } = await pagePromise;
|
|
await browser.close();
|
|
server.close();
|
|
api.server.close();
|
|
});
|