Skip to content

Commit

Permalink
Add unique-cmdline argument to build-uki
Browse files Browse the repository at this point in the history
Part of: kairos-io/kairos#2379

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
  • Loading branch information
jimmykarily committed Apr 15, 2024
1 parent a0f7b7f commit d3b596a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
5 changes: 3 additions & 2 deletions cmd/build-uki.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,9 @@ func NewBuildUKICmd() *cobra.Command {
c.Flags().StringP("boot-branding", "", "Kairos", "Boot title branding")
c.Flags().BoolP("include-version-in-config", "", false, "Include the OS version in the .config file")
c.Flags().BoolP("include-cmdline-in-config", "", false, "Include the cmdline in the .config file. Only the extra values are included.")
c.Flags().StringSliceP("extra-cmdline", "c", []string{}, "Add extra efi files with this cmdline. This creates a base efi with the default cmdline and extra efi files with the default+provided cmdline.")
c.Flags().StringP("extend-cmdline", "x", "", "Extend the default cmdline with this parameters. This creates a single efi entry with the default+provided cmdline.")
c.Flags().StringSliceP("extra-cmdline", "c", []string{}, "Add extra efi files with this cmdline for the default 'norole' artifacts. This creates efi files with the default cmdline and extra efi files with the default+provided cmdline.")
c.Flags().StringP("extend-cmdline", "x", "", "Extend the default cmdline for the default 'norole' artifacts. This creates efi files with the default+provided cmdline.")
c.Flags().StringSliceP("unique-cmdline", "u", []string{}, "Add one extra efi file with the default+provided cmdline. The syntax is '--unique-cmdline boot_entry_name=cmdline,options,here'. The boot entry name is the text under which it appears in systemd-boot menu.")
c.Flags().StringP("keys", "k", "", "Directory with the signing keys")
c.Flags().StringP("default-entry", "e", "", "Default entry selected in the boot menu.\nSupported glob wildcard patterns are \"?\", \"*\", and \"[...]\".\nIf not selected, the default entry with install-mode is selected.")
c.Flags().Int64P("efi-size-warn", "", 1024, "EFI file size warning threshold in megabytes. Default is 1024.")
Expand Down
38 changes: 29 additions & 9 deletions pkg/action/build-uki.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,29 @@ func (b *BuildUKIAction) Run() error {
cmdlines := utils.GetUkiCmdline()
for _, cmdline := range cmdlines {
b.logger.Info("Running ukify for cmdline: " + cmdline)
if err := b.ukify(sourceDir, artifactsTempDir, cmdline); err != nil {
efiName := nameFromCmdline(cmdline)
b.logger.Infof("Generating: " + efiName + ".efi")
if err := b.ukify(sourceDir, artifactsTempDir, cmdline, efiName+".efi"); err != nil {
return err
}
b.logger.Info("Creating kairos and loader conf files")
if err := b.createConfFiles(sourceDir, cmdline); err != nil {

if err := b.createConfFiles(sourceDir, cmdline, viper.GetString("boot-branding"), efiName); err != nil {
return err
}
}

uniqueCmdLines := utils.GetUkiUniqueCmdlines(b.logger)
for bootEntry, cmdline := range uniqueCmdLines {
b.logger.Info("Running ukify for cmdline: " + cmdline)

fileName := strings.ReplaceAll(bootEntry, " ", "_")
b.logger.Infof("Generating: " + fileName + ".efi")
if err := b.ukify(sourceDir, artifactsTempDir, cmdline, fileName+".efi"); err != nil {
return err
}
b.logger.Info("Creating kairos and loader conf files")
if err := b.createConfFiles(sourceDir, cmdline, bootEntry, fileName); err != nil {
return err
}
}
Expand Down Expand Up @@ -368,15 +386,12 @@ func (b *BuildUKIAction) copyKernel(sourceDir, targetDir string) error {
return err
}

func (b *BuildUKIAction) ukify(sourceDir, artifactsTempDir, cmdline string) error {
func (b *BuildUKIAction) ukify(sourceDir, artifactsTempDir, cmdline, finalEfiName string) error {
// Normally that's still the current dir but just making sure.
if err := os.Chdir(sourceDir); err != nil {
return fmt.Errorf("changing to %s directory: %w", sourceDir, err)
}

finalEfiName := nameFromCmdline(cmdline) + ".efi"
b.logger.Infof("Generating: " + finalEfiName)

stubFile, err := b.getEfiStub()
if err != nil {
return err
Expand Down Expand Up @@ -444,10 +459,9 @@ func (b *BuildUKIAction) sbSign(sourceDir string) error {
return nil
}

func (b *BuildUKIAction) createConfFiles(sourceDir, cmdline string) error {
func (b *BuildUKIAction) createConfFiles(sourceDir, cmdline, title, finalEfiName string) error {
// This is stored in the config
var extraCmdline string
finalEfiName := nameFromCmdline(cmdline)
// For the config title we get only the extra cmdline we added, no replacement of spaces with underscores needed
extraCmdline = strings.TrimSpace(strings.TrimPrefix(cmdline, constants.UkiCmdline))
// For the default install entry, do not add anything on the config
Expand All @@ -456,7 +470,6 @@ func (b *BuildUKIAction) createConfFiles(sourceDir, cmdline string) error {
}
b.logger.Infof("Creating the %s.conf file", finalEfiName)

title := viper.GetString("boot-branding")
// You can add entries into the config files, they will be ignored by systemd-boot
// So we store the cmdline in a key cmdline for easy tracking of what was added to the uki cmdline

Expand Down Expand Up @@ -648,6 +661,13 @@ func (b *BuildUKIAction) imageFiles(sourceDir string) (map[string][]string, erro
data["EFI/kairos"] = append(data["EFI/kairos"], filepath.Join(sourceDir, finalEfiName+".efi"))
data["loader/entries"] = append(data["loader/entries"], filepath.Join(sourceDir, finalEfiName+".conf"))
}

// Add the kairos efi files and the loader conf files for the "unique" cmdlines
uniqueCmdLines := utils.GetUkiUniqueCmdlines(b.logger)
for bootEntry := range uniqueCmdLines {
data["EFI/kairos"] = append(data["EFI/kairos"], filepath.Join(sourceDir, strings.ReplaceAll(bootEntry, " ", "_")+".efi"))
data["loader/entries"] = append(data["loader/entries"], filepath.Join(sourceDir, strings.ReplaceAll(bootEntry, " ", "_")+".conf"))
}
b.logger.Debug(fmt.Sprintf("data: %s", litter.Sdump(data)))
return data, nil
}
Expand Down
17 changes: 17 additions & 0 deletions pkg/utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,23 @@ func GetUkiCmdline() []string {
}
}

// GetUkiUniqueCmdlines returns the unique-cmdline as passed by the user.
func GetUkiUniqueCmdlines(logger v1.Logger) map[string]string {
result := map[string]string{}
// extra
cmdlines := viper.GetStringSlice("unique-cmdline")
for _, userValue := range cmdlines {
userSplitValues := strings.SplitN(userValue, "=", 2)
if len(userSplitValues) != 2 {
logger.Warnf("bad value for unique-cmdline: %s", userValue)
continue
}
result[userSplitValues[0]] = constants.UkiCmdline + " " + userSplitValues[1]
}

return result
}

// Tar takes a source and variable writers and walks 'source' writing each file
// found to the tar writer; the purpose for accepting multiple writers is to allow
// for multiple outputs (for example a file, or md5 hash)
Expand Down

0 comments on commit d3b596a

Please sign in to comment.