capistrano-nomad 0.11.1 → 0.12.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 +9 -1
- data/capistrano-nomad.gemspec +1 -1
- data/lib/capistrano/nomad/helpers/dsl.rb +9 -1
- data/lib/capistrano/nomad/helpers/nomad.rb +105 -28
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d14fcb69aa16bc0815770535ac91e2eef6ef6bbbebc372b2278267912389f68d
|
4
|
+
data.tar.gz: 8a031005e8a27ce2ac50a6cd8f026290b4f6bd3e482b3acc6d819adfb668cc3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc3c5fc5c9a43e97e3277e53120ffcf88f14e9436d34742fad563221d8a003e7d9a2d56c93cbd7dad8676f711f86235b6715cd259a037db320c5876bc8f62bf2
|
7
|
+
data.tar.gz: a21adbbb7fc30eac19788733406fbeae0840c8bfab8ece91ee69fc202a35ef200ae8c62000321a6b3562d7d56bb1c4d7408189fcc6276e1d6e7fdbb8407e2494
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -37,7 +37,7 @@ Within `deploy.rb`
|
|
37
37
|
set :nomad_jobs_path, "nomad/jobs"
|
38
38
|
set :nomad_var_files_path, "nomad/vars"
|
39
39
|
|
40
|
-
# Determines base URL to use when opening job in web UI
|
40
|
+
# Determines base URL to use when opening job in web UI
|
41
41
|
set :nomad_ui_url, "http://localhost:4646"
|
42
42
|
|
43
43
|
# Make variables available to all template .erb files
|
@@ -162,6 +162,14 @@ cap production nomad:app:stderr
|
|
162
162
|
cap production nomad:analytics:grafana:follow
|
163
163
|
```
|
164
164
|
|
165
|
+
Revert jobs
|
166
|
+
|
167
|
+
```shell
|
168
|
+
cap production nomad:app:revert
|
169
|
+
cap production nomad:app:revert VERSION=4
|
170
|
+
cap production nomad:app:revert DOCKER_IMAGE=v1.4.4
|
171
|
+
```
|
172
|
+
|
165
173
|
Open job in web UI
|
166
174
|
|
167
175
|
```shell
|
data/capistrano-nomad.gemspec
CHANGED
@@ -44,7 +44,7 @@ def nomad_job(name, attributes = {})
|
|
44
44
|
attributes[:tags] ||= []
|
45
45
|
|
46
46
|
# Tags added to namespace should be added to all jobs within
|
47
|
-
if (nomad_namespace_options = capistrano_nomad_fetch_namespace_options(@nomad_namespace))
|
47
|
+
if (nomad_namespace_options = capistrano_nomad_fetch_namespace_options(namespace: @nomad_namespace))
|
48
48
|
attributes[:tags] += nomad_namespace_options[:tags] || []
|
49
49
|
end
|
50
50
|
|
@@ -120,6 +120,14 @@ def nomad_job(name, attributes = {})
|
|
120
120
|
capistrano_nomad_restart_jobs([name], namespace: namespace)
|
121
121
|
end
|
122
122
|
|
123
|
+
desc "Revert #{description_name} job. Specify version with VERSION. Specify targeting tasks with docker image with DOCKER_IMAGE. If none specified, it will revert to previous version"
|
124
|
+
task :revert do
|
125
|
+
capistrano_nomad_revert_jobs([name], ENV["VERSION"].presence,
|
126
|
+
namespace: namespace,
|
127
|
+
docker_image: ENV["DOCKER_IMAGE"],
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
123
131
|
desc "Purge #{description_name} job"
|
124
132
|
task :purge do
|
125
133
|
capistrano_nomad_purge_jobs([name], namespace: namespace, is_detached: false)
|
@@ -29,7 +29,9 @@ def capistrano_nomad_ensure_absolute_path(path)
|
|
29
29
|
path[0] == "/" ? path : "/#{path}"
|
30
30
|
end
|
31
31
|
|
32
|
-
def capistrano_nomad_build_file_path(parent_path, basename, kind: nil,
|
32
|
+
def capistrano_nomad_build_file_path(parent_path, basename, kind: nil, **options)
|
33
|
+
capistrano_nomad_ensure_options!(**options)
|
34
|
+
namespace = options[:namespace]
|
33
35
|
segments = [parent_path]
|
34
36
|
|
35
37
|
unless namespace == :default
|
@@ -41,7 +43,7 @@ def capistrano_nomad_build_file_path(parent_path, basename, kind: nil, namespace
|
|
41
43
|
|
42
44
|
# Otherwise path can be overriden of where files belonging to namespace are stored locally
|
43
45
|
else
|
44
|
-
namespace_options = capistrano_nomad_fetch_namespace_options(namespace)
|
46
|
+
namespace_options = capistrano_nomad_fetch_namespace_options(namespace: namespace)
|
45
47
|
|
46
48
|
segments << (namespace_options[:path] || namespace)
|
47
49
|
end
|
@@ -132,14 +134,15 @@ def capistrano_nomad_capture_nomad_command(*args, **options)
|
|
132
134
|
output
|
133
135
|
end
|
134
136
|
|
135
|
-
def capistrano_nomad_find_job_task_details(name,
|
137
|
+
def capistrano_nomad_find_job_task_details(name, task: nil, **options)
|
138
|
+
capistrano_nomad_ensure_options!(**options)
|
136
139
|
task = task.presence || name
|
137
140
|
|
138
141
|
# Find alloc id that contains task that is also running
|
139
142
|
allocs_output = capistrano_nomad_capture_nomad_command(
|
140
143
|
:job,
|
141
144
|
:allocs,
|
142
|
-
|
145
|
+
options.merge(t: "'{{range .}}{{ .ID }},{{ .ClientStatus }},{{ .TaskGroup }}|{{end}}'"),
|
143
146
|
name,
|
144
147
|
)
|
145
148
|
alloc_id = allocs_output
|
@@ -154,7 +157,7 @@ def capistrano_nomad_find_job_task_details(name, namespace: :default, task: nil)
|
|
154
157
|
tasks_output = capistrano_nomad_capture_nomad_command(
|
155
158
|
:alloc,
|
156
159
|
:status,
|
157
|
-
|
160
|
+
options.merge(t: "'{{range $key, $value := .TaskStates}}{{ $key }},{{ .State }}|{{end}}'"),
|
158
161
|
alloc_id,
|
159
162
|
)
|
160
163
|
tasks_by_score = tasks_output.split("|").each_with_object({}) do |task_output, hash|
|
@@ -174,13 +177,15 @@ def capistrano_nomad_find_job_task_details(name, namespace: :default, task: nil)
|
|
174
177
|
}
|
175
178
|
end
|
176
179
|
|
177
|
-
def capistrano_nomad_exec_within_job(name, command,
|
180
|
+
def capistrano_nomad_exec_within_job(name, command, task: nil, **options)
|
181
|
+
capistrano_nomad_ensure_options!(**options)
|
182
|
+
|
178
183
|
capistrano_nomad_run_remotely do
|
179
|
-
if (task_details = capistrano_nomad_find_job_task_details(name,
|
184
|
+
if (task_details = capistrano_nomad_find_job_task_details(name, task: task, **options))
|
180
185
|
capistrano_nomad_execute_nomad_command(
|
181
186
|
:alloc,
|
182
187
|
:exec,
|
183
|
-
|
188
|
+
options.merge(task: task_details[:name]),
|
184
189
|
task_details[:alloc_id],
|
185
190
|
command,
|
186
191
|
)
|
@@ -189,7 +194,7 @@ def capistrano_nomad_exec_within_job(name, command, namespace: :default, task: n
|
|
189
194
|
capistrano_nomad_execute_nomad_command(
|
190
195
|
:alloc,
|
191
196
|
:exec,
|
192
|
-
|
197
|
+
options.merge(job: true),
|
193
198
|
task,
|
194
199
|
command,
|
195
200
|
)
|
@@ -246,19 +251,30 @@ def capistrano_nomad_upload(local_path:, remote_path:, erb_vars: {})
|
|
246
251
|
end
|
247
252
|
end
|
248
253
|
|
249
|
-
def
|
250
|
-
|
254
|
+
def capistrano_nomad_ensure_options!(**options)
|
255
|
+
options[:namespace] ||= :default
|
256
|
+
end
|
257
|
+
|
258
|
+
def capistrano_nomad_fetch_namespace_options(**options)
|
259
|
+
capistrano_nomad_ensure_options!(**options)
|
260
|
+
|
261
|
+
fetch(:nomad_namespaces)&.dig(options[:namespace])
|
251
262
|
end
|
252
263
|
|
253
|
-
def capistrano_nomad_fetch_job_options(name, *args,
|
254
|
-
|
264
|
+
def capistrano_nomad_fetch_job_options(name, *args, **options)
|
265
|
+
capistrano_nomad_ensure_options!(**options)
|
266
|
+
|
267
|
+
fetch(:nomad_jobs).dig(options[:namespace], name.to_sym, *args)
|
255
268
|
end
|
256
269
|
|
257
270
|
def capistrano_nomad_fetch_job_var_files(name, **options)
|
258
271
|
capistrano_nomad_fetch_job_options(name, :var_files, **options) || []
|
259
272
|
end
|
260
273
|
|
261
|
-
def capistrano_nomad_fetch_jobs_names_by_namespace(
|
274
|
+
def capistrano_nomad_fetch_jobs_names_by_namespace(**options)
|
275
|
+
capistrano_nomad_ensure_options!(**options)
|
276
|
+
namespace = options[:namespace]
|
277
|
+
|
262
278
|
# Can pass tags via command line (e.g. TAG=foo or TAGS=foo,bar)
|
263
279
|
tags =
|
264
280
|
[ENV["TAG"], ENV["TAGS"]].map do |tag_args|
|
@@ -281,8 +297,10 @@ def capistrano_nomad_fetch_jobs_names_by_namespace(namespace: :default)
|
|
281
297
|
end
|
282
298
|
end
|
283
299
|
|
284
|
-
def capistrano_nomad_fetch_jobs_docker_image_types(names,
|
285
|
-
|
300
|
+
def capistrano_nomad_fetch_jobs_docker_image_types(names, **options)
|
301
|
+
capistrano_nomad_ensure_options!(**options)
|
302
|
+
|
303
|
+
names.map { |n| fetch(:nomad_jobs).dig(options[:namespace], n.to_sym, :docker_image_types) }.flatten.compact.uniq
|
286
304
|
end
|
287
305
|
|
288
306
|
def capistrano_nomad_define_group_tasks(namespace:)
|
@@ -350,6 +368,13 @@ def capistrano_nomad_define_group_tasks(namespace:)
|
|
350
368
|
end
|
351
369
|
end
|
352
370
|
|
371
|
+
desc "Revert #{nomad_namespace} jobs"
|
372
|
+
task :revert do
|
373
|
+
capistrano_nomad_fetch_jobs_names_by_namespace(namespace: nomad_namespace).each do |jobs_namespace, names|
|
374
|
+
capistrano_nomad_revert_jobs(names, namespace: jobs_namespace)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
353
378
|
desc "Stop #{nomad_namespace} jobs"
|
354
379
|
task :stop do
|
355
380
|
capistrano_nomad_fetch_jobs_names_by_namespace(namespace: nomad_namespace).each do |jobs_namespace, names|
|
@@ -433,24 +458,26 @@ def capistrano_nomad_plan_jobs(names, **options)
|
|
433
458
|
end
|
434
459
|
end
|
435
460
|
|
436
|
-
def capistrano_nomad_run_jobs(names,
|
461
|
+
def capistrano_nomad_run_jobs(names, is_detached: true, **options)
|
462
|
+
capistrano_nomad_ensure_options!(**options)
|
463
|
+
|
437
464
|
names.each do |name|
|
438
465
|
run_options = {
|
439
|
-
namespace: namespace,
|
466
|
+
namespace: options[:namespace],
|
440
467
|
detach: is_detached,
|
441
468
|
|
442
469
|
# Don't reset counts since they may have been scaled
|
443
470
|
preserve_counts: true,
|
444
471
|
}
|
445
472
|
|
446
|
-
capistrano_nomad_fetch_job_var_files(name,
|
447
|
-
run_options[:var_file] = capistrano_nomad_build_release_var_file_path(var_file,
|
473
|
+
capistrano_nomad_fetch_job_var_files(name, **options).each do |var_file|
|
474
|
+
run_options[:var_file] = capistrano_nomad_build_release_var_file_path(var_file, **options)
|
448
475
|
end
|
449
476
|
|
450
477
|
capistrano_nomad_execute_nomad_command(
|
451
478
|
:run,
|
452
479
|
run_options,
|
453
|
-
capistrano_nomad_build_release_job_path(name,
|
480
|
+
capistrano_nomad_build_release_job_path(name, **options),
|
454
481
|
)
|
455
482
|
end
|
456
483
|
end
|
@@ -494,6 +521,8 @@ def capistrano_nomad_deploy_jobs(names, **options)
|
|
494
521
|
end
|
495
522
|
|
496
523
|
def capistrano_nomad_restart_jobs(names, **options)
|
524
|
+
capistrano_nomad_ensure_options!(**options)
|
525
|
+
|
497
526
|
names.each do |name|
|
498
527
|
# Automatic yes to prompts. If set, the command automatically restarts multi-region jobs only in the region targeted
|
499
528
|
# by the command, ignores batch errors, and automatically proceeds with the remaining batches without waiting
|
@@ -502,27 +531,75 @@ def capistrano_nomad_restart_jobs(names, **options)
|
|
502
531
|
end
|
503
532
|
|
504
533
|
def capistrano_nomad_stop_jobs(names, **options)
|
534
|
+
capistrano_nomad_ensure_options!(**options)
|
535
|
+
|
505
536
|
names.each do |name|
|
506
537
|
capistrano_nomad_execute_nomad_command(:job, :stop, options, name)
|
507
538
|
end
|
508
539
|
end
|
509
540
|
|
510
|
-
def capistrano_nomad_purge_jobs(names,
|
541
|
+
def capistrano_nomad_purge_jobs(names, is_detached: true, **options)
|
542
|
+
capistrano_nomad_ensure_options!(**options)
|
543
|
+
|
544
|
+
names.each do |name|
|
545
|
+
capistrano_nomad_execute_nomad_command(:stop, options.reverse_merge(purge: true, detach: is_detached), name)
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
def capistrano_nomad_revert_jobs(names, version, docker_image: nil, **options)
|
550
|
+
capistrano_nomad_ensure_options!(**options)
|
551
|
+
versions_by_job_name = {}
|
552
|
+
|
511
553
|
names.each do |name|
|
512
|
-
|
554
|
+
history_output_json = capistrano_nomad_display_job_history(name, **options.reverse_merge(json: true))
|
555
|
+
history_output = JSON.parse(history_output_json)
|
556
|
+
|
557
|
+
versions_by_job_name[name] = if docker_image
|
558
|
+
# Find job history with matching docker image
|
559
|
+
docker_image_job_history = history_output.find do |job_history|
|
560
|
+
task_images = job_history.dig("TaskGroups")
|
561
|
+
.map { |g| g.dig("Tasks").map { |t| t.dig("Config", "image") } }
|
562
|
+
.flatten
|
563
|
+
.compact
|
564
|
+
|
565
|
+
task_images.any? { |image| image.include?(docker_image) }
|
566
|
+
end
|
567
|
+
|
568
|
+
unless docker_image_job_history
|
569
|
+
raise ArgumentError, "No job history found for job #{name} with docker image: #{docker_image}"
|
570
|
+
end
|
571
|
+
|
572
|
+
docker_image_job_history.dig("Version")
|
573
|
+
else
|
574
|
+
# If no version specified then revert to previous version
|
575
|
+
history_output[1].dig("Version")
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
versions_by_job_name.each do |name, version|
|
580
|
+
capistrano_nomad_execute_nomad_command(:job, :revert, options, name, version)
|
513
581
|
end
|
514
582
|
end
|
515
583
|
|
584
|
+
def capistrano_nomad_display_job_history(name, **options)
|
585
|
+
capistrano_nomad_ensure_options!(**options)
|
586
|
+
|
587
|
+
capistrano_nomad_capture_nomad_command(:job, :history, options, name)
|
588
|
+
end
|
589
|
+
|
516
590
|
def capistrano_nomad_display_job_status(name, **options)
|
591
|
+
capistrano_nomad_ensure_options!(**options)
|
592
|
+
|
517
593
|
capistrano_nomad_execute_nomad_command(:status, options, name)
|
518
594
|
end
|
519
595
|
|
520
|
-
def capistrano_nomad_display_job_logs(name,
|
521
|
-
if (task_details = capistrano_nomad_find_job_task_details(name,
|
596
|
+
def capistrano_nomad_display_job_logs(name, **options)
|
597
|
+
if (task_details = capistrano_nomad_find_job_task_details(name, **options.slice(:namespace).reverse_merge(task: ENV["TASK"])
|
598
|
+
))
|
522
599
|
capistrano_nomad_execute_nomad_command(
|
523
600
|
:alloc,
|
524
601
|
:logs,
|
525
|
-
options.
|
602
|
+
options.reverse_merge(task: task_details[:name]),
|
526
603
|
task_details[:alloc_id],
|
527
604
|
)
|
528
605
|
else
|
@@ -530,7 +607,7 @@ def capistrano_nomad_display_job_logs(name, namespace: :default, **options)
|
|
530
607
|
capistrano_nomad_execute_nomad_command(
|
531
608
|
:alloc,
|
532
609
|
:logs,
|
533
|
-
options.
|
610
|
+
options.reverse_merge(job: true),
|
534
611
|
name,
|
535
612
|
)
|
536
613
|
end
|
@@ -540,7 +617,7 @@ def capistrano_nomad_tail_job_logs(*args, **options)
|
|
540
617
|
capistrano_nomad_display_job_logs(*args, **options.merge(tail: true, n: 50))
|
541
618
|
end
|
542
619
|
|
543
|
-
def capistrano_nomad_open_job_ui(name, namespace:
|
620
|
+
def capistrano_nomad_open_job_ui(name, namespace: nil)
|
544
621
|
run_locally do
|
545
622
|
url = "#{fetch(:nomad_ui_url)}/ui/jobs/#{name}"
|
546
623
|
url += "@#{namespace}" if namespace
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-nomad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Hu
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|