# frozen_string_literal: true require 'active_support/core_ext/object/blank' module Gitlab module QA module Runtime class OmnibusConfiguration def initialize @config = ["# Generated by GitLab QA Omnibus Configurator at #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"] end def to_s sanitize!.join("\n") end def configuration raise NotImplementedError end # Before hook for any additional configuration # This would usually be a container that needs to be running # @return Any instance of [Gitlab::QA::Component::Base] def prepare; end # Commands to execute before GitLab boots def exec_commands [] end # Ensures no duplicate entries # @raise RuntimeError if competing configurations exist # rubocop:disable Metrics/AbcSize def sanitize! sanitized = @config.map do |config| next config if config.start_with?('#') || config.match(/\w+\(/) # allow for comments and method invocations # sometimes "=" is part of a Hash. Only split based on the first "=" k, v = config.split("=", 2) # make sure each config is well-formed # e.g., gitlab_rails['packages_enabled'] = true # NOT gitlab_rails['packages_enabled']=true v.nil? ? k.strip : "#{k.strip} = #{v.strip.tr('"', "'")}".strip end.uniq errors = [] # check for duplicates duplicate_keys = [] duplicates = sanitized.reject do |n| key = n.split('=').first duplicate_keys << key unless duplicate_keys.include?(key) end duplicates.each { |duplicate| errors << "Duplicate entry found: `#{duplicate}`" } raise "Errors exist within the Omnibus Configuration!\n#{errors.join(',')}" if errors.any? @config = sanitized end # rubocop:enable Metrics/AbcSize def <<(config) @config << config.strip unless config.strip.empty? end end end end end