diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 081802f1c..4a64259cd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -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 diff --git a/app/controllers/build_lists_controller.rb b/app/controllers/build_lists_controller.rb index 91e6d345b..cfb84498c 100644 --- a/app/controllers/build_lists_controller.rb +++ b/app/controllers/build_lists_controller.rb @@ -1,147 +1,161 @@ class BuildListsController < ApplicationController - CALLBACK_ACTIONS = [:status_build, :pre_build, :post_build, :circle_build, :new_bbdt] + CALLBACK_ACTIONS = [:publish_build, :status_build, :pre_build, :post_build, :circle_build, :new_bbdt] + NESTED_ACTIONS = [:index, :new, :create] 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_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] + before_filter :find_project, :only => NESTED_ACTIONS + before_filter :find_build_list, :only => [:show, :publish, :cancel] + before_filter :find_build_list_by_bs, :only => [:publish_build, :status_build, :pre_build, :post_build] - load_and_authorize_resource :except => CALLBACK_ACTIONS + load_and_authorize_resource :project, :only => NESTED_ACTIONS + load_and_authorize_resource :through => :project, :only => NESTED_ACTIONS, :shallow => true + load_and_authorize_resource :except => CALLBACK_ACTIONS.concat(NESTED_ACTIONS) - def all - if params[:filter] - @filter = BuildList::Filter.new(nil, params[:filter]) - @build_lists = @filter.find.paginate :page => params[:page] + def index + filter_params = params[:filter] || {} + if @project + @action_url = project_build_lists_path(@project) else - @filter = BuildList::Filter.new(nil) - @build_lists = BuildList.recent.paginate :page => params[:page] + @action_url = build_lists_path end - @action_url = all_build_lists_path + + @filter = BuildList::Filter.new(@project, filter_params) + @build_lists = @filter.find.accessible_by(current_ability).recent.paginate :page => params[:page] @build_server_status = begin BuildServer.get_status rescue Exception # Timeout::Error {} end + end - 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 new + @build_list = BuildList.new + end - def index - @build_lists = @project.build_lists.recent.paginate :page => params[:page] - @filter = BuildList::Filter.new(@project) - @action_url = project_build_lists_path(@project) - end - - def filter - @filter = BuildList::Filter.new(@project, params[:filter]) - @build_lists = @filter.find.paginate :page => params[:page] - @action_url = project_build_lists_path(@project) - - render :action => "index" - end - - def show - @build_list = @project.build_lists.find(params[:id]) - @item_groups = @build_list.items.group_by_level - end - - def publish - @build_list = @project.build_lists.find(params[:id]) - @build_list.publish - - redirect_to project_build_lists_path(@project) - end - - def status_build - @item = @build_list.items.find_by_name!(params[:package_name]) - @item.status = params[:status] - @item.save - - @build_list.container_path = params[:container_path] - @build_list.notified_at = Time.current - - @build_list.save - - render :nothing => true, :status => 200 - end - - def pre_build - @build_list.status = BuildServer::BUILD_STARTED - @build_list.notified_at = Time.current - - @build_list.save - - render :nothing => true, :status => 200 - end - - def post_build - @build_list.status = params[:status] - @build_list.container_path = params[:container_path] - @build_list.notified_at = Time.current - - @build_list.save - - render :nothing => true, :status => 200 - end - - def circle_build - @build_list.is_circle = true - @build_list.container_path = params[:container_path] - @build_list.notified_at = Time.current - - @build_list.save - - render :nothing => true, :status => 200 - end - - def new_bbdt - @build_list = BuildList.find_by_id!(params[:web_id]) - @build_list.name = params[:name] - @build_list.additional_repos = ActiveSupport::JSON.decode(params[:additional_repos]) - @build_list.set_items(ActiveSupport::JSON.decode(params[:items])) - @build_list.notified_at = Time.current - @build_list.is_circle = (params[:is_circular] != "0") - @build_list.bs_id = params[:id] - params[:arch] - @build_list.save - - render :nothing => true, :status => 200 - end - - protected - - def find_project - @project = Project.find params[:project_id] - end - - def find_arches - @arches = Arch.recent - end - - def find_project_versions - @git_repository = @project.git_repository - @project_versions = @project.versions - end - - def find_build_list_by_bs - @build_list = BuildList.find_by_bs_id!(params[:id]) - end - - def authenticate_build_service! - if request.remote_ip != APP_CONFIG['build_server_ip'] - render :nothing => true, :status => 403 + 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; @build_list.user = current_user + 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('
').html_safe + render :action => :new + else + flash[:notice] = notices.join('
').html_safe + redirect_to @project + end + end + + def show + @item_groups = @build_list.items.group_by_level + end + + def publish + if @build_list.publish + redirect_to :back, :notice => t('layout.build_lists.publish_success') + else + redirect_to :back, :notice => t('layout.build_lists.publish_fail') + end + end + + def cancel + if @build_list.cancel + redirect_to :back, :notice => t('layout.build_lists.cancel_success') + else + redirect_to :back, :notice => t('layout.build_lists.cancel_fail') + end + end + + def publish_build + @build_list.status = (params[:status].to_i == 0 ? BuildList::BUILD_PUBLISHED : BuildList::FAILED_PUBLISH) + @build_list.notified_at = Time.current + @build_list.save + + render :nothing => true, :status => 200 + end + + def status_build + @item = @build_list.items.find_by_name!(params[:package_name]) + @item.status = params[:status] + @item.save + + @build_list.container_path = params[:container_path] + @build_list.notified_at = Time.current + @build_list.save + + render :nothing => true, :status => 200 + end + + def pre_build + @build_list.status = BuildServer::BUILD_STARTED + @build_list.notified_at = Time.current + @build_list.save + + render :nothing => true, :status => 200 + end + + def post_build + @build_list.status = params[:status] + @build_list.container_path = params[:container_path] + @build_list.notified_at = Time.current + @build_list.save + + render :nothing => true, :status => 200 + end + + def circle_build + @build_list.is_circle = true + @build_list.container_path = params[:container_path] + @build_list.notified_at = Time.current + @build_list.save + + render :nothing => true, :status => 200 + end + + def new_bbdt + @build_list = BuildList.find_by_id!(params[:web_id]) + @build_list.name = params[:name] + @build_list.additional_repos = ActiveSupport::JSON.decode(params[:additional_repos]) + @build_list.set_items(ActiveSupport::JSON.decode(params[:items])) + @build_list.notified_at = Time.current + @build_list.is_circle = (params[:is_circular] != "0") + @build_list.bs_id = params[:id] + params[:arch] + @build_list.save + + render :nothing => true, :status => 200 + end + + protected + + def find_project + @project = Project.find_by_id params[:project_id] + end + + def find_build_list + @build_list = BuildList.find(params[:id]) + end + + def find_build_list_by_bs + @build_list = BuildList.find_by_bs_id!(params[:id]) + end + + def authenticate_build_service! + if request.remote_ip != APP_CONFIG['build_server_ip'] + render :nothing => true, :status => 403 + end + end end diff --git a/app/controllers/platforms_controller.rb b/app/controllers/platforms_controller.rb index f096ff050..3aed37c95 100644 --- a/app/controllers/platforms_controller.rb +++ b/app/controllers/platforms_controller.rb @@ -10,7 +10,7 @@ class PlatformsController < ApplicationController def build_all @platform.repositories.each do |repository| repository.projects.each do |project| - project.delay.build_for(@platform) + project.delay.build_for(@platform, current_user) end end @@ -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 diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 4ec20ac45..a870d584c 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -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 diff --git a/app/models/ability.rb b/app/models/ability.rb index ca4b2ffc7..dfd6f105d 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -43,22 +43,26 @@ class Ability can :create, Project can :create, Group can :publish, BuildList do |build_list| - build_list.can_published? && build_list.project.relations.exists?(:object_type => 'User', :object_id => user.id) + build_list.can_publish? && build_list.project.relations.exists?(:object_type => 'User', :object_id => user.id) end - can :read, BuildList do |build_list| - build_list.project.public? || build_list.project.relations.exists?(:object_type => 'User', :object_id => user.id) + can [:index, :read], BuildList, ["build_lists.project_id IN (SELECT id FROM projects WHERE visibility = ?)", 'open'] do |build_list| + build_list.project.public? end + can [:index, :read], BuildList, build_lists_in_relations_with(:object_type => 'User', :object_id => user.id) do |build_list| + build_list.project.relations.exists?(:object_type => 'User', :object_id => user.id) + end + 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 @@ -132,23 +136,23 @@ class Ability # Same rights for groups: can [:read, :create], PrivateUser, :platform => {:owner_type => 'Group', :owner_id => user.group_ids} can :publish, BuildList do |build_list| - build_list.can_published? && build_list.project.relations.exists?(:object_type => 'Group', :object_id => user.group_ids) + build_list.can_publish? && build_list.project.relations.exists?(:object_type => 'Group', :object_id => user.group_ids) end - can :read, BuildList do |build_list| - build_list.project.public? || build_list.project.relations.exists?(:object_type => 'Group', :object_id => user.group_ids) + can [:index, :read], BuildList, build_lists_in_relations_with(:object_type => 'Group', :object_id => user.group_ids) do |build_list| + build_list.project.relations.exists?(:object_type => 'Group', :object_id => user.group_ids) end can :manage_collaborators, Project, projects_in_relations_with(:role => 'admin', :object_type => 'Group', :object_id => user.group_ids) do |project| 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 @@ -165,6 +169,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] @@ -202,6 +207,16 @@ class Ability return opts.values.unshift query end + def build_lists_in_relations_with(opts) + query = "build_lists.project_id IN (SELECT target_id FROM relations WHERE relations.target_type = 'Project'" + opts.each do |key, value| + query = query + " AND relations.#{ key } #{ value.class == Array ? 'IN (?)' : '= ?' } " + end + query = query + ")" + + return opts.values.unshift query + end + ## Sub query for project relations #def projects_in_relations_with(opts={}) # ["projects.id IN (SELECT target_id FROM relations WHERE relations.object_id #{ opts[:object_id].class == Array ? 'IN (?)' : '= ?' } AND relations.object_type = '#{ opts[:object_type] }' AND relations.target_type = 'Platform') AND relations.role", opts[:object_id]] diff --git a/app/models/build_list.rb b/app/models/build_list.rb index 1cab5a9f8..d28e0d293 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -3,30 +3,30 @@ class BuildList < ActiveRecord::Base belongs_to :arch belongs_to :pl, :class_name => 'Platform' belongs_to :bpl, :class_name => 'Platform' + belongs_to :user 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 { errors.add(:bpl, I18n.t('flash.build_list.wrong_platform')) if pl.platform_type == 'main' && pl_id != bpl_id } - validate lambda { - errors.add(:bpl, I18n.t('flash.build_list.can_not_published')) if status == BUILD_PUBLISHED && status_was != BuildServer::SUCCESS - } # The kernel does not send these statuses directly BUILD_CANCELED = 5000 WAITING_FOR_RESPONSE = 4000 BUILD_PENDING = 2000 BUILD_PUBLISHED = 6000 + BUILD_PUBLISH = 7000 + FAILED_PUBLISH = 8000 STATUSES = [ WAITING_FOR_RESPONSE, BUILD_CANCELED, BUILD_PENDING, BUILD_PUBLISHED, + BUILD_PUBLISH, + FAILED_PUBLISH, BuildServer::SUCCESS, BuildServer::BUILD_STARTED, BuildServer::BUILD_ERROR, @@ -41,6 +41,8 @@ class BuildList < ActiveRecord::Base BUILD_CANCELED => :build_canceled, BUILD_PENDING => :build_pending, BUILD_PUBLISHED => :build_published, + BUILD_PUBLISH => :build_publish, + FAILED_PUBLISH => :failed_publish, BuildServer::BUILD_ERROR => :build_error, BuildServer::BUILD_STARTED => :build_started, BuildServer::SUCCESS => :success, @@ -82,6 +84,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 @@ -103,29 +106,28 @@ class BuildList < ActiveRecord::Base end end end - + def publish - return false unless can_published? - - BuildServer.publish_container bs_id - self.update_attribute(:status, BUILD_PUBLISHED) - #self.destroy # self.delete - end - - def can_published? - self.status == BuildServer::SUCCESS + return false unless can_publish? + has_published = BuildServer.publish_container bs_id + update_attribute(:status, BUILD_PUBLISH) if has_published == 0 + return has_published == 0 end - def cancel_build_list + def can_publish? + status == BuildServer::SUCCESS or status == FAILED_PUBLISH + end + + def cancel + return false unless can_cancel? has_canceled = BuildServer.delete_build_list bs_id update_attribute(:status, BUILD_CANCELED) if has_canceled == 0 - return has_canceled == 0 end #TODO: Share this checking on product owner. def can_cancel? - self.status == BUILD_PENDING && bs_id + status == BUILD_PENDING && bs_id end def event_log_message @@ -139,8 +141,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 diff --git a/app/models/platform.rb b/app/models/platform.rb index 70f9c9414..e0768062a 100644 --- a/app/models/platform.rb +++ b/app/models/platform.rb @@ -14,9 +14,7 @@ class Platform < ActiveRecord::Base has_many :groups, :through => :objects, :source => :object, :source_type => 'Group' validates :description, :presence => true, :uniqueness => true - if !Rails.env.development? - validates :name, :uniqueness => true, :presence => true, :format => { :with => /^[a-zA-Z0-9_]+$/ } - end + validates :name, :uniqueness => true, :presence => true, :format => { :with => /^[a-zA-Z0-9_\-]+$/ } validates :distrib_type, :presence => true, :inclusion => {:in => APP_CONFIG['distr_types']} before_create :xml_rpc_create, :unless => lambda {Thread.current[:skip]} @@ -45,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 @@ -67,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 @@ -117,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 diff --git a/app/models/project.rb b/app/models/project.rb index 56e861308..8ef6d8753 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -49,7 +49,7 @@ class Project < ActiveRecord::Base end end - def build_for(platform) + def build_for(platform, user) build_lists.create do |bl| bl.pl = platform bl.bpl = platform @@ -57,6 +57,7 @@ class Project < ActiveRecord::Base bl.arch = Arch.find_by_name('i586') bl.project_version = "latest_#{platform.name}" bl.build_requires = false # already set as db default + bl.user = user end end @@ -129,6 +130,10 @@ class Project < ActiveRecord::Base end end + def platforms + @platforms ||= repositories.map(&:platform).uniq + end + protected def build_path(dir) diff --git a/app/models/project_to_repository.rb b/app/models/project_to_repository.rb index 68148f89c..a5a623123 100644 --- a/app/models/project_to_repository.rb +++ b/app/models/project_to_repository.rb @@ -7,4 +7,14 @@ class ProjectToRepository < ActiveRecord::Base after_create lambda { project.xml_rpc_create(repository) }, :unless => lambda {Thread.current[:skip]} after_destroy lambda { project.xml_rpc_destroy(repository) } # after_rollback lambda { project.xml_rpc_destroy(repository) rescue true if new_record? } + + validate :one_project_in_platform_repositories + + protected + + def one_project_in_platform_repositories + c = Platform.scoped.select('projects.*').joins(:repositories => :projects).where( + :projects => {:name => project.name}, :id => repository.platform_id).count + errors.add(:project, 'should be one in platform') if c > 0 + end end diff --git a/app/models/repository.rb b/app/models/repository.rb index c6acb4599..13c4e2a02 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -11,7 +11,7 @@ class Repository < ActiveRecord::Base has_many :groups, :through => :objects, :source => :object, :source_type => 'Group' validates :description, :uniqueness => {:scope => :platform_id}, :presence => true - validates :name, :uniqueness => {:scope => :platform_id}, :presence => true, :format => { :with => /^[a-z0-9_]+$/ } + validates :name, :uniqueness => {:scope => :platform_id}, :presence => true, :format => { :with => /^[a-z0-9_\-]+$/ } # validates :platform_id, :presence => true # if you uncomment this platform clone will not work scope :recent, order("name ASC") diff --git a/app/models/user.rb b/app/models/user.rb index b48d3f2a5..07e59a71f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,6 +5,7 @@ class User < ActiveRecord::Base :recoverable, :rememberable, :validatable #, :trackable, :confirmable, :lockable has_many :authentications, :dependent => :destroy + has_many :build_lists, :dependent => :destroy has_many :relations, :as => :object, :dependent => :destroy has_many :targets, :as => :object, :class_name => 'Relation' @@ -38,6 +39,9 @@ class User < ActiveRecord::Base self.id.blank? # persisted? end + def fullname + return "#{uname} (#{name})" + end class << self def find_for_database_authentication(warden_conditions) conditions = warden_conditions.dup diff --git a/app/views/build_lists/_build_lists.html.haml b/app/views/build_lists/_build_lists.html.haml index 4e41e1d26..8bd7ab667 100644 --- a/app/views/build_lists/_build_lists.html.haml +++ b/app/views/build_lists/_build_lists.html.haml @@ -5,21 +5,23 @@ %th= t("activerecord.attributes.build_list.project_version") %th= t("activerecord.attributes.build_list.project") %th= t("activerecord.attributes.build_list.arch") + %th= t("activerecord.attributes.build_list.user") %th= t("activerecord.attributes.build_list.is_circle") - - if controller.action_name = 'all' + - unless @project %th= t("layout.build_lists.cancel_button_header") %th.last= t("activerecord.attributes.build_list.notified_at") - build_lists.each do |build_list| %tr{:class => cycle("odd", "even")} - %td= link_to (build_list.bs_id.present? ? build_list.bs_id : t("layout.build_lists.bs_id_not_set")), project_build_list_path(build_list.project, build_list) + %td= link_to (build_list.bs_id.present? ? build_list.bs_id : t("layout.build_lists.bs_id_not_set")), build_list %td= build_list.human_status %td= link_to build_list.project_version, "#" %td= link_to build_list.project.name, project_path(build_list.project) %td= build_list.arch.name + %td= build_list.user.try(:fullname) %td= t("layout.#{build_list.is_circle?}_") - - if controller.action_name = 'all' - %td= link_to t("layout.build_lists.cancel_button"), build_list_cancel_path(build_list) if build_list.can_cancel? + - unless @project + %td= link_to t("layout.build_lists.cancel_button"), cancel_build_list_path(build_list), :method => "put", :confirm => t("layout.confirm") if build_list.can_cancel? %td.last= build_list.notified_at -= will_paginate build_lists \ No newline at end of file += will_paginate build_lists diff --git a/app/views/build_lists/_filter.html.haml b/app/views/build_lists/_filter.html.haml index a4c69725c..9a184f655 100644 --- a/app/views/build_lists/_filter.html.haml +++ b/app/views/build_lists/_filter.html.haml @@ -8,12 +8,12 @@ = f.select :status, BuildList::STATUSES.collect{|status| [BuildList.human_status(status), status]}, :include_blank => true, :selected => @filter.status .group = f.label :arch_id, t("activerecord.attributes.build_list.arch"), :class => :label - = f.select :arch_id, @arches.collect{|arch| [arch.name, arch.id]}, :include_blank => true, :selected => @filter.arch_id + = f.select :arch_id, Arch.recent.collect{|arch| [arch.name, arch.id]}, :include_blank => true, :selected => @filter.arch_id .column.right - - if @project_versions + - if @project .group = f.label :project_version, t("activerecord.attributes.build_list.project_version"), :class => :label - = f.select :project_version, @project_versions, :include_blank => true, :selected => @filter.project_version + = f.select :project_version, @project.versions, :include_blank => true, :selected => @filter.project_version .group = f.label :is_circle, t("activerecord.attributes.build_list.is_circle"), :class => :label = f.select :is_circle, [[t("layout.yes_"), 1], [t("layout.no_"), 0]], :include_blank => true, :selected => @filter.is_circle.present? ? (@filter.is_circle ? "1" : "0") : nil @@ -47,4 +47,4 @@ .group.navform.wat-cf %button.button{ :type => "submit" } = image_tag("web-app-theme/icons/tick.png", :alt => "Save") - = t("layout.search") \ No newline at end of file + = t("layout.search") diff --git a/app/views/build_lists/_include_repos.html.haml b/app/views/build_lists/_include_repos.html.haml new file mode 100644 index 000000000..55902b2f9 --- /dev/null +++ b/app/views/build_lists/_include_repos.html.haml @@ -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 \ No newline at end of file diff --git a/app/views/build_lists/_sidebar.html.haml b/app/views/build_lists/_sidebar.html.haml index 2b81fc62c..55d964a20 100644 --- a/app/views/build_lists/_sidebar.html.haml +++ b/app/views/build_lists/_sidebar.html.haml @@ -1,10 +1,10 @@ .block.notice %h3= t("layout.repositories.current_repository_header") .content - - @project.repositories.each do |repository| + - project.repositories.each do |repository| %p= link_to "#{repository.name} (#{repository.platform.name})", platform_repository_path(repository.platform, repository) .block.notice %h3= t("layout.projects.current_project_header") .content - %p= link_to @project.name, project_path(@project) \ No newline at end of file + %p= link_to project.name, project \ No newline at end of file diff --git a/app/views/build_lists/index.html.haml b/app/views/build_lists/index.html.haml index 9fe414890..97e5375f9 100644 --- a/app/views/build_lists/index.html.haml +++ b/app/views/build_lists/index.html.haml @@ -1,12 +1,12 @@ .block - - if controller.action_name != 'all' + - if @project .secondary-navigation %ul.wat-cf %li.first= link_to t("layout.build_lists.current"), project_path(@project) + "#build_lists" %li.active= link_to t("layout.build_lists.all"), project_build_lists_path(@project) .content - - if controller.action_name == 'all' + - unless @project .inner %h2= t('layout.build_lists.build_server_status.header') .field @@ -25,4 +25,4 @@ .inner = render :partial => "build_lists/build_lists", :object => @build_lists -- content_for :sidebar, render(:partial => 'sidebar') if controller.action_name != 'all' \ No newline at end of file +- content_for :sidebar, render('sidebar', :project => @project) if @project diff --git a/app/views/projects/build.html.haml b/app/views/build_lists/new.html.haml similarity index 51% rename from app/views/projects/build.html.haml rename to app/views/build_lists/new.html.haml index 531334fae..88aa55c5d 100644 --- a/app/views/projects/build.html.haml +++ b/app/views/build_lists/new.html.haml @@ -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 + .group.base_platforms = 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 diff --git a/app/views/build_lists/show.html.haml b/app/views/build_lists/show.html.haml index 6d53030e6..eafd98ddd 100644 --- a/app/views/build_lists/show.html.haml +++ b/app/views/build_lists/show.html.haml @@ -1,9 +1,9 @@ .block .secondary-navigation %ul.wat-cf - %li.first= link_to t("layout.build_lists.current"), project_path(@project) + "#build_lists" - %li= link_to t("layout.build_lists.all"), project_build_lists_path(@project) - %li.active= link_to t("layout.build_lists.show"), project_build_list_path(@project, @build_list) + %li.first= link_to t("layout.build_lists.current"), project_path(@build_list.project) + "#build_lists" + %li= link_to t("layout.build_lists.all"), project_build_lists_path(@build_list.project) + %li.active= link_to t("layout.build_lists.show"), @build_list .content .inner @@ -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") @@ -64,6 +69,11 @@ = t("activerecord.attributes.build_list.arch") \: = @build_list.arch.name + %p + %b + = t("activerecord.attributes.build_list.user") + \: + = @build_list.user.try(:fullname) %p %b = t("activerecord.attributes.build_list.notified_at") @@ -75,9 +85,9 @@ \: = t("layout.#{@build_list.is_circle?}_") - - if @build_list.can_published? + - if @build_list.can_publish? .wat-cf - = link_to image_tag("web-app-theme/icons/tick.png", :alt => t("layout.publish")) + " " + t("layout.publish"), publish_project_build_list_path(@project, @build_list), :method => "post", :class => "button", :confirm => t("layout.build_lists.confirm_publish") + = link_to image_tag("web-app-theme/icons/tick.png", :alt => t("layout.publish")) + " " + t("layout.publish"), publish_build_list_path(@build_list), :method => "put", :class => "button", :confirm => t("layout.confirm") .block .content @@ -101,4 +111,4 @@ %td= item.version %td.last= item.human_status -- content_for :sidebar, render(:partial => 'sidebar') +- content_for :sidebar, render('sidebar', :project => @build_list.project) diff --git a/app/views/git/shared/_navigation.html.haml b/app/views/git/shared/_navigation.html.haml index cb135dea6..e09fcb051 100644 --- a/app/views/git/shared/_navigation.html.haml +++ b/app/views/git/shared/_navigation.html.haml @@ -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) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 068431143..2520f8616 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -36,7 +36,7 @@ %a{:href => event_logs_path}= t("layout.menu.event_logs") -if can? :index, BuildList %li{:class => controller.controller_path == 'build_lists' ? 'active' : '' } - %a{:href => all_build_lists_path}= t("layout.menu.build_lists") + %a{:href => build_lists_path}= t("layout.menu.build_lists") -if can? :platforms, Category %li{:class => controller.controller_path == 'categories' ? 'active' : '' } %a{:href => catalogs_path}= t("layout.menu.categories") diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 7bbc69176..e302150d9 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -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) %li= link_to t("layout.projects.issues"), project_issues_path(@project) .content diff --git a/config/locales/event_log.ru.yml b/config/locales/event_log.ru.yml index c1aed3a86..c6e627043 100644 --- a/config/locales/event_log.ru.yml +++ b/config/locales/event_log.ru.yml @@ -23,8 +23,8 @@ ru: open_id: 'вход через OpenID' projects_controller: auto_build: 'отправлен на автоматическую сборку' - process_build: 'отправлен на сборку' build_lists_controller: + create: 'отправлен на сборку' cancel: 'сборка отменена' publish: 'сборка опубликована' auto_build_lists_controller: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 506eac2f8..97eea839c 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -299,7 +299,6 @@ ru: build_lists: filter_header: Фильтр current: Текущие - all: Все created_at_start: "Время постановки на сборку с:" created_at_end: "Время постановки на сборку по:" notified_at_start: "Время последнего обновления от BS с:" @@ -310,11 +309,12 @@ ru: items_header: Элементы сборки no_items_data: Данных нет show: Просмотр - confirm_publish: Вы уверены, что хотите опубликовать контейнер? cancel_button_header: Действие cancel_button: Отмена - cancel_successed: 'Сборка отменена.' - cancel_failed: 'При отмене сборки произошла ошибка!' + cancel_success: 'Сборка отменена.' + cancel_fail: 'При отмене сборки произошла ошибка!' + publish_success: 'Сборка поставлена в очередь на публикацию.' + publish_fail: 'При публикации сборки произошла ошибка!' build_server_status: header: Статус сборочного сервера @@ -333,6 +333,8 @@ ru: statuses: build_error: ошибка сборки build_published: опубликован + build_publish: публикуется + failed_publish: ошибка публикации dependencies_fail: зависимости не найдены waiting_for_response: ожидает ответа build_pending: ожидает сборку @@ -438,8 +440,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: Опубликовать сборку можно только со статусом "Собран" @@ -628,6 +629,7 @@ ru: is_circle: Циклическая сборка notified_at: Информация получена additional_repos: Дополнительные репозитории + include_repos: Подключаемые репозитории updated_at: Обновлен created_at: Создан pl: Репозиторий для сохранения пакетов @@ -637,6 +639,7 @@ ru: update_type: Критичность обновления build_requires: Пересборка с зависимостями project_version: Версия + user: Пользователь build_list/item: name: Название diff --git a/config/routes.rb b/config/routes.rb index 120556a0b..4a0227e63 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -24,8 +24,19 @@ Rosa::Application.routes.draw do match '/private/:platform_name/*file_path' => 'privates#show' - match 'build_lists/' => 'build_lists#all', :as => :all_build_lists - match 'build_lists/:id/cancel/' => 'build_lists#cancel', :as => :build_list_cancel + match 'build_lists/publish_build', :to => "build_lists#publish_build" + match 'build_lists/status_build', :to => "build_lists#status_build" + match 'build_lists/post_build', :to => "build_lists#post_build" + match 'build_lists/pre_build', :to => "build_lists#pre_build" + match 'build_lists/circle_build', :to => "build_lists#circle_build" + match 'build_lists/new_bbdt', :to => "build_lists#new_bbdt" + + resources :build_lists, :only => [:index, :show] do + member do + put :cancel + put :publish + end + end resources :auto_build_lists, :only => [:index, :create, :destroy] @@ -74,15 +85,7 @@ Rosa::Application.routes.draw do resources :comments, :only => [:edit, :create, :update, :destroy] end resource :repo, :controller => "git/repositories", :only => [:show] - resources :build_lists, :only => [:index, :show] do - collection do - get :recent - post :filter - end - member do - post :publish - end - end + resources :build_lists, :only => [:index, :new, :create] resources :collaborators, :only => [:index, :edit, :update, :add] do collection do @@ -98,8 +101,6 @@ Rosa::Application.routes.draw do # end member do - get :build - post :process_build post :fork end collection do @@ -138,12 +139,6 @@ Rosa::Application.routes.draw do match '/catalogs', :to => 'categories#platforms', :as => :catalogs - match 'build_lists/status_build', :to => "build_lists#status_build" - match 'build_lists/post_build', :to => "build_lists#post_build" - match 'build_lists/pre_build', :to => "build_lists#pre_build" - match 'build_lists/circle_build', :to => "build_lists#circle_build" - match 'build_lists/new_bbdt', :to => "build_lists#new_bbdt" - match 'product_status', :to => 'product_build_lists#status_build' # Tree diff --git a/db/migrate/20111220152347_add_include_repos_to_build_lists.rb b/db/migrate/20111220152347_add_include_repos_to_build_lists.rb new file mode 100644 index 000000000..cb0b8d7b0 --- /dev/null +++ b/db/migrate/20111220152347_add_include_repos_to_build_lists.rb @@ -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 diff --git a/db/migrate/20111221194422_add_user_id_to_build_lists.rb b/db/migrate/20111221194422_add_user_id_to_build_lists.rb new file mode 100644 index 000000000..1a52d0264 --- /dev/null +++ b/db/migrate/20111221194422_add_user_id_to_build_lists.rb @@ -0,0 +1,9 @@ +class AddUserIdToBuildLists < ActiveRecord::Migration + def self.up + add_column :build_lists, :user_id, :integer + end + + def self.down + remove_column :build_lists, :user_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 794ab6874..55f94564c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20111219073859) do +ActiveRecord::Schema.define(:version => 20111221194422) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -69,6 +69,8 @@ ActiveRecord::Schema.define(:version => 20111219073859) do t.string "update_type" t.integer "bpl_id" t.integer "pl_id" + t.text "include_repos" + t.integer "user_id" end add_index "build_lists", ["arch_id"], :name => "index_build_lists_on_arch_id" diff --git a/lib/build_server.rb b/lib/build_server.rb index 6ce8f87bb..b82c13387 100644 --- a/lib/build_server.rb +++ b/lib/build_server.rb @@ -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_hash = {}.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 + # raise include_repos_hash.inspect + self.client.call('add_build_list', project_name, project_version, plname, arch, bplname, update_type, build_requires, id_web, include_repos_hash) end def self.delete_build_list idlist diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 78895567c..b2617a1c7 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -1,42 +1,25 @@ -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(); + var base_platforms = $('.base_platforms input[type=checkbox]'); - $('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'); - } + base_platforms.each(function(){ + if ($.inArray(platform_id, base_platforms.map(function(){ return $(this).val() }).get()) >= 0) { + if ($(this).val() == platform_id) { + $(this).attr('checked', 'checked'); + $(this).removeAttr('disabled'); + } else { + $(this).removeAttr('checked'); + $(this).attr('disabled', 'disabled'); + } + } else { + $(this).removeAttr('disabled'); + } + }); }); - - $('select#build_pl').trigger('change'); + $('select#build_list_pl_id').trigger('change'); $('input.user_role_chbx').click(function() { var current = $(this); diff --git a/spec/controllers/build_lists_controller_spec.rb b/spec/controllers/build_lists_controller_spec.rb index 204b55fa9..27b6b8174 100644 --- a/spec/controllers/build_lists_controller_spec.rb +++ b/spec/controllers/build_lists_controller_spec.rb @@ -7,6 +7,11 @@ describe BuildListsController do get :show, @show_params response.should be_success end + + it 'should be able to perform index action in project scope' do + get :index, :project_id => @project.id + response.should be_success + end end shared_examples_for 'not show build list' do @@ -14,12 +19,17 @@ describe BuildListsController do get :show, @show_params response.should redirect_to(forbidden_url) end + + it 'should not be able to perform index action in project scope' do + get :index, :project_id => @project.id + response.should redirect_to(forbidden_url) + end end context 'crud' do context 'for guest' do - it 'should not be able to perform all action' do - get :all + it 'should not be able to perform index action' do + get :index response.should redirect_to(new_user_session_path) end end @@ -37,11 +47,31 @@ describe BuildListsController do @user = Factory(:user) set_session_for(@user) @show_params = {:project_id => @project.id, :id => @build_list.id} + end - it 'should not be able to perform all action' do - get :all - response.should redirect_to(forbidden_url) + context 'for all build lists' do + before(:each) do + @build_list1 = Factory(:build_list_core) + @build_list2 = Factory(:build_list_core, :project => Factory(:project, :visibility => 'hidden')) + @build_list3 = Factory(:build_list_core, :project => Factory(:project, :owner => @user, :visibility => 'hidden')) + b = Factory(:build_list_core, :project => Factory(:project, :visibility => 'hidden')) + b.project.relations.create :role => 'reader', :object_id => @user.id, :object_type => 'User' + @build_list4 = b + end + + it 'should be able to perform index action' do + get :index + response.should be_success + end + + it 'should show only accessible build_lists' do + get :index + assigns(:build_lists).should include(@build_list1) + assigns(:build_lists).should_not include(@build_list2) + assigns(:build_lists).should include(@build_list3) + assigns(:build_lists).should include(@build_list4) + end end context 'for open project' do @@ -52,7 +82,7 @@ describe BuildListsController do it_should_behave_like 'show build list' end - context 'if user is project owner' do + context 'if user is project member' do before(:each) {set_session_for(@member_user)} it_should_behave_like 'show build list' end @@ -71,7 +101,89 @@ describe BuildListsController do it_should_behave_like 'show build list' end - context 'if user is project owner' do + context 'if user is project member' do + before(:each) {set_session_for(@member_user)} + it_should_behave_like 'show build list' + end + end + + end + + context 'for group' do + before(:each) do + stub_rsync_methods + @owner_group = Factory(:group) + @owner_user = Factory(:user) + @owner_group.objects.create :role => 'reader', :object_id => @owner_user.id, :object_type => 'User' + @member_group = Factory(:group) + @member_user = Factory(:user) + @member_group.objects.create :role => 'reader', :object_id => @member_user.id, :object_type => 'User' + + @group = Factory(:group) + @user = Factory(:user) + @group.objects.create :role => 'reader', :object_id => @user.id, :object_type => 'User' + + @project = Factory(:project, :owner => @owner_group) + @project.relations.create :role => 'reader', :object_id => @member_group.id, :object_type => 'Group' + + @build_list = Factory(:build_list_core, :project => @project) + + set_session_for(@user) + @show_params = {:project_id => @project.id, :id => @build_list.id} + end + + context 'for all build lists' do + before(:each) do + @build_list1 = Factory(:build_list_core) + @build_list2 = Factory(:build_list_core, :project => Factory(:project, :visibility => 'hidden')) + @build_list3 = Factory(:build_list_core, :project => Factory(:project, :owner => @group, :visibility => 'hidden')) + b = Factory(:build_list_core, :project => Factory(:project, :visibility => 'hidden')) + b.project.relations.create :role => 'reader', :object_id => @group.id, :object_type => 'Group' + @build_list4 = b + end + + it 'should be able to perform index action' do + get :index + response.should be_success + end + + it 'should show only accessible build_lists' do + get :index + assigns(:build_lists).should include(@build_list1) + assigns(:build_lists).should_not include(@build_list2) + assigns(:build_lists).should include(@build_list3) + assigns(:build_lists).should include(@build_list4) + end + end + + context 'for open project' do + it_should_behave_like 'show build list' + + context 'if user is group owner' do + before(:each) {set_session_for(@owner_user)} + it_should_behave_like 'show build list' + end + + context 'if user is group member' do + before(:each) {set_session_for(@member_user)} + it_should_behave_like 'show build list' + end + end + + context 'for hidden project' do + before(:each) do + @project.visibility = 'hidden' + @project.save + end + + it_should_behave_like 'not show build list' + + context 'if user is group owner' do + before(:each) {set_session_for(@owner_user)} + it_should_behave_like 'show build list' + end + + context 'if user is group member' do before(:each) {set_session_for(@member_user)} it_should_behave_like 'show build list' end @@ -82,13 +194,13 @@ describe BuildListsController do context 'for admin' do before(:each) { set_session_for Factory(:admin) } - it "should be able to perform all action without exception" do + it "should be able to perform index action without exception" do any_instance_of(XMLRPC::Client) do |xml_rpc| stub(xml_rpc).call do |args| raise Timeout::Error end end - get :all + get :index assigns[:build_server_status].should == {} response.should be_success end @@ -100,46 +212,39 @@ describe BuildListsController do before(:each) do stub_rsync_methods set_session_for Factory(:admin) - end - - let(:build_list1) { Factory(:build_list_core) } - let(:build_list2) { Factory(:build_list_core) } - let(:build_list3) { Factory(:build_list_core) } - let(:build_list4) do - b = Factory(:build_list_core) - b.created_at = b.created_at - 1.day - b.project = build_list3.project - b.pl = build_list3.pl - b.arch = build_list3.arch - b.save - b + + @build_list1 = Factory(:build_list_core) + @build_list2 = Factory(:build_list_core) + @build_list3 = Factory(:build_list_core) + @build_list4 = Factory(:build_list_core, :created_at => (Time.now - 1.day), + :project => @build_list3.project, :pl => @build_list3.pl, + :arch => @build_list3.arch) end - before(:each) { set_session_for Factory(:admin); stub_rsync_methods; } it 'should filter by bs_id' do - get :all, :filter => {:bs_id => build_list1.bs_id, :project_name => 'fdsfdf', :any_other_field => 'do not matter'} - assigns[:build_lists].should include(build_list1) - assigns[:build_lists].should_not include(build_list2) - assigns[:build_lists].should_not include(build_list3) + get :index, :filter => {:bs_id => @build_list1.bs_id, :project_name => 'fdsfdf', :any_other_field => 'do not matter'} + assigns[:build_lists].should include(@build_list1) + assigns[:build_lists].should_not include(@build_list2) + assigns[:build_lists].should_not include(@build_list3) end it 'should filter by project_name' do # Project.where(:id => build_list2.project.id).update_all(:name => 'project_name') - get :all, :filter => {:project_name => build_list2.project.name} - assigns[:build_lists].should_not include(build_list1) - assigns[:build_lists].should include(build_list2) - assigns[:build_lists].should_not include(build_list3) + get :index, :filter => {:project_name => @build_list2.project.name} + assigns[:build_lists].should_not include(@build_list1) + assigns[:build_lists].should include(@build_list2) + assigns[:build_lists].should_not include(@build_list3) end it 'should filter by project_name and start_date' do - get :all, :filter => {:project_name => build_list3.project.name, - "created_at_start(1i)"=>build_list3.created_at.year.to_s, - "created_at_start(2i)"=>build_list3.created_at.month.to_s, - "created_at_start(3i)"=>build_list3.created_at.day.to_s} - assigns[:build_lists].should_not include(build_list1) - assigns[:build_lists].should_not include(build_list2) - assigns[:build_lists].should include(build_list3) - assigns[:build_lists].should_not include(build_list4) + get :index, :filter => {:project_name => @build_list3.project.name, + "created_at_start(1i)" => @build_list3.created_at.year.to_s, + "created_at_start(2i)" => @build_list3.created_at.month.to_s, + "created_at_start(3i)" => @build_list3.created_at.day.to_s} + assigns[:build_lists].should_not include(@build_list1) + assigns[:build_lists].should_not include(@build_list2) + assigns[:build_lists].should include(@build_list3) + assigns[:build_lists].should_not include(@build_list4) # response.should be_success end end diff --git a/spec/models/project_to_repository_spec.rb b/spec/models/project_to_repository_spec.rb index f908dee57..c27de0b5f 100644 --- a/spec/models/project_to_repository_spec.rb +++ b/spec/models/project_to_repository_spec.rb @@ -1,5 +1,18 @@ require 'spec_helper' describe ProjectToRepository do - pending "add some examples to (or delete) #{__FILE__}" + before(:each) do + stub_rsync_methods + @platform = Factory(:platform) + @first_repo = Factory(:repository, :platform_id => @platform.id) + @second_repo = Factory(:repository, :platform_id => @platform.id) + @project = Factory(:project) + @first_repo.projects << @project + @first_repo.save + end + + it 'should not add the same project in different repositories of same platform' do + p2r = @second_repo.project_to_repositories.build :project_id => @project.id + p2r.should_not be_valid + end end