class OctoLab

Constants

GITHUB_SECRET
GITHUB_TOKEN
GITLAB_CI_URL
GITLAB_TOKEN
GIT_DATA_PATH
LOG_DIR_PATH
LOG_GIT_AGE
LOG_GIT_SIZE
LOG_WEB_AGE
LOG_WEB_SIZE
PROCESS_GID
PROCESS_UID
ROOT_DIR

Public Instance Methods

get_project(name) click to toggle source
# File lib/octolab.rb, line 188
def get_project(name)
  begin
    url           = GITLAB_CI_URL + '/api/v3/projects'
    uri           = URI(url)
    http          = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl  = true
    headers       = { 'PRIVATE-TOKEN' => GITLAB_TOKEN }
    path          = uri.path.empty? ? '/' : uri.path
    code          = http.head(path, headers).code.to_i

    if (code >= 200 && code < 300)
      response = http.get(uri.path, headers)
      JSON.parse(response.body).select { |i| i['path_with_namespace'] == name }.first
    else
      raise HTTPError, 'Error code: ' + code.to_s + ' URL: ' + url
    end
  rescue
    raise $!
  end
end
get_trigger_token(id) click to toggle source
# File lib/octolab.rb, line 209
def get_trigger_token(id)
  begin
    uri           = URI(GITLAB_CI_URL + '/api/v3/projects/' + id.to_s + '/triggers')
    http          = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl  = true
    headers       = { 'PRIVATE-TOKEN' => GITLAB_TOKEN }
    path          = uri.path.empty? ? '/' : uri.path
    code          = http.head(path, headers).code.to_i

    if (code >= 200 && code < 300)
      response = http.get(uri.path, headers)
      res = JSON.parse(response.body).select { |i| i['deleted_at'] == nil }.first
      if res == nil
        raise HTTPError, 'Unable to obtain build trigger token for project id: ' + id.to_s
      end
      res
    else
      raise HTTPError, 'Error code: ' + code.to_s + ' URL: ' + url
    end
  rescue
    raise $!
  end
end
git_fetch_github(full_name) click to toggle source
# File lib/octolab.rb, line 171
def git_fetch_github(full_name)
  $log_app.info '[*] Fetching: ' + full_name

  Git.configure do |config|
    config.git_ssh = ROOT_DIR + '/helpers/ssh'
  end

  git_dir = GIT_DATA_PATH + '/' + full_name + '.git'
  git = Git.open(git_dir, { :log => $log_git, :repository => git_dir, :working_directory => nil })
  
  if git.remotes.length == 0
    git.add_remote('github', 'git@github.com:' + full_name + '.git', :mirror => true)
  end
  
  git.remote('github').fetch
end
logger() click to toggle source
# File lib/octolab.rb, line 162
def logger
  request.logger
end
process_pull_request(pull_request) click to toggle source
# File lib/octolab.rb, line 253
def process_pull_request(pull_request)
  Thread.new do
    begin
      remote_name   = pull_request['base']['repo']['full_name']
      commit        = pull_request['head']['sha']
      ref           = pull_request['head']['ref']
      build_status  = 'pending'
      description   = 'The build is in progress...'
      options       = {
                      :state        => build_status,
                      :description  => description,
                      :context      => 'continuous-integration/gitlab'
                    }

      $log_app.info '[*] Processing pull request: ' + remote_name + ': ' + commit
      @client.create_status(remote_name, commit, build_status, options)
      trigger_build(remote_name, ref)
    rescue Octokit::Unauthorized
      $log_app.error '[!] ' + $!.message
    rescue HTTPError
      $log_app.error $!
    rescue TriggerError
      $log_app.error $!
    rescue
      $log_app.error '[!] Unable to process request for: ' + remote_name + ' ref: ' + ref
      $log_app.internal($!)
    ensure
      build_status  = 'failure'
      description   = 'The build has failed!'
      options       = {
                      :state        => build_status,
                      :description  => description,
                      :context      => 'continuous-integration/gitlab'
                    }

      @client.create_status(remote_name, commit, build_status, options)
    end
  end
end
process_push(payload) click to toggle source
# File lib/octolab.rb, line 293
def process_push(payload)
  Thread.new do
    begin
      remote_name   = payload['repository']['full_name']
      ref           = payload['ref'].split("/").last
      
      trigger_build(remote_name, ref)
    rescue HTTPError
      $log_app.error $!
    rescue TriggerError
      $log_app.error $!
    rescue
      $log_app.error '[!] Unable to process request for: ' + remote_name + ' ref: ' + ref
      $log_app.internal($!)
    end
  end
end
trigger_build(remote_name, ref) click to toggle source
# File lib/octolab.rb, line 233
def trigger_build(remote_name, ref)
  begin
    project       = get_project(remote_name)
    token         = get_trigger_token(project['id'])['token']
    url           = GITLAB_CI_URL + '/api/v3/projects/' + project['id'].to_s + '/trigger/builds'
    uri           = URI(url)
    response      = Net::HTTP.post_form(uri, 'token' => token, 'ref' => ref)
    
    if (response.code.to_i >= 200 && response.code.to_i < 300)
      JSON.parse(response.body)
    elsif response.code.to_i == 400
      raise TriggerError, JSON.parse(response.body)['message']
    else
      raise HTTPError, 'Error code: ' + response.code.to_s + ' URL: ' + url
    end
  rescue
    raise $!
  end
end
verify_signature(body) click to toggle source
# File lib/octolab.rb, line 166
def verify_signature(body)
  signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), GITHUB_SECRET, body)
  return halt 500, { :error => "Signatures didn't match!" }.to_json unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE'])
end