altaire-siren 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/Gemfile +0 -1
- data/Gemfile.lock +7 -1
- data/altaire-siren.gemspec +1 -0
- data/build-schema.rb +206 -0
- data/docs/docs/commands/song.md +3 -0
- data/fantasia-export.rb +16 -0
- data/lib/siren.rb +2 -0
- data/lib/siren/cli.rb +16 -1
- data/lib/siren/compose.rb +103 -0
- data/lib/siren/compose/service.rb +321 -0
- data/lib/siren/compose/types.rb +230 -0
- data/lib/siren/schemabuilder.rb +56 -0
- data/lib/siren/song.rb +78 -50
- data/lib/siren/stack.rb +6 -2
- data/lib/siren/version.rb +1 -1
- data/schemas/docker-compose.yaml +78 -0
- metadata +23 -47
- data/docs/site/404.html +0 -313
- data/docs/site/assets/fonts/font-awesome.css +0 -4
- data/docs/site/assets/fonts/material-icons.css +0 -13
- data/docs/site/assets/fonts/specimen/FontAwesome.ttf +0 -0
- data/docs/site/assets/fonts/specimen/FontAwesome.woff +0 -0
- data/docs/site/assets/fonts/specimen/FontAwesome.woff2 +0 -0
- data/docs/site/assets/fonts/specimen/MaterialIcons-Regular.ttf +0 -0
- data/docs/site/assets/fonts/specimen/MaterialIcons-Regular.woff +0 -0
- data/docs/site/assets/fonts/specimen/MaterialIcons-Regular.woff2 +0 -0
- data/docs/site/assets/images/favicon.png +0 -0
- data/docs/site/assets/images/icons/bitbucket.1b09e088.svg +0 -1
- data/docs/site/assets/images/icons/github.f0b8504a.svg +0 -1
- data/docs/site/assets/images/icons/gitlab.6dd19c00.svg +0 -1
- data/docs/site/assets/javascripts/application.c648116f.js +0 -6
- data/docs/site/assets/javascripts/lunr/lunr.da.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.de.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.du.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.es.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.fi.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.fr.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.hu.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.it.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.ja.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.jp.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.multi.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.nl.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.no.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.pt.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.ro.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.ru.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.stemmer.support.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.sv.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.th.js +0 -1
- data/docs/site/assets/javascripts/lunr/lunr.tr.js +0 -1
- data/docs/site/assets/javascripts/lunr/tinyseg.js +0 -1
- data/docs/site/assets/javascripts/lunr/wordcut.js +0 -1
- data/docs/site/assets/javascripts/modernizr.74668098.js +0 -1
- data/docs/site/assets/stylesheets/application-palette.a8b3c06d.css +0 -1
- data/docs/site/assets/stylesheets/application.30686662.css +0 -1
- data/docs/site/commands/crypto/index.html +0 -470
- data/docs/site/commands/song/index.html +0 -474
- data/docs/site/index.html +0 -348
- data/docs/site/search/search_index.json +0 -1
- data/docs/site/sitemap.xml +0 -18
- data/docs/site/sitemap.xml.gz +0 -0
@@ -0,0 +1,321 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
|
4
|
+
module Siren
|
5
|
+
class Compose
|
6
|
+
|
7
|
+
class Service < Struct.new(:compose, :name, :build, :command, :configs, :container_name, :credential_spec, :deploy, :dns, :dns_search, :entrypoint,
|
8
|
+
:environment, :expose, :extra_hosts, :healthcheck, :image, :init, :labels, :logging, :networks, :pid, :ports, :secrets, :stop_grace_period,
|
9
|
+
:stop_signal, :sysctls, :ulimits, :volumes, :domainname, :hostname, :ipc, :mac_address, :privileged, :read_only, :shm_size, :stdin_open, :tty,
|
10
|
+
:user, :working_dir)
|
11
|
+
|
12
|
+
def initialize (compose, data = {})
|
13
|
+
self.compose = compose
|
14
|
+
data.each do |key, value|
|
15
|
+
self.__send__("#{key}=", value)
|
16
|
+
end
|
17
|
+
self.deploy = deploy ? Deploy.new(deploy) : Deploy.new
|
18
|
+
self.ports ||= []
|
19
|
+
self.volumes ||= []
|
20
|
+
self.name = namify(self.name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def ports= (ports)
|
24
|
+
ports = ports.map do |port|
|
25
|
+
if port.is_a?(String)
|
26
|
+
target, published, protocol = port.match(/^(\d+)?(?::(\d+))?(\/.+)?$/).to_a[1..-1]
|
27
|
+
else
|
28
|
+
target, published, protocol, mode = port.values_at("target", "published", "protocol", "mode")
|
29
|
+
end
|
30
|
+
protocol ||= "tcp"
|
31
|
+
{
|
32
|
+
"target" => target,
|
33
|
+
"published" => published,
|
34
|
+
"protocol" => protocol,
|
35
|
+
"mode" => mode,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
compose.xdomains.each do |xd|
|
39
|
+
next unless xd["service"] == name
|
40
|
+
ports.unshift({
|
41
|
+
"protocol" => "tcp",
|
42
|
+
"target" => xd["port"],
|
43
|
+
"published" => "80",
|
44
|
+
})
|
45
|
+
end
|
46
|
+
compose.xports.each do |xp|
|
47
|
+
next unless xp["service"] == name
|
48
|
+
ports.unshift({
|
49
|
+
"protocol" => xp["protocol"],
|
50
|
+
"target" => xp["inside"],
|
51
|
+
"published" => xp["outside"],
|
52
|
+
"mode" => "ingress",
|
53
|
+
})
|
54
|
+
end
|
55
|
+
ports.uniq!{|p|p.values_at("published", "protocol")}
|
56
|
+
super(ports)
|
57
|
+
end
|
58
|
+
|
59
|
+
def command= (value)
|
60
|
+
value = ["sh", "-c", value] if value.is_a?(String)
|
61
|
+
super(value)
|
62
|
+
# if configs
|
63
|
+
end
|
64
|
+
|
65
|
+
def resolve_environment (env)
|
66
|
+
if env.is_a?(Array)
|
67
|
+
env = env.map do |line|
|
68
|
+
key, value = line.split("=", 2)
|
69
|
+
[key, value || "$#{key}"]
|
70
|
+
end.to_h
|
71
|
+
end
|
72
|
+
env ||= {}
|
73
|
+
env.transform_values! do |value|
|
74
|
+
value.gsub(/\$[\dA-Z_a-z]+/) do |name|
|
75
|
+
compose.xenv[name[1..-1]]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
env.map do |name, value|
|
79
|
+
{
|
80
|
+
name: name,
|
81
|
+
value: value,
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def namify (*items)
|
87
|
+
items.flatten.compact.join("-").downcase.gsub(/[^a-z\d]/, '-').gsub(/-+/, "-")
|
88
|
+
end
|
89
|
+
|
90
|
+
def emit_deployment (stack)
|
91
|
+
stack << {
|
92
|
+
kind: "Deployment",
|
93
|
+
apiVersion: "apps/v1",
|
94
|
+
metadata: {
|
95
|
+
namespace: compose.name,
|
96
|
+
name: name,
|
97
|
+
},
|
98
|
+
spec: {
|
99
|
+
replicas: deploy.replicas,
|
100
|
+
selector: {
|
101
|
+
matchLabels: {
|
102
|
+
stack: compose.name,
|
103
|
+
service: name,
|
104
|
+
},
|
105
|
+
},
|
106
|
+
template: {
|
107
|
+
metadata: {
|
108
|
+
labels: {
|
109
|
+
stack: compose.name,
|
110
|
+
service: name,
|
111
|
+
},
|
112
|
+
},
|
113
|
+
spec: {
|
114
|
+
containers: [
|
115
|
+
command: command,
|
116
|
+
env: resolve_environment(environment),
|
117
|
+
image: image,
|
118
|
+
name: name,
|
119
|
+
volumeMounts: volumes.map do |volume|
|
120
|
+
name, path = volume.split(":", 2)
|
121
|
+
{
|
122
|
+
mountPath: path,
|
123
|
+
name: name,
|
124
|
+
}
|
125
|
+
end
|
126
|
+
],
|
127
|
+
hostname: hostname,
|
128
|
+
imagePullSecrets: [{name: "image-pull-secrets"}],
|
129
|
+
restartPolicy: { "none" => "Never", "on-failure" => "OnFailure" }[deploy.restart_policy&.condition],
|
130
|
+
volumes: volumes.map do |volume|
|
131
|
+
name = volume.split(":")[0]
|
132
|
+
{ name: name, persistentVolumeClaim: { claimName: name } }
|
133
|
+
end
|
134
|
+
},
|
135
|
+
},
|
136
|
+
},
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
def emit_services (stack)
|
141
|
+
ports.group_by{|port|port["mode"]}.each do |mode, ports|
|
142
|
+
stack << {
|
143
|
+
kind: "Service",
|
144
|
+
apiVersion: "v1",
|
145
|
+
metadata: {
|
146
|
+
namespace: compose.name,
|
147
|
+
name: mode == "ingress" ? "#{name}-nodeport" : name,
|
148
|
+
},
|
149
|
+
spec: {
|
150
|
+
ports: ports.map do |port|
|
151
|
+
{
|
152
|
+
name: ports.length == 1 ? nil : port["published"],
|
153
|
+
port: port["published"].to_i,
|
154
|
+
targetPort: port["target"] != port["published"] ? port["target"].to_i : nil,
|
155
|
+
protocol: port["protocol"] == "udp" ? "UDP" : nil
|
156
|
+
}
|
157
|
+
end,
|
158
|
+
selector: {
|
159
|
+
stack: compose.name,
|
160
|
+
service: name,
|
161
|
+
},
|
162
|
+
type: mode == "ingress" ? "NodePort" : nil,
|
163
|
+
}
|
164
|
+
}
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def emit_auth_middleware (stack)
|
169
|
+
return if @did_emit_auth_middleware
|
170
|
+
did_emit_auth_middleware = true
|
171
|
+
stack << {
|
172
|
+
kind: "Middleware",
|
173
|
+
apiVersion: "traefik.containo.us/v1alpha1",
|
174
|
+
metadata: {
|
175
|
+
namespace: compose.name,
|
176
|
+
name: "altaire-auth",
|
177
|
+
},
|
178
|
+
spec: {
|
179
|
+
forwardAuth: {
|
180
|
+
address: "http://auth-server.default.svc.cluster.local/auth",
|
181
|
+
},
|
182
|
+
},
|
183
|
+
}
|
184
|
+
end
|
185
|
+
|
186
|
+
def emit_middlewares (stack)
|
187
|
+
compose.xdomains.each do |xd|
|
188
|
+
next unless xd["service"] == name
|
189
|
+
next if xd["path"] == nil
|
190
|
+
stack << {
|
191
|
+
kind: "Middleware",
|
192
|
+
apiVersion: "traefik.containo.us/v1alpha1",
|
193
|
+
metadata: {
|
194
|
+
namespace: compose.name,
|
195
|
+
name: namify(xd["name"], xd["path"], "strip-prefix"),
|
196
|
+
},
|
197
|
+
spec: {
|
198
|
+
stripPrefix: {
|
199
|
+
prefixes: ["/#{xd["path"]}"],
|
200
|
+
},
|
201
|
+
},
|
202
|
+
}
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def emit_ingress_routes (stack)
|
207
|
+
compose.xdomains.each do |xd|
|
208
|
+
next unless xd["service"] == name
|
209
|
+
emit_auth_middleware stack if xd["auth"]
|
210
|
+
stack << {
|
211
|
+
kind: "IngressRoute",
|
212
|
+
apiVersion: "traefik.containo.us/v1alpha1",
|
213
|
+
metadata: {
|
214
|
+
namespace: compose.name,
|
215
|
+
name: namify(xd["name"], xd["path"]),
|
216
|
+
},
|
217
|
+
spec: {
|
218
|
+
tls: {
|
219
|
+
secretName: namify(xd["name"]),
|
220
|
+
},
|
221
|
+
routes: [{
|
222
|
+
kind: "Rule",
|
223
|
+
match: nil,
|
224
|
+
middlewares: [
|
225
|
+
xd["auth"] ? { name: "altaire-auth" } : nil,
|
226
|
+
xd["path"] ? { name: namify(xd["name"], xd["path"], "strip-prefix") } : nil,
|
227
|
+
],
|
228
|
+
services: [{
|
229
|
+
name: name,
|
230
|
+
port: 80
|
231
|
+
}],
|
232
|
+
}.merge(
|
233
|
+
if xd["path"]
|
234
|
+
{match: "Host(`#{xd["name"]}`) && PathPrefix(`#{xd["path"]}`)"}
|
235
|
+
else
|
236
|
+
{match: "Host(`#{xd["name"]}`)"}
|
237
|
+
end
|
238
|
+
)],
|
239
|
+
},
|
240
|
+
}
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def emit_domains (stack)
|
245
|
+
compose.xdomains.each do |xd|
|
246
|
+
stack << {
|
247
|
+
kind: "Domain",
|
248
|
+
apiVersion: "altaire.com/v1alpha1",
|
249
|
+
metadata: {
|
250
|
+
namespace: compose.name,
|
251
|
+
name: namify(xd["name"]),
|
252
|
+
},
|
253
|
+
spec: {
|
254
|
+
domain: xd["name"],
|
255
|
+
service: "traefik",
|
256
|
+
},
|
257
|
+
}
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def emit_certificates (stack)
|
262
|
+
compose.xdomains.each do |xd|
|
263
|
+
stack << {
|
264
|
+
kind: "Certificate",
|
265
|
+
apiVersion: "cert-manager.io/v1alpha2",
|
266
|
+
metadata: {
|
267
|
+
namespace: compose.name,
|
268
|
+
name: namify(xd["name"]),
|
269
|
+
},
|
270
|
+
spec: {
|
271
|
+
commonName: xd["name"],
|
272
|
+
dnsNames: [xd["name"]],
|
273
|
+
duration: "2160h0m0s",
|
274
|
+
renewBefore: "360h0m0s",
|
275
|
+
issuerRef: {
|
276
|
+
kind: "ClusterIssuer",
|
277
|
+
name: "letsencrypt-production",
|
278
|
+
},
|
279
|
+
secretName: namify(xd["name"]),
|
280
|
+
},
|
281
|
+
}
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def emit_volumes (stack)
|
286
|
+
volumes.each do |volume|
|
287
|
+
name, path = volume.split(":", 2)
|
288
|
+
stack << {
|
289
|
+
kind: "PersistentVolumeClaim",
|
290
|
+
apiVersion: "v1",
|
291
|
+
metadata: {
|
292
|
+
namespace: compose.name,
|
293
|
+
name: name,
|
294
|
+
},
|
295
|
+
spec: {
|
296
|
+
accessModes: ["ReadWriteOnce"],
|
297
|
+
resources: {
|
298
|
+
requests: {
|
299
|
+
storage: "1Gi",
|
300
|
+
},
|
301
|
+
},
|
302
|
+
storageClassName: "do-block-storage",
|
303
|
+
},
|
304
|
+
}
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def to_stack (stack)
|
309
|
+
emit_deployment stack
|
310
|
+
emit_services stack
|
311
|
+
emit_middlewares stack
|
312
|
+
emit_ingress_routes stack
|
313
|
+
# emit_domains stack
|
314
|
+
emit_certificates stack
|
315
|
+
emit_volumes stack
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
319
|
+
|
320
|
+
end
|
321
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
class Array
|
4
|
+
def deep_compact
|
5
|
+
map do |value|
|
6
|
+
value = value.deep_compact if value.respond_to?(:deep_compact)
|
7
|
+
value
|
8
|
+
end.compact.yield_self do |x|
|
9
|
+
x.empty? ? nil : x
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Hash
|
15
|
+
def deep_compact
|
16
|
+
transform_values do |value|
|
17
|
+
value = value.deep_compact if value.respond_to?(:deep_compact)
|
18
|
+
value
|
19
|
+
end.compact.yield_self do |x|
|
20
|
+
x.empty? ? nil : x
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module Siren
|
26
|
+
class Compose
|
27
|
+
module HashInitialize
|
28
|
+
def initialize (data = {})
|
29
|
+
data.each do |key, value|
|
30
|
+
self.__send__("#{key}=", value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
require_relative "service"
|
38
|
+
|
39
|
+
module Siren
|
40
|
+
class Compose
|
41
|
+
|
42
|
+
class RestartPolicy < Struct.new(:condition, :delay, :max_attempts, :window)
|
43
|
+
include HashInitialize
|
44
|
+
end
|
45
|
+
|
46
|
+
class RollbackConfig < Struct.new(:parallelism, :delay, :failure_action, :monitor, :max_failure_ratio, :order)
|
47
|
+
include HashInitialize
|
48
|
+
end
|
49
|
+
|
50
|
+
class UpdateConfig < Struct.new(:parallelism, :delay, :failure_action, :monitor, :max_failure_ratio, :order)
|
51
|
+
include HashInitialize
|
52
|
+
end
|
53
|
+
|
54
|
+
class Deploy < Struct.new(:endpoint_mode, :labels, :mode, :placement, :replicas, :resources, :restart_policy, :rollback_config, :update_config)
|
55
|
+
include HashInitialize
|
56
|
+
def restart_policy= (data)
|
57
|
+
data = RestartPolicy.new(data)
|
58
|
+
end
|
59
|
+
def rollback_config= (data)
|
60
|
+
data = RollbackConfig.new(data)
|
61
|
+
end
|
62
|
+
def update_config= (data)
|
63
|
+
data = UpdateConfig.new(data)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# restart_policy: object(
|
68
|
+
# condition: string(["none", "on-failure", "any"]),
|
69
|
+
# delay: duration,
|
70
|
+
# max_attemtps: integer,
|
71
|
+
# window: duration,
|
72
|
+
# ),
|
73
|
+
# rollback_config: object(
|
74
|
+
# parallelism: integer,
|
75
|
+
# delay: duration,
|
76
|
+
# failure_action: string(["continue", "pause"]),
|
77
|
+
# monitor: duration,
|
78
|
+
# max_failure_ratio: number,
|
79
|
+
# order: string(["stop-first", "start-first"]),
|
80
|
+
# ),
|
81
|
+
# update_config: object(
|
82
|
+
# parallelism: integer,
|
83
|
+
# delay: duration,
|
84
|
+
# failure_action: string(["continue", "pause", "rollback"]),
|
85
|
+
# monitor: duration,
|
86
|
+
# max_failure_ratio: number,
|
87
|
+
# order: string(["stop-first", "start-first"]),
|
88
|
+
# ),
|
89
|
+
|
90
|
+
# deploy: object(
|
91
|
+
# endpoint_mode: string(["vip", "dnsrr"]),
|
92
|
+
# labels: hashlike,
|
93
|
+
# mode: string(["global", "replicated"]),
|
94
|
+
# placement: object(
|
95
|
+
# constraints: array(string),
|
96
|
+
# preferences: array(object(spread: string)),
|
97
|
+
# ),
|
98
|
+
# replicas: integer,
|
99
|
+
# resources: object(
|
100
|
+
# limits: resources,
|
101
|
+
# reservations: resources,
|
102
|
+
# ),
|
103
|
+
|
104
|
+
Volume = Struct.new(:compose, :driver, :driver_opts, :external, :labels, :name)
|
105
|
+
|
106
|
+
Network = Struct.new(:compose, :driver, :driver_opts, :external, :labels, :name, :attachable, :ipam, :internal)
|
107
|
+
|
108
|
+
Config = Struct.new(:compose, :file, :external, :name)
|
109
|
+
|
110
|
+
Secret = Struct.new(:compose, :file, :external, :name)
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# version: string(/[0-9]+(\.[0-9]+)?/),
|
116
|
+
# services: hash(
|
117
|
+
# build: any(string, object(
|
118
|
+
# context: string,
|
119
|
+
# dockerfile: string,
|
120
|
+
# args: hashlike,
|
121
|
+
# cache_from: array(string),
|
122
|
+
# labels: hashlike,
|
123
|
+
# shm_size: string,
|
124
|
+
# target: string)
|
125
|
+
# ),
|
126
|
+
# command: any(string, array(string)),
|
127
|
+
# configs: array(any(string, object(
|
128
|
+
# source: string, target: string, uid: any(string, integer), gid: any(string, integer), mode: any(string, integer)
|
129
|
+
# ))),
|
130
|
+
# container_name: string,
|
131
|
+
# credential_spec: any(object(file: string), object(registry: string), object(config: string)),
|
132
|
+
# deploy: object(
|
133
|
+
# endpoint_mode: string(["vip", "dnsrr"]),
|
134
|
+
# labels: hashlike,
|
135
|
+
# mode: string(["global", "replicated"]),
|
136
|
+
# placement: object(
|
137
|
+
# constraints: array(string),
|
138
|
+
# preferences: array(object(spread: string)),
|
139
|
+
# ),
|
140
|
+
# replicas: integer,
|
141
|
+
# resources: object(
|
142
|
+
# limits: resources,
|
143
|
+
# reservations: resources,
|
144
|
+
# ),
|
145
|
+
# restart_policy: object(
|
146
|
+
# condition: string(["none", "on-failure", "any"]),
|
147
|
+
# delay: duration,
|
148
|
+
# max_attemtps: integer,
|
149
|
+
# window: duration,
|
150
|
+
# ),
|
151
|
+
# rollback_config: object(
|
152
|
+
# parallelism: integer,
|
153
|
+
# delay: duration,
|
154
|
+
# failure_action: string(["continue", "pause"]),
|
155
|
+
# monitor: duration,
|
156
|
+
# max_failure_ratio: number,
|
157
|
+
# order: string(["stop-first", "start-first"]),
|
158
|
+
# ),
|
159
|
+
# update_config: object(
|
160
|
+
# parallelism: integer,
|
161
|
+
# delay: duration,
|
162
|
+
# failure_action: string(["continue", "pause", "rollback"]),
|
163
|
+
# monitor: duration,
|
164
|
+
# max_failure_ratio: number,
|
165
|
+
# order: string(["stop-first", "start-first"]),
|
166
|
+
# ),
|
167
|
+
# ),
|
168
|
+
# dns: any(string, array(string)),
|
169
|
+
# dns_search: any(string, array(string)),
|
170
|
+
# entrypoint: any(string, array(string)),
|
171
|
+
# environment: hashlike,
|
172
|
+
# expose: array(string),
|
173
|
+
# extra_hosts: array(string),
|
174
|
+
# healthcheck: object(
|
175
|
+
# test: any(string, array(string)),
|
176
|
+
# interval: duration,
|
177
|
+
# timeout: duration,
|
178
|
+
# retries: integer,
|
179
|
+
# start_period: duration,
|
180
|
+
# ),
|
181
|
+
# image: string,
|
182
|
+
# init: bool,
|
183
|
+
# labels: hashlike,
|
184
|
+
# logging: object(
|
185
|
+
# driver: string,
|
186
|
+
# options: hash(string),
|
187
|
+
# ),
|
188
|
+
# networks: any(array(string), hash(object(aliases: array(string), ipv4_address: string, ipv6_address: string))),
|
189
|
+
# pid: string("host"),
|
190
|
+
# ports: array(any(string, object(target: integer, published: integer, protocol: string(["tcp", "udp"]), mode: string(["host", "ingress"])))),
|
191
|
+
# secrets: array(any(string, object(source: string, target: string, uid: integer, gid: integer, mode: integer))),
|
192
|
+
# stop_grace_period: duration,
|
193
|
+
# stop_signal: string(/^SIG/),
|
194
|
+
# sysctls: hashlike,
|
195
|
+
# ulimits: hash(any(integer, object(soft: integer, hard: integer))),
|
196
|
+
# volumes: array(any(string,
|
197
|
+
# object(type: string(["volume", "bind", "tmpfs", "npipe"]),
|
198
|
+
# source: string, target: string, read_only: boolean,
|
199
|
+
# consistency: string(["consistent", "cached", "delegated"]),
|
200
|
+
# volume: object(nocopy: boolean), bind: object(propagation: string),
|
201
|
+
# tmpfs: object(size: bytesize)),
|
202
|
+
# )),
|
203
|
+
# domainname: string,
|
204
|
+
# hostname: string,
|
205
|
+
# ipc: string,
|
206
|
+
# mac_address: string,
|
207
|
+
# privileged: boolean,
|
208
|
+
# read_only: boolean,
|
209
|
+
# shm_size: bytesize,
|
210
|
+
# stdin_open: boolean,
|
211
|
+
# tty: boolean,
|
212
|
+
# user: any(string, integer),
|
213
|
+
# working_dir: string,
|
214
|
+
# ),
|
215
|
+
# volumes: hash(any(null, object(driver: string, driver_opts: hash(string), external: boolean, labels: hashlike, name: string))),
|
216
|
+
# networks: hash(any(null, object(
|
217
|
+
# driver: string,
|
218
|
+
# driver_opts: hash(string),
|
219
|
+
# external: any(boolean, object(name: string)),
|
220
|
+
# attachable: boolean,
|
221
|
+
# ipam: object(
|
222
|
+
# driver: string,
|
223
|
+
# config: array(object(subnet: string))
|
224
|
+
# ),
|
225
|
+
# internal: boolean,
|
226
|
+
# labels: hashlike,
|
227
|
+
# name: string,
|
228
|
+
# ))),
|
229
|
+
# configs: hash(object(file: string, external: any(boolean, object(name: string)))),
|
230
|
+
# secrets: hash(object(file: string, external: boolean, name: string)),
|