Skip to content

Commit 1e1a2a1

Browse files
authored
add guardrail to completely bail out in very old versions (#4878)
1 parent 29ff735 commit 1e1a2a1

File tree

3 files changed

+78
-49
lines changed

3 files changed

+78
-49
lines changed

.github/workflows/project.yml

+14
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@ jobs:
4444
- uses: ./.github/actions/install
4545
- run: node node_modules/.bin/mocha --colors --timeout 30000 integration-tests/init.spec.js
4646

47+
integration-guardrails-unsupported:
48+
strategy:
49+
matrix:
50+
version: ['0.10', '4', '6', '8', '10']
51+
runs-on: ubuntu-latest
52+
env:
53+
DD_INJECTION_ENABLED: 'true'
54+
steps:
55+
- uses: actions/checkout@v4
56+
- uses: actions/setup-node@v3
57+
with:
58+
node-version: ${{ matrix.version }}
59+
- run: node ./init
60+
4761
integration-ci:
4862
strategy:
4963
matrix:

init.js

+60-47
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,71 @@
11
'use strict'
22

3-
const path = require('path')
4-
const Module = require('module')
5-
const semver = require('semver')
6-
const log = require('./packages/dd-trace/src/log')
7-
const { isTrue } = require('./packages/dd-trace/src/util')
8-
const telemetry = require('./packages/dd-trace/src/telemetry/init-telemetry')
3+
/* eslint-disable no-var */
94

10-
let initBailout = false
11-
let clobberBailout = false
12-
const forced = isTrue(process.env.DD_INJECT_FORCE)
5+
var NODE_MAJOR = require('./version').NODE_MAJOR
136

14-
if (process.env.DD_INJECTION_ENABLED) {
15-
// If we're running via single-step install, and we're not in the app's
16-
// node_modules, then we should not initialize the tracer. This prevents
17-
// single-step-installed tracer from clobbering the manually-installed tracer.
18-
let resolvedInApp
19-
const entrypoint = process.argv[1]
20-
try {
21-
resolvedInApp = Module.createRequire(entrypoint).resolve('dd-trace')
22-
} catch (e) {
23-
// Ignore. If we can't resolve the module, we assume it's not in the app.
24-
}
25-
if (resolvedInApp) {
26-
const ourselves = path.join(__dirname, 'index.js')
27-
if (ourselves !== resolvedInApp) {
28-
clobberBailout = true
7+
// We use several things that are not supported by older versions of Node:
8+
// - AsyncLocalStorage
9+
// - The `semver` module
10+
// - dc-polyfill
11+
// - Mocha (for testing)
12+
// and probably others.
13+
// TODO: Remove all these dependencies so that we can report telemetry.
14+
if (NODE_MAJOR >= 12) {
15+
var path = require('path')
16+
var Module = require('module')
17+
var semver = require('semver')
18+
var log = require('./packages/dd-trace/src/log')
19+
var isTrue = require('./packages/dd-trace/src/util').isTrue
20+
var telemetry = require('./packages/dd-trace/src/telemetry/init-telemetry')
21+
22+
var initBailout = false
23+
var clobberBailout = false
24+
var forced = isTrue(process.env.DD_INJECT_FORCE)
25+
26+
if (process.env.DD_INJECTION_ENABLED) {
27+
// If we're running via single-step install, and we're not in the app's
28+
// node_modules, then we should not initialize the tracer. This prevents
29+
// single-step-installed tracer from clobbering the manually-installed tracer.
30+
var resolvedInApp
31+
var entrypoint = process.argv[1]
32+
try {
33+
resolvedInApp = Module.createRequire(entrypoint).resolve('dd-trace')
34+
} catch (e) {
35+
// Ignore. If we can't resolve the module, we assume it's not in the app.
36+
}
37+
if (resolvedInApp) {
38+
var ourselves = path.join(__dirname, 'index.js')
39+
if (ourselves !== resolvedInApp) {
40+
clobberBailout = true
41+
}
2942
}
30-
}
3143

32-
// If we're running via single-step install, and the runtime doesn't match
33-
// the engines field in package.json, then we should not initialize the tracer.
34-
if (!clobberBailout) {
35-
const { engines } = require('./package.json')
36-
const version = process.versions.node
37-
if (!semver.satisfies(version, engines.node)) {
38-
initBailout = true
39-
telemetry([
40-
{ name: 'abort', tags: ['reason:incompatible_runtime'] },
41-
{ name: 'abort.runtime', tags: [] }
42-
])
43-
log.info('Aborting application instrumentation due to incompatible_runtime.')
44-
log.info(`Found incompatible runtime nodejs ${version}, Supported runtimes: nodejs ${engines.node}.`)
45-
if (forced) {
46-
log.info('DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.')
44+
// If we're running via single-step install, and the runtime doesn't match
45+
// the engines field in package.json, then we should not initialize the tracer.
46+
if (!clobberBailout) {
47+
var engines = require('./package.json').engines
48+
var version = process.versions.node
49+
if (!semver.satisfies(version, engines.node)) {
50+
initBailout = true
51+
telemetry([
52+
{ name: 'abort', tags: ['reason:incompatible_runtime'] },
53+
{ name: 'abort.runtime', tags: [] }
54+
])
55+
log.info('Aborting application instrumentation due to incompatible_runtime.')
56+
log.info('Found incompatible runtime nodejs ' + version + ', Supported runtimes: nodejs ' + engines.node + '.')
57+
if (forced) {
58+
log.info('DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.')
59+
}
4760
}
4861
}
4962
}
50-
}
5163

52-
if (!clobberBailout && (!initBailout || forced)) {
53-
const tracer = require('.')
54-
tracer.init()
55-
module.exports = tracer
56-
telemetry('complete', [`injection_forced:${forced && initBailout ? 'true' : 'false'}`])
57-
log.info('Application instrumentation bootstrapping complete')
64+
if (!clobberBailout && (!initBailout || forced)) {
65+
var tracer = require('.')
66+
tracer.init()
67+
module.exports = tracer
68+
telemetry('complete', ['injection_forced:' + (forced && initBailout ? 'true' : 'false')])
69+
log.info('Application instrumentation bootstrapping complete')
70+
}
5871
}

version.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
'use strict'
22

3-
const ddMatches = require('./package.json').version.match(/^(\d+)\.(\d+)\.(\d+)/)
4-
const nodeMatches = process.versions.node.match(/^(\d+)\.(\d+)\.(\d+)/)
3+
/* eslint-disable no-var */
4+
5+
var ddMatches = require('./package.json').version.match(/^(\d+)\.(\d+)\.(\d+)/)
6+
var nodeMatches = process.versions.node.match(/^(\d+)\.(\d+)\.(\d+)/)
57

68
module.exports = {
79
DD_MAJOR: parseInt(ddMatches[1]),

0 commit comments

Comments
 (0)