screwdriver-queue-service 2.0.46 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +1 -1
- package/Dockerfile.local +1 -1
- package/bin/server +1 -1
- package/config/custom-environment-variables.yaml +2 -0
- package/config/default.yaml +2 -0
- package/config/rabbitmq.js +2 -19
- package/lib/queue.js +1 -0
- package/package.json +28 -25
- package/plugins/auth/index.js +3 -4
- package/plugins/helper.js +20 -1
- package/plugins/queue/scheduler.js +74 -33
package/Dockerfile
CHANGED
package/Dockerfile.local
CHANGED
package/bin/server
CHANGED
|
@@ -237,6 +237,8 @@ queue:
|
|
|
237
237
|
tls: REDIS_TLS_ENABLED
|
|
238
238
|
slotsRefreshTimeout: REDIS_CLUSTER_SLOTS_REFRESH_TIMEOUT
|
|
239
239
|
prefix: REDIS_QUEUE_PREFIX
|
|
240
|
+
# whether or not to retrieve from redis that the data needed to start periodic builds
|
|
241
|
+
periodicBuildTableEnabled: PERIODIC_BUILD_TABLE_ENABLED
|
|
240
242
|
|
|
241
243
|
plugins:
|
|
242
244
|
blockedBy:
|
package/config/default.yaml
CHANGED
package/config/rabbitmq.js
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const config = require('config');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* convert value to Boolean
|
|
7
|
-
* @method convertToBool
|
|
8
|
-
* @param {(Boolean|String)} value
|
|
9
|
-
* @return {Boolean}
|
|
10
|
-
*/
|
|
11
|
-
function convertToBool(value) {
|
|
12
|
-
if (typeof value === 'boolean') {
|
|
13
|
-
return value;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// trueList refers to https://yaml.org/type/bool.html
|
|
17
|
-
const trueList = ['on', 'true', 'yes', 'y'];
|
|
18
|
-
const lowerValue = String(value).toLowerCase();
|
|
19
|
-
|
|
20
|
-
return trueList.includes(lowerValue);
|
|
21
|
-
}
|
|
4
|
+
const helper = require('../plugins/helper');
|
|
22
5
|
|
|
23
6
|
const rabbitmqConfig = config.get('scheduler').rabbitmq;
|
|
24
7
|
const { protocol, username, password, host, port, exchange, vhost, connectOptions } = rabbitmqConfig;
|
|
25
8
|
const amqpURI = `${protocol}://${username}:${password}@${host}:${port}${vhost}`;
|
|
26
|
-
const schedulerMode = convertToBool(config.get('scheduler').enabled);
|
|
9
|
+
const schedulerMode = helper.convertToBool(config.get('scheduler').enabled);
|
|
27
10
|
|
|
28
11
|
/**
|
|
29
12
|
* get configurations for rabbitmq
|
package/lib/queue.js
CHANGED
|
@@ -30,6 +30,7 @@ module.exports = class ExecutorQueue {
|
|
|
30
30
|
this.periodicBuildQueue = `${this.prefix}periodicBuilds`;
|
|
31
31
|
this.frozenBuildQueue = `${this.prefix}frozenBuilds`;
|
|
32
32
|
this.buildConfigTable = `${this.prefix}buildConfigs`;
|
|
33
|
+
this.periodicBuildTable = `${this.prefix}periodicBuildConfigs`;
|
|
33
34
|
this.frozenBuildTable = `${this.prefix}frozenBuildConfigs`;
|
|
34
35
|
this.tokenGen = null;
|
|
35
36
|
this.userTokenGen = null;
|
package/package.json
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "screwdriver-queue-service",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Screwdriver Queue Service API",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"directories": {
|
|
7
7
|
"lib": "lib"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@hapi/boom": "^
|
|
10
|
+
"@hapi/boom": "^10.0.0",
|
|
11
11
|
"@hapi/good": "^9.0.1",
|
|
12
12
|
"@hapi/good-console": "^9.0.1",
|
|
13
13
|
"@hapi/good-squeeze": "^6.0.0",
|
|
14
|
-
"@hapi/hapi": "^
|
|
15
|
-
"@hapi/hoek": "^
|
|
16
|
-
"amqp-connection-manager": "^
|
|
17
|
-
"amqplib": "^0.
|
|
14
|
+
"@hapi/hapi": "^21.1.0",
|
|
15
|
+
"@hapi/hoek": "^10.0.1",
|
|
16
|
+
"amqp-connection-manager": "^4.1.9",
|
|
17
|
+
"amqplib": "^0.10.3",
|
|
18
18
|
"blipp": "^4.0.2",
|
|
19
|
-
"circuit-fuses": "^
|
|
20
|
-
"config": "^
|
|
19
|
+
"circuit-fuses": "^5.0.0",
|
|
20
|
+
"config": "^3.3.6",
|
|
21
21
|
"cron-parser": "^4.2.1",
|
|
22
22
|
"hapi-auth-jwt2": "^10.2.0",
|
|
23
23
|
"ioredis": "^5.2.3",
|
|
24
|
-
"joi": "^17.
|
|
25
|
-
"js-yaml": "^
|
|
24
|
+
"joi": "^17.7.0",
|
|
25
|
+
"js-yaml": "^4.1.0",
|
|
26
26
|
"jsonwebtoken": "^8.5.1",
|
|
27
27
|
"node-resque": "^9.2.0",
|
|
28
28
|
"npm-auto-version": "^1.0.0",
|
|
29
29
|
"redlock": "^4.2.0",
|
|
30
|
-
"screwdriver-aws-producer-service": "^
|
|
31
|
-
"screwdriver-data-schema": "^
|
|
32
|
-
"screwdriver-executor-docker": "^
|
|
33
|
-
"screwdriver-executor-jenkins": "^
|
|
34
|
-
"screwdriver-executor-k8s": "^
|
|
30
|
+
"screwdriver-aws-producer-service": "^2.0.0",
|
|
31
|
+
"screwdriver-data-schema": "^22.0.1",
|
|
32
|
+
"screwdriver-executor-docker": "^6.0.0",
|
|
33
|
+
"screwdriver-executor-jenkins": "^6.0.0",
|
|
34
|
+
"screwdriver-executor-k8s": "^15.0.0",
|
|
35
35
|
"screwdriver-executor-k8s-vm": "^4.3.2",
|
|
36
|
-
"screwdriver-executor-router": "^
|
|
37
|
-
"screwdriver-logger": "^
|
|
38
|
-
"screwdriver-request": "^
|
|
36
|
+
"screwdriver-executor-router": "^3.0.0",
|
|
37
|
+
"screwdriver-logger": "^2.0.0",
|
|
38
|
+
"screwdriver-request": "^2.0.1",
|
|
39
39
|
"string-hash": "^1.1.3",
|
|
40
|
-
"uuid": "^
|
|
40
|
+
"uuid": "^9.0.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"chai": "^4.3.
|
|
43
|
+
"chai": "^4.3.7",
|
|
44
44
|
"chai-jwt": "^2.0.0",
|
|
45
45
|
"coveralls": "^3.0.9",
|
|
46
46
|
"cucumber": "^6.0.5",
|
|
47
|
-
"eslint": "^
|
|
48
|
-
"eslint-config-screwdriver": "^
|
|
49
|
-
"mocha": "^
|
|
47
|
+
"eslint": "^8.28.0",
|
|
48
|
+
"eslint-config-screwdriver": "^7.0.0",
|
|
49
|
+
"mocha": "^10.1.0",
|
|
50
50
|
"mocha-multi-reporters": "^1.5.1",
|
|
51
51
|
"mocha-sonarqube-reporter": "^1.0.2",
|
|
52
52
|
"mockery": "^2.1.0",
|
|
53
53
|
"nyc": "^15.1.0",
|
|
54
|
-
"sinon": "^
|
|
54
|
+
"sinon": "^15.0.0",
|
|
55
55
|
"snyk": "^1.814.0",
|
|
56
|
-
"util": "^0.12.
|
|
56
|
+
"util": "^0.12.5"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"start": "node ./bin/server",
|
|
@@ -81,6 +81,9 @@
|
|
|
81
81
|
"Pritam Paul <pritamstyz4ever@gmail.com>",
|
|
82
82
|
"Tiffany Kyi <tiffanykyi@gmail.com>"
|
|
83
83
|
],
|
|
84
|
+
"engines": {
|
|
85
|
+
"node": ">=18.0.0"
|
|
86
|
+
},
|
|
84
87
|
"bugs": {
|
|
85
88
|
"url": "https://github.com/screwdriver-cd/screwdriver/issues"
|
|
86
89
|
},
|
package/plugins/auth/index.js
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const joi = require('joi');
|
|
4
4
|
const jwt = require('jsonwebtoken');
|
|
5
|
-
const
|
|
6
|
-
|
|
5
|
+
const { v4: uuidv4 } = require('uuid');
|
|
7
6
|
const DEFAULT_TIMEOUT = 60; // 1h in minutes
|
|
8
7
|
const ALGORITHM = 'RS256';
|
|
9
8
|
|
|
10
|
-
const validate = async function() {
|
|
9
|
+
const validate = async function () {
|
|
11
10
|
// The _decoded token signature is validated by jwt.veriry so we can return true
|
|
12
11
|
return { isValid: true };
|
|
13
12
|
};
|
|
@@ -81,7 +80,7 @@ const authPlugin = {
|
|
|
81
80
|
jwt.sign(profile, pluginOptions.jwtPrivateKey, {
|
|
82
81
|
algorithm: ALGORITHM,
|
|
83
82
|
expiresIn: buildTimeout * 60, // must be in second
|
|
84
|
-
jwtid:
|
|
83
|
+
jwtid: uuidv4()
|
|
85
84
|
})
|
|
86
85
|
);
|
|
87
86
|
}
|
package/plugins/helper.js
CHANGED
|
@@ -364,6 +364,24 @@ async function processHooks(apiUri, token, webhookConfig) {
|
|
|
364
364
|
});
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
+
/**
|
|
368
|
+
* convert value to Boolean
|
|
369
|
+
* @method convertToBool
|
|
370
|
+
* @param {(Boolean|String)} value
|
|
371
|
+
* @return {Boolean}
|
|
372
|
+
*/
|
|
373
|
+
function convertToBool(value) {
|
|
374
|
+
if (typeof value === 'boolean') {
|
|
375
|
+
return value;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// trueList refers to https://yaml.org/type/bool.html
|
|
379
|
+
const trueList = ['on', 'true', 'yes', 'y'];
|
|
380
|
+
const lowerValue = String(value).toLowerCase();
|
|
381
|
+
|
|
382
|
+
return trueList.includes(lowerValue);
|
|
383
|
+
}
|
|
384
|
+
|
|
367
385
|
module.exports = {
|
|
368
386
|
requestRetryStrategy,
|
|
369
387
|
requestRetryStrategyPostEvent,
|
|
@@ -376,5 +394,6 @@ module.exports = {
|
|
|
376
394
|
getPipelineConfig,
|
|
377
395
|
updateBuild,
|
|
378
396
|
notifyJob,
|
|
379
|
-
processHooks
|
|
397
|
+
processHooks,
|
|
398
|
+
convertToBool
|
|
380
399
|
};
|
|
@@ -11,6 +11,7 @@ const helper = require('../helper');
|
|
|
11
11
|
const { timeOutOfWindows } = require('./utils/freezeWindows');
|
|
12
12
|
const { queueNamespace } = require('../../config/redis');
|
|
13
13
|
const ecosystem = Config.get('ecosystem');
|
|
14
|
+
const periodicBuildTableEnabled = helper.convertToBool(Config.get('queue').periodicBuildTableEnabled);
|
|
14
15
|
const DEFAULT_BUILD_TIMEOUT = 90;
|
|
15
16
|
const RETRY_LIMIT = 3;
|
|
16
17
|
const RETRY_DELAY = 5;
|
|
@@ -111,9 +112,15 @@ async function postBuildEvent(executor, eventConfig) {
|
|
|
111
112
|
async function stopPeriodic(executor, config) {
|
|
112
113
|
await executor.connect();
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
await executor.queueBreaker.runCommand('delDelayed', executor.periodicBuildQueue, 'startDelayed', [
|
|
115
116
|
{ jobId: config.jobId }
|
|
116
117
|
]);
|
|
118
|
+
|
|
119
|
+
if (periodicBuildTableEnabled) {
|
|
120
|
+
return executor.redisBreaker.runCommand('hdel', executor.periodicBuildTable, config.jobId);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return Promise.resolve();
|
|
117
124
|
}
|
|
118
125
|
|
|
119
126
|
/**
|
|
@@ -193,6 +200,25 @@ async function startPeriodic(executor, config) {
|
|
|
193
200
|
|
|
194
201
|
const next = cron.next(cron.transform(buildCron, job.id));
|
|
195
202
|
|
|
203
|
+
if (periodicBuildTableEnabled) {
|
|
204
|
+
try {
|
|
205
|
+
// Store the config in redis
|
|
206
|
+
await executor.redisBreaker.runCommand(
|
|
207
|
+
'hset',
|
|
208
|
+
executor.periodicBuildTable,
|
|
209
|
+
job.id,
|
|
210
|
+
JSON.stringify(
|
|
211
|
+
Object.assign(config, {
|
|
212
|
+
isUpdate: false,
|
|
213
|
+
triggerBuild: false
|
|
214
|
+
})
|
|
215
|
+
)
|
|
216
|
+
);
|
|
217
|
+
} catch (err) {
|
|
218
|
+
logger.error(`failed to store the config in Redis for job ${job.id}: ${err}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
196
222
|
// Note: arguments to enqueueAt are [timestamp, queue name, job name, array of args]
|
|
197
223
|
let shouldRetry = false;
|
|
198
224
|
|
|
@@ -454,42 +480,57 @@ async function init(executor) {
|
|
|
454
480
|
startDelayed: {
|
|
455
481
|
perform: async config => {
|
|
456
482
|
try {
|
|
457
|
-
const apiUri = ecosystem.api;
|
|
458
483
|
const { jobId } = config;
|
|
459
484
|
|
|
460
485
|
logger.info(`Started processing periodic job ${jobId}`);
|
|
461
486
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
487
|
+
let fullConfig;
|
|
488
|
+
|
|
489
|
+
if (periodicBuildTableEnabled) {
|
|
490
|
+
const periodicBuildConfig = await executor.redisBreaker.runCommand(
|
|
491
|
+
'hget',
|
|
492
|
+
executor.periodicBuildTable,
|
|
493
|
+
jobId
|
|
494
|
+
);
|
|
495
|
+
|
|
496
|
+
fullConfig = Object.assign(JSON.parse(periodicBuildConfig), {
|
|
497
|
+
triggerBuild: true
|
|
498
|
+
});
|
|
499
|
+
} else {
|
|
500
|
+
const apiUri = ecosystem.api;
|
|
501
|
+
|
|
502
|
+
const buildToken = executor.tokenGen({
|
|
503
|
+
jobId,
|
|
504
|
+
service: 'queue',
|
|
505
|
+
scope: ['build']
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
const job = await helper.getJobConfig({
|
|
509
|
+
jobId,
|
|
510
|
+
token: buildToken,
|
|
511
|
+
apiUri
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
const pipelineToken = executor.tokenGen({
|
|
515
|
+
pipelineId: job.pipelineId,
|
|
516
|
+
service: 'queue',
|
|
517
|
+
scope: ['pipeline']
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
const pipeline = await helper.getPipelineConfig({
|
|
521
|
+
pipelineId: job.pipelineId,
|
|
522
|
+
token: pipelineToken,
|
|
523
|
+
apiUri
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
fullConfig = {
|
|
527
|
+
pipeline,
|
|
528
|
+
job,
|
|
529
|
+
apiUri,
|
|
530
|
+
isUpdate: false,
|
|
531
|
+
triggerBuild: true
|
|
532
|
+
};
|
|
533
|
+
}
|
|
493
534
|
|
|
494
535
|
return await startPeriodic(executor, fullConfig);
|
|
495
536
|
} catch (err) {
|