orchestration 0.5.13 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,112 +0,0 @@
1
- TERM ?= 'dumb'
2
- pwd:=$(shell pwd)
3
- ifdef mounted_orchestration
4
- orchestration_dir=$(mounted_orchestration)
5
- else
6
- orchestration_dir=${pwd}/<%= env.orchestration_dir_name %>
7
- endif
8
-
9
- ifdef env_file
10
- custom_env_file ?= 1
11
- else
12
- custom_env_file ?= 0
13
- endif
14
-
15
- ifneq (,$(wildcard ${pwd}/config/database.yml))
16
- database_enabled = 1
17
- else
18
- database_enabled = 0
19
- endif
20
-
21
- make=$(MAKE) $1
22
- orchestration_config_filename:=.orchestration.yml
23
- orchestration_config:=${pwd}/${orchestration_config_filename}
24
- print_error=printf '${red}\#${reset} '$1 | tee '${stderr}'
25
- println_error=$(call print_error,$1'\n')
26
- print=printf '${blue}\#${reset} '$1
27
- println=$(call print,$1'\n')
28
- printraw=printf $1
29
- printrawln=$(call printraw,$1'\n')
30
- stdout=${pwd}/log/orchestration.stdout.log
31
- stderr=${pwd}/log/orchestration.stderr.log
32
- log_path_length=$(shell echo "${stdout}" | wc -c)
33
- ifndef verbose
34
- log_tee:= 2>&1 | tee -a ${stdout}
35
- log:= >>${stdout} 2>>${stderr}
36
- progress_point:=perl -e 'while( my $$line = <STDIN> ) { printf("."); select()->flush(); }'
37
- log_progress:= > >(tee -ai ${stdout} >&1 | ${progress_point}) 2> >(tee -ai ${stderr} 2>&1 | ${progress_point})
38
- endif
39
- red:=$(shell tput setaf 1)
40
- green:=$(shell tput setaf 2)
41
- yellow:=$(shell tput setaf 3)
42
- blue:=$(shell tput setaf 4)
43
- magenta:=$(shell tput setaf 5)
44
- cyan:=$(shell tput setaf 6)
45
- gray:=$(shell tput setaf 7)
46
- reset:=$(shell tput sgr0)
47
- tick=[${green}✓${reset}]
48
- cross=[${red}✘${reset}]
49
- warn=[${yellow}!${reset}]
50
- hr=$(call println,"$1$(shell head -c ${log_path_length} < /dev/zero | tr '\0' '=')${reset}")
51
- managed_env_tag:=\# -|- ORCHESTRATION
52
- standard_env_path:=${pwd}/.env
53
- backup_env_path:=${pwd}/.env.orchestration.backup
54
- is_managed_env:=$$(test -f '${standard_env_path}' && tail -n 1 '${standard_env_path}') == "${managed_env_tag}"*
55
- token:=$(shell cat /dev/urandom | LC_CTYPE=C tr -dc 'a-z0-9' | fold -w8 | head -n1)
56
- back_up_env:=( \
57
- [ ! -f '${standard_env_path}' ] \
58
- || \
59
- ( \
60
- [ -f '${standard_env_path}' ] \
61
- && cp '${standard_env_path}' '${backup_env_path}' \
62
- ) \
63
- )
64
-
65
- replace_env:=( \
66
- ( [ "${custom_env_file}" == "0" ] ) \
67
- || \
68
- ( \
69
- [ "${custom_env_file}" == "1" ] \
70
- && ${back_up_env} \
71
- && cp ${env_file} '${standard_env_path}' \
72
- && $(call printraw,'\n${managed_env_tag}') >> '${standard_env_path}' \
73
- ) \
74
- )
75
-
76
- restore_env:=( \
77
- ( \
78
- [[ ! ${is_managed_env} ]] \
79
- || [ ! -f '${backup_env_path}' ] \
80
- ) \
81
- || \
82
- ( \
83
- [ -f '${backup_env_path}' ] \
84
- && [[ ${is_managed_env} ]] \
85
- && mv '${backup_env_path}' '${standard_env_path}' \
86
- ) \
87
- )
88
-
89
- key_chars:=[a-zA-Z0-9_]
90
- censored:=**********
91
- censor=s/\(^${key_chars}*$(1)${key_chars}*\)=\(.*\)$$/\1=${censored}/
92
- censor_urls:=s|\([a-zA-Z0-9_+]\+://.*:\).*\(@.*\)$$|\1${censored}\2|
93
- format_env:=sed '$(call censor,SECRET); \
94
- $(call censor,TOKEN); \
95
- $(call censor,PRIVATE); \
96
- $(call censor,KEY); \
97
- $(censor_urls); \
98
- /^\s*$$/d; \
99
- /^\s*\#/d; \
100
- s/\(^[a-zA-Z0-9_]\+\)=/${blue}\1${reset}=/; \
101
- s/^/ /; \
102
- s/=\(.*\)$$/=${yellow}\1${reset}/' | \
103
- sort
104
-
105
- fail=( \
106
- $(call printraw,' ${cross}') ; \
107
- ${restore_env} ; \
108
- $(call make,dump) ; \
109
- echo ; \
110
- $(call println,'Failed. ${cross}') ; \
111
- exit 1 \
112
- )
@@ -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