diff --git a/cmd/rt-conf/main.go b/cmd/rt-conf/main.go index d8e89f3f..8e95de25 100644 --- a/cmd/rt-conf/main.go +++ b/cmd/rt-conf/main.go @@ -37,9 +37,6 @@ func run(args []string) error { configPath := flags.String("file", envConfigFile, "Path to the configuration file") - grubCfgPath := flags.String("grub-custom-file", - "/etc/default/grub.d/60_rt-conf.cfg", - "Path to the output drop-in grub configuration file, relevant only for GRUB bootloader") verbose := flags.Bool("verbose", verboseDefaultCfg, "Verbose mode, prints more information to the console") @@ -73,10 +70,6 @@ func run(args []string) error { } } - conf.GrubCfg = model.Grub{ - GrubDropInFile: *grubCfgPath, - } - if msgs, err := kcmd.ProcessKcmdArgs(&conf); err != nil { return fmt.Errorf("failed to process kernel cmdline args: %v", err) } else { diff --git a/snap/hooks/disconnect-plug-etc-default-grub b/snap/hooks/disconnect-plug-etc-default-grub new file mode 100644 index 00000000..249197ad --- /dev/null +++ b/snap/hooks/disconnect-plug-etc-default-grub @@ -0,0 +1,3 @@ +#!/bin/bash -eu + +rm -f $GRUB_DROPIN_FILE diff --git a/snap/hooks/remove b/snap/hooks/remove new file mode 100755 index 00000000..ec4360b3 --- /dev/null +++ b/snap/hooks/remove @@ -0,0 +1,4 @@ +#!/bin/bash -eu + +# Remove the grub drop-in file if it exists +rm -f $GRUB_DROPIN_FILE diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 1c23b6a8..6c2e99cb 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -11,6 +11,7 @@ confinement: strict environment: DEFAULT_CONFIG_FILE: $SNAP_COMMON/config.yaml + GRUB_DROPIN_FILE: /etc/default/grub.d/60_rt-conf.cfg parts: local: @@ -37,6 +38,11 @@ plugs: read: - /etc/default/grub +hooks: + remove: + plugs: + - etc-default-grub + apps: rt-conf: &rt-conf plugs: diff --git a/src/kcmd/grub.go b/src/kcmd/grub.go index f6860fbe..cb719784 100644 --- a/src/kcmd/grub.go +++ b/src/kcmd/grub.go @@ -15,6 +15,11 @@ func UpdateGrub(cfg *model.InternalConfig) ([]string, error) { if len(cfg.Data.KernelCmdline.Parameters) == 0 { return nil, fmt.Errorf("no parameters to inject") } + grubDropInFilePath, exists := os.LookupEnv("GRUB_DROPIN_FILE") + if !exists { + return nil, fmt.Errorf("GRUB_DROPIN_FILE environment variable not set") + } + cfg.GrubCfg.GrubDropInFile = grubDropInFilePath if err := cfg.Data.KernelCmdline.HasDuplicates(); err != nil { return nil, fmt.Errorf("invalid new parameters: %v", err) diff --git a/src/kcmd/grub_test.go b/src/kcmd/grub_test.go index 93089089..3f203fa8 100644 --- a/src/kcmd/grub_test.go +++ b/src/kcmd/grub_test.go @@ -67,11 +67,15 @@ func TestUpdateGrub(t *testing.T) { kcmd model.KernelCmdline expectErr string expectOutput string + envVars map[string]string }{ { name: "No params to inject", kcmd: model.KernelCmdline{}, expectErr: "no parameters to inject", + envVars: map[string]string{ + "GRUB_DROPIN_FILE": "/tmp/60-rt-conf.cfg", + }, }, { name: "detected bootloader GRUB", @@ -81,6 +85,9 @@ func TestUpdateGrub(t *testing.T) { }, }, expectOutput: "Detected bootloader: GRUB", + envVars: map[string]string{ + "GRUB_DROPIN_FILE": "/tmp/60-rt-conf.cfg", + }, }, { name: "ProcessFile fails", @@ -90,6 +97,9 @@ func TestUpdateGrub(t *testing.T) { }, }, expectErr: "error updating", + envVars: map[string]string{ + "GRUB_DROPIN_FILE": "/tmp/60-rt-conf.cfg", + }, }, { name: "Success", @@ -100,6 +110,9 @@ func TestUpdateGrub(t *testing.T) { }, }, expectOutput: "Detected bootloader: GRUB", + envVars: map[string]string{ + "GRUB_DROPIN_FILE": "/tmp/60-rt-conf.cfg", + }, }, { name: "duplicate parameters with different values", @@ -111,6 +124,19 @@ func TestUpdateGrub(t *testing.T) { }, }, expectErr: "invalid new parameters", + envVars: map[string]string{ + "GRUB_DROPIN_FILE": "/tmp/60-rt-conf.cfg", + }, + }, + { + name: "GRUB_DROPIN_FILE not set", + kcmd: model.KernelCmdline{ + Parameters: []string{ + "isolcpus=1-3", + "nohz=on", + }, + }, + expectErr: "environment variable not set", }, } @@ -119,6 +145,23 @@ func TestUpdateGrub(t *testing.T) { tmpDir := t.TempDir() cfgPath := filepath.Join(tmpDir, "rt-conf.cfg") + if tc.envVars != nil { + for tck, v := range tc.envVars { + if err := os.Setenv(tck, v); err != nil { + t.Fatalf("failed to set env var %s: %v", tck, err) + } + } + } + + // Unset env vars after the test + t.Cleanup(func() { + for tck := range tc.envVars { + if err := os.Unsetenv(tck); err != nil { + t.Fatalf("failed to unset env var %s: %v", tck, err) + } + } + }) + conf := &model.InternalConfig{ Data: model.Config{ KernelCmdline: tc.kcmd, diff --git a/src/model/kcmdline_test.go b/src/model/kcmdline_test.go index de5d277a..98b7df36 100644 --- a/src/model/kcmdline_test.go +++ b/src/model/kcmdline_test.go @@ -54,6 +54,10 @@ func mainLogic(t *testing.T, c TestCase, i int) (string, error) { t.Fatalf("failed to write grub: %v", err) } + if err := os.Setenv("GRUB_DROPIN_FILE", tempCustomCfgPath); err != nil { + t.Fatalf("failed to set env var GRUB_DROPIN_FILE: %v", err) + } + t.Cleanup(func() { if err := os.Remove(tempConfigPath); err != nil { t.Fatal(err)