orchestration 0.3.17 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/LICENSE +7 -0
  4. data/MANIFEST +76 -0
  5. data/Makefile +3 -3
  6. data/README.md +162 -137
  7. data/Rakefile +2 -2
  8. data/config/locales/en.yml +3 -1
  9. data/lib/orchestration/docker_compose/app_service.rb +84 -13
  10. data/lib/orchestration/docker_compose/compose_configuration.rb +69 -0
  11. data/lib/orchestration/docker_compose/database_service.rb +15 -13
  12. data/lib/orchestration/docker_compose/install_generator.rb +3 -2
  13. data/lib/orchestration/docker_compose/mongo_service.rb +5 -5
  14. data/lib/orchestration/docker_compose/rabbitmq_service.rb +2 -3
  15. data/lib/orchestration/docker_compose.rb +1 -0
  16. data/lib/orchestration/environment.rb +19 -6
  17. data/lib/orchestration/errors.rb +1 -1
  18. data/lib/orchestration/file_helpers.rb +27 -4
  19. data/lib/orchestration/install_generator.rb +85 -20
  20. data/lib/orchestration/services/app/configuration.rb +9 -5
  21. data/lib/orchestration/services/app/healthcheck.rb +1 -22
  22. data/lib/orchestration/services/database/adapters/mysql2.rb +13 -2
  23. data/lib/orchestration/services/database/adapters/postgresql.rb +0 -1
  24. data/lib/orchestration/services/database/configuration.rb +68 -75
  25. data/lib/orchestration/services/database/healthcheck.rb +10 -1
  26. data/lib/orchestration/services/listener/configuration.rb +1 -1
  27. data/lib/orchestration/services/listener/healthcheck.rb +2 -2
  28. data/lib/orchestration/services/{configuration_base.rb → mixins/configuration_base.rb} +15 -13
  29. data/lib/orchestration/services/{healthcheck_base.rb → mixins/healthcheck_base.rb} +3 -2
  30. data/lib/orchestration/services/mixins/http_healthcheck.rb +38 -0
  31. data/lib/orchestration/services/mongo/configuration.rb +37 -63
  32. data/lib/orchestration/services/mongo/healthcheck.rb +3 -32
  33. data/lib/orchestration/services/rabbitmq/configuration.rb +11 -22
  34. data/lib/orchestration/services/rabbitmq/healthcheck.rb +2 -2
  35. data/lib/orchestration/services.rb +3 -2
  36. data/lib/orchestration/templates/Dockerfile.erb +8 -4
  37. data/lib/orchestration/templates/database.yml.erb +32 -0
  38. data/lib/orchestration/templates/deploy.mk.erb +2 -2
  39. data/lib/orchestration/templates/entrypoint.sh.erb +13 -4
  40. data/lib/orchestration/templates/env.erb +10 -2
  41. data/lib/orchestration/templates/healthcheck.rb.erb +56 -0
  42. data/lib/orchestration/templates/makefile_macros.mk.erb +108 -0
  43. data/lib/orchestration/templates/mongoid.yml.erb +18 -0
  44. data/lib/orchestration/templates/orchestration.mk.erb +242 -120
  45. data/lib/orchestration/templates/puma.rb.erb +19 -0
  46. data/lib/orchestration/templates/rabbitmq.yml.erb +12 -0
  47. data/lib/orchestration/templates/unicorn.rb.erb +5 -5
  48. data/lib/orchestration/terminal.rb +13 -15
  49. data/lib/orchestration/version.rb +1 -1
  50. data/lib/orchestration.rb +20 -2
  51. data/lib/tasks/orchestration.rake +3 -1
  52. data/orchestration.gemspec +3 -5
  53. metadata +23 -13
@@ -0,0 +1,32 @@
1
+ default: &default
2
+ adapter: <%= compose.call(nil).database_adapter_name %>
3
+
4
+ <% if compose.call(nil).services.key?('database') %>
5
+ development:
6
+ <<: *default
7
+ host: 127.0.0.1
8
+ port: <%= compose.call('development').local_port('database') %>
9
+ username: <%= compose.call(nil).database_adapter.credentials['username'] %>
10
+ password: <%= compose.call(nil).database_adapter.credentials['password'] %>
11
+ database: <%= compose.call(nil).database_adapter.credentials['database'] %>
12
+ <% end %>
13
+
14
+ <% if compose.call('test').services.key?('database') %>
15
+ test:
16
+ <<: *default
17
+ host: 127.0.0.1
18
+ port: <%= compose.call('test').local_port('database') %>
19
+ username: <%= compose.call(nil).database_adapter.credentials['username'] %>
20
+ password: <%= compose.call(nil).database_adapter.credentials['password'] %>
21
+ database: <%= compose.call(nil).database_adapter.credentials['database'] %>
22
+ # Useful for certain continuous integration environments (e.g. Jenkins in
23
+ # Docker) where the DB hostname may be a service name rather than `127.0.0.1`:
24
+ <%% if ENV.key?('DATABASE_URL') %>
25
+ url: <%%= ENV['DATABASE_URL'] %>
26
+ <%% end %>
27
+ <% end %>
28
+
29
+
30
+ production:
31
+ <<: *default
32
+ url: <%%= ENV['DATABASE_URL'] %>
@@ -8,8 +8,8 @@ else ifneq (,$(RACK_ENV))
8
8
  endif
9
9
 
10
10
  verify-environment:
11
- ifndef LISTEN_PORT
12
- @$(error `LISTEN_PORT` must be defined in environment)
11
+ ifndef CONTAINER_PORT
12
+ @$(error `CONTAINER_PORT` must be defined in environment)
13
13
  endif
14
14
 
15
15
  ifndef env
@@ -1,9 +1,18 @@
1
1
  #!/bin/sh
2
- set -u
2
+ set -ue
3
+ echo "Host user ID: ${HOST_UID}"
4
+ set +u
3
5
  id owner >/dev/null 2>&1 || useradd -u ${HOST_UID} -m -o owner
4
6
  mkdir -p /app/tmp/pids
5
7
  chown -Rf owner:owner /app/tmp /app/log /app/db
6
- rm -f /app/tmp/pids/unicorn.pid
7
- mkdir -p /var/www/public/
8
- ln -nfs /app/public/* /var/www/public/
8
+ rm -f /app/tmp/pids/server.pid
9
+
10
+ DOCKER_HOST_IP="$(ip route | awk '/default/ { print $3 }' 2>/dev/null)"
11
+ if printf "${DOCKER_HOST_IP}" | egrep -q '([0-9]{1,3}[\.]){3}[0-9]{1,3}' \
12
+ && [ ! $(grep -q "${DOCKER_HOST_IP} host.docker.internal" '/etc/hosts') ]
13
+ then
14
+ echo "Host IP: ${DOCKER_HOST_IP}"
15
+ echo "${DOCKER_HOST_IP} host.docker.internal" >> '/etc/hosts'
16
+ fi
17
+
9
18
  exec gosu owner "$@"
@@ -1,2 +1,10 @@
1
- # Your application will be available on this port when deployed to the Swarm:
2
- LISTEN_PORT=3000
1
+ # Configure which port your `app` service will listen on:
2
+ CONTAINER_PORT=3000
3
+
4
+ # Use `make deploy` to deploy your application stack to a Docker Swarm.
5
+ # Use this setting to control the number of replicas to create for your
6
+ # application service:
7
+ REPLICAS=1
8
+
9
+ # Development database:
10
+ DATABASE_URL=<%= env.database_url %>
@@ -0,0 +1,56 @@
1
+ #
2
+ # Orchestration Healthcheck Utility
3
+ #
4
+ #
5
+ # https://github.com/bobf/orchestration
6
+ #
7
+
8
+ require 'net/http'
9
+
10
+ def run
11
+ client = Net::HTTP.new(
12
+ ENV.fetch('WEB_HOST', 'localhost'),
13
+ ENV.fetch('WEB_PORT', '8080').to_i
14
+ )
15
+
16
+ client.read_timeout = ENV.fetch('WEB_HEALTHCHECK_READ_TIMEOUT', '10').to_i
17
+ client.open_timeout = ENV.fetch('WEB_HEALTHCHECK_OPEN_TIMEOUT', '10').to_i
18
+
19
+ client.start do |request|
20
+ request.get(ENV.fetch('WEB_HEALTHCHECK_PATH') { '/' })
21
+ end
22
+ end
23
+
24
+ def success_codes
25
+ ENV.fetch('WEB_HEALTHCHECK_SUCCESS_CODES', '200,202,204').split(',')
26
+ end
27
+
28
+ def success?(code)
29
+ success_codes.include?(code.to_s)
30
+ end
31
+
32
+ def message(code)
33
+ if success?(code)
34
+ outcome = 'SUCCESS ✓ '
35
+ in_or_not = 'IN'
36
+ else
37
+ outcome = 'FAILURE ✘ '
38
+ in_or_not = 'NOT IN'
39
+ end
40
+
41
+ accepted = success_codes.join(', ')
42
+
43
+ "# HTTP_STATUS(#{code}) #{in_or_not} [#{accepted}] : #{outcome} [#{__FILE__}]"
44
+ end
45
+
46
+ return_code = 1
47
+
48
+ begin
49
+ response = run
50
+ return_code = 0 if success?(response.code)
51
+ puts message(response.code)
52
+ rescue Exception => e
53
+ puts "[#{__FILE__}] ERROR: #{e.inspect}"
54
+ ensure
55
+ exit return_code
56
+ end
@@ -0,0 +1,108 @@
1
+ is_container:=$(shell [ -f './.orchestration_container_flag' ] && echo -n '1' || echo -n '0')
2
+ TERM ?= 'dumb'
3
+ pwd:=$(shell pwd)
4
+ ifdef mounted_orchestration
5
+ orchestration_dir=$(mounted_orchestration)
6
+ else
7
+ orchestration_dir=${pwd}/<%= env.orchestration_dir_name %>
8
+ endif
9
+
10
+ ifdef env_file
11
+ custom_env_file ?= 1
12
+ else
13
+ custom_env_file ?= 0
14
+ endif
15
+
16
+ ifneq (,$(wildcard ${pwd}/config/database.yml))
17
+ database_enabled = 1
18
+ else
19
+ database_enabled = 0
20
+ endif
21
+
22
+ make=$(MAKE) $1
23
+ orchestration_config_filename:=.orchestration.yml
24
+ orchestration_config:=${pwd}/${orchestration_config_filename}
25
+ print_error=printf '${red}\#${reset} '$1 | tee '${stderr}'
26
+ println_error=$(call print_error,$1'\n')
27
+ print=printf '${blue}\#${reset} '$1
28
+ println=$(call print,$1'\n')
29
+ printraw=printf $1
30
+ printrawln=$(call printraw,$1'\n')
31
+ stdout=${pwd}/log/orchestration.stdout.log
32
+ stderr=${pwd}/log/orchestration.stderr.log
33
+ log_path_length=$(shell echo "${stdout}" | wc -c)
34
+ log:= >>${stdout} 2>>${stderr}
35
+ progress_point:=perl -e 'while( my $$line = <STDIN> ) { printf("."); select()->flush(); }'
36
+ log_progress:= > >(tee -ai ${stdout} >&1 | ${progress_point}) 2> >(tee -ai ${stderr} 2>&1 | ${progress_point})
37
+ red:=$(shell tput setaf 1)
38
+ green:=$(shell tput setaf 2)
39
+ yellow:=$(shell tput setaf 3)
40
+ blue:=$(shell tput setaf 4)
41
+ magenta:=$(shell tput setaf 5)
42
+ cyan:=$(shell tput setaf 6)
43
+ gray:=$(shell tput setaf 7)
44
+ reset:=$(shell tput sgr0)
45
+ tick=[${green}✓${reset}]
46
+ cross=[${red}✘${reset}]
47
+ warn=[${yellow}!${reset}]
48
+ hr=$(call println,"$1$(shell head -c ${log_path_length} < /dev/zero | tr '\0' '=')${reset}")
49
+ managed_env_tag:=\# -|- ORCHESTRATION
50
+ standard_env_path:=${pwd}/.env
51
+ backup_env_path:=${pwd}/.env.orchestration.backup
52
+ is_managed_env:=$$(test -f '${standard_env_path}' && tail -n 1 '${standard_env_path}') == "${managed_env_tag}"*
53
+
54
+ back_up_env:=( \
55
+ [ ! -f '${standard_env_path}' ] \
56
+ || \
57
+ ( \
58
+ [ -f '${standard_env_path}' ] \
59
+ && cp '${standard_env_path}' '${backup_env_path}' \
60
+ ) \
61
+ )
62
+
63
+ replace_env:=( \
64
+ ( [ "${custom_env_file}" == "0" ] ) \
65
+ || \
66
+ ( \
67
+ [ "${custom_env_file}" == "1" ] \
68
+ && ${back_up_env} \
69
+ && cp ${env_file} '${standard_env_path}' \
70
+ && $(call printraw,'\n${managed_env_tag}') >> '${standard_env_path}' \
71
+ ) \
72
+ )
73
+
74
+ restore_env:=( \
75
+ ( \
76
+ [[ ! ${is_managed_env} ]] \
77
+ || [ ! -f '${backup_env_path}' ] \
78
+ ) \
79
+ || \
80
+ ( \
81
+ [ -f '${backup_env_path}' ] \
82
+ && [[ ${is_managed_env} ]] \
83
+ && mv '${backup_env_path}' '${standard_env_path}' \
84
+ ) \
85
+ )
86
+
87
+ key_chars:=[a-zA-Z0-9_]
88
+ censored:=**********
89
+ censor=sed 's/\(^${key_chars}*$(1)${key_chars}*\)=\(.*\)$$/\1=${censored}/'
90
+ censor_urls:=sed 's|\([a-zA-Z0-9_+]\+://.*:\).*\(@.*\)$$|\1${censored}\2|'
91
+ format_env:=$(call censor,SECRET) | \
92
+ $(call censor,PASSWORD) | \
93
+ $(call censor,TOKEN) | \
94
+ $(call censor,PRIVATE) | \
95
+ $(call censor,KEY) | \
96
+ ${censor_urls} | \
97
+ sed 's/\(^[a-zA-Z0-9_]\+\)=/${blue}\1${reset}=/' | \
98
+ sed 's/^/ /' | \
99
+ sed 's/=\(.*\)$$/=${yellow}\1${reset}/'
100
+
101
+ fail=( \
102
+ $(call printraw,' ${cross}') ; \
103
+ ${restore_env} ; \
104
+ $(call make,dump) ; \
105
+ echo ; \
106
+ $(call println,'Failed. ${cross}') ; \
107
+ exit 1 \
108
+ )
@@ -0,0 +1,18 @@
1
+ development:
2
+ clients:
3
+ default:
4
+ hosts:
5
+ - 127.0.0.1:<%= compose.call('development').local_port('mongo') %>
6
+ database: development_db
7
+
8
+ test:
9
+ clients:
10
+ default:
11
+ hosts:
12
+ - 127.0.0.1:<%= compose.call('test').local_port('mongo') %>
13
+ database: test_db
14
+
15
+ production:
16
+ clients:
17
+ default:
18
+ uri: <%%= ENV['MONGO_URL'] %>