orchestration 0.5.14 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,391 +0,0 @@
1
- ### Environment setup ###
2
- SHELL:=/bin/bash
3
-
4
- <%= macros %>
5
-
6
- ifdef env_file
7
- -include ${env_file}
8
- else
9
- ifneq (${env},test)
10
- ifeq (,$(findstring test,$(MAKECMDGOALS)))
11
- -include .env
12
- endif
13
- endif
14
- endif
15
-
16
- export
17
-
18
- ifneq (,$(env))
19
- # `env` set by current shell.
20
- else ifneq (,$(RAILS_ENV))
21
- env=$(RAILS_ENV)
22
- else ifneq (,$(RACK_ENV))
23
- env=$(RACK_ENV)
24
- else
25
- env=development
26
- endif
27
-
28
- DOCKER_TAG ?= latest
29
-
30
- ifneq (,$(wildcard ./Gemfile))
31
- rake=RACK_ENV=${env} RAILS_ENV=${env} bundle exec rake
32
- else
33
- rake=RACK_ENV=${env} RAILS_ENV=${env} rake
34
- endif
35
-
36
- ifneq (,$(wildcard ${env_file}))
37
- rake_cmd:=${rake}
38
- rake=. ${env_file} && ${rake_cmd}
39
- endif
40
-
41
- ifeq (,$(findstring serve,$(MAKECMDGOALS)))
42
- ifeq (,$(findstring console,$(MAKECMDGOALS)))
43
- ifeq (,$(findstring test,$(MAKECMDGOALS)))
44
- docker_config:=$(shell RAILS_ENV=development bundle exec rake orchestration:config)
45
- docker_organization=$(word 1,$(docker_config))
46
- docker_repository=$(word 2,$(docker_config))
47
- endif
48
- endif
49
- endif
50
-
51
- ifeq (,$(project_name))
52
- project_base = ${docker_repository}_${env}
53
- else
54
- project_base := $(project_name)
55
- endif
56
-
57
- ifeq (,$(findstring deploy,$(MAKECMDGOALS)))
58
- sidecar_suffix := $(shell test -f ${orchestration_dir}/.sidecar && cat ${orchestration_dir}/.sidecar)
59
- ifneq (,${sidecar_suffix})
60
- sidecar := 1
61
- endif
62
-
63
- ifdef sidecar
64
- # Set the variable to an empty string so that "#{sidecar-1234}" will
65
- # evaluate to "1234" in port mappings.
66
- sidecar_compose = sidecar=''
67
- ifeq (,${sidecar_suffix})
68
- sidecar_suffix := $(call token)
69
- _ignore := $(shell echo ${sidecar_suffix} > ${orchestration_dir}/.sidecar)
70
- endif
71
-
72
- ifeq (,${sidecar_suffix})
73
- $(warning Unable to generate project suffix; project name collisions may occur.)
74
- endif
75
- compose_project_name = ${project_base}_${sidecar_suffix}
76
- else
77
- compose_project_name = ${project_base}
78
- endif
79
- else
80
- compose_project_name = ${project_base}
81
- endif
82
-
83
- compose_base=env -i \
84
- PATH=$(PATH) \
85
- HOST_UID=$(shell id -u) \
86
- DOCKER_ORGANIZATION="${docker_organization}" \
87
- DOCKER_REPOSITORY="${docker_repository}" \
88
- COMPOSE_PROJECT_NAME="${compose_project_name}" \
89
- ${sidecar_compose} \
90
- docker-compose \
91
- -f ${orchestration_dir}/docker-compose.${env}.yml
92
-
93
- git_branch ?= $(if $(branch),$(branch),$(shell git rev-parse --abbrev-ref HEAD))
94
- ifndef dev
95
- git_version ?= $(shell git rev-parse --short --verify ${git_branch})
96
- else
97
- git_version = dev
98
- endif
99
-
100
- docker_image=${docker_organization}/${docker_repository}:${git_version}
101
-
102
- compose=${compose_base}
103
- random_str=cat /dev/urandom | LC_ALL=C tr -dc 'a-z' | head -c $1
104
-
105
- ifneq (,$(wildcard ${orchestration_dir}/docker-compose.local.yml))
106
- compose:=${compose} -f ${orchestration_dir}/docker-compose.local.yml
107
- endif
108
-
109
- all: build
110
-
111
- ### Container management commands ###
112
-
113
- .PHONY: start
114
- ifndef network
115
- start: network := ${compose_project_name}
116
- endif
117
- start: _create-log-directory _clean-logs
118
- @$(call print,'${yellow}Starting ${cyan}${env}${yellow} containers${reset} ...')
119
- ifeq (${env},$(filter ${env},test development))
120
- @${compose} up --detach --force-recreate --renew-anon-volumes --remove-orphans ${services} ${log} || ${fail}
121
- @[ -n '${sidecar}' ] && \
122
- ( \
123
- $(call printraw,' ${yellow}(joining dependency network ${green}${network}${yellow})${reset} ... ') ; \
124
- docker network connect '${network}' '$(shell hostname)' ${log} \
125
- || ( \
126
- $(call println,'') ; \
127
- $(call println,'${yellow}Warning${reset}: Unable to join network: "${yellow}${network}${reset}". Container will not be able to connect to dependency services.') ; \
128
- $(call print,'You may need to delete "${yellow}orchestration/.sidecar${reset}" to disable sidecar mode if this file was added by mistake.\n...') ; \
129
- ) \
130
- ) \
131
- || ( [ -z '${sidecar}' ] || ${fail} )
132
- else
133
- @${compose} up --detach --scale app=$${instances:-1} ${log} || ${fail}
134
- endif
135
- @$(call printrawln,' ${green}started${reset} ${tick}')
136
- @$(call println,'${yellow}Waiting for services to become available${reset} ...')
137
- @$(call make,wait) 2>${stderr} || ${fail}
138
-
139
- <% services.each do |service| %>
140
- .PHONY: start-<%= service %>
141
- start-<%= service %>:
142
- @$(call make,start services='<%= service %>')
143
-
144
- <% end %>
145
-
146
- .PHONY: stop
147
- stop: network := ${compose_project_name}
148
- stop:
149
- @$(call print,'${yellow}Stopping ${cyan}${env}${yellow} containers${reset} ...')
150
- @if docker ps --format "{{.ID}}" | grep -q $(shell hostname) ; \
151
- then \
152
- ( docker network disconnect ${network} $(shell hostname) ${log} || : ) \
153
- && \
154
- ( ${compose} down ${log} || ${fail} ) ; \
155
- else \
156
- ${compose} down ${log} || ${fail} ; \
157
- fi
158
- @$(call printrawln,' ${green}stopped${reset}. ${tick}')
159
-
160
- .PHONY: logs
161
- logs:
162
- @${compose} logs -f
163
-
164
- .PHONY: config
165
- config:
166
- @${compose} config
167
-
168
- .PHONY: compose
169
- compose:
170
- @echo ${compose}
171
-
172
- ### Development/Test Utility Commands
173
-
174
- .PHONY: serve
175
- serve: env_file ?= ./.env
176
- serve: rails = RAILS_ENV='${env}' bundle exec rails server ${server}
177
- serve:
178
- @if [ -f "${env_file}" ] ; \
179
- then ( \
180
- $(call println,'${yellow}Environment${reset}: ${green}${env_file}${reset}') && \
181
- cat '${env_file}' | ${format_env} && \
182
- $(call printrawln,'') \
183
- ) ; \
184
- fi
185
- ${rails}
186
-
187
- .PHONY: console
188
- console: env_file ?= ./.env
189
- console: rails = RAILS_ENV='${env}' bundle exec rails
190
- console:
191
- @if [ -f "${env_file}" ] ; \
192
- then ( \
193
- $(call println,'${yellow}Environment${reset}: ${green}${env_file}${reset}') && \
194
- cat '${env_file}' | ${format_env} && \
195
- $(call printrawln,'') \
196
- ) ; \
197
- fi
198
- ${rails} console
199
-
200
- .PHONY: test-setup
201
- test-setup: env := test
202
- test-setup:
203
- ifndef light
204
- @$(call make,start env=test)
205
- ifneq (,$(wildcard config/database.yml))
206
- ${rake} db:create || :
207
- ifneq (,$(wildcard db/structure.sql))
208
- ${rake} db:structure:load
209
- else ifneq (,$(wildcard db/schema.rb))
210
- ${rake} db:schema:load
211
- endif
212
-
213
- ${rake} db:migrate
214
- endif
215
- endif
216
-
217
- .PHONY: dump
218
- dump:
219
- ifndef verbose
220
- @$(call println)
221
- @$(call println,'${yellow}Captured${reset} ${green}stdout${reset} ${yellow}and${reset} ${red}stderr${reset} ${yellow}log data [${cyan}${env}${yellow}]${reset}:')
222
- @$(call println)
223
- @echo
224
- @test -f '${stdout}' && ( \
225
- $(call hr,${green}) ; \
226
- $(call println,'${gray}${stdout}${reset}') ; \
227
- $(call hr,${green}) ; \
228
- echo ; cat '${stdout}' ; echo ; \
229
- $(call hr,${green}) ; \
230
- )
231
-
232
- @test -f '${stdout}' && ( \
233
- echo ; \
234
- $(call hr,${red}) ; \
235
- $(call println,'${gray}${stderr}${reset}') ; \
236
- $(call hr,${red}) ; \
237
- echo ; cat '${stderr}' ; echo ; \
238
- $(call hr,${red}) ; \
239
- )
240
- endif
241
- @echo ; \
242
- $(call hr,${yellow}) ; \
243
- $(call println,'${gray}docker-compose logs${reset}') ; \
244
- $(call hr,${yellow}) ; \
245
- echo
246
- @${compose} logs
247
- @echo ; \
248
- $(call hr,${yellow})
249
- @$(NOOP)
250
-
251
- .PHONY: image
252
- image:
253
- @echo ${docker_image}
254
-
255
- ### Deployment utility commands ###
256
-
257
- .PHONY: deploy
258
- ifdef env_file
259
- deploy: env_file_option = --env-file ${env_file}
260
- endif
261
- deploy: RAILS_ENV := ${env}
262
- deploy: RACK_ENV := ${env}
263
- deploy: DOCKER_TAG = ${git_version}
264
- deploy: base_vars = DOCKER_ORGANIZATION=${docker_organization} DOCKER_REPOSITORY=${docker_repository} DOCKER_TAG=${git_version}
265
- deploy: compose_deploy := ${base_vars} COMPOSE_PROJECT_NAME=${project_base} HOST_UID=$(shell id -u) docker-compose ${env_file_option} --project-name ${project_base} -f orchestration/docker-compose.production.yml
266
- deploy: compose_config := ${compose_deploy} config
267
- deploy: deploy_cmd := echo "$${config}" | ssh "${manager}" "/bin/bash -lc 'cat | docker stack deploy --prune --with-registry-auth -c - ${project_base}'"
268
- deploy: out_of_sequence_error := rpc error: code = Unknown desc = update out of sequence
269
- deploy: retry_message := ${yellow}Detected Docker RPC error: ${red}${out_of_sequence_error}${yellow}. Retrying in
270
- deploy:
271
- ifndef manager
272
- @$(call println_error,'Missing `manager` parameter: `make deploy manager=swarm-manager.example.com`') ; exit 1
273
- endif
274
- @$(call println,'${yellow}Deploying ${green}${env} ${yellow}stack via ${green}${manager} ${yellow}as ${green}${project_base}${reset} ...') && \
275
- ( \
276
- $(call println,'${yellow}Deployment environment${reset}:') && \
277
- ( test -f '${env_file}' && cat '${env_file}' | ${format_env} || : ) && \
278
- $(call println,'') && \
279
- $(call println,'${yellow}Application image${reset}: ${cyan}${docker_image}${reset}') && \
280
- export config="$$(${compose_config} 2>${stderr})" ; \
281
- config_exit_code=$$? ; \
282
- if [[ "$${config_exit_code}" != "0" ]]; then exit ${config_exit_code}; fi ; \
283
- output="$$(${deploy_cmd} | tee)" ; \
284
- deploy_exit_code=$$? ; \
285
- if [[ "$${deploy_exit_code}" == 0 ]] ; then exit 0 ; fi ; \
286
- if ! echo "$${output}" | grep -q '${out_of_sequence_error}' ; then exit ${deploy_exit_code} ; fi ; \
287
- retry_in="$$(( 10 + RANDOM % 50 ))" ; \
288
- echo "${retry_message} ${green}$${retry_in} ${yellow}seconds.${reset}" ; \
289
- sleep "$${retry_in}" ; \
290
- ${deploy_cmd} \
291
- ) \
292
- || ${fail}
293
-
294
- @$(call println,'${yellow}Deployment${reset} ${green}complete${reset}. ${tick}')
295
-
296
- .PHONY: rollback
297
- ifndef service
298
- rollback: service = app
299
- endif
300
- rollback:
301
- ifndef manager
302
- @$(call println_error,'Missing `manager` parameter: `make deploy manager=swarm-manager.example.com`') ; exit 1
303
- endif
304
- @$(call println,'${yellow}Rolling back${reset} ${green}${compose_project_name}_${service}${reset} ${yellow}via${reset} ${green}${manager}${reset} ...')
305
- @ssh "${manager}" 'docker service rollback --detach "${compose_project_name}_${service}"' ${log} || ${fail}
306
- @$(call println,'${yellow}Rollback request${reset} ${green}complete${reset}. ${tick}')
307
-
308
- ### Service healthcheck commands ###
309
-
310
- .PHONY: wait
311
- wait:
312
- @${rake} orchestration:wait
313
- @$(call println,'${yellow}All services${reset} ${green}ready${reset}. ${tick}')
314
-
315
- ## Generic Listener healthcheck for TCP services ##
316
-
317
- wait-listener:
318
- @${rake} orchestration:listener:wait service=${service} sidecar=${sidecar}
319
-
320
- ### Docker build commands ###
321
-
322
- .PHONY: build
323
- build: build_dir = ${orchestration_dir}/.build
324
- build: context = ${build_dir}/context.tar
325
- build: _create-log-directory check-local-changes
326
- @$(call print,'${yellow}Preparing build context from${reset} ${cyan}${git_branch}:${git_version}${reset} ... ')
327
- @mkdir -p ${orchestration_dir}/.build ${log} || ${fail}
328
- ifndef dev
329
- @git show ${git_branch}:./Gemfile > ${orchestration_dir}/.build/Gemfile 2>${stderr} || ${fail}
330
- @git show ${git_branch}:./Gemfile.lock > ${orchestration_dir}/.build/Gemfile.lock 2>${stderr} || ${fail}
331
- <% if defined?(Webpacker) %> @git show ${git_branch}:./package.json > ${orchestration_dir}/.build/package.json 2>${stderr} || ${fail}<% end %>
332
- <% if defined?(Webpacker) %> @git show ${git_branch}:./yarn.lock > ${orchestration_dir}/.build/yarn.lock 2>${stderr} || ${fail}<% end %>
333
- @git archive --format 'tar' -o '${context}' '${git_branch}' ${log} || ${fail}
334
- else
335
- @tar -cvf '${context}' . ${log} || ${fail}
336
- endif
337
- @$(call printrawln,'${green}complete.${reset} ${tick}')
338
- ifdef include
339
- @$(call print,'${yellow}Including files from:${reset} ${cyan}${include}${reset} ...')
340
- @(while read line; do \
341
- export line; \
342
- include_dir="${build_dir}/$$(dirname "$${line}")/" && \
343
- mkdir -p "$${include_dir}" && cp "$${line}" "$${include_dir}" \
344
- && (cd '${orchestration_dir}/.build/' && tar rf 'context.tar' "$${line}"); \
345
- done < '${include}') ${log} || ${fail}
346
- @$(call printrawln,' ${green}complete.${reset} ${tick}')
347
- endif
348
- ifdef sidecar
349
- # Assume we are in a line-buffered environment (e.g. Jenkins)
350
- @$(call println,'${yellow}Building image${reset} ...')
351
- else
352
- @$(call print,'${yellow}Building image${reset} ...')
353
- endif
354
- @docker build \
355
- --build-arg BUNDLE_GITHUB__COM \
356
- --build-arg BUNDLE_BITBUCKET__ORG \
357
- --build-arg GIT_COMMIT='${git_version}' \
358
- -t ${docker_organization}/${docker_repository} \
359
- -t ${docker_organization}/${docker_repository}:${git_version} \
360
- ${orchestration_dir}/ ${log_progress} || ${fail}
361
- @$(call printrawln,' ${green}complete${reset}. ${tick}')
362
- @$(call println,'[${green}tag${reset}] ${cyan}${docker_organization}/${docker_repository}${reset}')
363
- @$(call println,'[${green}tag${reset}] ${cyan}${docker_organization}/${docker_repository}:${git_version}${reset}')
364
-
365
- .PHONY: push
366
- push: _create-log-directory
367
- @$(call print,'${yellow}Pushing${reset} ${cyan}${docker_image}${reset} ...')
368
- @docker push ${docker_image} ${log_progress} || ${fail}
369
- @$(call printrawln,' ${green}complete${reset}. ${tick}')
370
-
371
- .PHONY: check-local-changes
372
- check-local-changes:
373
- ifndef dev
374
- @if [[ ! -z "$$(git status --porcelain)" ]] ; \
375
- then \
376
- $(call println,'${red}You have uncommitted changes which will not be included in your build:${reset}') ; \
377
- git status --porcelain ; \
378
- $(call println,'${yellow}Use ${cyan}make build dev=1${reset} ${yellow}to include these files.${reset}\n') ; \
379
- fi
380
- endif
381
-
382
- ### Internal Commands ###
383
- #
384
- .PHONY: _clean-logs
385
- _clean-logs:
386
- @rm -f '${stdout}' '${stderr}'
387
- @touch '${stdout}' '${stderr}'
388
-
389
- .PHONY: _create-log-directory
390
- _create-log-directory:
391
- @mkdir -p log