Skip to content

Add bootloader metadata for COSI 1.1 #285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

elainezhao1
Copy link
Contributor

Add bootloader metadata extraction logic support grub-based boot and multiple types of UKI-based boot:

  • First checks for systemd-boot config entries under /boot/loader/entries.
  • If none are found, checks for standalone UKI files in the ESP.
  • For each detected entry, extracts kernel version and command-line arguments, and constructs the appropriate metadata.
  • Fallback to GRUB-based detection remains unchanged.

tested with uki image:
image


Checklist

  • Tests added/updated
  • Documentation updated (if needed)
  • Code conforms to style guidelines

if err != nil {
return nil, fmt.Errorf("failed to extract systemd-boot entries:\n%w", err)
}
return &CosiBootloader{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this fallthrough if the directory exists but is empty?

line = strings.TrimSpace(line)
switch {
case strings.HasPrefix(line, "options"):
entry.Cmdline = strings.TrimSpace(strings.TrimPrefix(line, "options"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should append to entry.Cmdline rather than replace it. The spec says:

options shall contain kernel parameters to pass to the Linux kernel to spawn. This key is optional and may appear more than once in which case all specified parameters are combined in the order they are listed.

Also don't forget to include a space between concatenated items.

if kernelVer, err := getKernelVersion(filepath.Base(linuxPath)); err == nil {
entry.Kernel = kernelVer
}
case strings.HasPrefix(line, "uki"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version of systemd-boot in AZL3 doesn't actually support this option. I think it is planned to land in systemd 258

@elainezhao1
Copy link
Contributor Author

I haven’t tested two entry types yet: uki-config (a config file with a UKI) and config (a config file with kernel, initrd, and cmdline). Are there any existing images we can use to validate these cases?

@fintelia @frhuelsz

@elainezhao1 elainezhao1 marked this pull request as ready for review June 24, 2025 17:54
@elainezhao1 elainezhao1 requested a review from a team as a code owner June 24, 2025 17:54
@frhuelsz
Copy link
Contributor

I haven’t tested two entry types yet: uki-config (a config file with a UKI) and config (a config file with kernel, initrd, and cmdline). Are there any existing images we can use to validate these cases?

@fintelia @frhuelsz

Apparently uki-config is not possible yet (as @fintelia noted in another comment, will be supported in systemd 258).

Regarding config, we are not sure it is supported by customizer yet, so we are not aware of any image that would serve as an example. Perhaps @cwize1 might know?

Images []FileSystem `json:"images"`
OsRelease string `json:"osRelease"`
Id string `json:"id,omitempty"`
Bootloader *CosiBootloader `json:"bootloader"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add omitempty?

type BootloaderType string

const (
BootloaderGrub BootloaderType = "grub"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a good idea for enum values to start with the name of the enum. e.g. BootloaderTypeGrub. This makes it easier to see know the type of the value.

SystemdBoot *SystemDBoot `json:"systemdBoot,omitempty"`
}

type Metadata struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metadata doesn't seem to be used.

Path: filepath.Join("boot", "loader", "entries", file.Name()),
}

lines := strings.Split(string(content), "\n")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's write a proper parser for the systemd-boot entry files. That way, the code will be reusable for when we add proper support for systemd-boot.

Also, the way you have written the code has a lot of code duplication (e.g. strings.TrimSpace(strings.TrimPrefix(, which would be good to remove.

The file format is documented here: Type #1 Boot Loader Specification Entries

line = strings.TrimSpace(line)
switch {
case strings.HasPrefix(line, "options"):
entry.Cmdline = strings.TrimSpace(strings.TrimPrefix(line, "options"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any spaces at the end of the line are still considered to be part of the value. The only spaces that should be removed are the ones that are between the key and the value.

return entries, nil
}

func GrubConfigSupportExists(installChroot safechroot.ChrootInterface) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Azure Linux, the best way to tell which bootloader is being used is to check if either the grub2-efi-binary or systemd-boot package is installed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants