capistrano-nomad 0.6.5 → 0.7.1
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 +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
|