Merge pull request #745 from warpc/735-package-build-server

[refs #735]: package build server
This commit is contained in:
Vladimir Sharshov 2012-12-03 04:15:19 -08:00
commit 2fcc5ac6d7
12 changed files with 202 additions and 66 deletions

View File

@ -55,12 +55,16 @@ class Projects::BuildListsController < Projects::BaseController
build_for_platforms = Repository.select(:platform_id).
where(:id => params[:build_list][:include_repos]).group(:platform_id).map(&:platform_id)
new_core = current_user.admin? && params[:build_list][:new_core] == '1'
params[:build_list][:auto_publish] = false if new_core
Arch.where(:id => params[:arches]).each do |arch|
Platform.main.where(:id => build_for_platforms).each do |build_for_platform|
@build_list = @project.build_lists.build(params[:build_list])
@build_list.build_for_platform = build_for_platform; @build_list.arch = arch; @build_list.user = current_user
@build_list.include_repos = @build_list.include_repos.select {|ir| @build_list.build_for_platform.repository_ids.include? ir.to_i}
@build_list.priority = current_user.build_priority # User builds more priority than mass rebuild with zero priority
@build_list.new_core = new_core
flash_options = {:project_version => @build_list.project_version, :arch => arch.name, :build_for_platform => build_for_platform.name}
if @build_list.save
notices << t("flash.build_list.saved", flash_options)
@ -104,12 +108,10 @@ class Projects::BuildListsController < Projects::BaseController
end
def log
@log = `tail -n #{params[:load_lines].to_i} #{Rails.root + 'public' + @build_list.fs_log_path}`
@log = t("layout.build_lists.log.not_available") unless $?.success?
respond_to do |format|
format.json { render :json => { :log => @log, :building => @build_list.build_started? } }
end
render :json => {
:log => @build_list.log(params[:load_lines]),
:building => @build_list.build_started?
}
end
def publish_build

View File

@ -112,6 +112,7 @@ class BuildList < ActiveRecord::Base
serialize :additional_repos
serialize :include_repos
serialize :results, Array
after_commit :place_build
after_destroy :delete_container
@ -241,10 +242,88 @@ class BuildList < ActiveRecord::Base
can_publish? and not save_to_repository.publish_without_qa
end
def add_to_abf_worker_queue
include_repos_hash = {}.tap do |h|
include_repos.each do |r|
repo = Repository.find r
path = repo.platform.public_downloads_url(nil, arch.name, repo.name)
# path = path.gsub(/^http:\/\/0\.0\.0\.0\:3000/, 'https://abf.rosalinux.ru')
# Path looks like:
# http://abf.rosalinux.ru/downloads/rosa-server2012/repository/x86_64/base/
# so, we should append:
# /release
# /updates
h["#{repo.name}_release"] = path + 'release'
h["#{repo.name}_updates"] = path + 'updates'
end
end
# mdv example:
# https://abf.rosalinux.ru/import/plasma-applet-stackfolder.git
# bfe6d68cc607238011a6108014bdcfe86c69456a
# rhel example:
# https://abf.rosalinux.ru/server/gnome-settings-daemon.git
# fbb2549e44d97226fea6748a4f95d1d82ffb8726
options = {
:id => id,
:arch => arch.name,
:time_living => 2880, # 2 days
:distrib_type => build_for_platform.distrib_type,
# :git_project_address => 'https://abf.rosalinux.ru/server/gnome-settings-daemon.git',
:git_project_address => project.git_project_address,
# :commit_hash => 'fbb2549e44d97226fea6748a4f95d1d82ffb8726',
:commit_hash => commit_hash,
:build_requires => build_requires,
:include_repos => include_repos_hash,
:bplname => build_for_platform.name
# :project_version => project_version,
# :plname => save_to_platform.name,
# :bplname => (save_to_platform_id == build_for_platform_id ? '' : build_for_platform.name),
# :update_type => update_type,
# :priority => priority,
}
unless @status
Resque.push(
'rpm_worker',
'class' => 'AbfWorker::RpmWorker',
'args' => [options]
)
end
@status ||= BUILD_PENDING
end
def add_to_queue
#XML-RPC params: project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web, include_repos, priority, git_project_address
@status ||= BuildServer.add_build_list project.name, project_version, save_to_platform.name, arch.name, (save_to_platform_id == build_for_platform_id ? '' : build_for_platform.name), update_type, build_requires, id, include_repos, priority, project.git_project_address
if new_core?
add_to_abf_worker_queue
else
# XML-RPC params:
# - project_name
# - project_version
# - plname
# - arch
# - bplname
# - update_type
# - build_requires
# - id_web
# - include_repos
# - priority
# - git_project_address
@status ||= BuildServer.add_build_list(
project.name,
project_version,
save_to_platform.name,
arch.name,
(save_to_platform_id == build_for_platform_id ? '' : build_for_platform.name),
update_type,
build_requires,
id,
include_repos,
priority,
project.git_project_address
)
end
@status
end
def self.human_status(status)
@ -311,7 +390,17 @@ class BuildList < ActiveRecord::Base
!save_to_repository.publish_without_qa &&
save_to_platform.main? &&
save_to_platform.released &&
status == BUILD_PUBLISHED
build_published?
end
def log(load_lines)
if new_core?
log = Resque.redis.get("abfworker::rpm-worker-#{id}")
else
log = `tail -n #{load_lines.to_i} #{Rails.root + 'public' + fs_log_path}`
log = nil unless $?.success?
end
log || I18n.t('layout.build_lists.log.not_available')
end
protected

View File

@ -0,0 +1,18 @@
%h3= t("layout.product_build_lists.results")
- unless pbl.results.present?
%h4.nomargin= t("layout.product_build_lists.no_results")
- else
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
%thead
%tr
%th= t("activerecord.attributes.product_build_list/results.file_name")
%th= t("activerecord.attributes.product_build_list/results.sha1")
%th= t("activerecord.attributes.product_build_list/results.size")
%tbody
- pbl.results.each do |item|
%tr
- sha1 = item['sha1']
%td= link_to item['file_name'], "http://file-store.rosalinux.ru/api/v1/file_stores/#{sha1}"
%td= sha1
%td= item['size']
.both

View File

@ -30,25 +30,7 @@
.both
= render 'shared/log', { :build_started => true, :get_log_path => log_platform_product_product_build_list_path(pbl.product.platform, pbl.product, pbl) }
%h3= t("layout.product_build_lists.results")
- unless pbl.results.present?
%h4.nomargin= t("layout.product_build_lists.no_results")
- else
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
%thead
%tr
%th= t("activerecord.attributes.product_build_list/results.file_name")
%th= t("activerecord.attributes.product_build_list/results.sha1")
%th= t("activerecord.attributes.product_build_list/results.size")
%tbody
- pbl.results.each do |item|
%tr
- sha1 = item['sha1']
%td= link_to item['file_name'], "http://file-store.rosalinux.ru/api/v1/file_stores/#{sha1}"
%td= sha1
%td= item['size']
.both
= render 'results', :pbl => pbl
:javascript
$(function(){

View File

@ -29,6 +29,10 @@
.both
= f.check_box :build_requires
= f.label :build_requires
- if current_user.admin?
.both
= f.check_box :new_core
= f.label :new_core
%br
= f.submit t("layout.projects.build_button")

View File

@ -59,6 +59,9 @@
.leftlist= t("activerecord.attributes.build_list.is_circle")
.rightlist= t("layout.#{@build_list.is_circle?}_")
.both
.leftlist= t("activerecord.attributes.build_list.new_core")
.rightlist= t("layout.#{@build_list.new_core?}_")
.both
- if @build_list.mass_build_id.present?
.leftlist= t("activerecord.attributes.mass_build_id")
@ -125,53 +128,56 @@
});
- if BuildList::HUMAN_STATUSES[@build_list.status].in? [:build_started, :build_error, :success]
= render 'shared/log', { :build_started => @build_list.build_started?, :download_log_url => build_list_log_url(:build), :get_log_path => log_build_list_path(@build_list) }
- log_params = { :build_started => @build_list.build_started?, :get_log_path => log_build_list_path(@build_list) }
= render 'shared/log', ( @build_list.new_core? ? log_params : log_params.merge({:download_log_url => build_list_log_url(:build)}) )
- if (can_publish = @build_list.can_publish? && can?(:publish, @build_list))
- if (can_publish = @build_list.can_publish? && can?(:publish, @build_list) && !@build_list.new_core?)
.hr
= submit_tag t("layout.publish"), :confirm => t("layout.confirm"), :name => 'publish' if can_publish
- if @build_list.can_reject_publish? && can?(:reject_publish, @build_list)
= submit_tag t("layout.reject_publish"), :confirm => t("layout.confirm"), :name => 'reject_publish'
.hr
%h3= t("layout.build_lists.items_header")
- if @item_groups.blank?
%h4.nomargin= t("layout.build_lists.no_items_data")
- @item_groups.each_with_index do |group, level|
- group.each do |item|
%h4.nomargin= "#{item.name} ##{level}"
- if @build_list.new_core?
= render 'platforms/product_build_lists/results', :pbl => @build_list
- else
%h3= t("layout.build_lists.items_header")
- if @item_groups.blank?
%h4.nomargin= t("layout.build_lists.no_items_data")
- @item_groups.each_with_index do |group, level|
- group.each do |item|
%h4.nomargin= "#{item.name} ##{level}"
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
%thead
%tr
%th= t("activerecord.attributes.build_list/item.name")
%th= t("activerecord.attributes.build_list/item.version")
%th= t("activerecord.attributes.build_list/item.status")
%tbody
%tr{:class => build_list_item_status_color(item.status)}
%td= item.name
%td= item.version
%td= item.human_status
.both
- if @build_list.packages.present?
.hr
%h3= t("layout.build_lists.packages_header")
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
%thead
%tr
%th= t("activerecord.attributes.build_list/item.name")
%th= t("activerecord.attributes.build_list/item.version")
%th= t("activerecord.attributes.build_list/item.status")
%th= t("activerecord.attributes.build_list/package.fullname")
%th= t("activerecord.attributes.build_list/package.name")
%th= t("activerecord.attributes.build_list/package.version")
%th= t("activerecord.attributes.build_list/package.release")
%tbody
%tr{:class => build_list_item_status_color(item.status)}
%td= item.name
%td= item.version
%td= item.human_status
.both
- if @build_list.packages.present?
.hr
%h3= t("layout.build_lists.packages_header")
%table.tablesorter.width565{:cellpadding => "0", :cellspacing => "0"}
%thead
%tr
%th= t("activerecord.attributes.build_list/package.fullname")
%th= t("activerecord.attributes.build_list/package.name")
%th= t("activerecord.attributes.build_list/package.version")
%th= t("activerecord.attributes.build_list/package.release")
%tbody
- @build_list.packages.each do |package|
%tr
%td= package.fullname
%td= package.name
%td= package.version
%td= package.release
.both
- @build_list.packages.each do |package|
%tr
%td= package.fullname
%td= package.name
%td= package.version
%td= package.release
.both
:javascript
$('article .all').addClass('bigpadding');

View File

@ -13,6 +13,7 @@ en:
project: Project
arch_id: Architecture
arch: Architecture
new_core: New core
is_circle: Recurrent build
updated_at: Notified at
additional_repos: Additional repositories

View File

@ -13,6 +13,7 @@ ru:
project: Проект
arch_id: Архитектура
arch: Архитектура
new_core: Новое ядро
is_circle: Циклическая сборка
updated_at: Информация получена
additional_repos: Дополнительные репозитории

View File

@ -0,0 +1,6 @@
class AddResultsToBuildList < ActiveRecord::Migration
def change
add_column :build_lists, :results, :text
add_column :build_lists, :new_core, :boolean
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20121106113338) do
ActiveRecord::Schema.define(:version => 20121127122032) do
create_table "activity_feeds", :force => true do |t|
t.integer "user_id", :null => false
@ -130,6 +130,8 @@ ActiveRecord::Schema.define(:version => 20121106113338) do
t.integer "advisory_id"
t.integer "mass_build_id"
t.integer "save_to_repository_id"
t.text "results"
t.boolean "new_core"
end
add_index "build_lists", ["advisory_id"], :name => "index_build_lists_on_advisory_id"

View File

@ -0,0 +1,25 @@
module AbfWorker
class RpmWorkerObserver
@queue = :rpm_worker_observer
def self.perform(options)
bl = BuildList.find options['id']
status = options['status'].to_i
case status
when 0
bl.build_success
when 1
bl.build_error
when 3
bl.bs_id = bl.id
bl.save
bl.start_build
end
if status != 3
bl.results = options['results']
bl.save
end
end
end
end

View File

@ -26,7 +26,7 @@ Capistrano::Configuration.instance(:must_exist).load do
end
def start_workers
run "cd #{fetch :current_path} && COUNT=#{workers_count} QUEUE=fork_import,hook,clone_build,notification,iso_worker_observer #{rails_env} BACKGROUND=yes bundle exec rake resque:workers"
run "cd #{fetch :current_path} && COUNT=#{workers_count} QUEUE=fork_import,hook,clone_build,notification,iso_worker_observer,rpm_worker_observer #{rails_env} BACKGROUND=yes bundle exec rake resque:workers"
end
end
end