Dev Guidelines
by Martyn Taylor
After to speaking to some of the guys on the dev team it seems some people have differences of opinion with regards to some of the ways that things are done or are maybe unsure on the best way to do something.
I suggest we write some basic guidelines for any topics that people are unsure of, or if they're seeing things that they feel should be done differently.
I think a good start would be to get any suggestions from people who feel that things should be done differently and a list of things people are unsure of. Then we could maybe collate all the stuff together and stick it in the wiki - if its a standard practice or common knowledge we could maybe add a link to a web page that explains.
Some things that we've already discussed include:
Testing: lmartinc
Error Handling: mtaylor
When to use errors, throw/catch exceptions
Patch Submissions: mtaylor
I feel that all refactoring should be added in separate patches, rather than including this in any bug fixes or tasks. This way we can see exactly what the changes are wft particular bugs etc...
Thanks guys
Martyn
13 years, 5 months
[PATCH aggregator] BZ #644011 - consistent aritechture types
by Jan Provazník
From: Jan Provaznik <jprovazn(a)redhat.com>
https://bugzilla.redhat.com/show_bug.cgi?id=644011
Template's architecture is now 'x86_64' (or i386) instead of 64-bit or 32-bit
---
src/app/controllers/instances_controller.rb | 8 +-------
.../image_descriptor_platform_repositories.yml | 2 +-
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/src/app/controllers/instances_controller.rb b/src/app/controllers/instances_controller.rb
index 3ffb287..5e68b8e 100644
--- a/src/app/controllers/instances_controller.rb
+++ b/src/app/controllers/instances_controller.rb
@@ -82,15 +82,9 @@ class InstancesController < ApplicationController
def configure
@instance = Instance.new(params[:instance])
require_privilege(Privilege::INSTANCE_MODIFY, @instance.pool)
- # FIXME: change template.architecture to match expected HWP arch strings
- if (@instance.template.architecture == "64-bit")
- arch_value = "x86_64"
- else
- arch_value = "i386"
- end
@hardware_profiles = HardwareProfile.find(:all, :include => :architecture,
:conditions => {:provider_id => nil,
- "hardware_profile_properties.value" => arch_value})
+ 'hardware_profile_properties.value' => @instance.template.architecture})
end
def create
diff --git a/src/config/image_descriptor_platform_repositories.yml b/src/config/image_descriptor_platform_repositories.yml
index c29a244..d16d0c0 100644
--- a/src/config/image_descriptor_platform_repositories.yml
+++ b/src/config/image_descriptor_platform_repositories.yml
@@ -1,4 +1,4 @@
fedora:
name: Fedora
version: 13
- architecture: 64-bit
+ architecture: x86_64
--
1.7.2.3
13 years, 5 months
[PATCH aggregator] BZ #641385: remove redundant sql queries in condormatic_classads_sync
by Mo Morsi
replaces sql queries nested in multiple loops in condormatic with
single calls whose results get iterated over to form classad tuple
---
src/app/util/condormatic.rb | 91 ++++++++++++++++++++++--------------------
1 files changed, 48 insertions(+), 43 deletions(-)
diff --git a/src/app/util/condormatic.rb b/src/app/util/condormatic.rb
index 74c5a80..37040cd 100644
--- a/src/app/util/condormatic.rb
+++ b/src/app/util/condormatic.rb
@@ -204,50 +204,55 @@ def condormatic_classads_sync
end
Rails.logger.info "Syncing classads.."
- providers.each do |provider|
- provider.cloud_accounts.each do |account|
- provider.replicated_images.each do |replicated_image|
- # The replicated image entry gets put in the database as soon as we ask
- # to have the image built, so we only want to generate classads for it if
- # it is ready to be used. When ready it will have an image key assigned
- # to it.
- if replicated_image.provider_image_key != nil
- provider.hardware_profiles.each do |hwp|
- provider.realms.each do |realm|
- pipe = IO.popen("condor_advertise UPDATE_STARTD_AD 2>&1", "w+")
-
- pipe.puts "Name=\"provider_combination_#{index}\""
- pipe.puts 'MyType="Machine"'
- pipe.puts 'Requirements=true'
- pipe.puts "\n# Stuff needed to match:"
- pipe.puts "hardwareprofile=\"#{hwp.aggregator_hardware_profiles[0].id}\""
- pipe.puts "image=\"#{replicated_image.image.template.id}\""
- pipe.puts "realm=\"#{realm.frontend_realms[0].id}\""
- pipe.puts "\n# Backend info to complete this job:"
- pipe.puts "image_key=\"#{replicated_image.provider_image_key}\""
- pipe.puts "hardwareprofile_key=\"#{hwp.external_key}\""
- pipe.puts "realm_key=\"#{realm.external_key}\""
- pipe.puts "provider_url=\"#{account.provider.url}\""
- pipe.puts "username=\"#{account.username}\""
- pipe.puts "password=\"#{account.password}\""
- pipe.puts "cloud_account_id=\"#{account.id}\""
- pipe.puts "keypair=\"#{escape(account.instance_key.name)}\""
- pipe.close_write
-
- out = pipe.read
- pipe.close
-
- Rails.logger.error "Unable to submit condor classad: #{out}" if $? != 0
-
- index += 1
- end
- end
- end
- end
- end
+ ads = []
+ providers.each { |provider|
+ # The replicated image entry gets put in the database as soon as we ask
+ # to have the image built, so we only want to generate classads for it if
+ # it is ready to be used. When ready it will have an image key assigned
+ # to it.
+ replicated_images = provider.replicated_images.find(:all,
+ :conditions => ['provider_image_key IS NOT NULL'])
+ accounts = provider.cloud_accounts
+ hardware_profiles = provider.hardware_profiles
+ realms = provider.realms
+ accounts.each { |account|
+ replicated_images.each { |replicated_img|
+ hardware_profiles.each { |hwp|
+ ads += realms.collect { |realm|
+ [account, replicated_img, hwp, realm] } } } }
+ }
+
+ ads.each { |ad|
+ account, replicated_image, hwp, realm = *ad
+
+ pipe = IO.popen("condor_advertise UPDATE_STARTD_AD 2>&1", "w+")
+
+ pipe.puts "Name=\"provider_combination_#{index}\""
+ pipe.puts 'MyType="Machine"'
+ pipe.puts 'Requirements=true'
+ pipe.puts "\n# Stuff needed to match:"
+ pipe.puts "hardwareprofile=\"#{hwp.aggregator_hardware_profiles[0].id}\""
+ pipe.puts "image=\"#{replicated_image.image.template.id}\""
+ pipe.puts "realm=\"#{realm.frontend_realms[0].id}\""
+ pipe.puts "\n# Backend info to complete this job:"
+ pipe.puts "image_key=\"#{replicated_image.provider_image_key}\""
+ pipe.puts "hardwareprofile_key=\"#{hwp.external_key}\""
+ pipe.puts "realm_key=\"#{realm.external_key}\""
+ pipe.puts "provider_url=\"#{account.provider.url}\""
+ pipe.puts "username=\"#{account.username}\""
+ pipe.puts "password=\"#{account.password}\""
+ pipe.puts "cloud_account_id=\"#{account.id}\""
+ pipe.puts "keypair=\"#{escape(account.instance_key.name)}\""
+ pipe.close_write
- Rails.logger.info "done"
- end
+ out = pipe.read
+ pipe.close
+
+ Rails.logger.error "Unable to submit condor classad: #{out}" if $? != 0
+
+ index += 1
+ }
+ Rails.logger.info "done"
end
def kick_condor
--
1.7.2.3
13 years, 6 months
[PATCH aeolus] Redmine#8 Update Provider Links on Accounts Page
by Martyn Taylor
From: Martyn Taylor <mtaylor(a)redhat.com>
---
src/app/helpers/providers_helper.rb | 2 +-
src/app/views/providers/_providers.haml | 2 +-
src/spec/helpers/providers_helper_spec.rb | 1 -
3 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/app/helpers/providers_helper.rb b/src/app/helpers/providers_helper.rb
index 4da2a0b..5cff42c 100644
--- a/src/app/helpers/providers_helper.rb
+++ b/src/app/helpers/providers_helper.rb
@@ -1,7 +1,7 @@
module ProvidersHelper
def edit_button(provider, action)
- if provider and ['show', 'accounts'].include? action
+ if provider and ['show'].include? action
link_to 'Edit', edit_provider_path(provider), :class => 'button'
else
content_tag('a', 'Edit', :href => '#', :class => 'button disabled')
diff --git a/src/app/views/providers/_providers.haml b/src/app/views/providers/_providers.haml
index 8d184a5..279b257 100644
--- a/src/app/views/providers/_providers.haml
+++ b/src/app/views/providers/_providers.haml
@@ -11,4 +11,4 @@
- form_tag({:controller => 'providers', :action => 'new'}, {:method => :get , :class => 'buttononly'}) do
%input{ :type => 'submit', :value => t(:add), :disabled => ('disabled' unless controller.action_name == 'index') }
- form_tag({:controller => 'providers', :action => 'destroy', :id => @provider}, {:method => :delete , :class => 'buttononly'}) do
- = submit_tag 'delete', :disabled => ('disabled' unless @provider and ['show', 'accounts'].include? controller.action_name)
+ = submit_tag 'delete', :disabled => ('disabled' unless @provider and ['show'].include? controller.action_name)
\ No newline at end of file
diff --git a/src/spec/helpers/providers_helper_spec.rb b/src/spec/helpers/providers_helper_spec.rb
index ef7bc30..10b1476 100644
--- a/src/spec/helpers/providers_helper_spec.rb
+++ b/src/spec/helpers/providers_helper_spec.rb
@@ -9,7 +9,6 @@ describe ProvidersHelper do
provider = Factory(:mock_provider)
edit_button(provider, 'show').should =~ /providers\/[0-9]*\/edit/
- edit_button(provider, 'accounts').should =~ /providers\/[0-9]*\/edit/
end
it "formats blank link with no action and with disabled class if not in show or accounts action" do
--
1.7.2.3
13 years, 6 months
[PATCH aggregator 1/2] Factory UI cleanup
by Jan Provazník
From: Jan Provaznik <jprovazn(a)redhat.com>
This patch significantly cleanups template UI backend. Drops most of hacks made
for package selction in beta1, though there is still metagroup support (will be
removed with new UI design).
I think this is a good base for future rework of views (while we get it from
design team). I also moved build actions into separate controller (BuildsController).
Note that you should run 'rake dc:prepare_repos' if you don't use pulp.
---
src/app/controllers/builds_controller.rb | 90 ++++++
src/app/controllers/templates_controller.rb | 298 +++++++------------
src/app/models/template.rb | 72 ++++--
src/app/util/image_descriptor_xml.rb | 41 ++--
src/app/util/repository_manager.rb | 149 +++-------
.../util/repository_manager/abstract_repository.rb | 4 +
.../util/repository_manager/comps_repository.rb | 78 +++---
src/app/util/repository_manager/pulp_repository.rb | 23 +-
src/app/views/builds/index.haml | 89 ++++++
src/app/views/builds/new.haml | 55 ++++
src/app/views/templates/_collections.haml | 11 +-
src/app/views/templates/_form.haml | 122 ++++++++
src/app/views/templates/_hidden_fields.haml | 4 +-
.../views/templates/_local_content_to_bundle.haml | 21 ++
src/app/views/templates/_managed_content.haml | 15 +-
src/app/views/templates/_metagroup_packages.haml | 14 +-
src/app/views/templates/_metagroups.haml | 13 +
.../views/templates/_preboot_configuration.haml | 11 +
src/app/views/templates/_search_packages.haml | 45 +++
src/app/views/templates/_searched_packages.haml | 43 ---
src/app/views/templates/_software_selection.haml | 39 +++
src/app/views/templates/build_form.haml | 55 ----
src/app/views/templates/builds.haml | 89 ------
src/app/views/templates/collections.haml | 1 +
src/app/views/templates/content_selection.haml | 56 ----
src/app/views/templates/edit.haml | 6 +
src/app/views/templates/index.haml | 2 +-
src/app/views/templates/metagroup_packages.haml | 1 +
src/app/views/templates/new.haml | 162 +-----------
src/app/views/templates/search_packages.haml | 1 +
src/config/navigation.rb | 6 +-
src/config/routes.rb | 10 +-
src/features/step_definitions/general_steps.rb | 3 +
src/features/step_definitions/template_steps.rb | 13 +-
src/features/support/paths.rb | 6 +-
src/features/template.feature | 67 +++--
src/spec/controllers/builds_controller_spec.rb | 37 +++
src/spec/controllers/templates_controller_spec.rb | 27 +--
src/spec/factories/template.rb | 25 +--
src/spec/models/template_spec.rb | 2 +-
src/spec/utils/repository_manager_spec.rb | 20 ++-
41 files changed, 917 insertions(+), 909 deletions(-)
create mode 100644 src/app/controllers/builds_controller.rb
create mode 100644 src/app/views/builds/index.haml
create mode 100644 src/app/views/builds/new.haml
create mode 100644 src/app/views/templates/_form.haml
create mode 100644 src/app/views/templates/_local_content_to_bundle.haml
create mode 100644 src/app/views/templates/_metagroups.haml
create mode 100644 src/app/views/templates/_preboot_configuration.haml
create mode 100644 src/app/views/templates/_search_packages.haml
delete mode 100644 src/app/views/templates/_searched_packages.haml
create mode 100644 src/app/views/templates/_software_selection.haml
delete mode 100644 src/app/views/templates/build_form.haml
delete mode 100644 src/app/views/templates/builds.haml
create mode 100644 src/app/views/templates/collections.haml
delete mode 100644 src/app/views/templates/content_selection.haml
create mode 100644 src/app/views/templates/edit.haml
create mode 100644 src/app/views/templates/metagroup_packages.haml
create mode 100644 src/app/views/templates/search_packages.haml
create mode 100644 src/features/step_definitions/general_steps.rb
create mode 100644 src/spec/controllers/builds_controller_spec.rb
diff --git a/src/app/controllers/builds_controller.rb b/src/app/controllers/builds_controller.rb
new file mode 100644
index 0000000..820f28b
--- /dev/null
+++ b/src/app/controllers/builds_controller.rb
@@ -0,0 +1,90 @@
+class BuildsController < ApplicationController
+ before_filter :require_user
+
+ def section_id
+ 'build'
+ end
+
+ def index
+ require_privilege(Privilege::IMAGE_VIEW)
+ order = get_order('templates.name')
+ @running_images = Image.all(:include => :template, :conditions => ['status IN (?)', Image::ACTIVE_STATES], :order => order)
+ @completed_images = Image.all(:include => :template, :conditions => {:status => Image::STATE_COMPLETE}, :order => order)
+ @failed_images = Image.all(:include => :template, :conditions => {:status => Image::STATE_FAILED}, :order => order)
+ end
+
+ def new
+ raise "select template to build" unless id = params[:template_id]
+ @tpl = Template.find(id)
+ @all_targets = Image.available_targets
+ end
+
+ def create
+ if params[:cancel]
+ redirect_to templates_path
+ return
+ end
+
+ @tpl = Template.find(params[:template_id])
+ @all_targets = Image.available_targets
+
+ if params[:targets].blank?
+ flash.now[:warning] = 'You need to check at least one provider format'
+ render :action => 'new'
+ return
+ end
+
+ @tpl.upload_template unless @tpl.uploaded
+ errors = {}
+ params[:targets].each do |target|
+ # FIXME: for beta release we check explicitly that provider and provider
+ # account exists
+ unless provider = Provider.find_by_cloud_type(target)
+ flash_error('Error while trying to build image',
+ 'no provider account' => "There is no provider of '#{target}' type, \
+you can add provider on <a href=\"#{url_for :controller => 'provider'}\">the providers page.</a>")
+ render :action => 'new' and return
+ end
+ if provider.cloud_accounts.empty?
+ flash_error('Error while trying to build image',
+ 'no provider account' => "There is no provider account for '#{target}' \
+provider, you can add account on <a href=\"#{url_for :controller => 'provider', \
+:action => 'accounts', :id => provider.id}\">the provider accounts page</a>")
+ render :action => 'new' and return
+ end
+ begin
+ Image.build(@tpl, target)
+ rescue
+ errors[target] = $!.message
+ end
+ end
+ if errors.empty?
+ redirect_to builds_path
+ else
+ flash_error('Error while trying to build image', errors)
+ render :action => 'new'
+ end
+ end
+
+ def edit
+ end
+
+ def update
+ end
+
+ private
+
+ # TODO: DRY this, is used in templates controller too
+ def get_order(default)
+ @order_dir = params[:order_dir] == 'desc' ? 'desc' : 'asc'
+ @order_field = params[:order_field] || default
+ "#{@order_field} #{@order_dir}"
+ end
+
+ def flash_error(summary, errs)
+ flash.now[:error] ||= {}
+ flash.now[:error][:summary] = summary
+ flash.now[:error][:failures] ||= {}
+ flash.now[:error][:failures].merge!(errs)
+ end
+end
diff --git a/src/app/controllers/templates_controller.rb b/src/app/controllers/templates_controller.rb
index 12df295..403e6c3 100644
--- a/src/app/controllers/templates_controller.rb
+++ b/src/app/controllers/templates_controller.rb
@@ -2,7 +2,12 @@ require 'util/repository_manager'
class TemplatesController < ApplicationController
before_filter :require_user
- before_filter :check_permission, :except => [:index, :builds]
+ before_filter :check_permission, :except => :index
+ layout :layout
+
+ def layout
+ return "aggregator" unless request.xhr?
+ end
def section_id
'build'
@@ -18,31 +23,29 @@ class TemplatesController < ApplicationController
)
end
- def action
+ def index_action
if params[:new_template]
- redirect_to :action => 'new'
+ redirect_to new_template_path
elsif params[:assembly]
- redirect_to :action => 'assembly'
+ redirect_to assembly_template_path(:id => params[:ids].to_a.first)
elsif params[:deployment_definition]
- redirect_to :action => 'deployment_definition'
+ redirect_to deployment_definition_template_path(:id => params[:ids].to_a.first)
elsif params[:delete]
- redirect_to :action => 'delete', :ids => params[:ids].to_a
+ redirect_to destroy_multiple_templates_path(:ids => params[:ids].to_a)
elsif params[:edit]
- begin
- redirect_to :action => 'new', :id => get_selected_id
- rescue
- flash[:notice] = "No template selected"
- redirect_to :action => 'index'
+ if id = get_selected_id
+ redirect_to edit_template_path(:id => id)
+ else
+ redirect_to templates_path
end
elsif params[:build]
- begin
- redirect_to :action => 'build_form', 'template_id' => get_selected_id
- rescue
- flash[:notice] = "No template selected"
- redirect_to :action => 'index'
+ if id = get_selected_id
+ redirect_to new_build_path(:template_id => id)
+ else
+ redirect_to templates_path
end
else
- raise "Unknown action"
+ raise 'Unknown action'
end
end
@@ -51,183 +54,122 @@ class TemplatesController < ApplicationController
def dispatch
if params[:save]
create
-
elsif params[:cancel]
- redirect_to :action => 'index'
-
+ redirect_to templates_path
elsif params[:add_software_form]
- content_selection
-
+ collections
+ elsif params[:collections]
+ collections
elsif pkg = params.keys.find { |k| k =~ /^remove_package_(.*)$/ }
# actually remove the package from list
params[:packages].delete($1) if params[:packages]
new
-
elsif params[:add_selected]
new
-
elsif params[:cancel_add_software]
- params[:packages] = params[:selected_packages]
+ params[:selected_packages] = params[:packages]
+ params[:selected_groups] = params[:groups]
+ params[:cached_packages] = []
new
-
- elsif params.include?('show_metagroup')
- @metagroup = params['show_metagroup']
- content_selection
-
- elsif not params[:package_search].blank?
- content_selection
-
+ elsif params.include?('metagroup_packages')
+ metagroup_packages
+ elsif params[:package_search]
+ search_packages
+ else
+ raise "unknown action"
end
end
- # FIXME at some point split edit/update out from new/create
- # to conform to web standards
def new
# can't use @template variable - is used by compass (or something other)
- @id = params[:id]
- @tpl = @id.blank? ? Template.new : Template.find(@id)
- @tpl.attributes = params[:tpl] unless params[:tpl].nil?
- get_selected_packages(@tpl)
+ @tpl = Template.new(params[:tpl])
+ @repository_manager = RepositoryManager.new(:repositories => params[:repository] || @tpl.platform)
+ @tpl.add_software(params[:packages].to_a + params[:selected_packages].to_a + params[:cached_packages].to_a,
+ params[:groups].to_a + params[:selected_groups].to_a)
render :action => :new
end
- def create
- @id = params[:tpl][:id]
- @tpl = @id.blank? || @id == "" ? Template.new(params[:tpl]) : Template.find(@id)
-
- @tpl.xml.clear_packages
-
- params[:groups].to_a.each { |group| @tpl.xml.add_group(group) }
- params[:packages].to_a.each { |pkg| @tpl.xml.add_package(pkg) }
-
- # this is crazy, but we have most attrs in xml and also in model,
- # synchronize it at first to xml
- @tpl.update_xml_attributes(params[:tpl])
+ def edit
+ @tpl = Template.find(params[:id])
+ @tpl.attributes = params[:tpl] unless params[:tpl].blank?
+ @repository_manager = RepositoryManager.new(:repositories => params[:repository] || @tpl.platform)
+ render :action => :edit
+ end
+ def create
+ @tpl = Template.new(params[:tpl])
+ @tpl.packages = params[:packages]
if @tpl.save
flash[:notice] = "Template saved."
@tpl.set_complete
- redirect_to :action => 'index'
+ redirect_to templates_path
else
- get_selected_packages(@tpl)
+ @repository_manager = RepositoryManager.new(:repositories => params[:repository] || @tpl.platform)
render :action => 'new'
end
end
- def content_selection
- @repository_manager = RepositoryManager.new
- @id = params[:id]
- @tpl = @id.blank? ? Template.new : Template.find(@id)
- @tpl.attributes = params[:tpl] unless params[:tpl].nil?
- @packages = []
- @packages += params[:packages].collect{ |p| { :name => p } } unless params[:packages].blank?
- @packages += params[:selected_packages].collect{ |p| { :name => p } } unless params[:selected_packages].blank?
- @groups = @repository_manager.all_groups_with_tagged_selected_packages(@packages, params[:repository] || @tpl.platform)
- @embed = params[:embed]
- @categories = @repository_manager.categories(params[:tpl] ? params[:tpl][:platform] : nil)
- @metagroups = @repository_manager.metagroups
+ def update
+ @tpl = Template.find(params[:id])
+ @tpl.packages = []
- if not params[:package_search].blank?
- @page = get_page
- @cached_packages = params[:cached_packages].to_a
- @searched_packages = @repository_manager.search_package(params[:package_search],
- params[:repository] || @tpl.platform).paginate(:page => @page,
- :per_page => 60)
- elsif not @metagroup.blank?
- if @metagroup == 'Collections'
- # TODO: if we remember selected groups, this could be done much more simply
- @collections = @repository_manager.all_groups_with_tagged_selected_packages(@packages, params[:repository] || @tpl.platform)
- else
- @metagroup_packages = @repository_manager.metagroup_packages_with_tagged_selected_packages(@metagroup, @packages, params[:repository] || @tpl.platform)
- end
+ if @tpl.update_attributes(params[:tpl])
+ @tpl.set_complete
+ flash[:notice] = "Template updated."
+ redirect_to templates_path
else
- @collections = @repository_manager.all_groups_with_tagged_selected_packages(@packages, params[:repository] || @tpl.platform)
- end
- if request.xhr?
- if @metagroup_packages
- render :partial => 'metagroup_packages' and return
- end
- if @searched_packages
- render :partial => 'searched_packages' and return
- end
- if @collections and @metagroup
- render :partial => 'collections' and return
- end
+ @repository_manager = RepositoryManager.new(:repositories => params[:repository] || @tpl.platform)
+ render :action => 'edit'
end
+ end
- if @embed
- render :layout => false
+ def search_packages
+ set_package_vars
+ @page = get_page
+ @cached_packages = params[:cached_packages].to_a + params[:selected_packages].to_a
+ @searched_packages = params[:package_search].empty? ? [] : @repository_manager.search_package(
+ params[:package_search]).paginate(:page => @page, :per_page => 60)
+ if request.xhr?
+ render :partial => 'search_packages'
else
- render :action => :content_selection
+ render :search_packages
end
end
- def managed_content
- get_selected_packages
- render :layout => false
- end
-
- def build_form
- raise "select template to build" unless id = params[:template_id]
- @tpl = Template.find(id)
- @all_targets = Image.available_targets
- end
-
- def build
- if params[:cancel]
- redirect_to :action => 'index'
- return
- end
-
- @tpl = Template.find(params[:template_id])
- @all_targets = Image.available_targets
-
- if params[:targets].blank?
- flash.now[:warning] = 'You need to check at least one provider format'
- render :action => 'build_form'
- return
+ def metagroup_packages
+ set_package_vars
+ @metagroup_packages = @repository_manager.metagroup_packages(params[:metagroup_packages])
+ if request.xhr?
+ render :partial => 'metagroup_packages'
+ else
+ render :metagroup_packages
end
+ end
- @tpl.upload_template unless @tpl.uploaded
- params[:targets].each do |target|
- # FIXME: for beta release we check explicitly that provider and provider
- # account exists
- unless provider = Provider.find_by_cloud_type(target)
- flash_error("There is no provider of '#{target}' type, you can add provider \
-on <a href=\"#{url_for :controller => 'providers'}\">the providers page.</a>")
- render :action => 'build_form' and return
- end
- if provider.cloud_accounts.empty?
- flash_error("There is no provider account for '#{target}' provider, you can \
-add account on <a href=\"#{url_for :controller => 'providers', \
-:action => 'accounts', :id => provider.id}\">the provider accounts page</a>")
- render :action => 'build_form' and return
- end
- begin
- Image.build(@tpl, target)
- rescue
- flash.now[:error] ||= {}
- flash.now[:error][:failures] ||= {}
- flash.now[:error][:failures][target] = $!.message
- end
- end
- if flash[:error] and not flash[:error][:failures].blank?
- flash[:error][:summary] = 'Error while trying to build image'
- render :action => 'build_form'
+ def collections
+ set_package_vars
+ @collections = @repository_manager.groups
+ if request.xhr?
+ render :partial => 'collections'
else
- redirect_to :action => 'builds'
+ render :collections
end
end
- def builds
- order = get_order('templates.name')
- @running_images = Image.all(:include => :template, :conditions => ['status IN (?)', Image::ACTIVE_STATES], :order => order)
- @completed_images = Image.all(:include => :template, :conditions => {:status => Image::STATE_COMPLETE}, :order => order)
- @failed_images = Image.all(:include => :template, :conditions => {:status => Image::STATE_FAILED}, :order => order)
- require_privilege(Privilege::IMAGE_VIEW)
+ def content_selection
+ set_package_vars(true)
+ @collections = @repository_manager.groups
+ render :collections
end
- def delete
+ def managed_content
+ @tpl = params[:template_id].blank? ? Template.new : Template.find(params[:template_id])
+ @tpl.add_software(params[:packages].to_a + params[:selected_packages].to_a,
+ params[:groups].to_a + params[:selected_groups].to_a)
+ render :layout => false
+ end
+
+ def destroy_multiple
ids = params[:ids].to_a
if ids.empty?
flash[:notice] = "No Template Selected"
@@ -242,12 +184,10 @@ add account on <a href=\"#{url_for :controller => 'providers', \
if errs.empty?
flash[:notice] = 'Template deleted'
else
- flash[:error] ||= {}
- flash[:error][:summary] = 'Error while deleting template'
- (flash[:error][:failures] ||= {}).merge!(errs)
+ flash_error('Error while deleting template', errs)
end
end
- redirect_to :action => 'index'
+ redirect_to templates_path
end
def assembly
@@ -259,17 +199,27 @@ add account on <a href=\"#{url_for :controller => 'providers', \
private
+ def set_package_vars(set_all = false)
+ @tpl = params[:id].blank? ? Template.new : Template.find(params[:id])
+ @tpl.attributes = params[:tpl] unless params[:tpl].nil?
+ @repository_manager = RepositoryManager.new(:repositories => params[:repository] || @tpl.platform)
+ @groups = @repository_manager.groups
+ @categories = @repository_manager.categories if not request.xhr? or set_all
+ @metagroups = @repository_manager.metagroups if not request.xhr? or set_all
+ @tpl.add_software(params[:packages].to_a, params[:groups].to_a)
+ end
+
def get_order(default)
@order_dir = params[:order_dir] == 'desc' ? 'desc' : 'asc'
@order_field = params[:order_field] || default
"#{@order_field} #{@order_dir}"
end
- def flash_error(msg)
+ def flash_error(summary, errs)
flash.now[:error] ||= {}
- flash.now[:error][:summary] = 'Error while trying to build image'
+ flash.now[:error][:summary] = summary
flash.now[:error][:failures] ||= {}
- flash.now[:error][:failures]['no provider account'] = msg
+ flash.now[:error][:failures].merge!(errs)
end
def check_permission
@@ -279,40 +229,12 @@ add account on <a href=\"#{url_for :controller => 'providers', \
def get_selected_id
ids = params[:ids].to_a
if ids.size != 1
- raise "No Template Selected" if ids.empty?
- raise "You can select only one template" if ids.size > 1
+ flash[:warning] = ids.empty? ? 'No Template Selected' : 'You can select only one template'
+ return
end
return ids.first
end
- def get_selected_packages(tpl=nil)
- @repository_manager = RepositoryManager.new
- @groups = @repository_manager.all_groups(params[:repository])
-
- if not params[:packages].blank? or not params[:selected_packages].blank? or not params[:cached_packages].blank?
- @selected_packages = params[:packages].to_a + params[:selected_packages].to_a
- elsif !tpl.nil?
- @selected_packages = tpl.xml.packages.collect { |p| p[:name] }
- else
- @selected_packages = []
- end
-
- if params[:collections].to_s == 'true' or not request.xhr?
- [:selected_groups, :groups].each do |pg|
- if params[pg]
- params[pg].each { |grp|
- fg = @groups.find { |gk, gv| gk == grp }
- fg[1][:packages].each { |pk, pv|
- @selected_packages << pk
- } unless fg.nil?
- }
- end
- end
- end
-
- @selected_packages.uniq!
- end
-
def get_page
if params[:page] == 'Previous'
return params[:old_page].to_i - 1
diff --git a/src/app/models/template.rb b/src/app/models/template.rb
index e1e9df2..74bf208 100644
--- a/src/app/models/template.rb
+++ b/src/app/models/template.rb
@@ -4,7 +4,8 @@ require 'typhoeus'
class Template < ActiveRecord::Base
has_many :images, :dependent => :destroy
has_many :instances
- before_validation :update_attrs
+ before_validation :generate_uuid
+ before_save :update_xml
before_destroy :no_instances?
WAREHOUSE_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/image_warehouse.yml")
@@ -27,19 +28,6 @@ class Template < ActiveRecord::Base
true
end
- def update_xml_attributes(opts = {})
- xml.name = opts[:name] if opts[:name]
- xml.description = opts[:summary] if opts[:summary]
- if plat = opts[:platform]
- xml.platform = plat
- xml.platform_version = platforms[plat]['version'].to_s
- xml.architecture = platforms[plat]['architecture']
- end
- self[:xml] = xml.to_xml
- @xml = nil
- update_attrs
- end
-
def xml
@xml ||= ImageDescriptorXML.new(self[:xml].to_s)
end
@@ -54,14 +42,18 @@ class Template < ActiveRecord::Base
end
end
- def update_attrs
+ def generate_uuid
# TODO: generate real uuid here, e.g. with some ruby uuid generator
- self.uuid ||= "#{xml.name}-#{Time.now.to_f.to_s}"
- self.name = xml.name
- self.summary = xml.description
- self.platform = xml.platform
- self.platform_version = xml.platform_version
- self.architecture = xml.architecture
+ self.uuid ||= "#{self.name}-#{Time.now.to_f.to_s}"
+ end
+
+ def update_xml
+ xml.name = self.name
+ xml.description = self.summary
+ xml.platform = self.platform
+ xml.platform_version = self.platform_version
+ xml.architecture = self.architecture
+ write_attribute(:xml, xml.to_s)
end
def providers
@@ -83,4 +75,42 @@ class Template < ActiveRecord::Base
def platforms
@platforms ||= YAML.load_file("#{RAILS_ROOT}/config/image_descriptor_platform_repositories.yml")
end
+
+ def add_packages(packages)
+ packages.to_a.each {|pkg| xml.add_package(pkg)}
+ end
+
+ def add_groups(groups)
+ groups.to_a.each {|pkg| xml.add_group(pkg)}
+ end
+
+ def add_software(packages, groups)
+ add_packages(packages)
+ add_groups(groups)
+ end
+
+ def platform=(plat)
+ write_attribute(:platform, plat)
+ self.platform_version = platforms[plat]['version'].to_s
+ self.architecture = platforms[plat]['architecture']
+ end
+
+ # packages and groups are virtual attributes
+ def packages
+ xml.packages
+ end
+
+ def packages=(packages)
+ xml.clear_packages
+ packages.to_a.each {|pkg| xml.add_package(pkg)}
+ end
+
+ def groups
+ xml.groups
+ end
+
+ def groups=(groups)
+ xml.clear_groups
+ groups.to_a.each {|group| xml.add_group(group)}
+ end
end
diff --git a/src/app/util/image_descriptor_xml.rb b/src/app/util/image_descriptor_xml.rb
index 034d943..e9f71d9 100644
--- a/src/app/util/image_descriptor_xml.rb
+++ b/src/app/util/image_descriptor_xml.rb
@@ -52,7 +52,7 @@ class ImageDescriptorXML
# platform
# update: we don't add platform repo, image builder chooses right one from OS
# name, but we add all other repos
- recreate_repo_nodes
+ #recreate_repo_nodes
get_or_create_node('os')['name'] = str
end
@@ -109,28 +109,28 @@ class ImageDescriptorXML
end
def packages
- packages = []
- @root.xpath('/image/packages/package').each do |s|
- packages << {:name => s.at_xpath('.//name').text}
+ @root.xpath('/image/packages/package').map do |s|
+ s.at_xpath('.//name').text
+ end
+ end
+
+ def groups
+ @root.xpath('/image/groups/group').map do |s|
+ s.at_xpath('.//name').text
end
- return packages
end
def add_package(pkg)
pkgs_node = get_or_create_node('packages')
- unless older = packages.find {|p| p[:name] == pkg}
- add_package_node(pkgs_node, pkg)
- end
+ add_package_node(pkgs_node, pkg) unless packages.include?(pkg)
end
def add_group(gname)
- unless group = repository_manager.all_groups[gname]
- raise "group #{gname} not found in repositories"
- end
- group[:packages].each do |p, info|
- next if info[:type] == 'optional'
- add_package(p)
- end
+ #unless group = repository_manager.groups.find(gname)
+ # raise "group #{gname} not found in repositories"
+ #end
+ node = get_or_create_node('groups')
+ add_group_node(node, gname) unless groups.include?(gname)
end
def remove_package(package)
@@ -145,12 +145,17 @@ class ImageDescriptorXML
@root.xpath('/image/packages').each { |s| s.remove }
end
+ def clear_groups
+ @root.xpath('/image/groups').each { |s| s.remove }
+ end
+
private
def add_group_node(parent, group)
- n = Nokogiri::XML::Node.new('group', @doc)
- n.content = group
- parent << n
+ pnode = get_or_create_node('group', parent)
+ n = Nokogiri::XML::Node.new('name', @doc)
+ n.content = name
+ pnode << n
end
def recreate_repo_nodes
diff --git a/src/app/util/repository_manager.rb b/src/app/util/repository_manager.rb
index 382f48d..8ada489 100644
--- a/src/app/util/repository_manager.rb
+++ b/src/app/util/repository_manager.rb
@@ -28,141 +28,63 @@ class RepositoryManager
@config = opts[:config] || load_config
@config = [ @config ] if Hash === @config
@repositories = get_repositories
+ @selected_repositories = get_selected_repositories(opts[:repositories])
end
- def all_groups(repository = nil)
- unless @all_groups
- @all_groups = {}
- repositories.each do |r|
- next if repository and repository != 'all' and repository != r.id
- r.groups.each do |group, data|
- if @all_groups[group]
- @all_groups[group][:packages].merge!(data[:packages])
- else
- @all_groups[group] = data
- end
- end
- end
- end
- return @all_groups
+ def groups
+ @groups ||= @selected_repositories.map {|repo| repo.groups}.flatten
end
- def packages(repository = nil)
+ def packages
+ @packages ||= @selected_repositories.map {|repo| repo.packages}.flatten
end
- def categories(repository = nil)
- unless @all_categories
- @all_categories = {}
- repositories.each do |r|
- next if repository and repository != 'all' and repository != r.id
- r.categories.each do |id, data|
- if @all_categories[id]
- @all_categories[id][:groups] += data[:groups]
- else
- @all_categories[id] = data
- end
- end
- end
+ def categories
+ @categories ||= @selected_repositories.map {|repo| repo.categories}.flatten
+ end
+
+ def repositories_hash
+ res = {}
+ @repositories.each do |r|
+ res[r.id] = r
end
- return @all_categories
+ res
end
- def packages(repository = nil)
- unless @packages
- @packages = []
- repositories.each do |r|
- next if repository and repository != 'all' and repository != r.id
- @packages += r.packages
- end
+ def search_package(str)
+ @selected_repositories.map {|repo| repo.search_package(str)}.flatten
+ end
+
+ # TODO (remove): this is temporary solution for categorizing packages
+ def metagroup_packages(category)
+ res = []
+ grps = groups
+ metagroups[category].to_a.each do |entry|
+ gname = entry[1]
+ cat = categories.find{|t| t[:id] == entry[0]}
+ group = grps.find{|g| g[:id] == gname}
+ next unless cat and cat[:groups].include?(gname) and group
+ next if res.find{|g| g[:name] == gname}
+ res << {:name => gname, :packages => group[:packages].keys}
end
- return @packages
+ res
end
- # TODO: this is temporary solution for categorizing packages
+ # TODO (remove): this is temporary solution for categorizing packages
def metagroups
unless @metagroups
@metagroups = {}
File.readlines('config/image_descriptor_package_metagroups.conf').each do |line|
group, entries_str = line.chomp.split('=')
next unless group and entries_str
- @metagroups[group] = entries_str.split(',')
+ @metagroups[group] = entries_str.split(',').map {|entry| entry.split(';')}
end
end
@metagroups
end
- def metagroup_packages(category, repository = nil)
- res = {}
- groups = all_groups(repository)
- metagroups[category].to_a.each do |entry|
- cat, group = entry.split(';')
- next unless c = categories[cat] and c[:groups].include?(group) and groups[group]
- res[group] = {:packages => groups[group][:packages].keys}
- end
- res
- end
-
- def metagroup_packages_with_tagged_selected_packages(category, pkgs, repository = nil)
- mgroups = metagroup_packages(category, repository)
- mgroups.each_value do |group|
- missing = false
- group[:packages].each do |pkg|
- unless pkgs.find {|p| p[:name] == pkg}
- missing = true
- break
- end
- end
- next if missing
- group[:selected] = true
- end
- mgroups
- end
-
- def all_groups_with_tagged_selected_packages(pkgs, repository = nil)
- groups = all_groups(repository)
- groups.each_value do |group|
- pkgs.each do |pkg|
- next unless p = group[:packages][pkg[:name]]
- p[:selected] = true
- end
- group[:selected] = is_group_selected(group)
- end
- return groups
- end
-
- def repositories_hash
- res = {}
- @repositories.each do |r|
- res[r.id] = r
- end
- res
- end
-
- def search_package(str, repository = nil)
- packages(repository).select {|p| p =~ /#{Regexp.escape(str)}/i}
- end
-
private
- # returns true if all non-optional packages are selected
- # (if there are only non-optional packages in the group,
- # all packages must be selected)
- def is_group_selected(group)
- all = true
- all_nonopt = true
- only_opt = true
- group[:packages].each_value do |pkg|
- all = false unless pkg[:selected]
- if pkg[:type] != 'optional'
- only_opt = false
- if !pkg[:selected]
- all_nonopt = false
- end
- end
- end
- return only_opt ? all : all_nonopt
- end
-
def load_config
YAML.load_file("#{RAILS_ROOT}/config/image_descriptor_package_repositories.yml")
end
@@ -178,4 +100,11 @@ class RepositoryManager
end
return repositories
end
+
+ def get_selected_repositories(repos)
+ return @repositories if repos.blank?
+ repos.map do |repo|
+ @repositories.find {|r| r.id == repo} or raise "repository '#{repo}' not found"
+ end
+ end
end
diff --git a/src/app/util/repository_manager/abstract_repository.rb b/src/app/util/repository_manager/abstract_repository.rb
index 5400ae1..7b73926 100644
--- a/src/app/util/repository_manager/abstract_repository.rb
+++ b/src/app/util/repository_manager/abstract_repository.rb
@@ -8,4 +8,8 @@ class AbstractRepository
@yumurl = conf['yumurl'] || conf['baseurl']
@type = conf['type']
end
+
+ def search_package(what)
+ packages.select {|p| p[:name] =~ /#{Regexp.escape(what)}/i}
+ end
end
diff --git a/src/app/util/repository_manager/comps_repository.rb b/src/app/util/repository_manager/comps_repository.rb
index 6a90f14..494fbac 100644
--- a/src/app/util/repository_manager/comps_repository.rb
+++ b/src/app/util/repository_manager/comps_repository.rb
@@ -19,58 +19,55 @@ class CompsRepository < AbstractRepository
end
def packages
- pkgs = []
- groups.each_value do |g|
- pkgs += g[:packages].keys
- end
- pkgs.uniq
+ @packages ||= load_data[:packages]
end
def prepare_repo
- grps = {}
- @all_pkgs = pkg_names
- group_nodes.each do |g|
- pkgs = group_packages(g)
- next if pkgs.empty?
- name = g.at_xpath('name').text
- id = g.at_xpath('id').text
- grps[id] = {
- :name => name,
+ Dir.mkdir(@cache_dir) unless File.directory?(@cache_dir)
+ File.open(@cache_file, 'w') do |f|
+ Marshal.dump({
+ :packages => get_packages,
+ :groups => get_groups,
+ :categories => get_categories
+ }, f)
+ end
+ end
+
+ private
+
+ def get_packages
+ packages = package_nodes.map do |node|
+ {
+ #:id => node.at_xpath('./xmlns:id/child::text()').text,
+ :name => node.at_xpath('./xmlns:name/child::text()').text,
:repository_id => @id,
- :packages => pkgs
}
end
+ end
- other = {}
- @all_pkgs.each do |pkg, val|
- other[pkg] = {:type => 'optional'} if val != :listed
- end
- if other.size > 0
- name = 'unsorted'
- grps[name] = {
- :name => name,
+ def get_groups
+ group_nodes.map do |g|
+ pkgs = group_packages(g)
+ next if pkgs.empty?
+ {
+ :id => g.at_xpath('id').text,
+ :name => g.at_xpath('name').text,
:repository_id => @id,
- :packages => other
+ :packages => pkgs
}
end
+ end
- categories = {}
- category_nodes.each do |cat|
- id = cat.at_xpath('id').text
- categories[id] = {
+ def get_categories
+ category_nodes.map do |cat|
+ {
+ :id => cat.at_xpath('id').text,
:name => cat.at_xpath('name').text,
:groups => cat.xpath('./grouplist/groupid').map {|g| g.text}
}
end
-
- Dir.mkdir(@cache_dir) unless File.directory?(@cache_dir)
- File.open(@cache_file, 'w') do |f|
- Marshal.dump({:groups => grps, :categories => categories}, f)
- end
end
- private
-
def load_data
unless @load_data
begin
@@ -100,14 +97,9 @@ class CompsRepository < AbstractRepository
xml.xpath('/comps/category')
end
- def pkg_names
- pkgs = {}
+ def package_nodes
xml = Nokogiri::XML(primary_xml)
- xml.xpath('/xmlns:metadata/xmlns:package').each do |node|
- next unless name = node.at_xpath('./xmlns:name/child::text()')
- pkgs[name.text] = true
- end
- return pkgs
+ xml.xpath('/xmlns:metadata/xmlns:package')
end
def download_xml(url)
@@ -146,8 +138,6 @@ class CompsRepository < AbstractRepository
pkgs = {}
group_node.xpath('packagelist/packagereq').each do |p|
pkg_name = p.text
- next unless val = @all_pkgs[pkg_name]
- val = :listed
(pkgs[pkg_name] ||= {})[:type] = p.attr('type')
end
return pkgs
diff --git a/src/app/util/repository_manager/pulp_repository.rb b/src/app/util/repository_manager/pulp_repository.rb
index 051bc47..b232d7f 100644
--- a/src/app/util/repository_manager/pulp_repository.rb
+++ b/src/app/util/repository_manager/pulp_repository.rb
@@ -35,41 +35,36 @@ class PulpRepository < AbstractRepository
end
def groups
- groups = {}
- WrappedRestClient.get(@groups_url, HTTP_OPTS).each do |id, info|
+ WrappedRestClient.get(@groups_url, HTTP_OPTS).map do |id, info|
pkgs = {}
info['default_package_names'].each {|p| pkgs[p] = {:type => 'default'}}
info['optional_package_names'].each {|p| pkgs[p] = {:type => 'optional'}}
info['mandatory_package_names'].each {|p| pkgs[p] = {:type => 'mandatory'}}
next if pkgs.empty?
- name = info['name']
- groups[info['id']] = {
+ {
+ :id => id,
:name => info['name'],
:description => info['description'].to_s,
:repository_id => @id,
:packages => pkgs,
}
- end
- return groups
+ end.compact
end
def categories
- categories = {}
- WrappedRestClient.get(@categories_url, HTTP_OPTS).each do |id, info|
- categories[info['id']] = {
+ WrappedRestClient.get(@categories_url, HTTP_OPTS).map do |id, info|
+ {
+ :id => id,
:name => info['name'],
:groups => info['packagegroupids'],
}
end
- return categories
end
def packages
- packages = []
- WrappedRestClient.get(@packages_url, HTTP_OPTS).each do |info|
- packages << info['name']
+ WrappedRestClient.get(@packages_url, HTTP_OPTS).map do |info|
+ {:name => info['name']}
end
- return packages
end
private
diff --git a/src/app/views/builds/index.haml b/src/app/views/builds/index.haml
new file mode 100644
index 0000000..0d2d5ce
--- /dev/null
+++ b/src/app/views/builds/index.haml
@@ -0,0 +1,89 @@
+- columns = [ |
+ {:name => 'NAME', :sort_attr => 'templates.name'}, |
+ {:name => 'OS', :sort_attr => 'templates.platform'}, |
+ {:name => 'VERSION', :sort_attr => 'templates.platform_version'}, |
+ {:name => 'ARCH', :sort_attr => 'templates.architecture'}, |
+ {:name => 'STATUS', :sort_attr => 'status'}, |
+] |
+
+- form_tag :action => "" do
+ .actionsidebar.grid_3
+ %dl
+ %dt Build Job Actions
+ %dd
+ %h5 JOB QUEUE
+ %ul
+ %li.delete
+ %span
+ = submit_tag "Cancel Job", :name => "job_details", :disabled => true, :class => "icon"
+ %li.show
+ %span
+ = submit_tag "Show Job Details", :name => "job_details", :disabled => true, :class => "icon"
+ %li.show
+ %span
+ = submit_tag "Show Job Log", :name => "job_log", :disabled => true, :class => "icon"
+ %li.clear
+ %span
+ = submit_tag "Clear Job History", :name => "job_history", :disabled => true, :class => "icon"
+
+ .grid_13
+ %h1 Status
+ %section.wrap.status
+ %label.grid_4.alpha Image Warehouse Status:
+ .grid_3.suffix_6.omega
+ %span.good
+ Green
+
+ %label.grid_4.alpha Total Builds in Queue:
+ .grid_3.suffix_6.omega
+ = @running_images.size
+
+ %label.grid_4.alpha Number of VM's Building:
+ .grid_3.suffix_6.omega
+ = @running_images.select {|i| i.status == Image::STATE_BUILDING}.size
+
+ %h1 Running
+
+ %table
+ = sortable_table_header(columns)
+ %tbody
+ - if @running_images.empty?
+ %tr
+ %td{:colspan => 5} No Images
+ - else
+ - @running_images.each do |img|
+ %tr
+ %td= img.template.name
+ %td= img.template.platform
+ %td= img.template.platform_version
+ %td= img.template.architecture
+ %td= img.status
+
+ - unless @failed_images.empty?
+ %h1 Failed
+ %table
+ = sortable_table_header(columns)
+ %tbody
+ - @failed_images.each do |img|
+ %tr
+ %td= img.template.name
+ %td= img.template.platform
+ %td= img.template.platform_version
+ %td= img.template.architecture
+ %td= img.status
+
+ %h1 Completed
+ %table
+ = sortable_table_header(columns)
+ %tbody
+ - if @completed_images.empty?
+ %tr
+ %td{:colspan => 5} No Images
+ - else
+ - @completed_images.each do |img|
+ %tr
+ %td= img.template.name
+ %td= img.template.platform
+ %td= img.template.platform_version
+ %td= img.template.architecture
+ %td OK
diff --git a/src/app/views/builds/new.haml b/src/app/views/builds/new.haml
new file mode 100644
index 0000000..4cddb6f
--- /dev/null
+++ b/src/app/views/builds/new.haml
@@ -0,0 +1,55 @@
+%h2 BUILD REQUEST
+- form_tag :action => 'create' do
+ = hidden_field_tag :template_id, @tpl.id
+ %h3 Deployment Definition
+ %fieldset.clearfix
+ = label_tag :deploy_name, 'Deployment Definition Name:', :class => 'grid_4'
+ = text_field_tag 'deploy_name', 'Deployment Name', :disabled => true, :class => 'grid_3'
+ = text_field_tag 'deploy_description', 'Deployment Description', :disabled => true, :class => 'grid_3'
+ %fieldset.clearfix
+ .prefix_4.grid_6
+ = check_box_tag 'use_for_machine', 1, true, :disabled => true
+ = label_tag 'use_for_machine', 'Use for Machine Definition Name and Description'
+ %fieldset.clearfix
+ .grid_7
+ = file_field :templates, :choose_logo, :value => 'Choose Logo', :disabled => true
+ = text_field :templates, :logo_text, :value => 'Logo Text (5 characters)', :disabled => true, :class => "grid_3"
+
+ %fieldset.clearfix
+ %label.grid_4{:for => :template_group}
+ Template Category:
+ .grid_3
+ = select_tag(:template_group, options_for_select([['User Private', 1]]))
+
+ %h3 Deployment Options
+ %fieldset.clearfix
+ .grid_6
+ %label OS:
+ = @tpl.platform
+ .grid_3
+ Hardware Profile
+ .grid_3.suffix_3
+ Locale
+ %fieldset.clearfix
+ .grid_3
+ %label OS Version:
+ = @tpl.platform_version
+ .grid_3.ra
+ %label Global Settings:
+ .grid_3
+ Small
+ .grid_3
+ Any
+ .grid_3
+ = submit_tag "Config", :name => "config", :disabled => true
+ %h3 Build Options
+ %label Choose Provider Format:
+ %section.clearfix.gap
+ %ul.block
+ - @all_targets.each do |target_id, target|
+ %li
+ = check_box_tag 'targets[]', target_id, false
+ = label_tag 'targets[]', target['name']
+
+ = submit_tag "Submit to Build", :name => "build"
+ = submit_tag "Cancel", :name => "cancel"
diff --git a/src/app/views/templates/_collections.haml b/src/app/views/templates/_collections.haml
index 4623f6f..98ce959 100644
--- a/src/app/views/templates/_collections.haml
+++ b/src/app/views/templates/_collections.haml
@@ -1,9 +1,8 @@
-= hidden_field_tag :collections, true
-
%ul.collections
- - @collections.keys.sort.each do |id|
+ - @collections.each do |c|
%li
- - selected = @collections[id][:selected] ? true : false
- = check_box_tag 'groups[]', id, selected, {:disabled => selected, :id => "group_#{id}", :class => "#{selected ? 'selected' : ''}"}
- = label_tag "group_#{id}", @collections[id][:name]
+ /- selected = c[:selected] ? true : false
+ - selected = false
+ = check_box_tag 'groups[]', c[:id], selected, {:disabled => selected, :id => "group_#{c[:id]}", :class => "#{selected ? 'selected' : ''}"}
+ = label_tag "group_#{c[:id]}", c[:name]
= render :partial => 'addbuttons'
diff --git a/src/app/views/templates/_form.haml b/src/app/views/templates/_form.haml
new file mode 100644
index 0000000..dff9811
--- /dev/null
+++ b/src/app/views/templates/_form.haml
@@ -0,0 +1,122 @@
+:javascript
+ $(document).ready(function() {
+ var $content_container = $('#managed_content');
+ var $sel_pkg_container = $('#package_selection_list');
+ var $submit = $('#add_software_button');
+ $submit.click(function(e) {
+ e.preventDefault();
+ $submit.hide();
+ var data = {
+ 'packages[]': $("input[name='packages[]']").map(function() {return $(this).val()}).get(),
+ 'repository': $("select[name='tpl[platform]']").val() || ''
+ }
+ var url = '#{url_for :action => 'content_selection', :id => @id}';
+ //$content_container.empty().show();
+ $sel_pkg_container.empty().show().addClass('loading');
+ $sel_pkg_container.load(url, data, function(){
+ $sel_pkg_container.removeClass('loading');
+ var $groups = $('.softwaregroups .disclosure', this);
+ //search
+ $("input[name='package_search']").keypress(function(event) {
+ if (event.keyCode == '13') {
+ event.preventDefault();
+ $("input[name=package_search] ~ button").click();
+ }
+ });
+ $("input[name=package_search] ~ button").click(function(event) {
+ event.preventDefault();
+ var data = {
+ 'packages[]': $("input:text[name='packages[]']").map(function() {return $(this).val()}).get(),
+ 'package_search': $("input[name='package_search']").val(),
+ 'repository': $("select[name='tpl[platform]']").val()
+ };
+ var url = '#{url_for :action => 'search_packages', :id => @id}';
+ $('#metagrouppackages').empty().addClass('loading');
+ $('#metagrouppackages').load(url, data, function() {
+ $('#metagrouppackages').removeClass('loading');
+ });
+ });
+ });
+ });
+ //removing packages from the list
+ $('.remove_package').live('click', function (e) {
+ e.preventDefault();
+ $(this).parent().hide(300, function () {
+ $(this).remove();
+ });
+ });
+ //displaying extended package info and actions
+ $('.dropdown').hide();
+ $('.packagename').live('click', function () {
+ var dropdowncontent = $(this).siblings('.dropdown').html(),
+ $dropdown = $("#dropdown");
+ $('.packagewrap').removeClass('selected');
+ $(this).parent().addClass('selected');
+ $dropdown.empty().html(dropdowncontent).css({
+ 'top': $(this).positionAncestor('#content').top + 17,
+ 'left': $(this).positionAncestor('#content').left - 4
+ }).show();
+ });
+ //catch #content clicks and hide the #dropdown if it's not within it
+ $("#content").click(function (e) {
+ if(!e.target.id === 'dropdown' || !$(e.target).closest("#dropdown").length) {
+ $("#dropdown").hide();
+ $('.packagewrap').removeClass('selected');
+ }
+ });
+ // select correct package repo when we change platform
+ $("select[name='tpl[platform]']").change(function() {
+ if ($submit.is(':hidden')) {
+ $submit.trigger('click');
+ }
+ });
+ // add selected pkgs/groups
+ $('#do_add_software').live('click', function(e) {
+ e.preventDefault();
+ var $button = $(this).clone();
+ var label = "<span id='do_add_software' class='loading fl'>Adding Packages</span>";
+ var url = '#{url_for :action => 'managed_content'}';
+ var new_pkgs = $("input:checked[name='selected_packages[]']").map(function() {return $(this).val()}).get();
+ var old_pkgs = $("input:hidden[name='packages[]']").map(function() {return $(this).val()}).get()
+ var cached_pkgs = $("input:hidden[name='cached_packages[]']").map(function() {return $(this).val()}).get()
+ var data = {
+ 'selected_packages[]': old_pkgs.concat(new_pkgs.concat(cached_pkgs)),
+ 'selected_groups[]': $("input:checked[name='groups[]']").map(function() {return $(this).val()}).get(),
+ 'collections': $("input:hidden[name=collections]").val(),
+ 'template_id' : '#{(a)id.nil? ? nil : @id}'
+ };
+ $(this).replaceWith(label);
+ $('#managed_content').load(url, data, function(){
+ $("input:checked[name='groups[]']").attr('disabled', 'disabled');
+ $("input:checked[name='packages[]']").attr('disabled', 'disabled');
+ // $('#add_software_button').show();
+ $('.dropdown').hide();
+ $('#do_add_software').replaceWith($button);
+ });
+ });
+ // hide sw selection panel
+ $('#cancel_add_software').live('click', function(e) {
+ e.preventDefault();
+ $('#package_selection_list').hide();
+ $('#add_software_button').show();
+ $('.dropdown').hide();
+ });
+ });
+
+= error_messages_for :tpl, :object_name => 'template'
+= render :partial => 'basics'
+= render :partial => 'local_content_to_bundle'
+
+#managed_content
+ = render :partial => 'managed_content'
+
+.clearfix
+ .grid_16.alpha.omega
+ = submit_tag "Add Software", :name => "add_software_form", :id => "add_software_button", :class => "iconbutton"
+
+#package_selection_list{:style => 'display: none'}
+
+= render :partial => 'preboot_configuration'
+
+= submit_tag "Save", :name => "save", :class => "formbutton"
+= submit_tag "Cancel", :name => "cancel", :class => "formbutton"
diff --git a/src/app/views/templates/_hidden_fields.haml b/src/app/views/templates/_hidden_fields.haml
index 3fcab65..5709087 100644
--- a/src/app/views/templates/_hidden_fields.haml
+++ b/src/app/views/templates/_hidden_fields.haml
@@ -1,8 +1,8 @@
-- # the template fields as hidden form inputs
-<input type="hidden" id="id" name="id" value="#{@id}" />
= hidden_field :tpl, :id
= hidden_field :tpl, :name
= hidden_field :tpl, :summary
= hidden_field :tpl, :platform
= hidden_field :tpl, :platform_version
= hidden_field :tpl, :architecture
+- @tpl.packages.each do |p|
+ = hidden_field_tag "packages[]", p, :id => "package_#{p}"
diff --git a/src/app/views/templates/_local_content_to_bundle.haml b/src/app/views/templates/_local_content_to_bundle.haml
new file mode 100644
index 0000000..109ce20
--- /dev/null
+++ b/src/app/views/templates/_local_content_to_bundle.haml
@@ -0,0 +1,21 @@
+%h3.disabled.gap Local Content to Bundle
+%fieldset.clearfix
+ = label_tag :local_bundle_name, 'Local:', :class => "disabled grid_2 alpha"
+ = text_field_tag 'local_bundle_name[]', 'Bundle Name', :disabled => true, :class => "grid_8"
+ .grid_6.omega
+ %button{:type => 'button', :disabled => 'disabled'} Browse
+ %button{:type => 'button', :disabled => 'disabled'} Config
+ %button{:type => 'button', :disabled => 'disabled'} Metadata
+ (
+ %a{:href => '#'} Remove
+ )
+ .grid_2.alpha
+
+ = text_field_tag 'local_bundle_name[]', 'Bundle Name', :disabled => true, :class => "grid_8"
+ .grid_6.omega
+ %button{:type => 'button', :disabled => 'disabled'} Browse
+ %button{:type => 'button', :disabled => 'disabled'} Config
+ %button{:type => 'button', :disabled => 'disabled'} Metadata
+ (
+ %a{:href => '#'} Remove
+ )
diff --git a/src/app/views/templates/_managed_content.haml b/src/app/views/templates/_managed_content.haml
index 86b076f..5b9f13a 100644
--- a/src/app/views/templates/_managed_content.haml
+++ b/src/app/views/templates/_managed_content.haml
@@ -1,20 +1,21 @@
#selected_packages
%h3.gap Managed Content to Bundle
.grid_16.alpha.omega
- - if @selected_packages.empty?
+ - if @tpl.packages.empty?
No selected packages
- else
- - repos = @repository_manager.repositories_hash
- - @selected_packages.sort.each do |pkg|
- - pkg_group = @groups.keys.find {|g| @groups[g][:packages][pkg]}
+ /- repos = @repository_manager.repositories_hash
+ - @tpl.packages.sort.each do |pkg|
+ /- pkg_group = @groups.keys.find {|g| @groups[g][:packages][pkg]}
.packagewrap
%a.packagename{:id => "package_#{pkg}"}=pkg
= hidden_field_tag 'packages[]', pkg, :id => "package_#{pkg}"
= submit_tag "Remove", :name => "remove_package_#{pkg}", :id => "remove_package_#{pkg}", :class => 'remove_package'
.dropdown
- %section
- Repository:
- %label= (pkg_group and repo = repos[@groups[pkg_group][:repository_id]]) ? repo.name.to_s : ' '
+ / we don't display repository for now, it's pretty difficult with current design
+ /%section
+ / Repository:
+ / %label= (pkg_group and repo = repos[@groups[pkg_group][:repository_id]]) ? repo.name.to_s : ' '
%fieldset.nomargin
%button{:disabled => true} Browse
%button{:disabled => true} Config
diff --git a/src/app/views/templates/_metagroup_packages.haml b/src/app/views/templates/_metagroup_packages.haml
index c709f97..3e83d34 100644
--- a/src/app/views/templates/_metagroup_packages.haml
+++ b/src/app/views/templates/_metagroup_packages.haml
@@ -4,16 +4,16 @@
%h4
= "#{@metagroup} Packages"
%ul.metagrouppackages
- - @metagroup_packages.keys.sort.each do |group|
+ - @metagroup_packages.sort {|a, b| a[:name] <=> b[:name]}.each do |group|
%li
- - selected = !@metagroup_packages[group][:selected].nil?
+ - selected = false
%h5
- = check_box_tag 'groups[]', group, selected, {:disabled => selected, :id => "group_#{group}", :class => "softwaregroups #{selected ? 'selected' : ''}"}
- = label_tag "group_#{group}", group
+ = check_box_tag 'selected_groups[]', group[:id], selected, {:disabled => selected, :id => "group_#{group[:id]}", :class => "softwaregroups #{selected ? 'selected' : ''}"}
+ = label_tag "group_#{group[:id]}", group[:name]
%ul
- - @metagroup_packages[group][:packages].each do |pkg|
+ - group[:packages].each do |pkg|
%li
- selected = @packages.to_a.find {|p| p[:name] == pkg}
- = check_box_tag 'packages[]', pkg, selected, {:disabled => selected, :id => "pkg_#{group}_#{pkg}"}
- = label_tag "pkg_#{group}_#{pkg}", pkg
+ = check_box_tag 'selected_packages[]', pkg, selected, {:disabled => selected, :id => "pkg_#{group[:name]}_#{pkg}"}
+ = label_tag "pkg_#{group[:name]}_#{pkg}", pkg
= render :partial => 'addbuttons'
diff --git a/src/app/views/templates/_metagroups.haml b/src/app/views/templates/_metagroups.haml
new file mode 100644
index 0000000..b4fcf3f
--- /dev/null
+++ b/src/app/views/templates/_metagroups.haml
@@ -0,0 +1,13 @@
+%fieldset.clearfix
+ .search.grid_4.alpha
+ %input{:type => "search", :placeholder => "Search for package", :name => 'package_search', :value => params[:package_search], :id => 'package_search'}
+ %button.action{:id => 'package_search_button'}
+ .grid_8
+ %a.grid_4.omega Advanced Search
+
+%ul.metagroups{:class => 'packagegroupsidebar grid_4 alpha'}
+ %li
+ = submit_tag 'Collections', :name => 'collections', :id => 'collections', :class => 'icon'
+ - @metagroups.keys.sort.each do |cat|
+ %li
+ = submit_tag cat, :name => "metagroup_packages", :class => 'icon'
diff --git a/src/app/views/templates/_preboot_configuration.haml b/src/app/views/templates/_preboot_configuration.haml
new file mode 100644
index 0000000..79ae839
--- /dev/null
+++ b/src/app/views/templates/_preboot_configuration.haml
@@ -0,0 +1,11 @@
+%h3.clear.gap Preboot Configuration
+%fieldset.clearfix
+ .grid_4.alpha
+ = radio_button_tag :configure_via_script, 'no', :disabled => true
+ = label_tag :configure_via_script, 'Configure Via Script'
+ = file_field_tag 'script_file', :disabled => true, :class => 'grid_12 omega'
+%fieldset.clearfix
+ .grid_4.alpha
+ = radio_button_tag :configure_via_script, 'no', :disabled => true
+ = label_tag :configure_via_script, 'Configure Via Script'
+ = file_field_tag 'script_file', :disabled => true, :class => 'grid_12 omega'
diff --git a/src/app/views/templates/_search_packages.haml b/src/app/views/templates/_search_packages.haml
new file mode 100644
index 0000000..873f2ab
--- /dev/null
+++ b/src/app/views/templates/_search_packages.haml
@@ -0,0 +1,45 @@
+:javascript
+ $(document).ready(function() {
+ $('.pagination input[type=submit]').click(function(e) {
+ e.preventDefault();
+ var url = '#{url_for :action => 'dispatch', :id => @id}';
+ var old_pkgs = $("input:hidden[name='cached_packages[]']").map(function() {return $(this).val()}).get();
+ var new_pkgs = $("input:checked[name='selected_packages[]']").map(function() {return $(this).val()}).get();
+ var data = {
+ 'selected_packages[]': $("input:hidden[name='packages[]']").map(function() {return $(this).val()}).get(),
+ 'cached_packages[]': old_pkgs.concat(new_pkgs),
+ 'selected_groups[]': $("input:checked[name='groups[]']").map(function() {return $(this).val()}).get(),
+ 'package_search': $("input[name='package_search']").val(),
+ 'old_page': '#{@page}',
+ 'template_id' : '#{(a)id.nil? ? nil : @id}',
+ 'page': $(this).val(),
+ 'repository': $("select[name='tpl[platform]']").val()
+ };
+ $('#metagrouppackages').empty().addClass('loading');
+ $('#metagrouppackages').load(url, data, function() {
+ $('#metagrouppackages').removeClass('loading');
+ })
+ });
+ });
+
+- @cached_packages.uniq.each do |pkg|
+ = hidden_field_tag 'cached_packages[]', pkg
+
+- if params[:package_search].empty?
+ Search string is empty.
+-else
+ %h4
+ = "Search Results for '#{params[:package_search]}'"
+ %ul.searchedpackages
+ - @searched_packages.sort {|a, b| a [:name] <=> b[:name]}.each do |pkg|
+ %li
+ - selected = (@packages.to_a.find {|p| p[:name] == pkg[:name]} or @cached_packages.include?(pkg[:name]))
+ - disabled = @tpl.packages.include?(pkg[:name])
+ = check_box_tag 'selected_packages[]', pkg[:name], selected, {:disabled => disabled, :id => "pkg_#{pkg[:name]}"}
+ = label_tag "pkg_#{pkg[:name]}", pkg[:name]
+ .pageinfo
+ = page_entries_info @searched_packages, :entry_name => 'package'
+ = will_paginate @searched_packages, :params => {:package_search => params[:package_search]}, :renderer => TemplatesHelper::ButtonPaginationRenderer.new, :previous_label => 'Previous', :next_label => 'Next'
+
+
+ = render :partial => 'addbuttons'
diff --git a/src/app/views/templates/_searched_packages.haml b/src/app/views/templates/_searched_packages.haml
deleted file mode 100644
index 6533f1a..0000000
--- a/src/app/views/templates/_searched_packages.haml
+++ /dev/null
@@ -1,43 +0,0 @@
-:javascript
- $(document).ready(function() {
- $('.pagination input[type=submit]').click(function(e) {
- e.preventDefault();
- var url = '#{url_for :action => 'dispatch', :id => @id}';
- var old_pkgs = $("input:hidden[name='cached_packages[]']").map(function() {return $(this).val()}).get();
- var new_pkgs = $("input:checked[name='packages[]']").map(function() {return $(this).val()}).get();
- var data = {
- 'selected_packages[]': $("input:hidden[name='packages[]']").map(function() {return $(this).val()}).get(),
- 'cached_packages[]': old_pkgs.concat(new_pkgs),
- 'selected_groups[]': $("input:checked[name='groups[]']").map(function() {return $(this).val()}).get(),
- 'package_search': $("input[name='package_search']").val(),
- 'old_page': '#{@page}',
- 'template_id' : '#{(a)id.nil? ? nil : @id}',
- 'page': $(this).val(),
- 'repository': $("select[name='tpl[platform]']").val()
- };
- $('#metagrouppackages').empty().addClass('loading');
- $('#metagrouppackages').load(url, data, function() {
- $('#metagrouppackages').removeClass('loading');
- Aggregator.hook_selected_packages();
- })
- });
- });
-
-- @cached_packages.uniq.each do |pkg|
- = hidden_field_tag 'cached_packages[]', pkg
-
-%h4
- = "Search Results for '#{params[:package_search]}'"
-%ul.searchedpackages
- - @searched_packages.sort.each do |pkg|
- %li
- - selected = (@packages.to_a.find {|p| p[:name] == pkg} or @cached_packages.include?(pkg))
- - disabled = params[:selected_packages].to_a.include?(pkg)
- = check_box_tag 'packages[]', pkg, selected, {:disabled => disabled, :id => "pkg_#{pkg}"}
- = label_tag "pkg_#{pkg}", pkg
-.pageinfo
- = page_entries_info @searched_packages, :entry_name => 'package'
-= will_paginate @searched_packages, :params => {:package_search => params[:package_search]}, :renderer => TemplatesHelper::ButtonPaginationRenderer.new, :previous_label => 'Previous', :next_label => 'Next'
-
-
-= render :partial => 'addbuttons'
diff --git a/src/app/views/templates/_software_selection.haml b/src/app/views/templates/_software_selection.haml
new file mode 100644
index 0000000..79bbe1e
--- /dev/null
+++ b/src/app/views/templates/_software_selection.haml
@@ -0,0 +1,39 @@
+:javascript
+ $(document).ready(function() {
+ var $metagrouppackages = $('#metagrouppackages');
+ $('.metagroups input').click(function(e) {
+ e.preventDefault();
+ var data = {
+ 'repository': $("select[name='tpl[platform]']").val(),
+ 'packages[]': $("input:hidden[name='packages[]']").map(function() {return $(this).val()}).get()
+ };
+ if ($(this).attr('name') == 'collections') {
+ var url = '#{url_for :action => 'collections', :id => @id}';
+ } else {
+ var url = '#{url_for :action => 'metagroup_packages', :id => @id}';
+ data.metagroup_packages = e.currentTarget.value;
+ }
+ $metagrouppackages.empty().addClass('loading');
+ $metagrouppackages.load(url, data, function() {
+ $metagrouppackages.removeClass('loading');
+ //select all packages in collection
+ $(".softwaregroups").click(function() {
+ if ($(this).attr("checked") === true) {
+ $(this).parent().siblings("ul").find("input[type='checkbox']").attr("checked","checked");
+ } else {
+ $(this).parent().siblings("ul").find("input[type='checkbox']").removeAttr("checked");
+ }
+ });
+ });
+ });
+ });
+
+.grid_16
+ %h4 Managed Content Selection
+
+ - form_tag :action => 'dispatch' do
+ - unless request.xhr?
+ = render :partial => 'hidden_fields'
+ = render :partial => 'metagroups'
+ #metagrouppackages.grid_12.omega.gap
+ = render :partial => view
diff --git a/src/app/views/templates/build_form.haml b/src/app/views/templates/build_form.haml
deleted file mode 100644
index 7084f39..0000000
--- a/src/app/views/templates/build_form.haml
+++ /dev/null
@@ -1,55 +0,0 @@
-%h2 BUILD REQUEST
-- form_tag :action => 'build' do
- = hidden_field_tag :template_id, @tpl.id
- %h3 Deployment Definition
- %fieldset.clearfix
- = label_tag :deploy_name, 'Deployment Definition Name:', :class => 'grid_4'
- = text_field_tag 'deploy_name', 'Deployment Name', :disabled => true, :class => 'grid_3'
- = text_field_tag 'deploy_description', 'Deployment Description', :disabled => true, :class => 'grid_3'
- %fieldset.clearfix
- .prefix_4.grid_6
- = check_box_tag 'use_for_machine', 1, true, :disabled => true
- = label_tag 'use_for_machine', 'Use for Machine Definition Name and Description'
- %fieldset.clearfix
- .grid_7
- = file_field :templates, :choose_logo, :value => 'Choose Logo', :disabled => true
- = text_field :templates, :logo_text, :value => 'Logo Text (5 characters)', :disabled => true, :class => "grid_3"
-
- %fieldset.clearfix
- %label.grid_4{:for => :template_group}
- Template Category:
- .grid_3
- = select_tag(:template_group, options_for_select([['User Private', 1]]))
-
- %h3 Deployment Options
- %fieldset.clearfix
- .grid_6
- %label OS:
- = @tpl.platform
- .grid_3
- Hardware Profile
- .grid_3.suffix_3
- Locale
- %fieldset.clearfix
- .grid_3
- %label OS Version:
- = @tpl.platform_version
- .grid_3.ra
- %label Global Settings:
- .grid_3
- Small
- .grid_3
- Any
- .grid_3
- = submit_tag "Config", :name => "config", :disabled => true
- %h3 Build Options
- %label Choose Provider Format:
- %section.clearfix.gap
- %ul.block
- - @all_targets.each do |target_id, target|
- %li
- = check_box_tag 'targets[]', target_id, false
- = label_tag 'targets[]', target['name']
-
- = submit_tag "Submit to Build", :name => "build"
- = submit_tag "Cancel", :name => "cancel"
diff --git a/src/app/views/templates/builds.haml b/src/app/views/templates/builds.haml
deleted file mode 100644
index 0d2d5ce..0000000
--- a/src/app/views/templates/builds.haml
+++ /dev/null
@@ -1,89 +0,0 @@
-- columns = [ |
- {:name => 'NAME', :sort_attr => 'templates.name'}, |
- {:name => 'OS', :sort_attr => 'templates.platform'}, |
- {:name => 'VERSION', :sort_attr => 'templates.platform_version'}, |
- {:name => 'ARCH', :sort_attr => 'templates.architecture'}, |
- {:name => 'STATUS', :sort_attr => 'status'}, |
-] |
-
-- form_tag :action => "" do
- .actionsidebar.grid_3
- %dl
- %dt Build Job Actions
- %dd
- %h5 JOB QUEUE
- %ul
- %li.delete
- %span
- = submit_tag "Cancel Job", :name => "job_details", :disabled => true, :class => "icon"
- %li.show
- %span
- = submit_tag "Show Job Details", :name => "job_details", :disabled => true, :class => "icon"
- %li.show
- %span
- = submit_tag "Show Job Log", :name => "job_log", :disabled => true, :class => "icon"
- %li.clear
- %span
- = submit_tag "Clear Job History", :name => "job_history", :disabled => true, :class => "icon"
-
- .grid_13
- %h1 Status
- %section.wrap.status
- %label.grid_4.alpha Image Warehouse Status:
- .grid_3.suffix_6.omega
- %span.good
- Green
-
- %label.grid_4.alpha Total Builds in Queue:
- .grid_3.suffix_6.omega
- = @running_images.size
-
- %label.grid_4.alpha Number of VM's Building:
- .grid_3.suffix_6.omega
- = @running_images.select {|i| i.status == Image::STATE_BUILDING}.size
-
- %h1 Running
-
- %table
- = sortable_table_header(columns)
- %tbody
- - if @running_images.empty?
- %tr
- %td{:colspan => 5} No Images
- - else
- - @running_images.each do |img|
- %tr
- %td= img.template.name
- %td= img.template.platform
- %td= img.template.platform_version
- %td= img.template.architecture
- %td= img.status
-
- - unless @failed_images.empty?
- %h1 Failed
- %table
- = sortable_table_header(columns)
- %tbody
- - @failed_images.each do |img|
- %tr
- %td= img.template.name
- %td= img.template.platform
- %td= img.template.platform_version
- %td= img.template.architecture
- %td= img.status
-
- %h1 Completed
- %table
- = sortable_table_header(columns)
- %tbody
- - if @completed_images.empty?
- %tr
- %td{:colspan => 5} No Images
- - else
- - @completed_images.each do |img|
- %tr
- %td= img.template.name
- %td= img.template.platform
- %td= img.template.platform_version
- %td= img.template.architecture
- %td OK
diff --git a/src/app/views/templates/collections.haml b/src/app/views/templates/collections.haml
new file mode 100644
index 0000000..a899c85
--- /dev/null
+++ b/src/app/views/templates/collections.haml
@@ -0,0 +1 @@
+= render :partial => 'software_selection', :locals => {:view => 'collections'}
diff --git a/src/app/views/templates/content_selection.haml b/src/app/views/templates/content_selection.haml
deleted file mode 100644
index 689c33d..0000000
--- a/src/app/views/templates/content_selection.haml
+++ /dev/null
@@ -1,56 +0,0 @@
-:javascript
- $(document).ready(function() {
- var $metagrouppackages = $('#metagrouppackages');
- $('.metagroups input[name="show_metagroup"]').click(function(e) {
- e.preventDefault();
- var data = {
- 'show_metagroup': e.currentTarget.value,
- 'repository': $("select[name='tpl[platform]']").val(),
- 'packages[]': $("input:hidden[name='packages[]']").map(function() {return $(this).val()}).get()
- };
- var url = '#{url_for :action => 'dispatch', :id => @id}';
- $metagrouppackages.empty().addClass('loading');
- $metagrouppackages.load(url, data, function() {
- $metagrouppackages.removeClass('loading');
- Aggregator.hook_selected_packages();
- //select all packages in collection
- $(".softwaregroups").click(function() {
- if ($(this).attr("checked") === true) {
- $(this).parent().siblings("ul").find("input[type='checkbox']").attr("checked","checked");
- } else {
- $(this).parent().siblings("ul").find("input[type='checkbox']").removeAttr("checked");
- }
- });
- });
- });
- Aggregator.hook_selected_packages();
- });
-
-.grid_16
- %h4 Managed Content Selection
-
- - form_tag :action => "dispatch" do
- - unless @embed
- = render :partial => 'hidden_fields'
- - @packages.each do |p|
- <input type="hidden" id="selected_package_#{p[:name]}" name="selected_packages[]" value="#{p[:name]}" />
- %fieldset.clearfix
- .search.grid_4.alpha
- %input{:type => "search", :placeholder => "Search for package", :name => 'package_search', :value => params[:package_search]}
- %button.action
- .grid_8
- %a.grid_4.omega Advanced Search
-
- %ul.metagroups{:class => 'packagegroupsidebar grid_4 alpha'}
- %li
- = submit_tag 'Collections', :name => 'show_metagroup', :id => 'collections', :class => 'icon'
- - @metagroups.keys.sort.each do |cat|
- %li
- = submit_tag cat, :name => "show_metagroup", :class => 'icon'
- #metagrouppackages.grid_12.omega.gap
- - if @collections
- = render :partial => 'collections'
- - elsif @searched_packages
- = render :partial => 'searched_packages'
- - else
- = render :partial => 'metagroup_packages'
diff --git a/src/app/views/templates/edit.haml b/src/app/views/templates/edit.haml
new file mode 100644
index 0000000..a2fece4
--- /dev/null
+++ b/src/app/views/templates/edit.haml
@@ -0,0 +1,6 @@
+#dropdown
+.grid_16
+ %h2 Edit Template
+ - form_for @tpl, :url => {:action => 'dispatch'} do
+ = hidden_field_tag :id, @tpl.id
+ = render :partial => 'form'
diff --git a/src/app/views/templates/index.haml b/src/app/views/templates/index.haml
index 0d4c515..38b32de 100644
--- a/src/app/views/templates/index.haml
+++ b/src/app/views/templates/index.haml
@@ -1,4 +1,4 @@
-- form_tag(:action => 'action') do
+- form_tag(:action => 'index_action') do
.actionsidebar.grid_3
%dl
%dt Actions
diff --git a/src/app/views/templates/metagroup_packages.haml b/src/app/views/templates/metagroup_packages.haml
new file mode 100644
index 0000000..9703663
--- /dev/null
+++ b/src/app/views/templates/metagroup_packages.haml
@@ -0,0 +1 @@
+= render :partial => 'software_selection', :locals => {:view => 'metagroup_packages'}
diff --git a/src/app/views/templates/new.haml b/src/app/views/templates/new.haml
index 669babb..9ae8525 100644
--- a/src/app/views/templates/new.haml
+++ b/src/app/views/templates/new.haml
@@ -1,161 +1,5 @@
-:javascript
- $(document).ready(function() {
- var $content_container = $('#managed_content');
- var $sel_pkg_container = $('#package_selection_list');
- var $submit = $('#add_software_button');
- $submit.click(function(e) {
- e.preventDefault();
- $submit.hide();
- var data = {
- 'packages[]': $("input[name='packages[]']").map(function() {return $(this).val()}).get(),
- 'repository': $("select[name='tpl[platform]']").val() || ''
- }
- var url = '#{url_for :action => 'content_selection', :embed => true, :id => @id}';
- //$content_container.empty().show();
- $sel_pkg_container.empty().show().addClass('loading');
- $sel_pkg_container.load(url, data, function(){
- $sel_pkg_container.removeClass('loading');
- var $groups = $('.softwaregroups .disclosure', this);
- //search
- $("input[name='package_search']").keypress(function(event) {
- if (event.keyCode == '13') {
- event.preventDefault();
- $("input[name=package_search] ~ button").click();
- }
- });
- $("input[name=package_search] ~ button").click(function(event) {
- event.preventDefault();
- var data = {
- 'packages[]': $("input:text[name='packages[]']").map(function() {return $(this).val()}).get(),
- 'package_search': $("input[name='package_search']").val(),
- 'repository': $("select[name='tpl[platform]']").val()
- };
- var url = '#{url_for :action => 'dispatch', :id => @id}';
- $('#metagrouppackages').empty().addClass('loading');
- $('#metagrouppackages').load(url, data, function() {
- $('#metagrouppackages').removeClass('loading');
- Aggregator.hook_selected_packages();
- });
- });
- });
- });
- //removing packages from the list
- $('.remove_package').live('click', function (e) {
- e.preventDefault();
- $(this).parent().hide(300, function () {
- $(this).remove();
- });
- });
- //displaying extended package info and actions
- $('.dropdown').hide();
- $('.packagename').live('click', function () {
- var dropdowncontent = $(this).siblings('.dropdown').html(),
- $dropdown = $("#dropdown");
- $('.packagewrap').removeClass('selected');
- $(this).parent().addClass('selected');
- $dropdown.empty().html(dropdowncontent).css({
- 'top': $(this).positionAncestor('#content').top + 17,
- 'left': $(this).positionAncestor('#content').left - 4
- }).show();
- });
- //catch #content clicks and hide the #dropdown if it's not within it
- $("#content").click(function (e) {
- if(!e.target.id === 'dropdown' || !$(e.target).closest("#dropdown").length) {
- $("#dropdown").hide();
- $('.packagewrap').removeClass('selected');
- }
- });
- // select correct package repo when we change platform
- $("select[name='tpl[platform]']").change(function() {
- if ($submit.is(':hidden')) {
- $submit.trigger('click');
- }
- });
- Aggregator.hook_selected_packages = function() {
- $('#do_add_software').live('click', function(e) {
- e.preventDefault();
- var $button = $(this).clone();
- var label = "<span id='do_add_software' class='loading fl'>Adding Packages</span>";
- var url = '#{url_for :action => 'managed_content'}';
- var new_pkgs = $("input:checked[name='packages[]']").map(function() {return $(this).val()}).get();
- var old_pkgs = $("input:hidden[name='packages[]']").map(function() {return $(this).val()}).get()
- var cached_pkgs = $("input:hidden[name='cached_packages[]']").map(function() {return $(this).val()}).get()
- var data = {
- 'selected_packages[]': old_pkgs.concat(new_pkgs.concat(cached_pkgs)),
- 'selected_groups[]': $("input:checked[name='groups[]']").map(function() {return $(this).val()}).get(),
- 'cached_packages[]': $("input:text[name='cached[]']").map(function() {return $(this).val()}).get(),
- 'collections': $("input:hidden[name=collections]").val(),
- 'template_id' : '#{(a)id.nil? ? nil : @id}'
- };
- $(this).replaceWith(label);
- $('#managed_content').load(url, data, function(){
- $("input:checked[name='groups[]']").attr('disabled', 'disabled');
- $("input:checked[name='packages[]']").attr('disabled', 'disabled');
- $('#add_software_button').show();
- $('.dropdown').hide();
- $('#do_add_software').replaceWith($button);
- });
- });
- $('#cancel_add_software').click(function(e) {
- e.preventDefault();
- $('#package_selection_list').hide();
- $('#add_software_button').show();
- $('.dropdown').hide();
- });
- }
- });
-
#dropdown
.grid_16
- %h2 Template
- - form_for @tpl, :url => { :action => "dispatch" } do
- <input type="hidden" id="id" name="id" value="#{@id}" />
- = hidden_field :tpl, :id
- = error_messages_for :tpl, :object_name => 'template'
- = render :partial => 'basics'
-
- %h3.disabled.gap Local Content to Bundle
- %fieldset.clearfix
- = label_tag :local_bundle_name, 'Local:', :class => "disabled grid_2 alpha"
- = text_field_tag 'local_bundle_name[]', 'Bundle Name', :disabled => true, :class => "grid_8"
- .grid_6.omega
- %button{:type => 'button', :disabled => 'disabled'} Browse
- %button{:type => 'button', :disabled => 'disabled'} Config
- %button{:type => 'button', :disabled => 'disabled'} Metadata
- (
- %a{:href => '#'} Remove
- )
- .grid_2.alpha
-
- = text_field_tag 'local_bundle_name[]', 'Bundle Name', :disabled => true, :class => "grid_8"
- .grid_6.omega
- %button{:type => 'button', :disabled => 'disabled'} Browse
- %button{:type => 'button', :disabled => 'disabled'} Config
- %button{:type => 'button', :disabled => 'disabled'} Metadata
- (
- %a{:href => '#'} Remove
- )
-
- #managed_content
- = render :partial => 'managed_content'
-
- .clearfix
- .grid_16.alpha.omega
- = submit_tag "Add Software", :name => "add_software_form", :id => "add_software_button", :class => "iconbutton"
-
- #package_selection_list{:style => 'display: none'}
-
- %h3.clear.gap Preboot Configuration
- %fieldset.clearfix
- .grid_4.alpha
- = radio_button_tag :configure_via_script, 'no', :disabled => true
- = label_tag :configure_via_script, 'Configure Via Script'
- = file_field_tag 'script_file', :disabled => true, :class => 'grid_12 omega'
- %fieldset.clearfix
- .grid_4.alpha
- = radio_button_tag :configure_via_script, 'no', :disabled => true
- = label_tag :configure_via_script, 'Configure Via Script'
- = file_field_tag 'script_file', :disabled => true, :class => 'grid_12 omega'
-
- = submit_tag "Save", :name => "save", :class => "formbutton"
- = submit_tag "Cancel", :name => "cancel", :class => "formbutton"
+ %h2 New Template
+ - form_for @tpl, :url => {:action => 'dispatch'} do
+ = render :partial => 'form'
diff --git a/src/app/views/templates/search_packages.haml b/src/app/views/templates/search_packages.haml
new file mode 100644
index 0000000..94e30f5
--- /dev/null
+++ b/src/app/views/templates/search_packages.haml
@@ -0,0 +1 @@
+= render :partial => 'software_selection', :locals => {:view => 'search_packages'}
diff --git a/src/config/navigation.rb b/src/config/navigation.rb
index 3b63df1..9f5c8eb 100644
--- a/src/config/navigation.rb
+++ b/src/config/navigation.rb
@@ -30,10 +30,8 @@ SimpleNavigation::Configuration.run do |navigation|
second_level.item :assistance_requests, t(:assistance_requests), '#', :class => 'disabled'
end
first_level.item :define, t(:define), '#', :class => 'build' do |second_level|
- # TODO: currently we exclude /templates/builds (next tab), but
- # we could have special controller for builds in future
- second_level.item :deployables, t(:deployables), {:controller => 'templates'}, :highlights_on => /(\/templates$|\/templates\/(?!builds))/
- second_level.item :builds, t(:builds), :controller => 'templates', :action => 'builds'
+ second_level.item :deployables, t(:deployables), {:controller => 'templates'}, :highlights_on => /\/templates/
+ second_level.item :builds, t(:builds), :controller => 'builds', :action => 'index'
second_level.item :images, t(:images), '#', :class => 'disabled'
end
first_level.item :runtime, t(:runtime), '#', :class => 'runtime' do |second_level|
diff --git a/src/config/routes.rb b/src/config/routes.rb
index f59a2aa..e0672ef 100644
--- a/src/config/routes.rb
+++ b/src/config/routes.rb
@@ -46,7 +46,7 @@ ActionController::Routing::Routes.draw do |map|
map.dashboard '/dashboard', :controller => 'dashboard'
map.instance '/instances', :controller => 'instances'
- map.templates '/templates', :controller => 'templates'
+ # map.templates '/templates', :controller => 'templates'
map.settings '/settings', :controller => 'settings'
map.root :dashboard
@@ -54,6 +54,14 @@ ActionController::Routing::Routes.draw do |map|
# Will be re-enabled in upcoming patch
map.resources :providers
+ map.resources :templates, :collection => { :destroy_multiple => :get },
+ :member => {
+ :assembly => :get,
+ :deployment_definition => :get,
+ :action => :get,
+ }
+ map.resources :builds
+
# Allow downloading Web Service WSDL as a file with an extension
# instead of a file named 'wsdl'
map.connect ':controller/service.wsdl', :action => 'wsdl'
diff --git a/src/features/step_definitions/general_steps.rb b/src/features/step_definitions/general_steps.rb
new file mode 100644
index 0000000..df1f588
--- /dev/null
+++ b/src/features/step_definitions/general_steps.rb
@@ -0,0 +1,3 @@
+Then /^I should see an input "([^\"]*)"$/ do |value|
+ response.should have_selector("form input[value=#{value}]")
+end
diff --git a/src/features/step_definitions/template_steps.rb b/src/features/step_definitions/template_steps.rb
index 65b89c1..894bf0a 100644
--- a/src/features/step_definitions/template_steps.rb
+++ b/src/features/step_definitions/template_steps.rb
@@ -17,8 +17,7 @@ Given /^There is a mock pulp repository$/ do
end
Given /^there is a "([^"]*)" template$/ do |name|
- @template = Factory.build :template
- @template.xml.name = name
+ @template = Factory.build :template, :name => name
@template.save!
end
@@ -27,14 +26,13 @@ Given /^there is a package group$/ do
end
Given /^no package is selected$/ do
- @template.xml.packages = []
+ @template.packages = []
end
Given /^there is one selected package$/ do
pkg = RepositoryManager.new.all_packages.first
- @template.xml.packages = []
- @template.xml.add_package(pkg['name'], nil)
- @template.save_xml!
+ @template.packages = [pkg['name']]
+ @template.save!
end
# "I jump" is used instead of "I am" because "I am" is already defined in
@@ -72,8 +70,7 @@ Then /^I should see "([^"]*)" followed by "([^"]*)"$/ do |arg1, arg2|
end
Given /^there is a "([^"]*)" build$/ do |arg1|
- template = Factory.build :template
- template.xml.name = arg1
+ template = Factory.build :template, :name => arg1
template.save!
image = Factory.build(:image, :template => template)
image.save!
diff --git a/src/features/support/paths.rb b/src/features/support/paths.rb
index e948161..1c73ffa 100644
--- a/src/features/support/paths.rb
+++ b/src/features/support/paths.rb
@@ -66,16 +66,16 @@ module NavigationHelpers
url_for :action => 'new', :controller => 'permissions', :only_path => true
when /the new template page/
- url_for :action => 'new', :controller => 'templates', :only_path => true
+ url_for new_template_path
when /the template builds page/
- url_for :action => 'builds', :controller => 'templates', :only_path => true
+ url_for builds_path
when /the templates page/
templates_path
when /the create template page/
- url_for :action => 'create', :controller => 'templates', :only_path => true
+ url_for create_template_path
when /the self service settings page/
url_for :action => 'self_service', :controller => 'settings', :only_path => true
diff --git a/src/features/template.feature b/src/features/template.feature
index 3404638..4ce0151 100644
--- a/src/features/template.feature
+++ b/src/features/template.feature
@@ -21,27 +21,38 @@ Feature: Manage Templates
And I should see "Template saved"
And I should see "mocktemplate"
- Scenario: Add group and remove package to/from the template
- Given I am on the templates page
- When I press "Template"
- Then I should be on the new template page
- When I fill in the following:
- | tpl_name | mocktemplate |
- And I press "Add Software"
- Then I should see "Managed Content Selection"
- When I press "Collections"
- And I check "group_deltacloud"
+ Scenario: Add a searched package to a new template
+ Given I am on the new template page
+ When I press "Add Software"
+ And I fill in "package_search" with "libdeltacloud"
+ And I press "package_search_button"
+ Then I should see "libdeltacloud"
+ When I check "libdeltacloud"
And I press "Add Selected"
- Then I should see "Managed Content to Bundle"
- And the "tpl[name]" field by name should contain "mocktemplate"
- And the page should contain "#package_libdeltacloud" selector
- When I press "remove_package_libdeltacloud"
- Then I should see "Managed Content to Bundle"
- And the page should not contain "#package_libdeltacloud" selector
- When I press "Save"
- Then I should be on the templates page
- And I should see "Template saved"
- And I should see "mocktemplate"
+ Then I should see "New Template"
+ And I should see "libdeltacloud"
+
+ #Scenario: Add group and remove package to/from the template
+ # Given I am on the templates page
+ # When I press "Template"
+ # Then I should be on the new template page
+ # When I fill in the following:
+ # | tpl_name | mocktemplate |
+ # And I press "Add Software"
+ # Then I should see "Managed Content Selection"
+ # When I press "Collections"
+ # And I check "group_deltacloud"
+ # And I press "Add Selected"
+ # Then I should see "Managed Content to Bundle"
+ # And the "tpl[name]" field by name should contain "mocktemplate"
+ # And the page should contain "#package_libdeltacloud" selector
+ # When I press "remove_package_libdeltacloud"
+ # Then I should see "Managed Content to Bundle"
+ # And the page should not contain "#package_libdeltacloud" selector
+ # When I press "Save"
+ # Then I should be on the templates page
+ # And I should see "Template saved"
+ # And I should see "mocktemplate"
Scenario: Sorting templates
Given there is a "mock1" template
@@ -60,3 +71,19 @@ Feature: Manage Templates
Then I should see "mock1" followed by "mock2"
When I follow "Name"
Then I should see "mock2" followed by "mock1"
+
+ Scenario: Search software with empty string
+ Given I am on the new template page
+ When I press "Add Software"
+ And I fill in "package_search" with ""
+ And I press "package_search_button"
+ Then I should see "Search string is empty"
+
+ Scenario: Show software selection
+ Given I am on the new template page
+ And I press "Add Software"
+ Then I should see an input "Collections"
+ # test that we see a metagroup
+ Then I should see an input "admin-tools"
+ # test that we see a collection (collections are loaded by default)
+ And I should see an input "deltacloud"
diff --git a/src/spec/controllers/builds_controller_spec.rb b/src/spec/controllers/builds_controller_spec.rb
new file mode 100644
index 0000000..ef4f3d4
--- /dev/null
+++ b/src/spec/controllers/builds_controller_spec.rb
@@ -0,0 +1,37 @@
+require 'spec_helper'
+
+describe BuildsController do
+ fixtures :all
+ before(:each) do
+ @admin_permission = Factory :admin_permission
+ @admin = @admin_permission.user
+ @tuser = Factory :tuser
+ activate_authlogic
+ end
+
+ context "when a user has permission to build templates" do
+ #FIXME: The following functionality needs to come out of the controller
+
+ before(:each) do
+ UserSession.create(@admin)
+ @template = Factory.create(:template)
+ hydra = Typhoeus::Hydra.hydra
+ hydra.stub(:put, %r{http://localhost:9090/templates/.*}).and_return(
+ Typhoeus::Response.new(:code => 200))
+ Factory.create(:mock_cloud_account)
+ Factory.create(:mock_provider)
+ end
+
+ it "should create a new Image" do
+ lambda do
+ post :create, :template_id => @template.id, :targets => ["mock"]
+ end.should change(Image, :count).by(1)
+ end
+
+ it "should create a new ReplicatedImage" do
+ lambda do
+ post :create, :template_id => @template.id, :targets => ["mock"]
+ end.should change(ReplicatedImage, :count).by(1)
+ end
+ end
+end
diff --git a/src/spec/controllers/templates_controller_spec.rb b/src/spec/controllers/templates_controller_spec.rb
index 6e23609..0ead1b0 100644
--- a/src/spec/controllers/templates_controller_spec.rb
+++ b/src/spec/controllers/templates_controller_spec.rb
@@ -13,7 +13,7 @@ describe TemplatesController do
it "should allow a user with image_modify permission to create new template" do
UserSession.create(@admin)
lambda do
- post :create, :tpl => { :name => 'template', :platform => 'fedora', :platform_version => '11', :architecture => '64-bit' }
+ post :create, :tpl => { :name => 'template', :platform => 'fedora' }
end.should change(Template, :count).by(1)
response.should redirect_to(templates_path)
end
@@ -23,29 +23,4 @@ describe TemplatesController do
get :new
response.should_not render_template("new")
end
-
- context "when a user has permission to build templates" do
- #FIXME: The following functionality needs to come out of the controller
-
- before(:each) do
- UserSession.create(@admin)
- @template = Factory.create(:template)
- hydra = Typhoeus::Hydra.hydra
- hydra.stub(:put, %r{http://localhost:9090/templates/.*}).and_return(
- Typhoeus::Response.new(:code => 200))
- Factory.create(:mock_cloud_account)
- end
-
- it "should create a new Image" do
- lambda do
- post :build, :template_id => @template.id, :targets => ["mock"]
- end.should change(Image, :count).by(1)
- end
-
- it "should create a new ReplicatedImage" do
- lambda do
- post :build, :template_id => @template.id, :targets => ["mock"]
- end.should change(ReplicatedImage, :count).by(1)
- end
- end
end
diff --git a/src/spec/factories/template.rb b/src/spec/factories/template.rb
index 7130370..0305147 100644
--- a/src/spec/factories/template.rb
+++ b/src/spec/factories/template.rb
@@ -1,25 +1,4 @@
-Factory.sequence :template_name do |n|
- "template#{n}"
-end
-
Factory.define :template do |i|
- i.xml { %Q{
-<image>
- <name>#{Factory.next :template_name}</name>
- <repos>
- <repo>https://localhost/pulp/repos/jboss2</repo>
- </repos>
- <os name="Fedora" version="13" architecture="64-bit"/>
- <description/>
- <services/>
- <groups>
- <group>JBoss Core Packages</group>
- </groups>
- <packages>
- <package><name>jboss-as5</name><group>JBoss Core Packages</group></package>
- <package><name>jboss-jgroups</name><group>JBoss Core Packages</group></package>
- </packages>
-</image>
- }
-}
+ i.sequence(:name) { |n| "template#{n}" }
+ i.platform 'fedora'
end
diff --git a/src/spec/models/template_spec.rb b/src/spec/models/template_spec.rb
index 407657f..406febd 100644
--- a/src/spec/models/template_spec.rb
+++ b/src/spec/models/template_spec.rb
@@ -19,7 +19,7 @@ describe Template do
it "should not be valid if template name is too long" do
t = Factory.build(:template)
- t.xml.name = ('a' * 256)
+ t.name = ('a' * 256)
t.valid?.should be_false
t.errors[:name].should_not be_nil
t.errors[:name].should =~ /^is too long.*/
diff --git a/src/spec/utils/repository_manager_spec.rb b/src/spec/utils/repository_manager_spec.rb
index c2da511..98ff157 100644
--- a/src/spec/utils/repository_manager_spec.rb
+++ b/src/spec/utils/repository_manager_spec.rb
@@ -8,6 +8,8 @@ describe RepositoryManager do
'../fixtures/packagegroups.json'))
@packages_json = File.read(File.join(File.dirname(__FILE__),
'../fixtures/packages.json'))
+ @packagegroupcategories_json = File.read(File.join(File.dirname(__FILE__),
+ '../fixtures/packagegroupcategories.json'))
end
before(:each) do
@@ -18,6 +20,8 @@ describe RepositoryManager do
Typhoeus::Response.new(:code => 200, :body => @packagegroups_json))
hydra.stub(:get, "http://pulptest/repositories/fedora/packages/").and_return(
Typhoeus::Response.new(:code => 200, :body => @packages_json))
+ hydra.stub(:get, "http://pulptest/repositories/fedora/packagegroupcategories/").and_return(
+ Typhoeus::Response.new(:code => 200, :body => @packagegroupcategories_json))
@rmanager = RepositoryManager.new(:config => [{
'baseurl' => 'http://pulptest',
@@ -26,13 +30,23 @@ describe RepositoryManager do
}])
end
- it "should return a list of repositories" do
+ it 'should return a list of repositories' do
@rmanager.repositories.should have(1).items
@rmanager.repositories.first.id.should eql('fedora')
end
- it "should return a list of packagegroups" do
+ it 'should return a list of packagegroups' do
rep = @rmanager.repositories.first
- rep.groups.keys.sort.should == ["deltacloud"]
+ rep.groups.first[:id].should == 'deltacloud'
+ end
+
+ it 'should return a list of categories' do
+ @rmanager.categories.should have(1).items
+ @rmanager.categories.first[:id].should eql('base-system')
+ end
+
+ it "should return a list of packages" do
+ @rmanager.packages.should have(2).items
+ @rmanager.packages.first[:name].should eql('libdeltacloud')
end
end
--
1.7.2.3
13 years, 6 months
[PATCH aggregator] Rename CloudAccount to ProviderAccount.
by lmartinc@redhat.com
This patch is only rebase with new code so you can apply cleanly.
To use this patch you need my previous patch [deltacloud-devel] [PATCH aggregator] Refactor Provider Accounts to have index with list
At least discussion about this patch would be appreciated. ;)
-- Ladislav
13 years, 6 months