app/models/foreman_tasks/task.rb in foreman-tasks-0.8.6 vs app/models/foreman_tasks/task.rb in foreman-tasks-0.9.0
- old
+ new
@@ -2,11 +2,11 @@
module ForemanTasks
class Task < ActiveRecord::Base
include Authorizable
- # TODO missing validation of states
+ # TODO: missing validation of states
self.primary_key = :id
before_create :generate_id
belongs_to :parent_task, :class_name => 'ForemanTasks::Task'
@@ -16,109 +16,119 @@
has_many :task_group_members
has_many :task_groups, :through => :task_group_members
if Rails::VERSION::MAJOR < 4
has_many :recurring_logic_task_groups, :through => :task_group_members, :conditions => { :type => 'ForemanTasks::TaskGroups::RecurringLogicTaskGroup' }, :source => :task_group
has_many :owners, :through => :locks, :source => :resource, :source_type => 'User',
- :conditions => ["foreman_tasks_locks.name = ?", Lock::OWNER_LOCK_NAME]
+ :conditions => ['foreman_tasks_locks.name = ?', Lock::OWNER_LOCK_NAME]
else
has_many :recurring_logic_task_groups, -> { where :type => 'ForemanTasks::TaskGroups::RecurringLogicTaskGroup' },
:through => :task_group_members, :source => :task_group
# in fact, the task has only one owner but Rails don't let you to
# specify has_one relation though has_many relation
- has_many :owners, lambda {where(["foreman_tasks_locks.name = ?", Lock::OWNER_LOCK_NAME])},
+ has_many :owners, -> { where(['foreman_tasks_locks.name = ?', Lock::OWNER_LOCK_NAME]) },
:through => :locks, :source => :resource, :source_type => 'User'
end
-
scoped_search :on => :id, :complete_value => false
scoped_search :on => :label, :complete_value => true
scoped_search :on => :state, :complete_value => true
scoped_search :on => :result, :complete_value => true
scoped_search :on => :started_at, :complete_value => false
scoped_search :on => :start_at, :complete_value => false
scoped_search :on => :ended_at, :complete_value => false
scoped_search :on => :parent_task_id, :complete_value => true
- scoped_search :in => :locks, :on => :resource_type, :complete_value => true, :rename => "resource_type", :ext_method => :search_by_generic_resource
- scoped_search :in => :locks, :on => :resource_id, :complete_value => false, :rename => "resource_id", :ext_method => :search_by_generic_resource
- scoped_search :in => :owners, :on => :id, :complete_value => true, :rename => "owner.id", :ext_method => :search_by_owner
- scoped_search :in => :owners, :on => :login, :complete_value => true, :rename => "owner.login", :ext_method => :search_by_owner
- scoped_search :in => :owners, :on => :firstname, :complete_value => true, :rename => "owner.firstname", :ext_method => :search_by_owner
- scoped_search :in => :task_groups, :on => :id, :complete_value => true, :rename => "task_group.id"
+ scoped_search :relation => :locks, :on => :resource_type, :complete_value => true, :rename => 'resource_type', :ext_method => :search_by_generic_resource
+ scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'resource_id', :ext_method => :search_by_generic_resource
+ scoped_search :relation => :owners,
+ :on => :id,
+ :complete_value => true,
+ :rename => 'owner.id',
+ :ext_method => :search_by_owner,
+ :validator => ->(value) { ScopedSearch::Validators::INTEGER.call(value) || value == 'current_user' }
+ scoped_search :relation => :owners, :on => :login, :complete_value => true, :rename => 'owner.login', :ext_method => :search_by_owner
+ scoped_search :relation => :owners, :on => :firstname, :complete_value => true, :rename => 'owner.firstname', :ext_method => :search_by_owner
+ scoped_search :relation => :task_groups, :on => :id, :complete_value => true, :rename => 'task_group.id', :validator => ScopedSearch::Validators::INTEGER
scope :active, -> { where('foreman_tasks_tasks.state != ?', :stopped) }
- scope :running, -> { where("foreman_tasks_tasks.state NOT IN ('stopped', 'paused')") }
+ scope :running, -> { where("foreman_tasks_tasks.state NOT IN ('stopped', 'paused')") }
scope :for_resource,
- (lambda do |resource|
- joins(:locks).where(:"foreman_tasks_locks.resource_id" => resource.id,
- :"foreman_tasks_locks.resource_type" => resource.class.name)
- end)
- scope :for_action_types, (lambda { |action_types| where('foreman_tasks_tasks.label IN (?)', Array(action_types)) })
+ (lambda do |resource|
+ joins(:locks).where(:"foreman_tasks_locks.resource_id" => resource.id,
+ :"foreman_tasks_locks.resource_type" => resource.class.name)
+ end)
+ scope :for_action_types, (->(action_types) { where('foreman_tasks_tasks.label IN (?)', Array(action_types)) })
def input
{}
end
def output
{}
end
def owner
- self.owners.first
+ owners.first
end
def username
- self.owner.try(:login)
+ owner.try(:login)
end
def execution_type
- self.start_at.to_i == self.started_at.to_i ? N_('Immediate') : N_('Delayed')
+ delayed? ? N_('Delayed') : N_('Immediate')
end
def humanized
{ action: label,
- input: "",
- output: "" }
+ input: '',
+ output: '' }
end
def cli_example
- ""
+ ''
end
# returns true if the task is running or waiting to be run
def pending?
- self.state != 'stopped'
+ state != 'stopped'
end
- alias_method :pending, :pending?
+ alias pending pending?
def resumable?
false
end
def paused?
- self.state == 'paused'
+ state == 'paused'
end
+ def recurring?
+ !recurring_logic_task_group_ids.empty?
+ end
+
+ def delayed?
+ start_at.to_i != started_at.to_i
+ end
+
def self_and_parents
[self].tap do |ret|
- if parent_task
- ret.concat(parent_task.self_and_parents)
- end
+ ret.concat(parent_task.self_and_parents) if parent_task
end
end
def self.search_by_generic_resource(key, operator, value)
- key = "resource_type" if key.blank?
- key_name = self.connection.quote_column_name(key.sub(/^.*\./,''))
+ key = 'resource_type' if key.blank?
+ key_name = connection.quote_column_name(key.sub(/^.*\./, ''))
condition = sanitize_sql_for_conditions(["foreman_tasks_locks.#{key_name} #{operator} ?", value])
- return {:conditions => condition, :joins => :locks }
+ { :conditions => condition, :joins => :locks }
end
def self.search_by_owner(key, operator, value)
return { :conditions => '0 = 1' } if value == 'current_user' && User.current.nil?
- key_name = self.connection.quote_column_name(key.sub(/^.*\./,''))
+ key_name = connection.quote_column_name(key.sub(/^.*\./, ''))
joins = <<-SQL
INNER JOIN foreman_tasks_locks AS foreman_tasks_locks_owner
ON (foreman_tasks_locks_owner.task_id = foreman_tasks_tasks.id AND
foreman_tasks_locks_owner.resource_type = 'User' AND
foreman_tasks_locks_owner.name = '#{Lock::OWNER_LOCK_NAME}')
@@ -130,25 +140,23 @@
SQL
end
condition = if key.blank?
sanitize_sql_for_conditions(["users.login #{operator} ? or users.firstname #{operator} ? ", value, value])
elsif key =~ /\.id\Z/
- if value == 'current_user'
- value = User.current.id
- end
+ value = User.current.id if value == 'current_user'
sanitize_sql_for_conditions(["foreman_tasks_locks_owner.resource_id #{operator} ?", value])
else
sanitize_sql_for_conditions(["users.#{key_name} #{operator} ?", value])
end
- return {:conditions => condition, :joins => joins }
+ { :conditions => condition, :joins => joins }
end
def progress
- case self.state.to_s
- when "running", "paused"
+ case state.to_s
+ when 'running', 'paused'
0.5
- when "stopped"
+ when 'stopped'
1
else
0
end
end
@@ -159,9 +167,27 @@
end
def add_missing_task_groups(groups)
groups = [groups] unless groups.is_a? Array
(groups - task_groups).each { |group| task_groups << group }
+ end
+
+ def sub_tasks_counts
+ result = %w(cancelled error pending success warning).zip([0].cycle).to_h
+ result.update sub_tasks.group(:result).count
+ sum = result.values.reduce(:+)
+ if respond_to?(:main_action) && main_action.respond_to?(:total_count)
+ result[:total] = main_action.total_count
+ # In case of batch planning there might be some plans still unplanned (not present in database).
+ # To get correct counts we need to add them to either:
+ # cancelled when the parent is stopped
+ # pending when the parent is still running.
+ key = state == 'stopped' ? 'cancelled' : 'pending'
+ result[key] += result[:total] - sum
+ else
+ result[:total] = sum
+ end
+ result.symbolize_keys
end
protected
def generate_id