foreman-tasks 0.7.3 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Y2I3YzI4OGYwN2U1YWZmZGQ1MmE2MmVlYTBiNTBlZmUyMDhkMDJkYQ==
4
+ NzAzZDZlZGRhYjg2OWM2ZGU3NTdkMGMzMmZmMTg4ZDJhODU3NjU3NA==
5
5
  data.tar.gz: !binary |-
6
- NDNlOGVkYjFjODE5ZmQ2NWNiMjYzOTFjMmI3NTQ3N2FjYmYzMmI2Mg==
6
+ NzQ1ZDRmODAwYzg3ODhhNThjMGVmNmQyZDQwNDA3NDliNjVkYjYxNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OTA1NDM0MjUyZDIzNGNmMjA3NTgwNWNkYzVmZDhmODg4ZDk3MGY0YjMzZGIx
10
- ZjQyMTY4N2Y5NTgwNTQzMTEwNWU4ZmZlYThmNmEzZWVmMWE1ZGVmZDFlMWUz
11
- N2IyZjkyMzc1YjIzOWZjZjY4M2E1NDc1NmI2NTI4ZTI4Y2RhOWE=
9
+ N2U4ZmQ0ZTE4MTZkNDlmMWRmYmEzYThhODJiYWQwZTEyOTQyY2Q3MWZjMzM1
10
+ NDJlNjQ1YWNjNWU5ODgzZmE3NjVmN2Q0Y2YzMGI4Y2NlZjZkN2RmODcyYzRk
11
+ ODc5Y2FlNWQ5ZDE3YjlmODYyMWYzYTI3YTljOWIxMTdmOWYwMzE=
12
12
  data.tar.gz: !binary |-
13
- ZDRjZmVlN2I2NDgwMDc4YjVlODA2MjE1ZjY5MzRmZGJmMDlkOGM5OTI0YWMy
14
- ZTJkNmIzMDk0MDZiYTZmOGEzMzFiZDZmOTdmNGYwNTQzYjg2NzBkNTUwN2Ew
15
- YzQ2N2RlNWU1ZjdiNWRhOWY5NDE0ZmVjYWMxOTA4NmJkYTcwNjI=
13
+ YTU2ZjFlNTY2ZjI3MzA5ZmMxMWQ2YzQzMDQxMTZjMjY3NDExMjNmNjVlZjkz
14
+ ZjJhOGRlODk5OTgxOGIyZDI0NzE0YjY3ZmFhZDQxNmE4NGFlYWQ4Y2Q3ZWMw
15
+ MTY5MWMwNjMzNDVlOWJiMzE2YWZjMTgwZjc0NDZkZjYyNmE2MWY=
@@ -54,10 +54,10 @@ module Actions
54
54
 
55
55
  def check_targets!(targets)
56
56
  if targets.empty?
57
- fail _("Empty bulk action")
57
+ fail ::Foreman::Exception.new(N_("Empty bulk action"))
58
58
  end
59
59
  if targets.map(&:class).uniq.length > 1
60
- fail _("The targets are of different types")
60
+ fail ::Foreman::Exception.new(N_("The targets are of different types"))
61
61
  end
62
62
  end
63
63
 
@@ -56,5 +56,9 @@ module Actions
56
56
  subclasses.map { |k| k.allocate.humanized_name }
57
57
  end
58
58
 
59
+ def delay(_schedule_options, *args)
60
+ Serializers::ActiveRecordSerializer.new args
61
+ end
62
+
59
63
  end
60
64
  end
@@ -15,8 +15,15 @@ module Actions
15
15
  module Middleware
16
16
 
17
17
  class KeepCurrentUser < Dynflow::Middleware
18
+
19
+ def delay(*args)
20
+ pass(*args).tap { store_current_user }
21
+ end
22
+
18
23
  def plan(*args)
19
- pass(*args).tap { action.input[:current_user_id] = User.current.id }
24
+ with_current_user do
25
+ pass(*args).tap { store_current_user }
26
+ end
20
27
  end
21
28
 
22
29
  def run(*args)
@@ -29,6 +36,18 @@ module Actions
29
36
 
30
37
  private
31
38
 
39
+ def with_current_user
40
+ if User.current || action.input[:current_user_id].nil?
41
+ yield
42
+ else
43
+ restore_curent_user { yield }
44
+ end
45
+ end
46
+
47
+ def store_current_user
48
+ action.input[:current_user_id] = User.current.try(:id)
49
+ end
50
+
32
51
  def restore_curent_user
33
52
  User.current = User.find(action.input[:current_user_id])
34
53
  yield
@@ -2,6 +2,7 @@ module Actions
2
2
  class ProxyAction < Base
3
3
 
4
4
  include ::Dynflow::Action::Cancellable
5
+ include ::Dynflow::Action::Timeouts
5
6
 
6
7
  class CallbackData
7
8
  attr_reader :data
@@ -12,39 +13,65 @@ module Actions
12
13
  end
13
14
 
14
15
  def plan(proxy, options)
16
+ options[:connection_options] ||= {}
17
+ default_connection_options.each { |key, value| options[:connection_options][key] ||= value }
15
18
  plan_self(options.merge(:proxy_url => proxy.url))
16
19
  end
17
20
 
18
21
  def run(event = nil)
19
- case event
20
- when nil
21
- if output[:proxy_task_id]
22
- on_resume
22
+ with_connection_error_handling(event) do |event|
23
+ case event
24
+ when nil
25
+ if output[:proxy_task_id]
26
+ on_resume
27
+ else
28
+ trigger_proxy_task
29
+ end
30
+ suspend
31
+ when ::Dynflow::Action::Skip
32
+ # do nothing
33
+ when ::Dynflow::Action::Cancellable::Cancel
34
+ cancel_proxy_task
35
+ when CallbackData
36
+ on_data(event.data)
37
+ when ::Dynflow::Action::Timeouts::Timeout
38
+ check_task_status
23
39
  else
24
- trigger_proxy_task
40
+ raise "Unexpected event #{event.inspect}"
25
41
  end
26
- suspend
27
- when ::Dynflow::Action::Skip
28
- # do nothing
29
- when ::Dynflow::Action::Cancellable::Cancel
30
- cancel_proxy_task
31
- when CallbackData
32
- on_data(event.data)
33
- else
34
- raise "Unexpected event #{event.inspect}"
35
42
  end
36
43
  end
37
44
 
38
45
  def trigger_proxy_task
39
- response = proxy.trigger_task(proxy_action_name,
40
- input.merge(:callback => { :task_id => task.id,
41
- :step_id => run_step_id }))
42
- output[:proxy_task_id] = response["task_id"]
46
+ suspend do |_suspended_action|
47
+ set_timeout! unless timeout_set?
48
+ response = proxy.trigger_task(proxy_action_name,
49
+ input.merge(:callback => { :task_id => task.id,
50
+ :step_id => run_step_id }))
51
+ output[:proxy_task_id] = response["task_id"]
52
+ end
53
+ end
54
+
55
+ def check_task_status
56
+ if output[:proxy_task_id]
57
+ response = proxy.status_of_task(output[:proxy_task_id])
58
+ if response['state'] == 'stopped'
59
+ if response['result'] == 'error'
60
+ raise ::Foreman::Exception, _("The smart proxy task '#{output[:proxy_task_id]}' failed.")
61
+ else
62
+ on_data(response['actions'].find { |block_action| block_action['class'] == proxy_action_name }['output'])
63
+ end
64
+ else
65
+ cancel_proxy_task
66
+ end
67
+ else
68
+ process_timeout
69
+ end
43
70
  end
44
71
 
45
72
  def cancel_proxy_task
46
73
  if output[:cancel_sent]
47
- error! _("Cancel enforced: the task might be still running on the proxy")
74
+ error! ForemanTasks::Task::TaskCancelledException.new(_("Cancel enforced: the task might be still running on the proxy"))
48
75
  else
49
76
  proxy.cancel_task(output[:proxy_task_id])
50
77
  output[:cancel_sent] = true
@@ -78,5 +105,65 @@ module Actions
78
105
  def proxy_output=(output)
79
106
  output[:proxy_output] = output
80
107
  end
108
+
109
+ def metadata
110
+ output[:metadata] ||= {}
111
+ output[:metadata]
112
+ end
113
+
114
+ def metadata=(thing)
115
+ output[:metadata] ||= {}
116
+ output[:metadata] = thing
117
+ end
118
+
119
+ def timeout_set?
120
+ !metadata[:timeout].nil?
121
+ end
122
+
123
+ def set_timeout!
124
+ time = Time.now + input[:connection_options][:timeout]
125
+ schedule_timeout(time)
126
+ metadata[:timeout] = time.to_s
127
+ end
128
+
129
+ def default_connection_options
130
+ # Fails if the plan is not finished within 60 seconds from the first task trigger attempt on the smart proxy
131
+ # If the triggering fails, it retries 3 more times with 15 second delays
132
+ { :retry_interval => 15, :retry_count => 4, :timeout => 60 }
133
+ end
134
+
135
+ private
136
+
137
+ def with_connection_error_handling(event = nil)
138
+ yield event
139
+ rescue ::RestClient::Exception, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ETIMEDOUT => e
140
+ if event.class == CallbackData || event == ::Dynflow::Action::Timeouts::Timeout
141
+ raise e
142
+ else
143
+ handle_connection_exception(e, event)
144
+ end
145
+ end
146
+
147
+ def format_exception(exception)
148
+ { output[:proxy_task_id] =>
149
+ { :exception_class => exception.class.name,
150
+ :execption_message => exception.message } }
151
+ end
152
+
153
+ def handle_connection_exception(exception, event = nil)
154
+ metadata[:failed_proxy_tasks] ||= []
155
+ options = input[:connection_options]
156
+ metadata[:failed_proxy_tasks] << format_exception(exception)
157
+ output[:proxy_task_id] = nil
158
+ if metadata[:failed_proxy_tasks].count < options[:retry_count]
159
+ suspend do |suspended_action|
160
+ @world.clock.ping suspended_action,
161
+ Time.now + options[:retry_interval],
162
+ event
163
+ end
164
+ else
165
+ raise exception
166
+ end
167
+ end
81
168
  end
82
169
  end
@@ -0,0 +1,26 @@
1
+ module Actions
2
+ module Serializers
3
+
4
+ class ActiveRecordSerializer < ::Dynflow::Serializers::Noop
5
+ def serialize(arg)
6
+ if arg.is_a? ActiveRecord::Base
7
+ { :active_record_object => true,
8
+ :class_name => arg.class.name,
9
+ :id => arg.id }
10
+ else
11
+ super arg
12
+ end
13
+ end
14
+
15
+ def deserialize(arg)
16
+ if arg.is_a?(Hash) && arg[:active_record_object]
17
+ arg[:class_name].constantize.find(arg[:id])
18
+ else
19
+ super arg
20
+ end
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+
@@ -22,10 +22,14 @@ module ProxyAPI
22
22
  MultiJson.load(Task.new(@args).send(:post, payload))
23
23
  end
24
24
 
25
- # Initiate the command
25
+ # Cancel the command
26
26
  def cancel_task(proxy_task_id)
27
27
  MultiJson.load(Task.new(@args).send(:post, "", "#{ proxy_task_id }/cancel"))
28
28
  end
29
+
30
+ def status_of_task(proxy_task_id)
31
+ MultiJson.load(Task.new(@args).send(:get, "#{ proxy_task_id }/status"))
32
+ end
29
33
  end
30
34
  end
31
35
  end
@@ -23,6 +23,7 @@ module ForemanTasks
23
23
  scoped_search :on => :state, :complete_value => true
24
24
  scoped_search :on => :result, :complete_value => true
25
25
  scoped_search :on => :started_at, :complete_value => false
26
+ scoped_search :on => :ended_at, :complete_value => false
26
27
  scoped_search :on => :parent_task_id, :complete_value => true
27
28
  scoped_search :in => :locks, :on => :resource_type, :complete_value => true, :rename => "resource_type", :ext_method => :search_by_generic_resource
28
29
  scoped_search :in => :locks, :on => :resource_id, :complete_value => false, :rename => "resource_id", :ext_method => :search_by_generic_resource
@@ -66,9 +67,10 @@ module ForemanTasks
66
67
  end
67
68
 
68
69
  # returns true if the task is running or waiting to be run
69
- def pending
70
+ def pending?
70
71
  self.state != 'stopped'
71
72
  end
73
+ alias_method :pending, :pending?
72
74
 
73
75
  def resumable?
74
76
  false
@@ -11,6 +11,8 @@ module ForemanTasks
11
11
  self.ended_at = data[:ended_at]
12
12
  self.state = data[:state].to_s
13
13
  self.result = data[:result].to_s
14
+ self.start_at = data[:start_at] if data[:start_at]
15
+ self.start_before = data[:start_before] if data[:start_before]
14
16
  self.parent_task_id ||= begin
15
17
  if main_action.caller_execution_plan_id
16
18
  DynflowTask.find_by_external_id!(main_action.caller_execution_plan_id).id
@@ -102,10 +104,16 @@ module ForemanTasks
102
104
  logger.warn("Task %s updated at consistency check: %s" % [task.id, changes.inspect])
103
105
  end
104
106
  rescue => e
105
- Foreman::Logging.exception("Failed at consistency check for task #{task.id}", e, :logger => logger)
107
+ Foreman::Logging.exception("Failed at consistency check for task #{task.id}", e, :logger => 'foreman-tasks')
106
108
  end
107
109
  end
108
110
  return fixed_count
109
111
  end
112
+
113
+ def self.new_for_execution_plan(execution_plan_id, data)
114
+ self.new(:external_id => execution_plan_id,
115
+ :state => data[:state].to_s,
116
+ :result => data[:result].to_s)
117
+ end
110
118
  end
111
119
  end
@@ -1,8 +1,8 @@
1
1
  module ForemanTasks
2
2
  class Task::Summarizer
3
3
  def summarize_by_status(since=nil)
4
- result = ::ForemanTasks::Task.select('count(state), state, result').group(:state, :result).order(:state)
5
- result.where('started_at > ?', since) if since
4
+ result = ::ForemanTasks::Task.select('count(state) AS count, state, result').group(:state, :result).order(:state)
5
+ result = result.where('started_at > ?', since) if since
6
6
  result
7
7
  end
8
8
 
@@ -0,0 +1,7 @@
1
+ module ForemanTasks
2
+ class Task::TaskCancelledException < ::Foreman::Exception
3
+ def backtrace
4
+ []
5
+ end
6
+ end
7
+ end
@@ -95,13 +95,25 @@
95
95
  <span class="param-name"><%= _("Owner") %>:</span>
96
96
  <span class="param-value"><%= @task.username %></span>
97
97
  </div>
98
+ <div>
99
+ <span class="param-name"><%= _("Execution type") %>:</span>
100
+ <span class="param-value"><%= @task.start_at.nil? ? _('Immediate') : _('Delayed') %></span>
101
+ </div>
102
+ <div>
103
+ <span class="param-name"><%= _("Start at") %>:</span>
104
+ <span class="param-value"><%= @task.start_at.nil? ? '-' : @task.start_at %></span>
105
+ </div>
106
+ <div>
107
+ <span class="param-name"><%= _("Start before") %>:</span>
108
+ <span class="param-value"><%= @task.start_before.nil? ? '-' : @task.start_before %></span>
109
+ </div>
98
110
  <div>
99
111
  <span class="param-name"><%= _("Started at") %>:</span>
100
- <span class="param-value"><%= @task.started_at %></span>
112
+ <span class="param-value"><%= @task.started_at.try(:in_time_zone) %></span>
101
113
  </div>
102
114
  <div>
103
115
  <span class="param-name"><%= _("Ended at") %>:</span>
104
- <span class="param-value"><%= @task.ended_at %></span>
116
+ <span class="param-value"><%= @task.ended_at.try(:in_time_zone) %></span>
105
117
  </div>
106
118
  <div>
107
119
  <span class="param-name"><%= _("State") %>:</span>
@@ -32,6 +32,7 @@ $(document).on('click', ".table-two-pane td.two-pane-link", function(e) {
32
32
  <th><%= _("State") %></th>
33
33
  <th><%= _("Result") %></th>
34
34
  <th><%= sort :started_at, :as => _("Started at") %></th>
35
+ <th><%= sort :ended_at, :as => _("Ended at") %></th>
35
36
  <th><%= _("User") %></th>
36
37
  </tr>
37
38
  <% for task in @tasks %>
@@ -42,7 +43,8 @@ $(document).on('click', ".table-two-pane td.two-pane-link", function(e) {
42
43
  </td>
43
44
  <td><%= task.state %></td>
44
45
  <td><%= task.result %></td>
45
- <td><%= task.started_at %></td>
46
+ <td><%= task.started_at.try(:in_time_zone) %></td>
47
+ <td><%= task.ended_at.try(:in_time_zone) %></td>
46
48
  <td><%= task.username %></td>
47
49
  </tr>
48
50
  <% end %>
@@ -0,0 +1,6 @@
1
+ class AddDelayAttributes < ActiveRecord::Migration
2
+ def change
3
+ add_column :foreman_tasks_tasks, :start_at, :datetime, index: true, default: nil, null: true
4
+ add_column :foreman_tasks_tasks, :start_before, :datetime, index: true, default: nil, null: true
5
+ end
6
+ end
@@ -0,0 +1,12 @@
1
+ Bookmark.without_auditing do
2
+ [
3
+ { :name => "running", :query => "state = running" },
4
+ { :name => "failed", :query => "state = paused or result = error or result = warning" }
5
+
6
+ ].each do |item|
7
+ next if Bookmark.find_by_name(item[:name])
8
+ next if audit_modified? Bookmark, item[:name]
9
+ b = Bookmark.create({:controller => "foreman_tasks_tasks", :public => true}.merge(item))
10
+ raise "Unable to create bookmark: #{format_errors b}" if b.nil? || b.errors.any?
11
+ end
12
+ end
data/lib/foreman_tasks.rb CHANGED
@@ -40,4 +40,9 @@ module ForemanTasks
40
40
  raise TaskError.new(task) if task.execution_plan.error?
41
41
  end
42
42
  end
43
+
44
+ def self.delay(action, delay_options, *args)
45
+ result = dynflow.world.delay action, delay_options, *args
46
+ ForemanTasks::Task::DynflowTask.find_by_external_id!(result.id)
47
+ end
43
48
  end
@@ -13,7 +13,7 @@ module ForemanTasks
13
13
  begin
14
14
  on_execution_plan_save(execution_plan_id, value)
15
15
  rescue => e
16
- Foreman::Logging.exception("Error on on_execution_plan_save event", e, :logger => Foreman::Logging.logger('foreman-tasks/dynflow'))
16
+ Foreman::Logging.exception("Error on on_execution_plan_save event", e, :logger => 'foreman-tasks/dynflow')
17
17
  end
18
18
  end
19
19
  ensure
@@ -23,11 +23,22 @@ module ForemanTasks
23
23
  def on_execution_plan_save(execution_plan_id, data)
24
24
  # We can load the data unless the execution plan was properly planned and saved
25
25
  # including its steps
26
- if data[:state] == :planning
27
- task = ::ForemanTasks::Task::DynflowTask.new
26
+ case data[:state]
27
+ when :pending
28
+ ForemanTasks::Task::DynflowTask.new_for_execution_plan(execution_plan_id, data).save!
29
+ when :scheduled
30
+ delayed_plan = load_delayed_plan(execution_plan_id)
31
+ raise Foreman::Exception.new('Plan is delayed but the delay record is missing') if delayed_plan.nil?
32
+ # TODO: Rework this
33
+ delayed_plan = ::Dynflow::DelayedPlan.new_from_hash(ForemanTasks.dynflow.world, delayed_plan)
34
+ task = ::ForemanTasks::Task::DynflowTask.find_by_external_id(execution_plan_id)
35
+ task.update_from_dynflow(data.merge(:start_at => delayed_plan.start_at,
36
+ :start_before => delayed_plan.start_before))
37
+ when :planning
38
+ task = ::ForemanTasks::Task::DynflowTask.find_by_external_id(execution_plan_id)
28
39
  task.update_from_dynflow(data)
29
40
  Lock.owner!(::User.current, task.id) if ::User.current
30
- elsif data[:state] != :pending
41
+ else
31
42
  if task = ::ForemanTasks::Task::DynflowTask.find_by_external_id(execution_plan_id)
32
43
  unless task.state.to_s == data[:state].to_s
33
44
  task.update_from_dynflow(data)
@@ -21,5 +21,9 @@ module ForemanTasks
21
21
  def sync_task(action, *args, &block)
22
22
  foreman_tasks.sync_task(action, *args, &block)
23
23
  end
24
+
25
+ def delay(action, delay_options, *args)
26
+ foreman_tasks.delay(action, delay_options, *args)
27
+ end
24
28
  end
25
29
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanTasks
2
- VERSION = "0.7.3"
2
+ VERSION = "0.7.4"
3
3
  end
@@ -40,8 +40,8 @@ module ForemanTasks
40
40
  task.reload
41
41
  task.state.must_equal 'stopped'
42
42
  task.result.must_equal 'success'
43
- task.main_action.output.must_equal({ "proxy_task_id" => "123",
44
- "proxy_output" => { "result" => "success" }})
43
+ task.main_action.output['proxy_task_id'].must_equal "123"
44
+ task.main_action.output['proxy_output'].must_equal({ 'result' => 'success' })
45
45
  end
46
46
  end
47
47
  end
@@ -17,6 +17,7 @@ module ForemanTasks
17
17
  proxy_call = Support::DummyProxyAction.proxy.log[:trigger_task].first
18
18
  proxy_call.must_equal(["Proxy::DummyAction",
19
19
  { "foo" => "bar",
20
+ "connection_options" => { "retry_interval" => 15, "retry_count" => 4, "timeout" => 60 },
20
21
  "proxy_url" => "proxy.example.com",
21
22
  "callback" => { "task_id" => "123", "step_id" => @action.run_step_id }}])
22
23
  end
@@ -61,6 +62,23 @@ module ForemanTasks
61
62
  action = run_action(@action, ::Actions::ProxyAction::CallbackData.new('result' => 'success'))
62
63
  action.output[:proxy_output].must_equal({'result' => 'success'})
63
64
  end
65
+
66
+ it 'handles connection errors' do
67
+ action = create_and_plan_action(Support::DummyProxyAction, Support::DummyProxyAction.proxy, { :foo => 'bar' })
68
+ run_stubbed_action = lambda do |lambda_action|
69
+ run_action lambda_action do |block_action|
70
+ block_action.expects(:trigger_proxy_task).raises(Errno::ECONNREFUSED.new('Connection refused'))
71
+ end
72
+ end
73
+ action = run_stubbed_action.call action
74
+ action.state.must_equal :suspended
75
+ action.world.clock.pending_pings.length.must_equal 1
76
+ action.output[:metadata][:failed_proxy_tasks].length.must_equal 1
77
+ 2.times { action.output[:metadata][:failed_proxy_tasks] << {} }
78
+ proc { action = run_stubbed_action.call action }.must_raise(Errno::ECONNREFUSED)
79
+ action.state.must_equal :error
80
+ end
81
+
64
82
  end
65
83
 
66
84
  end
@@ -14,7 +14,7 @@ class TasksTest < ActiveSupport::TestCase
14
14
  FactoryGirl.create(:dynflow_task, :product_create_task)]
15
15
  cleaner.delete
16
16
  ForemanTasks::Task.where(id: tasks_to_delete).must_be_empty
17
- ForemanTasks::Task.where(id: tasks_to_keep).must_equal tasks_to_keep
17
+ ForemanTasks::Task.where(id: tasks_to_keep).order(:id).map(&:id).must_equal tasks_to_keep.map(&:id).sort
18
18
 
19
19
  ForemanTasks.dynflow.world.persistence.
20
20
  find_execution_plans(filters: {'uuid' => tasks_to_delete.map(&:external_id)}).size.must_equal 0
@@ -41,12 +41,13 @@ class TasksTest < ActiveSupport::TestCase
41
41
  let(:inconsistent_task) { FactoryGirl.create(:dynflow_task, :inconsistent_dynflow_task) }
42
42
 
43
43
  it 'ensures the tasks marked as running are really running in Dynflow' do
44
+ running_task_count = ForemanTasks::Task::DynflowTask.running.count
44
45
  consistent_task.state.must_equal 'planned'
45
46
  inconsistent_task.state.must_equal 'running'
46
47
 
47
48
  fixed_count = ForemanTasks::Task::DynflowTask.consistency_check
48
49
 
49
- fixed_count.must_equal 1
50
+ fixed_count.must_equal running_task_count + 1
50
51
  consistent_task.reload.state.must_equal 'planned'
51
52
  inconsistent_task.reload.state.must_equal 'planned'
52
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.3
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nečas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-13 00:00:00.000000000 Z
11
+ date: 2015-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dynflow
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 0.8.3
19
+ version: 0.8.6
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
- version: 0.8.3
26
+ version: 0.8.6
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sequel
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -105,6 +105,7 @@ files:
105
105
  - app/lib/actions/helpers/lock.rb
106
106
  - app/lib/actions/middleware/keep_current_user.rb
107
107
  - app/lib/actions/proxy_action.rb
108
+ - app/lib/actions/serializers/active_record_serializer.rb
108
109
  - app/lib/proxy_api/foreman_dynflow/dynflow_proxy.rb
109
110
  - app/models/foreman_tasks/concerns/action_subject.rb
110
111
  - app/models/foreman_tasks/concerns/action_triggering.rb
@@ -115,6 +116,7 @@ files:
115
116
  - app/models/foreman_tasks/task/dynflow_task.rb
116
117
  - app/models/foreman_tasks/task/status_explicator.rb
117
118
  - app/models/foreman_tasks/task/summarizer.rb
119
+ - app/models/foreman_tasks/task/task_cancelled_exception.rb
118
120
  - app/models/setting/foreman_tasks.rb
119
121
  - app/views/foreman_tasks/api/tasks/show.json.rabl
120
122
  - app/views/foreman_tasks/tasks/_details.html.erb
@@ -134,8 +136,10 @@ files:
134
136
  - db/migrate/20131209122644_create_foreman_tasks_locks.rb
135
137
  - db/migrate/20140324104010_remove_foreman_tasks_progress.rb
136
138
  - db/migrate/20140813215942_add_parent_task_id.rb
139
+ - db/migrate/20150817102538_add_delay_attributes.rb
137
140
  - db/seeds.d/20-foreman_tasks_permissions.rb
138
141
  - db/seeds.d/60-dynflow_proxy_feature.rb
142
+ - db/seeds.d/61-foreman_tasks_bookmarks.rb
139
143
  - deploy/foreman-tasks.init
140
144
  - deploy/foreman-tasks.service
141
145
  - deploy/foreman-tasks.sysconfig