From 6235a83e57c99c57d4d74402b2a977e1ee7458f0 Mon Sep 17 00:00:00 2001 From: Richard Oliveri Date: Thu, 18 Aug 2016 18:51:15 -0400 Subject: [PATCH] Merge pull request #10396 from moolitayer/fix_scan_timeout Fix container scanning timeout handling. (cherry picked from commit 1a367eac5ae24e3da78bd011a34217371769bf00) --- app/models/job.rb | 14 +++-- .../container_manager/scanning/job.rb | 4 -- spec/models/job_spec.rb | 57 +++++++++++++++++++ 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/app/models/job.rb b/app/models/job.rb index ed10160713a..afc77f6ea25 100644 --- a/app/models/job.rb +++ b/app/models/job.rb @@ -164,6 +164,10 @@ def timeout! end end + def target_entity + target_class.constantize.find_by_id(target_id) + end + def self.check_jobs_for_timeout $log.debug "Checking for timed out jobs" begin @@ -171,7 +175,7 @@ def self.check_jobs_for_timeout .where("state != 'finished' and (state != 'waiting_to_start' or dispatch_status = 'active')") .where("zone is null or zone = ?", MiqServer.my_zone) .each do |job| - next unless job.updated_on < job.current_job_timeout(timeout_adjustment(job)).seconds.ago + next unless job.updated_on < job.current_job_timeout(job.timeout_adjustment).seconds.ago # Allow jobs to run longer if the MiqQueue task is still active. (Limited to MiqServer for now.) if job.agent_class == "MiqServer" @@ -185,11 +189,11 @@ def self.check_jobs_for_timeout end end - def self.timeout_adjustment(job) + def timeout_adjustment timeout_adjustment = 1 - vm = VmOrTemplate.find(job.target_id) - if vm.kind_of?(ManageIQ::Providers::Microsoft::InfraManager::Vm) || - vm.kind_of?(ManageIQ::Providers::Microsoft::InfraManager::Template) + target = target_entity + if target.kind_of?(ManageIQ::Providers::Microsoft::InfraManager::Vm) || + target.kind_of?(ManageIQ::Providers::Microsoft::InfraManager::Template) timeout_adjustment = 4 end timeout_adjustment diff --git a/app/models/manageiq/providers/kubernetes/container_manager/scanning/job.rb b/app/models/manageiq/providers/kubernetes/container_manager/scanning/job.rb index 330c37f4fef..9e6350a3d48 100644 --- a/app/models/manageiq/providers/kubernetes/container_manager/scanning/job.rb +++ b/app/models/manageiq/providers/kubernetes/container_manager/scanning/job.rb @@ -223,10 +223,6 @@ def queue_callback(state, msg, _) private - def target_entity - target_class.constantize.find_by_id(target_id) - end - def ext_management_system @ext_management_system ||= ExtManagementSystem.find(options[:ems_id]) end diff --git a/spec/models/job_spec.rb b/spec/models/job_spec.rb index 7d8b3a7cbdc..472d57ade22 100644 --- a/spec/models/job_spec.rb +++ b/spec/models/job_spec.rb @@ -87,6 +87,35 @@ end end + context "where job is for a VM that disappeared" do + before(:each) do + @job.update_attributes(:state => "scanning", :dispatch_status => "active", :zone => nil) + + @vm.destroy + + Timecop.travel 5.minutes + + Job.check_jobs_for_timeout + + @msg = MiqQueue.get(:role => "smartstate", :zone => @zone.name) + status, message, result = @msg.deliver + @msg.delivered(status, message, result) + + @job.reload + end + + after(:each) do + Timecop.return + end + + it "should be timed out after 5 minutes" do + $log.info("@job: #{@job.inspect}") + expect(@job.state).to eq("finished") + expect(@job.status).to eq("error") + expect(@job.message.starts_with?("job timed out after")).to be_truthy + end + end + context "where 2 VMs in 2 Zones have an EVM Snapshot" do before(:each) do scan_type = nil @@ -220,6 +249,34 @@ # end end end + + context "where scan jobs exist for both vms and container images" do + before(:each) do + @ems_k8s = FactoryGirl.create( + :ems_kubernetes, :hostname => "test.com", :zone => @zone, :port => 8443, + :authentications => [AuthToken.new(:name => "test", :type => 'AuthToken', :auth_key => "a secret")] + ) + @image = FactoryGirl.create( + :container_image, :ext_management_system => @ems_k8s, :name => 'test', + :image_ref => "docker://3629a651e6c11d7435937bdf41da11cf87863c03f2587fa788cf5cbfe8a11b9a" + ) + @image_scan_job = @image.scan + end + + context "#target_entity" do + it "returns the job target" do + expect(@job.target_entity).to eq(@vm) + expect(@image_scan_job.target_entity).to eq(@image) + end + end + + context "#timeout_adjustment" do + it "returns the correct adjusment" do + expect(@job.timeout_adjustment).to eq(1) + expect(@image_scan_job.timeout_adjustment).to eq(1) + end + end + end end private