From ea486bbcbec7174e05a1fa0788366c2bb2ea6c84 Mon Sep 17 00:00:00 2001 From: Loic Devulder Date: Thu, 9 Nov 2023 14:02:40 +0100 Subject: [PATCH 1/2] Add support for RISC-V 64bit architecture Basic support of riscv64 architecture. Shim is not supported yet, will be added later. Signed-off-by: Loic Devulder --- .goreleaser.yaml | 7 +- Dockerfile | 19 ++-- Makefile | 51 +++++++---- examples/green/Dockerfile | 11 ++- examples/tumbleweed/Dockerfile | 42 ++++++--- ...e-restore-compatibility-with-earlier.patch | 28 ++++++ ...s-split-overlayfs-mount-in-two-steps.patch | 90 +++++++++++++++++++ pkg/action/build-iso.go | 6 +- pkg/constants/constants.go | 31 ++++++- pkg/live/common.go | 28 +++--- pkg/live/green.go | 51 +++++++---- pkg/types/v1/platform.go | 4 + pkg/utils/grub.go | 21 +++-- 13 files changed, 302 insertions(+), 87 deletions(-) create mode 100644 examples/tumbleweed/patches/0001-fix-dmsquash-live-restore-compatibility-with-earlier.patch create mode 100644 examples/tumbleweed/patches/0001-fix-overlayfs-split-overlayfs-mount-in-two-steps.patch diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 3dd153e9f6f..dc169565500 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -4,14 +4,15 @@ builds: - CGO_ENABLED=0 ldflags: - -s -w - - -X github.com/rancher/elemental-cli/internal/version.version={{.Tag}} - - -X github.com/rancher/elemental-cli/internal/version.gitCommit={{.Commit}} + - -X github.com/rancher/elemental-toolkit/internal/version.version={{.Tag}} + - -X github.com/rancher/elemental-toolkit/internal/version.gitCommit={{.Commit}} goos: - linux goarch: - amd64 - arm - arm64 + - riscv64 goarm: - 6 - 7 @@ -43,4 +44,4 @@ changelog: exclude: - '^docs:' - '^test:' - - '^Merge pull request' \ No newline at end of file + - '^Merge pull request' diff --git a/Dockerfile b/Dockerfile index a23af45733c..2f64de567c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,8 @@ +ARG BASE_OS_IMAGE=opensuse/leap +ARG BASE_OS_VERSION=15.5 ARG GO_VERSION=1.20 -ARG LEAP_VERSION=15.5 -FROM golang:${GO_VERSION}-alpine as elemental-bin +FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS elemental-bin ENV CGO_ENABLED=0 WORKDIR /src/ @@ -21,25 +22,25 @@ ARG ELEMENTAL_VERSION=0.0.1 ARG ELEMENTAL_COMMIT="" ENV ELEMENTAL_VERSION=${ELEMENTAL_VERSION} ENV ELEMENTAL_COMMIT=${ELEMENTAL_COMMIT} -RUN go build \ +RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \ -ldflags "-w -s \ - -X github.com/rancher/elemental-toolkit/internal/version.version=$ELEMENTAL_VERSION \ - -X github.com/rancher/elemental-toolkit/internal/version.gitCommit=$ELEMENTAL_COMMIT" \ + -X github.com/rancher/elemental-toolkit/internal/version.version=${ELEMENTAL_VERSION} \ + -X github.com/rancher/elemental-toolkit/internal/version.gitCommit=${ELEMENTAL_COMMIT}" \ -o /usr/bin/elemental -FROM opensuse/leap:$LEAP_VERSION AS elemental +FROM ${BASE_OS_IMAGE}:${BASE_OS_VERSION} AS elemental-toolkit # This helps invalidate the cache on each build so the following steps are really run again getting the latest packages # versions, as long as the elemental commit has changed ARG ELEMENTAL_COMMIT="" ENV ELEMENTAL_COMMIT=${ELEMENTAL_COMMIT} RUN ARCH=$(uname -m); \ - if [[ $ARCH == "aarch64" ]]; then ARCH="arm64"; fi; \ + [[ "${ARCH}" == "aarch64" ]] && ARCH="arm64"; \ + zypper --non-interactive removerepo repo-update || true; \ zypper install -y --no-recommends xfsprogs \ parted \ util-linux-systemd \ e2fsprogs \ - util-linux \ udev \ rsync \ grub2 \ @@ -52,10 +53,12 @@ RUN ARCH=$(uname -m); \ gptfdisk \ lvm2 +# Copy the built CLI COPY --from=elemental-bin /usr/bin/elemental /usr/bin/elemental # Fix for blkid only using udev on opensuse RUN echo "EVALUATE=scan" >> /etc/blkid.conf + ENTRYPOINT ["/usr/bin/elemental"] # Add to /system/oem folder so install/upgrade/reset hooks will run when running this container. diff --git a/Makefile b/Makefile index c9b66361d2e..ee235ae48c3 100644 --- a/Makefile +++ b/Makefile @@ -12,16 +12,24 @@ PACKER_TARGET?=qemu.elemental-${ARCH} REPO?=local/elemental-$(FLAVOR) TOOLKIT_REPO?=local/elemental-toolkit DOCKER?=docker - -GIT_COMMIT ?= $(shell git rev-parse HEAD) -GIT_COMMIT_SHORT ?= $(shell git rev-parse --short HEAD) -GIT_TAG ?= $(shell git describe --candidates=50 --abbrev=0 --tags 2>/dev/null || echo "v0.0.1" ) -VERSION ?= ${GIT_TAG}-g${GIT_COMMIT_SHORT} - -PKG := ./cmd ./pkg/... -LDFLAGS := -w -s -LDFLAGS += -X "github.com/rancher/elemental-toolkit/internal/version.version=${GIT_TAG}" -LDFLAGS += -X "github.com/rancher/elemental-toolkit/internal/version.gitCommit=${GIT_COMMIT}" +BASE_OS_IMAGE?=opensuse/leap +BASE_OS_VERSION?=15.5 + +GIT_COMMIT?=$(shell git rev-parse HEAD) +GIT_COMMIT_SHORT?=$(shell git rev-parse --short HEAD) +GIT_TAG?=$(shell git describe --candidates=50 --abbrev=0 --tags 2>/dev/null || echo "v0.0.1" ) +VERSION?=${GIT_TAG}-g${GIT_COMMIT_SHORT} + +PKG:=./cmd ./pkg/... +LDFLAGS:=-w -s +LDFLAGS+=-X "github.com/rancher/elemental-toolkit/internal/version.version=${GIT_TAG}" +LDFLAGS+=-X "github.com/rancher/elemental-toolkit/internal/version.gitCommit=${GIT_COMMIT}" + +# For RISC-V 64bit support +ifeq ($(PLATFORM),linux/riscv64) +BASE_OS_IMAGE=registry.opensuse.org/opensuse/factory/riscv/images/opensuse/tumbleweed +BASE_OS_VERSION=latest +endif # default target .PHONY: all @@ -35,7 +43,12 @@ include make/Makefile.test .PHONY: build build: - $(DOCKER) build --platform ${PLATFORM} ${DOCKER_ARGS} --build-arg ELEMENTAL_VERSION=${GIT_TAG} --build-arg ELEMENTAL_COMMIT=${GIT_COMMIT} --target elemental -t ${TOOLKIT_REPO}:${VERSION} . + $(DOCKER) build --platform $(PLATFORM) ${DOCKER_ARGS} \ + --build-arg ELEMENTAL_VERSION=${GIT_TAG} \ + --build-arg ELEMENTAL_COMMIT=${GIT_COMMIT} \ + --build-arg BASE_OS_IMAGE=$(BASE_OS_IMAGE) \ + --build-arg BASE_OS_VERSION=$(BASE_OS_VERSION) \ + --target elemental-toolkit -t $(TOOLKIT_REPO):$(VERSION) . .PHONY: push-toolkit push-toolkit: @@ -47,7 +60,11 @@ build-cli: .PHONY: build-os build-os: build - $(DOCKER) build examples/$(FLAVOR) --platform ${PLATFORM} ${DOCKER_ARGS} --build-arg TOOLKIT_REPO=$(TOOLKIT_REPO) --build-arg VERSION=$(VERSION) --build-arg REPO=$(REPO) -t $(REPO):$(VERSION) + $(DOCKER) build --platform ${PLATFORM} ${DOCKER_ARGS} \ + --build-arg TOOLKIT_REPO=$(TOOLKIT_REPO) \ + --build-arg VERSION=$(VERSION) \ + --build-arg REPO=$(REPO) -t $(REPO):$(VERSION) \ + examples/$(FLAVOR) .PHONY: push-os push-os: @@ -61,10 +78,6 @@ build-iso: build-os --entrypoint /usr/bin/elemental ${TOOLKIT_REPO}:${VERSION} --debug build-iso --bootloader-in-rootfs -n elemental-$(FLAVOR).$(ARCH) \ --local --platform $(PLATFORM) --squash-no-compression -o /build $(REPO):$(VERSION) -.PHONY: clean-iso -clean-iso: build-os - $(DOCKER) run --rm -v $(ROOT_DIR)/build:/build --entrypoint /bin/bash $(REPO):$(VERSION) -c "rm -v /build/*.iso /build/*.iso.sha256 || true" - .PHONY: build-disk build-disk: build-os @echo Building ${ARCH} disk @@ -77,9 +90,9 @@ build-disk: build-os qemu-img convert -O qcow2 $(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).img $(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).qcow2 qemu-img resize $(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).qcow2 $(DISKSIZE) -.PHONY: clean-disk -clean-disk: - rm $(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).{raw,img,qcow2} +.PHONY: clean +clean: + rm -fv $(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).{raw,img,qcow2,iso,iso.sha256} .PHONY: vet vet: diff --git a/examples/green/Dockerfile b/examples/green/Dockerfile index 95e5424205a..5844309d2e7 100644 --- a/examples/green/Dockerfile +++ b/examples/green/Dockerfile @@ -1,17 +1,17 @@ # run `make build` to build local/elemental-toolkit image ARG TOOLKIT_REPO ARG VERSION -FROM ${TOOLKIT_REPO}:${VERSION} as TOOLKIT +FROM ${TOOLKIT_REPO}:${VERSION} AS TOOLKIT # OS base image of our choice -FROM opensuse/leap:15.5 as OS +FROM opensuse/leap:15.5 AS OS ARG REPO ARG VERSION ENV VERSION=${VERSION} # install kernel, systemd, dracut, grub2 and other required tools RUN ARCH=$(uname -m); \ - if [[ $ARCH == "aarch64" ]]; then ARCH="arm64"; fi; \ + [[ "${ARCH}" == "aarch64" ]] && ARCH="arm64"; \ zypper --non-interactive install --no-recommends -- \ kernel-default \ device-mapper \ @@ -42,6 +42,7 @@ RUN ARCH=$(uname -m); \ less \ sudo \ curl \ + iproute2 \ sed # Just add the elemental cli @@ -55,7 +56,7 @@ RUN cp /usr/share/systemd/tmp.mount /etc/systemd/system # Generate initrd with required elemental services RUN elemental init -f && \ - kernel=$(ls /boot/Image-* | head -n1) && \ + kernel=$(ls /boot/Image-* 2>/dev/null | head -n1) && \ if [ -e "$kernel" ]; then ln -sf "${kernel#/boot/}" /boot/vmlinuz; fi && \ rm -rf /var/log/update* && \ >/var/log/lastlog && \ @@ -70,5 +71,3 @@ RUN echo IMAGE_REPO=\"${REPO}\" >> /etc/os-release && \ # Good for validation after the build CMD /bin/bash - - diff --git a/examples/tumbleweed/Dockerfile b/examples/tumbleweed/Dockerfile index b12c09a1981..725ceefc5b9 100644 --- a/examples/tumbleweed/Dockerfile +++ b/examples/tumbleweed/Dockerfile @@ -1,24 +1,38 @@ # run `make build` to build local/elemental-toolkit image ARG TOOLKIT_REPO ARG VERSION -FROM ${TOOLKIT_REPO}:${VERSION} as TOOLKIT +ARG OS_IMAGE=opensuse/tumbleweed +ARG OS_VERSION=latest + +FROM ${TOOLKIT_REPO}:${VERSION} AS TOOLKIT # OS base image of our choice -FROM opensuse/tumbleweed:latest as OS +FROM ${OS_IMAGE}:${OS_VERSION} AS OS ARG REPO ARG VERSION +ENV REPO=${REPO} ENV VERSION=${VERSION} -# install kernel, systemd, dracut, grub2 and other required tools +# Workaround for RISC-V, specific kernel might be needed for some boards +ARG ADD_REPO +ENV ADD_REPO=${ADD_REPO} + +# Install kernel, systemd, dracut, grub2 and other required tools RUN ARCH=$(uname -m); \ - if [[ $ARCH == "aarch64" ]]; then ARCH="arm64"; fi; \ - zypper --non-interactive install --no-recommends -- \ + zypper --non-interactive removerepo repo-update || true; \ + if [[ -n "${ADD_REPO}" ]]; then \ + zypper --non-interactive addrepo --enable --refresh ${ADD_REPO} added-repo; \ + fi; \ + if [[ "${ARCH}" != "riscv64" ]]; then \ + ADD_PKGS+=" shim"; \ + [[ "${ARCH}" == "aarch64" ]] && ARCH="arm64"; \ + fi; \ + zypper --non-interactive --gpg-auto-import-keys install --no-recommends -- \ kernel-default \ device-mapper \ dracut \ grub2 \ grub2-${ARCH}-efi \ - shim \ haveged \ systemd \ NetworkManager \ @@ -42,7 +56,10 @@ RUN ARCH=$(uname -m); \ less \ sudo \ curl \ - sed + sed \ + patch \ + iproute2 \ + ${ADD_PKGS} # Just add the elemental cli COPY --from=TOOLKIT /usr/bin/elemental /usr/bin/elemental @@ -53,9 +70,16 @@ RUN systemctl enable NetworkManager.service # This is for automatic testing purposes, do not do this in production. RUN echo "PermitRootLogin yes" > /etc/ssh/sshd_config.d/rootlogin.conf +# This is patches are fix upstream dracut, see https://github.com/dracutdevs/dracut/pull/2525 +ADD patches / +RUN cd /usr/lib/dracut && \ + patch -p 1 -f -i /0001-fix-dmsquash-live-restore-compatibility-with-earlier.patch && \ + patch -p 1 -f -i /0001-fix-overlayfs-split-overlayfs-mount-in-two-steps.patch && \ + rm /*.patch + # Generate initrd with required elemental services RUN elemental init -f && \ - kernel=$(ls /boot/Image-* | head -n1) && \ + kernel=$(ls /boot/Image-* 2>/dev/null | head -n1) && \ if [ -e "$kernel" ]; then ln -sf "${kernel#/boot/}" /boot/vmlinuz; fi && \ rm -rf /var/log/update* && \ >/var/log/lastlog && \ @@ -70,5 +94,3 @@ RUN echo IMAGE_REPO=\"${REPO}\" >> /etc/os-release && \ # Good for validation after the build CMD /bin/bash - - diff --git a/examples/tumbleweed/patches/0001-fix-dmsquash-live-restore-compatibility-with-earlier.patch b/examples/tumbleweed/patches/0001-fix-dmsquash-live-restore-compatibility-with-earlier.patch new file mode 100644 index 00000000000..3bbfaf675a9 --- /dev/null +++ b/examples/tumbleweed/patches/0001-fix-dmsquash-live-restore-compatibility-with-earlier.patch @@ -0,0 +1,28 @@ +From 0e780720efe6488c4e07af39926575ee12f40339 Mon Sep 17 00:00:00 2001 +From: Laszlo Gombos +Date: Fri, 24 Feb 2023 01:57:19 +0000 +Subject: [PATCH] fix(dmsquash-live): restore compatibility with earlier + releases + +Follow-up to 40dd5c90e0efcb9ebaa9abb42a38c7316e9706bd . +--- + modules.d/90dmsquash-live/dmsquash-live-root.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/modules.d/90dmsquash-live/dmsquash-live-root.sh b/modules.d/90dmsquash-live/dmsquash-live-root.sh +index 62d1b5e7..a98e258c 100755 +--- a/modules.d/90dmsquash-live/dmsquash-live-root.sh ++++ b/modules.d/90dmsquash-live/dmsquash-live-root.sh +@@ -403,6 +403,10 @@ fi + + ROOTFLAGS="$(getarg rootflags)" + ++if [ "$overlayfs" = required ]; then ++ echo "rd.live.overlay.overlayfs=1" > /etc/cmdline.d/dmsquash-need-overlay.conf ++fi ++ + if [ -n "$overlayfs" ]; then + if [ -n "$FSIMG" ]; then + mkdir -m 0755 -p /run/rootfsbase +-- +2.35.3 diff --git a/examples/tumbleweed/patches/0001-fix-overlayfs-split-overlayfs-mount-in-two-steps.patch b/examples/tumbleweed/patches/0001-fix-overlayfs-split-overlayfs-mount-in-two-steps.patch new file mode 100644 index 00000000000..46b3fce53a6 --- /dev/null +++ b/examples/tumbleweed/patches/0001-fix-overlayfs-split-overlayfs-mount-in-two-steps.patch @@ -0,0 +1,90 @@ +From bddffedae038ceca263a904e40513a6e92f1b558 Mon Sep 17 00:00:00 2001 +From: David Cassany +Date: Fri, 22 Sep 2023 16:28:48 +0200 +Subject: [PATCH] fix(overlayfs): split overlayfs mount in two steps + +This commit splits the creation of required overlayfs underlaying +directories and the actual overlayfs mount. This way it is still +possible to mount the overlayfs with the generated sysroot.mount that +dmsquash-live creates. + +The overlayfs tree is created in a pre-mount hook so it is executed +before sysroot.mount is started. Otherwise sysroot.mount starts and +fails before mount hooks are executed. + +Signed-off-by: David Cassany +--- + modules.d/90overlayfs/module-setup.sh | 1 + + modules.d/90overlayfs/mount-overlayfs.sh | 13 ------------- + modules.d/90overlayfs/prepare-overlayfs.sh | 21 +++++++++++++++++++++ + 3 files changed, 22 insertions(+), 13 deletions(-) + create mode 100755 modules.d/90overlayfs/prepare-overlayfs.sh + +diff --git a/modules.d/90overlayfs/module-setup.sh b/modules.d/90overlayfs/module-setup.sh +index 27aa7cfa..893e2dc3 100755 +--- a/modules.d/90overlayfs/module-setup.sh ++++ b/modules.d/90overlayfs/module-setup.sh +@@ -15,4 +15,5 @@ installkernel() { + + install() { + inst_hook mount 01 "$moddir/mount-overlayfs.sh" ++ inst_hook pre-mount 01 "$moddir/prepare-overlayfs.sh" + } +diff --git a/modules.d/90overlayfs/mount-overlayfs.sh b/modules.d/90overlayfs/mount-overlayfs.sh +index 7e2da1a8..e1d23fb4 100755 +--- a/modules.d/90overlayfs/mount-overlayfs.sh ++++ b/modules.d/90overlayfs/mount-overlayfs.sh +@@ -3,24 +3,11 @@ + type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + + getargbool 0 rd.live.overlay.overlayfs && overlayfs="yes" +-getargbool 0 rd.live.overlay.reset -d -y reset_overlay && reset_overlay="yes" + getargbool 0 rd.live.overlay.readonly -d -y readonly_overlay && readonly_overlay="--readonly" || readonly_overlay="" + + ROOTFLAGS="$(getarg rootflags)" + + if [ -n "$overlayfs" ]; then +- if ! [ -e /run/rootfsbase ]; then +- mkdir -m 0755 -p /run/rootfsbase +- mount --bind "$NEWROOT" /run/rootfsbase +- fi +- +- mkdir -m 0755 -p /run/overlayfs +- mkdir -m 0755 -p /run/ovlwork +- if [ -n "$reset_overlay" ] && [ -h /run/overlayfs ]; then +- ovlfsdir=$(readlink /run/overlayfs) +- info "Resetting the OverlayFS overlay directory." +- rm -r -- "${ovlfsdir:?}"/* "${ovlfsdir:?}"/.* > /dev/null 2>&1 +- fi + if [ -n "$readonly_overlay" ] && [ -h /run/overlayfs-r ]; then + ovlfs=lowerdir=/run/overlayfs-r:/run/rootfsbase + else +diff --git a/modules.d/90overlayfs/prepare-overlayfs.sh b/modules.d/90overlayfs/prepare-overlayfs.sh +new file mode 100755 +index 00000000..87bcc196 +--- /dev/null ++++ b/modules.d/90overlayfs/prepare-overlayfs.sh +@@ -0,0 +1,21 @@ ++#!/bin/sh ++ ++type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh ++ ++getargbool 0 rd.live.overlay.overlayfs && overlayfs="yes" ++getargbool 0 rd.live.overlay.reset -d -y reset_overlay && reset_overlay="yes" ++ ++if [ -n "$overlayfs" ]; then ++ if ! [ -e /run/rootfsbase ]; then ++ mkdir -m 0755 -p /run/rootfsbase ++ mount --bind "$NEWROOT" /run/rootfsbase ++ fi ++ ++ mkdir -m 0755 -p /run/overlayfs ++ mkdir -m 0755 -p /run/ovlwork ++ if [ -n "$reset_overlay" ] && [ -h /run/overlayfs ]; then ++ ovlfsdir=$(readlink /run/overlayfs) ++ info "Resetting the OverlayFS overlay directory." ++ rm -r -- "${ovlfsdir:?}"/* "${ovlfsdir:?}"/.* > /dev/null 2>&1 ++ fi ++fi +-- +2.35.3 diff --git a/pkg/action/build-iso.go b/pkg/action/build-iso.go index 64b4cfd706a..19e2ee14220 100644 --- a/pkg/action/build-iso.go +++ b/pkg/action/build-iso.go @@ -175,19 +175,19 @@ func (b BuildISOAction) prepareISORoot(isoDir string, rootDir string) error { b.cfg.Logger.Error("Could not find kernel and/or initrd") return elementalError.NewFromError(err, elementalError.StatFile) } - err = utils.MkdirAll(b.cfg.Fs, filepath.Join(isoDir, live.IsoLoaderPath), constants.DirPerm) + err = utils.MkdirAll(b.cfg.Fs, filepath.Join(isoDir, constants.ISOLoaderPath()), constants.DirPerm) if err != nil { return elementalError.NewFromError(err, elementalError.CreateDir) } //TODO document boot/kernel and boot/initrd expectation in bootloader config b.cfg.Logger.Debugf("Copying Kernel file %s to iso root tree", kernel) - err = utils.CopyFile(b.cfg.Fs, kernel, filepath.Join(isoDir, constants.ISOKernelPath)) + err = utils.CopyFile(b.cfg.Fs, kernel, filepath.Join(isoDir, constants.ISOKernelPath())) if err != nil { return elementalError.NewFromError(err, elementalError.CopyFile) } b.cfg.Logger.Debugf("Copying initrd file %s to iso root tree", initrd) - err = utils.CopyFile(b.cfg.Fs, initrd, filepath.Join(isoDir, constants.ISOInitrdPath)) + err = utils.CopyFile(b.cfg.Fs, initrd, filepath.Join(isoDir, constants.ISOInitrdPath())) if err != nil { return elementalError.NewFromError(err, elementalError.CopyFile) } diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 30448caba74..15607e65164 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -19,6 +19,7 @@ package constants import ( "os" "runtime" + "strings" ) const ( @@ -113,9 +114,6 @@ const ( SELinuxTargetedContextFile = SELinuxTargetedPath + "/contexts/files/file_contexts" SELinuxTargetedPolicyPath = SELinuxTargetedPath + "/policy" - // Kernel and initrd paths are arbitrary and coupled to grub.cfg - ISOKernelPath = "/boot/x86_64/loader/linux" - ISOInitrdPath = "/boot/x86_64/loader/initrd" ISORootFile = "rootfs.squashfs" ISOEFIImg = "uefi.img" ISOLabel = "COS_LIVE" @@ -140,6 +138,7 @@ const ( Archx86 = "x86_64" ArchArm64 = "arm64" ArchAarch64 = "aarch64" + ArchRiscV64 = "riscv64" Fedora = "fedora" Ubuntu = "ubuntu" @@ -240,3 +239,29 @@ func GetDiskKeyEnvMap() map[string]string { // None for the time being return map[string]string{} } + +// GetBootPath returns path use to store the boot files +func ISOLoaderPath() string { + var arch string + + switch strings.ToLower(runtime.GOARCH) { + case ArchAmd64: + arch = Archx86 + case ArchArm64: + arch = ArchAarch64 + case ArchRiscV64: + arch = ArchRiscV64 + } + + return "/boot/" + arch + "/loader/" +} + +// ISOKernelPath returns path use to store the kernel +func ISOKernelPath() string { + return ISOLoaderPath() + "linux" +} + +// ISOInitrdPath returns path use to store the initramfs +func ISOInitrdPath() string { + return ISOLoaderPath() + "initrd" +} diff --git a/pkg/live/common.go b/pkg/live/common.go index 97d70a9a410..5c1ddbf7e97 100644 --- a/pkg/live/common.go +++ b/pkg/live/common.go @@ -27,45 +27,43 @@ const ( efiBootPath = "/EFI/BOOT" efiImgX86 = "bootx64.efi" efiImgArm64 = "bootaa64.efi" + efiImgRiscV64 = "bootriscv64.efi" grubCfg = "grub.cfg" grubPrefixDir = "/boot/grub2" isoBootCatalog = "/boot/boot.catalog" +) +var ( // TODO document any custom BIOS bootloader must match this setup as these are not configurable // and coupled with the xorriso call - IsoLoaderPath = "/boot/x86_64/loader" - isoHybridMBR = IsoLoaderPath + "/boot_hybrid.img" - isoBootFile = IsoLoaderPath + "/eltorito.img" + isoHybridMBR = constants.ISOLoaderPath() + "/boot_hybrid.img" + isoBootFile = constants.ISOLoaderPath() + "/eltorito.img" //TODO use some identifer known to be unique - grubEfiCfg = "search --no-floppy --file --set=root " + constants.ISOKernelPath + + grubEfiCfg = "search --no-floppy --file --set=root " + constants.ISOKernelPath() + "\nset prefix=($root)" + grubPrefixDir + "\nconfigfile $prefix/" + grubCfg // TODO not convinced having such a config here is the best idea - grubCfgTemplate = "search --no-floppy --file --set=root " + constants.ISOKernelPath + "\n" + + grubCfgTemplate = "search --no-floppy --file --set=root " + constants.ISOKernelPath() + "\n" + `set default=0 set timeout=10 set timeout_style=menu set linux=linux set initrd=initrd - if [ "${grub_cpu}" = "x86_64" -o "${grub_cpu}" = "i386" -o "${grub_cpu}" = "arm64" ];then - if [ "${grub_platform}" = "efi" ]; then - if [ "${grub_cpu}" != "arm64" ]; then - set linux=linuxefi - set initrd=initrdefi - fi - fi - fi if [ "${grub_platform}" = "efi" ]; then + if [ "${grub_cpu}" != "arm64" -a "${grub_cpu}" != "riscv64" ]; then + set linux=linuxefi + set initrd=initrdefi + fi echo "Please press 't' to show the boot menu on this console" fi menuentry "%s" --class os --unrestricted { echo Loading kernel... - $linux ($root)` + constants.ISOKernelPath + ` cdroot root=live:CDLABEL=%s rd.live.dir=/ rd.live.squashimg=rootfs.squashfs console=tty1 console=ttyS0 rd.cos.disable cos.setup=` + constants.ISOCloudInitPath + ` + $linux ($root)` + constants.ISOKernelPath() + ` cdroot root=live:CDLABEL=%s rd.live.dir=/ rd.live.squashimg=rootfs.squashfs console=tty1 console=ttyS0 rd.cos.disable cos.setup=` + constants.ISOCloudInitPath + ` echo Loading initrd... - $initrd ($root)` + constants.ISOInitrdPath + ` + $initrd ($root)` + constants.ISOInitrdPath() + ` } if [ "${grub_platform}" = "efi" ]; then diff --git a/pkg/live/green.go b/pkg/live/green.go index 84fd0effce9..31feb1d1064 100644 --- a/pkg/live/green.go +++ b/pkg/live/green.go @@ -38,12 +38,14 @@ func NewGreenLiveBootLoader(cfg *v1.BuildConfig, spec *v1.LiveISO) *GreenLiveBoo func (g *GreenLiveBootLoader) PrepareEFI(rootDir, uefiDir string) error { const ( - grubEfiImageX86 = "/usr/share/grub2/x86_64-efi/grub.efi" - grubEfiImageArm64 = "/usr/share/grub2/arm64-efi/grub.efi" - shimBasePathX86 = "/usr/share/efi/x86_64" - shimBasePathArm64 = "/usr/share/efi/aarch64" - shimImg = "shim.efi" - mokManager = "MokManager.efi" + grubEfiImageX86 = "/usr/share/grub2/x86_64-efi/grub.efi" + grubEfiImageArm64 = "/usr/share/grub2/arm64-efi/grub.efi" + grubEfiImageRiscV64 = "/usr/share/grub2/riscv64-efi/grub.efi" + shimBasePathX86 = "/usr/share/efi/x86_64" + shimBasePathArm64 = "/usr/share/efi/aarch64" + shimBasePathRiscV64 = "/usr/share/efi/riscv64" + shimImg = "shim.efi" + mokManager = "MokManager.efi" ) err := utils.MkdirAll(g.buildCfg.Fs, filepath.Join(uefiDir, efiBootPath), constants.DirPerm) @@ -68,6 +70,15 @@ func (g *GreenLiveBootLoader) PrepareEFI(rootDir, uefiDir string) error { filepath.Join(rootDir, grubEfiImageArm64), efiImgArm64, ) + case constants.ArchRiscV64: + // No shim/MOK in RISC-V + err = g.copyEfiFiles( + uefiDir, + filepath.Join(rootDir, grubEfiImageRiscV64), + "", + filepath.Join(rootDir, grubEfiImageRiscV64), + efiImgRiscV64, + ) default: err = fmt.Errorf("Not supported architecture: %v", g.buildCfg.Platform.Arch) } @@ -79,15 +90,25 @@ func (g *GreenLiveBootLoader) PrepareEFI(rootDir, uefiDir string) error { } func (g *GreenLiveBootLoader) copyEfiFiles(uefiDir, shimImg, mokManager, grubImg, efiImg string) error { - err := utils.CopyFile(g.buildCfg.Fs, shimImg, filepath.Join(uefiDir, efiBootPath, efiImg)) - if err != nil { - return err + var err error + + // No shim in some architecture + if shimImg != "" { + err = utils.CopyFile(g.buildCfg.Fs, shimImg, filepath.Join(uefiDir, efiBootPath, efiImg)) + if err != nil { + return err + } } - err = utils.CopyFile(g.buildCfg.Fs, grubImg, filepath.Join(uefiDir, efiBootPath)) - if err != nil { - return err + + // No MOK in some architecture + if mokManager != "" { + err = utils.CopyFile(g.buildCfg.Fs, mokManager, filepath.Join(uefiDir, efiBootPath)) + if err != nil { + return err + } } - return utils.CopyFile(g.buildCfg.Fs, mokManager, filepath.Join(uefiDir, efiBootPath)) + + return utils.CopyFile(g.buildCfg.Fs, grubImg, filepath.Join(uefiDir, efiBootPath)) } func (g *GreenLiveBootLoader) PrepareISO(rootDir, imageDir string) error { @@ -112,7 +133,7 @@ func (g *GreenLiveBootLoader) PrepareISO(rootDir, imageDir string) error { } // Create loaders folder - loaderDir := filepath.Join(imageDir, IsoLoaderPath) + loaderDir := filepath.Join(imageDir, constants.ISOLoaderPath()) err = utils.MkdirAll(g.buildCfg.Fs, loaderDir, constants.DirPerm) if err != nil { return err @@ -124,7 +145,7 @@ func (g *GreenLiveBootLoader) PrepareISO(rootDir, imageDir string) error { err = utils.CopyFile( g.buildCfg.Fs, filepath.Join(rootDir, f), - filepath.Join(imageDir, IsoLoaderPath), + filepath.Join(imageDir, constants.ISOLoaderPath()), ) if err != nil { return err diff --git a/pkg/types/v1/platform.go b/pkg/types/v1/platform.go index ae35331366a..15a226636a0 100644 --- a/pkg/types/v1/platform.go +++ b/pkg/types/v1/platform.go @@ -117,6 +117,8 @@ func archToGolangArch(arch string) (string, error) { return constants.ArchArm64, nil case constants.ArchAarch64: return constants.ArchArm64, nil + case constants.ArchRiscV64: + return constants.ArchRiscV64, nil default: return "", errInvalidArch } @@ -132,6 +134,8 @@ func golangArchToArch(arch string) (string, error) { return constants.ArchArm64, nil case constants.ArchAarch64: return constants.ArchArm64, nil + case constants.ArchRiscV64: + return constants.ArchRiscV64, nil default: return "", errInvalidArch } diff --git a/pkg/utils/grub.go b/pkg/utils/grub.go index 30d2808a7ad..e77af6cebec 100644 --- a/pkg/utils/grub.go +++ b/pkg/utils/grub.go @@ -201,8 +201,15 @@ func (g Grub) InstallEFI(rootDir, bootDir, efiDir, deviceLabel string) (string, shimName = "shimx64.efi.signed" } case cnst.Suse: - shimFiles = []string{"shim.efi", "MokManager.efi", "grub.efi"} - shimName = "shim.efi" + switch g.config.Platform.Arch { + case cnst.ArchRiscV64: + // No shim/MOK in RISC-V + shimFiles = []string{"grub.efi"} + shimName = "grub.efi" + default: + shimFiles = []string{"shim.efi", "MokManager.efi", "grub.efi"} + shimName = "shim.efi" + } } for _, f := range shimFiles { @@ -240,10 +247,14 @@ func (g Grub) InstallEFI(rootDir, bootDir, efiDir, deviceLabel string) (string, // Rename the shimName to the fallback name so the system boots from fallback. This means that we do not create // any bootloader entries, so our recent installation has the lower priority if something else is on the bootloader - writeShim := "bootx64.efi" - - if g.config.Platform.Arch == cnst.ArchArm64 { + var writeShim string + switch g.config.Platform.Arch { + case cnst.ArchArm64: writeShim = "bootaa64.efi" + case cnst.ArchRiscV64: + writeShim = "bootriscv64.efi" + default: + writeShim = "bootx64.efi" } err = CopyFile(g.config.Fs, filepath.Join(efiDir, fallbackEFIPath, shimName), filepath.Join(efiDir, fallbackEFIPath, writeShim)) From 34d20310b61b662fc9fd85bc636bbe43ec9ccb7b Mon Sep 17 00:00:00 2001 From: Loic Devulder Date: Mon, 27 Nov 2023 11:04:08 +0100 Subject: [PATCH 2/2] Drop ARM32 build As only 64 architectures are supported Signed-off-by: Loic Devulder --- .goreleaser.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index dc169565500..f8faac40698 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -10,12 +10,10 @@ builds: - linux goarch: - amd64 - - arm - arm64 - riscv64 goarm: - - 6 - - 7 + - 8 signs: - cmd: cosign signature: "${artifact}.sig"