orchestration 0.6.13 → 0.6.15

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: 0eca537cffc7c1d04a9fee15b15d039e63f3ea64c29ca7384097ce5c3aeaedad
4
- data.tar.gz: 00c16b6c7a3d5cf3fa4fdf160a3664ce294d8fd52b4fb875eac0780e5013a9cf
3
+ metadata.gz: 5284c8bbcd13c4f409437f693bc1c9042ae79368dae8e2c7eef4c00fb79b11f3
4
+ data.tar.gz: 9350eee6b69c1b7b85d7267513cf4b76dd12a2a6d0a9699c249cb2ecafc5c3b8
5
5
  SHA512:
6
- metadata.gz: c1b0bd62ed5ce027fa5b3fd6e71891df96070c7b874fcdf90e86b9f4d13f3364105b05a456052dc8bed836ea96149ada3ee6b7ef875333b9af0ae22d8426404f
7
- data.tar.gz: 16e33c0e81496d722b04c5f60d446aa8e506cb549f5f14c3d39d107eb74c03f79e95b76e8f9ed13f35188fcda58b465f6bfa7fd2fe355af0c0adde36bb4a8c22
6
+ metadata.gz: 245335a561f1e72c5c74ca387e698c1a7186de4ee02de9f14cae0d0edf7257550d85eed880d590590ce3a7fd6b4eb9231461d336a50ab3a333f2064763f116bc
7
+ data.tar.gz: 6b8e6cbe7e45bee8acfef9ad828e986a8cf7c2ed702aced42d9ec029227004c091b7b60b01bd2ebdcf59f488f230728d17c8986068ad6a2b0f1a31f4997449b5
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- orchestration (0.6.13)
4
+ orchestration (0.6.14)
5
5
  database_url (~> 0.1.2)
6
6
  dotenv-rails (~> 2.8)
7
7
  erubis (~> 2.7)
@@ -17,6 +17,8 @@ module Orchestration
17
17
  end
18
18
 
19
19
  def orchestration_configuration
20
+ return unless build?('.orchestration.yml')
21
+
20
22
  configure_orchestration_settings
21
23
  relpath = relative_path(@env.orchestration_configuration_path)
22
24
  return @terminal.write(:create, relpath) unless @settings.exist? || force?
@@ -26,11 +28,15 @@ module Orchestration
26
28
  end
27
29
 
28
30
  def application_makefile
31
+ return unless build?('Makefile')
32
+
29
33
  path = @env.root.join('Makefile')
30
34
  simple_copy('application.mk', path) unless File.exist?(path)
31
35
  end
32
36
 
33
37
  def dockerfile
38
+ return unless build?('Dockerfile')
39
+
34
40
  create_file(
35
41
  orchestration_dir.join('Dockerfile'),
36
42
  dockerfile_content,
@@ -39,6 +45,8 @@ module Orchestration
39
45
  end
40
46
 
41
47
  def entrypoint_sh
48
+ return unless build?('entrypoint.sh')
49
+
42
50
  content = template('entrypoint.sh')
43
51
  path = orchestration_dir.join('entrypoint.sh')
44
52
  create_file(path, content, overwrite: false)
@@ -46,12 +54,15 @@ module Orchestration
46
54
  end
47
55
 
48
56
  def docker_compose
57
+ return unless build?('docker-compose.yml')
58
+
49
59
  @docker_compose.docker_compose_test_yml
50
60
  @docker_compose.docker_compose_development_yml
51
61
  @docker_compose.docker_compose_deployment_yml
52
62
  end
53
63
 
54
64
  def puma
65
+ return unless build?('puma.rb')
55
66
  return nil unless @env.web_server == 'puma'
56
67
 
57
68
  content = template('puma.rb')
@@ -60,6 +71,7 @@ module Orchestration
60
71
  end
61
72
 
62
73
  def unicorn
74
+ return unless build?('unicorn.rb')
63
75
  return nil unless @env.web_server == 'unicorn'
64
76
 
65
77
  content = template('unicorn.rb')
@@ -70,6 +82,7 @@ module Orchestration
70
82
  end
71
83
 
72
84
  def database_yml
85
+ return unless build?('database.yml')
73
86
  return unless defined?(ActiveRecord)
74
87
 
75
88
  adapter = DockerCompose::ComposeConfiguration.database_adapter_name
@@ -79,22 +92,28 @@ module Orchestration
79
92
  end
80
93
 
81
94
  def mongoid_yml
95
+ return unless build?('mongoid.yml')
82
96
  return unless defined?(Mongoid)
83
97
 
84
98
  service_config('mongoid.yml', Services::Mongo::Configuration)
85
99
  end
86
100
 
87
101
  def rabbitmq_yml
102
+ return unless build?('rabbitmq.yml')
88
103
  return unless defined?(Bunny)
89
104
 
90
105
  service_config('rabbitmq.yml', Services::RabbitMQ::Configuration)
91
106
  end
92
107
 
93
108
  def env
109
+ return unless build?('.env')
110
+
94
111
  simple_copy('env', @env.root.join('.env'), overwrite: false)
95
112
  end
96
113
 
97
114
  def gitignore
115
+ return unless build?('.gitignore')
116
+
98
117
  path = @env.root.join('.gitignore')
99
118
  globs = %w[.build/ .deploy/ Gemfile Gemfile.lock docker-compose.local.yml]
100
119
  lines = %w[orchestration/.sidecar .env deploy.tar] + globs.map do |line|
@@ -106,6 +125,13 @@ module Orchestration
106
125
 
107
126
  private
108
127
 
128
+ def build?(filename)
129
+ return true unless ENV.key?('build')
130
+ return true if ENV.fetch('build') == filename
131
+
132
+ false
133
+ end
134
+
109
135
  def t(key)
110
136
  I18n.t("orchestration.#{key}")
111
137
  end
@@ -182,12 +182,18 @@ ifeq (,$(findstring deploy,$(MAKECMDGOALS)))
182
182
  ifeq (,${sidecar_suffix})
183
183
  $(warning Unable to generate project suffix; project name collisions may occur.)
184
184
  endif
185
- compose_project_name = ${project_base}_${sidecar_suffix}
185
+ compose_project_name_base = ${project_base}_${sidecar_suffix}
186
186
  else
187
- compose_project_name = ${project_base}
187
+ compose_project_name_base = ${project_base}
188
188
  endif
189
189
  else
190
- compose_project_name = ${project_base}
190
+ compose_project_name_base = ${project_base}
191
+ endif
192
+
193
+ ifdef COMPOSE_PROJECT_NAME_SUFFIX
194
+ compose_project_name = ${compose_project_name_base}_${COMPOSE_PROJECT_NAME_SUFFIX}
195
+ else
196
+ compose_project_name = ${compose_project_name_base}
191
197
  endif
192
198
 
193
199
  compose_base:=env -i \
@@ -196,6 +202,7 @@ compose_base:=env -i \
196
202
  DOCKER_ORGANIZATION="${docker_organization}" \
197
203
  DOCKER_REPOSITORY="${docker_repository}" \
198
204
  COMPOSE_PROJECT_NAME="${compose_project_name}" \
205
+ COMPOSE_PROJECT_NAME_SUFFIX="${COMPOSE_PROJECT_NAME_SUFFIX}" \
199
206
  ${sidecar_compose} \
200
207
  docker-compose \
201
208
  -f ${orchestration_dir}/docker-compose.${env}.yml
@@ -386,14 +393,13 @@ tag:
386
393
  .PHONY: deploy
387
394
  deploy: _log-notify _clean-logs
388
395
  ifdef env_file
389
- deploy: env_file_option = --env-file ${env_file}
396
+ deploy: env_file_option = . ${env_file}
390
397
  endif
391
398
  deploy: RAILS_ENV := ${env}
392
399
  deploy: RACK_ENV := ${env}
393
400
  deploy: DOCKER_TAG = ${git_version}
394
401
  deploy: base_vars = DOCKER_ORGANIZATION=${docker_organization} DOCKER_REPOSITORY=${docker_repository} DOCKER_TAG=${git_version}
395
- 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.deployment.yml
396
- deploy: config_cmd = ${compose_deploy} config
402
+ deploy: config_cmd := ( set -a ; ${env_file_option} ; ${base_vars} COMPOSE_PROJECT_NAME=${project_base} HOST_UID=$(shell id -u) docker stack config --compose-file orchestration/docker-compose.deployment.yml )
397
403
  deploy: remote_cmd = cat | docker stack deploy --prune --with-registry-auth -c - ${project_base}
398
404
  deploy: ssh_cmd = ssh "${manager}"
399
405
  deploy: deploy_cmd := ${config_cmd} | ${ssh_cmd} "/bin/bash -lc '${remote_cmd}'"
@@ -0,0 +1,535 @@
1
+
2
+ ### Environment setup ###
3
+ SHELL:=/bin/bash
4
+ MAKE:=mkpath=${mkpath} make --no-print-directory
5
+ ORCHESTRATION_DISABLE_ENV=1
6
+ export
7
+ TERM ?= 'dumb'
8
+ pwd:=$(shell pwd)
9
+
10
+ orchestration_dir_name=orchestration
11
+ orchestration_dir=orchestration
12
+
13
+ ifdef env_file
14
+ custom_env_file ?= 1
15
+ else
16
+ custom_env_file ?= 0
17
+ endif
18
+
19
+ ifneq (,$(wildcard ${pwd}/config/database.yml))
20
+ database_enabled = 1
21
+ else
22
+ database_enabled = 0
23
+ endif
24
+
25
+ red:=$(shell tput setaf 1)
26
+ green:=$(shell tput setaf 2)
27
+ yellow:=$(shell tput setaf 3)
28
+ blue:=$(shell tput setaf 4)
29
+ magenta:=$(shell tput setaf 5)
30
+ cyan:=$(shell tput setaf 6)
31
+ gray:=$(shell tput setaf 7)
32
+ reset:=$(shell tput sgr0)
33
+ tick=[${green}✓${reset}]
34
+ cross=[${red}✘${reset}]
35
+
36
+ make=$(MAKE) $1
37
+ orchestration_config_filename:=.orchestration.yml
38
+ orchestration_config:=${pwd}/${orchestration_config_filename}
39
+ system_prefix=${reset}[${cyan}exec${reset}]
40
+ warn_prefix=${reset}[${yellow}warn${reset}]
41
+ echo_prefix=${reset}[${blue}info${reset}]
42
+ fail_prefix=${reset}[${red}fail${reset}]
43
+ logs_prefix=${reset}[${green}logs${reset}]
44
+ system=echo '${system_prefix} ${cyan}$1${reset}'
45
+ warn=echo '${warn_prefix} ${reset}$1${reset}'
46
+ echo=echo '${echo_prefix} ${reset}$1${reset}'
47
+ fail=echo '${fail_prefix} ${reset}$1${reset}'
48
+ logs=echo '${logs_prefix} ${reset}$1${reset}'
49
+ print_error=printf '${red}\#${reset} '$1 | tee '${stderr}'
50
+ println_error=$(call print_error,$1'\n')
51
+ print=printf '${blue}\#${reset} '$1
52
+ println=$(call print,$1'\n')
53
+ printraw=printf $1
54
+ stdout=${pwd}/log/orchestration.stdout.log
55
+ stderr=${pwd}/log/orchestration.stderr.log
56
+ log_path_length:=$(shell echo "${stdout}" | wc -c)
57
+ ifndef verbose
58
+ log_tee:= 2>&1 | tee -a ${stdout}
59
+ log:= >>${stdout} 2>>${stderr}
60
+ progress_point:=perl -e 'printf("[${magenta}busy${reset}] "); while( my $$line = <STDIN> ) { printf("."); select()->flush(); }'
61
+ log_progress:= > >(tee -ai ${stdout} >&1 | ${progress_point}) 2> >(tee -ai ${stderr} 2>&1 | ${progress_point})
62
+ endif
63
+ hr:=$(call println,"$1$(shell head -c ${log_path_length} < /dev/zero | tr '\0' '=')${reset}")
64
+ managed_env_tag:=\# -|- ORCHESTRATION
65
+ standard_env_path:=${pwd}/.env
66
+ backup_env_path:=${pwd}/.env.orchestration.backup
67
+ is_managed_env:=$$(test -f '${standard_env_path}' && tail -n 1 '${standard_env_path}') == "${managed_env_tag}"*
68
+ token:=$(shell cat /dev/urandom | LC_CTYPE=C tr -dc 'a-z0-9' | fold -w8 | head -n1)
69
+ back_up_env:=( \
70
+ [ ! -f '${standard_env_path}' ] \
71
+ || \
72
+ ( \
73
+ [ -f '${standard_env_path}' ] \
74
+ && cp '${standard_env_path}' '${backup_env_path}' \
75
+ ) \
76
+ )
77
+
78
+ key_chars:=[a-zA-Z0-9_]
79
+ censored:=**********
80
+ censor=s/\(^${key_chars}*$(1)${key_chars}*\)=\(.*\)$$/\1=${censored}/
81
+ censor_urls:=s|\([a-zA-Z0-9_+]\+://.*:\).*\(@.*\)$$|\1${censored}\2|
82
+ format_env:=sed '$(call censor,SECRET); \
83
+ $(call censor,TOKEN); \
84
+ $(call censor,PRIVATE); \
85
+ $(call censor,KEY); \
86
+ $(censor_urls); \
87
+ /^\s*$$/d; \
88
+ /^\s*\#/d; \
89
+ s/\(^[a-zA-Z0-9_]\+\)=/${blue}\1${reset}=/; \
90
+ s/^/ /; \
91
+ s/=\(.*\)$$/=${yellow}\1${reset}/' | \
92
+ sort
93
+
94
+ exit_fail=( \
95
+ $(call printraw,' ${cross}') ; \
96
+ $(call make,dump src_cmd=$(MAKECMDGOALS)) ; \
97
+ echo ; \
98
+ $(call println,'Failed. ${cross}') ; \
99
+ exit 1 \
100
+ )
101
+
102
+ ifdef env_file
103
+ env_path=${env_file}
104
+ else
105
+ env_path=.env
106
+ endif
107
+
108
+ ifneq (${env},test)
109
+ ifeq (,$(findstring test,$(MAKECMDGOALS)))
110
+ ifeq (,$(findstring deploy,$(MAKECMDGOALS)))
111
+ ifeq (,$(findstring setup,$(MAKECMDGOALS)))
112
+ -include ${env_path}
113
+ endif
114
+ endif
115
+ endif
116
+ endif
117
+
118
+ ifneq (,$(findstring deploy,$(MAKECMDGOALS)))
119
+ RAILS_ENV=$(shell grep '^RAILS_ENV=' '${env_path}' | tail -n1 | sed 's/^RAILS_ENV=//')
120
+ endif
121
+
122
+ export
123
+
124
+ ifneq (,$(findstring test,$(MAKECMDGOALS)))
125
+ env=test
126
+ endif
127
+
128
+ ifneq (,$(RAILS_ENV))
129
+ env=$(RAILS_ENV)
130
+ else ifneq (,$(env))
131
+ # `env` set by current shell.
132
+ else ifneq (,$(RAILS_ENV))
133
+ env=$(RAILS_ENV)
134
+ else ifneq (,$(RACK_ENV))
135
+ env=$(RACK_ENV)
136
+ else
137
+ env=development
138
+ endif
139
+
140
+ env_human=${gray}${env}${reset}
141
+ DOCKER_TAG ?= latest
142
+
143
+ ifneq (,$(wildcard ./Gemfile))
144
+ bundle_cmd = bundle exec
145
+ endif
146
+ rake=ORCHESTRATION_DISABLE_ENV=1 DEVPACK_DISABLE=1 RACK_ENV=${env} SECRET_KEY_BASE='placeholder-secret' RAILS_ENV=${env} ${bundle_cmd} rake
147
+
148
+ ifneq (,$(wildcard ${env_file}))
149
+ ifeq (,$(findstring deploy,$(MAKECMDGOALS)))
150
+ rake_cmd:=${rake}
151
+ rake=. ${env_file} && ${rake_cmd}
152
+ endif
153
+ endif
154
+
155
+ docker_config:=$(shell DEVPACK_DISABLE=1 RAILS_ENV=development ${bundle_cmd} rake orchestration:config 2>/dev/null || echo no-org no-repo)
156
+ docker_organization=$(word 1,$(docker_config))
157
+ docker_repository=$(word 2,$(docker_config))
158
+
159
+ compose_services:=$(shell ${rake} orchestration:compose_services RAILS_ENV=${env})
160
+
161
+ ifeq (,$(project_name))
162
+ project_base = ${docker_repository}_${env}
163
+ else
164
+ project_base := $(project_name)
165
+ endif
166
+
167
+ ifeq (,$(findstring deploy,$(MAKECMDGOALS)))
168
+ sidecar_suffix := $(shell test -f ${orchestration_dir}/.sidecar && cat ${orchestration_dir}/.sidecar)
169
+ ifneq (,${sidecar_suffix})
170
+ sidecar := 1
171
+ endif
172
+
173
+ ifdef sidecar
174
+ # Set the variable to an empty string so that "#{sidecar-1234}" will
175
+ # evaluate to "1234" in port mappings.
176
+ sidecar_compose = sidecar=''
177
+ ifeq (,${sidecar_suffix})
178
+ sidecar_suffix := $(call token)
179
+ _ignore := $(shell echo ${sidecar_suffix} > ${orchestration_dir}/.sidecar)
180
+ endif
181
+
182
+ ifeq (,${sidecar_suffix})
183
+ $(warning Unable to generate project suffix; project name collisions may occur.)
184
+ endif
185
+ compose_project_name_base = ${project_base}_${sidecar_suffix}
186
+ else
187
+ compose_project_name_base = ${project_base}
188
+ endif
189
+ else
190
+ compose_project_name_base = ${project_base}
191
+ endif
192
+
193
+ ifdef COMPOSE_PROJECT_NAME_SUFFIX
194
+ compose_project_name = ${compose_project_name_base}_${COMPOSE_PROJECT_NAME_SUFFIX}
195
+ else
196
+ compose_project_name = ${compose_project_name_base}
197
+ endif
198
+
199
+ compose_base:=env -i \
200
+ PATH=$(PATH) \
201
+ HOST_UID=$(shell id -u) \
202
+ DOCKER_ORGANIZATION="${docker_organization}" \
203
+ DOCKER_REPOSITORY="${docker_repository}" \
204
+ COMPOSE_PROJECT_NAME="${compose_project_name}" \
205
+ COMPOSE_PROJECT_NAME_SUFFIX="${COMPOSE_PROJECT_NAME_SUFFIX}" \
206
+ ${sidecar_compose} \
207
+ docker-compose \
208
+ -f ${orchestration_dir}/docker-compose.${env}.yml
209
+
210
+ git_branch := $(if $(branch),$(branch),$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo no-branch))
211
+ ifndef dev
212
+ git_version := $(shell git rev-parse --short --verify ${git_branch} 2>/dev/null || echo no-version)
213
+ else
214
+ git_version := dev
215
+ endif
216
+
217
+ docker_image:=${docker_organization}/${docker_repository}:${git_version}
218
+
219
+ compose=${compose_base}
220
+ compose_human=docker-compose -f ${orchestration_dir_name}/docker-compose.${env}.yml
221
+ random_str=cat /dev/urandom | LC_ALL=C tr -dc 'a-z' | head -c $1
222
+
223
+ ifneq (,$(wildcard ${orchestration_dir}/docker-compose.local.yml))
224
+ compose:=${compose} -f ${orchestration_dir}/docker-compose.local.yml
225
+ endif
226
+
227
+ all: build
228
+
229
+ ### Container management commands ###
230
+
231
+ .PHONY: pull
232
+ pull:
233
+ @$(call system,${compose_human} pull)
234
+ @${compose} pull
235
+
236
+ .PHONY: start
237
+ ifndef network
238
+ start: network := ${compose_project_name}
239
+ endif
240
+ start: _create-log-directory _clean-logs pull
241
+ ifneq (,${compose_services})
242
+ @$(call system,${compose_human} up --detach)
243
+ ifeq (${env},$(filter ${env},test development))
244
+ @${compose} up --detach --force-recreate --renew-anon-volumes --remove-orphans ${services} ${log} || ${exit_fail}
245
+ @[ -n '${sidecar}' ] && \
246
+ ( \
247
+ $(call echo,(joining dependency network ${cyan}${network}${reset})) ; \
248
+ $(call system,docker network connect "${network}") ; \
249
+ docker network connect '${network}' '$(shell hostname)' ${log} \
250
+ || ( \
251
+ $(call warn,Unable to join network: "${cyan}${network}${reset}". Container will not be able to connect to dependency services) ; \
252
+ $(call echo,Try deleting "${cyan}orchestration/.sidecar${reset}" if you do not want to use sidecar mode) ; \
253
+ ) \
254
+ ) \
255
+ || ( [ -z '${sidecar}' ] || ${exit_fail} )
256
+ else
257
+ @${compose} up --detach --scale app=$${instances:-1} ${log} || ${exit_fail}
258
+ endif
259
+ @$(call echo,${env_human} containers started ${tick})
260
+ @$(call echo,Waiting for services to become available)
261
+ @$(call make,wait) 2>${stderr} || ${exit_fail}
262
+ endif
263
+
264
+ .PHONY: stop
265
+ stop: network := ${compose_project_name}
266
+ stop:
267
+ ifneq (,${compose_services})
268
+ @$(call echo,Stopping ${env_human} containers)
269
+ @$(call system,${compose_human} down)
270
+ @if docker ps --format "{{.ID}}" | grep -q $(shell hostname) ; \
271
+ then \
272
+ ( docker network disconnect ${network} $(shell hostname) ${log} || : ) \
273
+ && \
274
+ ( ${compose} down ${log} || ${exit_fail} ) ; \
275
+ else \
276
+ ${compose} down ${log} || ${exit_fail} ; \
277
+ fi
278
+ @$(call echo,${env_human} containers stopped ${tick})
279
+ endif
280
+
281
+ .PHONY: logs
282
+ logs:
283
+ @${compose} logs -f
284
+
285
+ .PHONY: config
286
+ config:
287
+ @${compose} config
288
+
289
+ .PHONY: compose
290
+ compose:
291
+ @echo ${compose}
292
+
293
+ ### Development/Test Utility Commands
294
+
295
+ .PHONY: serve
296
+ serve: env_file ?= ./.env
297
+ serve: rails = RAILS_ENV='${env}' bundle exec rails server ${server}
298
+ serve:
299
+ @if [ -f "${env_file}" ] ; \
300
+ then ( \
301
+ $(call echo,Environment${reset}: ${cyan}${env_file}${reset}) && \
302
+ cat '${env_file}' | ${format_env} \
303
+ ) ; \
304
+ fi
305
+ ${rails}
306
+
307
+ .PHONY: console
308
+ console: env_file ?= ./.env
309
+ console: rails = RAILS_ENV='${env}' bundle exec rails
310
+ console:
311
+ @if [ -f "${env_file}" ] ; \
312
+ then ( \
313
+ $(call echo,Environment${reset}: ${cyan}${env_file}${reset}) && \
314
+ cat '${env_file}' | ${format_env} \
315
+ ) ; \
316
+ fi
317
+ ${rails} console
318
+
319
+ .PHONY: db-console
320
+ db-console:
321
+ @${rake} orchestration:db:console RAILS_ENV=${env}
322
+
323
+ .PHONY: setup
324
+ ifneq (,$(wildcard config/database.yml))
325
+ setup: url := $(shell ${rake} orchestration:db:url RAILS_ENV=${env} 2>/dev/null)
326
+ endif
327
+ setup: _log-notify
328
+ @$(call echo,Setting up ${env_human} environment)
329
+ @$(call make,start env=${env})
330
+ ifneq (,$(wildcard config/database.yml))
331
+ @$(call echo,Preparing ${env_human} database)
332
+ @$(call system,rake db:create RAILS_ENV="${env}")
333
+ @${rake} db:create RAILS_ENV=${env} DATABASE_URL='${url}' ${log} || : ${log}
334
+ ifneq (,$(wildcard db/structure.sql))
335
+ @$(call system,rake db:structure:load RAILS_ENV="${env}" ${url_prefix}DATABASE_URL="${url}")
336
+ @${rake} db:structure:load RAILS_ENV="${env}" DATABASE_URL='${url}' ${log} || ${exit_fail}
337
+ else ifneq (,$(wildcard db/schema.rb))
338
+ @$(call system,rake db:schema:load RAILS_ENV="${env}" ${url_prefix}DATABASE_URL="${url}")
339
+ @${rake} db:schema:load RAILS_ENV="${env}" DATABASE_URL='${url}' ${log} || ${exit_fail}
340
+ endif
341
+ @$(call system,rake db:migrate RAILS_ENV="${env}" ${url_prefix}DATABASE_URL="${url}")
342
+ @${rake} db:migrate RAILS_ENV="${env}" DATABASE_URL='${url}' ${log} || ${exit_fail}
343
+ endif
344
+ @if $(MAKE) -n post-setup >/dev/null 2>&1; then \
345
+ $(call system,make post-setup RAILS_ENV="${env}") \
346
+ && $(MAKE) post-setup RAILS_ENV=${env}; fi
347
+ @$(call echo,${env_human} environment setup complete ${tick})
348
+
349
+ .PHONY: dump
350
+ dump:
351
+ ifndef verbose
352
+ @$(call println)
353
+ @$(call println,'${yellow}Captured${reset} ${green}stdout${reset} ${yellow}and${reset} ${red}stderr${reset} ${yellow}log data [${cyan}${env}${yellow}]${reset}:')
354
+ @$(call println)
355
+ @echo
356
+ @test -f '${stdout}' && ( \
357
+ $(call hr,${green}) ; \
358
+ $(call println,'${gray}${stdout}${reset}') ; \
359
+ $(call hr,${green}) ; \
360
+ echo ; cat '${stdout}' ; echo ; \
361
+ $(call hr,${green}) ; \
362
+ )
363
+
364
+ @test -f '${stdout}' && ( \
365
+ echo ; \
366
+ $(call hr,${red}) ; \
367
+ $(call println,'${gray}${stderr}${reset}') ; \
368
+ $(call hr,${red}) ; \
369
+ echo ; cat '${stderr}' ; echo ; \
370
+ $(call hr,${red}) ; \
371
+ )
372
+ endif
373
+ ifneq (build,${src_cmd})
374
+ ifneq (push,${src_cmd})
375
+ @echo ; \
376
+ $(call hr,${yellow}) ; \
377
+ $(call println,'${gray}docker-compose logs${reset}') ; \
378
+ $(call hr,${yellow}) ; \
379
+ echo
380
+ @${compose} logs
381
+ @echo ; \
382
+ $(call hr,${yellow})
383
+ @$(NOOP)
384
+ endif
385
+ endif
386
+
387
+ .PHONY: tag
388
+ tag:
389
+ @echo ${docker_image}
390
+
391
+ ### Deployment utility commands ###
392
+
393
+ .PHONY: deploy
394
+ deploy: _log-notify _clean-logs
395
+ ifdef env_file
396
+ deploy: env_file_option = --env-file ${env_file}
397
+ endif
398
+ deploy: RAILS_ENV := ${env}
399
+ deploy: RACK_ENV := ${env}
400
+ deploy: DOCKER_TAG = ${git_version}
401
+ deploy: base_vars = DOCKER_ORGANIZATION=${docker_organization} DOCKER_REPOSITORY=${docker_repository} DOCKER_TAG=${git_version}
402
+ 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.deployment.yml
403
+ deploy: config_cmd = ${compose_deploy} config
404
+ deploy: remote_cmd = cat | docker stack deploy --prune --with-registry-auth -c - ${project_base}
405
+ deploy: ssh_cmd = ssh "${manager}"
406
+ deploy: deploy_cmd := ${config_cmd} | ${ssh_cmd} "/bin/bash -lc '${remote_cmd}'"
407
+ deploy:
408
+ ifndef manager
409
+ @$(call fail,Missing ${cyan}manager${reset} parameter: ${cyan}make deploy manager=swarm-manager.example.com${reset}) ; exit 1
410
+ endif
411
+ @$(call echo,Deploying ${env_human} stack via ${cyan}${manager}${reset} as ${cyan}${project_base}${reset}) && \
412
+ ( \
413
+ ( test -f '${env_file}' && $(call echo,Deployment environment:) && cat '${env_file}' | ${format_env} || : ) && \
414
+ $(call echo,Application image: ${cyan}${docker_image}${reset}) ; \
415
+ $(call system,${config_cmd} | ${ssh_cmd} "/bin/bash -lc '\''${remote_cmd}'\''") ; \
416
+ ${deploy_cmd} \
417
+ )
418
+ @$(call echo,Deployment ${green}complete${reset} ${tick})
419
+
420
+ .PHONY: rollback
421
+ ifndef service
422
+ rollback: service = app
423
+ endif
424
+ rollback:
425
+ ifndef manager
426
+ @$(call fail,Missing `manager` parameter: `make deploy manager=swarm-manager.example.com`)
427
+ @exit 1
428
+ endif
429
+ @$(call echo,Rolling back ${cyan}${compose_project_name}_${service}${reset} via ${cyan}${manager}${reset} ...)
430
+ @$(call system,docker service rollback --detach "${compose_project_name}_${service}")
431
+ @ssh "${manager}" 'docker service rollback --detach "${compose_project_name}_${service}"' ${log} || ${exit_fail}
432
+ @$(call echo,Rollback request ${green}complete${reset} ${tick})
433
+
434
+ ### Service healthcheck commands ###
435
+
436
+ .PHONY: wait
437
+ wait:
438
+ @${rake} orchestration:wait
439
+ @$(call echo,${env_human} services ${green}ready${reset} ${tick})
440
+
441
+ ## Generic Listener healthcheck for TCP services ##
442
+
443
+ wait-listener:
444
+ @${rake} orchestration:listener:wait service=${service} sidecar=${sidecar}
445
+
446
+ ### Docker build commands ###
447
+
448
+ .PHONY: build
449
+ build: _log-notify _clean-logs
450
+ build: build_dir = ${orchestration_dir}/.build
451
+ build: context = ${build_dir}/context.tar
452
+ build: build_args := --build-arg GIT_COMMIT='${git_version}' $(shell grep '^ARG ' orchestration/Dockerfile | sed -e 's/=.*$$//' -e 's/^ARG /--build-arg /')
453
+ build: tag_human = ${cyan}${docker_organization}/${docker_repository}:${git_version}${reset}
454
+ build: latest_tag_human = ${cyan}${docker_organization}/${docker_repository}:latest${reset}
455
+ build: _create-log-directory check-local-changes
456
+ @$(call echo,Preparing build context from ${cyan}${git_branch}${reset} (${cyan}${git_version}${reset})${reset})
457
+ @$(call system,git archive --format "tar" -o "${context}" "${git_branch}")
458
+ @mkdir -p ${orchestration_dir}/.build ${log} || ${exit_fail}
459
+ @cp '$(shell bundle info --path orchestration)/lib/orchestration/healthcheck.bash' '${orchestration_dir}/healthcheck'
460
+ @chmod +x '${orchestration_dir}/healthcheck'
461
+ ifndef dev
462
+ @git show ${git_branch}:./Gemfile > ${orchestration_dir}/.build/Gemfile 2>${stderr} || ${exit_fail}
463
+ @git show ${git_branch}:./Gemfile.lock > ${orchestration_dir}/.build/Gemfile.lock 2>${stderr} || ${exit_fail}
464
+ @git archive --format 'tar' -o '${context}' '${git_branch}' ${log} || ${exit_fail}
465
+ else
466
+ @tar -cvf '${context}' . ${log} || ${exit_fail}
467
+ endif
468
+ @tar --append --file '${context}' '${orchestration_dir}/healthcheck'
469
+ @rm '${orchestration_dir}/healthcheck'
470
+ ifdef include
471
+ @$(call echo,Including files from: ${cyan}${include}${reset})
472
+ @(while read line; do \
473
+ export line; \
474
+ include_dir="${build_dir}/$$(dirname "$${line}")/" && \
475
+ mkdir -p "$${include_dir}" && cp "$${line}" "$${include_dir}" \
476
+ && (cd '${orchestration_dir}/.build/' && tar rf 'context.tar' "$${line}"); \
477
+ echo "${system_prefix}" "tar rf 'context.tar' '$${line}'"; \
478
+ done < '${include}') ${log} || ${exit_fail}
479
+ @$(call echo,Build context ${green}ready${reset} ${tick})
480
+ endif
481
+ @$(call echo,Building image ${tag_human})
482
+ @$(call system,docker build ${build_args} -t ${docker_organization}/${docker_repository}:${git_version} ${orchestration_dir}/)
483
+ @docker build ${build_args} \
484
+ -t ${docker_organization}/${docker_repository}:${git_version} \
485
+ ${orchestration_dir}/ ${log_progress} || ${exit_fail}
486
+ @echo
487
+ @$(call echo,Build ${green}complete${reset} ${tick})
488
+ @$(call echo,[${green}tag${reset}] ${tag_human})
489
+
490
+ .PHONY: push
491
+ push: _log-notify _clean-logs
492
+ @$(call echo,Pushing ${cyan}${docker_image}${reset} to registry)
493
+ @$(call system,docker push ${docker_image})
494
+ @docker push ${docker_image} ${log_progress} || ${exit_fail}
495
+ @echo
496
+ @$(call echo,Push ${green}complete${reset} ${tick})
497
+
498
+ .PHONY: check-local-changes
499
+ check-local-changes:
500
+ ifndef dev
501
+ @changes="$$(git status --porcelain)"; if ! [ -z "${changes}" ] && [[ "${changes}" != "?? orchestration/.sidecar" ]]; \
502
+ then \
503
+ $(call warn,You have uncommitted changes which will not be included in your build:) ; \
504
+ git status --porcelain ; \
505
+ $(call echo,Commit these changes to Git or, alternatively, build in development mode to test your changes before committing: ${cyan}make build dev=1${reset}) ; \
506
+ fi
507
+ endif
508
+
509
+ ### Internal Commands ###
510
+ #
511
+ .PHONY: _log-notify
512
+ _log-notify: comma=,
513
+ _log-notify: _verify-repository
514
+ ifndef verbose
515
+ @$(call logs,${green}stdout${reset}: ${cyan}log/orchestration.stdout.log${reset}${comma} ${red}stderr${reset}: ${cyan}log/orchestration.stderr.log)
516
+ endif
517
+
518
+ .PHONY: _verify-repository
519
+ _verify-repository:
520
+ @if ! git rev-parse HEAD >/dev/null 2>&1 ; then $(call fail,You must make at least one commit before you can use Orchestration commands) ; exit 1 ; fi
521
+
522
+ .PHONY: _clean-logs
523
+ _clean-logs:
524
+ _clean-logs: _create-log-directory
525
+ @rm -f '${stdout}' '${stderr}'
526
+ @touch '${stdout}' '${stderr}'
527
+
528
+ .PHONY: _create-log-directory
529
+ _create-log-directory:
530
+ @mkdir -p log
531
+
532
+ # Used by Orchestration test suite to verify Makefile syntax
533
+ .PHONY: _test
534
+ _test:
535
+ @echo 'test command'
@@ -2,20 +2,22 @@ FROM ruby:<%= ruby_version %>
2
2
  ARG BUNDLE_BITBUCKET__ORG
3
3
  ARG BUNDLE_GITHUB__COM
4
4
  ARG GIT_COMMIT
5
- RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
6
- && apt-get update \
5
+ ENV NODE_MAJOR=20
6
+ RUN apt-get update \
7
7
  && DEBIAN_FRONTEND=noninteractive apt-get install -y \
8
- nodejs \
9
8
  gosu \
10
9
  sendmail \
10
+ ca-certificates \
11
+ curl \
12
+ gnupg \
13
+ && mkdir -p /etc/apt/keyrings \
14
+ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
15
+ && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
16
+ && apt-get update \
17
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs \
11
18
  && rm -rf /var/lib/apt/lists/* \
12
19
  && gem install bundler \
13
20
  && mkdir /app<%if defined?(Webpacker) %> \
14
- && curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash \
15
- && . /root/.bashrc \
16
- && nvm install 14.16.0 \
17
- && npm config set user 0 \
18
- && npm config set unsafe-perm true \
19
21
  && npm install -g yarn<% end %>
20
22
  WORKDIR /app
21
23
  COPY .build/Gemfile .build/Gemfile.lock ./
@@ -23,7 +25,7 @@ RUN bundle config set deployment 'true' \
23
25
  && bundle config set without 'development test' \
24
26
  && bundle install
25
27
  ADD .build/context.tar .
26
- <% if defined?(Webpacker) %>RUN . /root/.bashrc ; NODE_ENV=production RAILS_ENV=production yarn install && NODE_ENV=production RAILS_ENV=production SECRET_KEY_BASE=placeholder-secret bundle exec rake assets:precompile<% elsif Rake::Task.tasks.map(&:name).include?('assets:precompile') %>RUN NODE_ENV=production RAILS_ENV=production SECRET_KEY_BASE=placeholder-secret bundle exec rake assets:precompile<% end %>
28
+ <% if defined?(Webpacker) %>RUN NODE_ENV=production RAILS_ENV=production yarn install && NODE_ENV=production RAILS_ENV=production SECRET_KEY_BASE=placeholder-secret bundle exec rake assets:precompile<% elsif Rake::Task.tasks.map(&:name).include?('assets:precompile') %>RUN NODE_ENV=production RAILS_ENV=production SECRET_KEY_BASE=placeholder-secret bundle exec rake assets:precompile<% end %>
27
29
  RUN echo "${GIT_COMMIT}" > /app/GIT_COMMIT
28
30
  HEALTHCHECK --interval=<%= healthcheck['interval'] %> \
29
31
  --timeout=<%= healthcheck['timeout'] %> \
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orchestration
4
- VERSION = '0.6.13'
4
+ VERSION = '0.6.15'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orchestration
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.13
4
+ version: 0.6.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Farrell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-12 00:00:00.000000000 Z
11
+ date: 2023-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: database_url
@@ -403,6 +403,7 @@ files:
403
403
  - lib/orchestration/install_generator.rb
404
404
  - lib/orchestration/make.rb
405
405
  - lib/orchestration/make/orchestration.mk
406
+ - lib/orchestration/make/orchestration.mk.orig
406
407
  - lib/orchestration/railtie.rb
407
408
  - lib/orchestration/service_check.rb
408
409
  - lib/orchestration/services.rb