orchestration 0.4.20 → 0.5.3
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 +4 -4
- data/Makefile +0 -9
- data/README.md +24 -48
- data/config/locales/en.yml +4 -23
- data/lib/orchestration.rb +1 -0
- data/lib/orchestration/docker_compose/app_service.rb +1 -1
- data/lib/orchestration/docker_compose/install_generator.rb +0 -16
- data/lib/orchestration/docker_healthcheck.rb +65 -0
- data/lib/orchestration/environment.rb +1 -1
- data/lib/orchestration/file_helpers.rb +1 -2
- data/lib/orchestration/install_generator.rb +25 -22
- data/lib/orchestration/service_check.rb +1 -9
- data/lib/orchestration/services/database/configuration.rb +2 -2
- data/lib/orchestration/services/database/healthcheck.rb +1 -1
- data/lib/orchestration/services/listener/configuration.rb +1 -1
- data/lib/orchestration/services/mixins/configuration_base.rb +14 -5
- data/lib/orchestration/services/mixins/healthcheck_base.rb +2 -1
- data/lib/orchestration/templates/Dockerfile.erb +2 -2
- data/lib/orchestration/templates/application.mk.erb +8 -0
- data/lib/orchestration/templates/database.yml.erb +2 -2
- data/lib/orchestration/templates/deploy.mk.erb +2 -4
- data/lib/orchestration/templates/entrypoint.sh.erb +1 -1
- data/lib/orchestration/templates/makefile_macros.mk.erb +13 -11
- data/lib/orchestration/templates/orchestration.mk.erb +66 -57
- data/lib/orchestration/version.rb +1 -1
- data/lib/tasks/orchestration.rake +30 -37
- data/orchestration.gemspec +4 -1
- metadata +3 -6
- data/MANIFEST +0 -78
- data/lib/orchestration/templates/docker-compose.override.yml.erb +0 -1
- data/lib/orchestration/templates/healthcheck.rb.erb +0 -56
- data/lib/orchestration/templates/yaml.bash.erb +0 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 90d0d9e479a7b4797751a7a6b457c613813b2c8d2df9a6b17bb11c8b26c379ff
|
|
4
|
+
data.tar.gz: 7812364e32a9f3289fea6e86591b46d055cfe35ab13244932bf23b8597b2f0c8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee3ebbeb61d6be44d819067fb0dfcc4db27ee3a4c5c14510ca5b7313838ce853568365aebe4b7593550738834fadf5f34564c6db5bc9404669aa5f9b2e3dc4b7
|
|
7
|
+
data.tar.gz: ec9cfbd34b8909e7ff72887301423739c02ec96d86e2e6bece4f25cc27738fe4de6d8486d28e02e72103fadfe408b7b1cc4e61fc8b2b45060352e1ac1a45137f
|
data/Makefile
CHANGED
|
@@ -3,12 +3,3 @@ test:
|
|
|
3
3
|
bundle exec rspec
|
|
4
4
|
bundle exec rubocop
|
|
5
5
|
bundle exec strong_versions
|
|
6
|
-
|
|
7
|
-
.PHONY: manifest
|
|
8
|
-
manifest:
|
|
9
|
-
git ls-files | GREP_OPTIONS='' grep -v '^spec' > MANIFEST
|
|
10
|
-
git diff-index --quiet HEAD || (git add MANIFEST && git commit -m "Update manifest" || :)
|
|
11
|
-
|
|
12
|
-
.PHONY: release
|
|
13
|
-
release: manifest
|
|
14
|
-
gem build orchestration.gemspec
|
data/README.md
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
# Orchestration
|
|
2
2
|
|
|
3
|
-
```
|
|
4
|
-
I've got two tickets to the game
|
|
5
|
-
It'd be great if I could take you to it this Sunday
|
|
6
|
-
--Nickelback
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
3
|
_Orchestration_ aims to provide a convenient and consistent process for working with _Rails_ and _Docker_ without obscuring underlying components.
|
|
12
4
|
|
|
13
5
|
At its core _Orchestration_ is simply a `Makefile` and a set of `docker-compose.yml` files with sensible, general-purpose default settings. Users are encouraged to tailor the generated build-out to suit their application; once the build-out has been generated it belongs to the application.
|
|
@@ -35,7 +27,7 @@ The below screenshot demonstrates _Orchestration_ being installed in a brand new
|
|
|
35
27
|
Add _Orchestration_ to your Gemfile:
|
|
36
28
|
|
|
37
29
|
```ruby
|
|
38
|
-
gem 'orchestration', '~> 0.
|
|
30
|
+
gem 'orchestration', '~> 0.5.3'
|
|
39
31
|
```
|
|
40
32
|
|
|
41
33
|
Install:
|
|
@@ -56,6 +48,11 @@ rake orchestration:install server=unicorn # (or 'puma' [default], etc.)
|
|
|
56
48
|
|
|
57
49
|
To rebuild all build-out at any time, pass `force=yes` to the above install command.
|
|
58
50
|
|
|
51
|
+
To rebuild just `orchestration/Makefile` (useful after upgrading the _Orchestration_ gem):
|
|
52
|
+
```bash
|
|
53
|
+
rake orchestration:install:makefile
|
|
54
|
+
```
|
|
55
|
+
|
|
59
56
|
You will be prompted to enter values for your _Docker_ organisation and repository name. For example, the _organisation_ and _repository_ for https://hub.docker.com/r/rubyorchestration/sampleapp are `rubyorchestration` and `sampleapp` respectively. If you are unsure of these values, they can be modified later by editing `.orchestration.yml` in the root of your project directory.
|
|
60
57
|
|
|
61
58
|
#### Configuration files
|
|
@@ -138,7 +135,20 @@ Note that `git archive` is used to generate the build context. Any uncommitted c
|
|
|
138
135
|
make build
|
|
139
136
|
```
|
|
140
137
|
|
|
141
|
-
|
|
138
|
+
The `include` option can also be passed to provide a manifest file. Any files listed in this file will also be built into the _Docker_ image. Files **must** be located within the project directory.
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
make build include=manifest.txt
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# manifest.txt
|
|
146
|
+
doc/api/swagger.json
|
|
147
|
+
doc/api/soap.xml
|
|
148
|
+
doc/api/doc.html
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
See also [build environment](#build-environment) if you use gems hosted on private _GitHub_/_Bitbucket_ repositories.
|
|
142
152
|
|
|
143
153
|
#### Push latest image
|
|
144
154
|
|
|
@@ -276,10 +286,10 @@ The output from most underlying components is hidden in an effort to make contin
|
|
|
276
286
|
tail -f log/orchestration*.log
|
|
277
287
|
```
|
|
278
288
|
|
|
279
|
-
A convenience `Makefile` target `dump` is provided
|
|
289
|
+
A convenience `Makefile` target `dump` is provided. The following command will output all consumed _stdout_, _stderr_, and _Docker Compose_ container logs for the test environment:
|
|
280
290
|
|
|
281
291
|
```bash
|
|
282
|
-
make dump
|
|
292
|
+
make dump env=test
|
|
283
293
|
```
|
|
284
294
|
|
|
285
295
|
All commands also support the `verbose` flag which will output all logs immediately to the console:
|
|
@@ -395,44 +405,10 @@ This is a convention of the _Orchestration_ gem intended to make _RabbitMQ_ conf
|
|
|
395
405
|
|
|
396
406
|
## Alternate Database Configuration Files
|
|
397
407
|
|
|
398
|
-
If you have multiple databases configured in various
|
|
399
|
-
|
|
400
|
-
Note that all services from the relevant `docker-compose.yml` configuration will be loaded when using the `make start` or `make test-setup` (called by default `make test` command).
|
|
408
|
+
If you have multiple databases configured in various `config/database.*.yml` files then the `make wait` command will automatically detect database configurations.
|
|
401
409
|
|
|
402
|
-
|
|
403
|
-
```
|
|
404
|
-
# orchestration/docker-compose.test.yml
|
|
405
|
-
version: '3.7'
|
|
406
|
-
services:
|
|
407
|
-
customdb:
|
|
408
|
-
image: postgres
|
|
409
|
-
ports:
|
|
410
|
-
- "55667:5432"
|
|
411
|
-
# ...
|
|
412
|
-
```
|
|
410
|
+
If a service `database-example` is included in the relevant _Docker Compose_ configuration then `config/database.example.yml` will be used to load the connection configuration. Note that the service name _must_ begin with `database-`.
|
|
413
411
|
|
|
414
|
-
```
|
|
415
|
-
# config/database.custom.yml
|
|
416
|
-
test:
|
|
417
|
-
adapter: postgresql
|
|
418
|
-
host: 127.0.0.1
|
|
419
|
-
port: 55667
|
|
420
|
-
username: postgres
|
|
421
|
-
password: password
|
|
422
|
-
database: postgres
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
The following command can be used to ensure that the `customdb` service is available:
|
|
426
|
-
```
|
|
427
|
-
make wait-database service=custom config=config/database.custom.yml env=test
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
You may wish to extend the example `Makefile` to include something like this:
|
|
431
|
-
```
|
|
432
|
-
test: test-setup
|
|
433
|
-
$(MAKE) wait-database service=custom config=config/database.custom.yml env=test
|
|
434
|
-
# ...
|
|
435
|
-
```
|
|
436
412
|
## License
|
|
437
413
|
|
|
438
414
|
[MIT License](LICENSE)
|
data/config/locales/en.yml
CHANGED
|
@@ -2,6 +2,7 @@ en:
|
|
|
2
2
|
orchestration:
|
|
3
3
|
attempt_limit: "Unable to reconnect after %{limit} attempts. Aborting."
|
|
4
4
|
default: "default"
|
|
5
|
+
auto_update: "Orchestration Makefile was automatically updated to the latest version."
|
|
5
6
|
|
|
6
7
|
app:
|
|
7
8
|
waiting: "Waiting for app: %{config}"
|
|
@@ -19,10 +20,6 @@ en:
|
|
|
19
20
|
ready: "Mongo is ready."
|
|
20
21
|
bad_config: "Unable to parse Mongo config: %{path}. Expected section for one of: %{expected}"
|
|
21
22
|
|
|
22
|
-
haproxy:
|
|
23
|
-
waiting: "Waiting for HAProxy: %{config}"
|
|
24
|
-
ready: "HAProxy is ready."
|
|
25
|
-
|
|
26
23
|
rabbitmq:
|
|
27
24
|
waiting: "Waiting for RabbitMQ: %{config}"
|
|
28
25
|
ready: "RabbitMQ is ready."
|
|
@@ -42,24 +39,8 @@ en:
|
|
|
42
39
|
prompt: "project name"
|
|
43
40
|
|
|
44
41
|
rake:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
unknown_web_server: "Unrecognised web server '%{server}'. Expected: %{expected}"
|
|
48
|
-
|
|
49
|
-
database:
|
|
50
|
-
wait: "Wait for database to become available"
|
|
51
|
-
|
|
52
|
-
listener:
|
|
53
|
-
wait: "Wait for a locally-bound service to accept connections (pass `service=NAME`)"
|
|
54
|
-
|
|
55
|
-
mongo:
|
|
56
|
-
wait: "Wait for Mongo to become available"
|
|
57
|
-
|
|
58
|
-
haproxy:
|
|
59
|
-
wait: "Wait for HAProxy to become available"
|
|
60
|
-
|
|
61
|
-
rabbitmq:
|
|
62
|
-
wait: "Wait for RabbitMQ to become available"
|
|
63
|
-
|
|
42
|
+
config: "Parse and output Orchestration config (internal use)"
|
|
43
|
+
healthcheck: "Execute healthcheck; used for HEALTHCHECK command in Docker image"
|
|
64
44
|
install: "Install Orchestration tools"
|
|
65
45
|
install_makefile: "(Re)create orchestration/Makefile"
|
|
46
|
+
wait: "Wait for development/test dependencies to be available"
|
data/lib/orchestration.rb
CHANGED
|
@@ -22,6 +22,7 @@ require 'orchestration/file_helpers'
|
|
|
22
22
|
require 'orchestration/docker_compose'
|
|
23
23
|
require 'orchestration/environment'
|
|
24
24
|
require 'orchestration/errors'
|
|
25
|
+
require 'orchestration/docker_healthcheck'
|
|
25
26
|
require 'orchestration/install_generator'
|
|
26
27
|
require 'orchestration/railtie' if defined?(Rails)
|
|
27
28
|
require 'orchestration/service_check'
|
|
@@ -27,7 +27,7 @@ module Orchestration
|
|
|
27
27
|
|
|
28
28
|
def healthcheck
|
|
29
29
|
{
|
|
30
|
-
'test' => ['
|
|
30
|
+
'test' => ['bundle', 'exec', 'rake', 'orchestration:healthcheck'],
|
|
31
31
|
# Defaults according to
|
|
32
32
|
# https://docs.docker.com/engine/reference/builder/#healthcheck
|
|
33
33
|
# Except start_period which cannot be set to 0s
|
|
@@ -10,10 +10,6 @@ module Orchestration
|
|
|
10
10
|
@terminal = terminal
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def docker_compose_yml
|
|
14
|
-
create_compose_file
|
|
15
|
-
end
|
|
16
|
-
|
|
17
13
|
def docker_compose_test_yml
|
|
18
14
|
create_compose_file(:test)
|
|
19
15
|
end
|
|
@@ -22,22 +18,10 @@ module Orchestration
|
|
|
22
18
|
create_compose_file(:development)
|
|
23
19
|
end
|
|
24
20
|
|
|
25
|
-
def docker_compose_local_yml
|
|
26
|
-
create_compose_file(:local)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
21
|
def docker_compose_production_yml
|
|
30
22
|
create_compose_file(:production)
|
|
31
23
|
end
|
|
32
24
|
|
|
33
|
-
def docker_compose_override_yml
|
|
34
|
-
simple_copy(
|
|
35
|
-
'docker-compose.override.yml',
|
|
36
|
-
@env.docker_compose_path(:override),
|
|
37
|
-
overwrite: false
|
|
38
|
-
)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
25
|
def enabled_services(environment)
|
|
42
26
|
service_names(environment).select { |name| service_enabled?(name) }
|
|
43
27
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'net/http'
|
|
4
|
+
module Orchestration
|
|
5
|
+
class DockerHealthcheck
|
|
6
|
+
def self.execute
|
|
7
|
+
new.execute
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def execute
|
|
11
|
+
return_code = 1
|
|
12
|
+
|
|
13
|
+
# rubocop:disable Lint/RescueException
|
|
14
|
+
begin
|
|
15
|
+
response = run
|
|
16
|
+
return_code = 0 if success?(response.code)
|
|
17
|
+
puts message(response.code)
|
|
18
|
+
rescue Exception => e
|
|
19
|
+
puts "[#{__FILE__}] ERROR: #{e.inspect}"
|
|
20
|
+
ensure
|
|
21
|
+
exit return_code
|
|
22
|
+
end
|
|
23
|
+
# rubocop:enable Lint/RescueException
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def run
|
|
29
|
+
client = Net::HTTP.new(
|
|
30
|
+
ENV.fetch('WEB_HOST', 'localhost'),
|
|
31
|
+
ENV.fetch('WEB_PORT', '8080').to_i
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
client.read_timeout = ENV.fetch('WEB_HEALTHCHECK_READ_TIMEOUT', '10').to_i
|
|
35
|
+
client.open_timeout = ENV.fetch('WEB_HEALTHCHECK_OPEN_TIMEOUT', '10').to_i
|
|
36
|
+
|
|
37
|
+
client.start do |request|
|
|
38
|
+
request.get(ENV.fetch('WEB_HEALTHCHECK_PATH') { '/' })
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def success_codes
|
|
43
|
+
ENV.fetch('WEB_HEALTHCHECK_SUCCESS_CODES', '200,202,204').split(',')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def success?(code)
|
|
47
|
+
success_codes.include?(code.to_s)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def message(code)
|
|
51
|
+
if success?(code)
|
|
52
|
+
outcome = 'SUCCESS ✓ '
|
|
53
|
+
in_or_not = 'IN'
|
|
54
|
+
else
|
|
55
|
+
outcome = 'FAILURE ✘ '
|
|
56
|
+
in_or_not = 'NOT IN'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
accepted = success_codes.join(', ')
|
|
60
|
+
message = "#{in_or_not} [#{accepted}] : #{outcome} [#{__FILE__}]"
|
|
61
|
+
|
|
62
|
+
"# HTTP_STATUS(#{code}) #{message}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -66,9 +66,8 @@ module Orchestration
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def skip?(present, content, previous_content, options)
|
|
69
|
-
overwrite = options.fetch(:overwrite, true)
|
|
70
69
|
return false unless present
|
|
71
|
-
return true unless overwrite || force?
|
|
70
|
+
return true unless options.fetch(:overwrite, true) || force?
|
|
72
71
|
|
|
73
72
|
previous_content == content
|
|
74
73
|
end
|
|
@@ -27,10 +27,18 @@ module Orchestration
|
|
|
27
27
|
@terminal.write(:skip, relpath)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
def
|
|
30
|
+
def verify_makefile(skip = true)
|
|
31
|
+
# Only run when called explicitly [from Rake tasks].
|
|
32
|
+
# (I know this is hacky).
|
|
33
|
+
return if skip
|
|
34
|
+
|
|
31
35
|
content = template('orchestration.mk', makefile_environment)
|
|
32
36
|
path = @env.orchestration_root.join('Makefile')
|
|
33
|
-
path.exist?
|
|
37
|
+
return if path.exist? && content == File.read(path)
|
|
38
|
+
|
|
39
|
+
write_file(path, content)
|
|
40
|
+
@terminal.write(:update, 'Makefile')
|
|
41
|
+
@terminal.write(:status, t(:auto_update))
|
|
34
42
|
end
|
|
35
43
|
|
|
36
44
|
def application_makefile
|
|
@@ -39,6 +47,12 @@ module Orchestration
|
|
|
39
47
|
inject_if_missing(path, 'include orchestration/Makefile')
|
|
40
48
|
end
|
|
41
49
|
|
|
50
|
+
def orchestration_makefile
|
|
51
|
+
content = template('orchestration.mk', makefile_environment)
|
|
52
|
+
path = @env.orchestration_root.join('Makefile')
|
|
53
|
+
path.exist? ? update_file(path, content) : create_file(path, content)
|
|
54
|
+
end
|
|
55
|
+
|
|
42
56
|
def dockerfile
|
|
43
57
|
create_file(
|
|
44
58
|
orchestration_dir.join('Dockerfile'),
|
|
@@ -54,23 +68,10 @@ module Orchestration
|
|
|
54
68
|
FileUtils.chmod('a+x', path)
|
|
55
69
|
end
|
|
56
70
|
|
|
57
|
-
def gitignore
|
|
58
|
-
path = @env.root.join('.gitignore')
|
|
59
|
-
globs = %w[.build/ .deploy/ Gemfile Gemfile.lock docker-compose.local.yml]
|
|
60
|
-
lines = %w[orchestration/.sidecar .env deploy.tar] + globs.map do |line|
|
|
61
|
-
"#{@env.orchestration_dir_name}/#{line}"
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
ensure_lines_in_file(path, lines)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
71
|
def docker_compose
|
|
68
|
-
@docker_compose.docker_compose_yml
|
|
69
72
|
@docker_compose.docker_compose_test_yml
|
|
70
73
|
@docker_compose.docker_compose_development_yml
|
|
71
|
-
@docker_compose.docker_compose_local_yml
|
|
72
74
|
@docker_compose.docker_compose_production_yml
|
|
73
|
-
@docker_compose.docker_compose_override_yml
|
|
74
75
|
end
|
|
75
76
|
|
|
76
77
|
def puma
|
|
@@ -112,16 +113,18 @@ module Orchestration
|
|
|
112
113
|
service_config('rabbitmq.yml', Services::RabbitMQ::Configuration)
|
|
113
114
|
end
|
|
114
115
|
|
|
115
|
-
def
|
|
116
|
-
simple_copy('
|
|
116
|
+
def env
|
|
117
|
+
simple_copy('env', @env.root.join('.env'), overwrite: false)
|
|
117
118
|
end
|
|
118
119
|
|
|
119
|
-
def
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
def gitignore
|
|
121
|
+
path = @env.root.join('.gitignore')
|
|
122
|
+
globs = %w[.build/ .deploy/ Gemfile Gemfile.lock docker-compose.local.yml]
|
|
123
|
+
lines = %w[orchestration/.sidecar .env deploy.tar] + globs.map do |line|
|
|
124
|
+
"#{@env.orchestration_dir_name}/#{line}"
|
|
125
|
+
end
|
|
122
126
|
|
|
123
|
-
|
|
124
|
-
simple_copy('env', @env.root.join('.env'), overwrite: false)
|
|
127
|
+
ensure_lines_in_file(path, lines)
|
|
125
128
|
end
|
|
126
129
|
|
|
127
130
|
def deploy_mk
|
|
@@ -16,7 +16,7 @@ module Orchestration
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def run
|
|
19
|
-
return
|
|
19
|
+
return unless @service.configuration.configured?
|
|
20
20
|
|
|
21
21
|
echo_start
|
|
22
22
|
success = attempt_connection
|
|
@@ -39,14 +39,6 @@ module Orchestration
|
|
|
39
39
|
false
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def echo_missing
|
|
43
|
-
@terminal.write(
|
|
44
|
-
@service_name.to_sym,
|
|
45
|
-
"#{@service.configuration.error} (skipping)",
|
|
46
|
-
:error
|
|
47
|
-
)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
42
|
def echo_start
|
|
51
43
|
@terminal.write(@service_name.to_sym, '', :status)
|
|
52
44
|
end
|
|
@@ -18,14 +18,14 @@ module Orchestration
|
|
|
18
18
|
"[#{adapter.name}] #{host}:#{port}"
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def settings
|
|
21
|
+
def settings(healthcheck: false)
|
|
22
22
|
{
|
|
23
23
|
adapter: adapter.name,
|
|
24
24
|
host: host,
|
|
25
25
|
port: port,
|
|
26
26
|
username: username,
|
|
27
27
|
password: password,
|
|
28
|
-
database: database
|
|
28
|
+
database: healthcheck ? adapter.credentials['database'] : database
|
|
29
29
|
}.transform_keys(&:to_s)
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -29,6 +29,7 @@ module Orchestration
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def host
|
|
32
|
+
return @service_name if @env.environment == 'test' && @options[:sidecar]
|
|
32
33
|
return '127.0.0.1' if %w[test development].include?(@env.environment)
|
|
33
34
|
|
|
34
35
|
@service_name
|
|
@@ -42,15 +43,23 @@ module Orchestration
|
|
|
42
43
|
false
|
|
43
44
|
end
|
|
44
45
|
|
|
46
|
+
def image
|
|
47
|
+
service['image']
|
|
48
|
+
end
|
|
49
|
+
|
|
45
50
|
def port
|
|
46
51
|
return @env.app_port if @service_name == 'app'
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
local, remote = parse_port(service).map(&:to_i)
|
|
54
|
+
return remote if @env.environment == 'test' && @options[:sidecar]
|
|
55
|
+
|
|
56
|
+
(@env.environment == 'production' ? remote : local)
|
|
57
|
+
end
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
def service
|
|
60
|
+
@service ||= @env.docker_compose_config
|
|
61
|
+
.fetch('services')
|
|
62
|
+
.fetch(@service_name)
|
|
54
63
|
end
|
|
55
64
|
|
|
56
65
|
def parse_port(service)
|
|
@@ -37,7 +37,8 @@ module Orchestration
|
|
|
37
37
|
|
|
38
38
|
def initialize(env, service_name = nil, options = {})
|
|
39
39
|
@options = options
|
|
40
|
-
@
|
|
40
|
+
@options[:sidecar] = options[:sidecar] && !options[:sidecar].empty?
|
|
41
|
+
@configuration = configuration_class.new(env, service_name, @options)
|
|
41
42
|
end
|
|
42
43
|
|
|
43
44
|
def service_name
|
|
@@ -20,10 +20,10 @@ COPY .build/Gemfile .build/Gemfile.lock ./
|
|
|
20
20
|
RUN bundle install --without development test --deployment
|
|
21
21
|
<% if defined?(Webpacker) %>
|
|
22
22
|
COPY .build/package.json .build/yarn.lock ./
|
|
23
|
-
RUN . /root/.bashrc
|
|
23
|
+
RUN . /root/.bashrc ; yarn install
|
|
24
24
|
<% end %>
|
|
25
25
|
ADD .build/context.tar .
|
|
26
|
-
<% if defined?(Webpacker) %>RUN . /root/.bashrc
|
|
26
|
+
<% if defined?(Webpacker) %>RUN . /root/.bashrc ; NODE_ENV=production RAILS_ENV=production yarn install && NODE_ENV=production RAILS_ENV=production SECRET_KEY_BASE=abc123 bundle exec rake assets:precompile<% elsif Rake::Task.tasks.map(&:name).include?('assets:precompile') %>RUN NODE_ENV=production RAILS_ENV=production SECRET_KEY_BASE=abc123 bundle exec rake assets:precompile<% end %>
|
|
27
27
|
RUN echo "${GIT_COMMIT}" > /app/GIT_COMMIT
|
|
28
28
|
HEALTHCHECK --interval=<%= healthcheck['interval'] %> \
|
|
29
29
|
--timeout=<%= healthcheck['timeout'] %> \
|
|
@@ -12,3 +12,11 @@
|
|
|
12
12
|
test: test-setup
|
|
13
13
|
bundle exec rspec
|
|
14
14
|
bundle exec rubocop
|
|
15
|
+
|
|
16
|
+
# Start development containers and create/migrate/seed database
|
|
17
|
+
.PHONY: develop
|
|
18
|
+
develop: start
|
|
19
|
+
bundle install
|
|
20
|
+
bundle exec rake db:create
|
|
21
|
+
bundle exec rake db:migrate
|
|
22
|
+
bundle exec rake db:seed
|
|
@@ -8,7 +8,7 @@ development:
|
|
|
8
8
|
port: <%= compose.call('development').local_port('database') %>
|
|
9
9
|
username: <%= compose.call(nil).database_adapter.credentials['username'] %>
|
|
10
10
|
password: <%= compose.call(nil).database_adapter.credentials['password'] %>
|
|
11
|
-
database:
|
|
11
|
+
database: development
|
|
12
12
|
<%% if ENV.key?('DEVELOPMENT_DATABASE_URL') %>
|
|
13
13
|
url: <%%= ENV['DEVELOPMENT_DATABASE_URL'] %>
|
|
14
14
|
<%% end %>
|
|
@@ -21,7 +21,7 @@ test:
|
|
|
21
21
|
port: <%= compose.call('test').local_port('database') %>
|
|
22
22
|
username: <%= compose.call(nil).database_adapter.credentials['username'] %>
|
|
23
23
|
password: <%= compose.call(nil).database_adapter.credentials['password'] %>
|
|
24
|
-
database:
|
|
24
|
+
database: test
|
|
25
25
|
# Useful for certain continuous integration environments (e.g. Jenkins in
|
|
26
26
|
# Docker) where the DB hostname may be a service name rather than `127.0.0.1`:
|
|
27
27
|
<%% if ENV.key?('TEST_DATABASE_URL') %>
|
|
@@ -22,9 +22,7 @@ compose_base:=env HOST_UID=$(shell id -u) \
|
|
|
22
22
|
DOCKER_REPOSITORY=%%REPOSITORY%%:%%VERSION%% \
|
|
23
23
|
docker-compose \
|
|
24
24
|
-p ${project_name} \
|
|
25
|
-
-f docker-compose.yml
|
|
26
|
-
|
|
27
|
-
compose:=${compose_base} -f docker-compose.production.yml -f docker-compose.override.yml
|
|
25
|
+
-f docker-compose.production.yml
|
|
28
26
|
|
|
29
27
|
.PHONY: deploy
|
|
30
28
|
deploy:
|
|
@@ -36,7 +34,7 @@ endif
|
|
|
36
34
|
|
|
37
35
|
.PHONY: deploy-stack
|
|
38
36
|
deploy-stack:
|
|
39
|
-
|
|
37
|
+
${compose} config | docker stack deploy --prune --with-registry-auth -c - ${project_name}
|
|
40
38
|
|
|
41
39
|
.PHONY: console
|
|
42
40
|
service := app
|
|
@@ -87,17 +87,19 @@ restore_env:=( \
|
|
|
87
87
|
|
|
88
88
|
key_chars:=[a-zA-Z0-9_]
|
|
89
89
|
censored:=**********
|
|
90
|
-
censor=
|
|
91
|
-
censor_urls:=
|
|
92
|
-
format_env
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
90
|
+
censor=s/\(^${key_chars}*$(1)${key_chars}*\)=\(.*\)$$/\1=${censored}/
|
|
91
|
+
censor_urls:=s|\([a-zA-Z0-9_+]\+://.*:\).*\(@.*\)$$|\1${censored}\2|
|
|
92
|
+
format_env:=sed '$(call censor,SECRET); \
|
|
93
|
+
$(call censor,TOKEN); \
|
|
94
|
+
$(call censor,PRIVATE); \
|
|
95
|
+
$(call censor,KEY); \
|
|
96
|
+
$(censor_urls); \
|
|
97
|
+
/^\s*$$/d; \
|
|
98
|
+
/^\s*\#/d; \
|
|
99
|
+
s/\(^[a-zA-Z0-9_]\+\)=/${blue}\1${reset}=/; \
|
|
100
|
+
s/^/ /; \
|
|
101
|
+
s/=\(.*\)$$/=${yellow}\1${reset}/' | \
|
|
102
|
+
sort
|
|
101
103
|
|
|
102
104
|
fail=( \
|
|
103
105
|
$(call printraw,' ${cross}') ; \
|
|
@@ -38,8 +38,9 @@ ifneq (,$(wildcard ${env_file}))
|
|
|
38
38
|
rake=. ${env_file} && ${rake_cmd}
|
|
39
39
|
endif
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
docker_config:=$(shell ${rake} orchestration:config)
|
|
42
|
+
docker_organization=$(word 1,$(docker_config))
|
|
43
|
+
docker_repository=$(word 2,$(docker_config))
|
|
43
44
|
|
|
44
45
|
ifeq (,$(project_name))
|
|
45
46
|
project_base = ${docker_repository}_${env}
|
|
@@ -73,19 +74,26 @@ else
|
|
|
73
74
|
compose_project_name = ${project_base}
|
|
74
75
|
endif
|
|
75
76
|
|
|
76
|
-
compose_base=env
|
|
77
|
+
compose_base=env -i \
|
|
78
|
+
PATH=$(PATH) \
|
|
79
|
+
HOST_UID=$(shell id -u) \
|
|
77
80
|
DOCKER_ORGANIZATION="${docker_organization}" \
|
|
78
81
|
DOCKER_REPOSITORY="${docker_repository}" \
|
|
79
82
|
COMPOSE_PROJECT_NAME="${compose_project_name}" \
|
|
80
83
|
${sidecar_compose} \
|
|
81
84
|
docker-compose \
|
|
82
|
-
-f
|
|
85
|
+
-f ${orchestration_dir}/docker-compose.${env}.yml
|
|
83
86
|
|
|
84
87
|
git_branch ?= $(if $(branch),$(branch),$(shell git rev-parse --abbrev-ref HEAD))
|
|
85
|
-
|
|
88
|
+
ifndef dev
|
|
89
|
+
git_version ?= $(shell git rev-parse --short --verify ${git_branch})
|
|
90
|
+
else
|
|
91
|
+
git_version = dev
|
|
92
|
+
endif
|
|
93
|
+
|
|
86
94
|
docker_image=${docker_organization}/${docker_repository}:${git_version}
|
|
87
95
|
|
|
88
|
-
compose=${compose_base}
|
|
96
|
+
compose=${compose_base}
|
|
89
97
|
random_str=cat /dev/urandom | LC_ALL=C tr -dc 'a-z' | head -c $1
|
|
90
98
|
|
|
91
99
|
ifneq (,$(wildcard ${orchestration_dir}/docker-compose.local.yml))
|
|
@@ -101,9 +109,9 @@ ifndef network
|
|
|
101
109
|
start: network := ${compose_project_name}_default
|
|
102
110
|
endif
|
|
103
111
|
start: _clean-logs
|
|
104
|
-
@$(call print,'${yellow}Starting containers${reset} ...')
|
|
112
|
+
@$(call print,'${yellow}Starting ${cyan}${env}${yellow} containers${reset} ...')
|
|
105
113
|
ifeq (${env},$(filter ${env},test development))
|
|
106
|
-
@${compose} up --detach --force-recreate --renew-anon-volumes ${services} ${log} || ${fail}
|
|
114
|
+
@${compose} up --detach --force-recreate --renew-anon-volumes --remove-orphans ${services} ${log} || ${fail}
|
|
107
115
|
@[ -n '${sidecar}' ] && \
|
|
108
116
|
( \
|
|
109
117
|
$(call printraw,' ${yellow}(joining dependency network ${green}${network}${yellow})${reset} ... ') ; \
|
|
@@ -116,15 +124,11 @@ ifeq (${env},$(filter ${env},test development))
|
|
|
116
124
|
) \
|
|
117
125
|
|| ( [ -z '${sidecar}' ] || ${fail} )
|
|
118
126
|
else
|
|
119
|
-
@${compose} up --detach --scale app=$${instances:-1} ${
|
|
127
|
+
@${compose} up --detach --scale app=$${instances:-1} ${log} || ${fail}
|
|
120
128
|
endif
|
|
121
129
|
@$(call printrawln,' ${green}started${reset} ${tick}')
|
|
122
130
|
@$(call println,'${yellow}Waiting for services to become available${reset} ...')
|
|
123
|
-
ifdef services
|
|
124
|
-
@$(call make,wait services='${services}') 2>${stderr} || ${fail}
|
|
125
|
-
else
|
|
126
131
|
@$(call make,wait) 2>${stderr} || ${fail}
|
|
127
|
-
endif
|
|
128
132
|
|
|
129
133
|
<% services.each do |service| %>
|
|
130
134
|
.PHONY: start-<%= service %>
|
|
@@ -136,7 +140,7 @@ start-<%= service %>:
|
|
|
136
140
|
.PHONY: stop
|
|
137
141
|
stop: network := ${compose_project_name}_default
|
|
138
142
|
stop:
|
|
139
|
-
@$(call print,'${yellow}Stopping containers${reset} ...')
|
|
143
|
+
@$(call print,'${yellow}Stopping ${cyan}${env}${yellow} containers${reset} ...')
|
|
140
144
|
@if docker ps --format "{{.ID}}" | grep -q $(shell hostname) ; \
|
|
141
145
|
then \
|
|
142
146
|
( docker network disconnect ${network} $(shell hostname) ${log} || : ) \
|
|
@@ -169,7 +173,7 @@ serve:
|
|
|
169
173
|
then ( \
|
|
170
174
|
$(call println,'${yellow}Environment${reset}: ${green}${env_file}${reset}') && \
|
|
171
175
|
cat '${env_file}' | ${format_env} && \
|
|
172
|
-
$(call
|
|
176
|
+
$(call printrawln,'') \
|
|
173
177
|
) ; \
|
|
174
178
|
fi
|
|
175
179
|
${rails}
|
|
@@ -182,7 +186,7 @@ console:
|
|
|
182
186
|
then ( \
|
|
183
187
|
$(call println,'${yellow}Environment${reset}: ${green}${env_file}${reset}') && \
|
|
184
188
|
cat '${env_file}' | ${format_env} && \
|
|
185
|
-
$(call
|
|
189
|
+
$(call printrawln,'') \
|
|
186
190
|
) ; \
|
|
187
191
|
fi
|
|
188
192
|
${rails} console
|
|
@@ -190,23 +194,25 @@ console:
|
|
|
190
194
|
.PHONY: test-setup
|
|
191
195
|
test-setup: env := test
|
|
192
196
|
test-setup:
|
|
197
|
+
ifndef light
|
|
193
198
|
@$(call make,start env=test)
|
|
194
|
-
ifneq (,$(wildcard config/database.yml))
|
|
199
|
+
ifneq (,$(wildcard config/database.yml))
|
|
195
200
|
${rake} db:create || :
|
|
196
|
-
|
|
201
|
+
ifneq (,$(wildcard db/structure.sql))
|
|
197
202
|
${rake} db:structure:load
|
|
198
|
-
|
|
203
|
+
else ifneq (,$(wildcard db/schema.rb))
|
|
199
204
|
${rake} db:schema:load
|
|
200
|
-
|
|
205
|
+
endif
|
|
201
206
|
|
|
202
207
|
${rake} db:migrate
|
|
208
|
+
endif
|
|
203
209
|
endif
|
|
204
210
|
|
|
205
211
|
.PHONY: dump
|
|
206
212
|
dump:
|
|
207
213
|
ifndef verbose
|
|
208
214
|
@$(call println)
|
|
209
|
-
@$(call println,'${yellow}Captured${reset} ${green}stdout${reset} ${yellow}and${reset} ${red}stderr${reset} ${yellow}log data${reset}:')
|
|
215
|
+
@$(call println,'${yellow}Captured${reset} ${green}stdout${reset} ${yellow}and${reset} ${red}stderr${reset} ${yellow}log data [${cyan}${env}${yellow}]${reset}:')
|
|
210
216
|
@$(call println)
|
|
211
217
|
@echo
|
|
212
218
|
@test -f '${stdout}' && ( \
|
|
@@ -226,6 +232,14 @@ ifndef verbose
|
|
|
226
232
|
$(call hr,${red}) ; \
|
|
227
233
|
)
|
|
228
234
|
endif
|
|
235
|
+
@echo ; \
|
|
236
|
+
$(call hr,${yellow}) ; \
|
|
237
|
+
$(call println,'${gray}docker-compose logs${reset}') ; \
|
|
238
|
+
$(call hr,${yellow}) ; \
|
|
239
|
+
echo
|
|
240
|
+
@${compose} logs
|
|
241
|
+
@echo ; \
|
|
242
|
+
$(call hr,${yellow})
|
|
229
243
|
|
|
230
244
|
.PHONY: image
|
|
231
245
|
image:
|
|
@@ -245,10 +259,6 @@ endif
|
|
|
245
259
|
-e "s/%%ORGANIZATION%%/${docker_organization}/g" \
|
|
246
260
|
${orchestration_dir}/deploy.mk > \
|
|
247
261
|
${orchestration_dir}/.deploy/${docker_repository}/Makefile
|
|
248
|
-
@cp ${orchestration_dir}/docker-compose.yml \
|
|
249
|
-
${orchestration_dir}/docker-compose.production.yml \
|
|
250
|
-
${orchestration_dir}/docker-compose.override.yml \
|
|
251
|
-
${orchestration_dir}/.deploy/${docker_repository}/
|
|
252
262
|
@bundle_path="${path}" ; tar -C '${orchestration_dir}/.deploy' -cf "$${bundle_path:-./bundle.tar}" ./${docker_repository}
|
|
253
263
|
|
|
254
264
|
.PHONY: deploy
|
|
@@ -296,55 +306,43 @@ endif
|
|
|
296
306
|
### Service healthcheck commands ###
|
|
297
307
|
|
|
298
308
|
.PHONY: wait
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
wait: wait-<%= service %>
|
|
302
|
-
endif
|
|
303
|
-
<% end %>
|
|
304
|
-
ifndef services
|
|
305
|
-
wait: <%= services.map { |command| "wait-#{command}" }.join(' ') %>
|
|
306
|
-
endif
|
|
309
|
+
wait:
|
|
310
|
+
@${rake} orchestration:wait
|
|
307
311
|
@$(call println,'${yellow}All services${reset} ${green}ready${reset}. ${tick}')
|
|
308
312
|
|
|
309
313
|
## Generic Listener healthcheck for TCP services ##
|
|
310
314
|
|
|
311
315
|
wait-listener:
|
|
312
|
-
@${rake} orchestration:listener:wait service=${service}
|
|
313
|
-
|
|
314
|
-
## Test/development wait commands
|
|
315
|
-
|
|
316
|
-
<% services.each do |service| %>
|
|
317
|
-
<% next if service.to_sym == :app %>
|
|
318
|
-
.PHONY: wait-<%= service %>
|
|
319
|
-
ifdef config
|
|
320
|
-
wait-<%= service %>: configvar := config=$(config)
|
|
321
|
-
endif
|
|
322
|
-
ifdef service
|
|
323
|
-
wait-<%= service %>: servicevar := service=$(service)
|
|
324
|
-
endif
|
|
325
|
-
wait-<%= service %>:
|
|
326
|
-
@${rake} orchestration:<%= service %>:wait $(configvar) $(servicevar)
|
|
327
|
-
|
|
328
|
-
<% end %>
|
|
329
|
-
|
|
330
|
-
.PHONY: wait-app
|
|
331
|
-
wait-app:
|
|
332
|
-
@# no-op
|
|
316
|
+
@${rake} orchestration:listener:wait service=${service} sidecar=${sidecar}
|
|
333
317
|
|
|
334
318
|
### Docker build commands ###
|
|
335
319
|
|
|
336
320
|
.PHONY: build
|
|
337
|
-
build:
|
|
338
|
-
build:
|
|
321
|
+
build: build_dir = ${orchestration_dir}/.build
|
|
322
|
+
build: context = ${build_dir}/context.tar
|
|
323
|
+
build: check-local-changes
|
|
339
324
|
@$(call print,'${yellow}Preparing build context from${reset} ${cyan}${git_branch}:${git_version}${reset} ... ')
|
|
340
325
|
@mkdir -p ${orchestration_dir}/.build ${log} || ${fail}
|
|
326
|
+
ifndef dev
|
|
341
327
|
@git show ${git_branch}:./Gemfile > ${orchestration_dir}/.build/Gemfile 2>${stderr} || ${fail}
|
|
342
328
|
@git show ${git_branch}:./Gemfile.lock > ${orchestration_dir}/.build/Gemfile.lock 2>${stderr} || ${fail}
|
|
343
329
|
<% if defined?(Webpacker) %> @git show ${git_branch}:./package.json > ${orchestration_dir}/.build/package.json 2>${stderr} || ${fail}<% end %>
|
|
344
330
|
<% if defined?(Webpacker) %> @git show ${git_branch}:./yarn.lock > ${orchestration_dir}/.build/yarn.lock 2>${stderr} || ${fail}<% end %>
|
|
345
331
|
@git archive --format 'tar' -o '${context}' '${git_branch}' ${log} || ${fail}
|
|
346
|
-
|
|
332
|
+
else
|
|
333
|
+
@tar -cvf '${context}' . ${log} || ${fail}
|
|
334
|
+
endif
|
|
347
335
|
@$(call printrawln,'${green}complete.${reset} ${tick}')
|
|
336
|
+
ifdef include
|
|
337
|
+
@$(call print,'${yellow}Including files from:${reset} ${cyan}${include}${reset} ...')
|
|
338
|
+
@(while read line; do \
|
|
339
|
+
export line; \
|
|
340
|
+
include_dir="${build_dir}/$$(dirname "$${line}")/" && \
|
|
341
|
+
mkdir -p "$${include_dir}" && cp "$${line}" "$${include_dir}" \
|
|
342
|
+
&& (cd '${orchestration_dir}/.build/' && tar rf 'context.tar' "$${line}"); \
|
|
343
|
+
done < '${include}') ${log} || ${fail}
|
|
344
|
+
@$(call printrawln,' ${green}complete.${reset} ${tick}')
|
|
345
|
+
endif
|
|
348
346
|
ifdef sidecar
|
|
349
347
|
# Assume we are in a line-buffered environment (e.g. Jenkins)
|
|
350
348
|
@$(call println,'${yellow}Building image${reset} ...')
|
|
@@ -368,6 +366,17 @@ push:
|
|
|
368
366
|
@docker push ${docker_image} ${log_progress} || ${fail}
|
|
369
367
|
@$(call printrawln,' ${green}complete${reset}. ${tick}')
|
|
370
368
|
|
|
369
|
+
.PHONY: check-local-changes
|
|
370
|
+
check-local-changes:
|
|
371
|
+
ifndef dev
|
|
372
|
+
@if [[ ! -z "$$(git status --porcelain)" ]] ; \
|
|
373
|
+
then \
|
|
374
|
+
$(call println,'${red}You have uncommitted changes which will not be included in your build:${reset}') ; \
|
|
375
|
+
git status --porcelain ; \
|
|
376
|
+
$(call println,'${yellow}Use ${cyan}make build dev=1${reset} ${yellow}to include these files.${reset}\n') ; \
|
|
377
|
+
fi
|
|
378
|
+
endif
|
|
379
|
+
|
|
371
380
|
### Internal Commands ###
|
|
372
381
|
#
|
|
373
382
|
.PHONY: _clean-logs
|
|
@@ -15,47 +15,40 @@ namespace :orchestration do
|
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
nil, nil, config_path: ENV['config'], service_name: ENV['service']
|
|
23
|
-
)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
namespace :database do
|
|
28
|
-
desc I18n.t('orchestration.rake.database.wait')
|
|
29
|
-
task :wait do
|
|
30
|
-
Orchestration::Services::Database::Healthcheck.start(
|
|
31
|
-
nil, nil, config_path: ENV['config'], service_name: ENV['service']
|
|
32
|
-
)
|
|
33
|
-
end
|
|
18
|
+
desc I18n.t('orchestration.rake.config')
|
|
19
|
+
task :config do
|
|
20
|
+
config = YAML.safe_load(File.read('.orchestration.yml'))
|
|
21
|
+
puts "#{config['docker']['organization']} #{config['docker']['repository']}"
|
|
34
22
|
end
|
|
35
23
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Orchestration::Services::Mongo::Healthcheck.start(
|
|
40
|
-
nil, nil, config_path: ENV['config'], service_name: ENV['service']
|
|
41
|
-
)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
namespace :rabbitmq do
|
|
46
|
-
desc I18n.t('orchestration.rake.rabbitmq.wait')
|
|
47
|
-
task :wait do
|
|
48
|
-
Orchestration::Services::RabbitMQ::Healthcheck.start(
|
|
49
|
-
nil, nil, config_path: ENV['config'], service_name: ENV['service']
|
|
50
|
-
)
|
|
51
|
-
end
|
|
24
|
+
desc I18n.t('orchestration.rake.healthcheck')
|
|
25
|
+
task :healthcheck do
|
|
26
|
+
Orchestration::DockerHealthcheck.execute
|
|
52
27
|
end
|
|
53
28
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
29
|
+
desc I18n.t('orchestration.rake.wait')
|
|
30
|
+
task :wait do
|
|
31
|
+
Orchestration::InstallGenerator.new.verify_makefile(false)
|
|
32
|
+
env = Orchestration::Environment.new
|
|
33
|
+
services = Orchestration::Services
|
|
34
|
+
env.docker_compose_config['services'].each do |name, _service|
|
|
35
|
+
path = nil
|
|
36
|
+
|
|
37
|
+
adapter = if name == 'database'
|
|
38
|
+
services::Database
|
|
39
|
+
elsif name.include?('database')
|
|
40
|
+
path = "config/database.#{name.sub('database-', '')}.yml"
|
|
41
|
+
services::Database
|
|
42
|
+
elsif name == 'mongo'
|
|
43
|
+
services::Mongo
|
|
44
|
+
elsif name == 'rabbitmq'
|
|
45
|
+
services::RabbitMQ
|
|
46
|
+
else
|
|
47
|
+
services::Listener
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
adapter::Healthcheck.start(
|
|
51
|
+
nil, nil, config_path: path, service_name: name, sidecar: ENV['sidecar']
|
|
59
52
|
)
|
|
60
53
|
end
|
|
61
54
|
end
|
data/orchestration.gemspec
CHANGED
|
@@ -16,8 +16,11 @@ Gem::Specification.new do |spec|
|
|
|
16
16
|
spec.homepage = url
|
|
17
17
|
|
|
18
18
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
19
|
-
|
|
19
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
20
|
+
f.match(%r{^(test|spec|features)/})
|
|
21
|
+
end
|
|
20
22
|
end
|
|
23
|
+
|
|
21
24
|
spec.bindir = 'bin'
|
|
22
25
|
spec.executables = []
|
|
23
26
|
spec.require_paths = ['lib']
|
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.
|
|
4
|
+
version: 0.5.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bob Farrell
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-01
|
|
11
|
+
date: 2020-07-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: database_url
|
|
@@ -318,7 +318,6 @@ files:
|
|
|
318
318
|
- ".travis.yml"
|
|
319
319
|
- Gemfile
|
|
320
320
|
- LICENSE
|
|
321
|
-
- MANIFEST
|
|
322
321
|
- Makefile
|
|
323
322
|
- README.md
|
|
324
323
|
- Rakefile
|
|
@@ -340,6 +339,7 @@ files:
|
|
|
340
339
|
- lib/orchestration/docker_compose/install_generator.rb
|
|
341
340
|
- lib/orchestration/docker_compose/mongo_service.rb
|
|
342
341
|
- lib/orchestration/docker_compose/rabbitmq_service.rb
|
|
342
|
+
- lib/orchestration/docker_healthcheck.rb
|
|
343
343
|
- lib/orchestration/environment.rb
|
|
344
344
|
- lib/orchestration/errors.rb
|
|
345
345
|
- lib/orchestration/file_helpers.rb
|
|
@@ -374,17 +374,14 @@ files:
|
|
|
374
374
|
- lib/orchestration/templates/application.mk.erb
|
|
375
375
|
- lib/orchestration/templates/database.yml.erb
|
|
376
376
|
- lib/orchestration/templates/deploy.mk.erb
|
|
377
|
-
- lib/orchestration/templates/docker-compose.override.yml.erb
|
|
378
377
|
- lib/orchestration/templates/entrypoint.sh.erb
|
|
379
378
|
- lib/orchestration/templates/env.erb
|
|
380
|
-
- lib/orchestration/templates/healthcheck.rb.erb
|
|
381
379
|
- lib/orchestration/templates/makefile_macros.mk.erb
|
|
382
380
|
- lib/orchestration/templates/mongoid.yml.erb
|
|
383
381
|
- lib/orchestration/templates/orchestration.mk.erb
|
|
384
382
|
- lib/orchestration/templates/puma.rb.erb
|
|
385
383
|
- lib/orchestration/templates/rabbitmq.yml.erb
|
|
386
384
|
- lib/orchestration/templates/unicorn.rb.erb
|
|
387
|
-
- lib/orchestration/templates/yaml.bash.erb
|
|
388
385
|
- lib/orchestration/terminal.rb
|
|
389
386
|
- lib/orchestration/version.rb
|
|
390
387
|
- lib/tasks/orchestration.rake
|
data/MANIFEST
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
.gitignore
|
|
2
|
-
.rspec
|
|
3
|
-
.rubocop.yml
|
|
4
|
-
.strong_versions.yml
|
|
5
|
-
.travis.yml
|
|
6
|
-
Gemfile
|
|
7
|
-
LICENSE
|
|
8
|
-
MANIFEST
|
|
9
|
-
Makefile
|
|
10
|
-
README.md
|
|
11
|
-
Rakefile
|
|
12
|
-
bin/console
|
|
13
|
-
bin/rspec
|
|
14
|
-
bin/rubocop
|
|
15
|
-
bin/setup
|
|
16
|
-
bin/strong_versions
|
|
17
|
-
config/locales/en.yml
|
|
18
|
-
doc/images/example.png
|
|
19
|
-
lib/Rakefile
|
|
20
|
-
lib/orchestration.rb
|
|
21
|
-
lib/orchestration/docker_compose.rb
|
|
22
|
-
lib/orchestration/docker_compose/app_service.rb
|
|
23
|
-
lib/orchestration/docker_compose/compose_configuration.rb
|
|
24
|
-
lib/orchestration/docker_compose/compose_helpers.rb
|
|
25
|
-
lib/orchestration/docker_compose/configuration.rb
|
|
26
|
-
lib/orchestration/docker_compose/database_service.rb
|
|
27
|
-
lib/orchestration/docker_compose/install_generator.rb
|
|
28
|
-
lib/orchestration/docker_compose/mongo_service.rb
|
|
29
|
-
lib/orchestration/docker_compose/rabbitmq_service.rb
|
|
30
|
-
lib/orchestration/environment.rb
|
|
31
|
-
lib/orchestration/errors.rb
|
|
32
|
-
lib/orchestration/file_helpers.rb
|
|
33
|
-
lib/orchestration/install_generator.rb
|
|
34
|
-
lib/orchestration/railtie.rb
|
|
35
|
-
lib/orchestration/service_check.rb
|
|
36
|
-
lib/orchestration/services.rb
|
|
37
|
-
lib/orchestration/services/app.rb
|
|
38
|
-
lib/orchestration/services/app/configuration.rb
|
|
39
|
-
lib/orchestration/services/app/healthcheck.rb
|
|
40
|
-
lib/orchestration/services/database.rb
|
|
41
|
-
lib/orchestration/services/database/adapters.rb
|
|
42
|
-
lib/orchestration/services/database/adapters/mysql2.rb
|
|
43
|
-
lib/orchestration/services/database/adapters/postgresql.rb
|
|
44
|
-
lib/orchestration/services/database/adapters/sqlite3.rb
|
|
45
|
-
lib/orchestration/services/database/configuration.rb
|
|
46
|
-
lib/orchestration/services/database/healthcheck.rb
|
|
47
|
-
lib/orchestration/services/listener.rb
|
|
48
|
-
lib/orchestration/services/listener/configuration.rb
|
|
49
|
-
lib/orchestration/services/listener/healthcheck.rb
|
|
50
|
-
lib/orchestration/services/mixins/configuration_base.rb
|
|
51
|
-
lib/orchestration/services/mixins/healthcheck_base.rb
|
|
52
|
-
lib/orchestration/services/mixins/http_healthcheck.rb
|
|
53
|
-
lib/orchestration/services/mongo.rb
|
|
54
|
-
lib/orchestration/services/mongo/configuration.rb
|
|
55
|
-
lib/orchestration/services/mongo/healthcheck.rb
|
|
56
|
-
lib/orchestration/services/rabbitmq.rb
|
|
57
|
-
lib/orchestration/services/rabbitmq/configuration.rb
|
|
58
|
-
lib/orchestration/services/rabbitmq/healthcheck.rb
|
|
59
|
-
lib/orchestration/settings.rb
|
|
60
|
-
lib/orchestration/templates/Dockerfile.erb
|
|
61
|
-
lib/orchestration/templates/application.mk.erb
|
|
62
|
-
lib/orchestration/templates/database.yml.erb
|
|
63
|
-
lib/orchestration/templates/deploy.mk.erb
|
|
64
|
-
lib/orchestration/templates/docker-compose.override.yml.erb
|
|
65
|
-
lib/orchestration/templates/entrypoint.sh.erb
|
|
66
|
-
lib/orchestration/templates/env.erb
|
|
67
|
-
lib/orchestration/templates/healthcheck.rb.erb
|
|
68
|
-
lib/orchestration/templates/makefile_macros.mk.erb
|
|
69
|
-
lib/orchestration/templates/mongoid.yml.erb
|
|
70
|
-
lib/orchestration/templates/orchestration.mk.erb
|
|
71
|
-
lib/orchestration/templates/puma.rb.erb
|
|
72
|
-
lib/orchestration/templates/rabbitmq.yml.erb
|
|
73
|
-
lib/orchestration/templates/unicorn.rb.erb
|
|
74
|
-
lib/orchestration/templates/yaml.bash.erb
|
|
75
|
-
lib/orchestration/terminal.rb
|
|
76
|
-
lib/orchestration/version.rb
|
|
77
|
-
lib/tasks/orchestration.rake
|
|
78
|
-
orchestration.gemspec
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version: <%= env.docker_api_version.to_json %>
|
|
@@ -1,56 +0,0 @@
|
|
|
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
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# https://stackoverflow.com/a/21189044 - thanks.
|
|
2
|
-
function parse_yaml {
|
|
3
|
-
local prefix=$2
|
|
4
|
-
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
|
|
5
|
-
sed -ne "s|^\($s\):|\1|" \
|
|
6
|
-
-e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
|
|
7
|
-
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 |
|
|
8
|
-
awk -F$fs '{
|
|
9
|
-
indent = length($1)/2;
|
|
10
|
-
vname[indent] = $2;
|
|
11
|
-
for (i in vname) {if (i > indent) {delete vname[i]}}
|
|
12
|
-
if (length($3) > 0) {
|
|
13
|
-
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
|
|
14
|
-
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
|
|
15
|
-
}
|
|
16
|
-
}'
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
eval $(parse_yaml ./.orchestration.yml)
|
|
20
|
-
|
|
21
|
-
set -u
|
|
22
|
-
echo -n "$(eval echo \$$1)"
|