diff --git a/app/models/miq_widget.rb b/app/models/miq_widget.rb index 0d30d0d5be2c..ba8cc119cc11 100644 --- a/app/models/miq_widget.rb +++ b/app/models/miq_widget.rb @@ -492,6 +492,10 @@ 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? @@ -511,11 +515,12 @@ def sync_schedule(schedule_info) raise _("Unsupported interval '%{interval}'") % {:interval => interval} end - sched = MiqSchedule.create!( + 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}, @@ -532,6 +537,23 @@ 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 + _log.warn("Schedule #{sched.name} already exists, renaming it to `#{sched.name} #{suff}`") + 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 24295f639f97..43f08e03cdbd 100644 --- a/spec/models/miq_widget_spec.rb +++ b/spec/models/miq_widget_spec.rb @@ -56,6 +56,33 @@ ')) end + describe "#sync_schedule" do + let(:schedule) do + filter = @widget_chart_vendor_and_guest_os.filter_for_schedule + FactoryBot.create(:miq_schedule, :filter => filter, + :resource_type => "MiqWidget", :name => @widget_chart_vendor_and_guest_os.name) + end + + 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(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 + context "#queue_generate_content_for_users_or_group" do before do @widget = @widget_report_vendor_and_guest_os