diff --git a/cmd/boots/main.go b/cmd/boots/main.go index 41f87c78..1627db43 100644 --- a/cmd/boots/main.go +++ b/cmd/boots/main.go @@ -79,6 +79,8 @@ type config struct { syslogAddr string // loglevel is the log level for boots logLevel string + // extraKernelArgs are key=value pairs to be added as kernel commandline to the kernel in iPXE for OSIE + extraKernelArgs string } func main() { @@ -205,7 +207,7 @@ func main() { mainlog.With("addr", cfg.dhcpAddr).Info("serving dhcp") go dhcpServer.ServeDHCP(cfg.dhcpAddr, nextServer, ipxeBaseURL, bootsBaseURL) mainlog.With("addr", cfg.httpAddr).Info("serving http") - go httpServer.ServeHTTP(registerInstallers(), cfg.httpAddr, ipxePattern, ipxeHandler) + go httpServer.ServeHTTP(cfg.registerInstallers(), cfg.httpAddr, ipxePattern, ipxeHandler) <-ctx.Done() mainlog.Info("boots shutting down") @@ -345,6 +347,7 @@ func newCLI(cfg *config, fs *flag.FlagSet) *ffcli.Command { fs.StringVar(&cfg.logLevel, "log-level", "info", "log level.") fs.StringVar(&cfg.dhcpAddr, "dhcp-addr", conf.BOOTPBind, "IP and port to listen on for DHCP.") fs.StringVar(&cfg.syslogAddr, "syslog-addr", conf.SyslogBind, "IP and port to listen on for syslog messages.") + fs.StringVar(&cfg.extraKernelArgs, "extra-kernel-args", "", "Extra set of kernel args (k=v k=v) that are appended to the kernel cmdline when booting via iPXE.") return &ffcli.Command{ Name: name, @@ -357,7 +360,7 @@ func newCLI(cfg *config, fs *flag.FlagSet) *ffcli.Command { } } -func registerInstallers() job.Installers { +func (cf *config) registerInstallers() job.Installers { // register installers i := job.NewInstallers() // register coreos/flatcar @@ -375,7 +378,7 @@ func registerInstallers() job.Installers { o := osie.Installer{} i.RegisterDistro("discovery", o.Discover()) // register osie as default - d := osie.Installer{} + d := osie.Installer{ExtraKernelArgs: cf.extraKernelArgs} i.RegisterDefaultInstaller(d.DefaultHandler()) // register rancher r := rancher.Installer{} diff --git a/cmd/boots/main_test.go b/cmd/boots/main_test.go index 704a1553..a0262007 100644 --- a/cmd/boots/main_test.go +++ b/cmd/boots/main_test.go @@ -70,6 +70,7 @@ func TestCustomUsageFunc(t *testing.T) { FLAGS -dhcp-addr IP and port to listen on for DHCP. (default "%v:67") + -extra-kernel-args Extra set of kernel args (k=v k=v) that are appended to the kernel cmdline when booting via iPXE. -http-addr local IP and port to listen on for the serving iPXE binaries and files via HTTP. (default "%[1]v:80") -ipxe-enable-http enable serving iPXE binaries via HTTP. (default "true") -ipxe-enable-tftp enable serving iPXE binaries via TFTP. (default "true") diff --git a/installers/osie/main.go b/installers/osie/main.go index d6b82a5c..baa33073 100644 --- a/installers/osie/main.go +++ b/installers/osie/main.go @@ -10,7 +10,10 @@ import ( "go.opentelemetry.io/otel/trace" ) -type Installer struct{} +type Installer struct { + // ExtraKernelArgs are key=value pairs to be added as kernel commandline to the kernel in iPXE for OSIE. + ExtraKernelArgs string +} // DefaultHandler determines the ipxe boot script to be returned. // If the job has an instance with Rescue true, the rescue boot script is returned. @@ -31,7 +34,7 @@ func (i Installer) rescue() job.BootScript { s.Set("action", "rescue") s.Set("state", j.HardwareState()) - return bootScript(ctx, "rescue", j, s) + return i.bootScript(ctx, "rescue", j, s) } } @@ -50,7 +53,7 @@ func (i Installer) install() job.BootScript { } s.Set("state", j.HardwareState()) - return bootScript(ctx, "install", j, s) + return i.bootScript(ctx, "install", j, s) } } @@ -59,18 +62,18 @@ func (i Installer) Discover() job.BootScript { s.Set("action", "discover") s.Set("state", j.HardwareState()) - return bootScript(ctx, "discover", j, s) + return i.bootScript(ctx, "discover", j, s) } } -func bootScript(ctx context.Context, action string, j job.Job, s ipxe.Script) ipxe.Script { +func (i Installer) bootScript(ctx context.Context, action string, j job.Job, s ipxe.Script) ipxe.Script { s.Set("arch", j.Arch()) s.Set("parch", j.PArch()) s.Set("bootdevmac", j.PrimaryNIC().String()) s.Set("base-url", osieBaseURL(j)) s.Kernel("${base-url}/" + kernelPath(j)) - ks := kernelParams(ctx, action, j.HardwareState(), j, s) + ks := i.kernelParams(ctx, action, j.HardwareState(), j, s) ks.Initrd("${base-url}/" + initrdPath(j)) @@ -84,7 +87,7 @@ func bootScript(ctx context.Context, action string, j job.Job, s ipxe.Script) ip return ks } -func kernelParams(ctx context.Context, action, state string, j job.Job, s ipxe.Script) ipxe.Script { +func (i Installer) kernelParams(ctx context.Context, action, state string, j job.Job, s ipxe.Script) ipxe.Script { s.Args("ip=dhcp") // Dracut? s.Args("modules=loop,squashfs,sd-mod,usb-storage") s.Args("alpine_repo=" + alpineMirror(j)) @@ -96,6 +99,11 @@ func kernelParams(ctx context.Context, action, state string, j job.Job, s ipxe.S s.Args("packet_state=${state}") s.Args("osie_vendors_url=" + conf.OsieVendorServicesURL) + // Add extra kernel args + if i.ExtraKernelArgs != "" { + s.Args(i.ExtraKernelArgs) + } + // only add traceparent if tracing is enabled if sc := trace.SpanContextFromContext(ctx); sc.IsSampled() { // manually assemble a traceparent string because the "right" way is clunkier