ci-queue 0.99.0 → 0.100.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +14 -0
- data/ci-queue.gemspec +4 -3
- data/lib/ci/queue/configuration.rb +4 -1
- data/lib/ci/queue/redis/base.rb +24 -7
- data/lib/ci/queue/redis/monitor.rb +17 -1
- data/lib/ci/queue/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 64510328261d26c0b3299aa0e1bb4bbbb2fdd4f784293a304cec028527d25e8b
|
|
4
|
+
data.tar.gz: 8cf5e99fcf74935b71a2ee6814cfc7565b03b1b314af8380f999f4228400417c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c044a9cafe05602f22debf2ea91b5cc63c42dabc67f8689b88430c7c34ece68da7bf7ad03b62036648073c8225e3588382bce588f486359b339a65aa62e71951
|
|
7
|
+
data.tar.gz: 5d9f475df1260d6cc6cd04d1f1ceec0ca28e7b12e9d5d0b0931ac7b18a2e864a5a2386f102f878a8392722dbb535e260b8661e5ccc5722097ee8d8e866d977dc
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -260,3 +260,17 @@ After merging changes to `main`, follow these steps to release and propagate the
|
|
|
260
260
|
`ci-queue` expects the Redis server to have an [eviction policy](https://redis.io/docs/manual/eviction/#eviction-policies) of `allkeys-lru`.
|
|
261
261
|
|
|
262
262
|
You can also use `--redis-ttl` to set a custom expiration time for all CI Queue keys, this defaults to 8 hours (28,800 seconds)
|
|
263
|
+
|
|
264
|
+
## Redis over TLS
|
|
265
|
+
|
|
266
|
+
Use a `rediss://` queue URL to connect to Redis over TLS. The server certificate and hostname are verified using the system's trusted CAs.
|
|
267
|
+
|
|
268
|
+
> **Upgrading from 0.99.0 or earlier:** those versions did not verify certificates for `rediss://` URLs. If your Redis presents a self-signed or otherwise untrusted certificate, connections now fail with `certificate verify failed`. Workers treat this like an unreachable Redis: they report `Ran 0 tests` and exit successfully, and the error only surfaces when `report` fails with `Redis::CannotConnectError`. Trust the issuing CA or opt out as described below.
|
|
269
|
+
|
|
270
|
+
If your Redis server presents a certificate signed by a private CA, point OpenSSL at that CA (for example with `SSL_CERT_FILE=/path/to/ca.pem`).
|
|
271
|
+
|
|
272
|
+
If your hosted Redis only offers a self-signed certificate that can't be verified, you can opt out of verification with `CI_QUEUE_REDIS_SSL_VERIFY=0` (or `CI::Queue::Configuration#redis_ssl_verify = false`). The connection stays encrypted, but the server isn't authenticated, so anyone who can intercept traffic between your CI workers and Redis can impersonate the server and read the credentials in the queue URL. Only use this when you accept that risk.
|
|
273
|
+
|
|
274
|
+
| Environment variable | Description |
|
|
275
|
+
|---|---|
|
|
276
|
+
| `CI_QUEUE_REDIS_SSL_VERIFY=0` | Disable TLS certificate verification for `rediss://` connections. Defaults to enabled. No CLI equivalent. |
|
data/ci-queue.gemspec
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
lib = File.expand_path('../lib', __FILE__)
|
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
require 'ci/queue/version'
|
|
6
|
-
require 'pathname'
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
# Release Lua scripts are gitignored copies made by `rake scripts:copy`, so
|
|
8
|
+
# `git ls-files` misses them. Glob without touching CI::Queue constants:
|
|
9
|
+
# Dependabot evaluates this file with the `require` above rescued away.
|
|
10
|
+
lua_scripts = Dir.glob('lib/ci/queue/redis/*.lua', base: __dir__)
|
|
10
11
|
|
|
11
12
|
Gem::Specification.new do |spec|
|
|
12
13
|
spec.name = 'ci-queue'
|
|
@@ -11,6 +11,7 @@ module CI
|
|
|
11
11
|
attr_writer :lazy_load_streaming_timeout
|
|
12
12
|
attr_accessor :lazy_load_test_helpers
|
|
13
13
|
attr_accessor :skip_stale_tests
|
|
14
|
+
attr_accessor :redis_ssl_verify
|
|
14
15
|
attr_reader :circuit_breakers
|
|
15
16
|
attr_writer :seed, :build_id
|
|
16
17
|
attr_writer :queue_init_timeout, :report_timeout, :inactive_workers_timeout
|
|
@@ -34,6 +35,7 @@ module CI
|
|
|
34
35
|
lazy_load_streaming_timeout: (env['CI_QUEUE_LAZY_LOAD_STREAM_TIMEOUT'] || env['CI_QUEUE_STREAM_TIMEOUT'])&.to_i,
|
|
35
36
|
lazy_load_test_helpers: env['CI_QUEUE_LAZY_LOAD_TEST_HELPERS'] || env['CI_QUEUE_TEST_HELPERS'],
|
|
36
37
|
skip_stale_tests: %w(1 true).include?(env['CI_QUEUE_SKIP_STALE_TESTS']&.strip&.downcase),
|
|
38
|
+
redis_ssl_verify: !%w(0 false).include?(env['CI_QUEUE_REDIS_SSL_VERIFY']&.strip&.downcase),
|
|
37
39
|
)
|
|
38
40
|
end
|
|
39
41
|
|
|
@@ -60,7 +62,7 @@ module CI
|
|
|
60
62
|
queue_init_timeout: nil, redis_ttl: 8 * 60 * 60, report_timeout: nil, inactive_workers_timeout: nil,
|
|
61
63
|
export_flaky_tests_file: nil, warnings_file: nil, debug_log: nil, max_missed_heartbeat_seconds: nil, heartbeat_max_test_duration: nil,
|
|
62
64
|
lazy_load: false, lazy_load_stream_batch_size: nil, lazy_load_streaming_timeout: nil, lazy_load_test_helpers: nil,
|
|
63
|
-
skip_stale_tests: false)
|
|
65
|
+
skip_stale_tests: false, redis_ssl_verify: true)
|
|
64
66
|
@build_id = build_id
|
|
65
67
|
@circuit_breakers = [CircuitBreaker::Disabled]
|
|
66
68
|
@failure_file = failure_file
|
|
@@ -94,6 +96,7 @@ module CI
|
|
|
94
96
|
@lazy_load_streaming_timeout = lazy_load_streaming_timeout
|
|
95
97
|
@lazy_load_test_helpers = lazy_load_test_helpers
|
|
96
98
|
@skip_stale_tests = skip_stale_tests
|
|
99
|
+
@redis_ssl_verify = redis_ssl_verify
|
|
97
100
|
end
|
|
98
101
|
|
|
99
102
|
def lazy_load_test_helper_paths
|
data/lib/ci/queue/redis/base.rb
CHANGED
|
@@ -41,19 +41,33 @@ module CI
|
|
|
41
41
|
# it makes sense to retry for a while before giving up.
|
|
42
42
|
reconnect_attempts: reconnect_attempts,
|
|
43
43
|
middlewares: custom_middlewares,
|
|
44
|
-
|
|
45
|
-
# (because they do not own the domain they're running on such as compute-1.amazonaws.com)
|
|
46
|
-
# therefore a full SSL connection verification will fail.
|
|
47
|
-
# ci-queue should not contain any sensitive data, so we can just disable the verification.
|
|
48
|
-
ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE },
|
|
44
|
+
ssl_params: self.class.redis_ssl_params(ssl_verify: redis_ssl_verify?),
|
|
49
45
|
custom: custom_config,
|
|
50
46
|
timeout: DEFAULT_TIMEOUT,
|
|
51
47
|
)
|
|
52
48
|
else
|
|
53
|
-
@redis = ::Redis.new(
|
|
49
|
+
@redis = ::Redis.new(
|
|
50
|
+
url: redis_url,
|
|
51
|
+
timeout: DEFAULT_TIMEOUT,
|
|
52
|
+
ssl_params: self.class.redis_ssl_params(ssl_verify: redis_ssl_verify?),
|
|
53
|
+
)
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
# TLS (`rediss://`) connections verify the server certificate and hostname
|
|
58
|
+
# by default. Some hosted Redis providers present self-signed certificates;
|
|
59
|
+
# those deployments can either trust the issuing CA (e.g. via `SSL_CERT_FILE`)
|
|
60
|
+
# or explicitly opt out of verification with `CI_QUEUE_REDIS_SSL_VERIFY=0`.
|
|
61
|
+
def self.redis_ssl_params(ssl_verify:)
|
|
62
|
+
ssl_verify ? {} : { verify_mode: OpenSSL::SSL::VERIFY_NONE }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def redis_ssl_verify?
|
|
66
|
+
return true unless @config.respond_to?(:redis_ssl_verify)
|
|
67
|
+
|
|
68
|
+
@config.redis_ssl_verify != false
|
|
69
|
+
end
|
|
70
|
+
|
|
57
71
|
def reconnect_attempts
|
|
58
72
|
return [] if ENV["CI_QUEUE_DISABLE_RECONNECT_ATTEMPTS"]
|
|
59
73
|
|
|
@@ -271,8 +285,9 @@ module CI
|
|
|
271
285
|
# on every heartbeat, which fires once per running test per worker.
|
|
272
286
|
TICK_COMMAND = 'tick!'.freeze
|
|
273
287
|
|
|
274
|
-
def initialize(redis_url, zset_key, owners_key, leases_key)
|
|
288
|
+
def initialize(redis_url, zset_key, owners_key, leases_key, ssl_verify: true)
|
|
275
289
|
@redis_url = redis_url
|
|
290
|
+
@ssl_verify = ssl_verify
|
|
276
291
|
@zset_key = zset_key
|
|
277
292
|
@owners_key = owners_key
|
|
278
293
|
@leases_key = leases_key
|
|
@@ -283,6 +298,7 @@ module CI
|
|
|
283
298
|
ready_pipe, child_write = IO.pipe
|
|
284
299
|
@pipe.binmode
|
|
285
300
|
@pid = Process.spawn(
|
|
301
|
+
{ 'CI_QUEUE_REDIS_SSL_VERIFY' => @ssl_verify ? '1' : '0' },
|
|
286
302
|
RbConfig.ruby,
|
|
287
303
|
::File.join(__dir__, "monitor.rb"),
|
|
288
304
|
@redis_url,
|
|
@@ -380,6 +396,7 @@ module CI
|
|
|
380
396
|
key('running'),
|
|
381
397
|
key('owners'),
|
|
382
398
|
key('leases'),
|
|
399
|
+
ssl_verify: redis_ssl_verify?,
|
|
383
400
|
)
|
|
384
401
|
end
|
|
385
402
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# frozen_string_literal: true
|
|
4
4
|
|
|
5
5
|
require 'logger'
|
|
6
|
+
require 'openssl'
|
|
6
7
|
require 'redis'
|
|
7
8
|
require 'json'
|
|
8
9
|
|
|
@@ -18,7 +19,11 @@ module CI
|
|
|
18
19
|
@owners_key = owners_key
|
|
19
20
|
@leases_key = leases_key
|
|
20
21
|
@logger = logger
|
|
21
|
-
@redis = ::Redis.new(
|
|
22
|
+
@redis = ::Redis.new(
|
|
23
|
+
url: redis_url,
|
|
24
|
+
reconnect_attempts: [0, 0, 0.1, 0.5, 1, 3, 5],
|
|
25
|
+
ssl_params: ssl_params,
|
|
26
|
+
)
|
|
22
27
|
@shutdown = false
|
|
23
28
|
@pipe = pipe
|
|
24
29
|
@self_pipe_reader, @self_pipe_writer = IO.pipe
|
|
@@ -30,6 +35,17 @@ module CI
|
|
|
30
35
|
end
|
|
31
36
|
end
|
|
32
37
|
|
|
38
|
+
# Mirrors CI::Queue::Redis::Base.redis_ssl_params. This script runs as a
|
|
39
|
+
# standalone subprocess that doesn't load ci-queue or its Configuration,
|
|
40
|
+
# so the parent passes the setting through the environment.
|
|
41
|
+
def ssl_params
|
|
42
|
+
if %w(0 false).include?(ENV['CI_QUEUE_REDIS_SSL_VERIFY']&.strip&.downcase)
|
|
43
|
+
{ verify_mode: OpenSSL::SSL::VERIFY_NONE }
|
|
44
|
+
else
|
|
45
|
+
{}
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
33
49
|
def soft_signal(sig)
|
|
34
50
|
@queue << sig
|
|
35
51
|
@self_pipe_writer << '.'
|
data/lib/ci/queue/version.rb
CHANGED