From efaf5f3979d9856b0155f4d44520bf1b091e20f9 Mon Sep 17 00:00:00 2001 From: Alejandro Huertas Herrero Date: Fri, 29 Mar 2019 16:23:01 +0100 Subject: [PATCH] B #3136: timeout when using cleaunp option (#3142) * Increase the default timeout from 10 to 20 * Add cleanup_timeout parameter to configure it via CLI * Implement wait_image_delete, to wait until images are deleted --- src/cli/one_helper/oneprovision_helper.rb | 4 +- src/cli/oneprovision | 16 +++++++- src/oneprovision/lib/provision.rb | 49 ++++++++++++++++++----- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/cli/one_helper/oneprovision_helper.rb b/src/cli/one_helper/oneprovision_helper.rb index 40c5f1f49d..ec1fdf122c 100644 --- a/src/cli/one_helper/oneprovision_helper.rb +++ b/src/cli/one_helper/oneprovision_helper.rb @@ -93,12 +93,12 @@ class OneProvisionHelper < OpenNebulaHelper::OneHelper provision.configure(force) end - def delete(provision_id, cleanup) + def delete(provision_id, cleanup, timeout) provision = OneProvision::Provision.new(provision_id) provision.refresh - provision.delete(cleanup) + provision.delete(cleanup, timeout) end ####################################################################### diff --git a/src/cli/oneprovision b/src/cli/oneprovision index 0f63b945c1..f8ff7eb58b 100755 --- a/src/cli/oneprovision +++ b/src/cli/oneprovision @@ -162,6 +162,12 @@ CommandParser::CmdParser.new(ARGV) do 'then delete the resources.' } + CLEANUP_TIMEOUT = { + :name => 'cleanup_timeout', + :large => '--cleanup-timeout timeout', + :description => 'Change the default timeout when deleting VMs.' + } + INCREMENTAL = { :name => 'incremental', :large => '--incremental', @@ -266,10 +272,16 @@ CommandParser::CmdParser.new(ARGV) do command :delete, provision_delete_desc, :provisionid, - :options => [MODES, THREADS, CLEANUP] do + :options => [MODES, THREADS, CLEANUP, CLEANUP_TIMEOUT] do helper.parse_options(options) - helper.delete(args[0], (options.key? :cleanup)) + if options[:cleanup_timeout].nil? + timeout = 20 + else + timeout = options[:cleanup_timeout] + end + + helper.delete(args[0], (options.key? :cleanup), timeout) end ######################################################################## diff --git a/src/oneprovision/lib/provision.rb b/src/oneprovision/lib/provision.rb index 29489470e0..39122662da 100644 --- a/src/oneprovision/lib/provision.rb +++ b/src/oneprovision/lib/provision.rb @@ -63,7 +63,8 @@ module OneProvision # Deletes the PROVISION # # @param cleanup [Boolean] True to delete running VMs and images - def delete(cleanup = false) + # @param timeout [Integer] Timeout for deleting running VMs + def delete(cleanup, timeout) Utils.fail('Provision not found.') unless exists if running_vms? && !cleanup @@ -74,9 +75,9 @@ module OneProvision Utils.fail('Provision with images can\'t be deleted') end - delete_vms if cleanup + delete_vms(timeout) if cleanup - delete_images if cleanup + delete_images(timeout) if cleanup OneProvisionLogger.info("Deleting provision #{@id}") @@ -417,7 +418,9 @@ module OneProvision end # Deletes VMs from the PROVISION - def delete_vms + # + # @param timeout [Integer] Timeout for deleting running VMs + def delete_vms(timeout) Driver.retry_loop 'Failed to delete running_vms' do hosts = [] @@ -431,7 +434,7 @@ module OneProvision vm_ids = host.retrieve_elements('VMS/ID') vm_ids.each do |id| - delete_object('vm', id) + delete_object('vm', id, timeout) end end @@ -442,7 +445,9 @@ module OneProvision end # Deletes images from the PROVISION - def delete_images + # + # @param timeout [Integer] Timeout for deleting running VMs + def delete_images(timeout) Driver.retry_loop 'Failed to delete images' do datastores = [] @@ -458,7 +463,7 @@ module OneProvision image_ids = datastore.retrieve_elements('IMAGES/ID') image_ids.each do |id| - delete_object('image', id) + delete_object('image', id, timeout) end end @@ -470,9 +475,10 @@ module OneProvision # Deletes an object # - # @param type [String] Type of the object (vm, image) - # @param id [String] ID of the object - def delete_object(type, id) + # @param type [String] Type of the object (vm, image) + # @param id [String] ID of the object + # @param timeout [Integer] Timeout for deleting running VMs + def delete_object(type, id, timeout) msg = "Deleting OpenNebula #{type} #{id}" OneProvision::OneProvisionLogger.debug(msg) @@ -490,7 +496,28 @@ module OneProvision Utils.exception(object.delete) - Utils.exception(object.wait_state('DONE')) if type == 'vm' + if type == 'vm' + Utils.exception(object.wait_state('DONE', timeout)) + else + Utils.exception(wait_image_delete(object, timeout)) + end + end + + # Waits until the image is deleted + # + # @param image [OpenNebula::Image] Image to wait + # @param timeout [Integer ] Timeout for delete + def wait_image_delete(image, timeout) + timeout.times do + rc = image.info + + return true if OpenNebula.is_error?(rc) + + sleep 1 + end + + raise OneProvisionLoopExeception, 'Timeout expired for deleting' / + " image #{image['ID']}" end end