Class: ForemanTasks::Task::DynflowTask

Inherits:
ForemanTasks::Task show all
Includes:
Algebrick::TypeCheck
Defined in:
app/models/foreman_tasks/task/dynflow_task.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ForemanTasks::Task

#add_missing_task_groups, authorized_resource_name, #owner, #paused?, #pending?, search_by_generic_resource, search_by_owner, #self_and_parents, #username

Class Method Details

.consistency_checkObject



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 104

def self.consistency_check
  fixed_count = 0
  logger = Foreman::Logging.logger('foreman-tasks')
  self.running.each do |task|
    begin
      changes = task.update_from_dynflow(task.execution_plan.to_hash)
      unless changes.empty?
        fixed_count += 1
        logger.warn("Task %s updated at consistency check: %s" % [task.id, changes.inspect])
      end
    rescue => e
      Foreman::Logging.exception("Failed at consistency check for task #{task.id}", e, :logger => 'foreman-tasks')
    end
  end
  return fixed_count
end

.new_for_execution_plan(execution_plan_id, data) ⇒ Object



121
122
123
124
125
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 121

def self.new_for_execution_plan(execution_plan_id, data)
  self.new(:external_id => execution_plan_id,
           :state => data[:state].to_s,
           :result => data[:result].to_s)
end

Instance Method Details

#cancelObject



32
33
34
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 32

def cancel
  execution_plan.cancel.any?
end

#cancellable?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 28

def cancellable?
  execution_plan.cancellable?
end

#cancellable_action?(action) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 40

def cancellable_action?(action)
  action.is_a?(::Dynflow::Action::Cancellable)
end

#cli_exampleObject



75
76
77
78
79
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 75

def cli_example
  if main_action.respond_to?(:cli_example)
    main_action.cli_example
  end
end

#execution_planObject



48
49
50
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 48

def execution_plan
  @execution_plan ||= ForemanTasks.dynflow.world.persistence.load_execution_plan(external_id)
end

#failed_stepsObject



60
61
62
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 60

def failed_steps
  execution_plan.steps_in_state(:skipped, :skipping, :error)
end

#get_humanized(method) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 86

def get_humanized(method)
  @humanized_cache ||= {}
  if [:name, :input, :output, :error].include?(method)
    method = "humanized_#{method}".to_sym
  end
  Match! method, :humanized_name, :humanized_input, :humanized_output, :humanized_errors
  return N_('N/A') if method != :humanized_name && main_action.execution_plan.state == :scheduled
  @humanized_cache[method] ||= begin
                                 if main_action.respond_to? method
                                   begin
                                     main_action.send method
                                   rescue Exception => error # rubocop:disable Lint/RescueException
                                     "#{error.message} (#{error.class})\n#{error.backtrace.join "\n"}"
                                   end
                                 end
                               end
end

#humanizedObject



68
69
70
71
72
73
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 68

def humanized
  { action: get_humanized(:humanized_name),
    input:  get_humanized(:humanized_input),
    output: get_humanized(:humanized_output),
    errors: get_humanized(:humanized_errors) }
end

#inputObject



52
53
54
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 52

def input
  main_action.respond_to?(:task_input) && main_action.task_input
end

#main_actionObject



81
82
83
84
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 81

def main_action
  return @main_action if @main_action
  execution_plan.root_plan_step.action execution_plan
end

#outputObject



56
57
58
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 56

def output
  main_action.respond_to?(:task_output) && main_action.task_output
end

#progressObject



44
45
46
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 44

def progress
  execution_plan.progress
end

#resumable?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 36

def resumable?
  execution_plan.state == :paused
end

#running_stepsObject



64
65
66
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 64

def running_steps
  execution_plan.steps_in_state(:running, :suspended)
end

#update_from_dynflow(data) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'app/models/foreman_tasks/task/dynflow_task.rb', line 8

def update_from_dynflow(data)
  utc_zone = ActiveSupport::TimeZone.new('UTC')
  self.external_id    = data[:id]
  self.started_at     = utc_zone.parse(data[:started_at]) unless data[:started_at].nil?
  self.ended_at       = utc_zone.parse(data[:ended_at]) unless data[:ended_at].nil?
  self.state          = data[:state].to_s
  self.result         = data[:result].to_s
  self.start_at       = utc_zone.parse(data[:start_at]) if data[:start_at]
  self.start_before   = utc_zone.parse(data[:start_before]) if data[:start_before]
  self.parent_task_id ||= begin
                            if main_action.caller_execution_plan_id
                              DynflowTask.where(:external_id => main_action.caller_execution_plan_id).first!.id
                            end
                          end
  self.label          ||= main_action.class.name
  changes             = self.changes
  self.save!
  return changes
end