capistrano-nomad 0.6.5 → 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/Gemfile.lock +1 -1
- data/README.md +24 -10
- data/capistrano-nomad.gemspec +1 -1
- data/lib/capistrano/nomad/helpers/base.rb +4 -0
- data/lib/capistrano/nomad/helpers/docker.rb +31 -11
- data/lib/capistrano/nomad/helpers/dsl.rb +11 -1
- data/lib/capistrano/nomad/helpers/nomad.rb +44 -32
- 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: eac8deb55e886ac97912499380a208f03ef15f7f952123afda2d6f8910e30df0
|
|
4
|
+
data.tar.gz: 730715ed63a01273775a7dccc403993866d73cb562de7cf70d0c22cf2754b493
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 933da9e873b7d6ed030983f0a441a157a4b2bac6c8803076a6dbeebb2bf3afeb922e57d5d3f5ba1b437f9da371386c9a09676d4e3f8dc32e68e3bfa86e5ae4b8
|
|
7
|
+
data.tar.gz: a87d69e22c6df4fcb9189a43279e399e27d9a625d1a86d728626fba63327daeed6a924113f019ed639d2782fae6db47367fbcd2568337faeafe9410ed3176b9f
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -48,24 +48,38 @@ end)
|
|
|
48
48
|
|
|
49
49
|
# Make helpers available to all template .erb files
|
|
50
50
|
nomad_template_helpers do
|
|
51
|
-
def restart_stanza
|
|
51
|
+
def restart_stanza(interval = "1m")
|
|
52
52
|
<<-EOF
|
|
53
|
-
|
|
53
|
+
restart {
|
|
54
|
+
interval = "#{interval}"
|
|
55
|
+
attempts = 3
|
|
56
|
+
mode = "delay"
|
|
57
|
+
}
|
|
54
58
|
EOF
|
|
55
59
|
end
|
|
56
60
|
end
|
|
57
61
|
|
|
58
|
-
# Docker image
|
|
62
|
+
# Use hosted Docker image
|
|
63
|
+
nomad_docker_image_type :postgres,
|
|
64
|
+
alias: "postgres:5.0.0"
|
|
65
|
+
|
|
66
|
+
# Use Docker image that will be built locally relative to project and push
|
|
59
67
|
nomad_docker_image_type :backend,
|
|
60
68
|
path: "local/path/backend",
|
|
61
69
|
alias: ->(image_type:) { "gcr.io/axsuul/#{image_type}" },
|
|
62
70
|
target: "release",
|
|
63
71
|
build_args: { foo: "bar" }
|
|
72
|
+
|
|
73
|
+
# Use Docker image that will be built locally from an absolute path and push
|
|
64
74
|
nomad_docker_image_type :redis,
|
|
65
75
|
path: "/absolute/path/redis",
|
|
66
76
|
alias: "gcr.io/axsuul/redis"
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
|
|
78
|
+
# Use Docker image that will be built remotely on server
|
|
79
|
+
nomad_docker_image_type :restic,
|
|
80
|
+
path: "containers/restic",
|
|
81
|
+
alias: "my-project/restic:local",
|
|
82
|
+
strategy: :remote_build
|
|
69
83
|
|
|
70
84
|
# Jobs
|
|
71
85
|
nomad_job :backend, docker_image_types: [:backend], var_files: [:rails]
|
|
@@ -80,20 +94,20 @@ nomad_namespace :analytics do
|
|
|
80
94
|
end
|
|
81
95
|
```
|
|
82
96
|
|
|
83
|
-
Deploy all
|
|
97
|
+
Deploy all jobs
|
|
84
98
|
|
|
85
99
|
```shell
|
|
86
100
|
cap production nomad:all:deploy
|
|
87
101
|
```
|
|
88
102
|
|
|
89
|
-
Deploy jobs
|
|
103
|
+
Deploy individual jobs
|
|
90
104
|
|
|
91
105
|
```shell
|
|
92
106
|
cap production nomad:app:deploy
|
|
93
107
|
cap production nomad:analytics:grafana:deploy
|
|
94
108
|
```
|
|
95
109
|
|
|
96
|
-
Manage jobs
|
|
110
|
+
Manage jobs
|
|
97
111
|
|
|
98
112
|
```shell
|
|
99
113
|
cap production nomad:app:stop
|
|
@@ -102,7 +116,7 @@ cap production nomad:analytics:grafana:restart
|
|
|
102
116
|
cap production nomad:postgres:status
|
|
103
117
|
```
|
|
104
118
|
|
|
105
|
-
Open console
|
|
119
|
+
Open console
|
|
106
120
|
|
|
107
121
|
```shell
|
|
108
122
|
cap production nomad:app:console
|
|
@@ -110,7 +124,7 @@ cap production nomad:app:console TASK=custom-task-name
|
|
|
110
124
|
cap production nomad:analytics:grafana:console
|
|
111
125
|
```
|
|
112
126
|
|
|
113
|
-
|
|
127
|
+
Display logs
|
|
114
128
|
|
|
115
129
|
```shell
|
|
116
130
|
cap production nomad:app:logs
|
data/capistrano-nomad.gemspec
CHANGED
|
@@ -21,7 +21,7 @@ end
|
|
|
21
21
|
def capistrano_nomad_read_docker_image_types_manifest
|
|
22
22
|
manifest = {}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
capistrano_nomad_run_remotely do
|
|
25
25
|
# Ensure file exists
|
|
26
26
|
execute("mkdir -p #{shared_path}")
|
|
27
27
|
execute("touch #{capistrano_nomad_docker_image_types_manifest_path}")
|
|
@@ -37,7 +37,7 @@ def capistrano_nomad_read_docker_image_types_manifest
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def capistrano_nomad_update_docker_image_types_manifest(image_type, properties = {})
|
|
40
|
-
|
|
40
|
+
capistrano_nomad_run_remotely do
|
|
41
41
|
# Read and update manifest
|
|
42
42
|
manifest = capistrano_nomad_read_docker_image_types_manifest
|
|
43
43
|
manifest[image_type] = (manifest[image_type] || {}).merge(properties.stringify_keys)
|
|
@@ -90,12 +90,7 @@ def capistrano_nomad_build_docker_image_for_type(image_type)
|
|
|
90
90
|
args << "--build-arg #{key}=#{value}"
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
# If any of these files exist then we're in the middle of rebase so we should interrupt
|
|
95
|
-
if ["rebase-merge", "rebase-apply"].any? { |f| File.exist?("#{capistrano_nomad_git.dir.path}/.git/#{f}") }
|
|
96
|
-
raise StandardError, "Still in the middle of git rebase, interrupting docker image build"
|
|
97
|
-
end
|
|
98
|
-
|
|
93
|
+
docker_build_command = lambda do |path|
|
|
99
94
|
image_alias_args = args.dup
|
|
100
95
|
|
|
101
96
|
[capistrano_nomad_build_docker_image_alias(image_type)]
|
|
@@ -104,7 +99,30 @@ def capistrano_nomad_build_docker_image_for_type(image_type)
|
|
|
104
99
|
image_alias_args << "--tag #{tag}"
|
|
105
100
|
end
|
|
106
101
|
|
|
107
|
-
|
|
102
|
+
"docker build #{image_alias_args.join(' ')} #{path}"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
case attributes[:strategy]
|
|
106
|
+
|
|
107
|
+
# We need to build Docker container locally
|
|
108
|
+
when :local_build, :local_push
|
|
109
|
+
run_locally do
|
|
110
|
+
# If any of these files exist then we're in the middle of rebase so we should interrupt
|
|
111
|
+
if ["rebase-merge", "rebase-apply"].any? { |f| File.exist?("#{capistrano_nomad_git.dir.path}/.git/#{f}") }
|
|
112
|
+
raise StandardError, "Still in the middle of git rebase, interrupting docker image build"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
execute(docker_build_command.call(capistrano_nomad_root.join(attributes[:path])))
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# We need to build Docker container remotely
|
|
119
|
+
when :remote_build, :remote_push
|
|
120
|
+
remote_path = Pathname.new(release_path).join(attributes[:path])
|
|
121
|
+
capistrano_nomad_upload(local_path: attributes[:path], remote_path: remote_path)
|
|
122
|
+
|
|
123
|
+
capistrano_nomad_run_remotely do
|
|
124
|
+
execute(docker_build_command.call(remote_path))
|
|
125
|
+
end
|
|
108
126
|
end
|
|
109
127
|
end
|
|
110
128
|
|
|
@@ -112,9 +130,11 @@ def capistrano_nomad_push_docker_image_for_type(image_type, is_manifest_updated:
|
|
|
112
130
|
attributes = fetch(:nomad_docker_image_types)[image_type]
|
|
113
131
|
alias_digest = attributes&.dig(:alias_digest)
|
|
114
132
|
|
|
133
|
+
return false unless [:local_push, :remote_push].include?(attributes[:strategy])
|
|
134
|
+
|
|
115
135
|
run_locally do
|
|
116
|
-
#
|
|
117
|
-
|
|
136
|
+
# Only push Docker image if it was built from path
|
|
137
|
+
if attributes[:path]
|
|
118
138
|
interaction_handler = CapistranoNomadDockerPushImageInteractionHandler.new
|
|
119
139
|
image_alias = capistrano_nomad_build_docker_image_alias(image_type)
|
|
120
140
|
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
+
require "active_support/core_ext/hash"
|
|
2
|
+
|
|
1
3
|
def nomad_docker_image_type(image_type, attributes = {})
|
|
2
4
|
docker_image_types = fetch(:nomad_docker_image_types) || {}
|
|
3
|
-
docker_image_types[image_type] = attributes
|
|
5
|
+
docker_image_types[image_type] = attributes.reverse_merge(
|
|
6
|
+
# By default build and push Docker image locally
|
|
7
|
+
strategy: :local_push,
|
|
8
|
+
)
|
|
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]
|
|
4
14
|
|
|
5
15
|
set(:nomad_docker_image_types, docker_image_types)
|
|
6
16
|
end
|
|
@@ -96,7 +96,7 @@ def capistrano_nomad_run_nomad_command(kind, *args)
|
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
def capistrano_nomad_execute_nomad_command(*args)
|
|
99
|
-
|
|
99
|
+
capistrano_nomad_run_remotely do |host|
|
|
100
100
|
run_interactively(host) do
|
|
101
101
|
capistrano_nomad_run_nomad_command(:execute, *args)
|
|
102
102
|
end
|
|
@@ -106,7 +106,7 @@ end
|
|
|
106
106
|
def capistrano_nomad_capture_nomad_command(*args)
|
|
107
107
|
output = nil
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
capistrano_nomad_run_remotely do
|
|
110
110
|
output = capistrano_nomad_run_nomad_command(:capture, *args)
|
|
111
111
|
end
|
|
112
112
|
|
|
@@ -152,7 +152,7 @@ def capistrano_nomad_find_job_task_details(name, namespace: nil, task: nil)
|
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
def capistrano_nomad_exec_within_job(name, command, namespace: nil, task: nil)
|
|
155
|
-
|
|
155
|
+
capistrano_nomad_run_remotely do
|
|
156
156
|
if (task_details = capistrano_nomad_find_job_task_details(name, namespace: namespace, task: task))
|
|
157
157
|
capistrano_nomad_execute_nomad_command(
|
|
158
158
|
:alloc,
|
|
@@ -174,40 +174,52 @@ def capistrano_nomad_exec_within_job(name, command, namespace: nil, task: nil)
|
|
|
174
174
|
end
|
|
175
175
|
end
|
|
176
176
|
|
|
177
|
-
def
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
def capistrano_nomad_upload(local_path:, remote_path:, erb_vars: {})
|
|
178
|
+
# If directory upload everything within the directory
|
|
179
|
+
if File.directory?(local_path)
|
|
180
|
+
Dir.glob("#{local_path}/*").each do |path|
|
|
181
|
+
capistrano_nomad_upload(local_path: path, remote_path: "#{remote_path}/#{File.basename(path)}")
|
|
182
|
+
end
|
|
180
183
|
|
|
181
|
-
#
|
|
182
|
-
|
|
183
|
-
docker_image_types
|
|
184
|
-
|
|
184
|
+
# If file, attempt to always parse it as ERB
|
|
185
|
+
else
|
|
186
|
+
docker_image_types = fetch(:nomad_docker_image_types)
|
|
187
|
+
docker_image_types_manifest = capistrano_nomad_read_docker_image_types_manifest
|
|
185
188
|
|
|
186
|
-
|
|
187
|
-
|
|
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
|
|
188
193
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
+
}
|
|
193
201
|
|
|
194
|
-
|
|
195
|
-
|
|
202
|
+
# Add global ERB vars
|
|
203
|
+
final_erb_vars.merge!(fetch(:nomad_template_vars) || {})
|
|
196
204
|
|
|
197
|
-
|
|
198
|
-
|
|
205
|
+
# Add job-specific ERB vars
|
|
206
|
+
final_erb_vars.merge!(erb_vars)
|
|
199
207
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
erb_io = StringIO.new(erb.result(namespace.instance_eval { binding }))
|
|
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
|
+
)
|
|
207
214
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
215
|
+
string_io = StringIO.new(erb.result(namespace.instance_eval { binding }))
|
|
216
|
+
|
|
217
|
+
capistrano_nomad_run_remotely do
|
|
218
|
+
# Ensure parent directory exists
|
|
219
|
+
execute(:mkdir, "-p", File.dirname(remote_path))
|
|
220
|
+
|
|
221
|
+
upload!(string_io, remote_path)
|
|
222
|
+
end
|
|
211
223
|
end
|
|
212
224
|
end
|
|
213
225
|
|
|
@@ -253,7 +265,7 @@ def capistrano_nomad_upload_jobs(names, *args)
|
|
|
253
265
|
uniq_var_files = names.map { |n| capistrano_nomad_fetch_job_var_files(n, *args) }.flatten.uniq
|
|
254
266
|
|
|
255
267
|
uniq_var_files.each do |var_file|
|
|
256
|
-
|
|
268
|
+
capistrano_nomad_upload(
|
|
257
269
|
local_path: capistrano_nomad_build_local_var_file_path(var_file, *args),
|
|
258
270
|
remote_path: capistrano_nomad_build_release_var_file_path(var_file, *args),
|
|
259
271
|
)
|
|
@@ -269,7 +281,7 @@ def capistrano_nomad_upload_jobs(names, *args)
|
|
|
269
281
|
# Can set a custom template instead
|
|
270
282
|
file_basename = nomad_job_options[:template] || name
|
|
271
283
|
|
|
272
|
-
|
|
284
|
+
capistrano_nomad_upload(
|
|
273
285
|
local_path: capistrano_nomad_build_local_job_path(file_basename, *args),
|
|
274
286
|
remote_path: capistrano_nomad_build_release_job_path(name, *args),
|
|
275
287
|
erb_vars: erb_vars,
|
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.7.1
|
|
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-
|
|
11
|
+
date: 2023-11-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|