diff --git a/app/models/miq_widget.rb b/app/models/miq_widget.rb index 3c8f157c4b2..2c00d236996 100644 --- a/app/models/miq_widget.rb +++ b/app/models/miq_widget.rb @@ -494,6 +494,11 @@ def self.sync_from_hash(attrs) widget end + def filter_for_schedule + "\"=\" => {\"field\" => \"MiqWidget-id\", \"value\" => #{id}}" + end + + def sync_schedule(schedule_info) return if schedule_info.nil? @@ -513,12 +518,12 @@ def sync_schedule(schedule_info) raise _("Unsupported interval '%{interval}'") % {:interval => interval} end - sched = MiqSchedule.find_by(:name => description) + sched = existing_scheduler sched ||= MiqSchedule.create!( :name => description, :description => description, :sched_action => {:method => "generate_widget"}, - :filter => MiqExpression.new("=" => {"field" => "MiqWidget-id", "value" => id}), + :filter => MiqExpression.new(filter_for_schedule), :resource_type => self.class.name, :run_at => { :interval => {:value => value, :unit => unit}, @@ -535,6 +540,22 @@ def sync_schedule(schedule_info) sched end + + def existing_scheduler + return nil if (sched = MiqSchedule.find_by(:name => description)).nil? + + # return existing sheduler if filter referr to the same widget + return sched if sched.filter == filter_for_schedule + + # change name of existed schedule in case it is in use + suff = Time.new.utc.to_s + sched.name = "#{sched.name} #{suff}" + sched.description = "#{sched.description} #{suff}" + sched.save + + nil + end + def self.seed sync_from_dir end diff --git a/spec/models/miq_widget_spec.rb b/spec/models/miq_widget_spec.rb index e87483f1e6b..7af408e020d 100644 --- a/spec/models/miq_widget_spec.rb +++ b/spec/models/miq_widget_spec.rb @@ -55,13 +55,27 @@ end describe "#sync_schedule" do - let(:schedule) { FactoryBot.create(:miq_schedule, :resource_type => "MiqWidget", :name => @widget_chart_vendor_and_guest_os.name) } + let(:schedule) { FactoryBot.create(:miq_schedule, + :resource_type => "MiqWidget", :name => @widget_chart_vendor_and_guest_os.name, + :filter => @widget_chart_vendor_and_guest_os.filter_for_schedule) } it "uses existing schedule if link between widget and schedule broken" do expect(@widget_chart_vendor_and_guest_os.miq_schedule).to be_nil @widget_chart_vendor_and_guest_os.sync_schedule(:run_at => schedule.run_at) - expect(@widget_chart_vendor_and_guest_os.miq_schedule).to eq(schedule) + expect(MiqSchedule.count).to eq(1) + expect(@widget_chart_vendor_and_guest_os.miq_schedule.id).to eq(schedule.id) + end + + it "rename existing scheduler by adding timestamp go name if existing scheduler use different filter" do + schedule.update(:filter => "\"=\" => {\"field\" => \"MiqWidget-id\", \"value\" => 9999") + + time_now = Time.now.utc + Timecop.freeze(time_now) {@widget_chart_vendor_and_guest_os.sync_schedule(:run_at => schedule.run_at) } + schedule.reload + + expect(MiqSchedule.count).to eq(2) + expect(schedule.name.end_with?(time_now.to_s)).to be_truthy end end