orchestration 0.4.10 → 0.4.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23e3a1c23b6511daf4d79650fb8cbae39b697f7f70ae9924ac69c69cc58f5f39
4
- data.tar.gz: b41de78b238b8663070651b20e36f40c8d430a89c5173ce28042c434ddcf6898
3
+ metadata.gz: 9f875ac821552fa3fb97823f27d3883b9d3ac93305a5adb42eedc10322930bf3
4
+ data.tar.gz: fbe1fd7262d71100122faa46f98ad27bcf94f3cb02b8894b9cf23af11bc0abae
5
5
  SHA512:
6
- metadata.gz: 5facd62ea505866177a36e837e93244e3314909b71091f6bca63aed73d37f8bb1b7f4837ee7824bad659da660cb5ec862750ff84550769025a868f35bf2fd338
7
- data.tar.gz: e8da0ea3bd75f817735e67604299ee93058bc7900f37bceb17b2f25b9228cd5e77c8a5503239ad6105bbf8dc097341ecef086448e16e5ba36975ea461116f875
6
+ metadata.gz: a7650ee86ba929d95a4cfdc1eb6324b053c36acdd9e3e9eab105a85dd763485643855eb3b4a458292cdb5b68f35a83447d4e057477f2f326c416e4044a06db17
7
+ data.tar.gz: 640be0c857fbcadeb6eac07852b7255b2c67a0591efb9195537f942ad9be80163b386dba5b2147fe65e46769a399149bbf2088cfcc34493dbcff0344ac946db5
data/.gitignore CHANGED
@@ -21,6 +21,7 @@ spec/dummy/Makefile
21
21
  spec/dummy/orchestration/*
22
22
  spec/dummy/config/unicorn.rb
23
23
  spec/dummy/config/*.bak
24
+ spec/dummy/tmp/*
24
25
 
25
26
  orchestration-*.gem
26
27
 
@@ -32,3 +33,5 @@ docker/.build/
32
33
  docker/.context.tar
33
34
 
34
35
  .DS_Store
36
+
37
+ .ruby-version
data/MANIFEST CHANGED
@@ -21,6 +21,7 @@ lib/orchestration.rb
21
21
  lib/orchestration/docker_compose.rb
22
22
  lib/orchestration/docker_compose/app_service.rb
23
23
  lib/orchestration/docker_compose/compose_configuration.rb
24
+ lib/orchestration/docker_compose/compose_helpers.rb
24
25
  lib/orchestration/docker_compose/configuration.rb
25
26
  lib/orchestration/docker_compose/database_service.rb
26
27
  lib/orchestration/docker_compose/install_generator.rb
data/Makefile CHANGED
@@ -1,8 +1,8 @@
1
1
  .PHONY: test
2
2
  test:
3
- ./bin/rspec
4
- ./bin/rubocop
5
- ./bin/strong_versions
3
+ bundle exec rspec
4
+ bundle exec rubocop
5
+ bundle exec strong_versions
6
6
 
7
7
  .PHONY: manifest
8
8
  manifest:
data/README.md CHANGED
@@ -35,7 +35,7 @@ The below screenshot demonstrates _Orchestration_ being installed in a brand new
35
35
  Add _Orchestration_ to your Gemfile:
36
36
 
37
37
  ```ruby
38
- gem 'orchestration', '~> 0.4.10'
38
+ gem 'orchestration', '~> 0.4.12'
39
39
  ```
40
40
 
41
41
  Install:
@@ -336,6 +336,20 @@ To do this automatically, pass the `sidecar` parameter to the `start` or `test`
336
336
  make test sidecar=1
337
337
  ```
338
338
 
339
+ 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.
340
+
341
+ The _Docker Compose_ project name (and derived network name) is also suffixed with a random token to avoid container/network name conflicts.
342
+
343
+ Note that a temporary file `orchestration/.sidecar` containing the random project name suffix will be created when sidecar mode is used. If this file exists then sidecar mode is always assumed to be _on_. This is to allow (e.g.) stopping services that have been started separately with another command, for example:
344
+
345
+ ```bash
346
+ # Start dependencies and run tests in sidecar mode
347
+ make test sidecar=1
348
+
349
+ # Stop test dependencies in sidecar mode
350
+ make stop env=test
351
+ ```
352
+
339
353
  <a name="rabbitmq-configuration"></a>
340
354
  ## RabbitMQ Configuration
341
355
 
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orchestration
4
+ module DockerCompose
5
+ module ComposeHelpers
6
+ def sidecar_port(environment)
7
+ port = Orchestration.random_local_port
8
+ return "#{port}:" unless environment == :test
9
+
10
+ # If env var `sidecar` is not set then ports will be configured as e.g.:
11
+ # "50123:3306"
12
+ # otherwise it will be:
13
+ # "3306" (docker will use an ephemeral host port which we will not use)
14
+ "${#{port}\:-sidecar}"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -3,6 +3,8 @@
3
3
  module Orchestration
4
4
  module DockerCompose
5
5
  class DatabaseService
6
+ include ComposeHelpers
7
+
6
8
  def initialize(config, environment)
7
9
  @environment = environment
8
10
  @config = config
@@ -33,7 +35,7 @@ module Orchestration
33
35
  def ports
34
36
  return {} unless %i[development test].include?(@environment)
35
37
 
36
- { 'ports' => ["#{Orchestration.random_local_port}:#{remote_port}"] }
38
+ { 'ports' => ["#{sidecar_port(@environment)}#{remote_port}"] }
37
39
  end
38
40
 
39
41
  def volumes
@@ -3,6 +3,8 @@
3
3
  module Orchestration
4
4
  module DockerCompose
5
5
  class MongoService
6
+ include ComposeHelpers
7
+
6
8
  PORT = 27_020
7
9
 
8
10
  def initialize(config, environment)
@@ -21,7 +23,7 @@ module Orchestration
21
23
  def ports
22
24
  return {} unless %i[development test].include?(@environment)
23
25
 
24
- { 'ports' => ["#{local_port}:#{remote_port}"] }
26
+ { 'ports' => ["#{sidecar_port(@environment)}#{remote_port}"] }
25
27
  end
26
28
 
27
29
  def volumes
@@ -3,6 +3,8 @@
3
3
  module Orchestration
4
4
  module DockerCompose
5
5
  class RabbitMQService
6
+ include ComposeHelpers
7
+
6
8
  def initialize(config, environment)
7
9
  @config = config
8
10
  @environment = environment
@@ -19,7 +21,7 @@ module Orchestration
19
21
 
20
22
  container_port = Orchestration::Services::RabbitMQ::PORT
21
23
 
22
- { 'ports' => ["#{Orchestration.random_local_port}:#{container_port}"] }
24
+ { 'ports' => ["#{sidecar_port(@environment)}#{container_port}"] }
23
25
  end
24
26
  end
25
27
  end
@@ -5,6 +5,7 @@ module Orchestration
5
5
  end
6
6
  end
7
7
 
8
+ require 'orchestration/docker_compose/compose_helpers'
8
9
  require 'orchestration/docker_compose/install_generator'
9
10
  require 'orchestration/docker_compose/configuration'
10
11
  require 'orchestration/docker_compose/compose_configuration'
@@ -57,11 +57,11 @@ module Orchestration
57
57
  def gitignore
58
58
  path = @env.root.join('.gitignore')
59
59
  globs = %w[.build/ .deploy/ Gemfile Gemfile.lock docker-compose.local.yml]
60
- entries = %w[.env deploy.tar] + globs.map do |entry|
61
- "#{@env.orchestration_dir_name}/#{entry}"
60
+ lines = %w[orchestration/.sidecar .env deploy.tar] + globs.map do |line|
61
+ "#{@env.orchestration_dir_name}/#{line}"
62
62
  end
63
63
 
64
- ensure_lines_in_file(path, entries)
64
+ ensure_lines_in_file(path, lines)
65
65
  end
66
66
 
67
67
  def docker_compose
@@ -73,10 +73,14 @@ module Orchestration
73
73
  # A quirk of DatabaseUrl is that if no "/path" is present then the
74
74
  # `database` component is an empty string. In this unique case, we
75
75
  # want `nil` instead so that we can delegate to a default.
76
- config['database'] = nil if config['database']&.empty?
76
+ config['database'] = nil if database_missing?(config)
77
77
  config
78
78
  end
79
79
 
80
+ def database_missing?(config)
81
+ config.key?('database') && config['database'].empty?
82
+ end
83
+
80
84
  def host
81
85
  url_config['host'] || file_config['host'] || super
82
86
  end
@@ -37,8 +37,8 @@ module Orchestration
37
37
  def configured?
38
38
  port
39
39
  true
40
- rescue KeyError => error
41
- @error = error
40
+ rescue KeyError => e
41
+ @error = e
42
42
  false
43
43
  end
44
44
 
@@ -9,6 +9,9 @@ development:
9
9
  username: <%= compose.call(nil).database_adapter.credentials['username'] %>
10
10
  password: <%= compose.call(nil).database_adapter.credentials['password'] %>
11
11
  database: <%= compose.call(nil).database_adapter.credentials['database'] %>
12
+ <%% if ENV.key?('DEVELOPMENT_DATABASE_URL') %>
13
+ url: <%%= ENV['DEVELOPMENT_DATABASE_URL'] %>
14
+ <%% end %>
12
15
  <% end %>
13
16
 
14
17
  <% if compose.call('test').services.key?('database') %>
@@ -49,7 +49,7 @@ managed_env_tag:=\# -|- ORCHESTRATION
49
49
  standard_env_path:=${pwd}/.env
50
50
  backup_env_path:=${pwd}/.env.orchestration.backup
51
51
  is_managed_env:=$$(test -f '${standard_env_path}' && tail -n 1 '${standard_env_path}') == "${managed_env_tag}"*
52
-
52
+ token:=$(shell cat /dev/urandom | LC_CTYPE=C tr -dc 'a-z0-9' | fold -w8 | head -n1)
53
53
  back_up_env:=( \
54
54
  [ ! -f '${standard_env_path}' ] \
55
55
  || \
@@ -40,13 +40,36 @@ docker_organization=$(shell bash ${orchestration_dir}/yaml.bash docker_organizat
40
40
  docker_repository=$(shell bash ${orchestration_dir}/yaml.bash docker_repository)
41
41
 
42
42
  ifeq (,$(project_name))
43
- project_name = ${docker_repository}_${env}
43
+ project_base = ${docker_repository}_${env}
44
+ else
45
+ project_base := $(project_name)
46
+ endif
47
+
48
+ sidecar_suffix := $(shell test -f ${orchestration_dir}/.sidecar && cat ${orchestration_dir}/.sidecar)
49
+ ifneq (,${sidecar_suffix})
50
+ sidecar := 1
51
+ endif
52
+
53
+ ifdef sidecar
54
+ sidecar_compose = sidecar=1
55
+ ifeq (,${sidecar_suffix})
56
+ sidecar_suffix := $(call token)
57
+ _ignore := $(shell echo ${sidecar_suffix} > ${orchestration_dir}/.sidecar)
58
+ endif
59
+
60
+ ifeq (,${sidecar_suffix})
61
+ $(warning Unable to generate project suffix; project name collisions may occur.)
62
+ endif
63
+ compose_project_name = ${project_base}_${sidecar_suffix}
64
+ else
65
+ compose_project_name = ${project_base}
44
66
  endif
45
67
 
46
68
  compose_base=env HOST_UID=$(shell id -u) \
47
69
  DOCKER_ORGANIZATION="${docker_organization}" \
48
70
  DOCKER_REPOSITORY="${docker_repository}" \
49
- COMPOSE_PROJECT_NAME="${project_name}" \
71
+ COMPOSE_PROJECT_NAME="${compose_project_name}" \
72
+ ${sidecar_compose} \
50
73
  docker-compose \
51
74
  -f "${orchestration_dir}/docker-compose.yml"
52
75
 
@@ -67,7 +90,7 @@ all: build
67
90
 
68
91
  .PHONY: start
69
92
  ifndef network
70
- start: network := ${docker_repository}_${env}_default
93
+ start: network := ${compose_project_name}_default
71
94
  endif
72
95
  start: _clean-logs
73
96
  @$(call print,'${yellow}Starting containers${reset} ...')
@@ -75,9 +98,13 @@ ifeq (${env},$(filter ${env},test development))
75
98
  @${compose} up --detach --force-recreate --renew-anon-volumes ${services} ${log} || ${fail}
76
99
  @[ -n '${sidecar}' ] && \
77
100
  ( \
101
+ $(call printraw,' ${yellow}(joining dependency network ${green}${network}${yellow})${reset} ... ') ; \
78
102
  docker network connect '${network}' '$(shell hostname)' ${log} \
79
- || \
80
- $(call println,'${yellow}Warning${reset}: Unable to join network: "${yellow}${network}${reset}". Container will not be able to connect to dependency services.') \
103
+ || ( \
104
+ $(call println,'') ; \
105
+ $(call println,'${yellow}Warning${reset}: Unable to join network: "${yellow}${network}${reset}". Container will not be able to connect to dependency services.') ; \
106
+ $(call print,'You may need to delete "${yellow}orchestration/.sidecar${reset}" to disable sidecar mode if this file was added by mistake.\n...') ; \
107
+ ) \
81
108
  ) \
82
109
  || ( [ -z '${sidecar}' ] || ${fail} )
83
110
  else
@@ -99,13 +126,14 @@ start-<%= service %>:
99
126
  <% end %>
100
127
 
101
128
  .PHONY: stop
129
+ stop: network := ${compose_project_name}_default
102
130
  stop: _clean-logs
103
131
  @$(call print,'${yellow}Stopping containers${reset} ...')
104
132
  @if docker ps --format "{{.ID}}" | grep -q $(shell hostname) ; \
105
133
  then \
106
- ( ${compose} down ${log} || ${fail} ) \
134
+ ( docker network disconnect ${network} $(shell hostname) ${log} || : ) \
107
135
  && \
108
- ( docker network connect ${docker_repository}_${env}_default $(shell hostname) ${log} || : ) ; \
136
+ ( ${compose} down ${log} || ${fail} ) ; \
109
137
  else \
110
138
  ${compose} down ${log} || ${fail} ; \
111
139
  fi
@@ -231,7 +259,7 @@ endif
231
259
  echo 'DOCKER_TAG=${git_version}' >> ./.env && \
232
260
  $(call println,'') && \
233
261
  $(call println,'${yellow}Application image${reset}: ${cyan}${docker_image}${reset}') && \
234
- ${compose} config 2>${stderr} | ssh "${manager}" 'docker stack deploy --prune --with-registry-auth -c - "${project_name}"' ${log} && \
262
+ ${compose} config 2>${stderr} | ssh "${manager}" 'docker stack deploy --prune --with-registry-auth -c - "${project_base}"' ${log} && \
235
263
  ( [ -z "${path}" ] || rm -rf "${path}" ${log} ) \
236
264
  ) \
237
265
  || ${fail}
@@ -246,8 +274,8 @@ rollback:
246
274
  ifndef manager
247
275
  @$(call println_error,'Missing `manager` parameter: `make deploy manager=swarm-manager.example.com`') ; exit 1
248
276
  endif
249
- @$(call println,'${yellow}Rolling back${reset} ${green}${project_name}_${service}${reset} ${yellow}via${reset} ${green}${manager}${reset} ...')
250
- @ssh "${manager}" 'docker service rollback --detach "${project_name}_${service}"' ${log} || ${fail}
277
+ @$(call println,'${yellow}Rolling back${reset} ${green}${compose_project_name}_${service}${reset} ${yellow}via${reset} ${green}${manager}${reset} ...')
278
+ @ssh "${manager}" 'docker service rollback --detach "${compose_project_name}_${service}"' ${log} || ${fail}
251
279
  @$(call println,'${yellow}Rollback request${reset} ${green}complete${reset}. ${tick}')
252
280
 
253
281
  ### Service healthcheck commands ###
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orchestration
4
- VERSION = '0.4.10'
4
+ VERSION = '0.4.12'
5
5
  end
data/lib/orchestration.rb CHANGED
@@ -11,7 +11,7 @@ require 'paint'
11
11
  begin
12
12
  require 'rails'
13
13
  rescue LoadError
14
- STDERR.puts('[orchestration] Rails not detected; skipping.')
14
+ warn('[orchestration] Rails not detected; skipping.')
15
15
  end
16
16
 
17
17
  I18n.load_path += Dir[File.join(File.expand_path('..', __dir__),
@@ -40,8 +40,8 @@ module Orchestration
40
40
  end
41
41
 
42
42
  def self.error(key, options = {})
43
- STDERR.puts('# Orchestration Error')
44
- STDERR.puts('# ' + I18n.t("orchestration.#{key}", options))
43
+ warn('# Orchestration Error')
44
+ warn('# ' + I18n.t("orchestration.#{key}", options))
45
45
  end
46
46
 
47
47
  def self.random_local_port
@@ -40,7 +40,7 @@ Gem::Specification.new do |spec|
40
40
  spec.add_development_dependency 'rake', '~> 10.0'
41
41
  spec.add_development_dependency 'rspec', '~> 3.0'
42
42
  spec.add_development_dependency 'rspec-its', '~> 1.2'
43
- spec.add_development_dependency 'rubocop', '~> 0.59.2'
43
+ spec.add_development_dependency 'rubocop', '~> 0.77.0'
44
44
  spec.add_development_dependency 'sqlite3', '~> 1.3'
45
45
  spec.add_development_dependency 'strong_versions', '~> 0.3.1'
46
46
  spec.add_development_dependency 'webmock', '~> 3.4'
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.10
4
+ version: 0.4.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Farrell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-08 00:00:00.000000000 Z
11
+ date: 2019-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: database_url
@@ -254,14 +254,14 @@ dependencies:
254
254
  requirements:
255
255
  - - "~>"
256
256
  - !ruby/object:Gem::Version
257
- version: 0.59.2
257
+ version: 0.77.0
258
258
  type: :development
259
259
  prerelease: false
260
260
  version_requirements: !ruby/object:Gem::Requirement
261
261
  requirements:
262
262
  - - "~>"
263
263
  - !ruby/object:Gem::Version
264
- version: 0.59.2
264
+ version: 0.77.0
265
265
  - !ruby/object:Gem::Dependency
266
266
  name: sqlite3
267
267
  requirement: !ruby/object:Gem::Requirement
@@ -339,6 +339,7 @@ files:
339
339
  - lib/orchestration/docker_compose.rb
340
340
  - lib/orchestration/docker_compose/app_service.rb
341
341
  - lib/orchestration/docker_compose/compose_configuration.rb
342
+ - lib/orchestration/docker_compose/compose_helpers.rb
342
343
  - lib/orchestration/docker_compose/configuration.rb
343
344
  - lib/orchestration/docker_compose/database_service.rb
344
345
  - lib/orchestration/docker_compose/install_generator.rb
@@ -411,8 +412,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
411
412
  - !ruby/object:Gem::Version
412
413
  version: '0'
413
414
  requirements: []
414
- rubyforge_project:
415
- rubygems_version: 2.7.6
415
+ rubygems_version: 3.0.3
416
416
  signing_key:
417
417
  specification_version: 4
418
418
  summary: Docker orchestration toolkit