From af5ac30a7bb07351b7e41fb43c8137fcc7170eca Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 25 May 2022 17:28:51 +0400 Subject: [PATCH] feat: enable passing custom kernel args to the ISO creator Instead of hardcoded `grub.cfg`, use common code to generate list of kernel arguments and allow using `--extra-kernel-arg` as well. Before the change: ``` linux /boot/vmlinuz init_on_alloc=1 slab_nomerge pti=on panic=0 consoleblank=0 printk.devkmsg=on earlyprintk=ttyS0 console=tty0 console=ttyS0 talos.platform=metal ``` New (default line): ``` linux /boot/vmlinuz talos.platform=metal earlyprintk=ttyS0 console=ttyS0 console=tty0 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 random.trust_cpu=on printk.devkmsg=on ima_template=ima-ng ima_appraise=fix ima_hash=sha512 ``` Signed-off-by: Andrey Smirnov --- Makefile | 7 ++- cmd/installer/cmd/grub.iso.cfg | 14 +++++ cmd/installer/cmd/iso.go | 63 +++++++++++++------ .../content/v1.1/learn-more/knowledge-base.md | 14 +++++ 4 files changed, 77 insertions(+), 21 deletions(-) create mode 100644 cmd/installer/cmd/grub.iso.cfg diff --git a/Makefile b/Makefile index a2b5ffe8c..064c3379a 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,7 @@ RELEASES ?= v0.14.3 v1.0.0 SHORT_INTEGRATION_TEST ?= CUSTOM_CNI_URL ?= INSTALLER_ARCH ?= all +IMAGER_ARGS ?= CGO_ENABLED ?= 0 GO_BUILDFLAGS ?= @@ -235,7 +236,7 @@ image-%: ## Builds the specified image. Valid options are aws, azure, digital-oc @docker pull $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) @for platform in $(subst $(,),$(space),$(PLATFORM)); do \ arch=`basename "$${platform}"` ; \ - docker run --rm -v /dev:/dev --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) image --platform $* --arch $$arch --tar-to-stdout | tar xz -C $(ARTIFACTS) ; \ + docker run --rm -v /dev:/dev --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) image --platform $* --arch $$arch --tar-to-stdout $(IMAGER_ARGS) | tar xz -C $(ARTIFACTS) ; \ done images-essential: image-aws image-gcp image-metal ## Builds only essential images used in the CI (AWS, GCP, and Metal). @@ -244,7 +245,7 @@ images: image-aws image-azure image-digital-ocean image-gcp image-hcloud image-m sbc-%: ## Builds the specified SBC image. Valid options are rpi_4, rock64, bananapi_m64, libretech_all_h3_cc_h5, rockpi_4, rockpi_4c, pine64 and jetson_nano (e.g. sbc-rpi_4) @docker pull $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) - @docker run --rm -v /dev:/dev --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) image --platform metal --arch arm64 --board $* --tar-to-stdout | tar xz -C $(ARTIFACTS) + @docker run --rm -v /dev:/dev --privileged $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) image --platform metal --arch arm64 --board $* --tar-to-stdout $(IMAGER_ARGS) | tar xz -C $(ARTIFACTS) sbcs: sbc-rpi_4 sbc-rock64 sbc-bananapi_m64 sbc-libretech_all_h3_cc_h5 sbc-rockpi_4 sbc-rockpi_4c sbc-pine64 sbc-jetson_nano ## Builds all known SBC images (Raspberry Pi 4 Model B, Rock64, Banana Pi M64, Radxa ROCK Pi 4, Radxa ROCK Pi 4c, pine64, Libre Computer Board ALL-H3-CC and Jetson Nano). @@ -253,7 +254,7 @@ iso: ## Builds the ISO and outputs it to the artifact directory. @docker pull $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) @for platform in $(subst $(,),$(space),$(PLATFORM)); do \ arch=`basename "$${platform}"` ; \ - docker run --rm -e SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) -i $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) iso --arch $$arch --tar-to-stdout | tar xz -C $(ARTIFACTS) ; \ + docker run --rm -e SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) -i $(REGISTRY_AND_USERNAME)/imager:$(IMAGE_TAG) iso --arch $$arch --tar-to-stdout $(IMAGER_ARGS) | tar xz -C $(ARTIFACTS) ; \ done .PHONY: talosctl-cni-bundle diff --git a/cmd/installer/cmd/grub.iso.cfg b/cmd/installer/cmd/grub.iso.cfg new file mode 100644 index 000000000..03e8f0a5d --- /dev/null +++ b/cmd/installer/cmd/grub.iso.cfg @@ -0,0 +1,14 @@ +set default=0 +set timeout=3 + +insmod all_video + +terminal_input console +terminal_output console + +menuentry "Talos ISO" { + set gfxmode=auto + set gfxpayload=text + linux /boot/vmlinuz {{ .Cmdline }} + initrd /boot/initramfs.xz +} diff --git a/cmd/installer/cmd/iso.go b/cmd/installer/cmd/iso.go index 915913fe4..7b32ba403 100644 --- a/cmd/installer/cmd/iso.go +++ b/cmd/installer/cmd/iso.go @@ -5,32 +5,27 @@ package cmd import ( + "bytes" + _ "embed" "fmt" "io" "io/ioutil" "log" "os" "path/filepath" + "text/template" "github.com/spf13/cobra" + "github.com/talos-systems/go-procfs/procfs" "github.com/talos-systems/talos/cmd/installer/pkg" + "github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/metal" + "github.com/talos-systems/talos/pkg/machinery/constants" + "github.com/talos-systems/talos/pkg/machinery/kernel" ) -var cfg = []byte(`set default=0 -set timeout=3 - -insmod all_video - -terminal_input console -terminal_output console - -menuentry "Talos ISO" { - set gfxmode=auto - set gfxpayload=text - linux /boot/vmlinuz init_on_alloc=1 slab_nomerge pti=on panic=0 consoleblank=0 printk.devkmsg=on earlyprintk=ttyS0 console=tty0 console=ttyS0 talos.platform=metal - initrd /boot/initramfs.xz -}`) +//go:embed grub.iso.cfg +var isoGrubCfg []byte // isoCmd represents the iso command. var isoCmd = &cobra.Command{ @@ -90,17 +85,49 @@ func runISOCmd() error { log.Println("creating grub.cfg") + // ISO is always using platform "metal". + p := &metal.Metal{} + + cmdline := procfs.NewCmdline("") + cmdline.Append(constants.KernelParamPlatform, p.Name()) + cmdline.Append("earlyprintk", "ttyS0") + + cmdline.SetAll(p.KernelArgs().Strings()) + + if err := cmdline.AppendAll(kernel.DefaultArgs); err != nil { + return err + } + + if err := cmdline.AppendAll(options.ExtraKernelArgs, procfs.WithOverwriteArgs("console")); err != nil { + return err + } + + var grubCfg bytes.Buffer + + tmpl, err := template.New("grub.cfg").Parse(string(isoGrubCfg)) + if err != nil { + return err + } + + if err = tmpl.Execute(&grubCfg, struct { + Cmdline string + }{ + Cmdline: cmdline.String(), + }); err != nil { + return err + } + cfgPath := "/mnt/boot/grub/grub.cfg" - if err := os.MkdirAll(filepath.Dir(cfgPath), 0o755); err != nil { + if err = os.MkdirAll(filepath.Dir(cfgPath), 0o755); err != nil { return err } - if err := ioutil.WriteFile(cfgPath, cfg, 0o666); err != nil { + if err = ioutil.WriteFile(cfgPath, grubCfg.Bytes(), 0o666); err != nil { return err } - if err := pkg.TouchFiles("/mnt"); err != nil { + if err = pkg.TouchFiles("/mnt"); err != nil { return err } @@ -108,7 +135,7 @@ func runISOCmd() error { out := fmt.Sprintf("/tmp/talos-%s.iso", options.Arch) - if err := pkg.CreateISO(out, "/mnt"); err != nil { + if err = pkg.CreateISO(out, "/mnt"); err != nil { return err } diff --git a/website/content/v1.1/learn-more/knowledge-base.md b/website/content/v1.1/learn-more/knowledge-base.md index 7e8a16791..9483d6d77 100644 --- a/website/content/v1.1/learn-more/knowledge-base.md +++ b/website/content/v1.1/learn-more/knowledge-base.md @@ -19,3 +19,17 @@ machine: shutdownGracePeriod: 0s shutdownGracePeriodCriticalPods: 0s ``` + +## Generating Talos Linux ISO image with custom kernel arguments + +Pass additional kernel arguments using `--extra-kernel-arg` flag: + +```shell +$ docker run --rm -i ghcr.io/siderolabs/imager:{{< release >}} iso --arch amd64 --tar-to-stdout --extra-kernel-arg console=ttyS1 --extra-kernel-arg console=tty0 | tar xz +2022/05/25 13:18:47 copying /usr/install/amd64/vmlinuz to /mnt/boot/vmlinuz +2022/05/25 13:18:47 copying /usr/install/amd64/initramfs.xz to /mnt/boot/initramfs.xz +2022/05/25 13:18:47 creating grub.cfg +2022/05/25 13:18:47 creating ISO +``` + +ISO will be output to the file `talos-.iso` in the current directory.