class EtFullSystem::LocalCommand
Constants
- DEFAULT_BASE_URL
- GEM_PATH
- LOCK_FILE
- PROJECT_PATH
Public Instance Methods
boot()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 20 def boot STDERR.puts "boot - base_url is #{options[:base_url]}" json_setup_file = File.absolute_path('../../../foreman/traefik.json', __dir__) connect_retry_countdown = 10 begin resp = HTTParty.put "#{options[:base_url]}/api/providers/rest", body: File.read(json_setup_file) , headers: {'Content-Type': 'application/json', 'Accept': 'application/json'} raise "Error from traefik when performing initial config says: #{resp.body}" unless (200..299).include? resp.code sleep 1 rescue Errno::EADDRNOTAVAIL, Errno::ECONNREFUSED connect_retry_countdown -= 1 if connect_retry_countdown.zero? raise "Could not connect to the traefik API after 10 retries (boot)" else STDERR.puts "boot - Retrying connection to traefik API in 5 seconds" sleep 5 retry end end end
disable_admin()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 260 def disable_admin invoker 'remove', 'admin_web' puts "Admin is now stopped" end
disable_api()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 253 def disable_api invoker 'remove', 'api_web' invoker 'remove', 'api_sidekiq' puts "api is now stopped" end
disable_atos_api()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 247 def disable_atos_api invoker 'remove', 'atos_api_web' puts "atos_api is now stopped" end
disable_ccd_export()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 241 def disable_ccd_export invoker 'remove', 'et_ccd_export_sidekiq' puts "ccd_export is now stopped" end
disable_et1()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 234 def disable_et1 invoker 'remove', 'et1_web' invoker 'remove', 'et1_sidekiq' puts "ET1 is now stopped" end
disable_et3()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 266 def disable_et3 invoker 'remove', 'et3_web' puts "ET3 is now stopped" end
enable_admin()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 222 def enable_admin invoker 'add', 'admin_web' puts "Admin is now running" end
enable_api()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 215 def enable_api invoker 'add', 'api_web' invoker 'add', 'api_sidekiq' puts "api is now running" end
enable_atos_api()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 209 def enable_atos_api invoker 'add', 'atos_api_web' puts "atos_api is now running" end
enable_ccd_export()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 203 def enable_ccd_export invoker 'add', 'et_ccd_export_sidekiq' puts "ccd_export is now running" end
enable_et1()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 196 def enable_et1 invoker 'add', 'et1_web' invoker 'add', 'et1_sidekiq' puts "ET1 is now running" end
enable_et3()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 228 def enable_et3 invoker 'add', 'et3_web' puts "ET3 is now running" end
invoker(*args)
click to toggle source
# File lib/et_full_system/cli/local.rb, line 187 def invoker(*args) cmd = "invoker #{args.join(' ')}" puts cmd result = `#{cmd}` puts result result end
restart_admin()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 292 def restart_admin invoker 'reload', 'admin_web' puts "admin Has been restarted" end
restart_api()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 279 def restart_api invoker 'reload', 'api_web' invoker 'reload', 'api_sidekiq' puts "api Has been restarted" end
restart_atos_api()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 298 def restart_atos_api invoker 'reload', 'atos_api_web' puts "atos_api Has been restarted" end
restart_ccd_export()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 304 def restart_ccd_export invoker 'reload', 'et_ccd_export_sidekiq' puts "ccd_export Has been restarted" end
restart_et1()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 272 def restart_et1 invoker 'reload', 'et1_web' invoker 'reload', 'et1_sidekiq' puts "ET1 Has been restarted" end
restart_et3()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 286 def restart_et3 invoker 'reload', 'et3_web' puts "et3 Has been restarted" end
server()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 88 def server puts "Scheduling traefik config and file storage config" pid = fork do self.class.start(['boot']) EtFullSystem::Cli::Local::FileStorageCommand.start(['setup']) end Process.detach(pid) puts "Starting Invoker" unbundled do without = options[:without] if options.minimal? without = ['et1', 'et3', 'admin', 'api', 'ccd_export', 'atos_api'] end cmd = "CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} AZURITE_STORAGE_PATH=\"#{options[:azurite_storage_path]}\" MINIO_STORAGE_PATH=\"#{options[:minio_storage_path]}\" FS_ROOT_PATH=#{PROJECT_PATH} FOREMAN_PATH=#{GEM_PATH}/foreman godotenv -f #{GEM_PATH}/foreman/.env invoker start \"#{GEM_PATH}/foreman/Procfile\" --port=4000" STDERR.puts cmd unless without.empty? stop_cmds = without.reduce([]) do |acc, service| acc.concat(invoker_processes_for(service)) end.map do |proc| "invoker remove #{proc}" end stop_cmd = stop_cmds.join(' && ') puts "---------------------- DISABLING SERVICES IN 30 SECONDS ---------------------------" puts "command is #{stop_cmd}" Process.fork do sleep 30 puts `#{stop_cmd}` end end exec cmd end end
service_env(service)
click to toggle source
# File lib/et_full_system/cli/local.rb, line 168 def service_env(service) lookup = { 'atos_api' => :et_atos, 'admin' => :et_admin, 'api' => :et_api, 'et1' => :et1, 'et3' => :et3, 'et_ccd_export' => :et_ccd_export } file = lookup.fetch(service) parsed = Dotenv.parse("#{GEM_PATH}/foreman/.env", "#{GEM_PATH}/foreman/#{file}.env") parsed.each_pair do |name, value| puts "#{name}=#{value}" end rescue KeyError puts "The service must be one of #{lookup.keys}" end
setup()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 128 def setup setup_depencencies setup_ruby_versions setup_services end
setup_depencencies()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 147 def setup_depencencies cmd = "bash --login -c \"cd /tmp && git clone https://github.com/ministryofjustice/et_fake_acas_server.git && cd et_fake_acas_server && gem build -o et_fake_acas_server.gem et_fake_acas_server && gem install et_fake_acas_server.gem && cd .. && rm -rf et_fake_acas_server\"" STDERR.puts cmd external_command cmd, 'setup_dependencies' end
setup_ruby_versions()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 154 def setup_ruby_versions versions = Dir.glob(File.join(PROJECT_PATH, 'systems', '*', '.ruby-version')).map do |version_file| File.read(version_file).split("\n").first.gsub(/\Aruby-/, '') end.uniq - [RUBY_VERSION] versions.each do |version| puts "------------------------------------------------ SETTING UP ruby #{version} ---------------------------------------------------" cmd = "bash --login -c \"rvm install #{version}\"" puts cmd external_command cmd, "ruby #{version} install" end end
setup_services()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 135 def setup_services unbundled do setup_et1_service setup_et3_service setup_api_service setup_admin_service setup_atos_service setup_ccd_service end end
update_service_url(service, url)
click to toggle source
# File lib/et_full_system/cli/local.rb, line 43 def update_service_url(service, url) within_rest_lock do update_rest_backend_url(service, url) end end
wait_for_support()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 51 def wait_for_support connect_retry_countdown = 10 setup_retry_countdown = 10 begin resp = HTTParty.get "#{options[:base_url]}/api/providers/rest", headers: {'Content-Type': 'application/json', 'Accept': 'application/json'} raise RestProviderNotConfigured if resp.code == 404 rescue Errno::EADDRNOTAVAIL, Errno::ECONNREFUSED connect_retry_countdown -= 1 if connect_retry_countdown.zero? raise "Could not connect to the traefik API after 10 retries (wait_for_support)" else STDERR.puts "wait_for_support - Retrying connection to traefik API in 5 seconds" sleep 5 retry end rescue RestProviderNotConfigured setup_retry_countdown -= 1 if setup_retry_countdown.zero? raise "Could not find the REST provider in traefik after 10 retries" else STDERR.puts "Re checking for the REST provider in traefik in 5 seconds" sleep 5 retry end end STDERR.puts "Support services now ready" end
Private Instance Methods
external_command(cmd, tag)
click to toggle source
# File lib/et_full_system/cli/local.rb, line 335 def external_command(cmd, tag) IO.popen(cmd) do |io| io.each do |line| puts "| #{tag} | #{line}" end end end
invoker_processes_for(service)
click to toggle source
# File lib/et_full_system/cli/local.rb, line 316 def invoker_processes_for(service) case service when 'et1' then ['et1_web', 'et1_sidekiq'] when 'et3' then ['et3_web'] when 'api' then ['api_web', 'api_sidekiq'] when 'admin' then ['admin_web'] when 'atos_api' then ['atos_api_web'] when 'ccd_export' then ['et_ccd_export_sidekiq'] else raise "Unknown service #{service}" end end
procfile_services()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 328 def procfile_services File.readlines("#{GEM_PATH}/foreman/Procfile").inject([]) do |acc, line| next if line.strip.start_with?('#') acc + [line.split(':').first] end end
setup_admin_service()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 369 def setup_admin_service puts "------------------------------------------------ SETTING UP ADMIN SERVICE ---------------------------------------------------" cmd ="bash --login -c \"cd #{PROJECT_PATH}/systems/admin && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et_admin.env\" gem install bundler:1.17.3 && bundle install --with=#{options[:rails_env]}\"" puts cmd external_command cmd, 'admin setup' puts "| Admin | Running rake commands" cmd ="bash --login -c \"cd #{PROJECT_PATH}/systems/admin && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et_admin.env\" bundle exec rake db:seed assets:precompile\"" puts cmd external_command cmd, 'admin setup' end
setup_api_service()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 381 def setup_api_service puts "------------------------------------------------ SETTING UP API SERVICE ---------------------------------------------------" cmd ="bash --login -c \"cd #{PROJECT_PATH}/systems/api && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et_api.env\" gem install bundler:1.17.3 && bundle install --with=#{options[:rails_env]}\"" puts cmd external_command cmd, 'api setup' puts "| API | Running rake commands" cmd ="bash --login -c \"cd #{PROJECT_PATH}/systems/api && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et_api.env\" bundle exec rake db:create db:migrate db:seed\"" puts cmd external_command cmd, 'api setup' end
setup_atos_service()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 393 def setup_atos_service puts "------------------------------------------------ SETTING UP ATOS SERVICE ---------------------------------------------------" cmd ="bash --login -c \"cd #{PROJECT_PATH}/systems/atos && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et_atos.env\" gem install bundler:1.17.3 && bundle install --with=#{options[:rails_env]}\"" puts cmd external_command cmd, 'atos setup' end
setup_ccd_service()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 400 def setup_ccd_service puts "------------------------------------------------ SETTING UP CCD EXPORT SERVICE ---------------------------------------------------" cmd ="bash --login -c \"cd #{PROJECT_PATH}/systems/et_ccd_export && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et_ccd_export.env\" gem install bundler:1.17.3 && bundle install --with=#{options[:rails_env]}\"" puts cmd external_command cmd, 'ccd setup' end
setup_et1_service()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 343 def setup_et1_service puts "------------------------------------------------ SETTING UP ET1 SERVICE ---------------------------------------------------" cmd = "bash --login -c \"cd #{PROJECT_PATH}/systems/et1 && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et1.env\" gem install bundler:1.17.3 && bundle install --with=#{options[:rails_env]}\"" puts cmd external_command cmd, 'et1 setup' cmd = "bash --login -c \"cd #{PROJECT_PATH}/systems/et1 && npm install\"" puts cmd external_command cmd, 'et1 setup' cmd ="bash --login -c \"cd #{PROJECT_PATH}/systems/et1 && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et1.env\" bundle exec rake db:create db:migrate assets:precompile\"" puts cmd external_command cmd, 'et1 setup' end
setup_et3_service()
click to toggle source
# File lib/et_full_system/cli/local.rb, line 358 def setup_et3_service puts "------------------------------------------------ SETTING UP ET3 SERVICE ---------------------------------------------------" cmd ="bash --login -c \"cd #{PROJECT_PATH}/systems/et3 && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et3.env\" gem install bundler:1.17.3 && bundle install --with=#{options[:rails_env]}\"" puts cmd external_command cmd, 'et3 setup' cmd ="bash --login -c \"cd #{PROJECT_PATH}/systems/et3 && CLOUD_PROVIDER=#{options[:cloud_provider]} RAILS_ENV=#{options[:rails_env]} godotenv -f \"#{GEM_PATH}/foreman/.env\" godotenv -f \"#{GEM_PATH}/foreman/et3.env\" bundle exec rake db:create db:migrate assets:precompile\"" puts cmd external_command cmd, 'et3 setup' end
summarise_json(json)
click to toggle source
# File lib/et_full_system/cli/local.rb, line 479 def summarise_json(json) json['backends'].inject({}) do |acc, (service, value)| acc[service] = value.dig('servers', 'web', 'url') acc end end
unbundled(&block)
click to toggle source
# File lib/et_full_system/cli/local.rb, line 311 def unbundled(&block) method = Bundler.respond_to?(:with_unbundled_env) ? :with_unbundled_env : :with_original_env Bundler.send(method, &block) end
update_rest_backend_url(service, url)
click to toggle source
# File lib/et_full_system/cli/local.rb, line 407 def update_rest_backend_url(service, url) connect_retry_countdown = 10 setup_retry_countdown = 10 begin resp = HTTParty.get "#{options[:base_url]}/api/providers/rest", headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } raise RestProviderNotConfigured if resp.code == 404 rescue Errno::EADDRNOTAVAIL, Errno::ECONNREFUSED connect_retry_countdown -= 1 if !options[:wait] fail "Could not connect to the traefik API - specify --wait to keep retrying when this happens" elsif connect_retry_countdown.zero? fail "Could not connect to the traefik API after 10 retries (update_rest_backend_url)" else STDERR.puts "update_rest_backend_url - Retrying connection to traefik API in 5 seconds" sleep 5 retry end rescue RestProviderNotConfigured setup_retry_countdown -= 1 if !options[:wait] fail "The REST provider in traefik is not yet setup - specify --wait to keep retrying when this happens (i.e to wait for another command to set it up)" elsif setup_retry_countdown.zero? fail "Could not find the REST provider in traefik after 10 retries" else STDERR.puts "Re checking for the REST provider in traefik in 5 seconds" sleep 5 retry end end json = resp.parsed_response.dup backend = json['backends'][service] raise "Unknown service called #{service} - valid options are #{json['backends'].keys.join(', ')}" if backend.nil? container = backend.dig('servers', 'web') raise "The service '#{service}' has no server called 'web' - it must have for this command to work" if container.nil? if container['url'] != url container['url'] = url put_resp = HTTParty.put "#{options[:base_url]}/api/providers/rest", body: json.to_json, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } raise "Error from traefik says: #{put_resp.body}" unless (200..299).include? put_resp.code validate_rest_backend_url(service, url) STDERR.puts "The url for service '#{service}' is now '#{url}'" else STDERR.puts "The url for service '#{service}' was already '#{url}'" end end
validate_rest_backend_url(service, url)
click to toggle source
# File lib/et_full_system/cli/local.rb, line 456 def validate_rest_backend_url(service, url) retry_countdown = 10 begin resp = HTTParty.get "#{options[:base_url]}/api/providers/rest", headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } raise ServiceUrlIncorrect unless (200..299).include?(resp.code) && resp.parsed_response.dig('backends', service, 'servers', 'web', 'url') == url return rescue ServiceUrlIncorrect retry_countdown -= 1 raise if retry_countdown.zero? STDERR.puts "Retrying request to validate the url of '#{service}' is '#{url}' in 1 second" sleep 1 retry end end
within_rest_lock(wait: 60 * 60 * 24, timeout: 60) { |file| ... }
click to toggle source
# File lib/et_full_system/cli/local.rb, line 472 def within_rest_lock(wait: 60 * 60 * 24, timeout: 60) File.open(LOCK_FILE, File::RDWR|File::CREAT, 0644) do |file| Timeout::timeout(wait) { file.flock(File::LOCK_EX) } Timeout::timeout(timeout) { yield file } end end