foreman-tasks 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
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