From 4d1994af01ef6f66496f737a0a6fcc2e976522f9 Mon Sep 17 00:00:00 2001 From: Leos Stejskal Date: Mon, 17 Jun 2024 15:25:20 +0200 Subject: [PATCH] EFI & Secure Boot --- .rubocop.yml | 4 ++ lib/fog/libvirt/models/compute/server.rb | 33 +++++++++----- tests/libvirt/models/compute/server_tests.rb | 48 ++++++++++++++++---- 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 50cf087..050ba09 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -21,3 +21,7 @@ SignalException: Metrics/ClassLength: Enabled: false + +Metrics/BlockLength: + Exclude: + - tests/**/*.rb diff --git a/lib/fog/libvirt/models/compute/server.rb b/lib/fog/libvirt/models/compute/server.rb index 55241f2..b42b11c 100644 --- a/lib/fog/libvirt/models/compute/server.rb +++ b/lib/fog/libvirt/models/compute/server.rb @@ -1,6 +1,6 @@ -require 'fog/compute/models/server' -require 'fog/libvirt/models/compute/util/util' -require 'fileutils' +require "fog/compute/models/server" +require "fog/libvirt/models/compute/util/util" +require "fileutils" module Fog module Libvirt @@ -9,11 +9,13 @@ class Server < Fog::Compute::Server include Fog::Libvirt::Util attr_reader :xml - identity :id, :aliases => 'uuid' + identity :id, :aliases => "uuid" attribute :cpus attribute :cputime + attribute :os_firmware attribute :os_type + attribute :os_loader_attrs attribute :memory_size attribute :max_memory_size attribute :name @@ -61,7 +63,7 @@ def new? end def save - raise Fog::Errors::Error.new('Saving an existing server may create a duplicate') unless new? + raise Fog::Errors::Error.new("Saving an existing server may create a duplicate") unless new? create_or_clone_volume unless xml or @volumes create_user_data_iso if user_data @xml ||= to_xml @@ -170,7 +172,7 @@ def ssh(commands) def ssh_proxy begin - require 'net/ssh/proxy/command' + require "net/ssh/proxy/command" rescue LoadError Fog::Logger.warning("'net/ssh' missing, please install and try again.") exit(1) @@ -214,7 +216,7 @@ def setup(credentials = {}) Timeout::timeout(360) do begin Timeout::timeout(8) do - Fog::SSH.new(ssh_ip_address, username, credentials.merge(:timeout => 4)).run('pwd') + Fog::SSH.new(ssh_ip_address, username, credentials.merge(:timeout => 4)).run("pwd") end rescue Errno::ECONNREFUSED sleep(2) @@ -238,16 +240,16 @@ def vnc_port end def generate_config_iso(user_data, &blk) - Dir.mktmpdir('config') do |wd| + Dir.mktmpdir("config") do |wd| generate_config_iso_in_dir(wd, user_data, &blk) end end def generate_config_iso_in_dir(dir_path, user_data, &blk) FileUtils.touch(File.join(dir_path, "meta-data")) - File.open(File.join(dir_path, 'user-data'), 'w') { |f| f.write user_data } + File.open(File.join(dir_path, "user-data"), "w") { |f| f.write user_data } - isofile = Tempfile.new(['init', '.iso']).path + isofile = Tempfile.new(["init", ".iso"]).path unless system("genisoimage -output #{isofile} -volid cidata -joliet -rock #{File.join(dir_path, 'user-data')} #{File.join(dir_path, 'meta-data')}") raise Fog::Errors::Error.new("Couldn't generate cloud-init iso disk with genisoimage.") end @@ -281,14 +283,21 @@ def to_xml end xml.vcpu(cpus) - xml.os do + + os_tags = {} + # Set firmware only if it's EFI, BIOS don't need to be set + os_tags[:firmware] = "efi" if os_firmware == "efi" + + xml.os(**os_tags) do type = xml.type(os_type, :arch => arch) type[:machine] = "q35" if ["i686", "x86_64"].include?(arch) + xml.loader(os_loader_attrs) boot_order.each do |dev| xml.boot(:dev => dev) end end + xml.features do xml.acpi xml.apic @@ -678,7 +687,7 @@ def verify_boot_order order = [] end def default_display - {:port => '-1', :listen => '127.0.0.1', :type => 'vnc', :password => '' } + {:port => "-1", :listen => "127.0.0.1", :type => "vnc", :password => "" } end end end diff --git a/tests/libvirt/models/compute/server_tests.rb b/tests/libvirt/models/compute/server_tests.rb index 6983cbb..833b39a 100644 --- a/tests/libvirt/models/compute/server_tests.rb +++ b/tests/libvirt/models/compute/server_tests.rb @@ -1,13 +1,13 @@ -Shindo.tests('Fog::Compute[:libvirt] | server model', ['libvirt']) do +Shindo.tests("Fog::Compute[:libvirt] | server model", ["libvirt"]) do servers = Fog::Compute[:libvirt].servers server = servers.all.select{|v| v.name =~ /^fog/}.last - tests('The server model should') do - tests('have the action') do - test('autostart') { server.respond_to? 'autostart' } - test('update_autostart') { server.respond_to? 'update_autostart' } - test('reload') { server.respond_to? 'reload' } + tests("The server model should") do + tests("have the action") do + test("autostart") { server.respond_to? "autostart" } + test("update_autostart") { server.respond_to? "update_autostart" } + test("reload") { server.respond_to? "reload" } %w{ start stop destroy reboot suspend }.each do |action| test(action) { server.respond_to? action } end @@ -22,14 +22,16 @@ } end end - tests('have an ip_address action that') do - test('returns the latest IP address lease') { server.public_ip_address() == '1.2.5.6' } + tests("have an ip_address action that") do + test("returns the latest IP address lease") { server.public_ip_address() == "1.2.5.6" } end - tests('have attributes') do + tests("have attributes") do model_attribute_hash = server.attributes attributes = [ :id, :cpus, :cputime, + :os_firmware, + :os_loader, :os_type, :memory_size, :max_memory_size, @@ -58,8 +60,9 @@ end end end - test('be a kind of Fog::Libvirt::Compute::Server') { server.kind_of? Fog::Libvirt::Compute::Server } + test("be a kind of Fog::Libvirt::Compute::Server") { server.kind_of? Fog::Libvirt::Compute::Server } tests("serializes to xml") do + test("without firmware") { server.to_xml.include?("") } test("with memory") { server.to_xml.match?(%r{\d+}) } test("with disk of type file") do xml = server.to_xml @@ -78,6 +81,31 @@ xml.match?(//) && xml.match?(%r{}) end test("with q35 machine type on x86_64") { server.to_xml.match?(%r{hvm}) } + test("with efi firmware") do + server = Fog::Libvirt::Compute::Server.new( + { + :os_firmware => "efi", + :os_loader_attrs => {}, + :nics => [], + :volumes => [] + } + ) + + server.to_xml.include?('') + end + test("with secure boot") do + server = Fog::Libvirt::Compute::Server.new( + { + :os_firmware => "efi", + :os_loader_attrs => { :secure => "yes" }, + :nics => [], + :volumes => [] + } + ) + xml = server.to_xml + + xml.include?('') && xml.include?('') + end end end end