capistrano-nomad 0.7.0 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +14 -1
- data/capistrano-nomad.gemspec +1 -1
- data/lib/capistrano/nomad/helpers/docker.rb +4 -4
- data/lib/capistrano/nomad/helpers/dsl.rb +16 -4
- data/lib/capistrano/nomad/helpers/nomad.rb +72 -42
- data/lib/capistrano/nomad.rb +1 -0
- 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: '02685bbf3f2ad3d0bc5dbc45b33f31622ddbe9a465671381645bd665266cf4aa'
|
4
|
+
data.tar.gz: 6f386d0642e4cd00f66e5dc0ddefdb3815d537d254525e130717251d7407a56d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c7a4c7173a08c5ef7bc7207a5e3500864a1f85171a4a324342bf0ed6bdfda3b7bce2ba3db147440476db96513f1ab0b9af7458c59fee7bd8c4f6996686acc69
|
7
|
+
data.tar.gz: f6d8b9affa00bea01d56a6ef3c067d80a6596c7881b8f4893c4b16e17fd5f2d0030128dfa0f0de4dce6cd908e29013ca088d61a26df5897fe97bebf6aa215d7d
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -37,6 +37,9 @@ 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
|
41
|
+
set :nomad_ui_url, "http://localhost:4646"
|
42
|
+
|
40
43
|
# Make variables available to all template .erb files
|
41
44
|
set :nomad_template_vars, (lambda do
|
42
45
|
{
|
@@ -61,7 +64,7 @@ end
|
|
61
64
|
|
62
65
|
# Use hosted Docker image
|
63
66
|
nomad_docker_image_type :postgres,
|
64
|
-
|
67
|
+
alias: "postgres:5.0.0"
|
65
68
|
|
66
69
|
# Use Docker image that will be built locally relative to project and push
|
67
70
|
nomad_docker_image_type :backend,
|
@@ -92,6 +95,10 @@ nomad_job :"traefik-secondary", template: :traefik, erb_vars: { role: :secondary
|
|
92
95
|
nomad_namespace :analytics do
|
93
96
|
nomad_job :grafana
|
94
97
|
end
|
98
|
+
|
99
|
+
nomad_namespace :maintenance, path: "maintenance-stuff" do
|
100
|
+
nomad_job :garbage_collection
|
101
|
+
end
|
95
102
|
```
|
96
103
|
|
97
104
|
Deploy all jobs
|
@@ -133,6 +140,12 @@ cap production nomad:app:stderr
|
|
133
140
|
cap production nomad:analytics:grafana:follow
|
134
141
|
```
|
135
142
|
|
143
|
+
Open job in web UI
|
144
|
+
|
145
|
+
```shell
|
146
|
+
cap production nomad:app:ui
|
147
|
+
```
|
148
|
+
|
136
149
|
Create missing and delete unused namespaces
|
137
150
|
|
138
151
|
```shell
|
data/capistrano-nomad.gemspec
CHANGED
@@ -23,8 +23,8 @@ def capistrano_nomad_read_docker_image_types_manifest
|
|
23
23
|
|
24
24
|
capistrano_nomad_run_remotely do
|
25
25
|
# Ensure file exists
|
26
|
-
execute("mkdir -p
|
27
|
-
execute("touch
|
26
|
+
execute("mkdir", "-p", shared_path)
|
27
|
+
execute("touch", capistrano_nomad_docker_image_types_manifest_path)
|
28
28
|
|
29
29
|
output = capture("cat #{capistrano_nomad_docker_image_types_manifest_path}")
|
30
30
|
|
@@ -133,8 +133,8 @@ def capistrano_nomad_push_docker_image_for_type(image_type, is_manifest_updated:
|
|
133
133
|
return false unless [:local_push, :remote_push].include?(attributes[:strategy])
|
134
134
|
|
135
135
|
run_locally do
|
136
|
-
#
|
137
|
-
|
136
|
+
# Only push Docker image if it was built from path
|
137
|
+
if attributes[:path]
|
138
138
|
interaction_handler = CapistranoNomadDockerPushImageInteractionHandler.new
|
139
139
|
image_alias = capistrano_nomad_build_docker_image_alias(image_type)
|
140
140
|
|
@@ -3,17 +3,24 @@ require "active_support/core_ext/hash"
|
|
3
3
|
def nomad_docker_image_type(image_type, attributes = {})
|
4
4
|
docker_image_types = fetch(:nomad_docker_image_types) || {}
|
5
5
|
docker_image_types[image_type] = attributes.reverse_merge(
|
6
|
-
# In case image doesn't get pushed, this will still be populated
|
7
|
-
alias_digest: attributes[:alias],
|
8
|
-
|
9
6
|
# By default build and push Docker image locally
|
10
7
|
strategy: :local_push,
|
11
8
|
)
|
12
9
|
|
10
|
+
raise ArgumentError, "passing in alias_digest is not allowed!" if attributes[:alias_digest]
|
11
|
+
|
12
|
+
# If Docker image doesn't get pushed, this will still be populated
|
13
|
+
docker_image_types[image_type][:alias_digest] = attributes[:alias]
|
14
|
+
|
13
15
|
set(:nomad_docker_image_types, docker_image_types)
|
14
16
|
end
|
15
17
|
|
16
|
-
def nomad_namespace(namespace, &block)
|
18
|
+
def nomad_namespace(namespace, **options, &block)
|
19
|
+
nomad_namespaces = fetch(:nomad_namespaces) || {}
|
20
|
+
nomad_namespaces[namespace] = options
|
21
|
+
set(:nomad_namespaces, nomad_namespaces)
|
22
|
+
|
23
|
+
# Make namespace active for block
|
17
24
|
@nomad_namespace = namespace
|
18
25
|
|
19
26
|
instance_eval(&block)
|
@@ -133,6 +140,11 @@ def nomad_job(name, attributes = {})
|
|
133
140
|
task :follow do
|
134
141
|
capistrano_nomad_display_job_logs(name, namespace: namespace, f: true)
|
135
142
|
end
|
143
|
+
|
144
|
+
desc "Open job in web UI"
|
145
|
+
task :ui do
|
146
|
+
capistrano_nomad_open_job_ui(name, namespace: namespace)
|
147
|
+
end
|
136
148
|
end
|
137
149
|
end
|
138
150
|
|
@@ -29,9 +29,24 @@ 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, namespace: nil)
|
32
|
+
def capistrano_nomad_build_file_path(parent_path, basename, kind: nil, namespace: nil)
|
33
33
|
segments = [parent_path]
|
34
|
-
|
34
|
+
|
35
|
+
if namespace
|
36
|
+
case kind
|
37
|
+
|
38
|
+
# Always upload to namespace folder on remote
|
39
|
+
when :release
|
40
|
+
segments << namespace
|
41
|
+
|
42
|
+
# Otherwise path can be overriden of where files belonging to namespace are stored locally
|
43
|
+
else
|
44
|
+
namespace_options = capistrano_nomad_fetch_namespace_options(namespace)
|
45
|
+
|
46
|
+
segments << (namespace_options[:path] || namespace)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
35
50
|
segments << "#{basename}.hcl"
|
36
51
|
|
37
52
|
segments.join("/")
|
@@ -64,12 +79,16 @@ def capistrano_nomad_build_local_var_file_path(name, *args)
|
|
64
79
|
capistrano_nomad_build_local_path(capistrano_nomad_build_base_var_file_path(name, *args))
|
65
80
|
end
|
66
81
|
|
67
|
-
def capistrano_nomad_build_release_job_path(
|
68
|
-
|
82
|
+
def capistrano_nomad_build_release_job_path(name, **options)
|
83
|
+
options[:kind] = :release
|
84
|
+
|
85
|
+
"#{release_path}#{capistrano_nomad_ensure_absolute_path(capistrano_nomad_build_base_job_path(name, **options))}"
|
69
86
|
end
|
70
87
|
|
71
|
-
def capistrano_nomad_build_release_var_file_path(
|
72
|
-
|
88
|
+
def capistrano_nomad_build_release_var_file_path(name, **options)
|
89
|
+
options[:kind] = :release
|
90
|
+
|
91
|
+
"#{release_path}#{capistrano_nomad_ensure_absolute_path(capistrano_nomad_build_base_var_file_path(name, **options))}"
|
73
92
|
end
|
74
93
|
|
75
94
|
def capistrano_nomad_run_nomad_command(kind, *args)
|
@@ -180,52 +199,53 @@ def capistrano_nomad_upload(local_path:, remote_path:, erb_vars: {})
|
|
180
199
|
Dir.glob("#{local_path}/*").each do |path|
|
181
200
|
capistrano_nomad_upload(local_path: path, remote_path: "#{remote_path}/#{File.basename(path)}")
|
182
201
|
end
|
202
|
+
|
203
|
+
# If file, attempt to always parse it as ERB
|
183
204
|
else
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
StringIO.new(erb.result(namespace.instance_eval { binding }))
|
216
|
-
else
|
217
|
-
File.open(local_path)
|
218
|
-
end
|
205
|
+
docker_image_types = fetch(:nomad_docker_image_types)
|
206
|
+
docker_image_types_manifest = capistrano_nomad_read_docker_image_types_manifest
|
207
|
+
|
208
|
+
# Merge manifest into image types
|
209
|
+
docker_image_types_manifest.each do |manifest_image_type, manifest_attributes|
|
210
|
+
docker_image_types[manifest_image_type]&.merge!(manifest_attributes) || {}
|
211
|
+
end
|
212
|
+
|
213
|
+
# Parse manifest files using ERB
|
214
|
+
erb = ERB.new(File.open(local_path).read, trim_mode: "-")
|
215
|
+
|
216
|
+
final_erb_vars = {
|
217
|
+
git_commit_id: fetch(:current_revision) || capistrano_nomad_git_commit_id,
|
218
|
+
docker_image_types: docker_image_types,
|
219
|
+
}
|
220
|
+
|
221
|
+
# Add global ERB vars
|
222
|
+
final_erb_vars.merge!(fetch(:nomad_template_vars) || {})
|
223
|
+
|
224
|
+
# Add job-specific ERB vars
|
225
|
+
final_erb_vars.merge!(erb_vars)
|
226
|
+
|
227
|
+
# We use a custom namespace class so that we can include helper methods into the namespace to make them available
|
228
|
+
# for template to access
|
229
|
+
namespace = CapistranoNomadErbNamespace.new(
|
230
|
+
context: self,
|
231
|
+
vars: final_erb_vars,
|
232
|
+
)
|
233
|
+
|
234
|
+
string_io = StringIO.new(erb.result(namespace.instance_eval { binding }))
|
219
235
|
|
220
236
|
capistrano_nomad_run_remotely do
|
221
237
|
# Ensure parent directory exists
|
222
238
|
execute(:mkdir, "-p", File.dirname(remote_path))
|
223
239
|
|
224
|
-
upload!(
|
240
|
+
upload!(string_io, remote_path)
|
225
241
|
end
|
226
242
|
end
|
227
243
|
end
|
228
244
|
|
245
|
+
def capistrano_nomad_fetch_namespace_options(namespace)
|
246
|
+
fetch(:nomad_namespaces).dig(namespace)
|
247
|
+
end
|
248
|
+
|
229
249
|
def capistrano_nomad_fetch_job_options(name, *args, namespace: nil)
|
230
250
|
fetch(:nomad_jobs).dig(namespace, name.to_sym, *args)
|
231
251
|
end
|
@@ -405,3 +425,13 @@ end
|
|
405
425
|
def capistrano_nomad_tail_job_logs(*args, **options)
|
406
426
|
capistrano_nomad_display_job_logs(*args, **options.merge(tail: true, n: 50))
|
407
427
|
end
|
428
|
+
|
429
|
+
def capistrano_nomad_open_job_ui(name, namespace: nil)
|
430
|
+
run_locally do
|
431
|
+
url = "#{fetch(:nomad_ui_url)}/ui/jobs/#{name}"
|
432
|
+
url += "@#{namespace}" if namespace
|
433
|
+
|
434
|
+
# Only macOS supported for now
|
435
|
+
execute(:open, url)
|
436
|
+
end
|
437
|
+
end
|
data/lib/capistrano/nomad.rb
CHANGED
@@ -11,6 +11,7 @@ module Capistrano
|
|
11
11
|
def set_defaults
|
12
12
|
set_if_empty(:nomad_jobs_path, "nomad/jobs")
|
13
13
|
set_if_empty(:nomad_var_files_path, "nomad/var_files")
|
14
|
+
set_if_empty(:nomad_ui_url, "http://localhost:4646")
|
14
15
|
set_if_empty(:nomad_docker_image_alias, ->(**) {})
|
15
16
|
end
|
16
17
|
|
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.7.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Hu
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|