From a9d730db78df302ea2f061c8a3648c144e79526f Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 20 Nov 2023 20:09:56 +0900 Subject: [PATCH] QemuHCK: Enable UEFI Secure Boot when installing Signed-off-by: Akihiko Odaki --- lib/engines/hckinstall/hckinstall.json | 3 +- lib/engines/hckinstall/hckinstall.rb | 115 ++++++++++-------- .../Win11_22H2x64_host_uefi_q35_viommu.json | 1 - .../Win11nextx64_host_uefi_q35_viommu.json | 1 - lib/setupmanagers/qemuhck/fw.json | 10 +- lib/setupmanagers/qemuhck/qemu_machine.rb | 16 ++- lib/setupmanagers/qemuhck/qemuhck.rb | 13 +- lib/setupmanagers/qemuhck/states.json | 7 ++ 8 files changed, 92 insertions(+), 74 deletions(-) diff --git a/lib/engines/hckinstall/hckinstall.json b/lib/engines/hckinstall/hckinstall.json index 994c129e..1a4dd856 100644 --- a/lib/engines/hckinstall/hckinstall.json +++ b/lib/engines/hckinstall/hckinstall.json @@ -4,6 +4,5 @@ "autounattend.xml", "unattend.xml" ], - "studio_install_timeout": 10800, - "client_install_timeout": 3600 + "install_timeout": 10800 } diff --git a/lib/engines/hckinstall/hckinstall.rb b/lib/engines/hckinstall/hckinstall.rb index 91e7af5b..b1b0f4fe 100644 --- a/lib/engines/hckinstall/hckinstall.rb +++ b/lib/engines/hckinstall/hckinstall.rb @@ -84,8 +84,7 @@ def init_config @hck_setup_scripts_path = @config['hck_setup_scripts_path'] @answer_files = @config['answer_files'] - @studio_install_timeout = @config['studio_install_timeout'] - @client_install_timeout = @config['client_install_timeout'] + @install_timeout = @config['install_timeout'] end def studio_platform(kit) @@ -199,53 +198,72 @@ def run_studio(scope, iso_list = [], keep_alive:, snapshot: true) st_opts = { keep_alive:, create_snapshot: snapshot, - attach_iso_list: iso_list + attach_iso_list: iso_list, + secure: true } @project.setup_manager.run_studio(scope, st_opts) end - def run_client(scope, name, snapshot: true) + def run_client(scope, name, snapshot: true, secure: true) cl_opts = { create_snapshot: snapshot, attach_iso_list: [ @setup_client_iso, @client_iso_info['path'] - ] + ], + secure: } @project.setup_manager.run_client(scope, name, cl_opts) end - def run_studio_installer - @project.setup_manager.create_studio_image - - ResourceScope.open do |scope| - st = run_studio(scope, [ - @setup_studio_iso, - @studio_iso_info['path'] - ], keep_alive: false, snapshot: false) - @logger.info('Waiting for studio installation finished') - raise AutoHCKError, 'studio installation timed out' if st.wait(@studio_install_timeout).nil? + def wait_vms(vms) + vms.each do |name, vm| + @logger.info("Waiting for #{name} to finish") + vm.wait end end - def run_client_installer(scope, name) - @project.setup_manager.create_client_image(name) + def run_first(studio:, client:) + ResourceScope.open do |scope| + vms = [] + + if studio + prepare_studio_drives + + vms << [ + 'studio', + run_studio(scope, [ + @setup_studio_iso, + @studio_iso_info['path'] + ], keep_alive: false, snapshot: false) + ] + end + + if client + prepare_client_drives - run_client(scope, name, snapshot: false) + @clients_name.each do |c| + vms << [c, run_client(scope, c, snapshot: false)] + end + end + + wait_vms vms + end end - def run_clients_installer + def run_second(client:) + return unless client + ResourceScope.open do |scope| run_studio(scope, [], keep_alive: true) - cl = @clients_name.map { |c| [c, run_client_installer(scope, c)] } - Timeout.timeout(@client_install_timeout) do - cl.each do |name, client| - @logger.info("Waiting for #{name} installation finished") - client.wait - end + + cl = @clients_name.map do |c| + [c, run_client(scope, c, snapshot: false, secure: false)] end + + wait_vms cl end end @@ -321,7 +339,7 @@ def build_client_answer_file_path(file) build_answer_file_path(file, disk_config) end - def prepare_studio_installer + def prepare_studio_drives product_key = @studio_iso_info.dig('studio', 'product_key') replacement_list = { @@ -335,6 +353,8 @@ def prepare_studio_installer @hck_setup_scripts_path + "/#{file}", replacement_list) end create_iso(@setup_studio_iso, [@hck_setup_scripts_path]) + + @project.setup_manager.create_studio_image end def copy_drivers @@ -345,7 +365,7 @@ def copy_drivers remove_destination: true) end - def prepare_client_installer + def prepare_client_drives product_key = @client_iso_info.dig('client', 'product_key') replacement_list = { @@ -362,36 +382,28 @@ def prepare_client_installer copy_drivers if @need_copy_drivers create_iso(@setup_client_iso, [@hck_setup_scripts_path], ['Kits']) + + @clients_name.each { @project.setup_manager.create_client_image(_1) } end def tag "install-#{@project.options.install.platform}" end - def install_studio - if @project.setup_manager.check_studio_image_exist - if @project.options.install.force - @logger.info('HCKInstall: Studio image exist, force reinstall started') + def plan_studio + return true unless @project.setup_manager.check_studio_image_exist - prepare_studio_installer - run_studio_installer - else - @logger.info('HCKInstall: Studio image exist, installation skipped') - end - else - prepare_studio_installer - run_studio_installer + if @project.options.install.force + @logger.info('HCKInstall: Studio image exist, force reinstall started') + return true end - end - def install_clients - if @project.options.install.skip_client - @logger.info('HCKInstall: Client image installation skipped') - return - end + @logger.info('HCKInstall: Studio image exist, installation skipped') + false + end - prepare_client_installer - run_clients_installer + def plan_client + !@project.options.install.skip_client end def run @@ -399,8 +411,13 @@ def run prepare_setup_scripts_config - install_studio - install_clients + studio = plan_studio + client = plan_client + + Timeout.timeout(@install_timeout) do + run_first(studio:, client:) + run_second(client:) + end end end end diff --git a/lib/engines/hcktest/platforms/Win11_22H2x64_host_uefi_q35_viommu.json b/lib/engines/hcktest/platforms/Win11_22H2x64_host_uefi_q35_viommu.json index a4627ea7..9ed4a010 100644 --- a/lib/engines/hcktest/platforms/Win11_22H2x64_host_uefi_q35_viommu.json +++ b/lib/engines/hcktest/platforms/Win11_22H2x64_host_uefi_q35_viommu.json @@ -2,7 +2,6 @@ "name": "Win11_22H2x64_host_uefi_q35_viommu", "kit": "HLK11_22H2", "fw_type": "uefi", - "install_fw_type": "uefi_sb", "machine_type": "q35", "viommu_state": true, "enlightenments_state": true, diff --git a/lib/engines/hcktest/platforms/Win11nextx64_host_uefi_q35_viommu.json b/lib/engines/hcktest/platforms/Win11nextx64_host_uefi_q35_viommu.json index 4d090568..0419fca5 100644 --- a/lib/engines/hcktest/platforms/Win11nextx64_host_uefi_q35_viommu.json +++ b/lib/engines/hcktest/platforms/Win11nextx64_host_uefi_q35_viommu.json @@ -2,7 +2,6 @@ "name": "Win11nextx64_host_uefi_q35_viommu", "kit": "HLK11_next", "fw_type": "uefi", - "install_fw_type": "uefi_sb", "machine_type": "q35", "viommu_state": true, "enlightenments_state": true, diff --git a/lib/setupmanagers/qemuhck/fw.json b/lib/setupmanagers/qemuhck/fw.json index 71632041..6bad4b5a 100644 --- a/lib/setupmanagers/qemuhck/fw.json +++ b/lib/setupmanagers/qemuhck/fw.json @@ -4,12 +4,10 @@ }, "uefi": { "disk_config": "uefi", - "binary": "/usr/share/OVMF/OVMF_CODE.fd", - "nvram": "/usr/share/OVMF/OVMF_VARS.fd" - }, - "uefi_sb": { - "disk_config": "uefi", - "binary": "/usr/share/OVMF/OVMF_CODE.secboot.fd", + "binary": { + "secure": "/usr/share/OVMF/OVMF_CODE.secboot.fd", + "insecure": "/usr/share/OVMF/OVMF_CODE.fd" + }, "nvram": "/usr/share/OVMF/OVMF_VARS.secboot.fd" } } diff --git a/lib/setupmanagers/qemuhck/qemu_machine.rb b/lib/setupmanagers/qemuhck/qemu_machine.rb index 88d3cafe..261a8512 100644 --- a/lib/setupmanagers/qemuhck/qemu_machine.rb +++ b/lib/setupmanagers/qemuhck/qemu_machine.rb @@ -65,7 +65,6 @@ def initialize(scope, logger, machine, run_name, run_opts) @run_opts = run_opts @keep_alive = run_opts[:keep_alive] @delete_snapshot = run_opts[:create_snapshot] - @machine.run_config_commands run_vm scope << self end @@ -187,7 +186,8 @@ def close first_time: false, create_snapshot: true, attach_iso_list: [], - dump_only: false + dump_only: false, + secure: false }.freeze MACHINE_JSON = 'lib/setupmanagers/qemuhck/machine.json' @@ -221,6 +221,7 @@ def define_local_variables @drive_cache_options = [] @define_variables = {} @run_opts = {} + @configured = false end def load_options(options) @@ -492,7 +493,11 @@ def base_cmd def fw_cmd cmd = [] - cmd << "-drive if=pflash,format=raw,readonly=on,file=#{@fw['binary']}" if @fw['binary'] + if @fw['binary'] + file = @fw['binary'][@run_opts[:secure] ? 'secure' : 'insecure'] + cmd << "-drive if=pflash,format=raw,readonly=on,file=#{file}" + end + cmd << "-drive if=pflash,format=raw,file=#{@fw['nvram']}" if @fw['nvram'] cmd @@ -659,6 +664,11 @@ def run(scope, run_opts = nil) if @run_opts[:dump_only] dump_commands else + unless @configured + run_config_commands + @configured = true + end + scope.transaction do |tmp_scope| hostfwd = Hostfwd.new(@options['slirp'], [@monitor_port, @vnc_port]) tmp_scope << hostfwd diff --git a/lib/setupmanagers/qemuhck/qemuhck.rb b/lib/setupmanagers/qemuhck/qemuhck.rb index b4e7c83b..3c32e7c3 100644 --- a/lib/setupmanagers/qemuhck/qemuhck.rb +++ b/lib/setupmanagers/qemuhck/qemuhck.rb @@ -76,7 +76,7 @@ def boot_device end def client_vm_common_options - base = { + { 'id' => @id.to_i, 'workspace_path' => @workspace_path, 'devices_list' => @devices, @@ -85,17 +85,6 @@ def client_vm_common_options 'iso_path' => @project.config['iso_path'], 'client_world_net' => @project.options.common.client_world_net }.merge(boot_device) - - mode = @project.options.mode - fw_type = @platform["#{mode}_fw_type"] - unless fw_type.nil? - @logger.warn( - "Platform has #{mode}_fw_type = #{fw_type}, force to use it instead of #{base['fw_type']}" - ) - base['fw_type'] = fw_type - end - - base end def initialize_clients_vm diff --git a/lib/setupmanagers/qemuhck/states.json b/lib/setupmanagers/qemuhck/states.json index 271448b5..8dfe450a 100644 --- a/lib/setupmanagers/qemuhck/states.json +++ b/lib/setupmanagers/qemuhck/states.json @@ -51,5 +51,12 @@ "true": { "drive_cache_options": ",cache=unsafe" } + }, + "fw_type": { + "uefi": { + "devices_list": [ + "tpm-tis" + ] + } } }