configure_environment.rb 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #!/usr/bin/env ruby
  2. # Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
  3. require 'yaml'
  4. require 'resolv'
  5. #
  6. # Configures the CI system
  7. # - either (randomly) mysql or postgresql, if it is available
  8. # - (randomly) Redis or File as web socket session back end, if Redis is available
  9. #
  10. # Database config happens directly in config/database.yml, other settings are written to
  11. # .gitlab/environment.env which must be sourced in the CI configuration.
  12. #
  13. class ConfigureEnvironment
  14. @env_file_content = <<~ENV_FILE_CONTENT
  15. #!/bin/bash
  16. FRESHENVFILE=fresh.env && test -f $FRESHENVFILE && source $FRESHENVFILE
  17. true
  18. ENV_FILE_CONTENT
  19. def self.configure_redis
  20. if ENV['REDIS_URL'].nil? || ENV['REDIS_URL'].empty? # rubocop:disable Rails/Blank
  21. puts 'Redis is not available, using File as web socket session store.'
  22. return
  23. end
  24. if [true, false].sample
  25. puts 'Using Redis as web socket session store.'
  26. return
  27. end
  28. puts 'Using File as web socket session store.'
  29. @env_file_content += "unset REDIS_URL\n"
  30. end
  31. def self.configure_memcached
  32. if ENV['MEMCACHE_SERVERS'].nil? || ENV['MEMCACHE_SERVERS'].empty? # rubocop:disable Rails/Blank
  33. puts 'Memcached is not available, using File as Rails cache store.'
  34. return
  35. end
  36. if [true, false].sample
  37. puts 'Using memcached as Rails cache store.'
  38. return
  39. end
  40. puts "Using Zammad's file store as Rails cache store."
  41. @env_file_content += "unset MEMCACHE_SERVERS\n"
  42. end
  43. def self.configure_database # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
  44. if File.exist? File.join(__dir__, '../config/database.yml')
  45. puts "'config/database.yml' already exists and will not be changed."
  46. return
  47. end
  48. cnf = YAML.load_file(File.join(__dir__, '../config/database/database.yml'))
  49. cnf.delete('default')
  50. database = ENV['ENFORCE_DB_SERVICE']
  51. # Lookup in /etc/hosts first: gitlab uses that if FF_NETWORK_PER_BUILD is not set.
  52. if !database
  53. hostsfile = '/etc/hosts'
  54. database = %w[postgresql mysql].shuffle.find do |possible_database|
  55. File.foreach(hostsfile).any? { |l| l[possible_database] }
  56. end
  57. end
  58. # Lookup via DNS if needed: gitlab uses that if FF_NETWORK_PER_BUILD is enabled.
  59. if !database
  60. dns = Resolv::DNS.new
  61. dns.timeouts = 3
  62. database = %w[postgresql mysql].shuffle.find do |possible_database|
  63. # Perform a lookup of the database host to check if it is configured as a service.
  64. if dns.getaddress possible_database
  65. next possible_database
  66. end
  67. rescue Resolv::ResolvError
  68. # Ignore DNS lookup errors
  69. end
  70. end
  71. raise "Can't find any supported database." if database.nil?
  72. puts "Using #{database} as database service."
  73. db_settings_map = {
  74. 'postgresql' => {
  75. 'adapter' => 'postgresql',
  76. 'username' => 'zammad',
  77. 'password' => 'zammad',
  78. 'host' => 'postgresql', # db alias from gitlab-ci.yml
  79. },
  80. 'mysql' => {
  81. 'adapter' => 'mysql2',
  82. 'username' => 'root',
  83. 'password' => 'zammad',
  84. 'host' => 'mysql', # db alias from gitlab-ci.yml
  85. }
  86. }
  87. # fetch DB settings from settings map and fallback to postgresql
  88. db_settings = db_settings_map.fetch(database) { db_settings_map['postgresql'] }
  89. %w[development test production].each do |environment|
  90. cnf[environment].merge!(db_settings)
  91. end
  92. File.write(File.join(__dir__, '../config/database.yml'), Psych.dump(cnf))
  93. end
  94. def self.write_env_file
  95. File.write(File.join(__dir__, 'environment.env'), @env_file_content)
  96. end
  97. def self.run
  98. configure_redis
  99. configure_memcached
  100. configure_database
  101. write_env_file
  102. end
  103. end
  104. ConfigureEnvironment.run