# frozen_string_literal: true module License module Management class Shell SPLIT_SCRIPT = "'BEGIN {x=0;} /BEGIN CERT/{x++} { print > \"custom.\" x \".crt\" }'" COMMAND_MAP = { asdf: '/opt/asdf/bin/asdf', bundle: '/opt/asdf/bin/asdf exec bundle', cargo: '/opt/asdf/bin/asdf exec cargo', cert_sync: '/opt/asdf/installs/mono/6.8.0.123/bin/cert-sync', embedded_bundle: '/opt/gitlab/embedded/bin/bundle', gradle: '/opt/asdf/bin/asdf exec gradle', gem: '/opt/asdf/bin/asdf exec gem', go: '/opt/asdf/bin/asdf exec go', keytool: '/opt/asdf/bin/asdf exec keytool', mono: '/opt/asdf/installs/mono/6.8.0.123/bin/mono', mvn: '/opt/asdf/bin/asdf exec mvn', nuget: '/opt/asdf/installs/mono/6.8.0.123/bin/nuget.exe', ruby: '/opt/asdf/bin/asdf exec ruby', yarn: '/opt/asdf/bin/asdf exec yarn' }.freeze attr_reader :default_env, :default_certificate_path, :custom_certificate_path, :logger def initialize(logger: License::Management.logger, certificate: ENV['ADDITIONAL_CA_CERT_BUNDLE']) @logger = logger @custom_certificate_path = Pathname.new('/usr/local/share/ca-certificates/custom.crt') @default_certificate_path = Pathname.new('/etc/ssl/certs/ca-certificates.crt') @default_env = { 'SSL_CERT_FILE' => @default_certificate_path.to_s } trust!(certificate) if present?(certificate) end def execute(command, env: {}) expanded_command = expand(command) collapsible_section(expanded_command) do logger.debug(expanded_command) stdout, stderr, status = Open3.capture3(default_env.merge(env), expanded_command) record(stdout, stderr, status) [stdout, stderr, status] end end def sh(command, env: {}) execute("sh -c '#{expand(command)}'", env: env) end def custom_certificate_installed? present?(ENV['ADDITIONAL_CA_CERT_BUNDLE']) && custom_certificate_path.exist? end private def expand(command) Array(command) .flatten .map { |x| COMMAND_MAP.fetch(x, x).to_s } .join(' ') end def trust!(certificate) custom_certificate_path.write(certificate) Dir.chdir custom_certificate_path.dirname do execute([:awk, SPLIT_SCRIPT, '<', custom_certificate_path]) execute('update-ca-certificates -v') Dir.glob('custom.*.crt').each do |path| execute([:openssl, :x509, '-in', File.expand_path(path), '-text', '-noout']) end end execute([:cp, custom_certificate_path.to_s, "/usr/lib/ssl/certs/"]) execute([:c_rehash, '-v']) end def present?(item) !item.nil? && !item.empty? end def record(stdout, stderr, status) severity = status.success? ? Logger::DEBUG : Logger::ERROR flush(stdout, severity) flush(stderr, severity) end def flush(message, severity) logger.add(severity, message) if present?(message) end def collapsible_section(header) id = header.downcase.gsub(/[[:space:]]/, '_').gsub(/[^0-9a-z ]/i, '_') logger.debug("\nsection_start:#{Time.now.to_i}:#{id}\r\e[0K#{header}") yield ensure logger.debug("\nsection_end:#{Time.now.to_i}:#{id}\r\e[0K") end end end end