diff --git a/Dockerfile b/Dockerfile index a80122f19ba23339fdb82ebc9a422a9cfc3dae39..40aa2226f5ada5c026695c9fea4b6fe701642d07 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ -ARG GITLAB_VERSION=v14.1.2-ubi8 +ARG GITLAB_VERSION=v14.2.0-ubi8 ARG BASE_REGISTRY=nexus-docker-secure.levelup-nexus.svc.cluster.local:18082 ARG BASE_IMAGE=gitlab/gitlab/gitlab-ruby -ARG BASE_TAG=14.1.2 +ARG BASE_TAG=14.2.0 ARG RUBY_IMAGE=${BASE_REGISTRY}/${BASE_IMAGE}:${BASE_TAG} diff --git a/README.md b/README.md index 5ddcab452fd95b1dade763356b35366882f9cd6f..cd4d8d50abf6d9e6198c33875887019466cf1027 100644 --- a/README.md +++ b/README.md @@ -37,5 +37,5 @@ Some of the GitLab containers are build ontop of previous containers, building t * gitaly - Phase 4 * gitlab-sidekiq - * gitlab-task-runner + * gitlab-toolbox * gitlab-webservice diff --git a/build-scripts/build.sh b/build-scripts/build.sh index c405acbe1d2fd6d20f16897365c0d34d3639b94e..6fe56cd51fb8e4edb9f3ab254a77dfee60f96cff 100755 --- a/build-scripts/build.sh +++ b/build-scripts/build.sh @@ -4,7 +4,7 @@ set -euxo pipefail -TAG=${1:-14.1.2} +TAG=${1:-14.2.0} REPOSITORY=${2:-} DOCKER_OPTS=${DOCKER_OPTS:-""} diff --git a/hardening_manifest.yaml b/hardening_manifest.yaml index af650dd6b38eec8a93ca19424a2dc0d62439ba5d..18d380035fac04b897440d01d37ed8e2f32e6eef 100644 --- a/hardening_manifest.yaml +++ b/hardening_manifest.yaml @@ -5,12 +5,12 @@ name: "gitlab/gitlab/gitlab-rails" # The most specific version should be the first tag and will be shown # on ironbank.dsop.io tags: - - "14.1.2" + - "14.2.0" - "latest" # Build args passed to Dockerfile ARGs args: BASE_IMAGE: "gitlab/gitlab/gitlab-ruby" - BASE_TAG: "14.1.2" + BASE_TAG: "14.2.0" # Docker image labels labels: org.opencontainers.image.title: "Gitlab Rails" @@ -22,7 +22,7 @@ labels: org.opencontainers.image.url: "https://about.gitlab.com/" ## Name of the distributing entity, organization or individual org.opencontainers.image.vendor: "Gitlab" - org.opencontainers.image.version: "14.1.2" + org.opencontainers.image.version: "14.2.0" ## Keywords to help with search (ex. "cicd,gitops,golang") mil.dso.ironbank.image.keywords: "gitlab, git, gitops" ## This value can be "opensource" or "commercial" @@ -43,8 +43,8 @@ maintainers: username: "alfontaine" email: "alan.fontaine@centauricorp.com" resources: - - url: "https://gitlab-ubi.s3.amazonaws.com/ubi8-build-dependencies-v14.1.2-ubi8/gitlab-rails-ee.tar.gz" + - url: "https://gitlab-ubi.s3.amazonaws.com/ubi8-build-dependencies-v14.2.0-ubi8/gitlab-rails-ee.tar.gz" filename: "gitlab-rails-ee.tar.gz" validation: type: "sha256" - value: "7d1de28f066928e21c7a8b0d8b81c81a6cd4837557a20dbdb047aa60b343490d" + value: "f91fb653191e4b80aa5512c7cc76a1195f24f5672ad2b045e18de56f85a9c26f" diff --git a/scripts/lib/checks/postgresql.rb b/scripts/lib/checks/postgresql.rb index eaf82960d0fafe205b72b7f37560b0355e97a4f9..784c8e18329e3dc59265333c36bd3fcd4e5a4ae5 100644 --- a/scripts/lib/checks/postgresql.rb +++ b/scripts/lib/checks/postgresql.rb @@ -14,7 +14,7 @@ module Checks counter = 1 passed = false until (counter == wait_for_timeout) || passed - passed = check_schema_version + passed = check_all_databases sleep sleep_duration unless passed counter += 1 end @@ -29,10 +29,6 @@ module Checks ENV['SLEEP_DURATION'].to_i end - def self.codebase_schema_version - ENV['SCHEMA_VERSION'].to_i - end - def self.config_directory ENV['CONFIG_DIRECTORY'] end @@ -41,43 +37,83 @@ module Checks ENV['DATABASE_FILE'] end - def self.config - return @@config if @@config + class DatabaseConfig + def initialize(shard_name) + @shard_name = shard_name + end - config = YAML.load_file(File.join(config_directory, database_file)) - @@config = config['production'] - end + def check_schema_version + ActiveRecord::Base.connected_to(shard: @shard_name, role: :writing) do + success = database_schema_version - def self.database_schema_version - ActiveRecord::Base.establish_connection(config) - begin - @@database_version = ActiveRecord::Migrator.current_version + puts "Database Schema - #{@shard_name} (#{ActiveRecord::Base.connection_db_config.database}) - current: #{@database_version}, codebase: #{codebase_schema_version}" - # Rails silently eats `ActiveRecord::NoDatabaseError` when calling `current_version` - # This stems from https://github.com/rails/rails/blob/v6.0.3.6/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L48-L54 - puts "WARNING: Problem accessing '#{config.database}' database. Confirm username, password, and permissions." if @@database_version.nil? + puts 'NOTICE: Database has not been initialized yet.' unless @database_version.to_i.positive? - # returning false prevents bailing when BYPASS_SCHEMA_VERSION set. - !@@database_version.nil? - rescue PG::ConnectionBad => e - puts "PostgreSQL Error: #{e.message}" - false - rescue RuntimeError => e - puts "Error: #{e.message}" + return true if (ENV['BYPASS_SCHEMA_VERSION'] && success) + + (success && @database_version.to_i >= codebase_schema_version) + end + rescue => e + puts "Error checking #{@shard_name}: #{e.message}" false end + + private + + def database_schema_version + begin + @database_version = ActiveRecord::Base.connection.migration_context.current_version + + # Rails silently eats `ActiveRecord::NoDatabaseError` when calling `current_version` + # This stems from https://github.com/rails/rails/blob/v6.0.3.6/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L48-L54 + puts "WARNING: Problem accessing #{@shard_name} database (#{ActiveRecord::Base.connection_db_config.database})."\ + " Confirm username, password, and permissions." if @database_version.nil? + + # returning false prevents bailing when BYPASS_SCHEMA_VERSION set. + !@database_version.nil? + rescue RuntimeError => e + puts "Error fetching #{@shard_name} schema: #{e.message}" + false + end + end + + def codebase_schema_version + # TODO: This may be suspect if there is a separate schema per shard + ENV['SCHEMA_VERSION'].to_i + end end - def self.check_schema_version - success = database_schema_version + def self.database_configurations + @@database_configurations ||= ActiveRecord::DatabaseConfigurations + .new(database_yaml) + end + + def self.database_yaml + @@database_yaml ||= ActiveSupport::ConfigurationFile.parse( + File.join(config_directory, database_file)) + end + + def self.check_all_databases + ActiveRecord::Base.legacy_connection_handling = false + ActiveRecord::Base.configurations = database_configurations + + production_databases = database_configurations.configs_for( + env_name: 'production', include_replicas: false) - puts "Database Schema - current: #{@@database_version}, codebase: #{codebase_schema_version}" + puts "Checking: #{production_databases.map(&:name).join(', ')}" - puts 'NOTICE: Database has not been initialized yet.' unless @@database_version.to_i.positive? + results = production_databases.map do |db_config| + ActiveRecord::Base.connection_handler.establish_connection( + db_config, role: :writing, shard: db_config.name) - return true if (ENV['BYPASS_SCHEMA_VERSION'] && success) + Thread.new do + DatabaseConfig.new(db_config.name).check_schema_version + end + end.map(&:value) - (success && @@database_version.to_i >= codebase_schema_version) + # Collect the checks that passed. + results.all? end end end