diff --git a/package/autoyast2.changes b/package/autoyast2.changes index 2d5691299..7507ce4e7 100644 --- a/package/autoyast2.changes +++ b/package/autoyast2.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Thu Nov 18 11:10:28 UTC 2021 - Knut Anderssen + +- Add support for detecting EFI boot during autoinstallation + (jsc#SLE-18819) +- 4.4.21 + ------------------------------------------------------------------- Fri Nov 12 13:21:54 UTC 2021 - Imobach Gonzalez Sosa diff --git a/package/autoyast2.spec b/package/autoyast2.spec index 3a13a9e36..3674ab4ae 100644 --- a/package/autoyast2.spec +++ b/package/autoyast2.spec @@ -22,7 +22,7 @@ %endif Name: autoyast2 -Version: 4.4.20 +Version: 4.4.21 Release: 0 Summary: YaST2 - Automated Installation License: GPL-2.0-only diff --git a/src/autoyast-rnc/rules.rnc b/src/autoyast-rnc/rules.rnc index ff62e55e8..dcf4b8286 100644 --- a/src/autoyast-rnc/rules.rnc +++ b/src/autoyast-rnc/rules.rnc @@ -49,6 +49,7 @@ y2_match_to = | hostname | hostaddress | hostid + | efi | karch | linux | installed_product @@ -72,6 +73,7 @@ custom4 = element custom4 { MAP, (match_text custom5 = element custom5 { MAP, (match_text & match_type? & script) } disksize = element disksize { MAP, (match_text & match_type?) } domain = element domain { MAP, (match_text & match_type?) } +efi = element efi { MAP, (match_text & match_type?) } hostname = element hostname { MAP, (match_text & match_type?) } hostaddress = element hostaddress { MAP, (match_text & match_type?) } hostid = element hostid { MAP, (match_text & match_type?) } diff --git a/src/lib/autoinstall/clients/ayast_probe.rb b/src/lib/autoinstall/clients/ayast_probe.rb index bc9e01af1..4d1e5b919 100644 --- a/src/lib/autoinstall/clients/ayast_probe.rb +++ b/src/lib/autoinstall/clients/ayast_probe.rb @@ -75,6 +75,7 @@ def table(rows) :hostaddress, :network, :domain, + :efi, :arch, :karch, :product, diff --git a/src/lib/autoinstall/efi_detector.rb b/src/lib/autoinstall/efi_detector.rb new file mode 100644 index 000000000..714503d9e --- /dev/null +++ b/src/lib/autoinstall/efi_detector.rb @@ -0,0 +1,23 @@ +Yast.import "Linuxrc" +Yast.import "Stage" + +module Y2Autoinstallation + # This class is responsible of detecting if the system was booted using EFI or not + class EFIDetector + EFI_VARS_DIRS = ["/sys/firmware/efi/efivars", "/sys/firmware/efi/vars/"].freeze + + # Returns whether the system was booted using UEFI or not + # + # During the First Stage of the installation it relies on linuxrc for detecting the boot + # but in the rest of cases it checks if any of the EFI vars directories exist + # + # @return [Boolean] whether the system was booted using UEFI or not + def self.boot_efi? + if Yast::Stage.initial + Yast::Linuxrc.InstallInf("EFI") == "1" + else + EFI_VARS_DIRS.any? { |d| Dir.exist?(d) } + end + end + end +end diff --git a/src/lib/autoinstall/y2erb.rb b/src/lib/autoinstall/y2erb.rb index 7a2deecbf..e108dac01 100644 --- a/src/lib/autoinstall/y2erb.rb +++ b/src/lib/autoinstall/y2erb.rb @@ -1,5 +1,6 @@ require "yast" require "erb" +require "autoinstall/efi_detector" module Y2Autoinstallation class Y2ERB @@ -12,6 +13,12 @@ def self.render(path) class TemplateEnvironment include Yast::Logger + # @see Y2Autoinstallation::EFIDetector + # @return [Boolean] whether the system is booted using EFI or not + def boot_efi? + EFIDetector.boot_efi? + end + def hardware @hardware ||= Yast::SCR.Read(Yast::Path.new(".probe")) end diff --git a/src/modules/AutoInstallRules.rb b/src/modules/AutoInstallRules.rb index 2955d5110..03a850b02 100644 --- a/src/modules/AutoInstallRules.rb +++ b/src/modules/AutoInstallRules.rb @@ -6,6 +6,7 @@ # $Id$ require "yast" require "autoinstall/xml_checks" +require "autoinstall/efi_detector" require "yast2/popup" require "y2storage" @@ -24,6 +25,7 @@ def main Yast.import "XML" Yast.import "Kernel" Yast.import "Mode" + Yast.import "Linuxrc" Yast.import "Profile" Yast.import "Label" Yast.import "Report" @@ -84,6 +86,7 @@ def reset @totaldisk = 0 @hostid = "" @mac = "" + @efi = "no" @linux = 0 @others = 0 @xserver = "" @@ -286,6 +289,11 @@ def ProbeRules # Ops.set(@ATTR, "mac", @mac) + # + # EFI Boot + @efi = boot_efi? + @ATTR["efi"] = @efi + # # Network # @@ -470,6 +478,7 @@ def Read "installed_product_version", "installed_product", "domain", + "efi", "network", "mac", "karch", @@ -1072,10 +1081,17 @@ def CreateFile(filename) def AutoInstallRules @mac = getMAC @hostid = getHostid - Builtins.y2milestone("init mac:%1 hostid:%2", @mac, @hostid) + @efi = boot_efi? + log.info "init mac:#{@mac} hostid: #{@hostid} efi: #{@efi}" nil end + # @see Y2Autoinstallation::EFIDetector + # @return [String] "yes" when the system is booted using EFI or "no" when not + def boot_efi? + Y2Autoinstallation::EFIDetector.boot_efi? ? "yes" : "no" + end + # Regexp to extract the IP from the routes table HOSTADDRESS_REGEXP = /src ([\w.]+) /.freeze @@ -1118,6 +1134,7 @@ def hostaddress publish variable: :mac, type: "string" publish variable: :linux, type: "integer" publish variable: :others, type: "integer" + publish variable: :efi, type: "string" publish variable: :xserver, type: "string" publish variable: :NonLinuxPartitions, type: "list" publish variable: :LinuxPartitions, type: "list" diff --git a/test/AutoInstallRules_test.rb b/test/AutoInstallRules_test.rb index a62b7d5e2..bd72526a5 100755 --- a/test/AutoInstallRules_test.rb +++ b/test/AutoInstallRules_test.rb @@ -43,6 +43,7 @@ expect(Yast::Kernel).to receive(:GetPackages).and_return([]) expect(subject).to receive(:getNetwork).and_return("192.168.1.0") expect(subject).to receive(:getHostname).and_return("myhost") + expect(Y2Autoinstallation::EFIDetector).to receive(:boot_efi?).and_return(true) expect(Yast::SCR).to receive(:Read).with(Yast::Path.new(".etc.install_inf.XServer")) expect(Yast::Hostname).to receive(:CurrentDomain).and_return("mydomain.lan") @@ -55,6 +56,7 @@ expect(Yast::AutoInstallRules.installed_product).to eq("SUSE Linux Enterprise Server 12") expect(Yast::AutoInstallRules.installed_product_version).to eq("12") + expect(Yast::AutoInstallRules.efi).to eq("yes") end end diff --git a/test/lib/efi_detector_test.rb b/test/lib/efi_detector_test.rb new file mode 100644 index 000000000..f843a1b06 --- /dev/null +++ b/test/lib/efi_detector_test.rb @@ -0,0 +1,49 @@ +require_relative "../test_helper" +require "autoinstall/efi_detector" + +describe Y2Autoinstallation::EFIDetector do + describe ".boot_efi?" do + let(:efi) { true } + + context "when called in the initial Stage" do + before do + allow(Yast::Linuxrc).to receive(:InstallInf).with("EFI").and_return(efi) + end + + context "and EFI is read as '1' from the Install.inf file" do + it "returns true" do + expect(described_class.boot_efi?) + end + end + + context "and EFI is not read as '1' from the Install.inf file" do + let(:efi) { false } + + it "returns false" do + expect(described_class.boot_efi?) + end + end + end + + context "when called in normal Mode" do + before do + allow(Dir).to receive(:exist?) + end + + described_class.const_get("EFI_VARS_DIRS").each do |dir| + it "returns true if '#{dir}' exists" do + expect(Dir).to receive(:exist?).with(dir).and_return(true) + expect(described_class.boot_efi?).to eq(true) + end + end + + it "returns false otherwise" do + described_class.const_get("EFI_VARS_DIRS").each do |dir| + allow(Dir).to receive(:exist?).with(dir).and_return(false) + end + + expect(described_class.boot_efi?).to eq(false) + end + end + end +end diff --git a/test/lib/y2erb_test.rb b/test/lib/y2erb_test.rb index 55cb48006..30ed1a1b7 100644 --- a/test/lib/y2erb_test.rb +++ b/test/lib/y2erb_test.rb @@ -212,6 +212,28 @@ def hardware_mock_data allow(Yast::SCR).to receive(:Read).and_return(hardware_mock_data) end + describe "#boot_efi?" do + let(:efi) { true } + + before do + allow(Y2Autoinstallation::EFIDetector).to receive(:boot_efi?).and_return(efi) + end + + context "when the system was booted with EFI" do + it "returns true" do + expect(subject.boot_efi?).to eq(true) + end + end + + context "when the system was not booted with EFI" do + let(:efi) { false } + + it "returns false" do + expect(subject.boot_efi?).to eq(false) + end + end + end + describe "#network_cards" do it "returns list of map" do expect(subject.network_cards).to be_a(Array)