Skip to content

Commit d2d2889

Browse files
authored
Add target for rpi disk (#1859)
* Add target for rpi disk This commit adds a flavor for tumbleweed raspberry pi image that uses a after-disk hook to copy firmware into the EFI partition. Signed-off-by: Fredrik Lönnegren <[email protected]> * Add DOCKER_SOCK Makefile variable Signed-off-by: Fredrik Lönnegren <[email protected]> * Rebase rpi example to leap Signed-off-by: Fredrik Lönnegren <[email protected]> --------- Signed-off-by: Fredrik Lönnegren <[email protected]>
1 parent b4ad085 commit d2d2889

7 files changed

Lines changed: 130 additions & 24 deletions

File tree

Dockerfile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ ARG BASE_OS_IMAGE=opensuse/leap
22
ARG BASE_OS_VERSION=15.5
33
ARG GO_VERSION=1.20
44

5-
FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS elemental-bin
5+
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine as elemental-bin
66

77
ENV CGO_ENABLED=0
88
WORKDIR /src/
@@ -22,7 +22,9 @@ ARG ELEMENTAL_VERSION=0.0.1
2222
ARG ELEMENTAL_COMMIT=""
2323
ENV ELEMENTAL_VERSION=${ELEMENTAL_VERSION}
2424
ENV ELEMENTAL_COMMIT=${ELEMENTAL_COMMIT}
25-
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \
25+
ARG TARGETOS
26+
ARG TARGETARCH
27+
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build \
2628
-ldflags "-w -s \
2729
-X github.com/rancher/elemental-toolkit/internal/version.version=${ELEMENTAL_VERSION} \
2830
-X github.com/rancher/elemental-toolkit/internal/version.gitCommit=${ELEMENTAL_COMMIT}" \
@@ -34,6 +36,8 @@ FROM ${BASE_OS_IMAGE}:${BASE_OS_VERSION} AS elemental-toolkit
3436
ARG ELEMENTAL_COMMIT=""
3537
ENV ELEMENTAL_COMMIT=${ELEMENTAL_COMMIT}
3638

39+
ARG TARGETARCH
40+
3741
RUN ARCH=$(uname -m); \
3842
[[ "${ARCH}" == "aarch64" ]] && ARCH="arm64"; \
3943
zypper --non-interactive removerepo repo-update || true; \

Makefile

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ TOOLKIT_REPO?=local/elemental-toolkit
1414
DOCKER?=docker
1515
BASE_OS_IMAGE?=opensuse/leap
1616
BASE_OS_VERSION?=15.5
17+
DOCKER_SOCK?=/var/run/docker.sock
1718

1819
GIT_COMMIT?=$(shell git rev-parse HEAD)
1920
GIT_COMMIT_SHORT?=$(shell git rev-parse --short HEAD)
@@ -74,22 +75,35 @@ push-os:
7475
build-iso: build-os
7576
@echo Building ${ARCH} ISO
7677
mkdir -p $(ROOT_DIR)/build
77-
$(DOCKER) run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(ROOT_DIR)/build:/build \
78+
$(DOCKER) run --rm -v ${DOCKER_SOCK}:${DOCKER_SOCK} -v $(ROOT_DIR)/build:/build \
7879
--entrypoint /usr/bin/elemental ${TOOLKIT_REPO}:${VERSION} --debug build-iso --bootloader-in-rootfs -n elemental-$(FLAVOR).$(ARCH) \
7980
--local --platform $(PLATFORM) --squash-no-compression -o /build $(REPO):$(VERSION)
8081

8182
.PHONY: build-disk
8283
build-disk: build-os
8384
@echo Building ${ARCH} disk
8485
mkdir -p $(ROOT_DIR)/build
85-
$(DOCKER) run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(ROOT_DIR)/build:/build \
86+
$(DOCKER) run --rm -v ${DOCKER_SOCK}:${DOCKER_SOCK} -v $(ROOT_DIR)/build:/build \
8687
--entrypoint /usr/bin/elemental \
87-
${TOOLKIT_REPO}:${VERSION} --debug build-disk --unprivileged --expandable -n elemental-$(FLAVOR).$(ARCH) --local \
88+
${TOOLKIT_REPO}:${VERSION} --debug build-disk --platform $(PLATFORM) --unprivileged --expandable -n elemental-$(FLAVOR).$(ARCH) --local \
8889
--squash-no-compression -o /build ${REPO}:${VERSION}
8990
dd if=$(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).raw of=$(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).img conv=notrunc
9091
qemu-img convert -O qcow2 $(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).img $(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).qcow2
9192
qemu-img resize $(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).qcow2 $(DISKSIZE)
9293

94+
.PHONY: build-rpi-disk
95+
build-rpi-disk: build-os
96+
ifneq ("$(PLATFORM)","linux/arm64")
97+
@echo "Cannot build raspberry pi disk for $PLATFORM"
98+
@exit 1
99+
endif
100+
@echo Building ${ARCH} disk
101+
mkdir -p $(ROOT_DIR)/build
102+
$(DOCKER) run --rm -v ${DOCKER_SOCK}:${DOCKER_SOCK} -v $(ROOT_DIR)/examples:/examples -v $(ROOT_DIR)/build:/build \
103+
--entrypoint /usr/bin/elemental \
104+
${TOOLKIT_REPO}:${VERSION} --debug build-disk --platform $(PLATFORM) --cloud-init-paths /examples/${FLAVOR} --unprivileged --expandable -n elemental-$(FLAVOR).aarch64 --local \
105+
--squash-no-compression --deploy-command elemental,--debug,reset,--reboot,--disable-boot-entry -o /build ${REPO}:${VERSION}
106+
93107
.PHONY: clean
94108
clean:
95109
rm -fv $(ROOT_DIR)/build/elemental-$(FLAVOR).$(ARCH).{raw,img,qcow2,iso,iso.sha256}

cmd/build-disk.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ func NewBuildDisk(root *cobra.Command, addCheckRoot bool) *cobra.Command {
105105
c.Flags().Bool("expandable", false, "Creates an expandable image including only the recovery image")
106106
c.Flags().Bool("unprivileged", false, "Makes a build runnable within a non-privileged container, avoids mounting filesystems (experimental)")
107107
c.Flags().VarP(imgType, "type", "t", "Type of image to create")
108-
c.Flags().StringSliceP("cloud-init", "c", []string{}, "Cloud-init config files")
108+
c.Flags().StringSliceP("cloud-init", "c", []string{}, "Cloud-init config files to include in disk")
109+
c.Flags().StringSlice("cloud-init-paths", []string{}, "Cloud-init config files to run during build")
109110
c.Flags().StringSlice("deploy-command", []string{"elemental", "--debug", "reset", "--reboot"}, "Deployment command for expandable images")
110111
addPlatformFlags(c)
111112
addLocalImageFlag(c)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name: "Raspberry Pi post disk hook"
2+
stages:
3+
after-disk:
4+
- &copyfirmware
5+
name: "Copy firmware to EFI partition"
6+
commands:
7+
- cp -r /build/build/recovery.img.root/boot/vc/* /build/build/efi/

examples/green-rpi/Dockerfile

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# run `make build` to build local/elemental-toolkit image
2+
ARG TOOLKIT_REPO
3+
ARG VERSION
4+
FROM ${TOOLKIT_REPO}:${VERSION} as TOOLKIT
5+
6+
# OS base image of our choice
7+
FROM registry.opensuse.org/opensuse/leap:15.5 as OS
8+
ARG REPO
9+
ARG VERSION
10+
ENV VERSION=${VERSION}
11+
12+
# install kernel, systemd, dracut, grub2 and other required tools
13+
RUN zypper --non-interactive install --no-recommends -- \
14+
kernel-default \
15+
device-mapper \
16+
dracut \
17+
grub2 \
18+
grub2-arm64-efi \
19+
raspberrypi-firmware \
20+
raspberrypi-firmware-config \
21+
raspberrypi-firmware-dt \
22+
u-boot-rpiarm64 \
23+
shim \
24+
haveged \
25+
systemd \
26+
NetworkManager \
27+
openssh-server \
28+
openssh-clients \
29+
timezone \
30+
parted \
31+
e2fsprogs \
32+
dosfstools \
33+
mtools \
34+
xorriso \
35+
findutils \
36+
gptfdisk \
37+
rsync \
38+
squashfs \
39+
lvm2 \
40+
tar \
41+
gzip \
42+
vim \
43+
which \
44+
less \
45+
sudo \
46+
curl \
47+
sed
48+
49+
# Just add the elemental cli
50+
COPY --from=TOOLKIT /usr/bin/elemental /usr/bin/elemental
51+
52+
# Enable essential services
53+
RUN systemctl enable NetworkManager.service
54+
55+
# Enable /tmp to be on tmpfs
56+
RUN cp /usr/share/systemd/tmp.mount /etc/systemd/system
57+
58+
# Generate initrd with required elemental services
59+
RUN elemental init -f && \
60+
kernel=$(ls /boot/Image-* | head -n1) && \
61+
if [ -e "$kernel" ]; then ln -sf "${kernel#/boot/}" /boot/vmlinuz; fi && \
62+
rm -rf /var/log/update* && \
63+
>/var/log/lastlog && \
64+
rm -rf /boot/vmlinux*
65+
66+
# Update os-release file with some metadata
67+
RUN echo IMAGE_REPO=\"${REPO}\" >> /etc/os-release && \
68+
echo IMAGE_TAG=\"${VERSION}\" >> /etc/os-release && \
69+
echo IMAGE=\"${REPO}:${VERSION}\" >> /etc/os-release && \
70+
echo TIMESTAMP="`date +'%Y%m%d%H%M%S'`" >> /etc/os-release && \
71+
echo GRUB_ENTRY_NAME=\"Elemental\" >> /etc/os-release
72+
73+
# Good for validation after the build
74+
CMD /bin/bash
75+

pkg/action/build-disk.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -364,16 +364,20 @@ func (b *BuildDiskAction) CreatePartitionImages(e *elemental.Elemental) ([]*v1.I
364364
if err != nil {
365365
return err
366366
}
367-
if d.IsDir() && path != b.roots[constants.EfiPartName] {
367+
368+
if path != b.roots[constants.EfiPartName] {
368369
rel, err := filepath.Rel(b.roots[constants.EfiPartName], path)
369370
if err != nil {
370371
return err
371372
}
372-
_, err = b.cfg.Runner.Run("mcopy", "-i", img.File, path, fmt.Sprintf("::%s", rel))
373+
374+
b.cfg.Logger.Debugf("copying file %s to %s", path, rel)
375+
_, err = b.cfg.Runner.Run("mcopy", "-n", "-o", "-i", img.File, path, fmt.Sprintf("::%s", rel))
373376
if err != nil {
374377
return err
375378
}
376379
}
380+
377381
return nil
378382
})
379383
if err != nil {
@@ -594,10 +598,11 @@ func (b *BuildDiskAction) CreateDiskPartitionTable(disk string) error {
594598
}
595599
sizeS = partitioner.MiBToSectors(part.Size, secSize)
596600
var gdPart = partitioner.Partition{
597-
Number: i + 1,
598-
StartS: startS,
599-
SizeS: sizeS,
600-
PLabel: part.Name,
601+
Number: i + 1,
602+
StartS: startS,
603+
SizeS: sizeS,
604+
PLabel: part.Name,
605+
FileSystem: part.FS,
601606
}
602607
gd.CreatePartition(&gdPart)
603608
}

pkg/action/build_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,9 @@ var _ = Describe("Build Actions", func() {
265265
{"mksquashfs", "/tmp/test/build/recovery.img.root", "/tmp/test/build/state/cOS/passive.img"},
266266
{"mksquashfs", "/tmp/test/build/recovery.img.root", "/tmp/test/build/recovery/cOS/recovery.img"},
267267
{"mkfs.vfat", "-n", "COS_GRUB"},
268-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI", "::EFI"},
269-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/boot", "::EFI/boot"},
270-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/elemental", "::EFI/elemental"},
268+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI", "::EFI"},
269+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/boot", "::EFI/boot"},
270+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/elemental", "::EFI/elemental"},
271271
{"mkfs.ext4", "-L", "COS_OEM"},
272272
{"losetup", "--show", "-f", "/tmp/test/build/oem.part"},
273273
{"mkfs.ext4", "-L", "COS_RECOVERY"},
@@ -295,9 +295,9 @@ var _ = Describe("Build Actions", func() {
295295
{"mkfs.ext2", "-d", "/tmp/test/build/recovery.img.root", "/tmp/test/build/state/cOS/passive.img"},
296296
{"mksquashfs", "/tmp/test/build/recovery.img.root", "/tmp/test/build/recovery/cOS/recovery.img"},
297297
{"mkfs.vfat", "-n", "COS_GRUB"},
298-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI", "::EFI"},
299-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/boot", "::EFI/boot"},
300-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/elemental", "::EFI/elemental"},
298+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI", "::EFI"},
299+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/boot", "::EFI/boot"},
300+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/elemental", "::EFI/elemental"},
301301
{"mkfs.ext4", "-L", "COS_OEM"},
302302
{"mkfs.ext4", "-L", "COS_RECOVERY"},
303303
{"mkfs.ext4", "-L", "COS_STATE"},
@@ -347,9 +347,9 @@ var _ = Describe("Build Actions", func() {
347347
{"mkfs.ext2", "-d", "/tmp/test/build/active.img.root", "/tmp/test/build/state/cOS/passive.img"},
348348
{"mksquashfs", "/tmp/test/build/recovery.img.root", "/tmp/test/build/recovery/cOS/recovery.img"},
349349
{"mkfs.vfat", "-n", "COS_GRUB"},
350-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI", "::EFI"},
351-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/boot", "::EFI/boot"},
352-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/elemental", "::EFI/elemental"},
350+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI", "::EFI"},
351+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/boot", "::EFI/boot"},
352+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/elemental", "::EFI/elemental"},
353353
{"mkfs.ext4", "-L", "COS_OEM"},
354354
{"mkfs.ext4", "-L", "COS_RECOVERY"},
355355
{"mkfs.ext4", "-L", "COS_STATE"},
@@ -373,9 +373,9 @@ var _ = Describe("Build Actions", func() {
373373
Expect(runner.MatchMilestones([][]string{
374374
{"mksquashfs", "/tmp/test/build/recovery.img.root", "/tmp/test/build/recovery/cOS/recovery.img"},
375375
{"mkfs.vfat", "-n", "COS_GRUB"},
376-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI", "::EFI"},
377-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/boot", "::EFI/boot"},
378-
{"mcopy", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/elemental", "::EFI/elemental"},
376+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI", "::EFI"},
377+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/boot", "::EFI/boot"},
378+
{"mcopy", "-n", "-o", "-i", "/tmp/test/build/efi.part", "/tmp/test/build/efi/EFI/elemental", "::EFI/elemental"},
379379
{"mkfs.ext4", "-L", "COS_OEM"},
380380
{"mkfs.ext4", "-L", "COS_RECOVERY"},
381381
{"mkfs.ext4", "-L", "COS_STATE"},

0 commit comments

Comments
 (0)