lib/gitlab/qa/component/runner_ops.rb (96 lines of code) (raw):
# frozen_string_literal: true
module Gitlab
module QA
module Component
class RunnerOps < Base
include Support::Shellout
RUNNER_DESCRIPTION = "QA Runner"
DOCKER_IMAGE = "registry.gitlab.com/gitlab-org/gitlab-runner:alpine"
BUILD_IMAGE = "registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.7"
def setup_runner(gitlab)
token = SecureRandom.hex(15)
add_runner_to_gitlab(gitlab, token)
register_docker_runner(gitlab, token)
end
private
def add_runner_to_gitlab(gitlab, token)
gitlab.docker.exec(
gitlab.name,
create_runner_command(token),
mask_secrets: token
)
end
def create_runner_command(token)
<<~RUBY.strip.gsub(/\s+/, ' ')
gitlab-rails runner '
Ci::Runner.create!(
description: "#{RUNNER_DESCRIPTION}",
run_untagged: true,
active: true,
token: "#{token}",
runner_type: :instance_type
);
puts "Runner created"
'
RUBY
end
def register_docker_runner(gitlab, token)
runner_name = generate_runner_name
docker_command = build_docker_command(
runner_name: runner_name,
network: gitlab.network,
address: gitlab.address,
token: token
)
shell(docker_command, mask_secrets: [token])
end
def generate_runner_name
"test-runner-#{SecureRandom.hex(4)}"
end
def build_docker_command(runner_name:, network:, address:, token:)
<<~CMD.tr("\n", ' ')
docker run -d --rm --network #{network} --name #{runner_name}
-v /var/run/docker.sock:/var/run/docker.sock
--privileged
#{DOCKER_IMAGE}
&& docker exec --detach #{runner_name} sh -c "#{register_command(runner_name, address, token, network)}"
CMD
end
def runner_config
<<~CONFIG
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
CONFIG
end
def register_command(name, address, token, network)
registration_args = build_registration_args(
name: name,
address: address,
token: token,
network: network
)
<<~CMD.strip
printf '#{runner_config.chomp.gsub(/\n/, '\\n').gsub('"', '\"')}' > /etc/gitlab-runner/config.toml &&
gitlab-runner register #{registration_args} &&
gitlab-runner run
CMD
end
def build_registration_args(name:, address:, token:, network:)
[
'--non-interactive',
"--name #{name}",
"--url #{address}",
"--token #{token}",
'--run-untagged=true',
'--executor docker',
"--docker-image #{BUILD_IMAGE}",
'--docker-tlsverify=false',
'--docker-privileged=true',
"--docker-network-mode=#{network}",
'--docker-volumes=/certs/client'
].join(' ')
end
end
end
end
end