[PATCH conductor] Add Build & Push to Deployable Details

tsedovic at redhat.com tsedovic at redhat.com
Fri Dec 2 15:13:50 UTC 2011


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
 
   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
 
-- 
1.7.6.4




More information about the aeolus-devel mailing list