From 5badb97c5cfd39a3619efed7ee49206890025bbb Mon Sep 17 00:00:00 2001 From: Boris Odnopozov Date: Wed, 20 Jun 2018 12:40:04 +0300 Subject: [PATCH] Add sysprep support for ovirt Add sysprep specification support for vm provisioning from template for the oVirt provider. Depends on: https://github.com/ManageIQ/manageiq/pull/17636 Required for: https://github.com/ManageIQ/manageiq-ui-classic/pull/4211 Implements: https://bugzilla.redhat.com/show_bug.cgi?id=1553833 --- .../infra_manager/provision/configuration.rb | 22 +++- .../infra_manager/provision_workflow.rb | 118 +++++++++++++++++- .../provision/configuration_spec.rb | 51 ++++++++ 3 files changed, 184 insertions(+), 7 deletions(-) diff --git a/app/models/manageiq/providers/redhat/infra_manager/provision/configuration.rb b/app/models/manageiq/providers/redhat/infra_manager/provision/configuration.rb index 7efff7017..5b98bde84 100644 --- a/app/models/manageiq/providers/redhat/infra_manager/provision/configuration.rb +++ b/app/models/manageiq/providers/redhat/infra_manager/provision/configuration.rb @@ -21,8 +21,7 @@ def configure_cloud_init end def configure_sysprep - content = get_option(:sysprep_upload_text) - + content = sysprep_specification_selected? ? customization_template_content : get_option(:sysprep_upload_text) return unless content with_provider_destination { |d| d.update_sysprep!(content) } @@ -37,9 +36,8 @@ def configure_container configure_cpu(rhevm_vm) configure_host_affinity(rhevm_vm) configure_network_adapters - sysprep_option = get_option(:sysprep_enabled) - if sysprep_option == 'file' + if sysprep_option == 'file' || sysprep_specification_selected? configure_sysprep elsif sysprep_option == 'fields' configure_cloud_init @@ -49,6 +47,22 @@ def configure_container private + def sysprep_specification_selected? + options.dig(:sysprep_enabled, 1) == "Sysprep Specification" + end + + def prepare_customization_template_substitution_options + super.tap do |substitution_options| + substitution_options[:sysprep_timezone] = extract_timezone(substitution_options[:sysprep_timezone]) + end + end + + def extract_timezone(timezone_option_from_ui) + timezone = timezone_option_from_ui[1] if timezone_option_from_ui.present? + return unless timezone + /\) (.*)/.match(timezone)[1] + end + def customization_template_content return unless customization_template options = prepare_customization_template_substitution_options diff --git a/app/models/manageiq/providers/redhat/infra_manager/provision_workflow.rb b/app/models/manageiq/providers/redhat/infra_manager/provision_workflow.rb index 5524ad879..8e3f0ae93 100644 --- a/app/models/manageiq/providers/redhat/infra_manager/provision_workflow.rb +++ b/app/models/manageiq/providers/redhat/infra_manager/provision_workflow.rb @@ -1,5 +1,110 @@ class ManageIQ::Providers::Redhat::InfraManager::ProvisionWorkflow < MiqProvisionInfraWorkflow include CloudInitTemplateMixin + include SysprepTemplateMixin + + SYSPREP_TIMEZONES = { + '001' => '(UTC-12:00) Dateline Standard Time', + '002' => '(UTC-11:00) UTC-11', + '003' => '(UTC-10:00) Hawaiian Standard Time', + '004' => '(UTC-09:00) Alaskan Standard Time', + '005' => '(UTC-08:00) Pacific Standard Time', + '006' => '(UTC-07:00) US Mountain Standard Time', + '007' => '(UTC-07:00) Mountain Standard Time', + '008' => '(UTC-06:00) Central America Standard Time', + '009' => '(UTC-06:00) Central Standard Time', + '010' => '(UTC-06:00) Canada Central Standard Time', + '011' => '(UTC-05:00) SA Pacific Standard Time', + '012' => '(UTC-05:00) Eastern Standard Time', + '013' => '(UTC-05:00) US Eastern Standard Time', + '014' => '(UTC-04:30) Venezuela Standard Time', + '015' => '(UTC-04:00) Paraguay Standard Time', + '016' => '(UTC-04:00) Atlantic Standard Time', + '017' => '(UTC-04:00) Central Brazilian Standard Time', + '018' => '(UTC-04:00) SA Western Standard Time', + '019' => '(UTC-04:00) Pacific SA Standard Time', + '020' => '(UTC-03:30) Newfoundland Standard Time', + '021' => '(UTC-03:00) E. South America Standard Time', + '022' => '(UTC-03:00) Argentina Standard Time', + '023' => '(UTC-03:00) SA Eastern Standard Time', + '024' => '(UTC-03:00) Greenland Standard Time', + '025' => '(UTC-03:00) Montevideo Standard Time', + '026' => '(UTC-03:00) Bahia Standard Time', + '027' => '(UTC-02:00) UTC-02', + '028' => '(UTC-01:00) Azores Standard Time', + '029' => '(UTC-01:00) Cape Verde Standard Time', + '030' => '(UTC) Morocco Standard Time', + '031' => '(UTC) UTC', + '032' => '(UTC) GMT Standard Time', + '033' => '(UTC) Greenwich Standard Time', + '034' => '(UTC+01:00) W. Europe Standard Time', + '035' => '(UTC+01:00) Central Europe Standard Time', + '036' => '(UTC+01:00) Romance Standard Time', + '037' => '(UTC+01:00) Central European Standard Time', + '038' => '(UTC+01:00) Libya Standard Time', + '039' => '(UTC+01:00) W. Central Africa Standard Time', + '040' => '(UTC+01:00) Namibia Standard Time', + '041' => '(UTC+02:00) GTB Standard Time', + '042' => '(UTC+02:00) Middle East Standard Time', + '043' => '(UTC+02:00) Egypt Standard Time', + '044' => '(UTC+02:00) Syria Standard Time', + '045' => '(UTC+02:00) E. Europe Standard Time', + '046' => '(UTC+02:00) South Africa Standard Time', + '047' => '(UTC+02:00) FLE Standard Time', + '048' => '(UTC+02:00) Turkey Standard Time', + '049' => '(UTC+02:00) Israel Standard Time', + '050' => '(UTC+03:00) Jordan Standard Time', + '051' => '(UTC+03:00) Arabic Standard Time', + '052' => '(UTC+03:00) Kaliningrad Standard Time', + '053' => '(UTC+03:00) Arab Standard Time', + '054' => '(UTC+03:00) E. Africa Standard Time', + '055' => '(UTC+03:30) Iran Standard Time', + '056' => '(UTC+04:00) Arabian Standard Time', + '057' => '(UTC+04:00) Azerbaijan Standard Time', + '058' => '(UTC+04:00) Russian Standard Time', + '059' => '(UTC+04:00) Mauritius Standard Time', + '060' => '(UTC+04:00) Georgian Standard Time', + '061' => '(UTC+04:00) Caucasus Standard Time', + '062' => '(UTC+04:30) Afghanistan Standard Time', + '063' => '(UTC+05:00) West Asia Standard Time', + '064' => '(UTC+05:00) Pakistan Standard Time', + '065' => '(UTC+05:30) India Standard Time', + '066' => '(UTC+05:30) Sri Lanka Standard Time', + '067' => '(UTC+05:45) Nepal Standard Time', + '068' => '(UTC+06:00) Central Asia Standard Time', + '069' => '(UTC+06:00) Bangladesh Standard Time', + '070' => '(UTC+06:00) Ekaterinburg Standard Time', + '071' => '(UTC+06:30) Myanmar Standard Time', + '072' => '(UTC+07:00) SE Asia Standard Time', + '073' => '(UTC+07:00) N. Central Asia Standard Time', + '074' => '(UTC+08:00) China Standard Time', + '075' => '(UTC+08:00) North Asia Standard Time', + '076' => '(UTC+08:00) Singapore Standard Time', + '077' => '(UTC+08:00) W. Australia Standard Time', + '078' => '(UTC+08:00) Taipei Standard Time', + '079' => '(UTC+08:00) Ulaanbaatar Standard Time', + '080' => '(UTC+09:00) North Asia East Standard Time', + '081' => '(UTC+09:00) Tokyo Standard Time', + '082' => '(UTC+09:00) Korea Standard Time', + '083' => '(UTC+09:30) Cen. Australia Standard Time', + '084' => '(UTC+09:30) AUS Central Standard Time', + '085' => '(UTC+10:00) E. Australia Standard Time', + '086' => '(UTC+10:00) AUS Eastern Standard Time', + '087' => '(UTC+10:00) West Pacific Standard Time', + '088' => '(UTC+10:00) Tasmania Standard Time', + '089' => '(UTC+10:00) Yakutsk Standard Time', + '090' => '(UTC+11:00) Central Pacific Standard Time', + '091' => '(UTC+11:00) Vladivostok Standard Time', + '092' => '(UTC+12:00) New Zealand Standard Time', + '093' => '(UTC+12:00) UTC+12', + '094' => '(UTC+12:00) Fiji Standard Time', + '095' => '(UTC+12:00) Magadan Standard Time', + '096' => '(UTC+13:00) Tonga Standard Time', + '097' => '(UTC+13:00) Samoa Standard Time' + }.freeze + + def get_timezones(_options = {}) + SYSPREP_TIMEZONES + end def self.default_dialog_file 'miq_provision_dialogs' @@ -55,7 +160,11 @@ def update_field_visibility_linked_clone(_options = {}, f) def allowed_customization_templates(options = {}) if supports_native_clone? - allowed_cloud_init_customization_templates(options) + if get_source_vm.platform == 'windows' + allowed_sysprep_customization_templates(options) + else + allowed_cloud_init_customization_templates(options) + end else super(options) end @@ -73,8 +182,11 @@ def allowed_customization(_options = {}) result = {"disabled" => ""} case src[:vm].platform - when 'windows' then result["file"] = "Sysprep Answer File" - when 'linux' then result["fields"] = "Specification" + when 'windows' + result["file"] = "Sysprep Answer File" + result["fields"] = "Sysprep Specification" + when 'linux' + result["fields"] = "Specification" end result diff --git a/spec/models/manageiq/providers/redhat/infra_manager/provision/configuration_spec.rb b/spec/models/manageiq/providers/redhat/infra_manager/provision/configuration_spec.rb index e30559136..110e9afa7 100644 --- a/spec/models/manageiq/providers/redhat/infra_manager/provision/configuration_spec.rb +++ b/spec/models/manageiq/providers/redhat/infra_manager/provision/configuration_spec.rb @@ -80,6 +80,57 @@ expect(task.phase_context[:boot_with_sysprep]).to eq(true) end + + let(:cust_template) { FactoryGirl.create(:customization_template_sysprep, :script => "the script: <%= evm[:replace_me] %>") } + + it "provisions sysprep from template with substitutions" do + allow(MiqRegion).to receive_message_chain(:my_region, :remote_ui_url => "1.1.1.1") + task.options[:sysprep_enabled] = ["fields", "Sysprep Specification"] + task.options[:customization_template_id] = cust_template.id + task.options[:replace_me] = "replaced!" + + expect(vm_service).to receive(:update).with(OvirtSDK4::Vm.new( + :initialization => { + :custom_script => "the script: replaced!" + } + )) + + task.configure_sysprep + end + + context "with timezone set" do + let(:cust_template) { FactoryGirl.create(:customization_template_sysprep, :script => "timezone: <%= evm[:sysprep_timezone] %>") } + + it "it properly substitutes timezone when it is set" do + allow(MiqRegion).to receive_message_chain(:my_region, :remote_ui_url => "1.1.1.1") + task.options[:sysprep_enabled] = ["fields", "Sysprep Specification"] + task.options[:customization_template_id] = cust_template.id + task.options[:sysprep_timezone] = ["300", "(GMT+13:00) Nuku'alofa"] + + expect(vm_service).to receive(:update).with(OvirtSDK4::Vm.new( + :initialization => { + :custom_script => "timezone: Nuku'alofa" + } + )) + + task.configure_sysprep + end + + it "it properly substitutes timezone when it is not set" do + allow(MiqRegion).to receive_message_chain(:my_region, :remote_ui_url => "1.1.1.1") + task.options[:sysprep_enabled] = ["fields", "Sysprep Specification"] + task.options[:customization_template_id] = cust_template.id + task.options[:sysprep_timezone] = nil + + expect(vm_service).to receive(:update).with(OvirtSDK4::Vm.new( + :initialization => { + :custom_script => "timezone: " + } + )) + + task.configure_sysprep + end + end end context "#configure_container" do