capistrano-nomad 0.7.0 → 0.7.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d227d6f15f433cd6410884afc5572cf9c7e115a7365e00e244d3b95ca320f148
4
- data.tar.gz: a0cdd0e131319cd0f1a17a926afe70619d24550018de9731c96a610b075300c2
3
+ metadata.gz: '02685bbf3f2ad3d0bc5dbc45b33f31622ddbe9a465671381645bd665266cf4aa'
4
+ data.tar.gz: 6f386d0642e4cd00f66e5dc0ddefdb3815d537d254525e130717251d7407a56d
5
5
  SHA512:
6
- metadata.gz: fd4aec6aecd6698d4ed23d4e1a2c3d3e8ded18467c1a4d8daee191e29304e2f91f85ca7d604681dba4ec6cb885308f0fb6985fb4e9d952e459fc7859a3b3917a
7
- data.tar.gz: 6009d60f5bd99e35fdb2961f6b9d860ea9db40ac844cebacf87b21ae58381eeefd35022fb58c7a6b88fa74da7e3acff3ee26a0f9a71a92e1b61495102bf53a21
6
+ metadata.gz: 5c7a4c7173a08c5ef7bc7207a5e3500864a1f85171a4a324342bf0ed6bdfda3b7bce2ba3db147440476db96513f1ab0b9af7458c59fee7bd8c4f6996686acc69
7
+ data.tar.gz: f6d8b9affa00bea01d56a6ef3c067d80a6596c7881b8f4893c4b16e17fd5f2d0030128dfa0f0de4dce6cd908e29013ca088d61a26df5897fe97bebf6aa215d7d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- capistrano-nomad (0.7.0)
4
+ capistrano-nomad (0.7.2)
5
5
  activesupport (<= 7.0.8)
6
6
  byebug
7
7
  capistrano (~> 3.0)
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
- alias_digest: "postgres:5.0.0"
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "capistrano-nomad"
5
- spec.version = "0.7.0"
5
+ spec.version = "0.7.2"
6
6
  spec.authors = ["James Hu"]
7
7
 
8
8
  spec.summary = "Capistrano plugin for deploying and managing Nomad jobs"
@@ -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 #{shared_path}")
27
- execute("touch #{capistrano_nomad_docker_image_types_manifest_path}")
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
- # Don't push Docker image if alias digest is already passed in
137
- unless alias_digest
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
- segments << namespace if namespace
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(*args)
68
- "#{release_path}#{capistrano_nomad_ensure_absolute_path(capistrano_nomad_build_base_job_path(*args))}"
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(*args)
72
- "#{release_path}#{capistrano_nomad_ensure_absolute_path(capistrano_nomad_build_base_var_file_path(*args))}"
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
- io =
185
- if File.extname(local_path) == ".erb"
186
- docker_image_types = fetch(:nomad_docker_image_types)
187
- docker_image_types_manifest = capistrano_nomad_read_docker_image_types_manifest
188
-
189
- # Merge manifest into image types
190
- docker_image_types_manifest.each do |manifest_image_type, manifest_attributes|
191
- docker_image_types[manifest_image_type]&.merge!(manifest_attributes) || {}
192
- end
193
-
194
- # Parse manifest files using ERB
195
- erb = ERB.new(File.open(local_path).read, trim_mode: "-")
196
-
197
- final_erb_vars = {
198
- git_commit_id: fetch(:current_revision) || capistrano_nomad_git_commit_id,
199
- docker_image_types: docker_image_types,
200
- }
201
-
202
- # Add global ERB vars
203
- final_erb_vars.merge!(fetch(:nomad_template_vars) || {})
204
-
205
- # Add job-specific ERB vars
206
- final_erb_vars.merge!(erb_vars)
207
-
208
- # We use a custom namespace class so that we can include helper methods into the namespace to make them available
209
- # for template to access
210
- namespace = CapistranoNomadErbNamespace.new(
211
- context: self,
212
- vars: final_erb_vars,
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!(io, remote_path)
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
@@ -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.0
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-20 00:00:00.000000000 Z
11
+ date: 2023-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport