docker-engine-ruby 0.7.0 → 0.7.1
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/CHANGELOG.md +4 -0
- data/README.md +32 -1
- data/lib/docker_engine_ruby/client.rb +33 -1
- data/lib/docker_engine_ruby/internal/transport/base_client.rb +50 -7
- data/lib/docker_engine_ruby/internal/transport/pooled_net_requester.rb +80 -8
- data/lib/docker_engine_ruby/resources/containers.rb +6 -0
- data/lib/docker_engine_ruby/version.rb +1 -1
- data/rbi/docker_engine_ruby/client.rbi +25 -0
- data/rbi/docker_engine_ruby/internal/transport/base_client.rbi +8 -2
- data/rbi/docker_engine_ruby/internal/transport/pooled_net_requester.rbi +19 -4
- data/sig/docker_engine_ruby/client.rbs +9 -0
- data/sig/docker_engine_ruby/internal/transport/base_client.rbs +4 -1
- data/sig/docker_engine_ruby/internal/transport/pooled_net_requester.rbs +8 -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: fafdca8c2cef062dd3b4f6507c7e6e5104086c309b0b21ace45dd6933885df19
|
|
4
|
+
data.tar.gz: ab90e04471337080bfaa26bd67222c1337fa3b091c3790db49f100eda74e2ad7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 226c1ba64e8795206b77bae093b19cd03f9e75c861065b92bf3787ca05cff41e42b34ce4aea4c592d0264cc56006dd5321fc8a1a83b0595851ffad4bb6b55961
|
|
7
|
+
data.tar.gz: 4e47041c7d35b8c340db8f3ea9d3fcf953fa2247a74a05314268b8f913894943f2b67dd5631efa4e99433ac3aabc7c9c3108170006a9a3b7d7481533e7b601c2
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.1 (2026-02-20)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.7.0...v0.7.1](https://github.com/Hexlet/docker-ruby/compare/v0.7.0...v0.7.1)
|
|
6
|
+
|
|
3
7
|
## 0.7.0 (2026-02-20)
|
|
4
8
|
|
|
5
9
|
Full Changelog: [v0.6.0...v0.7.0](https://github.com/Hexlet/docker-ruby/compare/v0.6.0...v0.7.0)
|
data/README.md
CHANGED
|
@@ -17,7 +17,7 @@ To use this gem, install via Bundler by adding the following to your application
|
|
|
17
17
|
<!-- x-release-please-start-version -->
|
|
18
18
|
|
|
19
19
|
```ruby
|
|
20
|
-
gem "docker-engine-ruby", "~> 0.7.
|
|
20
|
+
gem "docker-engine-ruby", "~> 0.7.1"
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
<!-- x-release-please-end -->
|
|
@@ -37,6 +37,18 @@ create_response = docker.containers.create(name: "sample-container")
|
|
|
37
37
|
puts(create_response.Id)
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
### Using a Unix socket
|
|
41
|
+
|
|
42
|
+
You can connect to a local Docker daemon over a Unix socket by setting `base_url` to a `unix:///...` path:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
docker = DockerEngineRuby::Client.new(
|
|
46
|
+
base_url: "unix:///var/run/docker.sock"
|
|
47
|
+
)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
When `base_url` uses `unix:///`, TLS-related options are not used. TLS/mTLS configuration applies to HTTPS daemon endpoints (for example, `https://localhost:2376`).
|
|
51
|
+
|
|
40
52
|
### Handling errors
|
|
41
53
|
|
|
42
54
|
When the library is unable to connect to the API, or if the API returns a non-success status code (i.e., 4xx or 5xx response), a subclass of `DockerEngineRuby::Errors::APIError` will be thrown:
|
|
@@ -107,6 +119,25 @@ On timeout, `DockerEngineRuby::Errors::APITimeoutError` is raised.
|
|
|
107
119
|
|
|
108
120
|
Note that requests that time out are retried by default.
|
|
109
121
|
|
|
122
|
+
### TLS / mTLS
|
|
123
|
+
|
|
124
|
+
For Docker Engine over TLS (`https://...:2376`), you can provide CA, client certificate, and client key paths:
|
|
125
|
+
|
|
126
|
+
```ruby
|
|
127
|
+
docker = DockerEngineRuby::Client.new(
|
|
128
|
+
base_url: "https://localhost:2376",
|
|
129
|
+
tls_ca_cert_path: "/path/to/ca.pem",
|
|
130
|
+
tls_client_cert_path: "/path/to/cert.pem",
|
|
131
|
+
tls_client_key_path: "/path/to/key.pem"
|
|
132
|
+
)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
You can also configure these through environment variables:
|
|
136
|
+
|
|
137
|
+
- `DOCKER_TLS_CA_CERT_PATH`
|
|
138
|
+
- `DOCKER_TLS_CLIENT_CERT_PATH`
|
|
139
|
+
- `DOCKER_TLS_CLIENT_KEY_PATH`
|
|
140
|
+
|
|
110
141
|
## Advanced concepts
|
|
111
142
|
|
|
112
143
|
### BaseModel
|
|
@@ -20,6 +20,19 @@ module DockerEngineRuby
|
|
|
20
20
|
ENVIRONMENTS = {production: "http://localhost:2375", production_tls: "https://localhost:2376"}
|
|
21
21
|
# rubocop:enable Style/MutableConstant
|
|
22
22
|
|
|
23
|
+
# Path to the trusted CA certificate file (PEM) used to verify the Docker daemon
|
|
24
|
+
# certificate.
|
|
25
|
+
# @return [String, nil]
|
|
26
|
+
attr_reader :tls_ca_cert_path
|
|
27
|
+
|
|
28
|
+
# Path to the client TLS certificate file (PEM).
|
|
29
|
+
# @return [String, nil]
|
|
30
|
+
attr_reader :tls_client_cert_path
|
|
31
|
+
|
|
32
|
+
# Path to the client TLS private key file (PEM).
|
|
33
|
+
# @return [String, nil]
|
|
34
|
+
attr_reader :tls_client_key_path
|
|
35
|
+
|
|
23
36
|
# @return [DockerEngineRuby::Resources::Auth]
|
|
24
37
|
attr_reader :auth
|
|
25
38
|
|
|
@@ -67,6 +80,15 @@ module DockerEngineRuby
|
|
|
67
80
|
|
|
68
81
|
# Creates and returns a new client for interacting with the API.
|
|
69
82
|
#
|
|
83
|
+
# @param tls_ca_cert_path [String, nil] Path to the trusted CA certificate file (PEM) used to verify the Docker daemon
|
|
84
|
+
# certificate. Defaults to `ENV["DOCKER_TLS_CA_CERT_PATH"]`
|
|
85
|
+
#
|
|
86
|
+
# @param tls_client_cert_path [String, nil] Path to the client TLS certificate file (PEM). Defaults to
|
|
87
|
+
# `ENV["DOCKER_TLS_CLIENT_CERT_PATH"]`
|
|
88
|
+
#
|
|
89
|
+
# @param tls_client_key_path [String, nil] Path to the client TLS private key file (PEM). Defaults to
|
|
90
|
+
# `ENV["DOCKER_TLS_CLIENT_KEY_PATH"]`
|
|
91
|
+
#
|
|
70
92
|
# @param environment [:production, :production_tls, nil] Specifies the environment to use for the API.
|
|
71
93
|
#
|
|
72
94
|
# Each environment maps to a different base URL:
|
|
@@ -85,6 +107,9 @@ module DockerEngineRuby
|
|
|
85
107
|
#
|
|
86
108
|
# @param max_retry_delay [Float]
|
|
87
109
|
def initialize(
|
|
110
|
+
tls_ca_cert_path: ENV["DOCKER_TLS_CA_CERT_PATH"],
|
|
111
|
+
tls_client_cert_path: ENV["DOCKER_TLS_CLIENT_CERT_PATH"],
|
|
112
|
+
tls_client_key_path: ENV["DOCKER_TLS_CLIENT_KEY_PATH"],
|
|
88
113
|
environment: nil,
|
|
89
114
|
base_url: ENV["DOCKER_BASE_URL"],
|
|
90
115
|
max_retries: self.class::DEFAULT_MAX_RETRIES,
|
|
@@ -97,12 +122,19 @@ module DockerEngineRuby
|
|
|
97
122
|
raise ArgumentError.new(message)
|
|
98
123
|
end
|
|
99
124
|
|
|
125
|
+
@tls_ca_cert_path = tls_ca_cert_path&.to_s
|
|
126
|
+
@tls_client_cert_path = tls_client_cert_path&.to_s
|
|
127
|
+
@tls_client_key_path = tls_client_key_path&.to_s
|
|
128
|
+
|
|
100
129
|
super(
|
|
101
130
|
base_url: base_url,
|
|
102
131
|
timeout: timeout,
|
|
103
132
|
max_retries: max_retries,
|
|
104
133
|
initial_retry_delay: initial_retry_delay,
|
|
105
|
-
max_retry_delay: max_retry_delay
|
|
134
|
+
max_retry_delay: max_retry_delay,
|
|
135
|
+
tls_ca_cert_path: @tls_ca_cert_path,
|
|
136
|
+
tls_client_cert_path: @tls_client_cert_path,
|
|
137
|
+
tls_client_key_path: @tls_client_key_path
|
|
106
138
|
)
|
|
107
139
|
|
|
108
140
|
@auth = DockerEngineRuby::Resources::Auth.new(client: self)
|
|
@@ -11,6 +11,7 @@ module DockerEngineRuby
|
|
|
11
11
|
|
|
12
12
|
# from whatwg fetch spec
|
|
13
13
|
MAX_REDIRECTS = 20
|
|
14
|
+
REDIRECT_STATUSES = [301, 302, 303, 307, 308].freeze
|
|
14
15
|
|
|
15
16
|
# rubocop:disable Style/MutableConstant
|
|
16
17
|
PLATFORM_HEADERS =
|
|
@@ -67,6 +68,15 @@ module DockerEngineRuby
|
|
|
67
68
|
end
|
|
68
69
|
end
|
|
69
70
|
|
|
71
|
+
# @api private
|
|
72
|
+
#
|
|
73
|
+
# @param status [Integer]
|
|
74
|
+
#
|
|
75
|
+
# @return [Boolean]
|
|
76
|
+
def redirect_status?(status)
|
|
77
|
+
REDIRECT_STATUSES.include?(status)
|
|
78
|
+
end
|
|
79
|
+
|
|
70
80
|
# @api private
|
|
71
81
|
#
|
|
72
82
|
# @param request [Hash{Symbol=>Object}] .
|
|
@@ -187,6 +197,9 @@ module DockerEngineRuby
|
|
|
187
197
|
# @param max_retry_delay [Float]
|
|
188
198
|
# @param headers [Hash{String=>String, Integer, Array<String, Integer, nil>, nil}]
|
|
189
199
|
# @param idempotency_header [String, nil]
|
|
200
|
+
# @param tls_ca_cert_path [String, nil]
|
|
201
|
+
# @param tls_client_cert_path [String, nil]
|
|
202
|
+
# @param tls_client_key_path [String, nil]
|
|
190
203
|
def initialize(
|
|
191
204
|
base_url:,
|
|
192
205
|
timeout: 0.0,
|
|
@@ -194,9 +207,22 @@ module DockerEngineRuby
|
|
|
194
207
|
initial_retry_delay: 0.0,
|
|
195
208
|
max_retry_delay: 0.0,
|
|
196
209
|
headers: {},
|
|
197
|
-
idempotency_header: nil
|
|
210
|
+
idempotency_header: nil,
|
|
211
|
+
tls_ca_cert_path: nil,
|
|
212
|
+
tls_client_cert_path: nil,
|
|
213
|
+
tls_client_key_path: nil
|
|
198
214
|
)
|
|
199
|
-
|
|
215
|
+
parsed_base_url = DockerEngineRuby::Internal::Util.parse_uri(base_url)
|
|
216
|
+
@unix_socket_path = parsed_base_url[:scheme] == "unix" ? parsed_base_url[:path] : nil
|
|
217
|
+
if parsed_base_url[:scheme] == "unix" && @unix_socket_path.to_s.empty?
|
|
218
|
+
raise ArgumentError.new("base_url unix:// must include an absolute socket path")
|
|
219
|
+
end
|
|
220
|
+
@requester = DockerEngineRuby::Internal::Transport::PooledNetRequester.new(
|
|
221
|
+
unix_socket_path: @unix_socket_path,
|
|
222
|
+
tls_ca_cert_path: tls_ca_cert_path,
|
|
223
|
+
tls_client_cert_path: tls_client_cert_path,
|
|
224
|
+
tls_client_key_path: tls_client_key_path
|
|
225
|
+
)
|
|
200
226
|
@headers = DockerEngineRuby::Internal::Util.normalized_headers(
|
|
201
227
|
self.class::PLATFORM_HEADERS,
|
|
202
228
|
{
|
|
@@ -206,8 +232,13 @@ module DockerEngineRuby
|
|
|
206
232
|
},
|
|
207
233
|
headers
|
|
208
234
|
)
|
|
209
|
-
@base_url_components =
|
|
210
|
-
|
|
235
|
+
@base_url_components =
|
|
236
|
+
if @unix_socket_path
|
|
237
|
+
DockerEngineRuby::Internal::Util.parse_uri("http://localhost")
|
|
238
|
+
else
|
|
239
|
+
parsed_base_url
|
|
240
|
+
end
|
|
241
|
+
@base_url = base_url
|
|
211
242
|
@idempotency_header = idempotency_header&.to_s&.downcase
|
|
212
243
|
@timeout = timeout
|
|
213
244
|
@max_retries = max_retries
|
|
@@ -308,6 +339,7 @@ module DockerEngineRuby
|
|
|
308
339
|
{
|
|
309
340
|
method: method,
|
|
310
341
|
url: url,
|
|
342
|
+
unix_socket_path: @unix_socket_path,
|
|
311
343
|
headers: headers,
|
|
312
344
|
body: encoded,
|
|
313
345
|
max_retries: opts.fetch(:max_retries, @max_retries),
|
|
@@ -383,7 +415,8 @@ module DockerEngineRuby
|
|
|
383
415
|
case status
|
|
384
416
|
in ..299
|
|
385
417
|
[status, response, stream]
|
|
386
|
-
in
|
|
418
|
+
in Integer => status if self.class.redirect_status?(status) &&
|
|
419
|
+
redirect_count >= self.class::MAX_REDIRECTS
|
|
387
420
|
self.class.reap_connection!(status, stream: stream)
|
|
388
421
|
|
|
389
422
|
message = "Failed to complete the request within #{self.class::MAX_REDIRECTS} redirects."
|
|
@@ -392,7 +425,7 @@ module DockerEngineRuby
|
|
|
392
425
|
response: response,
|
|
393
426
|
message: message
|
|
394
427
|
)
|
|
395
|
-
in
|
|
428
|
+
in Integer => status if self.class.redirect_status?(status)
|
|
396
429
|
self.class.reap_connection!(status, stream: stream)
|
|
397
430
|
|
|
398
431
|
request = self.class.follow_redirect(request, status: status, response_headers: headers)
|
|
@@ -404,7 +437,7 @@ module DockerEngineRuby
|
|
|
404
437
|
)
|
|
405
438
|
in DockerEngineRuby::Errors::APIConnectionError if retry_count >= max_retries
|
|
406
439
|
raise status
|
|
407
|
-
in (
|
|
440
|
+
in (300..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: headers)
|
|
408
441
|
decoded = Kernel.then do
|
|
409
442
|
DockerEngineRuby::Internal::Util.decode_content(headers, stream: stream, suppress_error: true)
|
|
410
443
|
ensure
|
|
@@ -492,6 +525,15 @@ module DockerEngineRuby
|
|
|
492
525
|
)
|
|
493
526
|
|
|
494
527
|
headers = DockerEngineRuby::Internal::Util.normalized_headers(response.each_header.to_h)
|
|
528
|
+
|
|
529
|
+
# Some Docker endpoints return non-JSON streaming payloads while generated
|
|
530
|
+
# resource methods intentionally model their response as `nil`.
|
|
531
|
+
# In that case, drain the response body and return early.
|
|
532
|
+
if model == NilClass && !req.key?(:stream) && !req.key?(:page)
|
|
533
|
+
stream&.each { next }
|
|
534
|
+
return nil
|
|
535
|
+
end
|
|
536
|
+
|
|
495
537
|
decoded = DockerEngineRuby::Internal::Util.decode_content(headers, stream: stream)
|
|
496
538
|
case req
|
|
497
539
|
in {stream: Class => st}
|
|
@@ -560,6 +602,7 @@ module DockerEngineRuby
|
|
|
560
602
|
{
|
|
561
603
|
method: Symbol,
|
|
562
604
|
url: URI::Generic,
|
|
605
|
+
unix_socket_path: T.nilable(String),
|
|
563
606
|
headers: T::Hash[String, String],
|
|
564
607
|
body: T.anything,
|
|
565
608
|
max_retries: Integer,
|
|
@@ -7,6 +7,23 @@ module DockerEngineRuby
|
|
|
7
7
|
class PooledNetRequester
|
|
8
8
|
extend DockerEngineRuby::Internal::Util::SorbetRuntimeSupport
|
|
9
9
|
|
|
10
|
+
class UnixSocketHTTP < Net::HTTP
|
|
11
|
+
# Net::HTTP.new forwards multiple args to #initialize.
|
|
12
|
+
# We only care about socket_path and ignore the rest.
|
|
13
|
+
def initialize(socket_path, *_rest)
|
|
14
|
+
super("localhost", Net::HTTP.http_default_port)
|
|
15
|
+
@socket_path = socket_path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private def connect
|
|
19
|
+
raise ArgumentError.new("TLS over unix sockets is not supported") if use_ssl?
|
|
20
|
+
|
|
21
|
+
@socket = Net::BufferedIO.new(UNIXSocket.new(@socket_path))
|
|
22
|
+
@last_communicated = nil
|
|
23
|
+
on_connect
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
10
27
|
# from the golang stdlib
|
|
11
28
|
# https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49
|
|
12
29
|
KEEP_ALIVE_TIMEOUT = 30
|
|
@@ -17,10 +34,19 @@ module DockerEngineRuby
|
|
|
17
34
|
# @api private
|
|
18
35
|
#
|
|
19
36
|
# @param cert_store [OpenSSL::X509::Store]
|
|
37
|
+
# @param tls_cert [OpenSSL::X509::Certificate, nil]
|
|
38
|
+
# @param tls_key [OpenSSL::PKey::PKey, nil]
|
|
39
|
+
# @param unix_socket_path [String, nil]
|
|
20
40
|
# @param url [URI::Generic]
|
|
21
41
|
#
|
|
22
42
|
# @return [Net::HTTP]
|
|
23
|
-
def connect(cert_store:, url:)
|
|
43
|
+
def connect(cert_store:, tls_cert:, tls_key:, unix_socket_path:, url:)
|
|
44
|
+
if unix_socket_path
|
|
45
|
+
return UnixSocketHTTP.new(unix_socket_path).tap do
|
|
46
|
+
_1.use_ssl = false
|
|
47
|
+
_1.max_retries = 0
|
|
48
|
+
end
|
|
49
|
+
end
|
|
24
50
|
port =
|
|
25
51
|
case [url.port, url.scheme]
|
|
26
52
|
in [Integer, _]
|
|
@@ -35,7 +61,11 @@ module DockerEngineRuby
|
|
|
35
61
|
_1.use_ssl = %w[https wss].include?(url.scheme)
|
|
36
62
|
_1.max_retries = 0
|
|
37
63
|
|
|
38
|
-
|
|
64
|
+
if _1.use_ssl?
|
|
65
|
+
_1.cert_store = cert_store
|
|
66
|
+
_1.cert = tls_cert if tls_cert
|
|
67
|
+
_1.key = tls_key if tls_key
|
|
68
|
+
end
|
|
39
69
|
end
|
|
40
70
|
end
|
|
41
71
|
|
|
@@ -94,18 +124,25 @@ module DockerEngineRuby
|
|
|
94
124
|
# @api private
|
|
95
125
|
#
|
|
96
126
|
# @param url [URI::Generic]
|
|
127
|
+
# @param unix_socket_path [String, nil]
|
|
97
128
|
# @param deadline [Float]
|
|
98
129
|
# @param blk [Proc]
|
|
99
130
|
#
|
|
100
131
|
# @raise [Timeout::Error]
|
|
101
132
|
# @yieldparam [Net::HTTP]
|
|
102
|
-
private def with_pool(url, deadline:, &blk)
|
|
103
|
-
origin = DockerEngineRuby::Internal::Util.uri_origin(url)
|
|
133
|
+
private def with_pool(url, unix_socket_path:, deadline:, &blk)
|
|
134
|
+
origin = unix_socket_path || DockerEngineRuby::Internal::Util.uri_origin(url)
|
|
104
135
|
timeout = deadline - DockerEngineRuby::Internal::Util.monotonic_secs
|
|
105
136
|
pool =
|
|
106
137
|
@mutex.synchronize do
|
|
107
138
|
@pools[origin] ||= ConnectionPool.new(size: @size) do
|
|
108
|
-
self.class.connect(
|
|
139
|
+
self.class.connect(
|
|
140
|
+
cert_store: @cert_store,
|
|
141
|
+
tls_cert: @tls_cert,
|
|
142
|
+
tls_key: @tls_key,
|
|
143
|
+
unix_socket_path: unix_socket_path,
|
|
144
|
+
url: url
|
|
145
|
+
)
|
|
109
146
|
end
|
|
110
147
|
end
|
|
111
148
|
|
|
@@ -129,6 +166,7 @@ module DockerEngineRuby
|
|
|
129
166
|
# @return [Array(Integer, Net::HTTPResponse, Enumerable<String>)]
|
|
130
167
|
def execute(request)
|
|
131
168
|
url, deadline = request.fetch_values(:url, :deadline)
|
|
169
|
+
unix_socket_path = request.fetch(:unix_socket_path, @default_unix_socket_path)
|
|
132
170
|
|
|
133
171
|
req = nil
|
|
134
172
|
finished = false
|
|
@@ -137,7 +175,7 @@ module DockerEngineRuby
|
|
|
137
175
|
enum = Enumerator.new do |y|
|
|
138
176
|
next if finished
|
|
139
177
|
|
|
140
|
-
with_pool(url, deadline: deadline) do |conn|
|
|
178
|
+
with_pool(url, unix_socket_path: unix_socket_path, deadline: deadline) do |conn|
|
|
141
179
|
eof = false
|
|
142
180
|
closing = nil
|
|
143
181
|
::Thread.handle_interrupt(Object => :never) do
|
|
@@ -194,15 +232,49 @@ module DockerEngineRuby
|
|
|
194
232
|
# @api private
|
|
195
233
|
#
|
|
196
234
|
# @param size [Integer]
|
|
197
|
-
|
|
235
|
+
# @param tls_ca_cert_path [String, nil]
|
|
236
|
+
# @param tls_client_cert_path [String, nil]
|
|
237
|
+
# @param tls_client_key_path [String, nil]
|
|
238
|
+
# @param unix_socket_path [String, nil]
|
|
239
|
+
def initialize(
|
|
240
|
+
size: self.class::DEFAULT_MAX_CONNECTIONS,
|
|
241
|
+
unix_socket_path: nil,
|
|
242
|
+
tls_ca_cert_path: nil,
|
|
243
|
+
tls_client_cert_path: nil,
|
|
244
|
+
tls_client_key_path: nil
|
|
245
|
+
)
|
|
198
246
|
@mutex = Mutex.new
|
|
199
247
|
@size = size
|
|
248
|
+
@default_unix_socket_path = unix_socket_path
|
|
200
249
|
@cert_store = OpenSSL::X509::Store.new.tap(&:set_default_paths)
|
|
250
|
+
@cert_store.add_file(tls_ca_cert_path) if tls_ca_cert_path
|
|
251
|
+
|
|
252
|
+
if tls_client_cert_path || tls_client_key_path
|
|
253
|
+
if tls_client_cert_path.nil? || tls_client_key_path.nil?
|
|
254
|
+
raise ArgumentError.new("Both tls_client_cert_path and tls_client_key_path must be provided together.")
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
@tls_cert = OpenSSL::X509::Certificate.new(File.read(tls_client_cert_path))
|
|
258
|
+
@tls_key = OpenSSL::PKey.read(File.read(tls_client_key_path))
|
|
259
|
+
else
|
|
260
|
+
@tls_cert = nil
|
|
261
|
+
@tls_key = nil
|
|
262
|
+
end
|
|
263
|
+
|
|
201
264
|
@pools = {}
|
|
202
265
|
end
|
|
203
266
|
|
|
204
267
|
define_sorbet_constant!(:Request) do
|
|
205
|
-
T.type_alias
|
|
268
|
+
T.type_alias do
|
|
269
|
+
{
|
|
270
|
+
method: Symbol,
|
|
271
|
+
url: URI::Generic,
|
|
272
|
+
unix_socket_path: T.nilable(String),
|
|
273
|
+
headers: T::Hash[String, String],
|
|
274
|
+
body: T.anything,
|
|
275
|
+
deadline: Float
|
|
276
|
+
}
|
|
277
|
+
end
|
|
206
278
|
end
|
|
207
279
|
end
|
|
208
280
|
end
|
|
@@ -483,6 +483,9 @@ module DockerEngineRuby
|
|
|
483
483
|
model: NilClass,
|
|
484
484
|
options: options
|
|
485
485
|
)
|
|
486
|
+
rescue DockerEngineRuby::Errors::APIStatusError => e
|
|
487
|
+
raise e unless e.status == 304
|
|
488
|
+
nil
|
|
486
489
|
end
|
|
487
490
|
|
|
488
491
|
# Get container stats based on resource usage
|
|
@@ -529,6 +532,9 @@ module DockerEngineRuby
|
|
|
529
532
|
model: NilClass,
|
|
530
533
|
options: options
|
|
531
534
|
)
|
|
535
|
+
rescue DockerEngineRuby::Errors::APIStatusError => e
|
|
536
|
+
raise e unless e.status == 304
|
|
537
|
+
nil
|
|
532
538
|
end
|
|
533
539
|
|
|
534
540
|
# List processes running inside a container
|
|
@@ -19,6 +19,19 @@ module DockerEngineRuby
|
|
|
19
19
|
T::Hash[Symbol, String]
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
+
# Path to the trusted CA certificate file (PEM) used to verify the Docker daemon
|
|
23
|
+
# certificate.
|
|
24
|
+
sig { returns(T.nilable(String)) }
|
|
25
|
+
attr_reader :tls_ca_cert_path
|
|
26
|
+
|
|
27
|
+
# Path to the client TLS certificate file (PEM).
|
|
28
|
+
sig { returns(T.nilable(String)) }
|
|
29
|
+
attr_reader :tls_client_cert_path
|
|
30
|
+
|
|
31
|
+
# Path to the client TLS private key file (PEM).
|
|
32
|
+
sig { returns(T.nilable(String)) }
|
|
33
|
+
attr_reader :tls_client_key_path
|
|
34
|
+
|
|
22
35
|
sig { returns(DockerEngineRuby::Resources::Auth) }
|
|
23
36
|
attr_reader :auth
|
|
24
37
|
|
|
@@ -67,6 +80,9 @@ module DockerEngineRuby
|
|
|
67
80
|
# Creates and returns a new client for interacting with the API.
|
|
68
81
|
sig do
|
|
69
82
|
params(
|
|
83
|
+
tls_ca_cert_path: T.nilable(String),
|
|
84
|
+
tls_client_cert_path: T.nilable(String),
|
|
85
|
+
tls_client_key_path: T.nilable(String),
|
|
70
86
|
environment: T.nilable(T.any(Symbol, String)),
|
|
71
87
|
base_url: T.nilable(String),
|
|
72
88
|
max_retries: Integer,
|
|
@@ -76,6 +92,15 @@ module DockerEngineRuby
|
|
|
76
92
|
).returns(T.attached_class)
|
|
77
93
|
end
|
|
78
94
|
def self.new(
|
|
95
|
+
# Path to the trusted CA certificate file (PEM) used to verify the Docker daemon
|
|
96
|
+
# certificate. Defaults to `ENV["DOCKER_TLS_CA_CERT_PATH"]`
|
|
97
|
+
tls_ca_cert_path: ENV["DOCKER_TLS_CA_CERT_PATH"],
|
|
98
|
+
# Path to the client TLS certificate file (PEM). Defaults to
|
|
99
|
+
# `ENV["DOCKER_TLS_CLIENT_CERT_PATH"]`
|
|
100
|
+
tls_client_cert_path: ENV["DOCKER_TLS_CLIENT_CERT_PATH"],
|
|
101
|
+
# Path to the client TLS private key file (PEM). Defaults to
|
|
102
|
+
# `ENV["DOCKER_TLS_CLIENT_KEY_PATH"]`
|
|
103
|
+
tls_client_key_path: ENV["DOCKER_TLS_CLIENT_KEY_PATH"],
|
|
79
104
|
# Specifies the environment to use for the API.
|
|
80
105
|
#
|
|
81
106
|
# Each environment maps to a different base URL:
|
|
@@ -165,7 +165,10 @@ module DockerEngineRuby
|
|
|
165
165
|
)
|
|
166
166
|
)
|
|
167
167
|
],
|
|
168
|
-
idempotency_header: T.nilable(String)
|
|
168
|
+
idempotency_header: T.nilable(String),
|
|
169
|
+
tls_ca_cert_path: T.nilable(String),
|
|
170
|
+
tls_client_cert_path: T.nilable(String),
|
|
171
|
+
tls_client_key_path: T.nilable(String)
|
|
169
172
|
).returns(T.attached_class)
|
|
170
173
|
end
|
|
171
174
|
def self.new(
|
|
@@ -175,7 +178,10 @@ module DockerEngineRuby
|
|
|
175
178
|
initial_retry_delay: 0.0,
|
|
176
179
|
max_retry_delay: 0.0,
|
|
177
180
|
headers: {},
|
|
178
|
-
idempotency_header: nil
|
|
181
|
+
idempotency_header: nil,
|
|
182
|
+
tls_ca_cert_path: nil,
|
|
183
|
+
tls_client_cert_path: nil,
|
|
184
|
+
tls_client_key_path: nil
|
|
179
185
|
)
|
|
180
186
|
end
|
|
181
187
|
|
|
@@ -27,11 +27,16 @@ module DockerEngineRuby
|
|
|
27
27
|
class << self
|
|
28
28
|
# @api private
|
|
29
29
|
sig do
|
|
30
|
-
params(
|
|
30
|
+
params(
|
|
31
|
+
cert_store: OpenSSL::X509::Store,
|
|
32
|
+
tls_cert: T.nilable(OpenSSL::X509::Certificate),
|
|
33
|
+
tls_key: T.nilable(OpenSSL::PKey::PKey),
|
|
34
|
+
url: URI::Generic
|
|
35
|
+
).returns(
|
|
31
36
|
Net::HTTP
|
|
32
37
|
)
|
|
33
38
|
end
|
|
34
|
-
def connect(cert_store:, url:)
|
|
39
|
+
def connect(cert_store:, tls_cert:, tls_key:, url:)
|
|
35
40
|
end
|
|
36
41
|
|
|
37
42
|
# @api private
|
|
@@ -73,9 +78,19 @@ module DockerEngineRuby
|
|
|
73
78
|
end
|
|
74
79
|
|
|
75
80
|
# @api private
|
|
76
|
-
sig
|
|
81
|
+
sig do
|
|
82
|
+
params(
|
|
83
|
+
size: Integer,
|
|
84
|
+
tls_ca_cert_path: T.nilable(String),
|
|
85
|
+
tls_client_cert_path: T.nilable(String),
|
|
86
|
+
tls_client_key_path: T.nilable(String)
|
|
87
|
+
).returns(T.attached_class)
|
|
88
|
+
end
|
|
77
89
|
def self.new(
|
|
78
|
-
size: DockerEngineRuby::Internal::Transport::PooledNetRequester::DEFAULT_MAX_CONNECTIONS
|
|
90
|
+
size: DockerEngineRuby::Internal::Transport::PooledNetRequester::DEFAULT_MAX_CONNECTIONS,
|
|
91
|
+
tls_ca_cert_path: nil,
|
|
92
|
+
tls_client_cert_path: nil,
|
|
93
|
+
tls_client_key_path: nil
|
|
79
94
|
)
|
|
80
95
|
end
|
|
81
96
|
end
|
|
@@ -13,6 +13,12 @@ module DockerEngineRuby
|
|
|
13
13
|
production_tls: "https://localhost:2376"
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
attr_reader tls_ca_cert_path: String?
|
|
17
|
+
|
|
18
|
+
attr_reader tls_client_cert_path: String?
|
|
19
|
+
|
|
20
|
+
attr_reader tls_client_key_path: String?
|
|
21
|
+
|
|
16
22
|
attr_reader auth: DockerEngineRuby::Resources::Auth
|
|
17
23
|
|
|
18
24
|
attr_reader system_: DockerEngineRuby::Resources::System
|
|
@@ -44,6 +50,9 @@ module DockerEngineRuby
|
|
|
44
50
|
attr_reader distribution: DockerEngineRuby::Resources::Distribution
|
|
45
51
|
|
|
46
52
|
def initialize: (
|
|
53
|
+
?tls_ca_cert_path: String?,
|
|
54
|
+
?tls_client_cert_path: String?,
|
|
55
|
+
?tls_client_key_path: String?,
|
|
47
56
|
?environment: :production | :production_tls | nil,
|
|
48
57
|
?base_url: String?,
|
|
49
58
|
?max_retries: Integer,
|
|
@@ -82,7 +82,10 @@ module DockerEngineRuby
|
|
|
82
82
|
?headers: ::Hash[String, (String
|
|
83
83
|
| Integer
|
|
84
84
|
| ::Array[(String | Integer)?])?],
|
|
85
|
-
?idempotency_header: String
|
|
85
|
+
?idempotency_header: String?,
|
|
86
|
+
?tls_ca_cert_path: String?,
|
|
87
|
+
?tls_client_cert_path: String?,
|
|
88
|
+
?tls_client_key_path: String?
|
|
86
89
|
) -> void
|
|
87
90
|
|
|
88
91
|
private def user_agent: -> String
|
|
@@ -19,6 +19,8 @@ module DockerEngineRuby
|
|
|
19
19
|
|
|
20
20
|
def self.connect: (
|
|
21
21
|
cert_store: OpenSSL::X509::Store,
|
|
22
|
+
tls_cert: OpenSSL::X509::Certificate?,
|
|
23
|
+
tls_key: OpenSSL::PKey::PKey?,
|
|
22
24
|
url: URI::Generic
|
|
23
25
|
) -> top
|
|
24
26
|
|
|
@@ -41,7 +43,12 @@ module DockerEngineRuby
|
|
|
41
43
|
DockerEngineRuby::Internal::Transport::PooledNetRequester::request request
|
|
42
44
|
) -> [Integer, top, Enumerable[String]]
|
|
43
45
|
|
|
44
|
-
def initialize: (
|
|
46
|
+
def initialize: (
|
|
47
|
+
?size: Integer,
|
|
48
|
+
?tls_ca_cert_path: String?,
|
|
49
|
+
?tls_client_cert_path: String?,
|
|
50
|
+
?tls_client_key_path: String?
|
|
51
|
+
) -> void
|
|
45
52
|
end
|
|
46
53
|
end
|
|
47
54
|
end
|