Skip to content

Commit 0f311d3

Browse files
committed
azl4: Create Distro-Aware FindBootPartitionUuidFromEsp for output.artfacts API support
1 parent 956edd5 commit 0f311d3

8 files changed

Lines changed: 62 additions & 17 deletions

File tree

toolkit/tools/pkg/imagecustomizerlib/artifactsinputoutput.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ var ukiRegex = regexp.MustCompile(`^vmlinuz-.*\.efi$`)
5757

5858
func outputArtifacts(ctx context.Context, items []imagecustomizerapi.OutputArtifactsItemType,
5959
outputDir string, buildDir string, buildImage string, verityMetadata []verityDeviceMetadata,
60-
previewFeatures []imagecustomizerapi.PreviewFeature,
60+
previewFeatures []imagecustomizerapi.PreviewFeature, distroHandler DistroHandler,
6161
) error {
6262
logger.Log.Infof("Outputting artifacts")
6363

@@ -82,7 +82,7 @@ func outputArtifacts(ctx context.Context, items []imagecustomizerapi.OutputArtif
8282
return err
8383
}
8484

85-
bootPartition, err := findBootPartitionFromEsp(systemBootPartition, diskPartitions, buildDir)
85+
bootPartition, err := findBootPartitionFromEsp(systemBootPartition, diskPartitions, buildDir, distroHandler)
8686
if err != nil {
8787
return err
8888
}

toolkit/tools/pkg/imagecustomizerlib/distrohandler.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ type DistroHandler interface {
5555
// For example: "boot/efi" for most distros, "boot" for ACL.
5656
GetEspDir() string
5757

58+
// FindBootPartitionUuidFromEsp reads the distro's grub.cfg stub from the already-mounted ESP at espMountDir and
59+
// returns the UUID of the partition that contains the grub.cfg.
60+
FindBootPartitionUuidFromEsp(espMountDir string) (string, error)
61+
5862
// Reports whether SELinux configuration is supported by the tool for this distro.
5963
SELinuxSupported() bool
6064

toolkit/tools/pkg/imagecustomizerlib/distrohandler_acl.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"fmt"
99
"io/fs"
10+
"path/filepath"
1011

1112
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/imagecustomizerapi"
1213
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/internal/imageconnection"
@@ -78,6 +79,10 @@ func (d *aclDistroHandler) GetEspDir() string {
7879
return "boot"
7980
}
8081

82+
func (d *aclDistroHandler) FindBootPartitionUuidFromEsp(espMountDir string) (string, error) {
83+
return readBootPartitionUuidFromGrubCfg(filepath.Join(espMountDir, espGrubCfgPathAzl3), bootPartitionRegexAzl3)
84+
}
85+
8186
func (d *aclDistroHandler) SELinuxSupported() bool {
8287
return true
8388
}

toolkit/tools/pkg/imagecustomizerlib/distrohandler_azurelinux.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package imagecustomizerlib
66
import (
77
"context"
88
"fmt"
9+
"path/filepath"
910

1011
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/imagecustomizerapi"
1112
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/imagegen/installutils"
@@ -99,6 +100,17 @@ func (d *azureLinuxDistroHandler) GetEspDir() string {
99100
return "boot/efi"
100101
}
101102

103+
func (d *azureLinuxDistroHandler) FindBootPartitionUuidFromEsp(espMountDir string) (string, error) {
104+
espGrubCfgPath := espGrubCfgPathAzl3
105+
bootPartitionRegex := bootPartitionRegexAzl3
106+
if d.version == "4.0" {
107+
espGrubCfgPath = espGrubCfgPathAzl4
108+
bootPartitionRegex = bootPartitionRegexAzl4
109+
}
110+
111+
return readBootPartitionUuidFromGrubCfg(filepath.Join(espMountDir, espGrubCfgPath), bootPartitionRegex)
112+
}
113+
102114
func (d *azureLinuxDistroHandler) SELinuxSupported() bool {
103115
return true
104116
}

toolkit/tools/pkg/imagecustomizerlib/distrohandler_fedora.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package imagecustomizerlib
66
import (
77
"context"
88
"fmt"
9+
"path/filepath"
910
"slices"
1011

1112
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/imagecustomizerapi"
@@ -91,6 +92,10 @@ func (d *fedoraDistroHandler) GetEspDir() string {
9192
return "boot/efi"
9293
}
9394

95+
func (d *fedoraDistroHandler) FindBootPartitionUuidFromEsp(espMountDir string) (string, error) {
96+
return readBootPartitionUuidFromGrubCfg(filepath.Join(espMountDir, espGrubCfgPathAzl3), bootPartitionRegexAzl3)
97+
}
98+
9499
func (d *fedoraDistroHandler) SELinuxSupported() bool {
95100
return true
96101
}

toolkit/tools/pkg/imagecustomizerlib/distrohandler_ubuntu.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package imagecustomizerlib
66
import (
77
"context"
88
"fmt"
9+
"path/filepath"
910
"slices"
1011

1112
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/imagecustomizerapi"
@@ -112,6 +113,10 @@ func (d *ubuntuDistroHandler) GetEspDir() string {
112113
return "boot/efi"
113114
}
114115

116+
func (d *ubuntuDistroHandler) FindBootPartitionUuidFromEsp(espMountDir string) (string, error) {
117+
return readBootPartitionUuidFromGrubCfg(filepath.Join(espMountDir, espGrubCfgPathAzl3), bootPartitionRegexAzl3)
118+
}
119+
115120
func (d *ubuntuDistroHandler) SELinuxSupported() bool {
116121
return false
117122
}

toolkit/tools/pkg/imagecustomizerlib/imagecustomizer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ func customizeImageOptionsHelper(ctx context.Context, baseConfigPath string, con
271271
outputDir := file.GetAbsPathWithBase(baseConfigPath, rc.OutputArtifacts.Path)
272272

273273
err = outputArtifacts(ctx, rc.OutputArtifacts.Items, outputDir, rc.BuildDirAbs,
274-
rc.RawImageFile, im.verityMetadata, rc.PreviewFeatures)
274+
rc.RawImageFile, im.verityMetadata, rc.PreviewFeatures, im.distroHandler)
275275
if err != nil {
276276
return fmt.Errorf("%w:\n%w", ErrCustomizeOutputArtifacts, err)
277277
}

toolkit/tools/pkg/imagecustomizerlib/partitionutils.go

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717

1818
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/imagecustomizerapi"
1919
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/imagegen/diskutils"
20-
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/imagegen/installutils"
2120
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/internal/file"
2221
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/internal/grub"
2322
"github.com/microsoft/azure-linux-image-tools/toolkit/tools/internal/imageconnection"
@@ -32,12 +31,18 @@ import (
3231
)
3332

3433
var (
35-
bootPartitionRegex = regexp.MustCompile(`(?m)^search -n -u ([a-zA-Z0-9\-]+) -s$`)
34+
bootPartitionRegexAzl3 = regexp.MustCompile(`(?m)^[\t ]*search\s+-n\s+-u\s+([a-zA-Z0-9\-]+)\s+-s\s*$`)
35+
bootPartitionRegexAzl4 = regexp.MustCompile(`(?m)^[\t ]*search\s+--fs-uuid\s+--set=root\s+([a-zA-Z0-9\-]+)\s*$`)
3636

3737
// Extract the partition number from the loopback partition path.
3838
partitionNumberRegex = regexp.MustCompile(`^/dev/loop\d+p(\d+)$`)
3939
)
4040

41+
const (
42+
espGrubCfgPathAzl3 = "boot/grub2/grub.cfg"
43+
espGrubCfgPathAzl4 = "EFI/fedora/grub.cfg"
44+
)
45+
4146
const (
4247
// BtrfsTopLevelSubvolumeId is the ID of the top-level subvolume in a BTRFS filesystem.
4348
// This is BTRFS_FS_TREE_OBJECTID, the objectid that refers to the global FS_TREE root.
@@ -76,7 +81,9 @@ func findSystemBootPartition(diskPartitions []diskutils.PartitionInfo) (*diskuti
7681
return bootPartition, nil
7782
}
7883

79-
func findBootPartitionFromEsp(efiSystemPartition *diskutils.PartitionInfo, diskPartitions []diskutils.PartitionInfo, buildDir string) (*diskutils.PartitionInfo, error) {
84+
func findBootPartitionFromEsp(efiSystemPartition *diskutils.PartitionInfo, diskPartitions []diskutils.PartitionInfo,
85+
buildDir string, distroHandler DistroHandler,
86+
) (*diskutils.PartitionInfo, error) {
8087
tmpDir := filepath.Join(buildDir, tmpEspPartitionDirName)
8188

8289
// Mount the EFI System Partition.
@@ -86,9 +93,7 @@ func findBootPartitionFromEsp(efiSystemPartition *diskutils.PartitionInfo, diskP
8693
}
8794
defer efiSystemPartitionMount.Close()
8895

89-
// Read the grub.cfg file.
90-
grubConfigFilePath := filepath.Join(tmpDir, installutils.FedoraGrubCfgFile)
91-
grubConfigFile, err := os.ReadFile(grubConfigFilePath)
96+
bootPartitionUuid, err := distroHandler.FindBootPartitionUuidFromEsp(tmpDir)
9297
if err != nil {
9398
return nil, fmt.Errorf("failed to read EFI system partition's grub.cfg file:\n%w", err)
9499
}
@@ -99,14 +104,6 @@ func findBootPartitionFromEsp(efiSystemPartition *diskutils.PartitionInfo, diskP
99104
return nil, fmt.Errorf("failed to close EFI system partition mount:\n%w", err)
100105
}
101106

102-
// Look for the bootloader partition declaration line in the grub.cfg file.
103-
match := bootPartitionRegex.FindStringSubmatch(string(grubConfigFile))
104-
if match == nil {
105-
return nil, fmt.Errorf("failed to find boot partition in grub.cfg file")
106-
}
107-
108-
bootPartitionUuid := match[1]
109-
110107
var bootPartition *diskutils.PartitionInfo
111108
for i := range diskPartitions {
112109
diskPartition := diskPartitions[i]
@@ -124,6 +121,23 @@ func findBootPartitionFromEsp(efiSystemPartition *diskutils.PartitionInfo, diskP
124121
return bootPartition, nil
125122
}
126123

124+
// readBootPartitionUuidFromGrubCfg reads the grub.cfg file at grubConfigFilePath and
125+
// returns the UUID captured by bootPartitionRegex's first capture group.
126+
func readBootPartitionUuidFromGrubCfg(grubConfigFilePath string, bootPartitionRegex *regexp.Regexp,
127+
) (string, error) {
128+
grubConfigFile, err := os.ReadFile(grubConfigFilePath)
129+
if err != nil {
130+
return "", fmt.Errorf("failed to read EFI system partition's grub.cfg file (%s):\n%w", grubConfigFilePath, err)
131+
}
132+
133+
match := bootPartitionRegex.FindStringSubmatch(string(grubConfigFile))
134+
if match == nil {
135+
return "", fmt.Errorf("failed to find boot partition in grub.cfg file (%s)", grubConfigFilePath)
136+
}
137+
138+
return match[1], nil
139+
}
140+
127141
// Searches for the partition that contains the /etc/fstab file.
128142
// While technically it is possible to place /etc on a different partition, doing so is fairly difficult and requires
129143
// a custom initramfs module.

0 commit comments

Comments
 (0)