From 78c1504f7f284d5d6fa6eb8084b07a99feffcf6e Mon Sep 17 00:00:00 2001 From: Dustin Sweigart Date: Sat, 1 Jun 2024 10:00:01 +0000 Subject: [PATCH 01/16] lxd/instance/drivers/edk2: Add new package to track EDK2 firmwares Signed-off-by: Dustin Sweigart (cherry picked from commit 6d04eb437b0f35ba0faca3e25b846cdbccf5d8ce) Signed-off-by: Thomas Parrott License: Apache-2.0 --- lxd/instance/drivers/edk2/edk2.go | 153 ++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 lxd/instance/drivers/edk2/edk2.go diff --git a/lxd/instance/drivers/edk2/edk2.go b/lxd/instance/drivers/edk2/edk2.go new file mode 100644 index 000000000000..d2b1e3cd6f08 --- /dev/null +++ b/lxd/instance/drivers/edk2/edk2.go @@ -0,0 +1,153 @@ +package edk2 + +import ( + "os" + "path/filepath" + + "github.com/canonical/lxd/shared/osarch" +) + +// FirmwarePair represents a combination of firmware code (Code) and storage (Vars). +type FirmwarePair struct { + Code string + Vars string +} + +// Installation represents a set of available firmware at a given location on the system. +type Installation struct { + Path string + Usage map[FirmwareUsage][]FirmwarePair +} + +// FirmwareUsage represents the situation in which a given firmware file will be used. +type FirmwareUsage int + +const ( + // GENERIC is a generic EDK2 firmware. + GENERIC FirmwareUsage = iota + + // SECUREBOOT is a UEFI Secure Boot enabled firmware. + SECUREBOOT + + // CSM is a firmware with the UEFI Compatibility Support Module enabled to boot BIOS-only operating systems. + CSM +) + +// OVMFDebugFirmware is the debug version of the "preferred" firmware. +const OVMFDebugFirmware = "OVMF_CODE.4MB.debug.fd" + +var architectureInstallations = map[int][]Installation{ + osarch.ARCH_64BIT_INTEL_X86: {{ + Path: "/usr/share/OVMF", + Usage: map[FirmwareUsage][]FirmwarePair{ + GENERIC: { + {Code: "OVMF_CODE.4MB.fd", Vars: "OVMF_VARS.4MB.fd"}, + {Code: "OVMF_CODE_4M.fd", Vars: "OVMF_VARS_4M.fd"}, + {Code: "OVMF_CODE.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.2MB.fd", Vars: "OVMF_VARS.2MB.fd"}, + {Code: "OVMF_CODE.fd", Vars: "OVMF_VARS.fd"}, + {Code: "OVMF_CODE.fd", Vars: "qemu.nvram"}, + }, + SECUREBOOT: { + {Code: "OVMF_CODE.4MB.fd", Vars: "OVMF_VARS.4MB.ms.fd"}, + {Code: "OVMF_CODE_4M.ms.fd", Vars: "OVMF_VARS_4M.ms.fd"}, + {Code: "OVMF_CODE_4M.secboot.fd", Vars: "OVMF_VARS_4M.secboot.fd"}, + {Code: "OVMF_CODE.secboot.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.secboot.fd", Vars: "OVMF_VARS.secboot.fd"}, + {Code: "OVMF_CODE.secboot.fd", Vars: "OVMF_VARS.fd"}, + {Code: "OVMF_CODE.2MB.fd", Vars: "OVMF_VARS.2MB.ms.fd"}, + {Code: "OVMF_CODE.fd", Vars: "OVMF_VARS.ms.fd"}, + {Code: "OVMF_CODE.fd", Vars: "qemu.nvram"}, + }, + CSM: { + {Code: "bios-256k.bin", Vars: "bios-256k.bin"}, + {Code: "seabios.bin", Vars: "seabios.bin"}, + {Code: "OVMF_CODE.4MB.CSM.fd", Vars: "OVMF_VARS.4MB.CSM.fd"}, + {Code: "OVMF_CODE.csm.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.2MB.CSM.fd", Vars: "OVMF_VARS.2MB.CSM.fd"}, + {Code: "OVMF_CODE.CSM.fd", Vars: "OVMF_VARS.CSM.fd"}, + {Code: "OVMF_CODE.csm.fd", Vars: "OVMF_VARS.fd"}, + }, + }, + }, { + Path: "/usr/share/qemu", + Usage: map[FirmwareUsage][]FirmwarePair{ + GENERIC: { + {Code: "ovmf-x86_64-4m-code.bin", Vars: "ovmf-x86_64-4m-vars.bin"}, + {Code: "ovmf-x86_64.bin", Vars: "ovmf-x86_64-code.bin"}, + }, + SECUREBOOT: { + {Code: "ovmf-x86_64-ms-4m-vars.bin", Vars: "ovmf-x86_64-ms-4m-code.bin"}, + {Code: "ovmf-x86_64-ms-code.bin", Vars: "ovmf-x86_64-ms-vars.bin"}, + }, + }, + }}, + osarch.ARCH_64BIT_ARMV8_LITTLE_ENDIAN: {{ + Path: "/usr/share/AAVMF", + Usage: map[FirmwareUsage][]FirmwarePair{ + GENERIC: { + {Code: "AAVMF_CODE.fd", Vars: "AAVMF_VARS.fd"}, + }, + SECUREBOOT: { + {Code: "AAVMF_CODE.ms.fd", Vars: "AAVMF_VARS.ms.fd"}, + }, + }, + }}, +} + +// GetArchitectureInstallations returns an array of installations for a specific host architecture. +func GetArchitectureInstallations(hostArch int) []Installation { + installations, found := architectureInstallations[hostArch] + if found { + return installations + } + + return []Installation{} +} + +// GetAchitectureFirmwarePairs creates an array of FirmwarePair for a +// specific host architecture. If the environment variable LXD_QEMU_FW_PATH +// has been set it will override the default installation path when +// constructing Code & Vars paths. +func GetAchitectureFirmwarePairs(hostArch int) []FirmwarePair { + firmwares := make([]FirmwarePair, 0) + + for _, usage := range []FirmwareUsage{GENERIC, SECUREBOOT, CSM} { + firmwares = append(firmwares, GetArchitectureFirmwarePairsForUsage(hostArch, usage)...) + } + + return firmwares +} + +// GetArchitectureFirmwarePairsForUsage creates an array of FirmwarePair +// for a specific host architecture and usage combination. If the +// environment variable LXD_QEMU_FW_PATH has been set it will override the +// default installation path when constructing Code & Vars paths. +func GetArchitectureFirmwarePairsForUsage(hostArch int, usage FirmwareUsage) []FirmwarePair { + firmwares := make([]FirmwarePair, 0) + + for _, installation := range GetArchitectureInstallations(hostArch) { + usage, found := installation.Usage[usage] + if found { + for _, firmwarePair := range usage { + searchPath := installation.Path + + if GetenvEdk2Path() != "" { + searchPath = GetenvEdk2Path() + } + + firmwares = append(firmwares, FirmwarePair{ + Code: filepath.Join(searchPath, firmwarePair.Code), + Vars: filepath.Join(searchPath, firmwarePair.Vars), + }) + } + } + } + + return firmwares +} + +// GetenvEdk2Path returns the environment variable for overriding the path to use for EDK2 installations. +func GetenvEdk2Path() string { + return os.Getenv("LXD_QEMU_FW_PATH") +} From 63e6d372ff92aea5a4b2f98a8392237bf73f891c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Fri, 12 Jul 2024 23:48:21 -0400 Subject: [PATCH 02/16] lxd/instance/drivers/edk2: Support OVMF filenames on arm64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quite a few environments use OVMF on arm64 rather than the more technicaly correct AAVMF name. Signed-off-by: Stéphane Graber (cherry picked from commit cc33d436d193f12a38818482c050fafd1ecae04c) Signed-off-by: Thomas Parrott License: Apache-2.0 --- lxd/instance/drivers/edk2/edk2.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lxd/instance/drivers/edk2/edk2.go b/lxd/instance/drivers/edk2/edk2.go index d2b1e3cd6f08..84b0fdf384c5 100644 --- a/lxd/instance/drivers/edk2/edk2.go +++ b/lxd/instance/drivers/edk2/edk2.go @@ -87,9 +87,24 @@ var architectureInstallations = map[int][]Installation{ Usage: map[FirmwareUsage][]FirmwarePair{ GENERIC: { {Code: "AAVMF_CODE.fd", Vars: "AAVMF_VARS.fd"}, + {Code: "OVMF_CODE.4MB.fd", Vars: "OVMF_VARS.4MB.fd"}, + {Code: "OVMF_CODE_4M.fd", Vars: "OVMF_VARS_4M.fd"}, + {Code: "OVMF_CODE.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.2MB.fd", Vars: "OVMF_VARS.2MB.fd"}, + {Code: "OVMF_CODE.fd", Vars: "OVMF_VARS.fd"}, + {Code: "OVMF_CODE.fd", Vars: "qemu.nvram"}, }, SECUREBOOT: { {Code: "AAVMF_CODE.ms.fd", Vars: "AAVMF_VARS.ms.fd"}, + {Code: "OVMF_CODE.4MB.fd", Vars: "OVMF_VARS.4MB.ms.fd"}, + {Code: "OVMF_CODE_4M.ms.fd", Vars: "OVMF_VARS_4M.ms.fd"}, + {Code: "OVMF_CODE_4M.secboot.fd", Vars: "OVMF_VARS_4M.secboot.fd"}, + {Code: "OVMF_CODE.secboot.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.secboot.fd", Vars: "OVMF_VARS.secboot.fd"}, + {Code: "OVMF_CODE.secboot.fd", Vars: "OVMF_VARS.fd"}, + {Code: "OVMF_CODE.2MB.fd", Vars: "OVMF_VARS.2MB.ms.fd"}, + {Code: "OVMF_CODE.fd", Vars: "OVMF_VARS.ms.fd"}, + {Code: "OVMF_CODE.fd", Vars: "qemu.nvram"}, }, }, }}, From 6168f3559c0e34e43b0409dc76a45926196e8a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Sun, 21 Jul 2024 19:09:05 -0400 Subject: [PATCH 03/16] lxd/instance/drivers/edk2: Move seabios to /usr/share/qemu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber (cherry picked from commit 5b093d06795e2c65cf5b4682b341237c1acd31d3) Signed-off-by: Thomas Parrott License: Apache-2.0 --- lxd/instance/drivers/edk2/edk2.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lxd/instance/drivers/edk2/edk2.go b/lxd/instance/drivers/edk2/edk2.go index 84b0fdf384c5..52fe301e1edd 100644 --- a/lxd/instance/drivers/edk2/edk2.go +++ b/lxd/instance/drivers/edk2/edk2.go @@ -60,8 +60,6 @@ var architectureInstallations = map[int][]Installation{ {Code: "OVMF_CODE.fd", Vars: "qemu.nvram"}, }, CSM: { - {Code: "bios-256k.bin", Vars: "bios-256k.bin"}, - {Code: "seabios.bin", Vars: "seabios.bin"}, {Code: "OVMF_CODE.4MB.CSM.fd", Vars: "OVMF_VARS.4MB.CSM.fd"}, {Code: "OVMF_CODE.csm.4m.fd", Vars: "OVMF_VARS.4m.fd"}, {Code: "OVMF_CODE.2MB.CSM.fd", Vars: "OVMF_VARS.2MB.CSM.fd"}, @@ -73,6 +71,7 @@ var architectureInstallations = map[int][]Installation{ Path: "/usr/share/qemu", Usage: map[FirmwareUsage][]FirmwarePair{ GENERIC: { + {Code: "seabios.bin", Vars: "seabios.bin"}, {Code: "ovmf-x86_64-4m-code.bin", Vars: "ovmf-x86_64-4m-vars.bin"}, {Code: "ovmf-x86_64.bin", Vars: "ovmf-x86_64-code.bin"}, }, From b0499ef8db1fd4468aa5421c2924d4cb83b66b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Sun, 21 Jul 2024 19:09:15 -0400 Subject: [PATCH 04/16] lxd/instance/drivers/edk2: Add ArchLinux x86_64 paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber (cherry picked from commit 9072c73f9269113cc5ff46fd3014f6a291c59e54) Signed-off-by: Thomas Parrott License: Apache-2.0 --- lxd/instance/drivers/edk2/edk2.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lxd/instance/drivers/edk2/edk2.go b/lxd/instance/drivers/edk2/edk2.go index 52fe301e1edd..a5d413993a38 100644 --- a/lxd/instance/drivers/edk2/edk2.go +++ b/lxd/instance/drivers/edk2/edk2.go @@ -80,6 +80,22 @@ var architectureInstallations = map[int][]Installation{ {Code: "ovmf-x86_64-ms-code.bin", Vars: "ovmf-x86_64-ms-vars.bin"}, }, }, + }, { + Path: "/usr/share/OVMF/x64", + Usage: map[FirmwareUsage][]FirmwarePair{ + GENERIC: { + {Code: "OVMF_CODE.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.fd", Vars: "OVMF_VARS.fd"}, + }, + CSM: { + {Code: "OVMF_CODE.csm.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.csm.fd", Vars: "OVMF_VARS.fd"}, + }, + SECUREBOOT: { + {Code: "OVMF_CODE.secboot.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.secboot.fd", Vars: "OVMF_VARS.fd"}, + }, + }, }}, osarch.ARCH_64BIT_ARMV8_LITTLE_ENDIAN: {{ Path: "/usr/share/AAVMF", From d9afb307c9cdc451eabbf9093bb89678bb77e904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Sat, 27 Jul 2024 01:36:07 -0400 Subject: [PATCH 05/16] lxd/instance/drivers/edk2: Fix CSM handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber (cherry picked from commit 8e33c788fa48ffceaf5a4f91eeb9835141dd7862) Signed-off-by: Thomas Parrott License: Apache-2.0 --- lxd/instance/drivers/edk2/edk2.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lxd/instance/drivers/edk2/edk2.go b/lxd/instance/drivers/edk2/edk2.go index a5d413993a38..f1d7fd1e796f 100644 --- a/lxd/instance/drivers/edk2/edk2.go +++ b/lxd/instance/drivers/edk2/edk2.go @@ -60,6 +60,7 @@ var architectureInstallations = map[int][]Installation{ {Code: "OVMF_CODE.fd", Vars: "qemu.nvram"}, }, CSM: { + {Code: "seabios.bin", Vars: "seabios.bin"}, {Code: "OVMF_CODE.4MB.CSM.fd", Vars: "OVMF_VARS.4MB.CSM.fd"}, {Code: "OVMF_CODE.csm.4m.fd", Vars: "OVMF_VARS.4m.fd"}, {Code: "OVMF_CODE.2MB.CSM.fd", Vars: "OVMF_VARS.2MB.CSM.fd"}, @@ -71,7 +72,6 @@ var architectureInstallations = map[int][]Installation{ Path: "/usr/share/qemu", Usage: map[FirmwareUsage][]FirmwarePair{ GENERIC: { - {Code: "seabios.bin", Vars: "seabios.bin"}, {Code: "ovmf-x86_64-4m-code.bin", Vars: "ovmf-x86_64-4m-vars.bin"}, {Code: "ovmf-x86_64.bin", Vars: "ovmf-x86_64-code.bin"}, }, @@ -79,6 +79,9 @@ var architectureInstallations = map[int][]Installation{ {Code: "ovmf-x86_64-ms-4m-vars.bin", Vars: "ovmf-x86_64-ms-4m-code.bin"}, {Code: "ovmf-x86_64-ms-code.bin", Vars: "ovmf-x86_64-ms-vars.bin"}, }, + CSM: { + {Code: "seabios.bin", Vars: "seabios.bin"}, + }, }, }, { Path: "/usr/share/OVMF/x64", From fa5ce8053d37553537388ce4aa5c5006319e5d39 Mon Sep 17 00:00:00 2001 From: dkwo Date: Mon, 2 Sep 2024 10:44:18 -0400 Subject: [PATCH 06/16] lxd/instance/drivers/edk2: Add Void Linux x86_64 paths Signed-off-by: dkwo (cherry picked from commit cfbbe5d289ac5285b2a9880bd6f6cbb9041f8a4f) Signed-off-by: Thomas Parrott License: Apache-2.0 --- lxd/instance/drivers/edk2/edk2.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lxd/instance/drivers/edk2/edk2.go b/lxd/instance/drivers/edk2/edk2.go index f1d7fd1e796f..e861eb1ea1f0 100644 --- a/lxd/instance/drivers/edk2/edk2.go +++ b/lxd/instance/drivers/edk2/edk2.go @@ -83,6 +83,18 @@ var architectureInstallations = map[int][]Installation{ {Code: "seabios.bin", Vars: "seabios.bin"}, }, }, + }, { + Path: "/usr/share/edk2/x64", + Usage: map[FirmwareUsage][]FirmwarePair{ + GENERIC: { + {Code: "OVMF_CODE.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.fd", Vars: "OVMF_VARS.fd"}, + }, + SECUREBOOT: { + {Code: "OVMF_CODE.secure.4m.fd", Vars: "OVMF_VARS.4m.fd"}, + {Code: "OVMF_CODE.secure.fd", Vars: "OVMF_VARS.fd"}, + }, + }, }, { Path: "/usr/share/OVMF/x64", Usage: map[FirmwareUsage][]FirmwarePair{ From 4341a6cd230c5abff5ecbb344601daeb5cd6de95 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 3 Sep 2024 14:13:27 +0100 Subject: [PATCH 07/16] lxd/instance/drivers/edk2: Rework to support both LXD_QEMU_FW_PATH and LXD_OVMF_PATH Supporting multiple search paths. Signed-off-by: Thomas Parrott --- lxd/instance/drivers/edk2/edk2.go | 55 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/lxd/instance/drivers/edk2/edk2.go b/lxd/instance/drivers/edk2/edk2.go index e861eb1ea1f0..8974e598708b 100644 --- a/lxd/instance/drivers/edk2/edk2.go +++ b/lxd/instance/drivers/edk2/edk2.go @@ -3,6 +3,7 @@ package edk2 import ( "os" "path/filepath" + "strings" "github.com/canonical/lxd/shared/osarch" ) @@ -15,7 +16,7 @@ type FirmwarePair struct { // Installation represents a set of available firmware at a given location on the system. type Installation struct { - Path string + Paths []string Usage map[FirmwareUsage][]FirmwarePair } @@ -38,7 +39,7 @@ const OVMFDebugFirmware = "OVMF_CODE.4MB.debug.fd" var architectureInstallations = map[int][]Installation{ osarch.ARCH_64BIT_INTEL_X86: {{ - Path: "/usr/share/OVMF", + Paths: GetenvEdk2Paths("/usr/share/OVMF"), Usage: map[FirmwareUsage][]FirmwarePair{ GENERIC: { {Code: "OVMF_CODE.4MB.fd", Vars: "OVMF_VARS.4MB.fd"}, @@ -69,7 +70,7 @@ var architectureInstallations = map[int][]Installation{ }, }, }, { - Path: "/usr/share/qemu", + Paths: GetenvEdk2Paths("/usr/share/qemu"), Usage: map[FirmwareUsage][]FirmwarePair{ GENERIC: { {Code: "ovmf-x86_64-4m-code.bin", Vars: "ovmf-x86_64-4m-vars.bin"}, @@ -84,7 +85,7 @@ var architectureInstallations = map[int][]Installation{ }, }, }, { - Path: "/usr/share/edk2/x64", + Paths: GetenvEdk2Paths("/usr/share/edk2/x64"), Usage: map[FirmwareUsage][]FirmwarePair{ GENERIC: { {Code: "OVMF_CODE.4m.fd", Vars: "OVMF_VARS.4m.fd"}, @@ -96,7 +97,7 @@ var architectureInstallations = map[int][]Installation{ }, }, }, { - Path: "/usr/share/OVMF/x64", + Paths: GetenvEdk2Paths("/usr/share/OVMF/x64"), Usage: map[FirmwareUsage][]FirmwarePair{ GENERIC: { {Code: "OVMF_CODE.4m.fd", Vars: "OVMF_VARS.4m.fd"}, @@ -113,7 +114,7 @@ var architectureInstallations = map[int][]Installation{ }, }}, osarch.ARCH_64BIT_ARMV8_LITTLE_ENDIAN: {{ - Path: "/usr/share/AAVMF", + Paths: GetenvEdk2Paths("/usr/share/AAVMF"), Usage: map[FirmwareUsage][]FirmwarePair{ GENERIC: { {Code: "AAVMF_CODE.fd", Vars: "AAVMF_VARS.fd"}, @@ -151,9 +152,7 @@ func GetArchitectureInstallations(hostArch int) []Installation { } // GetAchitectureFirmwarePairs creates an array of FirmwarePair for a -// specific host architecture. If the environment variable LXD_QEMU_FW_PATH -// has been set it will override the default installation path when -// constructing Code & Vars paths. +// specific host architecture. func GetAchitectureFirmwarePairs(hostArch int) []FirmwarePair { firmwares := make([]FirmwarePair, 0) @@ -165,9 +164,7 @@ func GetAchitectureFirmwarePairs(hostArch int) []FirmwarePair { } // GetArchitectureFirmwarePairsForUsage creates an array of FirmwarePair -// for a specific host architecture and usage combination. If the -// environment variable LXD_QEMU_FW_PATH has been set it will override the -// default installation path when constructing Code & Vars paths. +// for a specific host architecture and usage combination. func GetArchitectureFirmwarePairsForUsage(hostArch int, usage FirmwareUsage) []FirmwarePair { firmwares := make([]FirmwarePair, 0) @@ -175,16 +172,12 @@ func GetArchitectureFirmwarePairsForUsage(hostArch int, usage FirmwareUsage) []F usage, found := installation.Usage[usage] if found { for _, firmwarePair := range usage { - searchPath := installation.Path - - if GetenvEdk2Path() != "" { - searchPath = GetenvEdk2Path() + for _, searchPath := range installation.Paths { + firmwares = append(firmwares, FirmwarePair{ + Code: filepath.Join(searchPath, firmwarePair.Code), + Vars: filepath.Join(searchPath, firmwarePair.Vars), + }) } - - firmwares = append(firmwares, FirmwarePair{ - Code: filepath.Join(searchPath, firmwarePair.Code), - Vars: filepath.Join(searchPath, firmwarePair.Vars), - }) } } } @@ -192,7 +185,21 @@ func GetArchitectureFirmwarePairsForUsage(hostArch int, usage FirmwareUsage) []F return firmwares } -// GetenvEdk2Path returns the environment variable for overriding the path to use for EDK2 installations. -func GetenvEdk2Path() string { - return os.Getenv("LXD_QEMU_FW_PATH") +// GetenvEdk2Paths returns a list of paths to search for VM firmwares. +// If LXD_QEMU_FW_PATH or LXD_OVMF_PATH env vars are set then these values are split on ":" and prefixed to the +// returned slice of paths. +// The defaultPath argument is returned as the last element in the slice. +func GetenvEdk2Paths(defaultPath string) []string { + var qemuFwPaths []string + + for _, v := range []string{"LXD_QEMU_FW_PATH", "LXD_OVMF_PATH"} { + searchPaths := os.Getenv(v) + if searchPaths == "" { + continue + } + + qemuFwPaths = append(qemuFwPaths, strings.Split(searchPaths, ":")...) + } + + return append(qemuFwPaths, defaultPath) } From f58e2dfa95cf61481441ffb96a8beafab85d0a71 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 4 Sep 2024 08:53:34 +0100 Subject: [PATCH 08/16] lxd/instance/drivers/edk2: Add support for seabios in Ubuntu Signed-off-by: Thomas Parrott --- lxd/instance/drivers/edk2/edk2.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lxd/instance/drivers/edk2/edk2.go b/lxd/instance/drivers/edk2/edk2.go index 8974e598708b..bd3df2805c77 100644 --- a/lxd/instance/drivers/edk2/edk2.go +++ b/lxd/instance/drivers/edk2/edk2.go @@ -112,6 +112,13 @@ var architectureInstallations = map[int][]Installation{ {Code: "OVMF_CODE.secboot.fd", Vars: "OVMF_VARS.fd"}, }, }, + }, { + Paths: GetenvEdk2Paths("/usr/share/seabios"), + Usage: map[FirmwareUsage][]FirmwarePair{ + CSM: { + {Code: "bios-256k.bin", Vars: "bios-256k.bin"}, + }, + }, }}, osarch.ARCH_64BIT_ARMV8_LITTLE_ENDIAN: {{ Paths: GetenvEdk2Paths("/usr/share/AAVMF"), From 61c78dd850de7965dabaaa70f6935bf9940f7bc9 Mon Sep 17 00:00:00 2001 From: Dustin Sweigart Date: Fri, 17 May 2024 12:57:56 +0000 Subject: [PATCH 09/16] lxd/instance/drivers/qemu: Update to use the new edk2 package Modified to support boot.debug_edk2 Signed-off-by: Dustin Sweigart (cherry picked from commit 2546c56300c08aabb68278a483a0dfa696f99f61) Signed-off-by: Thomas Parrott License: Apache-2.0 --- lxd/instance/drivers/driver_qemu.go | 155 ++++++++++------------------ 1 file changed, 52 insertions(+), 103 deletions(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index 2e54f1cb0812..d38d89f6a917 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -47,6 +47,7 @@ import ( deviceConfig "github.com/canonical/lxd/lxd/device/config" "github.com/canonical/lxd/lxd/device/nictype" "github.com/canonical/lxd/lxd/instance" + "github.com/canonical/lxd/lxd/instance/drivers/edk2" "github.com/canonical/lxd/lxd/instance/drivers/qmp" "github.com/canonical/lxd/lxd/instance/drivers/uefi" "github.com/canonical/lxd/lxd/instance/instancetype" @@ -107,37 +108,6 @@ const qemuDeviceNameMaxLength = 31 // qemuMigrationNBDExportName is the name of the disk device export by the migration NBD server. const qemuMigrationNBDExportName = "lxd_root" -// VM firmwares. -type vmFirmware struct { - code string - vars string -} - -// Debug version of the "default" firmware. -var vmDebugFirmware = "OVMF_CODE.4MB.debug.fd" - -var vmGenericFirmwares = []vmFirmware{ - {code: "OVMF_CODE.4MB.fd", vars: "OVMF_VARS.4MB.fd"}, - {code: "OVMF_CODE.2MB.fd", vars: "OVMF_VARS.2MB.fd"}, - {code: "OVMF_CODE.fd", vars: "OVMF_VARS.fd"}, - {code: "OVMF_CODE.fd", vars: "qemu.nvram"}, -} - -var vmSecurebootFirmwares = []vmFirmware{ - {code: "OVMF_CODE.4MB.fd", vars: "OVMF_VARS.4MB.ms.fd"}, - {code: "OVMF_CODE.2MB.fd", vars: "OVMF_VARS.2MB.ms.fd"}, - {code: "OVMF_CODE.fd", vars: "OVMF_VARS.ms.fd"}, - {code: "OVMF_CODE.fd", vars: "qemu.nvram"}, -} - -// Only valid for x86_64. -var vmLegacyFirmwares = []vmFirmware{ - {code: "bios-256k.bin", vars: "bios-256k.bin"}, - {code: "OVMF_CODE.4MB.CSM.fd", vars: "OVMF_VARS.4MB.CSM.fd"}, - {code: "OVMF_CODE.2MB.CSM.fd", vars: "OVMF_VARS.2MB.CSM.fd"}, - {code: "OVMF_CODE.CSM.fd", vars: "OVMF_VARS.CSM.fd"}, -} - // qemuSparseUSBPorts is the amount of sparse USB ports for VMs. // 4 are reserved, and the other 4 can be used for any USB device. const qemuSparseUSBPorts = 8 @@ -788,29 +758,6 @@ func (d *qemu) Rebuild(img *api.Image, op *operations.Operation) error { return d.rebuildCommon(d, img, op) } -func (*qemu) fwPath(filename string) string { - qemuFwPathsArr, err := util.GetQemuFwPaths() - if err != nil { - return "" - } - - // GetQemuFwPaths resolves symlinks for us, but we still need EvalSymlinks() in here, - // because filename itself can be a symlink. - for _, path := range qemuFwPathsArr { - filePath := filepath.Join(path, filename) - filePath, err := filepath.EvalSymlinks(filePath) - if err != nil { - continue - } - - if shared.PathExists(filePath) { - return filePath - } - } - - return "" -} - // killQemuProcess kills specified process. Optimistically attempts to wait for the process to fully exit, but does // not return an error if the Wait call fails. This is because this function is used in scenarios where LXD has // been restarted after the VM has been started and is no longer the parent of the QEMU process. @@ -1272,7 +1219,7 @@ func (d *qemu) start(stateful bool, op *operationlock.InstanceOperation) error { return err } - // Copy VM firmware settings firmware to nvram file if needed. + // Copy EDK2 settings firmware to nvram file if needed. // This firmware file can be modified by the VM so it must be copied from the defaults. if d.architectureSupportsUEFI(d.architecture) && (!shared.PathExists(d.nvramPath()) || shared.IsTrue(d.localConfig["volatile.apply_nvram"])) { err = d.setupNvram() @@ -1984,51 +1931,54 @@ func (d *qemu) setupNvram() error { d.logger.Debug("Generating NVRAM") // Cleanup existing variables. - for _, firmwares := range [][]vmFirmware{vmGenericFirmwares, vmSecurebootFirmwares, vmLegacyFirmwares} { - for _, firmware := range firmwares { - err := os.Remove(filepath.Join(d.Path(), firmware.vars)) - if err != nil && !os.IsNotExist(err) { - return err - } + for _, firmwarePair := range edk2.GetAchitectureFirmwarePairs(d.architecture) { + err := os.Remove(filepath.Join(d.Path(), filepath.Base(firmwarePair.Vars))) + if err != nil && !os.IsNotExist(err) { + return err } } // Determine expected firmware. - firmwares := vmGenericFirmwares + var firmwares []edk2.FirmwarePair if shared.IsTrue(d.expandedConfig["security.csm"]) { - firmwares = vmLegacyFirmwares + firmwares = edk2.GetArchitectureFirmwarePairsForUsage(d.architecture, edk2.CSM) } else if shared.IsTrueOrEmpty(d.expandedConfig["security.secureboot"]) { - firmwares = vmSecurebootFirmwares + firmwares = edk2.GetArchitectureFirmwarePairsForUsage(d.architecture, edk2.SECUREBOOT) + } else { + firmwares = edk2.GetArchitectureFirmwarePairsForUsage(d.architecture, edk2.GENERIC) } // Find the template file. - var vmfVarsPath string - var vmfVarsName string + var vmFirmwarePath string + var vmFirmwareName string for _, firmware := range firmwares { - varsPath := d.fwPath(firmware.vars) + varsPath, err := filepath.EvalSymlinks(firmware.Vars) + if err != nil { + continue + } - if varsPath != "" { - vmfVarsPath = varsPath - vmfVarsName = firmware.vars + if shared.PathExists(varsPath) { + vmFirmwarePath = varsPath + vmFirmwareName = filepath.Base(firmware.Vars) break } } - if vmfVarsPath == "" { - return fmt.Errorf("Couldn't find one of the required firmware files: %+v", firmwares) + if vmFirmwarePath == "" { + return fmt.Errorf("Couldn't find one of the required VM firmware files: %+v", firmwares) } // Copy the template. - err = shared.FileCopy(vmfVarsPath, filepath.Join(d.Path(), vmfVarsName)) + err = shared.FileCopy(vmFirmwarePath, filepath.Join(d.Path(), vmFirmwareName)) if err != nil { return err } // Generate a symlink if needed. - // This is so qemu.nvram can always be assumed to be the VM firmware vars file. + // This is so qemu.nvram can always be assumed to be the EDK2 vars file. // The real file name is then used to determine what firmware must be selected. if !shared.PathExists(d.nvramPath()) { - err = os.Symlink(vmfVarsName, d.nvramPath()) + err = os.Symlink(vmFirmwareName, d.nvramPath()) if err != nil { return err } @@ -3183,29 +3133,31 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo } // Determine expected firmware. - firmwares := vmGenericFirmwares + var firmwares []edk2.FirmwarePair if shared.IsTrue(d.expandedConfig["security.csm"]) { - firmwares = vmLegacyFirmwares + firmwares = edk2.GetArchitectureFirmwarePairsForUsage(d.architecture, edk2.CSM) } else if shared.IsTrueOrEmpty(d.expandedConfig["security.secureboot"]) { - firmwares = vmSecurebootFirmwares + firmwares = edk2.GetArchitectureFirmwarePairsForUsage(d.architecture, edk2.SECUREBOOT) + } else { + firmwares = edk2.GetArchitectureFirmwarePairsForUsage(d.architecture, edk2.GENERIC) } - var vmfCode string + var efiCode string for _, firmware := range firmwares { - if shared.PathExists(filepath.Join(d.Path(), firmware.vars)) { - vmfCode = firmware.code + if shared.PathExists(filepath.Join(d.Path(), filepath.Base(firmware.Vars))) { + efiCode = firmware.Code break } } - if vmfCode == "" { - return "", nil, fmt.Errorf("Unable to locate matching firmware: %+v", firmwares) + if efiCode == "" { + return "", nil, fmt.Errorf("Unable to locate matching VM firmware: %+v", firmwares) } // As 2MB firmware was deprecated in the LXD snap we have to regenerate NVRAM for VMs which used the 2MB one. // As EDK2-based CSM firmwares were deprecated in the LXD snap we want to force VMs to start using SeaBIOS directly. - isOVMF2MB := (strings.Contains(vmfCode, "OVMF") && !strings.Contains(vmfCode, "4MB")) - isOVMFCSM := (strings.Contains(vmfCode, "OVMF") && strings.Contains(vmfCode, "CSM")) + isOVMF2MB := (strings.Contains(efiCode, "OVMF") && !strings.Contains(efiCode, "4MB")) + isOVMFCSM := (strings.Contains(efiCode, "OVMF") && strings.Contains(efiCode, "CSM")) if shared.InSnap() && (isOVMF2MB || isOVMFCSM) { err = d.setupNvram() if err != nil { @@ -3213,21 +3165,16 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo } // force to use a top-priority firmware - vmfCode = firmwares[0].code + efiCode = firmwares[0].Code } - // Use debug version of firmware. (Only works for "default" (4MB, no CSM) firmware flavor) - if shared.IsTrue(d.localConfig["boot.debug_edk2"]) && vmfCode == vmGenericFirmwares[0].code { - vmfCode = vmDebugFirmware - } - - fwPath := d.fwPath(vmfCode) - if fwPath == "" { - return "", nil, fmt.Errorf("Unable to locate the file for firmware %q", vmfCode) + // Use debug version of firmware. (Only works for "preferred" (OVMF 4MB, no CSM) firmware flavor) + if shared.IsTrue(d.localConfig["boot.debug_edk2"]) && efiCode == firmwares[0].Code { + efiCode = filepath.Join(filepath.Dir(efiCode), edk2.OVMFDebugFirmware) } driveFirmwareOpts := qemuDriveFirmwareOpts{ - roPath: fwPath, + roPath: efiCode, nvramPath: fmt.Sprintf("/dev/fd/%d", d.addFileDescriptor(fdFiles, nvRAMFile)), } @@ -8720,18 +8667,20 @@ func (d *qemu) checkFeatures(hostArch int, qemuPath string) (map[string]any, err } if d.architectureSupportsUEFI(hostArch) { - vmfCode := "OVMF_CODE.fd" - - if shared.InSnap() { - vmfCode = vmGenericFirmwares[0].code + // Try to locate a UEFI firmware. + var efiPath string + for _, firmwarePair := range edk2.GetArchitectureFirmwarePairsForUsage(hostArch, edk2.GENERIC) { + if shared.PathExists(firmwarePair.Code) { + efiPath = firmwarePair.Code + break + } } - fwPath := d.fwPath(vmfCode) - if fwPath == "" { - return nil, fmt.Errorf("Unable to locate the file for firmware %q", vmfCode) + if efiPath == "" { + return nil, fmt.Errorf("Unable to locate a UEFI firmware") } - qemuArgs = append(qemuArgs, "-drive", fmt.Sprintf("if=pflash,format=raw,readonly=on,file=%s", fwPath)) + qemuArgs = append(qemuArgs, "-drive", fmt.Sprintf("if=pflash,format=raw,readonly=on,file=%s", efiPath)) } var stderr bytes.Buffer From abce75d6bf5024f2a5f46a9d4c05922e33507fbc Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 3 Sep 2024 14:14:45 +0100 Subject: [PATCH 10/16] lxd/instance/drivers/driver/qemu: Log the VM UEFI firmware found in checkFeatures Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_qemu.go | 1 + 1 file changed, 1 insertion(+) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index d38d89f6a917..230a771d9271 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -8671,6 +8671,7 @@ func (d *qemu) checkFeatures(hostArch int, qemuPath string) (map[string]any, err var efiPath string for _, firmwarePair := range edk2.GetArchitectureFirmwarePairsForUsage(hostArch, edk2.GENERIC) { if shared.PathExists(firmwarePair.Code) { + logger.Info("Found VM UEFI firmware", logger.Ctx{"code": firmwarePair.Code, "vars": firmwarePair.Vars}) efiPath = firmwarePair.Code break } From 0dafab0559243736893ec4da9cefcb2fc37ed666 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Tue, 3 Sep 2024 14:15:13 +0100 Subject: [PATCH 11/16] lxd/instance/drivers/driver/qemu: Improve error in checkFeatures Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_qemu.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index 230a771d9271..8c1317dc2b45 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -8678,7 +8678,7 @@ func (d *qemu) checkFeatures(hostArch int, qemuPath string) (map[string]any, err } if efiPath == "" { - return nil, fmt.Errorf("Unable to locate a UEFI firmware") + return nil, fmt.Errorf("Unable to locate a VM UEFI firmware") } qemuArgs = append(qemuArgs, "-drive", fmt.Sprintf("if=pflash,format=raw,readonly=on,file=%s", efiPath)) From a4e131ee722d9aa4ffd7b26d822ccfc7cc15e43f Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 4 Sep 2024 09:01:23 +0100 Subject: [PATCH 12/16] lxd/util/sys: Removes unused GetQemuFwPaths function Signed-off-by: Thomas Parrott --- lxd/util/sys.go | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/lxd/util/sys.go b/lxd/util/sys.go index 606ece092ae9..0be5f9934891 100644 --- a/lxd/util/sys.go +++ b/lxd/util/sys.go @@ -3,9 +3,7 @@ package util import ( - "fmt" "os" - "path/filepath" "strings" "golang.org/x/sys/unix" @@ -65,40 +63,3 @@ func ReplaceDaemon() error { return nil } - -// GetQemuFwPaths returns a list of directory paths to search for QEMU firmware files. -func GetQemuFwPaths() ([]string, error) { - var qemuFwPaths []string - - for _, v := range []string{"LXD_QEMU_FW_PATH", "LXD_OVMF_PATH"} { - searchPaths := os.Getenv(v) - if searchPaths == "" { - continue - } - - qemuFwPaths = append(qemuFwPaths, strings.Split(searchPaths, ":")...) - } - - // Append default paths after ones extracted from env vars so they take precedence. - qemuFwPaths = append(qemuFwPaths, "/usr/share/OVMF", "/usr/share/seabios") - - count := 0 - for i, path := range qemuFwPaths { - var err error - resolvedPath, err := filepath.EvalSymlinks(path) - if err != nil { - // don't fail, just skip as some search paths can be optional - continue - } - - count++ - qemuFwPaths[i] = resolvedPath - } - - // We want to have at least one valid path to search for firmware. - if count == 0 { - return nil, fmt.Errorf("Failed to find a valid search path for firmware") - } - - return qemuFwPaths, nil -} From 3a86dda731c4a5186aba8daaaf04e7319726886a Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 4 Sep 2024 11:19:41 +0100 Subject: [PATCH 13/16] lxd/instance/instance/interface: Add FirmwarePath to VM interface Signed-off-by: Thomas Parrott --- lxd/instance/instance_interface.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lxd/instance/instance_interface.go b/lxd/instance/instance_interface.go index 8763436848d0..91a057240e29 100644 --- a/lxd/instance/instance_interface.go +++ b/lxd/instance/instance_interface.go @@ -193,6 +193,8 @@ type VM interface { AgentCertificate() *x509.Certificate + FirmwarePath() string + // UEFI vars handling. UEFIVars() (*api.InstanceUEFIVars, error) UEFIVarsUpdate(newUEFIVarsSet api.InstanceUEFIVars) error From 797ea0665b21b695405591bd090b4b6b788e9a30 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 4 Sep 2024 11:20:05 +0100 Subject: [PATCH 14/16] lxd/instance/drivers/driver/qemu: Add firmware path concept and set it during generateQemuConfigFile Allows access to start time firmware path for apparmor profile generation. Signed-off-by: Thomas Parrott --- lxd/instance/drivers/driver_qemu.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index 8c1317dc2b45..e274e801c8bb 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -326,6 +326,9 @@ func qemuCreate(s *state.State, args db.InstanceArgs, p api.Project) (instance.I type qemu struct { common + // Path to firmware, set at start time. + firmwarePath string + // Cached handles. // Do not use these variables directly, instead use their associated get functions so they // will be initialised on demand. @@ -1765,6 +1768,11 @@ func (d *qemu) start(stateful bool, op *operationlock.InstanceOperation) error { return nil } +// FirmwarePath returns the path to firmware, set at start time. +func (d *qemu) FirmwarePath() string { + return d.firmwarePath +} + func (d *qemu) setupSEV(fdFiles *[]*os.File) (*qemuSevOpts, error) { if d.architecture != osarch.ARCH_64BIT_INTEL_X86 { return nil, errors.New("AMD SEV support is only available on x86_64 systems") @@ -3178,6 +3186,9 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo nvramPath: fmt.Sprintf("/dev/fd/%d", d.addFileDescriptor(fdFiles, nvRAMFile)), } + // Set firmware path for apparmor profile. + d.firmwarePath = driveFirmwareOpts.roPath + cfg = append(cfg, qemuDriveFirmware(&driveFirmwareOpts)...) } From 9a404886414c1f02e86b6ff68ecf9fd4a1fca576 Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 4 Sep 2024 11:19:00 +0100 Subject: [PATCH 15/16] lxd/apparmor/instance: Update instanceProfile to use start time firmware path Rather than allowing access to all potential firmware directories. Signed-off-by: Thomas Parrott --- lxd/apparmor/instance.go | 23 +++++++++++++++++++---- lxd/apparmor/instance_qemu.go | 10 +++------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/lxd/apparmor/instance.go b/lxd/apparmor/instance.go index ee056ce092e3..636ee645482b 100644 --- a/lxd/apparmor/instance.go +++ b/lxd/apparmor/instance.go @@ -26,6 +26,12 @@ type instance interface { DevicesPath() string } +type instanceVM interface { + instance + + FirmwarePath() string +} + // InstanceProfileName returns the instance's AppArmor profile name. func InstanceProfileName(inst instance) string { path := shared.VarPath("") @@ -194,9 +200,18 @@ func instanceProfile(sysOS *sys.OS, inst instance) (string, error) { return "", err } - qemuFwPathsArr, err := util.GetQemuFwPaths() - if err != nil { - return "", err + vmInst, ok := inst.(instanceVM) + if !ok { + return "", fmt.Errorf("Instance is not VM type") + } + + // Get start time firmware path to allow access to it. + firmwarePath := vmInst.FirmwarePath() + if firmwarePath != "" { + firmwarePath, err = filepath.EvalSymlinks(firmwarePath) + if err != nil { + return "", fmt.Errorf("Failed finding firmware: %w", err) + } } execPath := util.GetExecPath() @@ -216,7 +231,7 @@ func instanceProfile(sysOS *sys.OS, inst instance) (string, error) { "rootPath": rootPath, "snap": shared.InSnap(), "userns": sysOS.RunningInUserNS, - "qemuFwPaths": qemuFwPathsArr, + "firmwarePath": firmwarePath, "snapExtQemuPrefix": os.Getenv("SNAP_QEMU_PREFIX"), }) if err != nil { diff --git a/lxd/apparmor/instance_qemu.go b/lxd/apparmor/instance_qemu.go index 1d7b9bed5073..360f656d9996 100644 --- a/lxd/apparmor/instance_qemu.go +++ b/lxd/apparmor/instance_qemu.go @@ -102,13 +102,9 @@ profile "{{ .name }}" flags=(attach_disconnected,mediate_deleted) { {{- end }} {{- end }} -{{if .qemuFwPaths -}} - # Entries from LXD_OVMF_PATH or LXD_QEMU_FW_PATH -{{range $index, $element := .qemuFwPaths}} - {{$element}}/OVMF_CODE.fd kr, - {{$element}}/OVMF_CODE.*.fd kr, - {{$element}}/*bios*.bin kr, -{{- end }} +{{if .firmwarePath -}} + # Firmware path + {{ .firmwarePath }} kr, {{- end }} {{- if .raw }} From 7bdeb9b315e7955eabd208b28e1ca62390f2591b Mon Sep 17 00:00:00 2001 From: Thomas Parrott Date: Wed, 4 Sep 2024 11:23:54 +0100 Subject: [PATCH 16/16] lxd/instance/drivers/edk2: Removes unused GetArchitectureInstallations function Signed-off-by: Thomas Parrott --- lxd/instance/drivers/edk2/edk2.go | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/lxd/instance/drivers/edk2/edk2.go b/lxd/instance/drivers/edk2/edk2.go index bd3df2805c77..380d4e22eaa4 100644 --- a/lxd/instance/drivers/edk2/edk2.go +++ b/lxd/instance/drivers/edk2/edk2.go @@ -148,16 +148,6 @@ var architectureInstallations = map[int][]Installation{ }}, } -// GetArchitectureInstallations returns an array of installations for a specific host architecture. -func GetArchitectureInstallations(hostArch int) []Installation { - installations, found := architectureInstallations[hostArch] - if found { - return installations - } - - return []Installation{} -} - // GetAchitectureFirmwarePairs creates an array of FirmwarePair for a // specific host architecture. func GetAchitectureFirmwarePairs(hostArch int) []FirmwarePair { @@ -175,7 +165,7 @@ func GetAchitectureFirmwarePairs(hostArch int) []FirmwarePair { func GetArchitectureFirmwarePairsForUsage(hostArch int, usage FirmwareUsage) []FirmwarePair { firmwares := make([]FirmwarePair, 0) - for _, installation := range GetArchitectureInstallations(hostArch) { + for _, installation := range architectureInstallations[hostArch] { usage, found := installation.Usage[usage] if found { for _, firmwarePair := range usage {