Skip to content

Commit

Permalink
Merge pull request ManageIQ#17825 from hsong-rh/miq_request_cancel
Browse files Browse the repository at this point in the history
Enable cancel operation for service template transformation plan request
  • Loading branch information
gmcculloug authored Sep 13, 2018
2 parents ed40ac3 + 5f10870 commit 9f3c401
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 12 deletions.
35 changes: 34 additions & 1 deletion app/models/miq_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ class MiqRequest < ApplicationRecord
ACTIVE_STATES = %w(active queued)
REQUEST_UNIQUE_KEYS = %w(id state status created_on updated_on type).freeze

CANCEL_STATUS_REQUESTED = "cancel_requested".freeze
CANCEL_STATUS_PROCESSING = "canceling".freeze
CANCEL_STATUS_FINISHED = "canceled".freeze
CANCEL_STATUS = [CANCEL_STATUS_REQUESTED, CANCEL_STATUS_PROCESSING, CANCEL_STATUS_FINISHED].freeze

belongs_to :source, :polymorphic => true
belongs_to :destination, :polymorphic => true
belongs_to :requester, :class_name => "User"
Expand All @@ -26,6 +31,10 @@ class MiqRequest < ApplicationRecord
validates_inclusion_of :approval_state, :in => %w(pending_approval approved denied), :message => "should be 'pending_approval', 'approved' or 'denied'"
validates_inclusion_of :status, :in => %w(Ok Warn Error Timeout Denied)

validates :cancelation_status, :inclusion => { :in => CANCEL_STATUS,
:allow_nil => true,
:message => "should be one of #{CANCEL_STATUS.join(", ")}" }

validate :validate_class, :validate_request_type

include TenancyMixin
Expand Down Expand Up @@ -54,6 +63,7 @@ class MiqRequest < ApplicationRecord

scope :created_recently, ->(days_ago) { where("miq_requests.created_on > ?", days_ago.days.ago) }
scope :with_approval_state, ->(state) { where(:approval_state => state) }
scope :with_cancel_status, ->(status) { where(:cancelation_status => status) }
scope :with_type, ->(type) { where(:type => type) }
scope :with_request_type, ->(type) { where(:request_type => type) }
scope :with_requester, ->(id) { where(:requester_id => User.with_same_userid(id).collect(&:id)) }
Expand Down Expand Up @@ -432,6 +442,11 @@ def execute
end

def create_request_tasks
if cancel_requested?
do_cancel
return
end

# Quota denial will result in automate_event_failed? being true
return if automate_event_failed?("request_starting")

Expand Down Expand Up @@ -589,12 +604,30 @@ def cancel
raise _("Cancel operation is not supported for #{self.class.name}")
end

def cancel_requested?
cancelation_status == CANCEL_STATUS_REQUESTED
end

def canceling?
false
cancelation_status == CANCEL_STATUS_PROCESSING
end

def canceled?
cancelation_status == CANCEL_STATUS_FINISHED
end

private

def do_cancel
update_attributes(:cancelation_status => CANCEL_STATUS_PROCESSING)
cancel_cleanup
update_attributes(:cancelation_status => CANCEL_STATUS_FINISHED, :request_state => "finished", :status => "Error", :message => "Request is canceled by user.")
_log.info("Request #{description} is canceled by user.")
end

def cancel_cleanup
end

def clean_up_keys_for_request_task
req_task_attributes = attributes.dup
(req_task_attributes.keys - MiqRequestTask.column_names + REQUEST_UNIQUE_KEYS).each { |key| req_task_attributes.delete(key) }
Expand Down
19 changes: 18 additions & 1 deletion app/models/miq_request_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ class MiqRequestTask < ApplicationRecord
include MiqRequestMixin
include TenancyMixin

CANCEL_STATUS_REQUESTED = "cancel_requested".freeze
CANCEL_STATUS_PROCESSING = "canceling".freeze
CANCEL_STATUS_FINISHED = "canceled".freeze
CANCEL_STATUS = [CANCEL_STATUS_REQUESTED, CANCEL_STATUS_PROCESSING, CANCEL_STATUS_FINISHED].freeze

validates :cancelation_status, :inclusion => { :in => CANCEL_STATUS,
:allow_nil => true,
:message => "should be one of #{CANCEL_STATUS.join(", ")}" }

def approved?
if miq_request.class.name.include?('Template') && miq_request_task
miq_request_task.miq_request.approved?
Expand Down Expand Up @@ -208,8 +217,16 @@ def cancel
raise _("Cancel operation is not supported for #{self.class.name}")
end

def cancel_requested?
cancelation_status == MiqRequestTask::CANCEL_STATUS_REQUESTED
end

def canceling?
false
cancelation_status == MiqRequestTask::CANCEL_STATUS_PROCESSING
end

def canceled?
cancelation_status == MiqRequestTask::CANCEL_STATUS_FINISHED
end

private
Expand Down
5 changes: 5 additions & 0 deletions app/models/service_template_provision_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ class ServiceTemplateProvisionRequest < MiqRequest
include MiqProvisionQuotaMixin

def process_service_order
if cancel_requested?
do_cancel
return
end

case options[:cart_state]
when ServiceOrder::STATE_ORDERED
ServiceOrder.order_immediately(self, requester)
Expand Down
7 changes: 1 addition & 6 deletions app/models/service_template_transformation_plan_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,7 @@ def approve_vm(vm_id)
end

def cancel
options['cancel_requested'] = true
save!
update_attributes(:cancelation_status => MiqRequest::CANCEL_STATUS_REQUESTED)
miq_request_tasks.each(&:cancel)
end

def canceling?
options['cancel_requested']
end
end
11 changes: 7 additions & 4 deletions app/models/service_template_transformation_plan_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,15 @@ def transformation_log_queue(userid = nil)
end

def cancel
options['cancel_requested'] = true
save!
update_attributes(:cancelation_status => MiqRequestTask::CANCEL_STATUS_REQUESTED)
end

def canceling?
options['cancel_requested']
def canceling
update_attributes(:cancelation_status => MiqRequestTask::CANCEL_STATUS_PROCESSING)
end

def canceled
update_attributes(:cancelation_status => MiqRequestTask::CANCEL_STATUS_FINISHED)
end

private
Expand Down
19 changes: 19 additions & 0 deletions spec/models/service_template_transformation_plan_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,23 @@
expect(ServiceResource.find_by(:resource => vms[0]).status).to eq(ServiceResource::STATUS_APPROVED)
end
end

context "when request gets canceled" do
before { request.cancel }

it "cancelation_status is set to requested" do
expect(request.cancelation_status).to eq(MiqRequest::CANCEL_STATUS_REQUESTED)
expect(request.cancel_requested?).to be_truthy
expect(request.canceling?).to be_falsey
expect(request.canceled?).to be_falsey
end

it "marks request as finished in error" do
request.send(:do_cancel)
expect(request.cancelation_status).to eq(MiqRequest::CANCEL_STATUS_FINISHED)
expect(request.request_state).to eq('finished')
expect(request.status).to eq('Error')
expect(request.message).to eq('Request is canceled by user.')
end
end
end
8 changes: 8 additions & 0 deletions spec/models/service_template_transformation_plan_task_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -196,5 +196,13 @@
expect(vm).to be_is_tagged_with("migrated", :ns => "/managed", :cat => "transformation_status")
end
end

describe '#cancel' do
it 'catches cancel state' do
task.cancel
expect(task.cancelation_status).to eq(MiqRequestTask::CANCEL_STATUS_REQUESTED)
expect(task.cancel_requested?).to be_truthy
end
end
end
end

0 comments on commit 9f3c401

Please sign in to comment.