[PATCH conductor] BZ773034: Autoupdate for images#show (rev. 3)
Petr Blaho
pblaho at redhat.com
Wed Feb 1 11:51:02 UTC 2012
On Monday, January 30, 2012 02:11:58 PM ifarkas at redhat.com wrote:
> From: Imre Farkas <ifarkas at redhat.com>
>
> Rebased it once again.
> Note: it depends on my previous patchset "BZ781482: feedback for image build/push failures".
>
> https://bugzilla.redhat.com/show_bug.cgi?id=773034
> ---
> src/app/controllers/images_controller.rb | 53 ++++++++++++++
> src/app/models/provider_account.rb | 6 ++
> src/app/views/images/show.html.haml | 105 ++++++++++++++++++++++++++++
> src/public/javascripts/application.js | 32 +++++++++
> src/public/javascripts/backbone/models.js | 8 ++
> src/public/javascripts/backbone/routers.js | 19 +++++
> src/public/javascripts/backbone/views.js | 45 ++++++------
> 7 files changed, 245 insertions(+), 23 deletions(-)
>
> diff --git a/src/app/controllers/images_controller.rb b/src/app/controllers/images_controller.rb
> index 41c48a5..997ab6a 100644
> --- a/src/app/controllers/images_controller.rb
> +++ b/src/app/controllers/images_controller.rb
> @@ -60,6 +60,59 @@ class ImagesController < ApplicationController
> load_builds
> load_target_images(@build)
> flash[:error] = t("images.flash.error.no_provider_accounts") if @account_groups.size == 0
> +
> + respond_to do |format|
> + format.html
> + format.json do
> + active_builds = @account_groups.keys.inject({}) do |result, driver|
> + result[driver] = @builder.find_active_build(@build.id, driver) if @build
> + result
> + end
> +
> + active_pushes = @account_groups.inject({}) do |result, (driver, group)|
> + timg = @target_images_by_target[driver]
> + group[:accounts].each do |account|
> + result[account.id] = @builder.find_active_push(timg.id, account.provider.name, account.credentials_hash['username'])
> + end if timg.present?
> +
> + result
> + end
> +
> + provider_images = @account_groups.inject({}) do |result, (driver, group)|
> + timg = @target_images_by_target[driver]
> + group[:accounts].each do |account|
> + result[account.id] = timg.find_provider_image_by_provider_and_account(account.provider.name, account.credentials_hash['username']).first
> + end if timg.present?
> +
> + result
> + end
> +
> + failed_build_counts = @account_groups.keys.inject({}) do |result, driver|
> + result[driver] = @builder.failed_build_count(@build.id, driver) if @build
> + result
> + end
> +
> + failed_push_counts = @account_groups.inject({}) do |result, (driver, group)|
> + timg = @target_images_by_target[driver]
> + group[:accounts].each do |account|
> + result[account.id] = @builder.failed_push_count(timg.id, account.provider.name, account.credentials_hash['username'])
> + end if timg.present?
> +
> + result
> + end
> +
> + render :json => { :image => @image,
> + :build => @build,
> + :account_groups => @account_groups,
> + :provider_images => provider_images,
> + :target_images_by_target => @target_images_by_target,
> + :active_builds => active_builds,
> + :active_pushes => active_pushes,
> + :failed_build_counts => failed_build_counts,
> + :failed_push_counts => failed_push_counts,
> + :latest_build_id => @latest_build }
> + end
> + end
> end
>
> def rebuild_all
> diff --git a/src/app/models/provider_account.rb b/src/app/models/provider_account.rb
> index e772f52..153a910 100644
> --- a/src/app/models/provider_account.rb
> +++ b/src/app/models/provider_account.rb
> @@ -150,6 +150,12 @@ class ProviderAccount < ActiveRecord::Base
> label.blank? ? credentials_hash['username'] : label
> end
>
> + def as_json(options={})
> + super(options).merge({
> + :provider_name => provider.name
> + })
> + end
> +
> def populate_profiles_and_validate
> begin
> populate_hardware_profiles
> diff --git a/src/app/views/images/show.html.haml b/src/app/views/images/show.html.haml
> index 0667aa9..3f47973 100644
> --- a/src/app/views/images/show.html.haml
> +++ b/src/app/views/images/show.html.haml
> @@ -91,3 +91,108 @@
> $("#seletect_build_button").click();
> });
> });
> +
> +%script#imageBuildsTemplate{ :type => 'text/x-jquery-tmpl' }
> + :plain
> + {{each(driver, groups) account_groups}}
> + <li>
> + <dl>
> + <dt>
> + <h3>${groups['type']['name']}</h3>
> + {{if build && active_builds[driver]}}
> + <label>${active_builds[driver]['status']}</label>
> + {{else target_images_by_target[driver]}}
> + #{path = image_target_image_path('replace_image_id', 'replace_target_image_id')
> + path = path.sub('replace_image_id', '${image[\'uuid\']}')
> + path = path.sub('replace_target_image_id', '${target_images_by_target[driver][\'uuid\']}')
> + button_to(t('images.show.delete'), path, :method => :delete)}
> + {{else build && build['uuid'] == latest_build_id}}
> + #{path = image_target_images_path('replace_image_id', :target => 'replace_driver', :build_id => 'replace_build_id')
> + path = path.sub('replace_image_id', '${image[\'uuid\']}')
> + path = path.sub('replace_driver', '${driver}')
> + path = path.sub('replace_build_id', '${build[\'uuid\']}')
> + button_to(t('images.show.build'), path, :method => :post)}
> + {{if failed_build_counts[driver] > 1}}
> + <div class="light">
> + #{t('images.show.failed_build_attemts', :count => '${failed_build_counts[driver]}' )}
> + </div>
> + {{else failed_build_counts[driver] == 1}}
> + <div class="light">
> + #{t('images.show.failed_build_attemts', :count => 1 )}
> + </div>
> + {{/if}}
> + {{else}}
> +
> + {{/if}}
> + </dt>
> + <dd>
> + <table class="light_table">
> + <thead>
> + <tr>
> + <th>
> + <strong>#{t'images.show.account'}</strong>
> + </th>
> + <th>
> + #{t'images.show.provider'}
> + </th>
> + <th>
> + #{t'images.show.image_uuid'}
> + </th>
> + <th>
> + #{t'images.show.image_uri'}
> + </th>
> + <th class="image_controls"></th>
> + </tr></thead>
> +
> + <tbody>
> + {{each(index, account) groups['accounts']}}
> + <tr>
> + <td>
> + <strong>${account['label']}</strong>
> + </td>
> + <td class="light">
> + ${account['provider_name']}
> + </td>
> + <td class="light">
> + {{if provider_images[account['id']]}}
> + ${provider_images[account['id']]['target_identifier']}
> + {{/if}}
> + </td>
> + <td class="light">
> + {{if provider_images[account['id']]}}
> + ${provider_images[account['id']]['uuid']}
> + {{/if}}
> + </td>
> + <td class="image_controls light">
> + {{if target_images_by_target[driver] && active_pushes[account['id']]}}
> + <label>${active_pushes[account['id']]['status']}</label>
> + {{else target_images_by_target[driver] && !provider_images[account['id']] && build && build['uuid'] == latest_build_id}}
> + #{path = image_provider_images_path('replace_image_id', :build_id => 'replace_build_id', :target_image_id => 'replace_target_image_id', :account_id => 'replace_account_id')
> + path = path.sub('replace_image_id', '${image[\'uuid\']}')
> + path = path.sub('replace_build_id', '${build[\'uuid\']}')
> + path = path.sub('replace_target_image_id', '${target_images_by_target[driver][\'uuid\']}')
> + path = path.sub('replace_account_id', '${account[\'id\']}')
> + button_to(t('images.show.upload'), path, :method => :post, :class => 'upload_image')}
> + {{if failed_push_counts[account['id']] > 1}}
> + #{t('images.show.failed_push_attemts', :count => '${failed_push_counts[account[\'id\']]}' )}
> + {{else failed_push_counts[account['id']] == 1}}
> + #{t('images.show.failed_push_attemts', :count => 1 )}
> + {{/if}}
> + {{else provider_images[account['id']]}}
> + #{path = image_provider_image_path('replace_image_id', 'replace_provider_image_id')
> + path = path.sub('replace_image_id', '${image[\'uuid\']}')
> + path = path.sub('replace_provider_image_id', '${provider_images[account[\'id\']][\'uuid\']}')
> + button_to("", path, :method => :delete, :class => 'delete_image')}
> + {{else}}
> +
> + {{/if}}
> + </td>
> + </tr>
> + {{/each}}
> + </tbody>
> + </table>
> + </dd>
> + </dl>
> + <div class="clear"></div>
> + </li>
> + {{/each}}
> diff --git a/src/public/javascripts/application.js b/src/public/javascripts/application.js
> index e9c0ca3..a3dd4a7 100644
> --- a/src/public/javascripts/application.js
> +++ b/src/public/javascripts/application.js
> @@ -164,6 +164,34 @@ $.extend(Conductor, {
> });
> },
>
> + urlParams: function() {
> + var paramsData = window.location.search.slice(1).split('&');
> + var params = {};
> + $.each(paramsData, function(index, value){
> + var eqSign = value.search('=');
> + if(eqSign != -1) {
> + params[value.substring(0, eqSign)] = value.substring(eqSign+1);
> + }
> + });
> +
> + return params;
> + },
> +
> + extractQueryParams: function(paramsToInclude) {
> + var result = {};
> + var urlParams = Conductor.urlParams();
> +
> + $.each(paramsToInclude, function(paramIndex, paramValue) {
> + for (var urlParamName in urlParams) {
> + if (urlParamName == paramValue) {
> + result[urlParamName] = urlParams[urlParamName];
> + break;
> + }
> + };
> + });
> +
> + return result;
> + },
>
> prefixedPath: function(path) {
> var prefix = this.PATH_PREFIX;
> @@ -205,6 +233,10 @@ $.extend(Conductor, {
> return parseInt(urlFragment.split('?')[0]);
> },
>
> + uuidFromURLFragment: function(urlFragment) {
> + return urlFragment.split('?')[0];
> + },
> +
> saveCheckboxes: function(checkboxSelector, $scope) {
> if(!$scope) $scope = $;
>
> diff --git a/src/public/javascripts/backbone/models.js b/src/public/javascripts/backbone/models.js
> index a89cb6b..15ebf7c 100644
> --- a/src/public/javascripts/backbone/models.js
> +++ b/src/public/javascripts/backbone/models.js
> @@ -45,3 +45,11 @@ Conductor.Models.Deployments = Backbone.Collection.extend({
> return Conductor.parameterizedPath(path, this.queryParams);
> }
> });
> +
> +Conductor.Models.Image = Backbone.Model.extend({
> + queryParams: {},
> + url: function() {
> + var path = Conductor.prefixedPath('/images/' + this.id);
> + return Conductor.parameterizedPath(path, this.queryParams);
> + }
> +});
> diff --git a/src/public/javascripts/backbone/routers.js b/src/public/javascripts/backbone/routers.js
> index ed896d6..d2f0123 100644
> --- a/src/public/javascripts/backbone/routers.js
> +++ b/src/public/javascripts/backbone/routers.js
> @@ -85,3 +85,22 @@ Conductor.Routers.Deployments = Backbone.Router.extend({
> }, Conductor.AJAX_REFRESH_INTERVAL);
> }
> });
> +
> +Conductor.Routers.Images = Backbone.Router.extend({
> + routes: {
> + 'images/:id': 'show'
> + },
> +
> + show: function(id) {
> + id = Conductor.uuidFromURLFragment(id);
> +
> + setInterval(function() {
> + var image = new Conductor.Models.Image({ id: id });
> +
> + var view = new Conductor.Views.ImagesShow({ model: image });
> + view.model.queryParams = view.queryParams();
> +
> + image.fetch({ success: function() { view.render(); } })
> + }, Conductor.AJAX_REFRESH_INTERVAL);
> + }
> +});
> diff --git a/src/public/javascripts/backbone/views.js b/src/public/javascripts/backbone/views.js
> index 97f678d..ec558e9 100644
> --- a/src/public/javascripts/backbone/views.js
> +++ b/src/public/javascripts/backbone/views.js
> @@ -38,32 +38,10 @@ Conductor.Views.PoolsIndex = Backbone.View.extend({
> }
> },
>
> - urlParams: function() {
> - var paramsData = window.location.search.slice(1).split('&');
> - var params = {};
> - $.each(paramsData, function(index, value){
> - var eqSign = value.search('=');
> - if(eqSign != -1) {
> - params[value.substring(0, eqSign)] = value.substring(eqSign+1);
> - }
> - });
> -
> - return params;
> - },
> -
> queryParams: function() {
> - var result = {};
> var paramsToInclude = [this.currentTab() + '_preset_filter', this.currentTab() + '_search'];
> - var urlParams = this.urlParams();
> + var result = Conductor.extractQueryParams(paramsToInclude);
>
> - $.each(paramsToInclude, function(paramIndex, paramValue) {
> - for (var urlParamName in urlParams) {
> - if (urlParamName == paramValue) {
> - result[urlParamName] = urlParams[urlParamName];
> - break;
> - }
> - };
> - });
> // If there is no URL param for the preset filter, we still need to merge in the preset filter
> var filter = this.currentTab() + '_preset_filter';
> if(result[filter] == undefined) {
> @@ -179,3 +157,24 @@ Conductor.Views.DeploymentsShow = Backbone.View.extend({
> }
>
> });
> +
> +
> +Conductor.Views.ImagesShow = Backbone.View.extend({
> + el: '#content',
> +
> + queryParams: function() {
> + var paramsToInclude = ['build'];
> + var result = Conductor.extractQueryParams(paramsToInclude);
> +
> + return result;
> + },
> +
> + render: function() {
> + var $builds = this.$('ul.image_builds');
> + if($builds.length === 0) return;
> +
> + $builds.empty();
> +
> + $('#imageBuildsTemplate').tmpl(this.model.toJSON()).appendTo($builds);
> + }
> +});
>
Looks good, works for me, ACK.
--
With regards
Petr Blaho
More information about the aeolus-devel
mailing list