app/controllers/katello/sync_management_controller.rb in katello-1.5.0 vs app/controllers/katello/sync_management_controller.rb in katello-2.2.2

- old
+ new

@@ -1,7 +1,7 @@ # -# Copyright 2013 Red Hat, Inc. +# Copyright 2014 Red Hat, Inc. # # This software is licensed to you under the GNU General Public # License as published by the Free Software Foundation; either version # 2 of the License (GPLv2) or (at your option) any later version. # There is NO WARRANTY for this software, express or implied, @@ -10,233 +10,146 @@ # have received a copy of GPLv2 along with this software; if not, see # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. # rubocop:disable ClassVars module Katello -class SyncManagementController < Katello::ApplicationController - include TranslationHelper - include ActionView::Helpers::DateHelper - include ActionView::Helpers::NumberHelper - include SyncManagementHelper::RepoMethods - respond_to :html, :json + class SyncManagementController < Katello::ApplicationController + include TranslationHelper + include ActionView::Helpers::DateHelper + include ActionView::Helpers::NumberHelper + include SyncManagementHelper::RepoMethods + respond_to :html, :json - # to avoid problems when generating Headpin documenation when - # building RPMs - if Katello.config.use_pulp - @@status_values = { PulpSyncStatus::Status::WAITING => _("Queued."), - PulpSyncStatus::Status::FINISHED => _("Sync complete."), - PulpSyncStatus::Status::ERROR => _("Error syncing!"), - PulpSyncStatus::Status::RUNNING => _("Running."), - PulpSyncStatus::Status::CANCELED => _("Canceled."), - PulpSyncStatus::Status::NOT_SYNCED => ""} - else - @@status_values = {} - end + @@status_values = { :stopped => _("Syncing Complete."), + :error => _("Sync Incomplete"), + :never_synced => _("Never Synced"), + :paused => _("Paused")}.with_indifferent_access - before_filter :find_provider, :except => [:index, :sync, :sync_status, :manage] - before_filter :find_providers, :only => [:sync, :sync_status] - before_filter :authorize + def section_id + 'contents' + end - def menu_definition - {:manage => :admin_menu}.with_indifferent_access - end + def title + _('Sync Status') + end - def section_id - 'contents' - end + def index + org = current_organization + @products = org.library.products.readable + redhat_products, custom_products = @products.partition(&:redhat?) + redhat_products.sort_by { |p| p.name.downcase } + custom_products.sort_by { |p| p.name.downcase } - def rules + @products = redhat_products + custom_products + @product_size = {} + @repo_status = {} + @product_map = collect_repos(@products, org.library, false) - list_test = lambda{current_organization && Provider.any_readable?(current_organization) } - sync_read_test = lambda do - @providers.each { |prov| return false if !prov.readable? } - return true + @products.each { |product| get_product_info(product) } end - sync_test = lambda {current_organization && current_organization.syncable?} - { :index => list_test, - :manage => list_test, - :sync_status => sync_read_test, - :product_status => sync_read_test, - :sync => sync_test, - :destroy => sync_test - } - end + def sync + tasks = sync_repos(params[:repoids]) || [] + render :json => tasks.as_json + end - def index - org = current_organization - @products = org.library.products.readable(org) - redhat_products, custom_products = @products.partition(&:redhat?) - redhat_products.sort_by { |p| p.name.downcase } - custom_products.sort_by { |p| p.name.downcase } + def sync_status + repos = Repository.where(:id => params[:repoids]).readable + statuses = repos.map { |repo| format_sync_progress(repo) } + render :json => statuses.flatten.to_json + end - @products = redhat_products + custom_products - @product_size = {} - @repo_status = {} - @product_map = collect_repos(@products, org.library, false, false) + def destroy + repo = Repository.where(:id => params[:id]).syncable.first + repo.cancel_dynflow_sync if repo + render :text => "" + end - @products.each { |product| get_product_info(product) } - end + private - def manage - @products = [] - @sproducts = [] - @product_map = [] - @product_size = {} - @repo_status = {} - @show_org = true - - User.current.allowed_organizations.each do |org| - products = org.library.products.readable(org) - next if products.blank? - @sproducts.concat products.select(&:syncable_content?) - @product_map.concat collect_repos(products, org.library) - products.each { |product| get_product_info(product) } - @products.concat products + def format_sync_progress(repo) + task = latest_task(repo) + if task + { :id => repo.id, + :product_id => repo.product.id, + :progress => {:progress => task.progress * 100}, + :sync_id => task.id, + :state => format_state(task), + :raw_state => raw_state(task), + :start_time => format_date(task.started_at), + :finish_time => format_date(task.ended_at), + :duration => format_duration(task.ended_at, task.started_at), + :display_size => task.humanized[:output], + :size => task.humanized[:output], + :is_running => task.pending && task.state != 'paused', + :error_details => task.errors + } + else + empty_task(repo) + end end - @sync_plans = SyncPlan.all - end - - def sync - ids = sync_repos(params[:repoids]) || {} - respond_with(ids) do |format| - format.js { render :json => ids.to_json, :status => :ok } + def empty_task(repo) + state = 'never_synced' + { :id => repo.id, + :product_id => repo.product.id, + :progress => {}, + :state => format_state(OpenStruct.new(:state => state)), + :raw_state => state + } end - end - def sync_status - collected = [] - params[:repoids].each do |id| - begin - repo = Repository.find(id) - progress = format_sync_progress(repo.sync_status, repo) - collected.push(progress) - rescue ActiveRecord::RecordNotFound => e - notify.exception e # debugging and skip for now - next + def raw_state(task) + if task.result == 'error' || task.result == 'warning' + return 'error' + else + task.state end end - respond_with(collected) do |format| - format.js { render :json => collected.to_json, :status => :ok } + def format_state(task) + @@status_values[raw_state(task)] || task.state end - end - def destroy - Repository.find(params[:id]).cancel_sync - render :text => "" - end - - private - - def find_provider - Repository.find(params[:repo] || params[:id]).product.provider - end - - def find_providers - ids = params[:repoids] - ids = [params[:repoids]] if !params[:repoids].is_a? Array - @providers = [] - ids.each do |id| - repo = Repository.find(id) - @providers << repo.product.provider + def format_duration(finish, start) + retval = nil + if !finish.nil? && !start.nil? + retval = distance_of_time_in_words(finish, start) + end + retval end - end - def format_sync_progress(sync_status, repo) - progress = sync_status.progress - error_details = progress.error_details - - not_running_states = [PulpSyncStatus::Status::FINISHED, - PulpSyncStatus::Status::ERROR, - PulpSyncStatus::Status::WAITING, - PulpSyncStatus::Status::CANCELED, - PulpSyncStatus::Status::NOT_SYNCED] - { :id => repo.id, - :product_id => repo.product.id, - :progress => calc_progress(sync_status, repo.content_type), - :sync_id => sync_status.uuid, - :state => format_state(sync_status.state), - :raw_state => sync_status.state, - :start_time => format_date(sync_status.start_time), - :finish_time => format_date(sync_status.finish_time), - :duration => format_duration(sync_status.finish_time, sync_status.start_time), - :packages => sync_status.progress.total_count, - :display_size => number_to_human_size(sync_status.progress.total_size), - :size => sync_status.progress.total_size, - :is_running => !not_running_states.include?(sync_status.state.to_sym), - :error_details => error_details ? error_details : "No errors." - } - end - - def format_state(state) - @@status_values[state.to_sym] - end - - def format_duration(finish, start) - retval = nil - if !finish.nil? && !start.nil? - retval = distance_of_time_in_words(finish, start) + def format_date(check_date) + retval = nil + unless check_date.nil? + retval = relative_time_in_words(check_date) + end + retval end - retval - end - def format_date(check_date) - retval = nil - if !check_date.nil? - retval = relative_time_in_words(check_date) + def latest_task(repo) + repo.latest_dynflow_sync end - retval - end - # loop through checkbox list of products and sync - def sync_repos(repos) - repos = [repos] if !repos.is_a? Array - collected = [] - repos.each do |id| - repo = Repository.find(id) - begin - resp = repo.sync(:notify => true).first - collected.push(:id => id, :product_id => repo.product.id, :state => resp[:state]) - rescue RestClient::Conflict - notify.error N_("There is already an active sync process for the '%s' repository. Please try again later") % - repo.name + # loop through checkbox list of products and sync + def sync_repos(repo_ids) + collected = [] + repos = Repository.where(:id => repo_ids).syncable + repos.each do |repo| + if latest_task(repo).try(:state) != 'running' + ForemanTasks.async_task(::Actions::Katello::Repository::Sync, repo) + collected << format_sync_progress(repo) + else + notify.error N_("There is already an active sync process for the '%s' repository. Please try again later") % + repo.name + end end + collected end - collected - end - # calculate the % complete of ongoing sync from pulp - def calc_progress(val, content_type) - - if content_type == Repository::PUPPET_TYPE - completed = val.progress.total_count - val.progress.items_left - progress = if val.state =~ /error/i then -1 - elsif val.progress.total_count == 0 then 0 - else completed.to_f / val.progress.total_count.to_f * 100 - end - else - completed = val.progress.total_size - val.progress.size_left - progress = if val.state =~ /error/i then -1 - elsif val.progress.total_size == 0 then 0 - else completed.to_f / val.progress.total_size.to_f * 100 - end + def get_product_info(product) + product.repos(product.organization.library).each do |repo| + @repo_status[repo.id] = format_sync_progress(repo) + end end - - {:count => val.progress.total_count, - :left => val.progress.items_left, - :progress => progress - } end - - def get_product_info(product) - product_size = 0 - product.repos(product.organization.library).each do |repo| - status = repo.sync_status - @repo_status[repo.id] = format_sync_progress(status, repo) - product_size += status.progress.total_size - end - @product_size[product.id] = number_to_human_size(product_size) - end -end end