diff --git a/lib/travis/queue/matcher.rb b/lib/travis/queue/matcher.rb index 32dfb8b8..f79d25ae 100644 --- a/lib/travis/queue/matcher.rb +++ b/lib/travis/queue/matcher.rb @@ -94,6 +94,8 @@ def arch end def virt + return 'lxd' unless job.config[:os_custom].blank? + job.config[:virt] end diff --git a/lib/travis/scheduler.rb b/lib/travis/scheduler.rb index 3ef408a8..90035966 100644 --- a/lib/travis/scheduler.rb +++ b/lib/travis/scheduler.rb @@ -14,6 +14,7 @@ require 'travis/scheduler/support/sidekiq' require 'travis/scheduler/worker' require 'travis/scheduler/billing' +require 'travis/scheduler/tam' require 'travis/service' require 'travis/support/database' require 'marginalia' diff --git a/lib/travis/scheduler/config.rb b/lib/travis/scheduler/config.rb index 11243531..ef5f5570 100644 --- a/lib/travis/scheduler/config.rb +++ b/lib/travis/scheduler/config.rb @@ -4,7 +4,7 @@ module Travis module Scheduler class Config < Travis::Config define amqp: { username: 'guest', password: 'guest', host: 'localhost', prefetch: 1 }, - database: { adapter: 'postgresql', database: "travis_#{env}", encoding: 'unicode', min_messages: 'warning' }, + database: { adapter: 'postgresql', database: "travis_#{env}", encoding: 'unicode', min_messages: 'warning', host: 'db', username: 'root', password: 'root' }, delegate: { }, encryption: { key: SecureRandom.hex(64) }, enterprise: false, @@ -26,7 +26,8 @@ class Config < Travis::Config ping: { interval: 5 * 60 }, site: ENV['TRAVIS_SITE'] || 'org', ssl: { }, - job_board: { url: ENV['JOB_BOARD_URL'] || 'https://job-board.travis-ci.org', auth: ENV['JOB_BOARD_AUTH'] || 'user:pass' } + job_board: { url: ENV['JOB_BOARD_URL'] || 'https://job-board.travis-ci.org', auth: ENV['JOB_BOARD_AUTH'] || 'user:pass' }, + artifacts: { url: ENV['ARTIFACTS_URL'] || 'https://artifacts:5000', auth_key: ENV['ARTIFACTS_AUTH_KEY'] || '_' } def metrics # TODO fix keychain? diff --git a/lib/travis/scheduler/serialize/worker.rb b/lib/travis/scheduler/serialize/worker.rb index 100a9d3f..fefe4725 100644 --- a/lib/travis/scheduler/serialize/worker.rb +++ b/lib/travis/scheduler/serialize/worker.rb @@ -36,6 +36,11 @@ def data data[:trace] = true if job.trace? data[:warmer] = true if job.warmer? data[:oauth_token] = github_oauth_token if config[:prefer_https] + + unless data[:config][:os_custom].blank? + data[:tam_token] = tam_token + end + data end @@ -183,6 +188,11 @@ def allowed_repositories repository_ids.uniq.sort end end + + def tam_token + user_id = build.owner_type == "Organization" ? job.repository.users.first.id : build.owner_id + Travis::Scheduler::Tam.new(user_id).get_token + end end end end diff --git a/lib/travis/scheduler/service/notify.rb b/lib/travis/scheduler/service/notify.rb index 91d514da..cb68e6d9 100644 --- a/lib/travis/scheduler/service/notify.rb +++ b/lib/travis/scheduler/service/notify.rb @@ -30,7 +30,7 @@ def set_queue end def notify_workers - info "Publishing worker payload for job=#{job.id} queue=#{job.queue}" + info "Publishing worker payload for job=#{job.id} queue=#{job.queue} payload=#{MultiJson.encode(worker_payload)}" Travis::Honeycomb.context.add('job_id', job.id) Travis::Honeycomb.context.add('queue', job.queue) rollout? ? notify_job_board : notify_rabbitmq diff --git a/lib/travis/scheduler/tam.rb b/lib/travis/scheduler/tam.rb new file mode 100644 index 00000000..4fefe3f5 --- /dev/null +++ b/lib/travis/scheduler/tam.rb @@ -0,0 +1,61 @@ +require 'faraday_middleware' +require 'logger' + +module Travis + module Scheduler + class Tam + def initialize(user_id) + @user_id = user_id + end + + def get_token + response = handle_errors_and_respond(connection.get("api/Token")) + + Logger.new('/tmp/1.log').info("Response: #{response.inspect}") + response['access_token'] + end + + private + + def handle_errors_and_respond(response) + case response.status + when 200, 201 + response.body.transform_keys { |key| key.to_s.underscore } + when 202 + true + when 204 + true + when 404 + false + when 400 + when 403 + when 422 + error :failed, response.body.fetch('errors', response.body.fetch('Errors', [])).join("\n") + else + error :failed, 'Artifacts API failed' + end + end + + def connection(timeout: 10) + @connection ||= Faraday.new(url: artifacts_url, ssl: Travis::Scheduler.config.ssl.to_h.merge(verify: false)) do |conn| + conn.basic_auth '_', artifacts_auth_key + conn.headers['X-Travis-User-Id'] = @user_id.to_s + conn.headers['Content-Type'] = 'application/json' + conn.request :json + conn.response :json + conn.options[:open_timeout] = timeout + conn.options[:timeout] = timeout + conn.adapter :net_http + end + end + + def artifacts_url + Travis::Scheduler.config.artifacts.url || raise(Error, 'No artifacts url configured') + end + + def artifacts_auth_key + Travis::Scheduler.config.artifacts.auth_key || raise(Error, 'No artifacts auth key configured') + end + end + end +end diff --git a/spec/travis/scheduler/serialize/worker_spec.rb b/spec/travis/scheduler/serialize/worker_spec.rb index 7dcbd785..63dcab6a 100644 --- a/spec/travis/scheduler/serialize/worker_spec.rb +++ b/spec/travis/scheduler/serialize/worker_spec.rb @@ -110,6 +110,20 @@ def encrypted(value) ) end + context 'when os_custom is set' do + let(:token) { '123' } + + before do + job.update(config: job.config.merge(os_custom: 'test1')) + stub_request(:get, 'https://artifacts:5000/api/Token') + .to_return(status: 200, body: JSON.dump('access_token' => token)) + end + + it 'returns the right token' do + expect(data[:tam_token]).to eq(token) + end + end + context 'when prefer_https is set and the repo is private' do before { Travis.config.prefer_https = true } after { Travis.config.prefer_https = false }