Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable cancel operation for service template transformation plan request #17825

Merged
merged 1 commit into from
Sep 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
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
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