Move project build functinality to build_lists controller. Refactor downloads url - create model based methods for url genertion. Cleanup code. Add includeed_repos functionality. Display included_repos on build_list page. Refs #65

This commit is contained in:
Pavel Chipiga 2011-12-21 16:01:50 +02:00
parent f1206a4abd
commit d901426b79
19 changed files with 163 additions and 162 deletions

View File

@ -4,7 +4,7 @@ class ApplicationController < ActionController::Base
layout :layout_by_resource
before_filter lambda { EventLog.current_controller = self },
:only => [:create, :destroy, :open_id, :auto_build, :process_build, :cancel, :publish, :change_visibility] # :update
:only => [:create, :destroy, :open_id, :auto_build, :cancel, :publish, :change_visibility] # :update
after_filter lambda { EventLog.current_controller = nil }
helper_method :get_owner

View File

@ -3,11 +3,13 @@ class BuildListsController < ApplicationController
before_filter :authenticate_user!, :except => CALLBACK_ACTIONS
before_filter :authenticate_build_service!, :only => CALLBACK_ACTIONS
before_filter :find_project, :only => [:index, :filter, :show, :publish]
before_filter :find_project, :only => [:index, :filter, :show, :publish, :new, :create]
before_filter :find_arches, :only => [:index, :filter, :all]
before_filter :find_project_versions, :only => [:index, :filter]
before_filter :find_build_list_by_bs, :only => [:status_build, :pre_build, :post_build]
# load_and_authorize_resource :project, :except => CALLBACK_ACTIONS
# load_and_authorize_resource :build_list, :through => :project, :shallow => true, :except => CALLBACK_ACTIONS
load_and_authorize_resource :except => CALLBACK_ACTIONS
def all
@ -29,15 +31,6 @@ class BuildListsController < ApplicationController
render :action => 'index'
end
def cancel
build_list = BuildList.find(params[:id])
if build_list.cancel_build_list
redirect_to :back, :notice => t('layout.build_lists.cancel_successed')
else
redirect_to :back, :notice => t('layout.build_lists.cancel_failed')
end
end
def index
@build_lists = @project.build_lists.recent.paginate :page => params[:page]
@filter = BuildList::Filter.new(@project)
@ -57,6 +50,35 @@ class BuildListsController < ApplicationController
@item_groups = @build_list.items.group_by_level
end
def new
@build_list = BuildList.new
end
def create
notices, errors = [], []
Arch.where(:id => params[:archs]).each do |arch|
Platform.main.where(:id => params[:bpls]).each do |bpl|
@build_list = @project.build_lists.build(params[:build_list])
@build_list.bpl = bpl; @build_list.arch = arch
flash_options = {:project_version => @build_list.project_version, :arch => arch.name, :bpl => bpl.name, :pl => @build_list.pl}
if @build_list.save
notices << t("flash.build_list.saved", flash_options)
else
errors << t("flash.build_list.save_error", flash_options)
end
end
end
errors << t("flash.build_list.no_arch_or_platform_selected") if errors.blank? and notices.blank?
if errors.present?
@build_list ||= BuildList.new
flash[:error] = errors.join('<br>').html_safe
render :action => :new
else
flash[:notice] = notices.join('<br>').html_safe
redirect_to @project
end
end
def publish
@build_list = @project.build_lists.find(params[:id])
@build_list.publish
@ -64,6 +86,15 @@ class BuildListsController < ApplicationController
redirect_to project_build_lists_path(@project)
end
def cancel
build_list = BuildList.find(params[:id])
if build_list.cancel_build_list
redirect_to :back, :notice => t('layout.build_lists.cancel_successed')
else
redirect_to :back, :notice => t('layout.build_lists.cancel_failed')
end
end
def status_build
@item = @build_list.items.find_by_name!(params[:package_name])
@item.status = params[:status]

View File

@ -30,7 +30,7 @@ class PlatformsController < ApplicationController
{:name => p.name,
:architectures => ['i586', 'x86_64'],
:repositories => p.repositories.map(&:name),
:url => "http://#{request.host_with_port}/downloads/#{p.name}/repository/"}
:url => p.public_downloads_url(request.host_with_port)}
end
}
end

View File

@ -4,14 +4,12 @@ class ProjectsController < ApplicationController
belongs_to :user, :group, :polymorphic => true, :optional => true
before_filter :authenticate_user!, :except => :auto_build
before_filter :find_project, :only => [:show, :edit, :update, :destroy, :fork, :build, :process_build]
before_filter :find_project, :only => [:show, :edit, :update, :destroy, :fork]
before_filter :get_paths, :only => [:new, :create, :edit, :update]
load_and_authorize_resource
def index
# puts parent.inspect
# puts parent.is_a? User
@projects = if parent? and !parent.nil?
parent.projects
else
@ -95,52 +93,6 @@ class ProjectsController < ApplicationController
render :nothing => true
end
def build
@arches = Arch.recent
@bpls = Platform.main
@pls = @project.repositories.collect { |rep| ["#{rep.platform.name}/#{rep.name}", rep.platform.id] }
@project_versions = @project.versions
end
def process_build
@arch_ids = params[:build][:arches].select{|_,v| v == "1"}.collect{|x| x[0].to_i }
@arches = Arch.where(:id => @arch_ids)
@project_version = params[:build][:project_version]
bpls_ids = params[:build][:bpl].blank? ? [] : params[:build][:bpl].select{|_,v| v == "1"}.collect{|x| x[0].to_i }
bpls = Platform.where(:id => bpls_ids)
pl = Platform.find params[:build][:pl]
update_type = params[:build][:update_type]
build_requires = params[:build][:build_requires]
@project_versions = @project.versions
if !check_arches || !check_project_versions
@arches = Arch.recent
@bpls = Platform.main
@pls = @project.repositories.collect { |rep| ["#{rep.platform.name}/#{rep.name}", rep.platform.id] }
render :action => "build"
else
flash[:notice], flash[:error] = "", ""
@arches.each do |arch|
bpls.each do |bpl|
build_list = @project.build_lists.new(:arch => arch, :project_version => @project_version, :pl => pl, :bpl => bpl, :update_type => update_type, :build_requires => build_requires)
if build_list.save
flash[:notice] += t("flash.build_list.saved", :project_version => @project_version, :arch => arch.name, :bpl => bpl.name, :pl => pl)
else
flash[:error] += t("flash.build_list.save_error", :project_version => @project_version, :arch => arch.name, :bpl => bpl.name, :pl => pl)
end
end
end
redirect_to project_path(@project)
end
end
protected
def get_paths
@ -161,28 +113,4 @@ class ProjectsController < ApplicationController
def find_project
@project = Project.find params[:id]
end
def check_arches
if @arch_ids.blank?
flash[:error] = t("flash.build_list.no_arch_selected")
false
elsif @arch_ids.length != @arches.length
flash[:error] = t("flash.build_list.no_arch_found")
false
else
true
end
end
def check_project_versions
if @project_version.blank?
flash[:error] = t("flash.build_list.no_project_version_selected")
false
elsif !@project_versions.flatten.include?(@project_version)
flash[:error] = t("flash.build_list.no_project_version_found", :project_version => @project_version)
false
else
true
end
end
end

View File

@ -51,14 +51,14 @@ class Ability
can [:read, :create], PrivateUser, :platform => {:owner_type => 'User', :owner_id => user.id}
# If rule has multiple conditions CanCan joins them by 'AND' sql operator
can [:read, :update, :process_build, :build, :destroy], Project, :owner_type => 'User', :owner_id => user.id
can [:read, :update, :destroy], Project, :owner_type => 'User', :owner_id => user.id
#can :read, Project, :relations => {:role => 'reader'}
can :read, Project, projects_in_relations_with(:role => 'reader', :object_type => 'User', :object_id => user.id) do |project|
#The can? and cannot? call cannot be used with a raw sql 'can' definition.
project.relations.exists?(:role => 'reader', :object_type => 'User', :object_id => user.id)
end
#can [:update, :process_build, :build], Project, :relations => {:role => 'writer'}
can [:read, :update, :process_build, :build], Project, projects_in_relations_with(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id) do |project|
#can [:update], Project, :relations => {:role => 'writer'}
can [:read, :update], Project, projects_in_relations_with(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id) do |project|
project.relations.exists?(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id)
end
@ -112,13 +112,13 @@ class Ability
project.relations.exists? :object_id => user.group_ids, :object_type => 'Group', :role => 'admin'
end
can [:read, :update, :process_build, :build, :destroy], Project, :owner_type => 'Group', :owner_id => user.group_ids
can [:read, :update, :destroy], Project, :owner_type => 'Group', :owner_id => user.group_ids
#can :read, Project, :relations => {:role => 'reader', :object_type => 'Group', :object_id => user.group_ids}
can :read, Project, projects_in_relations_with(:role => 'reader', :object_type => 'Group', :object_id => user.group_ids) do |project|
project.relations.exists?(:role => 'reader', :object_type => 'Group', :object_id => user.group_ids)
end
#can [:update, :process_build, :build], Project, :relations => {:role => 'writer', :object_type => 'Group', :object_id => user.group_ids}
can [:read, :update, :process_build, :build], Project, projects_in_relations_with(:role => ['writer', 'admin'], :object_type => 'Group', :object_id => user.group_ids) do |project|
#can [:update], Project, :relations => {:role => 'writer', :object_type => 'Group', :object_id => user.group_ids}
can [:read, :update], Project, projects_in_relations_with(:role => ['writer', 'admin'], :object_type => 'Group', :object_id => user.group_ids) do |project|
project.relations.exists?(:role => ['writer', 'admin'], :object_type => 'Group', :object_id => user.group_ids)
end
@ -135,6 +135,7 @@ class Ability
end
can(:fork, Project) {|p| can? :read, p}
can(:create, BuildList) {|bl| can? :update, bl.project}
# Things that can not do simple user
cannot :create, [Platform, User]

View File

@ -5,9 +5,7 @@ class BuildList < ActiveRecord::Base
belongs_to :bpl, :class_name => 'Platform'
has_many :items, :class_name => "BuildList::Item", :dependent => :destroy
validates :project_id, :presence => true
validates :project_version, :presence => true
#validates_inclusion_of :update_type, :in => UPDATE_TYPES#, :message => "extension %s is not included in the list"
validates :project_id, :project_version, :arch, :include_repos, :presence => true
UPDATE_TYPES = %w[security bugfix enhancement recommended newpackage]
validates :update_type, :inclusion => UPDATE_TYPES
validate lambda {
@ -82,6 +80,7 @@ class BuildList < ActiveRecord::Base
scope :scoped_to_project_name, lambda {|project_name| joins(:project).where('projects.name LIKE ?', "%#{project_name}%")}
serialize :additional_repos
serialize :include_repos
before_create :set_default_status
after_create :place_build
@ -139,8 +138,8 @@ class BuildList < ActiveRecord::Base
end
def place_build
#XML-RPC params: project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web
self.status = BuildServer.add_build_list project.name, project_version, pl.name, arch.name, (pl_id == bpl_id ? '' : bpl.name), update_type, build_requires, id
#XML-RPC params: project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web, include_repos
self.status = BuildServer.add_build_list project.name, project_version, pl.name, arch.name, (pl_id == bpl_id ? '' : bpl.name), update_type, build_requires, id, include_repos
self.status = BUILD_PENDING if self.status == 0
save
end

View File

@ -43,14 +43,17 @@ class Platform < ActiveRecord::Base
urpmi_commands[pl.name] = []
local_pair = pl.id != self.id ? blank_pair : pair
head = hidden? ? "http://#{local_pair[:login]}@#{local_pair[:pass]}:#{host}/private/" : "http://#{host}/downloads/"
if pl.distrib_type == APP_CONFIG['distr_types'].first
# prefix = prefix_url hidden?, :host => host, :login => local_pair[:login], :password => local_pair[:pass]
if pl.distrib_type == APP_CONFIG['distr_types'].first # mdv
Arch.all.each do |arch|
tail = "/#{arch.name}/main/release"
urpmi_commands[pl.name] << "urpmi.addmedia #{name} #{head}#{name}/repository/#{pl.name}#{tail}"
# urpmi_commands[pl.name] << "urpmi.addmedia #{name} #{prefix}/#{name}/repository#{pl.downloads_url '', arch.name, 'main', 'release'}"
end
else
tail = ''
urpmi_commands[pl.name] << "urpmi.addmedia #{name} #{head}#{name}/repository/#{pl.name}#{tail}"
# urpmi_commands[pl.name] << "urpmi.addmedia #{name} #{prefix}/#{name}/repository#{pl.downloads_url ''}"
end
end
@ -65,6 +68,27 @@ class Platform < ActiveRecord::Base
Rails.root.join("public", "downloads", name)
end
def prefix_url(pub, options = {})
options[:host] ||= EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host]
pub ? "http://#{options[:host]}/downloads" : "http://#{options[:login]}:#{options[:password]}@#{options[:host]}/private"
end
def public_downloads_url(host = nil, arch = nil, repo = nil, suffix = nil)
downloads_url prefix_url(true, :host => host), arch, repo, suffix
end
def private_downloads_url(login, password, host = nil, arch = nil, repo = nil, suffix = nil)
downloads_url prefix_url(false, :host => host, :login => login, :password => password), arch, repo, suffix
end
def downloads_url(prefix, arch = nil, repo = nil, suffix = nil)
"#{prefix}/#{name}/repository/".tap do |url|
url << "#{arch}/" if arch.present?
url << "#{repo}/" if repo.present?
url << "#{suffix}/" if suffix.present?
end
end
def hidden?
visibility == 'hidden'
end
@ -115,9 +139,7 @@ class Platform < ActiveRecord::Base
system("sudo mkdir -p #{mount_path}")
system("sudo mount --bind #{path} #{mount_path}")
Arch.all.each do |arch|
host = EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host]
url = "http://#{host}/downloads/#{name}/repository/"
str = "country=Russian Federation,city=Moscow,latitude=52.18,longitude=48.88,bw=1GB,version=2011,arch=#{arch.name},type=distrib,url=#{url}\n"
str = "country=Russian Federation,city=Moscow,latitude=52.18,longitude=48.88,bw=1GB,version=2011,arch=#{arch.name},type=distrib,url=#{public_downloads_url}\n"
File.open(File.join(mount_path, "#{name}.#{arch.name}.list"), 'w') {|f| f.write(str) }
end
end

View File

@ -128,6 +128,10 @@ class Project < ActiveRecord::Base
end
end
def platforms
@platforms ||= repositories.map(&:platform).uniq
end
protected
def build_path(dir)

View File

@ -0,0 +1,3 @@
- platform.repositories.each do |repo|
= check_box_tag "build_list[include_repos][]", repo.id, repo.name == 'main' || @project.repositories.map(&:id).include?(repo.id), :id => "include_repos_#{repo.id}" # (params[:build_list]||[]).fetch(:include_repos, []).include?(repo.id.to_s)
= label_tag "include_repos_#{repo.id}", repo.name

View File

@ -5,46 +5,50 @@
%li= link_to t("layout.projects.new"), new_project_path
%li= link_to t("layout.projects.show"), project_path(@project)
%li=# link_to "git-repo", project_repo_path(@platform, @repository, @project)
%li.active= link_to t("layout.projects.build"), build_project_path(@project)
%li.active= link_to t("layout.projects.build"), new_project_build_list_path(@project)
.content
%h2.title= t("layout.projects.new_build", :project_name => @project.name)
.inner
= form_for :build, :url => process_build_project_path(@project), :html => { :class => :form, :method => :post } do |f|
= form_for [@project, @build_list], :html => { :class => :form, :method => :post } do |f|
.columns.wat-cf
.column.left
.group
= f.label :project_version, t("activerecord.attributes.build_list.project_version"), :class => :label
= f.select :project_version, @project_versions
= f.select :project_version, @project.versions
.group.pl_ids_container
= f.label :bpl, t("activerecord.attributes.build_list.bpl"), :class => :label
- @bpls.each do |bpl|
= f.check_box "bpl[#{bpl.id}]", :bpl_id => bpl.id, :class => 'build_bpl_ids'
= bpl.name
- Platform.main.each do |bpl|
= check_box_tag "bpls[]", bpl.id, (params[:bpls]||[]).include?(bpl.id.to_s), :class => 'build_bpl_ids', :id => "bpls_#{bpl.id}"
= label_tag "bpls_#{bpl.id}", bpl.name
%br
.group
= f.label :update_type, t("activerecord.attributes.build_list.update_type"), :class => :label
= f.select :update_type, BuildList::UPDATE_TYPES.collect { |ut| [ut, ut] }
= f.select :update_type, BuildList::UPDATE_TYPES
.group
= f.check_box :build_requires
= t("activerecord.attributes.build_list.build_requires")
= f.label :build_requires, t("activerecord.attributes.build_list.build_requires")
.column.right
.group
= f.label :arches, t("activerecord.attributes.build_list.arch"), :class => :label
- @arches.each do |arch|
= f.check_box "arches[#{arch.id}]"
= arch.name
- Arch.recent.each do |arch|
= check_box_tag "archs[]", arch.id, (params[:archs]||[]).include?(arch.id.to_s), :id => "archs_#{arch.id}"
= label_tag "archs_#{arch.id}", arch.name
%br
.group
= f.label :pl, t("activerecord.attributes.build_list.pl"), :class => :label
= f.select :pl, @pls
= f.label :pl_id, t("activerecord.attributes.build_list.pl"), :class => :label
= f.select :pl_id, @project.repositories.collect{|r| ["#{r.platform.name}/#{r.name}", r.platform.id]}
.group
= f.label :include_repos, t("activerecord.attributes.build_list.include_repos"), :class => :label
#include_repos
.group.navform.wat-cf
%button.button{:type => "submit"}
@ -53,4 +57,6 @@
%span.text_button_padding= t("layout.or")
= link_to t("layout.cancel"), root_path, :class => "text_button_padding link_button"
-# content_for :sidebar, render(:partial => 'sidebar')
.preloaded_include_repos{:style => 'display: none'}
- @project.platforms.each do |p|
%div{:class => "include_repos_#{p.id}"}= render 'include_repos', :platform => p

View File

@ -34,6 +34,11 @@
= t("activerecord.attributes.build_list.pl")
\:
= @build_list.pl.name
%p
%b
= t("activerecord.attributes.build_list.include_repos")
\:
= (@build_list.include_repos||[]).map{|r| Repository.find(r).name}.join(', ')
%p
%b
= t("activerecord.attributes.build_list.update_type")

View File

@ -4,7 +4,7 @@
%li= link_to t("layout.projects.new"), new_project_path
%li= link_to t("layout.projects.show"), project_path(@project)
%li.active= link_to t("layout.git.repositories.source"), project_repo_path(@project)
%li= link_to t("layout.projects.build"), build_project_path(@project)
%li= link_to t("layout.projects.build"), new_project_build_list_path(@project)
%ul#git_submenu.sub-wat-cf.wat-cf
%li= link_to t("layout.git.repositories.commits"), commits_path(@project, :treeish => @treeish)

View File

@ -5,7 +5,7 @@
%li= link_to t("layout.projects.new"), new_project_path
%li.active= link_to t("layout.projects.show"), project_path(@project)
%li= link_to t("layout.git.repositories.source"), project_repo_path(@project)
%li= link_to t("layout.projects.build"), build_project_path(@project)
%li= link_to t("layout.projects.build"), new_project_build_list_path(@project)
.content
.inner

View File

@ -412,8 +412,7 @@ ru:
save_error: Не удалось сохранить билд лист для версии '%{project_version}', платформы '%{bpl}' и архитектуры '%{arch}'
no_project_version_selected: Выберите какую-нибудь версию
no_project_version_found: Выбранная версия '%{project_version}' не найдена
no_arch_selected: Выберите хотя бы одну ахритектуру
no_arch_found: Выбранные ахритектуры не найдены
no_arch_or_platform_selected: Выберите хотя бы одну ахритектуру и платформу
wrong_platform: Для основного репозитория (main) может быть выбран только его же основная платформа!
can_not_published: Опубликовать сборку можно только со статусом "Собран"
@ -590,6 +589,7 @@ ru:
is_circle: Циклическая сборка
notified_at: Информация получена
additional_repos: Дополнительные репозитории
include_repos: Подключаемые репозитории
updated_at: Обновлен
created_at: Создан
pl: Репозиторий для сохранения пакетов

View File

@ -69,7 +69,7 @@ Rosa::Application.routes.draw do
resources :projects do
resource :repo, :controller => "git/repositories", :only => [:show]
resources :build_lists, :only => [:index, :show] do
resources :build_lists, :only => [:index, :show, :new, :create] do
collection do
get :recent
post :filter
@ -93,8 +93,6 @@ Rosa::Application.routes.draw do
# end
member do
get :build
post :process_build
post :fork
end
collection do

View File

@ -0,0 +1,9 @@
class AddIncludeReposToBuildLists < ActiveRecord::Migration
def self.up
add_column :build_lists, :include_repos, :text
end
def self.down
remove_column :build_lists, :include_repos
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20111130181101) do
ActiveRecord::Schema.define(:version => 20111220152347) do
create_table "arches", :force => true do |t|
t.string "name", :null => false
@ -69,6 +69,7 @@ ActiveRecord::Schema.define(:version => 20111130181101) do
t.string "update_type"
t.integer "bpl_id"
t.integer "pl_id"
t.text "include_repos"
end
add_index "build_lists", ["arch_id"], :name => "index_build_lists_on_arch_id"

View File

@ -72,8 +72,15 @@ class BuildServer
self.client.call('add_to_repo', name, repo_name)
end
def self.add_build_list project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web
self.client.call('add_build_list', project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web)
def self.add_build_list project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web, include_repos
include_repos_json = {}.tap do |h|
include_repos.each do |r|
repo = Repository.find r
h[repo.name] = repo.platform.public_downloads_url(nil, arch, repo.name)
end
end.to_json
# raise include_repos_json.inspect
self.client.call('add_build_list', project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web, include_repos_json)
end
def self.delete_build_list idlist

View File

@ -1,42 +1,29 @@
function check_by_ids(ids) {
for(var i = 0; i < ids.length; i++){
$('#'+ids[i]).attr('checked', true);
}
return false;
}
function uncheck_by_ids(ids) {
for(var i = 0; i < ids.length; i++){
$('#'+ids[i]).attr('checked', false);
}
return false;
}
$(document).ready(function() {
$('.pl_ids_container input[type="hidden"]').remove();
$('select#build_pl').change(function() {
var is_pl_main = false;
var granted_bpl_id = '';
var pl_id = $('select#build_pl').val();
$('select#build_list_pl_id').change(function() {
var platform_id = $(this).val();
$('input.build_bpl_ids').each(function(i,el) {
var bpl_id = $(el).attr('bpl_id');
if (pl_id == bpl_id) {
is_pl_main = true;
//granted_bpl_id = $(el).attr('bpl_id');
}
});
$('#include_repos').html($('.preloaded_include_repos .include_repos_' + platform_id).html());
if (is_pl_main) {
$('input.build_bpl_ids').attr('disabled', 'disabled');
$('input.build_bpl_ids[bpl_id="'+pl_id+'"]').removeAttr('disabled');
} else {
$('input.build_bpl_ids').removeAttr('disabled');
}
// var is_pl_main = false;
// var granted_bpl_id = '';
// var pl_id = $('select#build_pl').val();
//
// $('input.build_bpl_ids').each(function(i,el) {
// var bpl_id = $(el).attr('bpl_id');
// if (pl_id == bpl_id) {
// is_pl_main = true;
// //granted_bpl_id = $(el).attr('bpl_id');
// }
// });
//
// if (is_pl_main) {
// $('input.build_bpl_ids').attr('disabled', 'disabled');
// $('input.build_bpl_ids[bpl_id="'+pl_id+'"]').removeAttr('disabled');
// } else {
// $('input.build_bpl_ids').removeAttr('disabled');
// }
});
$('select#build_pl').trigger('change');
$('select#build_list_pl_id').trigger('change');
$('input.user_role_chbx').click(function() {
var current = $(this);