require'securerandom'require'net/http'require'uri'require'forwardable'require'openssl'moduleGitlabmoduleQAmoduleComponentclassGitlabextendForwardableincludeScenario::Actableattr_reader:release,:dockerattr_accessor:volumes,:network,:environment,:tlsattr_writer:name,:relative_path,:exec_commandsdef_delegators:release,:tag,:image,:editionCERTIFICATES_PATH=File.expand_path('../../../../tls_certificates/gitlab'.freeze,__dir__)SSL_PATH='/etc/gitlab/ssl'.freezedefinitialize@docker=Docker::Engine.new@environment={}@volumes={}@network_aliases=[]@volumes[CERTIFICATES_PATH]=SSL_PATHself.release='CE'self.exec_commands=[]enddefomnibus_config=(config)@environment['GITLAB_OMNIBUS_CONFIG']=config.tr("\n",' ')enddefadd_network_alias(name)@network_aliases.push(name)enddefrelease=(release)@release=Release.new(release)enddefname@name||="gitlab-#{edition}-#{SecureRandom.hex(4)}"enddefaddress"#{scheme}://#{hostname}#{relative_path}"enddefschemetls?'https':'http'enddefporttls?'443':'80'enddefhostname"#{name}.#{network}"enddefrelative_path@relative_path||=''enddefinstancepreparestartreconfigurewaitprocess_exec_commandsyieldselfifblock_given?ensureteardownendalias_method:launch_and_teardown_instance,:instancedefprepare@docker.pull(image,tag)unlessRuntime::Env.skip_pull?returnif@docker.network_exists?(network)@docker.network_create(network)enddefstart# rubocop:disable Metrics/AbcSizeensure_configured!docker.run(image,tag)do|command|command<<"-d -p #{port}"command<<"--name #{name}"command<<"--net #{network}"command<<"--hostname #{hostname}"@volumes.to_h.eachdo|to,from|command.volume(to,from,'Z')endcommand.volume(File.join(Runtime::Env.host_artifacts_dir,name,'logs'),'/var/log/gitlab','Z')@environment.to_h.eachdo|key,value|command.env(key,value)end@network_aliases.to_a.eachdo|network_alias|command<<"--network-alias #{network_alias}"endendenddefreconfigure@docker.attach(name)do|line,wait|putsline# TODO, workaround which allows to detach from the container#Process.kill('INT',wait.pid)ifline=~/gitlab Reconfigured!/endenddefrestart@docker.restart(name)enddefteardownraise'Invalid instance name!'unlessname@docker.stop(name)@docker.remove(name)enddefwaitifAvailability.new(name,relative_path: relative_path,scheme: scheme,protocol_port: port.to_i).check(180)sleep12# TODO, handle that betterputs' -> GitLab is available.'elseabort' -> GitLab unavailable!'endenddefpull@docker.pull(@release.image,@release.tag)enddefsha_versionjson=@docker.read_file(@release.image,@release.tag,'/opt/gitlab/version-manifest.json')manifest=JSON.parse(json)manifest['software']['gitlab-rails']['locked_version']enddefprocess_exec_commandsexec_commands.each{|command|@docker.exec(name,command)}endprivateattr_reader:exec_commandsdefensure_configured!raise'Please configure an instance first!'unless[name,release,network].all?endclassAvailabilitydefinitialize(name,relative_path: '',scheme: 'http',protocol_port: 80)@docker=Docker::Engine.newhost=@docker.hostnameport=@docker.port(name,protocol_port).split(':').last@uri=URI.join("#{scheme}://#{host}:#{port}","#{relative_path}/",'help')enddefcheck(retries)print"Waiting for GitLab at `#{@uri}` to become available "retries.timesdoreturntrueifservice_available?print'.'sleep1endfalseendprivatedefservice_available?response=Net::HTTP.start(@uri.host,@uri.port,opts)do|http|http.head2(@uri.request_uri)endresponse.code.to_i==200rescueErrno::ECONNREFUSED,Errno::ECONNRESET,EOFErrorfalseenddefopts@uri.scheme=='https'?{use_ssl: true,verify_mode: OpenSSL::SSL::VERIFY_NONE}:{}endendendendendend