[PATCH conductor] Add Build & Push to Deployable Details
Jan Provazník
jprovazn at redhat.com
Fri Dec 2 16:36:54 UTC 2011
On 12/02/2011 04:13 PM, tsedovic at redhat.com wrote:
> From: Tomas Sedovic<tomas at sedovic.cz>
>
> https://www.aeolusproject.org/redmine/issues/2853
>
> It shows the following states: not built, building, not pushed, pushing,
> pushed. And it allows the user to rebuild and re-push all images.
>
> As things are now, building and pushing is a 2-step operation.
>
> Note that the page isn't styled properly yet.
> ---
> src/app/controllers/deployables_controller.rb | 33 ++++++++++++
> src/app/models/deployable.rb | 70 ++++++++++++++++++++++---
> src/app/views/deployables/show.html.haml | 35 ++++++++-----
> src/config/locales/en.yml | 9 +++
> src/config/routes.rb | 1 +
> 5 files changed, 127 insertions(+), 21 deletions(-)
>
> diff --git a/src/app/controllers/deployables_controller.rb b/src/app/controllers/deployables_controller.rb
> index a1d7f9b..a6457d3 100644
> --- a/src/app/controllers/deployables_controller.rb
> +++ b/src/app/controllers/deployables_controller.rb
> @@ -64,6 +64,21 @@ class DeployablesController< ApplicationController
> flash[:error] = assembly[key] if key.to_s =~ /^error\w+/
> end
> end
> + images = @deployable.fetch_images
> + uuids = @deployable.fetch_image_uuids
> + @missing_images = images.zip(uuids).select{|p| p.first.nil?}.map{|p| p.second}
> + return unless @missing_images.empty?
> +
> + @build_results = {}
> + ProviderAccount.list_for_user(current_user, Privilege::VIEW).each do |account|
> + type = account.provider.provider_type.deltacloud_driver
> + @build_results[type] ||= []
> + @build_results[type]<< {
> + :account => account.label,
> + :provider => account.provider.name,
> + :status => @deployable.build_status(images, account),
> + }
> + end
> end
>
> def create
> @@ -171,6 +186,24 @@ class DeployablesController< ApplicationController
> redirect_to original_path.merge(original_params).merge("catalog_entries_preset_filter" => params[:catalog_entries_preset_filter], "catalog_entries_search" => params[:catalog_entries_search])
> end
>
> + def build
> + catalog = Catalog.find(params[:catalog_id])
> + deployable = Deployable.find(params[:deployable_id])
> + require_privilege(Privilege::MODIFY, catalog)
> + require_privilege(Privilege::MODIFY, deployable)
> +
> + images = deployable.fetch_images
> + accounts = ProviderAccount.list_for_user(current_user, Privilege::VIEW)
> + options = params[:build_options].to_sym
> + case options
> + when :build_missing
> + deployable.build_missing(images, accounts)
> + when :push_missing
> + deployable.push_missing(images, accounts)
> + end
> + redirect_to catalog_deployable_path(catalog, deployable)
> + end
> +
> private
>
> def set_header
> diff --git a/src/app/models/deployable.rb b/src/app/models/deployable.rb
> index 2a568ac..ac68454 100644
> --- a/src/app/models/deployable.rb
> +++ b/src/app/models/deployable.rb
> @@ -60,13 +60,8 @@ class Deployable< ActiveRecord::Base
>
> # Round up Catalog Entries, fetch their Deployables, and extract image UUIDs.
> def fetch_images
> - images = []
> - unless fetch_image_uuids.nil?
> - fetch_image_uuids.each do |uuid|
> - images<< Aeolus::Image::Warehouse::Image.find(uuid)
> - end
> - return images.compact.uniq
> - end
> + uuids = fetch_image_uuids || []
> + uuids.map { |uuid| Aeolus::Image::Warehouse::Image.find(uuid) }
> end
^ since this method now returns nil values too, handle nil value where
it's called from:
app/models/pool.rb
app/views/deployments/launch_from_catalog.html.haml
>
> def fetch_image_uuids
> @@ -143,6 +138,66 @@ class Deployable< ActiveRecord::Base
> result_array
> end
>
> + def build_status(images, account)
> + image_statuses = images.map { |i| image_status(i, account) }
> + return :not_built if image_statuses.any? { |status| status == :not_built }
> + return :building if image_statuses.any? { |status| status == :building }
> + return :pushing if image_statuses.any? { |status| status == :pushing }
> + return :not_pushed if image_statuses.any? { |status| status == :not_pushed }
> + :pushed
> + end
> +
> + def image_status(image, account)
> + build = image.latest_pushed_or_unpushed_build
> + target = account.provider.provider_type.deltacloud_driver
> + return :not_built unless build
> +
> + builder = Aeolus::Image::Factory::Builder.first
> + return :building if builder.find_active_build(build.id, target)
> +
> + target_image = build.target_images.find { |ti| ti.target == target }
> + return :not_built unless target_image
> +
> + return :pushing if builder.find_active_push(target_image.id,
> + account.provider.name,
> + account.credentials_hash["username"])
> +
> + provider_image = target_image.find_provider_image_by_provider_and_account(
> + account.provider.name, account.warehouse_id).first
> + return :not_pushed unless provider_image
> + :pushed
> + end
> +
> + def build_missing(images, accounts)
> + targets = accounts.map { |acc| acc.provider.provider_type.deltacloud_driver }.uniq.join(',')
> + images.each do |image|
> + factory_image = Aeolus::Image::Factory::Image.new(:id => image.id)
> + factory_image.targets = targets
> + factory_image.template = image.template
> + factory_image.save!
> + end
> + end
> +
> + def push_missing(images, accounts)
> + images.each do |image|
> + accounts.each do |account|
> + if image_status(image, account) == :not_pushed
> + target = account.provider.provider_type.deltacloud_driver
> + build = image.latest_pushed_or_unpushed_build
> + target_image = build.target_images.find { |ti| ti.target == target }
> + provider_image = Aeolus::Image::Factory::ProviderImage.new(
> + :provider => account.provider.name,
> + :credentials => account.to_xml(:with_credentials => true),
> + :image_id => image.uuid,
> + :build_id => build.uuid,
> + :target_image_id => target_image.uuid
> + )
> + provider_image.save!
> + end
> + end
> + end
> + end
> +
> private
>
> def self.apply_search_filter(search)
> @@ -152,5 +207,4 @@ class Deployable< ActiveRecord::Base
> scoped
> end
> end
> -
> end
> diff --git a/src/app/views/deployables/show.html.haml b/src/app/views/deployables/show.html.haml
> index e09f4bf..6a8576a 100644
> --- a/src/app/views/deployables/show.html.haml
> +++ b/src/app/views/deployables/show.html.haml
> @@ -39,19 +39,28 @@
> %header
> %h2= t('.build')
>
> - = form_tag() do
> - = select_tag :build_option, options_for_select([[t("rebuild_all"), 1]])
> - = submit_tag t('.start'), :id => :start_build
> + - if @missing_images.empty?
> + = form_tag(catalog_deployable_build_path(@catalog, @deployable)) do
> + = select_tag :build_options, options_for_select([[t(".build_missing"), :build_missing], [t(".push_missing"), :push_missing]])
> + = submit_tag t('.start'), :id => :start_build
>
> - %p.description= t('.build_description')
> + %p.description= t('.build_description')
>
> - %ul#providers-list
> - - @providers.each do |provider|
> - %li
> - %span.provider= provider.name
> - %span.status Building 98%
> - -#= form_tag()
> - -# %button on/off
> + %ul#providers-list
> + - @build_results.each do |provider_type, results|
> + %li
> + = provider_type
> + %ul
> + - results.each do |result|
> + %li
> + %span.provider= result[:provider]
> + %span.account= result[:account]
> + %span.status= result[:status]
> + - else
> + %h3= t('.missing_images')
> + %ul#missing-images-list
> + - @missing_images.each do |uuid|
> + %li= uuid
>
>
> %section.catalogs
> diff --git a/src/config/locales/en.yml b/src/config/locales/en.yml
> index e45d743..2819ce6 100644
> --- a/src/config/locales/en.yml
> +++ b/src/config/locales/en.yml
> @@ -783,6 +783,15 @@ en:
> not_deleted:
> one: "Deployable %{list} was not deleted. There are deployments associated with it."
> other: "Deployables %{list} were not deleted. They have deployments associated with them."
> + show:
> + build: Build
> + build_description:
> + "Allow this deployable's associated image(s) to be built and pushed to
> + providers by enabling them below."
> + start: Start
> + rebuild_all: Build missing images
> + push_all: Push missing images
> + missing_images: Images missing from the Image Warehouse
> flash:
> error:
> attribute_not_exist: "Some attribute(s) is missing in XML, please check the file!"
> diff --git a/src/config/routes.rb b/src/config/routes.rb
> index 7a7df6e..b07ba9e 100644
> --- a/src/config/routes.rb
> +++ b/src/config/routes.rb
> @@ -205,6 +205,7 @@ Conductor::Application.routes.draw do
> resources :deployables do
> delete 'multi_destroy', :on => :collection
> post :filter, :on => :collection
> + post :build
> end
> end
>
Hi Tomas,
code looks good, works for me. Conditional ACK - see inline note.
As we discussed on IRC: optional build_id param in deployable XML is
ignored for now, will be fixed later.
Great work, Jan
More information about the aeolus-devel
mailing list