From e1c479dc3187545dd77caad2ba2cb77e8148eb8c Mon Sep 17 00:00:00 2001 From: Brian Hudson Date: Mon, 22 Jan 2024 22:46:06 -0500 Subject: [PATCH 1/5] Require --no-node-snapshot in node 20+ When started using node 20+ checks if the --no-node-snapshot option was provided and throws an error if not. Signed-off-by: Brian Hudson --- .changeset/unlucky-pens-search.md | 6 +++ .../scaffolder-backend/src/service/helpers.ts | 40 +++++++++++++++++++ .../scaffolder-backend/src/service/router.ts | 16 +++++++- 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 .changeset/unlucky-pens-search.md diff --git a/.changeset/unlucky-pens-search.md b/.changeset/unlucky-pens-search.md new file mode 100644 index 0000000000..4786c14691 --- /dev/null +++ b/.changeset/unlucky-pens-search.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +When using node 20+ the `scaffolder-backend` will now throw an error at startup if the `--no-node-snapshot` option was +not provided to node. diff --git a/plugins/scaffolder-backend/src/service/helpers.ts b/plugins/scaffolder-backend/src/service/helpers.ts index 3412fec2d3..62f8d78810 100644 --- a/plugins/scaffolder-backend/src/service/helpers.ts +++ b/plugins/scaffolder-backend/src/service/helpers.ts @@ -107,3 +107,43 @@ export async function findTemplate(options: { return template as TemplateEntityV1beta3; } + +/** + * Checks if the '--no-node-snapshot' option is included in the NODE_OPTIONS environment variable + * or not included in the command line arguments. + * + * @remarks + * This function checks whether the '--no-node-snapshot' option is part of the NODE_OPTIONS environment + * variable or is missing from the command line arguments. If either condition is met, the function returns `true`. + * This check is especially important when using the "isolated-vm" package with Node.js version 20.x or later. + * + * According to the "isolated-vm" documentation on GitHub (https://github.com/laverdet/isolated-vm), + * if you are using a version of Node.js 20.x or later and you don't pass the '--no-node-snapshot' option, + * it can cause the process to crash. This function helps prevent such crashes by ensuring that the option + * is correctly provided. + * + * @returns {boolean} Returns `true` if the '--no-node-snapshot' option is included in the NODE_OPTIONS + * environment variable or not included in the command line arguments. Otherwise, it returns `false`. + */ +export function isNoNodeSnapshotOptionProvided(): boolean { + return ( + process.env.NODE_OPTIONS?.includes('--no-node-snapshot') || + process.argv.includes('--no-node-snapshot') + ); +} + +/** + * Gets the major version of the currently running Node.js process. + * + * @remarks + * This function extracts the major version from `process.versions.node` (a string representing the Node.js version), + * which includes the major, minor, and patch versions. It splits this string by the `.` character to get an array + * of these versions, and then parses the first element of this array (the major version) to a number. + * + * @returns {number} The major version of the currently running Node.js process. + */ +export function getMajorNodeVersion(): number { + const version = process.versions.node; + return parseInt(version.split('.')[0], 10); +} + diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index de0087e7de..5f27154c5b 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -61,7 +61,13 @@ import { } from '../scaffolder'; import { createDryRunner } from '../scaffolder/dryrun'; import { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker'; -import { findTemplate, getEntityBaseUrl, getWorkingDirectory } from './helpers'; +import { + findTemplate, + getEntityBaseUrl, + getMajorNodeVersion, + getWorkingDirectory, + isNoNodeSnapshotOptionProvided +} from './helpers'; import { IdentityApi, IdentityApiGetIdentityRequest, @@ -258,6 +264,14 @@ export async function createRouter( const logger = parentLogger.child({ plugin: 'scaffolder' }); + const nodeVersion = getMajorNodeVersion(); + if (nodeVersion >= 20 && !isNoNodeSnapshotOptionProvided()) { + throw new Error( + 'When using node v20+ Scaffolder requires that node be started with the --no-node-snapshot option. Please restart ' + + 'Backstage providing the node --no-node-snapshot option.', + ); + } + const identity: IdentityApi = options.identity || buildDefaultIdentityClient(options); const workingDirectory = await getWorkingDirectory(config, logger); From 1bb3ff229c4f4ecbcc8a764937060b94083ed238 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 23 Jan 2024 10:33:42 +0100 Subject: [PATCH 2/5] chore: fix prettier Signed-off-by: blam --- plugins/scaffolder-backend/src/service/helpers.ts | 1 - plugins/scaffolder-backend/src/service/router.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend/src/service/helpers.ts b/plugins/scaffolder-backend/src/service/helpers.ts index 62f8d78810..9e271a9d79 100644 --- a/plugins/scaffolder-backend/src/service/helpers.ts +++ b/plugins/scaffolder-backend/src/service/helpers.ts @@ -146,4 +146,3 @@ export function getMajorNodeVersion(): number { const version = process.versions.node; return parseInt(version.split('.')[0], 10); } - diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 5f27154c5b..baeae56e64 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -66,7 +66,7 @@ import { getEntityBaseUrl, getMajorNodeVersion, getWorkingDirectory, - isNoNodeSnapshotOptionProvided + isNoNodeSnapshotOptionProvided, } from './helpers'; import { IdentityApi, @@ -268,7 +268,7 @@ export async function createRouter( if (nodeVersion >= 20 && !isNoNodeSnapshotOptionProvided()) { throw new Error( 'When using node v20+ Scaffolder requires that node be started with the --no-node-snapshot option. Please restart ' + - 'Backstage providing the node --no-node-snapshot option.', + 'Backstage providing the node --no-node-snapshot option.', ); } From 6606560fdee9af8b5320e9d93be6f48af5aa01df Mon Sep 17 00:00:00 2001 From: Brian Hudson Date: Wed, 24 Jan 2024 08:58:52 -0500 Subject: [PATCH 3/5] Provide --no-node-version option for tests in CI when 20.x is used Signed-off-by: Brian Hudson --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd6e2edbc3..71d6b2e56a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -190,7 +190,7 @@ jobs: env: CI: true - NODE_OPTIONS: --max-old-space-size=4096 + NODE_OPTIONS: ${{ matrix.node-version == '20.x' && '--max-old-space-size=4096 --no-node-snapshot' || '--max-old-space-size=4096' }} INTEGRATION_TEST_GITHUB_TOKEN: ${{ secrets.INTEGRATION_TEST_GITHUB_TOKEN }} INTEGRATION_TEST_GITLAB_TOKEN: ${{ secrets.INTEGRATION_TEST_GITLAB_TOKEN }} INTEGRATION_TEST_BITBUCKET_TOKEN: ${{ secrets.INTEGRATION_TEST_BITBUCKET_TOKEN }} From df63f3d88280c3dab334aecb084966939de0e7a7 Mon Sep 17 00:00:00 2001 From: Brian Hudson Date: Wed, 24 Jan 2024 09:39:33 -0500 Subject: [PATCH 4/5] Provide --no-node-version option for E2E tests when 20.x is used Signed-off-by: Brian Hudson --- .github/workflows/verify_e2e-linux.yml | 2 +- .github/workflows/verify_e2e-windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index 3f403b2c91..3a94259eeb 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -36,7 +36,7 @@ jobs: env: CI: true - NODE_OPTIONS: --max-old-space-size=4096 + NODE_OPTIONS: ${{ matrix.node-version == '20.x' && '--max-old-space-size=4096 --no-node-snapshot' || '--max-old-space-size=4096' }} name: E2E Linux ${{ matrix.node-version }} steps: diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index d549ac2a40..37b39f29d3 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -26,7 +26,7 @@ jobs: env: CI: true - NODE_OPTIONS: --max-old-space-size=8192 + NODE_OPTIONS: ${{ matrix.node-version == '20.x' && '--max-old-space-size=4096 --no-node-snapshot' || '--max-old-space-size=4096' }} name: E2E Windows ${{ matrix.node-version }} steps: From f9869e3b901d548bbb5e5b3cfce95cc548a7117c Mon Sep 17 00:00:00 2001 From: Brian Hudson Date: Wed, 24 Jan 2024 17:05:40 -0500 Subject: [PATCH 5/5] Use --max-old-space-size=8192 in E2E tests Signed-off-by: Brian Hudson --- .github/workflows/verify_e2e-linux.yml | 2 +- .github/workflows/verify_e2e-windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index 3a94259eeb..0fe258b740 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -36,7 +36,7 @@ jobs: env: CI: true - NODE_OPTIONS: ${{ matrix.node-version == '20.x' && '--max-old-space-size=4096 --no-node-snapshot' || '--max-old-space-size=4096' }} + NODE_OPTIONS: ${{ matrix.node-version == '20.x' && '--max-old-space-size=8192 --no-node-snapshot' || '--max-old-space-size=8192' }} name: E2E Linux ${{ matrix.node-version }} steps: diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index 37b39f29d3..395dbe0b7f 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -26,7 +26,7 @@ jobs: env: CI: true - NODE_OPTIONS: ${{ matrix.node-version == '20.x' && '--max-old-space-size=4096 --no-node-snapshot' || '--max-old-space-size=4096' }} + NODE_OPTIONS: ${{ matrix.node-version == '20.x' && '--max-old-space-size=8192 --no-node-snapshot' || '--max-old-space-size=8192' }} name: E2E Windows ${{ matrix.node-version }} steps: