foreman_remote_execution 10.1.0 → 11.1.0

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
  SHA256:
3
- metadata.gz: 25c5d179ccedf9911c0f95df7a9c020567b350a668923a589462b89d9fbe056e
4
- data.tar.gz: f49191c9a787288bbf00e1049ae65aa9633fb2b06e5491eb690f463f59d29442
3
+ metadata.gz: '019c69e822a9bf8be86315b9cbdf83901e05e0209c115c82a815e92bf0f912e8'
4
+ data.tar.gz: 7349a60661ccf18d18874a4332a0267dfc535c29fc3871182898dbd8bcf70091
5
5
  SHA512:
6
- metadata.gz: ece23e8faa1a113183be16083d6ffee2cfeb8d0e3c460272f9ba017f9eeac692fac95f4a7f87629cbf58d0974da039fd52e74476b05a47e029efd1f6104ed3d2
7
- data.tar.gz: c4891b7a8a43ec390d7b50d1bb3a7da6b19fc667a0e53d4551dd7e235da29e1bdabcf5c431e038a386e30e43a396b06e957f0fcf1366692d786b5e8778618838
6
+ metadata.gz: 97ebac293e75d109be674cb5f01bf760da29d570fa1bd5de83aee24118fb2fd739b384f2b3f058d0400b9a9579e554d2cc401f5c32cd2c557e7a5d012ae4b4ef
7
+ data.tar.gz: 15557ecad1b8b5a702fa43c235fa381e3e5a9ce18cf9479beef39c4e93e16caf361590559930f4a23de81ef917b57e7ca2a009125e8bd8aaa63559d9a5c5e4a1
@@ -62,7 +62,6 @@ module Api
62
62
  end
63
63
 
64
64
  param :concurrency_control, Hash, :desc => N_('Control concurrency level and distribution over time') do
65
- param :time_span, Integer, :desc => N_('Distribute tasks over N seconds')
66
65
  param :concurrency_level, Integer, :desc => N_('Run at most N tasks at a time')
67
66
  end
68
67
 
@@ -5,7 +5,6 @@ module Types
5
5
  global_id_field :id
6
6
  field :job_category, String
7
7
  field :description, String
8
- field :time_span, Integer
9
8
  field :start_at, GraphQL::Types::ISO8601DateTime
10
9
  field :status_label, String
11
10
 
@@ -63,7 +63,6 @@ module Actions
63
63
  :execution_timeout_interval => job_invocation.execution_timeout_interval,
64
64
  :secrets => secrets(host, job_invocation, provider),
65
65
  :use_batch_triggering => true,
66
- :use_concurrency_control => options[:use_concurrency_control],
67
66
  :first_execution => first_execution,
68
67
  :alternative_names => provider.alternative_names(host) }
69
68
  action_options = provider.proxy_command_options(template_invocation, host)
@@ -1,9 +1,6 @@
1
1
  module Actions
2
2
  module RemoteExecution
3
3
  class RunHostsJob < Actions::ActionWithSubPlans
4
-
5
- include Dynflow::Action::WithBulkSubPlans
6
- include Dynflow::Action::WithPollingSubPlans
7
4
  include Actions::RecurringAction
8
5
  include Actions::ObservableAction
9
6
 
@@ -49,7 +46,7 @@ module Actions
49
46
  # composer creates just "pattern" for template_invocations because target is evaluated
50
47
  # during actual run (here) so we build template invocations from these patterns
51
48
  template_invocation = job_invocation.pattern_template_invocation_for_host(host).deep_clone
52
- trigger(RunHostJob, job_invocation, host, template_invocation, proxy_selector, { :use_concurrency_control => uses_concurrency_control })
49
+ trigger(RunHostJob, job_invocation, host, template_invocation, proxy_selector)
53
50
  end
54
51
  end
55
52
 
@@ -60,11 +57,19 @@ module Actions
60
57
  end
61
58
 
62
59
  def trigger_remote_batch
63
- batches_ready = (output[:planned_count] - output[:remote_triggered_count]) / proxy_batch_size
64
- return unless batches_ready > 0
60
+ remaining = output[:planned_count] - output[:remote_triggered_count]
61
+ return if remaining.zero?
62
+ batches_ready = remaining / proxy_batch_size
63
+ if concurrency_limit
64
+ count = remaining
65
+ else
66
+ return unless batches_ready > 0
67
+ count = proxy_batch_size * batches_ready
68
+ end
69
+ batches_ready = [1, batches_ready].max
65
70
 
66
71
  plan_event(Actions::TriggerProxyBatch::TriggerNextBatch[batches_ready], nil, step_id: input[:trigger_run_step_id])
67
- output[:remote_triggered_count] += proxy_batch_size * batches_ready
72
+ output[:remote_triggered_count] += count
68
73
  end
69
74
 
70
75
  def on_planning_finished
@@ -126,11 +131,7 @@ module Actions
126
131
  end
127
132
 
128
133
  def set_up_concurrency_control(invocation)
129
- limit_concurrency_level invocation.concurrency_level unless invocation.concurrency_level.nil?
130
- unless invocation.time_span.nil?
131
- distribute_over_time(invocation.time_span,
132
- invocation.targeting.hosts.count)
133
- end
134
+ limit_concurrency_level! invocation.concurrency_level unless invocation.concurrency_level.nil?
134
135
  end
135
136
 
136
137
  def rescue_strategy
@@ -79,7 +79,6 @@ class JobInvocationComposer
79
79
 
80
80
  def concurrency_control_params
81
81
  {
82
- :time_span => job_invocation_base[:time_span],
83
82
  :level => job_invocation_base[:concurrency_level],
84
83
  }
85
84
  end
@@ -175,7 +174,6 @@ class JobInvocationComposer
175
174
  def concurrency_control_params
176
175
  {
177
176
  :level => api_params.fetch(:concurrency_control, {})[:concurrency_level],
178
- :time_span => api_params.fetch(:concurrency_control, {})[:time_span],
179
177
  }
180
178
  end
181
179
 
@@ -256,7 +254,6 @@ class JobInvocationComposer
256
254
  def concurrency_control_params
257
255
  {
258
256
  :level => job_invocation.concurrency_level,
259
- :time_span => job_invocation.time_span,
260
257
  }
261
258
  end
262
259
 
@@ -411,7 +408,6 @@ class JobInvocationComposer
411
408
  job_invocation.triggering = build_triggering
412
409
  job_invocation.pattern_template_invocations = build_template_invocations
413
410
  job_invocation.description_format = params[:description_format]
414
- job_invocation.time_span = params[:concurrency_control][:time_span].to_i if params[:concurrency_control][:time_span].present?
415
411
  job_invocation.concurrency_level = params[:concurrency_control][:level].to_i if params[:concurrency_control][:level].present?
416
412
  job_invocation.execution_timeout_interval = params[:execution_timeout_interval]
417
413
  job_invocation.password = params[:password]
@@ -1,4 +1,4 @@
1
- <% if job_invocation.concurrency_level || job_invocation.time_span ||
1
+ <% if job_invocation.concurrency_level ||
2
2
  (job_invocation.task && (job_invocation.task.delayed? || job_invocation.task.recurring?)) ||
3
3
  job_invocation.execution_timeout_interval.present? %>
4
4
  <div class="card-pf card-pf-accented">
@@ -13,9 +13,6 @@
13
13
  <% if job_invocation.concurrency_level %>
14
14
  <li><b><%= _("Concurrency level limited to") %></b>: <%= job_invocation.concurrency_level %> <%= _('tasks at a time') %><br></li>
15
15
  <% end %>
16
- <% if job_invocation.time_span %>
17
- <li><b><%= _("Set to distribute over") %></b>: <%= job_invocation.time_span %> <%= _('seconds') %><br></li>
18
- <% end %>
19
16
  <% if job_invocation.start_before %>
20
17
  <li><b><%= _("Scheduled to start before") %></b>: <%= job_invocation.start_before %><br></li>
21
18
  <% end %>
@@ -114,7 +114,6 @@
114
114
 
115
115
  <div class="advanced hidden">
116
116
  <%= number_f f, :concurrency_level, :label => _('Concurrency level'), :placeholder => 'N', :min => 1, :label_help => N_("Run at most N tasks at a time. If this is set and proxy batch triggering is enabled, then tasks are triggered on the smart proxy in batches of size 1.") %>
117
- <%= number_f f, :time_span, :label => _('Time span'), :placeholder => 'N', :min => 1, :label_help => N_("Distribute execution over N seconds. If this is set and proxy batch triggering is enabled, then tasks are triggered on the smart proxy in batches of size 1.") %>
118
117
  </div>
119
118
 
120
119
  <div class="form-group advanced hidden">
@@ -1,12 +1,12 @@
1
1
  class AddHostProxyInvocations < ActiveRecord::Migration[6.0]
2
2
  def change
3
3
  # rubocop:disable Rails/CreateTableWithTimestamps
4
- create_table :host_proxy_invocations do |t|
4
+ create_table :host_proxy_invocations, if_not_exists: true do |t|
5
5
  t.references :host, :null => false
6
6
  t.references :smart_proxy, :null => false
7
7
  end
8
8
  # rubocop:enable Rails/CreateTableWithTimestamps
9
9
 
10
- add_index :host_proxy_invocations, [:host_id, :smart_proxy_id], unique: true
10
+ add_index :host_proxy_invocations, [:host_id, :smart_proxy_id], unique: true, if_not_exists: true
11
11
  end
12
12
  end
@@ -0,0 +1,5 @@
1
+ class DropTimeSpanFromJobInvocations < ActiveRecord::Migration[6.0]
2
+ def change
3
+ remove_column :job_invocations, :time_span, :integer, :null => true
4
+ end
5
+ end
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.add_dependency 'deface'
26
26
  s.add_dependency 'dynflow', '>= 1.0.2', '< 2.0.0'
27
- s.add_dependency 'foreman-tasks', '>= 7.1.0'
27
+ s.add_dependency 'foreman-tasks', '>= 8.2.0'
28
28
 
29
29
  s.add_development_dependency 'factory_bot_rails', '~> 4.8.0'
30
30
  s.add_development_dependency 'rdoc'
@@ -47,7 +47,7 @@ module ForemanRemoteExecution
47
47
 
48
48
  initializer 'foreman_remote_execution.register_plugin', before: :finisher_hook do |_app|
49
49
  Foreman::Plugin.register :foreman_remote_execution do
50
- requires_foreman '>= 3.7'
50
+ requires_foreman '>= 3.8'
51
51
  register_global_js_file 'global'
52
52
  register_gettext
53
53
 
@@ -1,3 +1,3 @@
1
1
  module ForemanRemoteExecution
2
- VERSION = '10.1.0'.freeze
2
+ VERSION = '11.1.0'.freeze
3
3
  end
@@ -122,33 +122,14 @@ module ForemanRemoteExecution
122
122
 
123
123
  describe 'concurrency control' do
124
124
  let(:level) { 5 }
125
- let(:span) { 60 }
126
125
 
127
126
  it 'can be disabled' do
128
- job_invocation.expects(:concurrency_level)
129
- job_invocation.expects(:time_span)
130
- _(planned.input.key?(:concurrency_control)).must_equal false
127
+ _(planned.concurrency_limit).must_equal nil
131
128
  end
132
129
 
133
130
  it 'can limit concurrency level' do
134
- job_invocation.expects(:concurrency_level).returns(level).twice
135
- job_invocation.expects(:time_span)
136
- planned.input[:concurrency_control][:level].wont_be_empty
137
- planned.input[:concurrency_control].key?(:time).must_equal false
138
- end
139
-
140
- it 'can distribute tasks over time' do
141
- job_invocation.expects(:time_span).returns(span).twice
142
- job_invocation.expects(:concurrency_level)
143
- planned.input[:concurrency_control][:time].wont_be_empty
144
- planned.input[:concurrency_control].key?(:level).must_equal false
145
- end
146
-
147
- it 'can use both' do
148
- job_invocation.expects(:time_span).returns(span).twice
149
- job_invocation.expects(:concurrency_level).returns(level).twice
150
- planned.input[:concurrency_control][:time].wont_be_empty
151
- planned.input[:concurrency_control][:level].wont_be_empty
131
+ job_invocation.expects(:concurrency_level).twice.returns(level)
132
+ _(planned.concurrency_limit).must_equal level
152
133
  end
153
134
  end
154
135
 
@@ -458,18 +458,16 @@ class JobInvocationComposerTest < ActiveSupport::TestCase
458
458
 
459
459
  describe 'with concurrency control set' do
460
460
  let(:params) do
461
- { :job_invocation => { :providers => { :ssh => ssh_params }, :concurrency_level => '5', :time_span => '60' } }.with_indifferent_access
461
+ { :job_invocation => { :providers => { :ssh => ssh_params }, :concurrency_level => '5' } }.with_indifferent_access
462
462
  end
463
463
 
464
464
  it 'accepts the concurrency options' do
465
465
  _(composer.job_invocation.concurrency_level).must_equal 5
466
- _(composer.job_invocation.time_span).must_equal 60
467
466
  end
468
467
  end
469
468
 
470
469
  it 'can be disabled' do
471
470
  _(composer.job_invocation.concurrency_level).must_be_nil
472
- _(composer.job_invocation.time_span).must_be_nil
473
471
  end
474
472
  end
475
473
 
@@ -568,7 +566,6 @@ class JobInvocationComposerTest < ActiveSupport::TestCase
568
566
  :job_invocation => {
569
567
  :providers => { :ssh => ssh_params },
570
568
  :concurrency_level => 5,
571
- :time_span => 60,
572
569
  },
573
570
  :targeting => {
574
571
  :search_query => "name = #{host.name}",
@@ -607,7 +604,6 @@ class JobInvocationComposerTest < ActiveSupport::TestCase
607
604
 
608
605
  it 'sets the same concurrency control options' do
609
606
  _(new_composer.job_invocation.concurrency_level).must_equal existing.concurrency_level
610
- _(new_composer.job_invocation.time_span).must_equal existing.time_span
611
607
  end
612
608
 
613
609
  end
@@ -711,22 +707,19 @@ class JobInvocationComposerTest < ActiveSupport::TestCase
711
707
 
712
708
  context 'with concurrency_control' do
713
709
  let(:level) { 5 }
714
- let(:time_span) { 60 }
715
710
  let(:params) do
716
711
  { :job_category => trying_job_template_1.job_category,
717
712
  :job_template_id => trying_job_template_1.id,
718
713
  :concurrency_control => {
719
714
  :concurrency_level => level,
720
- :time_span => time_span,
721
715
  },
722
716
  :targeting_type => 'static_query',
723
717
  :search_query => 'some hosts',
724
718
  :inputs => { input1.name => 'some_value' } }
725
719
  end
726
720
 
727
- it 'sets the concurrency level and time span based on the input' do
721
+ it 'sets the concurrency level based on the input' do
728
722
  assert composer.save!
729
- _(composer.job_invocation.time_span).must_equal time_span
730
723
  _(composer.job_invocation.concurrency_level).must_equal level
731
724
  end
732
725
  end
@@ -127,7 +127,6 @@ export const JobWizard = ({ rerunData }) => {
127
127
  }) || '',
128
128
  isRandomizedOrdering: randomized_ordering,
129
129
  sshUser: ssh_user || '',
130
- timeSpan: concurrency_control.time_span || '',
131
130
  concurrencyLevel: concurrency_control.level || '',
132
131
  };
133
132
  });
@@ -461,7 +460,6 @@ export const JobWizard = ({ rerunData }) => {
461
460
  onClose={() => history.goBack()}
462
461
  navAriaLabel="Run Job steps"
463
462
  steps={steps}
464
- height="100%"
465
463
  className="job-wizard"
466
464
  onSave={onSave}
467
465
  footer={
@@ -491,7 +489,6 @@ JobWizard.propTypes = {
491
489
  ssh_user: PropTypes.string,
492
490
  concurrency_control: PropTypes.shape({
493
491
  level: PropTypes.number,
494
- time_span: PropTypes.number,
495
492
  }),
496
493
  execution_timeout_interval: PropTypes.number,
497
494
  time_to_pickup: PropTypes.number,
@@ -11,7 +11,6 @@
11
11
  }
12
12
 
13
13
  .pf-c-wizard__main {
14
- overflow: visible;
15
14
  z-index: calc(
16
15
  var(--pf-c-wizard__toggle--ZIndex) + 1
17
16
  ); // So the select box can be shown above the wizard footer and navigation toggle
@@ -127,7 +126,7 @@
127
126
  .pf-c-radio__body {
128
127
  font-size: var(--pf-c-radio__label--FontSize);
129
128
  }
130
- .reset-default{
129
+ .reset-default {
131
130
  padding-bottom: 0;
132
131
  }
133
132
  }
@@ -135,4 +134,4 @@
135
134
  .job-wizard-alert.pf-c-alert.pf-m-warning {
136
135
  margin-bottom: 10px;
137
136
  margin-top: 10px;
138
- }
137
+ }
@@ -75,10 +75,5 @@ describe('Job wizard fill', () => {
75
75
  selector: 'input',
76
76
  }).value
77
77
  ).toBe('6');
78
- expect(
79
- screen.getByLabelText('Time span', {
80
- selector: 'input',
81
- }).value
82
- ).toBe('4');
83
78
  });
84
79
  });
@@ -277,7 +277,6 @@ export const jobInvocation = {
277
277
  description_format: null,
278
278
  concurrency_control: {
279
279
  level: 6,
280
- time_span: 4,
281
280
  },
282
281
  execution_timeout_interval: 1,
283
282
  time_to_pickup: 25,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { Title, Divider, Flex, FlexItem, Button } from '@patternfly/react-core';
3
+ import { Title, Flex, FlexItem, Button } from '@patternfly/react-core';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
5
  import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
6
6
  import { JobWizard } from './JobWizard';
@@ -18,8 +18,7 @@ const JobWizardPage = ({ location: { search } }) => {
18
18
  header={title}
19
19
  breadcrumbOptions={breadcrumbOptions}
20
20
  searchable={false}
21
- >
22
- <React.Fragment>
21
+ beforeToolbarComponent={
23
22
  <Flex>
24
23
  <FlexItem>
25
24
  <Title headingLevel="h2" size="2xl">
@@ -36,7 +35,10 @@ const JobWizardPage = ({ location: { search } }) => {
36
35
  </Button>
37
36
  </FlexItem>
38
37
  </Flex>
39
- <Divider component="div" />
38
+ }
39
+ pageSectionType="wizard"
40
+ >
41
+ <React.Fragment>
40
42
  <JobWizard />
41
43
  </React.Fragment>
42
44
  </PageLayout>
@@ -17,7 +17,6 @@ import {
17
17
  KeyPassphraseField,
18
18
  EffectiveUserPasswordField,
19
19
  ConcurrencyLevelField,
20
- TimeSpanLevelField,
21
20
  TemplateInputsFields,
22
21
  ExecutionOrderingField,
23
22
  SSHUserField,
@@ -128,15 +127,6 @@ export const AdvancedFields = ({
128
127
  })
129
128
  }
130
129
  />
131
- <TimeSpanLevelField
132
- value={advancedValues.timeSpan}
133
- defaultValue={jobTemplate.concurrency_control?.time_span}
134
- setValue={newValue =>
135
- setAdvancedValues({
136
- timeSpan: newValue,
137
- })
138
- }
139
- />
140
130
  <ExecutionOrderingField
141
131
  isRandomizedOrdering={advancedValues.isRandomizedOrdering}
142
132
  setValue={newValue =>
@@ -169,32 +169,6 @@ export const ConcurrencyLevelField = ({ value, setValue, defaultValue }) => (
169
169
  />
170
170
  );
171
171
 
172
- export const TimeSpanLevelField = ({ value, setValue, defaultValue }) => (
173
- <NumberInput
174
- formProps={{
175
- label: __('Time span'),
176
- labelIcon: helpLabel(
177
- __(
178
- 'Distribute execution over N seconds. If this is set and proxy batch triggering is enabled, then tasks are triggered on the smart proxy in batches of size 1.'
179
- ),
180
- 'time-span'
181
- ),
182
- fieldId: 'time-span',
183
- labelInfo: (
184
- <ResetDefault setValue={setValue} defaultValue={defaultValue} />
185
- ),
186
- }}
187
- inputProps={{
188
- min: 1,
189
- autoComplete: 'time-span',
190
- id: 'time-span',
191
- placeholder: __('For example: 1, 2, 3, 4, 5...'),
192
- value,
193
- onChange: newValue => setValue(newValue),
194
- }}
195
- />
196
- );
197
-
198
172
  export const ExecutionOrderingField = ({ isRandomizedOrdering, setValue }) => (
199
173
  <FormGroup
200
174
  label={__('Execution ordering')}
@@ -274,8 +248,6 @@ EffectiveUserPasswordField.propTypes = EffectiveUserField.propTypes;
274
248
  EffectiveUserPasswordField.defaultProps = EffectiveUserField.defaultProps;
275
249
  ConcurrencyLevelField.propTypes = EffectiveUserField.propTypes;
276
250
  ConcurrencyLevelField.defaultProps = EffectiveUserField.defaultProps;
277
- TimeSpanLevelField.propTypes = EffectiveUserField.propTypes;
278
- TimeSpanLevelField.defaultProps = EffectiveUserField.defaultProps;
279
251
  ExecutionOrderingField.propTypes = {
280
252
  isRandomizedOrdering: PropTypes.bool,
281
253
  setValue: PropTypes.func.isRequired,
@@ -268,7 +268,6 @@ const ReviewDetails = ({
268
268
  { label: __('Timeout to kill'), value: advancedValues.timeoutToKill },
269
269
  { label: __('Time to pickup'), value: advancedValues.timeToPickup },
270
270
  { label: __('Concurrency level'), value: advancedValues.concurrencyLevel },
271
- { label: __('Time span'), value: advancedValues.timeSpan },
272
271
  {
273
272
  label: __('Execution ordering'),
274
273
  value: advancedValues.isRandomizedOrdering
@@ -32,7 +32,6 @@ export const submit = ({
32
32
  description,
33
33
  timeoutToKill,
34
34
  isRandomizedOrdering,
35
- timeSpan,
36
35
  concurrencyLevel,
37
36
  templateValues: advancedTemplateValues,
38
37
  password,
@@ -109,7 +108,6 @@ export const submit = ({
109
108
  }
110
109
  : null,
111
110
  concurrency_control: {
112
- time_span: timeSpan,
113
111
  concurrency_level: concurrencyLevel,
114
112
  },
115
113
  bookmark_id: null,
@@ -41,7 +41,6 @@ export const useValidation = ({ advancedValues, templateValues }) => {
41
41
  advancedValues.timeoutToKill,
42
42
  advancedValues.timeToPickup,
43
43
  advancedValues.concurrencyLevel,
44
- advancedValues.timeSpan,
45
44
  ].forEach(value => {
46
45
  if (value && !isPositiveNumber(value)) {
47
46
  setValid(currValid => ({ ...currValid, advanced: false }));
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_remote_execution
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.1.0
4
+ version: 11.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Remote Execution team
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: 7.1.0
53
+ version: 8.2.0
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: 7.1.0
60
+ version: 8.2.0
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: factory_bot_rails
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -338,7 +338,7 @@ files:
338
338
  - db/migrate/20200623073022_rename_sudo_password_to_effective_user_password.rb
339
339
  - db/migrate/20200820122057_add_proxy_selector_override_to_remote_execution_feature.rb
340
340
  - db/migrate/20210312074713_add_provider_inputs.rb
341
- - db/migrate/2021051713291621250977_add_host_proxy_invocations.rb
341
+ - db/migrate/20210517132916_add_host_proxy_invocations.rb
342
342
  - db/migrate/20210816100932_rex_setting_category_to_dsl.rb
343
343
  - db/migrate/20220321101835_rename_ssh_provider_to_script.rb
344
344
  - db/migrate/20220331112719_add_ssh_user_to_job_invocation.rb
@@ -346,6 +346,7 @@ files:
346
346
  - db/migrate/20220713095705_create_template_invocation_events.rb
347
347
  - db/migrate/20220822155946_add_time_to_pickup_to_job_invocation.rb
348
348
  - db/migrate/20221129170145_redefine_template_invocation_events_index.rb
349
+ - db/migrate/20230816154510_drop_time_span_from_job_invocations.rb
349
350
  - db/seeds.d/100-assign_features_with_templates.rb
350
351
  - db/seeds.d/20-permissions.rb
351
352
  - db/seeds.d/50-notification_blueprints.rb