[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}}
> +              &nbsp;
> +            {{/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}}
> +                        &nbsp;
> +                      {{/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