orchestration 0.5.14 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@
3
3
  module Orchestration
4
4
  class ServiceCheck
5
5
  ATTEMPT_LIMIT = ENV.fetch('ORCHESTRATION_RETRY_LIMIT', '15').to_i
6
- RETRY_INTERVAL = ENV.fetch('ORCHESTRATION_RETRY_INTERVAL', '10').to_i
6
+ RETRY_INTERVAL = ENV.fetch('ORCHESTRATION_RETRY_INTERVAL', '15').to_i
7
7
 
8
8
  def initialize(service, terminal, options = {})
9
9
  @service = service
@@ -31,36 +31,36 @@ module Orchestration
31
31
  @service.connect
32
32
  true
33
33
  rescue *@service.connection_errors => e
34
- @attempts += 1
35
- sleep @retry_interval
34
+ wait_failure(e)
36
35
  retry unless @attempts == @attempt_limit
37
36
  echo_error(e)
38
37
  echo_failure
39
38
  false
40
39
  end
41
40
 
42
- def echo_start
43
- @terminal.write(@service_name.to_sym, '', :status)
41
+ def wait_failure(error)
42
+ @attempts += 1
43
+ @last_error = error
44
+ sleep @retry_interval
44
45
  end
45
46
 
46
- def echo_waiting
47
- @terminal.write(:waiting, service_waiting)
47
+ def last_error
48
+ return nil if @last_error.nil?
49
+
50
+ last_error_message
48
51
  end
49
52
 
50
- def service_waiting
51
- I18n.t(
52
- "orchestration.#{@service_name}.waiting",
53
- config: friendly_config,
54
- default: default_waiting
55
- )
53
+ def last_error_message
54
+ "(#{@last_error&.cause&.class&.name || @last_error&.class&.name})"
56
55
  end
57
56
 
58
- def default_waiting
59
- I18n.t(
60
- 'orchestration.custom_service.waiting',
61
- config: friendly_config,
62
- service: @service_name
63
- )
57
+ def echo_start
58
+ @terminal.write(@service_name.to_sym, '', :status)
59
+ @terminal.write(:config, friendly_config)
60
+ end
61
+
62
+ def echo_waiting
63
+ @terminal.write(:waiting, last_error)
64
64
  end
65
65
 
66
66
  def echo_ready
@@ -68,30 +68,16 @@ module Orchestration
68
68
  end
69
69
 
70
70
  def service_ready
71
- I18n.t(
72
- "orchestration.#{@service_name}.ready",
73
- config: friendly_config,
74
- default: default_ready
75
- )
76
- end
77
-
78
- def default_ready
79
- I18n.t(
80
- 'orchestration.custom_service.ready',
81
- config: friendly_config,
82
- service: @service_name
83
- )
71
+ I18n.t('orchestration.service.ready', service: @service_name)
84
72
  end
85
73
 
86
74
  def echo_failure
87
- @terminal.write(
88
- :failure,
89
- I18n.t('orchestration.attempt_limit', limit: @attempt_limit)
90
- )
75
+ @terminal.write(:failure, I18n.t('orchestration.attempt_limit', limit: @attempt_limit))
91
76
  end
92
77
 
93
78
  def echo_error(error)
94
- @terminal.write(:error, "[#{error.class.name}] #{error.message}")
79
+ cause = error.cause.nil? ? error : error.cause
80
+ @terminal.write(:error, "[#{cause.class.name}] #{cause.message}")
95
81
  end
96
82
 
97
83
  def friendly_config
@@ -9,6 +9,7 @@ module Orchestration
9
9
  end
10
10
  end
11
11
 
12
+ require 'orchestration/services/database/adapters/adapter_base'
12
13
  require 'orchestration/services/database/adapters/mysql2'
13
14
  require 'orchestration/services/database/adapters/postgresql'
14
15
  require 'orchestration/services/database/adapters/sqlite3'
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orchestration
4
+ module Services
5
+ module Database
6
+ module Adapters
7
+ module AdapterBase
8
+ attr_reader :config
9
+
10
+ def initialize(config = nil)
11
+ @config = config
12
+ end
13
+
14
+ def console_command
15
+ I18n.t("orchestration.dbconsole.#{name}") % config.settings.transform_keys(&:to_sym)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -5,6 +5,8 @@ module Orchestration
5
5
  module Database
6
6
  module Adapters
7
7
  class Mysql2
8
+ include AdapterBase
9
+
8
10
  def name
9
11
  'mysql2'
10
12
  end
@@ -5,6 +5,8 @@ module Orchestration
5
5
  module Database
6
6
  module Adapters
7
7
  class Postgresql
8
+ include AdapterBase
9
+
8
10
  def name
9
11
  'postgresql'
10
12
  end
@@ -5,6 +5,8 @@ module Orchestration
5
5
  module Database
6
6
  module Adapters
7
7
  class Sqlite3
8
+ include AdapterBase
9
+
8
10
  def name
9
11
  'sqlite3'
10
12
  end
@@ -33,6 +33,10 @@ module Orchestration
33
33
  sqlite? || super
34
34
  end
35
35
 
36
+ def console_command
37
+ adapter.console_command
38
+ end
39
+
36
40
  def adapter
37
41
  url_adapter = url_config['adapter']
38
42
  file_adapter = file_config['adapter']
@@ -115,7 +119,7 @@ module Orchestration
115
119
  'mysql' => adapters::Mysql2,
116
120
  'postgresql' => adapters::Postgresql,
117
121
  'sqlite3' => adapters::Sqlite3
118
- }.fetch(name).new
122
+ }.fetch(name).new(self)
119
123
  rescue KeyError
120
124
  Orchestration.error('database.unknown_adapter', adapter: name.inspect)
121
125
  raise
@@ -53,7 +53,7 @@ module Orchestration
53
53
  local, remote = parse_port(service).map(&:to_i)
54
54
  return remote if @env.environment == 'test' && @options[:sidecar]
55
55
 
56
- (@env.environment == 'production' ? remote : local)
56
+ (@env.environment == 'deployment' ? remote : local)
57
57
  end
58
58
 
59
59
  def service
@@ -2,7 +2,7 @@ FROM ruby:<%= ruby_version %>
2
2
  ARG BUNDLE_BITBUCKET__ORG
3
3
  ARG BUNDLE_GITHUB__COM
4
4
  ARG GIT_COMMIT
5
- RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
5
+ RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
6
6
  && apt-get update \
7
7
  && DEBIAN_FRONTEND=noninteractive apt-get install -y \
8
8
  nodejs \
@@ -13,17 +13,13 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
13
13
  && mkdir /app<%if defined?(Webpacker) %> \
14
14
  && curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash \
15
15
  && . /root/.bashrc \
16
- && nvm install 10.13.0 \
16
+ && nvm install 14.16.0 \
17
17
  && npm config set user 0 \
18
18
  && npm config set unsafe-perm true \
19
19
  && npm install -g yarn<% end %>
20
20
  WORKDIR /app
21
21
  COPY .build/Gemfile .build/Gemfile.lock ./
22
22
  RUN bundle install --without development test --deployment
23
- <% if defined?(Webpacker) %>
24
- COPY .build/package.json .build/yarn.lock ./
25
- RUN . /root/.bashrc ; yarn install
26
- <% end %>
27
23
  ADD .build/context.tar .
28
24
  <% 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 %>
29
25
  RUN echo "${GIT_COMMIT}" > /app/GIT_COMMIT
@@ -1,20 +1,36 @@
1
+ include $(shell bundle exec ruby -e 'require "orchestration/make"')
2
+
1
3
  #
2
4
  # Example test command
3
5
  #
4
- # This command will call `test-setup` before running your usual test pipeline.
6
+ # Define your test tasks here. The default command runs RSpec and Rubocop but
7
+ # you can feel free to add any other tasks you like.
5
8
  #
6
- # `test-setup` starts all containers specified in `docker-compose.test.yml`,
7
- # waits for them to be ready, and runs DB migrations.
9
+ # Set up your test dependencies and run tests by calling: `make setup test`
8
10
  #
9
- # In your CI environment, simply run `make test`.
11
+ # Subsequent test runs can skip the setup step and simply run: `make test`
10
12
  #
11
13
  .PHONY: test
12
- test: test-setup
14
+ test:
13
15
  bundle exec rspec
14
16
  bundle exec rubocop
15
17
 
16
- # Start development containers and create/migrate/seed database
17
- .PHONY: develop
18
+ #
19
+ # Define any custom setup that needs to take place before running tests.
20
+ # If the command exists, it will be called immediately after the `setup`
21
+ # command (which starts containers and sets up the database).
22
+ #
23
+ # This command can be deleted if it is not needed.
24
+ #
25
+ .PHONY: post-setup
26
+ post-setup:
27
+ # Setup tasks that are not already provided by Orchestration go here.
28
+
29
+ #
30
+ # Launch all dependencies needed for a development environment and set up the
31
+ # development database.
32
+ #
33
+ .PHONY: setup
18
34
  develop:
19
35
  bundle install
20
36
  @$(MAKE) start env=test
@@ -4,7 +4,6 @@ module Orchestration
4
4
  COLOR_MAP = {
5
5
  failure: %i[red bright],
6
6
  error: %i[red],
7
- waiting: %i[yellow],
8
7
  ready: %i[green],
9
8
  create: %i[green],
10
9
  update: %i[yellow],
@@ -12,7 +11,9 @@ module Orchestration
12
11
  status: %i[blue],
13
12
  setup: %i[blue],
14
13
  input: %i[red],
15
- skip: %i[yellow bright]
14
+ skip: %i[yellow bright],
15
+ waiting: %i[yellow],
16
+ config: %i[cyan]
16
17
  }.freeze
17
18
 
18
19
  class Terminal
@@ -20,7 +21,7 @@ module Orchestration
20
21
  @settings = settings
21
22
  end
22
23
 
23
- def write(desc, message, color_name = nil, newline: true)
24
+ def write(desc, message = nil, color_name = nil, newline: true)
24
25
  output = newline ? "#{message}\n" : message.to_s
25
26
  $stdout.print colorize(desc, output, color_name)
26
27
  $stdout.flush
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orchestration
4
- VERSION = '0.5.14'
4
+ VERSION = '0.6.0'
5
5
  end
@@ -8,11 +8,9 @@ namespace :orchestration do
8
8
  Orchestration::InstallGenerator.start
9
9
  end
10
10
 
11
- namespace :install do
12
- desc I18n.t('orchestration.rake.install_makefile')
13
- task :makefile do
14
- Orchestration::InstallGenerator.new.orchestration_makefile
15
- end
11
+ desc I18n.t('orchestration.makefile')
12
+ task :makefile do
13
+ Orchestration.makefile
16
14
  end
17
15
 
18
16
  desc I18n.t('orchestration.rake.config')
@@ -21,6 +19,20 @@ namespace :orchestration do
21
19
  puts "#{config['docker']['organization']} #{config['docker']['repository']}"
22
20
  end
23
21
 
22
+ namespace :db do
23
+ desc I18n.t('orchestration.rake.db.url')
24
+ task :url do
25
+ puts DatabaseUrl.to_active_record_url(Rails.application.config_for(:database))
26
+ end
27
+
28
+ desc I18n.t('orchestration.rake.db.console')
29
+ task :console do
30
+ env = Orchestration::Environment.new
31
+ options = ENV['db'] ? { config_path: "config/database.#{ENV['db']}.yml" } : {}
32
+ sh Orchestration::Services::Database::Configuration.new(env, nil, options).console_command
33
+ end
34
+ end
35
+
24
36
  desc I18n.t('orchestration.rake.healthcheck')
25
37
  task :healthcheck do
26
38
  Orchestration::DockerHealthcheck.execute
@@ -28,7 +40,6 @@ namespace :orchestration do
28
40
 
29
41
  desc I18n.t('orchestration.rake.wait')
30
42
  task :wait do
31
- Orchestration::InstallGenerator.new.verify_makefile(skip: false)
32
43
  env = Orchestration::Environment.new
33
44
  services = Orchestration::Services
34
45
  env.docker_compose_config['services'].each do |name, _service|
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_runtime_dependency 'erubis', '~> 2.7'
31
31
  spec.add_runtime_dependency 'i18n', '>= 0.5'
32
32
  spec.add_runtime_dependency 'paint', '~> 2.0'
33
+ spec.add_runtime_dependency 'rails', '~> 6.0'
33
34
  spec.add_runtime_dependency 'thor', '~> 1.0'
34
35
 
35
36
  spec.add_development_dependency 'activerecord', '~> 6.0'
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.5.14
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Farrell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-25 00:00:00.000000000 Z
11
+ date: 2021-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: database_url
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rails
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '6.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '6.0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: thor
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -355,6 +369,8 @@ files:
355
369
  - lib/orchestration/errors.rb
356
370
  - lib/orchestration/file_helpers.rb
357
371
  - lib/orchestration/install_generator.rb
372
+ - lib/orchestration/make.rb
373
+ - lib/orchestration/make/orchestration.mk
358
374
  - lib/orchestration/railtie.rb
359
375
  - lib/orchestration/service_check.rb
360
376
  - lib/orchestration/services.rb
@@ -363,6 +379,7 @@ files:
363
379
  - lib/orchestration/services/app/healthcheck.rb
364
380
  - lib/orchestration/services/database.rb
365
381
  - lib/orchestration/services/database/adapters.rb
382
+ - lib/orchestration/services/database/adapters/adapter_base.rb
366
383
  - lib/orchestration/services/database/adapters/mysql2.rb
367
384
  - lib/orchestration/services/database/adapters/postgresql.rb
368
385
  - lib/orchestration/services/database/adapters/sqlite3.rb
@@ -386,9 +403,7 @@ files:
386
403
  - lib/orchestration/templates/database.yml.erb
387
404
  - lib/orchestration/templates/entrypoint.sh.erb
388
405
  - lib/orchestration/templates/env.erb
389
- - lib/orchestration/templates/makefile_macros.mk.erb
390
406
  - lib/orchestration/templates/mongoid.yml.erb
391
- - lib/orchestration/templates/orchestration.mk.erb
392
407
  - lib/orchestration/templates/puma.rb.erb
393
408
  - lib/orchestration/templates/rabbitmq.yml.erb
394
409
  - lib/orchestration/templates/unicorn.rb.erb
@@ -1,112 +0,0 @@
1
- TERM ?= 'dumb'
2
- pwd:=$(shell pwd)
3
- ifdef mounted_orchestration
4
- orchestration_dir=$(mounted_orchestration)
5
- else
6
- orchestration_dir=${pwd}/<%= env.orchestration_dir_name %>
7
- endif
8
-
9
- ifdef env_file
10
- custom_env_file ?= 1
11
- else
12
- custom_env_file ?= 0
13
- endif
14
-
15
- ifneq (,$(wildcard ${pwd}/config/database.yml))
16
- database_enabled = 1
17
- else
18
- database_enabled = 0
19
- endif
20
-
21
- make=$(MAKE) $1
22
- orchestration_config_filename:=.orchestration.yml
23
- orchestration_config:=${pwd}/${orchestration_config_filename}
24
- print_error=printf '${red}\#${reset} '$1 | tee '${stderr}'
25
- println_error=$(call print_error,$1'\n')
26
- print=printf '${blue}\#${reset} '$1
27
- println=$(call print,$1'\n')
28
- printraw=printf $1
29
- printrawln=$(call printraw,$1'\n')
30
- stdout=${pwd}/log/orchestration.stdout.log
31
- stderr=${pwd}/log/orchestration.stderr.log
32
- log_path_length=$(shell echo "${stdout}" | wc -c)
33
- ifndef verbose
34
- log_tee:= 2>&1 | tee -a ${stdout}
35
- log:= >>${stdout} 2>>${stderr}
36
- progress_point:=perl -e 'while( my $$line = <STDIN> ) { printf("."); select()->flush(); }'
37
- log_progress:= > >(tee -ai ${stdout} >&1 | ${progress_point}) 2> >(tee -ai ${stderr} 2>&1 | ${progress_point})
38
- endif
39
- red:=$(shell tput setaf 1)
40
- green:=$(shell tput setaf 2)
41
- yellow:=$(shell tput setaf 3)
42
- blue:=$(shell tput setaf 4)
43
- magenta:=$(shell tput setaf 5)
44
- cyan:=$(shell tput setaf 6)
45
- gray:=$(shell tput setaf 7)
46
- reset:=$(shell tput sgr0)
47
- tick=[${green}✓${reset}]
48
- cross=[${red}✘${reset}]
49
- warn=[${yellow}!${reset}]
50
- hr=$(call println,"$1$(shell head -c ${log_path_length} < /dev/zero | tr '\0' '=')${reset}")
51
- managed_env_tag:=\# -|- ORCHESTRATION
52
- standard_env_path:=${pwd}/.env
53
- backup_env_path:=${pwd}/.env.orchestration.backup
54
- is_managed_env:=$$(test -f '${standard_env_path}' && tail -n 1 '${standard_env_path}') == "${managed_env_tag}"*
55
- token:=$(shell cat /dev/urandom | LC_CTYPE=C tr -dc 'a-z0-9' | fold -w8 | head -n1)
56
- back_up_env:=( \
57
- [ ! -f '${standard_env_path}' ] \
58
- || \
59
- ( \
60
- [ -f '${standard_env_path}' ] \
61
- && cp '${standard_env_path}' '${backup_env_path}' \
62
- ) \
63
- )
64
-
65
- replace_env:=( \
66
- ( [ "${custom_env_file}" == "0" ] ) \
67
- || \
68
- ( \
69
- [ "${custom_env_file}" == "1" ] \
70
- && ${back_up_env} \
71
- && cp ${env_file} '${standard_env_path}' \
72
- && $(call printraw,'\n${managed_env_tag}') >> '${standard_env_path}' \
73
- ) \
74
- )
75
-
76
- restore_env:=( \
77
- ( \
78
- [[ ! ${is_managed_env} ]] \
79
- || [ ! -f '${backup_env_path}' ] \
80
- ) \
81
- || \
82
- ( \
83
- [ -f '${backup_env_path}' ] \
84
- && [[ ${is_managed_env} ]] \
85
- && mv '${backup_env_path}' '${standard_env_path}' \
86
- ) \
87
- )
88
-
89
- key_chars:=[a-zA-Z0-9_]
90
- censored:=**********
91
- censor=s/\(^${key_chars}*$(1)${key_chars}*\)=\(.*\)$$/\1=${censored}/
92
- censor_urls:=s|\([a-zA-Z0-9_+]\+://.*:\).*\(@.*\)$$|\1${censored}\2|
93
- format_env:=sed '$(call censor,SECRET); \
94
- $(call censor,TOKEN); \
95
- $(call censor,PRIVATE); \
96
- $(call censor,KEY); \
97
- $(censor_urls); \
98
- /^\s*$$/d; \
99
- /^\s*\#/d; \
100
- s/\(^[a-zA-Z0-9_]\+\)=/${blue}\1${reset}=/; \
101
- s/^/ /; \
102
- s/=\(.*\)$$/=${yellow}\1${reset}/' | \
103
- sort
104
-
105
- fail=( \
106
- $(call printraw,' ${cross}') ; \
107
- ${restore_env} ; \
108
- $(call make,dump) ; \
109
- echo ; \
110
- $(call println,'Failed. ${cross}') ; \
111
- exit 1 \
112
- )