orchestration 0.5.14 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +31 -28
- data/UPGRADE.md +90 -0
- data/config/locales/en.yml +11 -15
- data/lib/orchestration/docker_compose/app_service.rb +1 -0
- data/lib/orchestration/docker_compose/database_service.rb +1 -1
- data/lib/orchestration/docker_compose/install_generator.rb +3 -3
- data/lib/orchestration/install_generator.rb +2 -29
- data/lib/orchestration/make/orchestration.mk +502 -0
- data/lib/orchestration/make.rb +4 -0
- data/lib/orchestration/service_check.rb +23 -37
- data/lib/orchestration/services/database/adapters/adapter_base.rb +21 -0
- data/lib/orchestration/services/database/adapters/mysql2.rb +2 -0
- data/lib/orchestration/services/database/adapters/postgresql.rb +2 -0
- data/lib/orchestration/services/database/adapters/sqlite3.rb +2 -0
- data/lib/orchestration/services/database/adapters.rb +1 -0
- data/lib/orchestration/services/database/configuration.rb +5 -1
- data/lib/orchestration/services/mixins/configuration_base.rb +1 -1
- data/lib/orchestration/templates/Dockerfile.erb +5 -7
- data/lib/orchestration/templates/application.mk.erb +23 -7
- data/lib/orchestration/templates/puma.rb.erb +1 -1
- data/lib/orchestration/terminal.rb +4 -3
- data/lib/orchestration/version.rb +1 -1
- data/lib/orchestration.rb +4 -0
- data/lib/tasks/orchestration.rake +23 -6
- data/orchestration.gemspec +1 -0
- metadata +20 -4
- data/lib/orchestration/templates/makefile_macros.mk.erb +0 -112
- data/lib/orchestration/templates/orchestration.mk.erb +0 -391
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca5c9bd9b0a391d077e39e8447c38483f7149c3435b150289d2bebee4ca951b9
|
4
|
+
data.tar.gz: '08d6fdbd61e22b9ab3b5f3367250c7adfa0ad65dfecccc128a1075db8e6a478c'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f07f4b6ad5d5ce98cf65f94ccc9ae6ae280fab784a1760ede004a0cecdc4c90294e781d585868da9784603fca08f7e530b87ad94bf886e9c6f4c78e48264e7f3
|
7
|
+
data.tar.gz: 2cf4176c26c23d05733a926a8d22871a0e801a35d7e4b5643e92d7adfdb6a7627b23ee37dd97c01250937ebb31a7c9d638a5902377b91d512a48bcf90e5a0d90
|
data/README.md
CHANGED
@@ -7,12 +7,14 @@ At its core _Orchestration_ is simply a `Makefile` and a set of `docker-compose.
|
|
7
7
|
A typical _Rails_ application can be tested, built, pushed to _Docker Hub_, and deployed to _Docker Swarm_ with the following commands:
|
8
8
|
|
9
9
|
```bash
|
10
|
-
make test build push
|
10
|
+
make setup test build push
|
11
11
|
make deploy manager=user@swarm.example.com env_file=/var/configs/myapp.env
|
12
12
|
```
|
13
13
|
|
14
14
|
_Orchestration_ has been successfully used to build continuous delivery pipelines for numerous production applications with a wide range or requirements.
|
15
15
|
|
16
|
+
See [upgrade guide](UPGRADE.md) if you are upgrading from `0.5.x` to `0.6.x`.
|
17
|
+
|
16
18
|
## Example
|
17
19
|
|
18
20
|
The below screenshot demonstrates _Orchestration_ being installed in a brand new _Rails_ application with support for _PostgreSQL_ (via the _PG_ gem) and _RabbitMQ_ (via the _Bunny_ gem):
|
@@ -27,7 +29,7 @@ The below screenshot demonstrates _Orchestration_ being installed in a brand new
|
|
27
29
|
Add _Orchestration_ to your Gemfile:
|
28
30
|
|
29
31
|
```ruby
|
30
|
-
gem 'orchestration', '~> 0.
|
32
|
+
gem 'orchestration', '~> 0.6.3'
|
31
33
|
```
|
32
34
|
|
33
35
|
Install:
|
@@ -83,7 +85,7 @@ All `make` commands provided by _Orchestration_ (with the exception of `test` an
|
|
83
85
|
e.g.:
|
84
86
|
```
|
85
87
|
# Stop all test containers
|
86
|
-
make stop
|
88
|
+
make stop RAILS_ENV=test
|
87
89
|
```
|
88
90
|
|
89
91
|
The default value for `env` is `development`.
|
@@ -91,7 +93,7 @@ The default value for `env` is `development`.
|
|
91
93
|
As with any `Makefile` targets can be chained together, e.g.:
|
92
94
|
```
|
93
95
|
# Run tests, build, and push image
|
94
|
-
make test build push
|
96
|
+
make setup test build push
|
95
97
|
```
|
96
98
|
|
97
99
|
### Containers
|
@@ -113,7 +115,7 @@ make stop
|
|
113
115
|
#### Interface directly with `docker-compose`
|
114
116
|
|
115
117
|
```bash
|
116
|
-
$(make compose
|
118
|
+
$(make compose RAILS_ENV=test) logs -f database
|
117
119
|
```
|
118
120
|
|
119
121
|
### Images
|
@@ -192,21 +194,15 @@ A default `test` target is provided in your application's main `Makefile`. You a
|
|
192
194
|
|
193
195
|
To launch all dependency containers, run database migrations, and run tests:
|
194
196
|
```bash
|
195
|
-
make test
|
197
|
+
make setup test
|
196
198
|
```
|
197
199
|
|
198
200
|
The default `test` command can (and should) be extended. This command is defined in the root `Makefile` in the project and, by defaults, runs `rspec` and `rubocop`.
|
199
201
|
|
200
|
-
To
|
202
|
+
To skip the setup step and just run tests (i.e. once test containers are up and running and ready for use) simply run:
|
201
203
|
|
202
204
|
```bash
|
203
|
-
make test
|
204
|
-
```
|
205
|
-
|
206
|
-
If you prefer to run tests manually (e.g. if you want to run tests for a specific file) then the `test-setup` target can be used:
|
207
|
-
```bash
|
208
|
-
make test-setup
|
209
|
-
bundle exec rspec spec/my_class_spec.rb
|
205
|
+
make test
|
210
206
|
```
|
211
207
|
|
212
208
|
Note that _Orchestration_ will wait for all services to become fully available (i.e. running and providing valid responses) before attempting to run tests. This is specifically intended to facilitate testing in continuous integration environments.
|
@@ -220,22 +216,29 @@ ORCHESTRATION_RETRY_LIMIT # default: 15
|
|
220
216
|
ORCHESTRATION_RETRY_INTERVAL # default: 10 [seconds]
|
221
217
|
```
|
222
218
|
|
223
|
-
### (Local)
|
219
|
+
### (Local) Deployment
|
224
220
|
|
225
|
-
Run a
|
221
|
+
Run a deployment environment locally to simulate your deployment platform:
|
226
222
|
|
223
|
+
```bash
|
224
|
+
make deploy manager=localhost
|
227
225
|
```
|
228
|
-
|
229
|
-
|
226
|
+
|
227
|
+
Ensure you have passwordless _SSH_ access to your own workstation and that you have approved the host authenticity/fingerprint.
|
230
228
|
|
231
229
|
#### Deploy to a remote swarm
|
232
230
|
|
233
231
|
To connect via _SSH_ to a remote swarm and deploy, pass the `manager` parameter:
|
234
|
-
```
|
232
|
+
```bash
|
235
233
|
make deploy manager=user@manager.swarm.example.com
|
236
234
|
```
|
237
235
|
|
238
|
-
The file `orchestration/docker-compose.
|
236
|
+
The file `orchestration/docker-compose.deployment.yml` is created automatically. This file will be used for all deployments, regardless of _Rails_ environment. Other environments should be configured using a separate [`.env` file](#env-file) for each environment. i.e. to deploy a staging environment, create a `staging.env` (for example), set `RAILS_ENV=staging` and run:
|
237
|
+
```bash
|
238
|
+
make deploy manager=user@manager.swarm.example.com env_file=staging.env
|
239
|
+
```
|
240
|
+
|
241
|
+
This way you can set different publish ports and other application configuration variables for each stage you want to deploy to.
|
239
242
|
|
240
243
|
#### Roll back a deployment
|
241
244
|
|
@@ -254,11 +257,11 @@ The `project_name` parameter is also supported.
|
|
254
257
|
|
255
258
|
#### Use a custom stack name
|
256
259
|
|
257
|
-
The [_Docker_ stack](https://docs.docker.com/engine/reference/commandline/stack/) name defaults to the name of your repository (as defined in `.orchesration.yml`) and the _Rails_ environment, e.g. `
|
260
|
+
The [_Docker_ stack](https://docs.docker.com/engine/reference/commandline/stack/) name defaults to the name of your repository (as defined in `.orchesration.yml`) and the _Rails_ environment, e.g. `anvil_staging`.
|
258
261
|
|
259
262
|
To override this default, pass the `project_name` parameter:
|
260
263
|
```
|
261
|
-
make deploy project_name=
|
264
|
+
make deploy project_name=custom_stack_name
|
262
265
|
```
|
263
266
|
|
264
267
|
This variable will also be available as `COMPOSE_PROJECT_NAME` for use within your `docker-compose.yml`. e.g. to explicitly name a network after the project name:
|
@@ -300,7 +303,7 @@ tail -f log/orchestration*.log
|
|
300
303
|
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:
|
301
304
|
|
302
305
|
```bash
|
303
|
-
make dump
|
306
|
+
make dump RAILS_ENV=test
|
304
307
|
```
|
305
308
|
|
306
309
|
All commands also support the `verbose` flag which will output all logs immediately to the console:
|
@@ -327,7 +330,7 @@ See related documentation:
|
|
327
330
|
|
328
331
|
## Healthchecks
|
329
332
|
|
330
|
-
[Healthchecks](https://docs.docker.com/engine/reference/builder/#healthcheck) are automatically configured for your application. A healthcheck utility is provided in `orchestration/healthcheck.rb`. The following environment variables can be configured (in the `app` service of `orchestration/docker-compose.
|
333
|
+
[Healthchecks](https://docs.docker.com/engine/reference/builder/#healthcheck) are automatically configured for your application. A healthcheck utility is provided in `orchestration/healthcheck.rb`. The following environment variables can be configured (in the `app` service of `orchestration/docker-compose.deployment.yml`):
|
331
334
|
|
332
335
|
| Variable | Meaning | Default Value |
|
333
336
|
|-|-|-|
|
@@ -355,7 +358,7 @@ Real-world applications will inevitably need to make changes to this file. As wi
|
|
355
358
|
|
356
359
|
## Entrypoint
|
357
360
|
|
358
|
-
An [entrypoint](https://docs.docker.com/engine/reference/builder/#entrypoint) script for your application is provided which does the following:
|
361
|
+
An [entrypoint](https://docs.docker.com/engine/reference/builder/#entrypoint) script for your application is provided at `orchestration/entrypoint.sh` which does the following:
|
359
362
|
|
360
363
|
* Runs the `CMD` process as the same system user that launched the container (rather than the default `root` user);
|
361
364
|
* Creates various required temporary directories and removes stale `pid` files;
|
@@ -370,7 +373,7 @@ If you need to start dependency services (databases, etc.) and connect to them f
|
|
370
373
|
To do this automatically, pass the `sidecar` parameter to the `start` or `test` targets:
|
371
374
|
|
372
375
|
```bash
|
373
|
-
make test sidecar=1
|
376
|
+
make setup test sidecar=1
|
374
377
|
```
|
375
378
|
|
376
379
|
When running in sidecar mode container-to-container networking is used so there is no benefit to binding dependency containers to a specific port on the host machine (only the target port will be used). For this reason a random, ephemeral port (chosen by _Docker_) will be used to allow multiple instances of each dependency to run alongside one another.
|
@@ -381,10 +384,10 @@ Note that a temporary file `orchestration/.sidecar` containing the random projec
|
|
381
384
|
|
382
385
|
```bash
|
383
386
|
# Start dependencies and run tests in sidecar mode
|
384
|
-
make test sidecar=1
|
387
|
+
make setup test sidecar=1
|
385
388
|
|
386
389
|
# Stop test dependencies in sidecar mode
|
387
|
-
make stop
|
390
|
+
make stop RAILS_ENV=test
|
388
391
|
```
|
389
392
|
|
390
393
|
<a name="rabbitmq-configuration"></a>
|
data/UPGRADE.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Upgrade guide
|
2
|
+
|
3
|
+
## 0.5 to 0.6
|
4
|
+
|
5
|
+
### Delete/rename files
|
6
|
+
|
7
|
+
Delete all files from `orchestration/` directory except:
|
8
|
+
|
9
|
+
* `docker-compose.production.yml`
|
10
|
+
* `docker-compose.development.yml`
|
11
|
+
* `docker-compose.test.yml`
|
12
|
+
* `Dockerfile`
|
13
|
+
* `entrypoint.sh`
|
14
|
+
|
15
|
+
Rename:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
orchestration/docker-compose.production.yml => orchestration/docker-compose.deployment.yml
|
19
|
+
```
|
20
|
+
|
21
|
+
Any environment-specific compose files (e.g. `staging`) should also be removed as the same compose file is now used for all deployment stages.
|
22
|
+
|
23
|
+
### Update Makefile
|
24
|
+
|
25
|
+
Remove the first line of the main `Makefile` (in root of project) and replace it with the new `include` declaration:
|
26
|
+
|
27
|
+
#### OLD
|
28
|
+
|
29
|
+
```make
|
30
|
+
include orchestration/Makefile
|
31
|
+
```
|
32
|
+
|
33
|
+
#### NEW
|
34
|
+
|
35
|
+
```make
|
36
|
+
include $(shell bundle exec ruby -e 'require "orchestration/make"')
|
37
|
+
```
|
38
|
+
|
39
|
+
#### Post-setup target
|
40
|
+
|
41
|
+
Add a new target anywhere in the `Makefile` called `post-setup`:
|
42
|
+
|
43
|
+
```make
|
44
|
+
.PHONY: post-setup
|
45
|
+
post-setup:
|
46
|
+
echo 'doing post setup stuff'
|
47
|
+
```
|
48
|
+
|
49
|
+
Replace the body of this target with any commands that you want to take place once the initial setup (launching development/test containers, running migrations, etc.) is complete. For example, running migrations for a secondary database.
|
50
|
+
|
51
|
+
### Continuous Integration files
|
52
|
+
|
53
|
+
Update any continuous integration scripts (e.g. `Jenkinsfile`) to run the `setup` target before `test`, e.g.:
|
54
|
+
|
55
|
+
#### OLD
|
56
|
+
|
57
|
+
```Jenkinsfile
|
58
|
+
stage('Test') {
|
59
|
+
steps {
|
60
|
+
sh 'make test sidecar=1'
|
61
|
+
}
|
62
|
+
}
|
63
|
+
```
|
64
|
+
|
65
|
+
#### NEW
|
66
|
+
|
67
|
+
```Jenkinsfile
|
68
|
+
stage('Test') {
|
69
|
+
steps {
|
70
|
+
sh 'make setup test sidecar=1'
|
71
|
+
}
|
72
|
+
}
|
73
|
+
```
|
74
|
+
|
75
|
+
(`sidecar` may or may not be needed depending on your setup but, if it was there prior to upgrade, then it should remain after upgrade).
|
76
|
+
|
77
|
+
### General Usage
|
78
|
+
|
79
|
+
All _Orchestration_ commands behave exactly the same as before with the exception of the `test` target. Now, instead of running `make test` to launch all containers and then run tests, _Rubocop_, etc., you must run `make setup test`.
|
80
|
+
|
81
|
+
This will set up the test environment and then run tests. You may then run `make test` to just run tests without having to go through the full setup process again.
|
82
|
+
|
83
|
+
Similarly you can set up the development environment by just running `make setup`.
|
84
|
+
|
85
|
+
To set up the test environment and run tests as two separate steps (i.e. equivalent of using the shorthand `make setup test`) you can run:
|
86
|
+
|
87
|
+
```bash
|
88
|
+
make setup RAILS_ENV=test
|
89
|
+
make test
|
90
|
+
```
|
data/config/locales/en.yml
CHANGED
@@ -1,33 +1,21 @@
|
|
1
1
|
en:
|
2
2
|
orchestration:
|
3
|
-
attempt_limit: "Unable to
|
3
|
+
attempt_limit: "Unable to connect after %{limit} attempts. Aborting."
|
4
4
|
default: "default"
|
5
5
|
auto_update: "Orchestration Makefile was automatically updated to the latest version."
|
6
|
+
service:
|
7
|
+
ready: "%{service} is ready"
|
6
8
|
|
7
9
|
app:
|
8
|
-
waiting: "Waiting for app: %{config}"
|
9
|
-
ready: "App is ready."
|
10
10
|
connection_error: "Error attempting to connect to app: received status code %{code}"
|
11
11
|
|
12
12
|
database:
|
13
|
-
waiting: "Waiting for database: %{config}"
|
14
|
-
ready: "Database is ready."
|
15
13
|
unknown_environment: "Environment not defined in database configuration: %{environment}"
|
16
14
|
unknown_adapter: "Unable to determine adapter from database.yml: %{adapter}"
|
17
15
|
|
18
16
|
mongo:
|
19
|
-
waiting: "Waiting for Mongo: %{config}"
|
20
|
-
ready: "Mongo is ready."
|
21
17
|
bad_config: "Unable to parse Mongo config: %{path}. Expected section for one of: %{expected}"
|
22
18
|
|
23
|
-
rabbitmq:
|
24
|
-
waiting: "Waiting for RabbitMQ: %{config}"
|
25
|
-
ready: "RabbitMQ is ready."
|
26
|
-
|
27
|
-
custom_service:
|
28
|
-
waiting: "Waiting for [%{service}]: %{config}"
|
29
|
-
ready: "[%{service}] is ready."
|
30
|
-
|
31
19
|
settings:
|
32
20
|
docker:
|
33
21
|
organization:
|
@@ -44,3 +32,11 @@ en:
|
|
44
32
|
install: "Install Orchestration tools"
|
45
33
|
install_makefile: "(Re)create orchestration/Makefile"
|
46
34
|
wait: "Wait for development/test dependencies to be available"
|
35
|
+
db:
|
36
|
+
url: "Return the database URL for the current environment (RAILS_ENV)"
|
37
|
+
console: "Launch a database console for the current environment (RAILS_ENV)"
|
38
|
+
|
39
|
+
dbconsole:
|
40
|
+
postgresql: "PGPASSWORD='%<password>s' psql --username=%<username>s --host=%<host>s --port=%<port>s --dbname=%<database>s"
|
41
|
+
sqlite3: "sqlite3 %<database>s"
|
42
|
+
mysql2: "mysql --user=%<username>s --port=%<port>s --host=%<host>s --password=%<password>s --no-auto-rehash %<database>s"
|
@@ -99,6 +99,7 @@ module Orchestration
|
|
99
99
|
'RAILS_SERVE_STATIC_FILES' => '1',
|
100
100
|
'WEB_PRELOAD_APP' => '1',
|
101
101
|
'WEB_HEALTHCHECK_PATH' => '/',
|
102
|
+
'WEB_PORT' => 8080,
|
102
103
|
'DATABASE_URL' => database_url
|
103
104
|
}.merge(inherited_environment.map { |key| [key, nil] }.to_h).merge(rabbitmq_urls)
|
104
105
|
end
|
@@ -18,8 +18,8 @@ module Orchestration
|
|
18
18
|
create_compose_file(:development)
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
create_compose_file(:
|
21
|
+
def docker_compose_deployment_yml
|
22
|
+
create_compose_file(:deployment)
|
23
23
|
end
|
24
24
|
|
25
25
|
def enabled_services(environment)
|
@@ -68,7 +68,7 @@ module Orchestration
|
|
68
68
|
case environment
|
69
69
|
when :test, :development
|
70
70
|
%i[database mongo rabbitmq]
|
71
|
-
when :
|
71
|
+
when :deployment
|
72
72
|
%i[app database mongo rabbitmq]
|
73
73
|
when :local, nil
|
74
74
|
[]
|
@@ -27,30 +27,9 @@ module Orchestration
|
|
27
27
|
@terminal.write(:skip, relpath)
|
28
28
|
end
|
29
29
|
|
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
|
-
|
35
|
-
content = template('orchestration.mk', makefile_environment)
|
36
|
-
path = @env.orchestration_root.join('Makefile')
|
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))
|
42
|
-
end
|
43
|
-
|
44
30
|
def application_makefile
|
45
31
|
path = @env.root.join('Makefile')
|
46
32
|
simple_copy('application.mk', path) unless File.exist?(path)
|
47
|
-
inject_if_missing(path, 'include orchestration/Makefile')
|
48
|
-
end
|
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
33
|
end
|
55
34
|
|
56
35
|
def dockerfile
|
@@ -71,7 +50,7 @@ module Orchestration
|
|
71
50
|
def docker_compose
|
72
51
|
@docker_compose.docker_compose_test_yml
|
73
52
|
@docker_compose.docker_compose_development_yml
|
74
|
-
@docker_compose.
|
53
|
+
@docker_compose.docker_compose_deployment_yml
|
75
54
|
end
|
76
55
|
|
77
56
|
def puma
|
@@ -133,14 +112,8 @@ module Orchestration
|
|
133
112
|
I18n.t("orchestration.#{key}")
|
134
113
|
end
|
135
114
|
|
136
|
-
def makefile_environment
|
137
|
-
macros = template('makefile_macros.mk', env: @env)
|
138
|
-
|
139
|
-
{ env: @env, services: enabled_services, macros: macros }
|
140
|
-
end
|
141
|
-
|
142
115
|
def enabled_services
|
143
|
-
%i[test development
|
116
|
+
%i[test development deployment].map do |environment|
|
144
117
|
@docker_compose.enabled_services(environment)
|
145
118
|
end.flatten.uniq
|
146
119
|
end
|
@@ -0,0 +1,502 @@
|
|
1
|
+
|
2
|
+
### Environment setup ###
|
3
|
+
SHELL:=/bin/bash
|
4
|
+
MAKE:=mkpath=${mkpath} make --no-print-directory
|
5
|
+
|
6
|
+
TERM ?= 'dumb'
|
7
|
+
pwd:=$(shell pwd)
|
8
|
+
|
9
|
+
orchestration_dir_name=orchestration
|
10
|
+
orchestration_dir=orchestration
|
11
|
+
|
12
|
+
ifdef env_file
|
13
|
+
custom_env_file ?= 1
|
14
|
+
else
|
15
|
+
custom_env_file ?= 0
|
16
|
+
endif
|
17
|
+
|
18
|
+
ifneq (,$(wildcard ${pwd}/config/database.yml))
|
19
|
+
database_enabled = 1
|
20
|
+
else
|
21
|
+
database_enabled = 0
|
22
|
+
endif
|
23
|
+
|
24
|
+
red:=$(shell tput setaf 1)
|
25
|
+
green:=$(shell tput setaf 2)
|
26
|
+
yellow:=$(shell tput setaf 3)
|
27
|
+
blue:=$(shell tput setaf 4)
|
28
|
+
magenta:=$(shell tput setaf 5)
|
29
|
+
cyan:=$(shell tput setaf 6)
|
30
|
+
gray:=$(shell tput setaf 7)
|
31
|
+
reset:=$(shell tput sgr0)
|
32
|
+
tick=[${green}✓${reset}]
|
33
|
+
cross=[${red}✘${reset}]
|
34
|
+
|
35
|
+
make=$(MAKE) $1
|
36
|
+
orchestration_config_filename:=.orchestration.yml
|
37
|
+
orchestration_config:=${pwd}/${orchestration_config_filename}
|
38
|
+
system_prefix=${reset}[${cyan}exec${reset}]
|
39
|
+
warn_prefix=${reset}[${yellow}warn${reset}]
|
40
|
+
echo_prefix=${reset}[${blue}info${reset}]
|
41
|
+
fail_prefix=${reset}[${red}fail${reset}]
|
42
|
+
logs_prefix=${reset}[${green}logs${reset}]
|
43
|
+
system=echo '${system_prefix} ${cyan}$1${reset}'
|
44
|
+
warn=echo '${warn_prefix} ${reset}$1${reset}'
|
45
|
+
echo=echo '${echo_prefix} ${reset}$1${reset}'
|
46
|
+
fail=echo '${fail_prefix} ${reset}$1${reset}'
|
47
|
+
logs=echo '${logs_prefix} ${reset}$1${reset}'
|
48
|
+
print_error=printf '${red}\#${reset} '$1 | tee '${stderr}'
|
49
|
+
println_error=$(call print_error,$1'\n')
|
50
|
+
print=printf '${blue}\#${reset} '$1
|
51
|
+
println=$(call print,$1'\n')
|
52
|
+
printraw=printf $1
|
53
|
+
stdout=${pwd}/log/orchestration.stdout.log
|
54
|
+
stderr=${pwd}/log/orchestration.stderr.log
|
55
|
+
log_path_length=$(shell echo "${stdout}" | wc -c)
|
56
|
+
ifndef verbose
|
57
|
+
log_tee:= 2>&1 | tee -a ${stdout}
|
58
|
+
log:= >>${stdout} 2>>${stderr}
|
59
|
+
progress_point:=perl -e 'printf("[${magenta}busy${reset}] "); while( my $$line = <STDIN> ) { printf("."); select()->flush(); }'
|
60
|
+
log_progress:= > >(tee -ai ${stdout} >&1 | ${progress_point}) 2> >(tee -ai ${stderr} 2>&1 | ${progress_point})
|
61
|
+
endif
|
62
|
+
hr=$(call println,"$1$(shell head -c ${log_path_length} < /dev/zero | tr '\0' '=')${reset}")
|
63
|
+
managed_env_tag:=\# -|- ORCHESTRATION
|
64
|
+
standard_env_path:=${pwd}/.env
|
65
|
+
backup_env_path:=${pwd}/.env.orchestration.backup
|
66
|
+
is_managed_env:=$$(test -f '${standard_env_path}' && tail -n 1 '${standard_env_path}') == "${managed_env_tag}"*
|
67
|
+
token:=$(shell cat /dev/urandom | LC_CTYPE=C tr -dc 'a-z0-9' | fold -w8 | head -n1)
|
68
|
+
back_up_env:=( \
|
69
|
+
[ ! -f '${standard_env_path}' ] \
|
70
|
+
|| \
|
71
|
+
( \
|
72
|
+
[ -f '${standard_env_path}' ] \
|
73
|
+
&& cp '${standard_env_path}' '${backup_env_path}' \
|
74
|
+
) \
|
75
|
+
)
|
76
|
+
|
77
|
+
key_chars:=[a-zA-Z0-9_]
|
78
|
+
censored:=**********
|
79
|
+
censor=s/\(^${key_chars}*$(1)${key_chars}*\)=\(.*\)$$/\1=${censored}/
|
80
|
+
censor_urls:=s|\([a-zA-Z0-9_+]\+://.*:\).*\(@.*\)$$|\1${censored}\2|
|
81
|
+
format_env:=sed '$(call censor,SECRET); \
|
82
|
+
$(call censor,TOKEN); \
|
83
|
+
$(call censor,PRIVATE); \
|
84
|
+
$(call censor,KEY); \
|
85
|
+
$(censor_urls); \
|
86
|
+
/^\s*$$/d; \
|
87
|
+
/^\s*\#/d; \
|
88
|
+
s/\(^[a-zA-Z0-9_]\+\)=/${blue}\1${reset}=/; \
|
89
|
+
s/^/ /; \
|
90
|
+
s/=\(.*\)$$/=${yellow}\1${reset}/' | \
|
91
|
+
sort
|
92
|
+
|
93
|
+
exit_fail=( \
|
94
|
+
$(call printraw,' ${cross}') ; \
|
95
|
+
$(call make,dump src_cmd=$(MAKECMDGOALS)) ; \
|
96
|
+
echo ; \
|
97
|
+
$(call println,'Failed. ${cross}') ; \
|
98
|
+
exit 1 \
|
99
|
+
)
|
100
|
+
|
101
|
+
ifdef env_file
|
102
|
+
-include ${env_file}
|
103
|
+
else
|
104
|
+
ifneq (${env},test)
|
105
|
+
ifeq (,$(findstring test,$(MAKECMDGOALS)))
|
106
|
+
-include .env
|
107
|
+
endif
|
108
|
+
endif
|
109
|
+
endif
|
110
|
+
|
111
|
+
export
|
112
|
+
|
113
|
+
ifneq (,$(findstring test,$(MAKECMDGOALS)))
|
114
|
+
env=test
|
115
|
+
endif
|
116
|
+
|
117
|
+
ifneq (,$(env))
|
118
|
+
# `env` set by current shell.
|
119
|
+
else ifneq (,$(RAILS_ENV))
|
120
|
+
env=$(RAILS_ENV)
|
121
|
+
else ifneq (,$(RACK_ENV))
|
122
|
+
env=$(RACK_ENV)
|
123
|
+
else
|
124
|
+
env=development
|
125
|
+
endif
|
126
|
+
|
127
|
+
env_human=${gray}${env}${reset}
|
128
|
+
DOCKER_TAG ?= latest
|
129
|
+
|
130
|
+
ifneq (,$(wildcard ./Gemfile))
|
131
|
+
bundle_cmd = bundle exec
|
132
|
+
endif
|
133
|
+
rake=DEVPACK_DISABLE=1 RACK_ENV=${env} RAILS_ENV=${env} ${bundle_cmd} rake
|
134
|
+
|
135
|
+
ifneq (,$(wildcard ${env_file}))
|
136
|
+
rake_cmd:=${rake}
|
137
|
+
rake=. ${env_file} && ${rake_cmd}
|
138
|
+
endif
|
139
|
+
|
140
|
+
docker_config:=$(shell DEVPACK_DISABLE=1 RAILS_ENV=development ${bundle_cmd} rake orchestration:config 2>/dev/null || echo no-org no-repo)
|
141
|
+
docker_organization=$(word 1,$(docker_config))
|
142
|
+
docker_repository=$(word 2,$(docker_config))
|
143
|
+
|
144
|
+
ifeq (,$(project_name))
|
145
|
+
project_base = ${docker_repository}_${env}
|
146
|
+
else
|
147
|
+
project_base := $(project_name)
|
148
|
+
endif
|
149
|
+
|
150
|
+
ifeq (,$(findstring deploy,$(MAKECMDGOALS)))
|
151
|
+
sidecar_suffix := $(shell test -f ${orchestration_dir}/.sidecar && cat ${orchestration_dir}/.sidecar)
|
152
|
+
ifneq (,${sidecar_suffix})
|
153
|
+
sidecar := 1
|
154
|
+
endif
|
155
|
+
|
156
|
+
ifdef sidecar
|
157
|
+
# Set the variable to an empty string so that "#{sidecar-1234}" will
|
158
|
+
# evaluate to "1234" in port mappings.
|
159
|
+
sidecar_compose = sidecar=''
|
160
|
+
ifeq (,${sidecar_suffix})
|
161
|
+
sidecar_suffix := $(call token)
|
162
|
+
_ignore := $(shell echo ${sidecar_suffix} > ${orchestration_dir}/.sidecar)
|
163
|
+
endif
|
164
|
+
|
165
|
+
ifeq (,${sidecar_suffix})
|
166
|
+
$(warning Unable to generate project suffix; project name collisions may occur.)
|
167
|
+
endif
|
168
|
+
compose_project_name = ${project_base}_${sidecar_suffix}
|
169
|
+
else
|
170
|
+
compose_project_name = ${project_base}
|
171
|
+
endif
|
172
|
+
else
|
173
|
+
compose_project_name = ${project_base}
|
174
|
+
endif
|
175
|
+
|
176
|
+
compose_base=env -i \
|
177
|
+
PATH=$(PATH) \
|
178
|
+
HOST_UID=$(shell id -u) \
|
179
|
+
DOCKER_ORGANIZATION="${docker_organization}" \
|
180
|
+
DOCKER_REPOSITORY="${docker_repository}" \
|
181
|
+
COMPOSE_PROJECT_NAME="${compose_project_name}" \
|
182
|
+
${sidecar_compose} \
|
183
|
+
docker-compose \
|
184
|
+
-f ${orchestration_dir}/docker-compose.${env}.yml
|
185
|
+
|
186
|
+
git_branch ?= $(if $(branch),$(branch),$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo no-branch))
|
187
|
+
ifndef dev
|
188
|
+
git_version ?= $(shell git rev-parse --short --verify ${git_branch} 2>/dev/null || echo no-version)
|
189
|
+
else
|
190
|
+
git_version = dev
|
191
|
+
endif
|
192
|
+
|
193
|
+
docker_image=${docker_organization}/${docker_repository}:${git_version}
|
194
|
+
|
195
|
+
compose=${compose_base}
|
196
|
+
compose_human=docker-compose -f ${orchestration_dir_name}/docker-compose.${env}.yml
|
197
|
+
random_str=cat /dev/urandom | LC_ALL=C tr -dc 'a-z' | head -c $1
|
198
|
+
|
199
|
+
ifneq (,$(wildcard ${orchestration_dir}/docker-compose.local.yml))
|
200
|
+
compose:=${compose} -f ${orchestration_dir}/docker-compose.local.yml
|
201
|
+
endif
|
202
|
+
|
203
|
+
all: build
|
204
|
+
|
205
|
+
### Container management commands ###
|
206
|
+
|
207
|
+
.PHONY: start
|
208
|
+
ifndef network
|
209
|
+
start: network := ${compose_project_name}
|
210
|
+
endif
|
211
|
+
start: _create-log-directory _clean-logs
|
212
|
+
@$(call system,${compose_human} up --detach)
|
213
|
+
ifeq (${env},$(filter ${env},test development))
|
214
|
+
@${compose} up --detach --force-recreate --renew-anon-volumes --remove-orphans ${services} ${log} || ${exit_fail}
|
215
|
+
@[ -n '${sidecar}' ] && \
|
216
|
+
( \
|
217
|
+
$(call echo,(joining dependency network ${cyan}${network}${reset})) ; \
|
218
|
+
$(call system,docker network connect "${network}") ; \
|
219
|
+
docker network connect '${network}' '$(shell hostname)' ${log} \
|
220
|
+
|| ( \
|
221
|
+
$(call warn,Unable to join network: "${cyan}${network}${reset}". Container will not be able to connect to dependency services) ; \
|
222
|
+
$(call echo,Try deleting "${cyan}orchestration/.sidecar${reset}" if you do not want to use sidecar mode) ; \
|
223
|
+
) \
|
224
|
+
) \
|
225
|
+
|| ( [ -z '${sidecar}' ] || ${exit_fail} )
|
226
|
+
else
|
227
|
+
@${compose} up --detach --scale app=$${instances:-1} ${log} || ${exit_fail}
|
228
|
+
endif
|
229
|
+
@$(call echo,${env_human} containers started ${tick})
|
230
|
+
@$(call echo,Waiting for services to become available)
|
231
|
+
@$(call make,wait) 2>${stderr} || ${exit_fail}
|
232
|
+
|
233
|
+
.PHONY: stop
|
234
|
+
stop: network := ${compose_project_name}
|
235
|
+
stop:
|
236
|
+
@$(call echo,Stopping ${env_human} containers)
|
237
|
+
@$(call system,${compose_human} down)
|
238
|
+
@if docker ps --format "{{.ID}}" | grep -q $(shell hostname) ; \
|
239
|
+
then \
|
240
|
+
( docker network disconnect ${network} $(shell hostname) ${log} || : ) \
|
241
|
+
&& \
|
242
|
+
( ${compose} down ${log} || ${exit_fail} ) ; \
|
243
|
+
else \
|
244
|
+
${compose} down ${log} || ${exit_fail} ; \
|
245
|
+
fi
|
246
|
+
@$(call echo,${env_human} containers stopped ${tick})
|
247
|
+
|
248
|
+
.PHONY: logs
|
249
|
+
logs:
|
250
|
+
@${compose} logs -f
|
251
|
+
|
252
|
+
.PHONY: config
|
253
|
+
config:
|
254
|
+
@${compose} config
|
255
|
+
|
256
|
+
.PHONY: compose
|
257
|
+
compose:
|
258
|
+
@echo ${compose}
|
259
|
+
|
260
|
+
### Development/Test Utility Commands
|
261
|
+
|
262
|
+
.PHONY: serve
|
263
|
+
serve: env_file ?= ./.env
|
264
|
+
serve: rails = RAILS_ENV='${env}' bundle exec rails server ${server}
|
265
|
+
serve:
|
266
|
+
@if [ -f "${env_file}" ] ; \
|
267
|
+
then ( \
|
268
|
+
$(call echo,Environment${reset}: ${cyan}${env_file}${reset}) && \
|
269
|
+
cat '${env_file}' | ${format_env} \
|
270
|
+
) ; \
|
271
|
+
fi
|
272
|
+
${rails}
|
273
|
+
|
274
|
+
.PHONY: console
|
275
|
+
console: env_file ?= ./.env
|
276
|
+
console: rails = RAILS_ENV='${env}' bundle exec rails
|
277
|
+
console:
|
278
|
+
@if [ -f "${env_file}" ] ; \
|
279
|
+
then ( \
|
280
|
+
$(call echo,Environment${reset}: ${cyan}${env_file}${reset}) && \
|
281
|
+
cat '${env_file}' | ${format_env} \
|
282
|
+
) ; \
|
283
|
+
fi
|
284
|
+
${rails} console
|
285
|
+
|
286
|
+
.PHONY: db-console
|
287
|
+
db-console:
|
288
|
+
@${rake} orchestration:db:console RAILS_ENV=${env}
|
289
|
+
|
290
|
+
.PHONY: setup
|
291
|
+
setup: url = $(shell ${rake} orchestration:db:url RAILS_ENV=${env})
|
292
|
+
setup: _log-notify
|
293
|
+
@$(call echo,Setting up ${env_human} environment)
|
294
|
+
@$(call make,start env=${env})
|
295
|
+
ifneq (,$(wildcard config/database.yml))
|
296
|
+
@$(call echo,Preparing ${env_human} database)
|
297
|
+
@$(call system,rake db:create DATABASE_URL="${url}")
|
298
|
+
@${rake} db:create RAILS_ENV=${env} ${log} || : ${log}
|
299
|
+
ifneq (,$(wildcard db/structure.sql))
|
300
|
+
@$(call system,rake db:schema:load DATABASE_URL="${url}")
|
301
|
+
@${rake} db:schema:load DATABASE_URL='${url}' ${log} || ${exit_fail}
|
302
|
+
else ifneq (,$(wildcard db/schema.rb))
|
303
|
+
@$(call system,rake db:schema:load DATABASE_URL="${url}")
|
304
|
+
@${rake} db:schema:load DATABASE_URL='${url}' ${log} || ${exit_fail}
|
305
|
+
endif
|
306
|
+
@$(call system,rake db:migrate DATABASE_URL="${url}")
|
307
|
+
@${rake} db:migrate RAILS_ENV=${env}
|
308
|
+
endif
|
309
|
+
@$(MAKE) -n post-setup >/dev/null 2>&1 \
|
310
|
+
&& $(call system,make post-setup RAILS_ENV=${env}) \
|
311
|
+
&& $(MAKE) post-setup RAILS_ENV=${env}
|
312
|
+
@$(call echo,${env_human} environment setup complete ${tick})
|
313
|
+
|
314
|
+
.PHONY: dump
|
315
|
+
dump:
|
316
|
+
ifndef verbose
|
317
|
+
@$(call println)
|
318
|
+
@$(call println,'${yellow}Captured${reset} ${green}stdout${reset} ${yellow}and${reset} ${red}stderr${reset} ${yellow}log data [${cyan}${env}${yellow}]${reset}:')
|
319
|
+
@$(call println)
|
320
|
+
@echo
|
321
|
+
@test -f '${stdout}' && ( \
|
322
|
+
$(call hr,${green}) ; \
|
323
|
+
$(call println,'${gray}${stdout}${reset}') ; \
|
324
|
+
$(call hr,${green}) ; \
|
325
|
+
echo ; cat '${stdout}' ; echo ; \
|
326
|
+
$(call hr,${green}) ; \
|
327
|
+
)
|
328
|
+
|
329
|
+
@test -f '${stdout}' && ( \
|
330
|
+
echo ; \
|
331
|
+
$(call hr,${red}) ; \
|
332
|
+
$(call println,'${gray}${stderr}${reset}') ; \
|
333
|
+
$(call hr,${red}) ; \
|
334
|
+
echo ; cat '${stderr}' ; echo ; \
|
335
|
+
$(call hr,${red}) ; \
|
336
|
+
)
|
337
|
+
endif
|
338
|
+
ifneq (build,${src_cmd})
|
339
|
+
ifneq (push,${src_cmd})
|
340
|
+
@echo ; \
|
341
|
+
$(call hr,${yellow}) ; \
|
342
|
+
$(call println,'${gray}docker-compose logs${reset}') ; \
|
343
|
+
$(call hr,${yellow}) ; \
|
344
|
+
echo
|
345
|
+
@${compose} logs
|
346
|
+
@echo ; \
|
347
|
+
$(call hr,${yellow})
|
348
|
+
@$(NOOP)
|
349
|
+
endif
|
350
|
+
endif
|
351
|
+
|
352
|
+
.PHONY: tag
|
353
|
+
tag:
|
354
|
+
@echo ${docker_image}
|
355
|
+
|
356
|
+
### Deployment utility commands ###
|
357
|
+
|
358
|
+
.PHONY: deploy
|
359
|
+
deploy: _log-notify _clean-logs
|
360
|
+
ifdef env_file
|
361
|
+
deploy: env_file_option = --env-file ${env_file}
|
362
|
+
endif
|
363
|
+
deploy: RAILS_ENV := ${env}
|
364
|
+
deploy: RACK_ENV := ${env}
|
365
|
+
deploy: DOCKER_TAG = ${git_version}
|
366
|
+
deploy: base_vars = DOCKER_ORGANIZATION=${docker_organization} DOCKER_REPOSITORY=${docker_repository} DOCKER_TAG=${git_version}
|
367
|
+
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
|
368
|
+
deploy: config_cmd = ${compose_deploy} config
|
369
|
+
deploy: remote_cmd = cat | docker stack deploy --prune --with-registry-auth -c - ${project_base}
|
370
|
+
deploy: ssh_cmd = ssh "${manager}"
|
371
|
+
deploy: deploy_cmd := ${config_cmd} | ${ssh_cmd} "/bin/bash -lc '${remote_cmd}'"
|
372
|
+
deploy:
|
373
|
+
ifndef manager
|
374
|
+
@$(call fail,Missing ${cyan}manager${reset} parameter: ${cyan}make deploy manager=swarm-manager.example.com${reset}) ; exit 1
|
375
|
+
endif
|
376
|
+
@$(call echo,Deploying ${env_human} stack via ${cyan}${manager}${reset} as ${cyan}${project_base}${reset}) && \
|
377
|
+
( \
|
378
|
+
( test -f '${env_file}' && $(call echo,Deployment environment:) && cat '${env_file}' | ${format_env} || : ) && \
|
379
|
+
$(call echo,Application image: ${cyan}${docker_image}${reset}) ; \
|
380
|
+
$(call system,${config_cmd} | ${ssh_cmd} "/bin/bash -lc '\''${remote_cmd}'\''") ; \
|
381
|
+
${deploy_cmd} \
|
382
|
+
)
|
383
|
+
@$(call echo,Deployment ${green}complete${reset} ${tick})
|
384
|
+
|
385
|
+
.PHONY: rollback
|
386
|
+
ifndef service
|
387
|
+
rollback: service = app
|
388
|
+
endif
|
389
|
+
rollback:
|
390
|
+
ifndef manager
|
391
|
+
@$(call fail,Missing `manager` parameter: `make deploy manager=swarm-manager.example.com`)
|
392
|
+
@exit 1
|
393
|
+
endif
|
394
|
+
@$(call echo,Rolling back ${cyan}${compose_project_name}_${service}${reset} via ${cyan}${manager}${reset} ...)
|
395
|
+
@$(call system,docker service rollback --detach "${compose_project_name}_${service}")
|
396
|
+
@ssh "${manager}" 'docker service rollback --detach "${compose_project_name}_${service}"' ${log} || ${exit_fail}
|
397
|
+
@$(call echo,Rollback request ${green}complete${reset} ${tick})
|
398
|
+
|
399
|
+
### Service healthcheck commands ###
|
400
|
+
|
401
|
+
.PHONY: wait
|
402
|
+
wait:
|
403
|
+
@${rake} orchestration:wait
|
404
|
+
@$(call echo,${env_human} services ${green}ready${reset} ${tick})
|
405
|
+
|
406
|
+
## Generic Listener healthcheck for TCP services ##
|
407
|
+
|
408
|
+
wait-listener:
|
409
|
+
@${rake} orchestration:listener:wait service=${service} sidecar=${sidecar}
|
410
|
+
|
411
|
+
### Docker build commands ###
|
412
|
+
|
413
|
+
.PHONY: build
|
414
|
+
build: _log-notify _clean-logs
|
415
|
+
build: build_dir = ${orchestration_dir}/.build
|
416
|
+
build: context = ${build_dir}/context.tar
|
417
|
+
build: build_args := --build-arg GIT_COMMIT='${git_version}'
|
418
|
+
build: tag_human = ${cyan}${docker_organization}/${docker_repository}:${git_version}${reset}
|
419
|
+
build: latest_tag_human = ${cyan}${docker_organization}/${docker_repository}:latest${reset}
|
420
|
+
ifdef BUNDLE_GITHUB__COM
|
421
|
+
build: build_args := ${build_args} --build-arg BUNDLE_GITHUB__COM
|
422
|
+
endif
|
423
|
+
ifdef BUNDLE_BITBUCKET__ORG
|
424
|
+
build: build_args := ${build_args} --build-arg BUNDLE_BITBUCKET__ORG
|
425
|
+
endif
|
426
|
+
build: _create-log-directory check-local-changes
|
427
|
+
@$(call echo,Preparing build context from ${cyan}${git_branch}${reset} (${cyan}${git_version}${reset})${reset})
|
428
|
+
@$(call system,git archive --format "tar" -o "${context}" "${git_branch}")
|
429
|
+
@mkdir -p ${orchestration_dir}/.build ${log} || ${exit_fail}
|
430
|
+
ifndef dev
|
431
|
+
@git show ${git_branch}:./Gemfile > ${orchestration_dir}/.build/Gemfile 2>${stderr} || ${exit_fail}
|
432
|
+
@git show ${git_branch}:./Gemfile.lock > ${orchestration_dir}/.build/Gemfile.lock 2>${stderr} || ${exit_fail}
|
433
|
+
@git archive --format 'tar' -o '${context}' '${git_branch}' ${log} || ${exit_fail}
|
434
|
+
else
|
435
|
+
@tar -cvf '${context}' . ${log} || ${exit_fail}
|
436
|
+
endif
|
437
|
+
ifdef include
|
438
|
+
@$(call echo,Including files from: ${cyan}${include}${reset})
|
439
|
+
@(while read line; do \
|
440
|
+
export line; \
|
441
|
+
include_dir="${build_dir}/$$(dirname "$${line}")/" && \
|
442
|
+
mkdir -p "$${include_dir}" && cp "$${line}" "$${include_dir}" \
|
443
|
+
&& (cd '${orchestration_dir}/.build/' && tar rf 'context.tar' "$${line}"); \
|
444
|
+
echo "${system_prefix}" "tar rf 'context.tar' '$${line}'"; \
|
445
|
+
done < '${include}') ${log} || ${exit_fail}
|
446
|
+
@$(call echo,Build context ${green}ready${reset} ${tick})
|
447
|
+
endif
|
448
|
+
@$(call echo,Building image ${tag_human})
|
449
|
+
@$(call system,docker build ${build_args} -t ${docker_organization}/${docker_repository}:${git_version} ${orchestration_dir}/)
|
450
|
+
@docker build ${build_args} \
|
451
|
+
-t ${docker_organization}/${docker_repository}:${git_version} \
|
452
|
+
${orchestration_dir}/ ${log_progress} || ${exit_fail}
|
453
|
+
@echo
|
454
|
+
@$(call echo,Build ${green}complete${reset} ${tick})
|
455
|
+
@$(call echo,[${green}tag${reset}] ${tag_human})
|
456
|
+
|
457
|
+
.PHONY: push
|
458
|
+
push: _log-notify _clean-logs
|
459
|
+
@$(call echo,Pushing ${cyan}${docker_image}${reset} to registry)
|
460
|
+
@$(call system,docker push ${docker_image})
|
461
|
+
@docker push ${docker_image} ${log_progress} || ${exit_fail}
|
462
|
+
@echo
|
463
|
+
@$(call echo,Push ${green}complete${reset} ${tick})
|
464
|
+
|
465
|
+
.PHONY: check-local-changes
|
466
|
+
check-local-changes:
|
467
|
+
ifndef dev
|
468
|
+
@changes="$$(git status --porcelain)"; if ! [ -z "${changes}" ] && [[ "${changes}" != "?? orchestration/.sidecar" ]]; \
|
469
|
+
then \
|
470
|
+
$(call warn,You have uncommitted changes which will not be included in your build:) ; \
|
471
|
+
git status --porcelain ; \
|
472
|
+
$(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}) ; \
|
473
|
+
fi
|
474
|
+
endif
|
475
|
+
|
476
|
+
### Internal Commands ###
|
477
|
+
#
|
478
|
+
.PHONY: _log-notify
|
479
|
+
_log-notify: comma=,
|
480
|
+
_log-notify: _verify-repository
|
481
|
+
ifndef verbose
|
482
|
+
@$(call logs,${green}stdout${reset}: ${cyan}log/orchestration.stdout.log${reset}${comma} ${red}stderr${reset}: ${cyan}log/orchestration.stderr.log)
|
483
|
+
endif
|
484
|
+
|
485
|
+
.PHONY: _verify-repository
|
486
|
+
_verify-repository:
|
487
|
+
@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
|
488
|
+
|
489
|
+
.PHONY: _clean-logs
|
490
|
+
_clean-logs:
|
491
|
+
_clean-logs: _create-log-directory
|
492
|
+
@rm -f '${stdout}' '${stderr}'
|
493
|
+
@touch '${stdout}' '${stderr}'
|
494
|
+
|
495
|
+
.PHONY: _create-log-directory
|
496
|
+
_create-log-directory:
|
497
|
+
@mkdir -p log
|
498
|
+
|
499
|
+
# Used by Orchestration test suite to verify Makefile syntax
|
500
|
+
.PHONY: _test
|
501
|
+
_test:
|
502
|
+
@echo 'test command'
|