foreman-tasks 0.7.16 → 0.7.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31ae188eb51b073634a6022419eca1a9da0386ae
4
- data.tar.gz: ac58624747c4767a2a6281a5b528bd7bec73cdfc
3
+ metadata.gz: 6af64bff2142846ebf7fcc41ca5202b3f1bf5850
4
+ data.tar.gz: a001ea05b594c4180546b6505f20fd66bf01e14b
5
5
  SHA512:
6
- metadata.gz: 6ee4441852726080335eed0f0b98b50a90aab99cebeacc774bff9e213068d4d6853338007d7b589a04703f96abd6792721a186536e48d58281f758ed1cb48655
7
- data.tar.gz: 2989a4a292c841fcc829f9b3882edb3702915a0e40f32115c722fde27bf74c9f68507830df9938643c9f98a6673d58b6abd786a73f220c3d4114eda9225d7cb1
6
+ metadata.gz: 995c854d10a044c6cdcd8d33b52b342b639d134623145afe198908936f3c4d14ca2ab97dbdcf4c3f2703b8c27253da788ac87913009f35e633ba8139f862264e
7
+ data.tar.gz: 343184b0db3a10549586fdda4fc0e89361f39a9dc8576ebdcfc466f0c044411c7abfb5de6c3dfc34c4f65145fa4ab171c2d5cd22263845ec964bb72d55fe0294
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  module ForemanTasks
2
3
  module ForemanTasksHelper
3
4
 
@@ -39,10 +40,26 @@ module ForemanTasks
39
40
  end
40
41
  end
41
42
 
43
+ def date_f(f, attr, field_options = {}, date_options = {}, html_options = {})
44
+ f.fields_for attr do |fields|
45
+ field(fields, attr, field_options) do
46
+ fields.date_select attr, date_options, html_options
47
+ end
48
+ end
49
+ end
50
+
42
51
  def datetime_f(f, attr, field_options = {}, datetime_options = {}, html_options = {})
43
52
  f.fields_for attr do |fields|
44
53
  field(fields, attr, field_options) do
45
- fields.datetime_select attr, datetime_options, html_options
54
+ [
55
+ content_tag(:span, nil, :class => 'date', :style => 'white-space: nowrap;') do
56
+ fields.date_select(attr, datetime_options, html_options)
57
+ end,
58
+ ' — ',
59
+ content_tag(:span, nil, :class => 'time', :style => 'white-space: nowrap;') do
60
+ fields.time_select(attr, datetime_options.merge(:ignore_date => true), html_options)
61
+ end
62
+ ].join
46
63
  end
47
64
  end
48
65
  end
@@ -45,6 +45,25 @@ module ForemanTasks
45
45
  dynflow_task_wrap(:save) { super(*args) }
46
46
  end
47
47
 
48
+ # this can be used when HostActionSubject is used for orchestration but you want to avoid
49
+ # triggering more tasks by ActiveRecord callbacks within run/finalize phase of your task
50
+ # e.g. host.disable_dynflow_hooks { |h| h.save }
51
+ def disable_dynflow_hooks(&block)
52
+ @_disable_dynflow_hooks = true
53
+
54
+ if block_given?
55
+ begin
56
+ block.call(self)
57
+ ensure
58
+ @_disable_dynflow_hooks = false
59
+ end
60
+ end
61
+ end
62
+
63
+ def enable_dynflow_hooks
64
+ @_disable_dynflow_hooks = false
65
+ end
66
+
48
67
  protected
49
68
 
50
69
  def sync_action_flag_reset!
@@ -96,6 +115,7 @@ module ForemanTasks
96
115
  # to unexpected results.
97
116
  def dynflow_task_wrap(method)
98
117
  if ForemanTasks.dynflow.config.disable_active_record_actions ||
118
+ @_disable_dynflow_hooks ||
99
119
  @_dynflow_task_wrapped
100
120
  return yield
101
121
  end
@@ -15,8 +15,6 @@ module ForemanTasks
15
15
  has_many :task_groups, -> { uniq }, :through => :tasks
16
16
  end
17
17
 
18
- validates :cron_line, :presence => true
19
-
20
18
  scoped_search :on => :id, :complete_value => false
21
19
  scoped_search :on => :max_iteration, :complete_value => false, :rename => :iteration_limit
22
20
  scoped_search :on => :iteration, :complete_value => false
@@ -69,12 +67,25 @@ module ForemanTasks
69
67
  }
70
68
  end
71
69
 
72
- def can_continue?(time = Time.now)
73
- self.state == 'active' &&
74
- (end_time.nil? || next_occurrence_time(time) < end_time) &&
70
+ def valid?(*_)
71
+ cron_line.present? && valid_cronline? && !self.state.nil? || can_start?
72
+ end
73
+
74
+ def valid_cronline?
75
+ !!next_occurrence_time
76
+ rescue ArgumentError => _
77
+ false
78
+ end
79
+
80
+ def can_start?(time = Time.now)
81
+ (end_time.nil? || next_occurrence_time(time) < end_time) &&
75
82
  (max_iteration.nil? || iteration < max_iteration)
76
83
  end
77
84
 
85
+ def can_continue?(time = Time.now)
86
+ self.state == 'active' && can_start?(time)
87
+ end
88
+
78
89
  def finished?
79
90
  self.state == 'finished'
80
91
  end
@@ -15,10 +15,6 @@ module ForemanTasks
15
15
  end
16
16
  end
17
17
 
18
- after_find do |triggering|
19
- triggering.mode = triggering.mode.to_sym
20
- end
21
-
22
18
  ALLOWED_MODES = [:immediate, :future, :recurring]
23
19
  ALLOWED_INPUT_TYPES = [:cronline, :monthly, :weekly, :daily, :hourly]
24
20
 
@@ -39,7 +35,8 @@ module ForemanTasks
39
35
  :message => _("%{value} is wrong format"), :allow_blank => true
40
36
  validates_format_of :days, :with => DAYS_REGEXP,
41
37
  :if => Proc.new { |t| t.recurring? && t.input_type == :monthly }
42
- validate :correct_cronline, :if => Proc.new { |t| t.recurring? && t.input_type == :cronline }
38
+ validate :can_start_recurring, :if => :recurring?
39
+ validate :can_start_future, :if => :future?
43
40
 
44
41
  def self.new_from_params(params = {})
45
42
  self.new(params.except(:mode, :start_at, :start_before)).tap do |triggering|
@@ -47,6 +44,19 @@ module ForemanTasks
47
44
  triggering.input_type = params.fetch(:input_type, :daily).to_sym
48
45
  triggering.end_time_limited = params[:end_time_limited] == "true"
49
46
  triggering.start_at_raw ||= Time.now.strftime(TIME_FORMAT)
47
+ triggering.recurring_logic = ::ForemanTasks::RecurringLogic.new_from_triggering(triggering) if triggering.recurring?
48
+ end
49
+ end
50
+
51
+ def mode
52
+ super.to_sym
53
+ end
54
+
55
+ def mode=(mod)
56
+ if (mod.is_a?(String) || mod.is_a?(Symbol)) && ALLOWED_MODES.map(&:to_s).include?(mod.downcase.to_s)
57
+ super(mod.downcase.to_sym)
58
+ else
59
+ raise ArgumentError, _('mode has to be one of %{allowed_modes}') % { :allowed_modes => ALLOWED_MODES.join(', ') }
50
60
  end
51
61
  end
52
62
 
@@ -59,8 +69,7 @@ module ForemanTasks
59
69
  delay_options,
60
70
  *args
61
71
  when :recurring
62
- ::ForemanTasks::RecurringLogic.new_from_triggering(self)
63
- .start(action, *args)
72
+ recurring_logic.start(action, *args)
64
73
  end
65
74
  end
66
75
 
@@ -93,10 +102,15 @@ module ForemanTasks
93
102
 
94
103
  private
95
104
 
96
- def correct_cronline
97
- ForemanTasks::RecurringLogic.new_from_cronline(cronline).next_occurrence_time
98
- rescue ArgumentError => _
99
- self.errors.add(:cronline, _("%s is not valid format of cron line")) % (cronline)
105
+ def can_start_recurring
106
+ self.errors.add(:input_type, _('No task could be started')) unless recurring_logic.valid?
107
+ self.errors.add(:cronline, _('%s is not valid format of cron line') % (cronline)) unless recurring_logic.valid_cronline?
108
+ end
109
+
110
+ def can_start_future
111
+ parse_start_before!
112
+ parse_start_at!
113
+ self.errors.add(:start_before_raw, _('The task could not be started')) if !start_before.nil? && start_before < start_at
100
114
  end
101
115
  end
102
116
  end
@@ -12,11 +12,12 @@
12
12
  <%= radio_button_f trigger_fields, :mode, :class => 'trigger_mode_selector', :value => 'immediate', :text => _("Execute now") %>
13
13
  <%= radio_button_f trigger_fields, :mode, :class => 'trigger_mode_selector', :value => 'future', :text => _("Schedule future execution") %>
14
14
  <%= radio_button_f trigger_fields, :mode, :class => 'trigger_mode_selector', :value => 'recurring', :text => _("Set up recurring execution") %>
15
-
16
- <div class="trigger_fields">
17
- <%= future_mode_fieldset trigger_fields, triggering %>
18
- <%= recurring_mode_fieldset trigger_fields, triggering %>
19
- </div>
20
- <% end %>
21
15
  </div>
22
16
  </div>
17
+
18
+ <div class="trigger_fields">
19
+ <%= future_mode_fieldset trigger_fields, triggering %>
20
+ <%= recurring_mode_fieldset trigger_fields, triggering %>
21
+ </div>
22
+ <% end %>
23
+
@@ -93,6 +93,14 @@ namespace :foreman_tasks do
93
93
  end
94
94
  end
95
95
 
96
+ def show_world(world_id)
97
+ if registered_world = world.coordinator.find_worlds(false, id: world_id).first
98
+ "%{world_id} %{world_meta}" % { world_id: world_id, world_meta: registered_world.meta.inspect }
99
+ else
100
+ world_id
101
+ end
102
+ end
103
+
96
104
  def show_action_data(label, value)
97
105
  value_html = prettyprint(value)
98
106
  if !value_html.empty?
@@ -1,3 +1,3 @@
1
1
  module ForemanTasks
2
- VERSION = "0.7.16"
2
+ VERSION = "0.7.17"
3
3
  end
@@ -13,6 +13,7 @@ FactoryGirl.define do
13
13
  mode :recurring
14
14
  input_type :cronline
15
15
  cronline '* * * * *'
16
+ after(:build) { |triggering| triggering.recurring_logic = build(:recurring_logic) }
16
17
  end
17
18
 
18
19
  trait :end_time_limited do
@@ -87,9 +87,34 @@ class RecurringLogicsTest < ActiveSupport::TestCase
87
87
  end
88
88
 
89
89
  it 'can be created from triggering' do
90
- triggering = FactoryGirl.create(:triggering, :recurring, :end_time_limited)
90
+ triggering = FactoryGirl.build(:triggering, :recurring, :end_time_limited)
91
91
  logic = ForemanTasks::RecurringLogic.new_from_triggering(triggering)
92
92
  logic.end_time.must_equal triggering.end_time
93
93
  end
94
+
95
+ describe 'validation' do
96
+ let(:logic) { FactoryGirl.build(:recurring_logic) }
97
+
98
+ it 'is valid by default' do
99
+ logic.must_be :valid?
100
+ end
101
+
102
+ it 'is invalid when end time in past' do
103
+ logic.end_time = (Time.now - 120)
104
+ logic.wont_be :valid?
105
+ end
106
+
107
+ it 'is invalid when iteration limit < 1' do
108
+ logic.max_iteration = 0
109
+ logic.wont_be :valid?
110
+ end
111
+
112
+ it 'is valid when in active state' do
113
+ logic.end_time = (Time.now - 120)
114
+ logic.wont_be :valid?
115
+ logic.state = 'active'
116
+ logic.must_be :valid?
117
+ end
118
+ end
94
119
  end
95
120
  end
@@ -0,0 +1,31 @@
1
+ require 'foreman_tasks_test_helper'
2
+
3
+ class TriggeringTest < ActiveSupport::TestCase
4
+
5
+ describe 'validation' do
6
+ it 'is valid when immediate' do
7
+ FactoryGirl.build(:triggering).must_be :valid?
8
+ end
9
+
10
+ it 'is validates future execution' do
11
+ triggering = FactoryGirl.build(:triggering, :future)
12
+ triggering.must_be :valid?
13
+ triggering.start_before = triggering.start_at - 120
14
+ triggering.wont_be :valid?
15
+ end
16
+
17
+ it 'is invalid when recurring logic is invalid' do
18
+ triggering = FactoryGirl.build(:triggering, :recurring)
19
+ triggering.must_be :valid?
20
+ triggering.recurring_logic.stubs(:valid?).returns(false)
21
+ triggering.wont_be :valid?
22
+ end
23
+ end
24
+
25
+ it 'cannot have mode set to arbitrary value' do
26
+ triggering = FactoryGirl.build(:triggering)
27
+ triggering.must_be :valid?
28
+ proc { triggering.mode = 'bogus' }.must_raise ArgumentError
29
+ proc { triggering.mode = 27 }.must_raise ArgumentError
30
+ end
31
+ 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.16
4
+ version: 0.7.17
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: 2016-04-08 00:00:00.000000000 Z
11
+ date: 2016-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dynflow
@@ -225,6 +225,7 @@ files:
225
225
  - test/unit/recurring_logic_test.rb
226
226
  - test/unit/task_groups_test.rb
227
227
  - test/unit/task_test.rb
228
+ - test/unit/triggering_test.rb
228
229
  homepage: https://github.com/theforeman/foreman-tasks
229
230
  licenses: []
230
231
  metadata: {}
@@ -265,4 +266,5 @@ test_files:
265
266
  - test/unit/recurring_logic_test.rb
266
267
  - test/unit/task_groups_test.rb
267
268
  - test/unit/task_test.rb
269
+ - test/unit/triggering_test.rb
268
270
  has_rdoc: