From 53295b92283e55c3da79663f8b26af23875e8d42 Mon Sep 17 00:00:00 2001
From: Darren Shepherd <darren@rancher.com>
Date: Tue, 12 Oct 2021 10:24:39 -0700
Subject: [PATCH] Add arm64

---
 .drone.yml                                 | 50 ++++++++++++++++++++++
 Dockerfile                                 | 22 +++++-----
 Dockerfile.dapper                          |  3 +-
 Makefile                                   | 14 +++---
 framework/files/etc/luet/luet.yaml.aarch64 | 12 ++++++
 ros-image-build                            | 31 ++++++++++----
 scripts/ci                                 |  2 +-
 scripts/package                            | 10 ++---
 8 files changed, 113 insertions(+), 31 deletions(-)
 create mode 100644 framework/files/etc/luet/luet.yaml.aarch64

diff --git a/.drone.yml b/.drone.yml
index dfa03b41..5e57ca5e 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -47,6 +47,55 @@ volumes:
   host:
     path: /var/run/docker.sock
 
+#---
+#kind: pipeline
+#name: arm64
+#
+#platform:
+#  os: linux
+#  arch: arm64
+#
+#steps:
+#- name: build
+#  image: rancher/dapper:v0.4.1
+#  commands:
+#  - dapper ci
+#  environment:
+#    DOCKER_PASSWORD:
+#      from_secret: docker_password
+#    DOCKER_USERNAME:
+#      from_secret: docker_username
+#    ARCH: "arm64"
+#  volumes:
+#  - name: docker
+#    path: /var/run/docker.sock
+#
+#- name: github_binary_release
+#  image: plugins/github-release
+#  settings:
+#    api_key:
+#      from_secret: github_token
+#    prerelease: true
+#    checksum:
+#    - sha256
+#    checksum_file: CHECKSUMsum-arm64.txt
+#    checksum_flatten: true
+#    files:
+#    - "dist/artifacts/*"
+#  when:
+#    instance:
+#    - drone-publish.rancher.io
+#    ref:
+#    - refs/head/master
+#    - refs/tags/*
+#    event:
+#    - tag
+#
+#volumes:
+#- name: docker
+#  host:
+#    path: /var/run/docker.sock
+#
 ---
 kind: pipeline
 name: manifest
@@ -78,3 +127,4 @@ steps:
 
 depends_on:
 - amd64
+#- arm64
diff --git a/Dockerfile b/Dockerfile
index 9f7067b6..45cca2f9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,8 @@
 FROM opensuse/leap:15.3 AS build
-RUN zypper in -y squashfs xorriso go1.16 upx busybox-static
+RUN zypper ref
+RUN zypper in -y squashfs xorriso go1.16 upx busybox-static curl
+RUN curl -Lo /usr/bin/luet https://github.com/mudler/luet/releases/download/0.18.1/luet-0.18.1-linux-$(go env GOARCH) && \
+    chmod +x /usr/bin/luet
 COPY go.mod go.sum /usr/src/
 COPY cmd /usr/src/cmd
 COPY pkg /usr/src/pkg
@@ -9,7 +12,7 @@ RUN cd /usr/src && \
 
 FROM scratch AS framework
 COPY --from=build /usr/bin/busybox-static /usr/bin/busybox
-COPY --from=quay.io/luet/base:0.17.8 /usr/bin/luet /usr/bin/luet
+COPY --from=build /usr/bin/luet /usr/bin/luet
 COPY framework/files/etc/luet/luet.yaml /etc/luet/luet.yaml
 COPY --from=build /etc/ssl/certs /etc/ssl/certs
 
@@ -19,23 +22,19 @@ RUN ["luet", \
     "install", "--no-spinner", "-d", "-y", \
     "selinux/k3s", \
     "selinux/rancher", \
-    "system/base-dracut-modules", \
-    "system/cloud-config", \
-    "system/cos-setup", \
-    "system/grub2-config", \
-    "system/immutable-rootfs", \
-    "toolchain/yip", \
-    "utils/installer", \
+    "meta/cos-minimal", \
     "utils/k9s", \
     "utils/rancherd", \
     "utils/nerdctl"]
 
 COPY --from=build /usr/sbin/ros-installer /usr/sbin/ros-installer
 COPY framework/files/ /
+RUN ["/usr/bin/busybox", "sh", "-c", "if [ -e /etc/luet/luet.yaml.$(busybox uname -m) ]; then busybox mv -f /etc/luet/luet.yaml.$(busybox uname -m) /etc/luet/luet.yaml; fi && busybox rm -f /etc/luet/luet.yaml.*"]
 RUN ["/usr/bin/busybox", "rm", "-rf", "/var", "/etc/ssl", "/usr/bin/busybox"]
 
 # Make OS image
 FROM opensuse/leap:15.3 as os
+RUN zypper ref
 RUN zypper in -y \
     apparmor-parser \
     avahi \
@@ -129,4 +128,7 @@ RUN echo "IMAGE_REPO=${IMAGE_REPO}"          > /usr/lib/rancheros-release && \
 COPY --from=framework / /
 
 # Rebuild initrd to setup dracut with the boot configurations
-RUN mkinitrd
+RUN mkinitrd && \
+    # aarch64 has an uncompressed kernel so we need to link it to vmlinuz
+    kernel=$(ls /boot/Image-* | head -n1) && \
+    if [ -e "$kernel" ]; then ln -sf "${kernel#/boot/}" /boot/vmlinuz; fi
diff --git a/Dockerfile.dapper b/Dockerfile.dapper
index 331e72ce..65c12ae4 100644
--- a/Dockerfile.dapper
+++ b/Dockerfile.dapper
@@ -1,9 +1,9 @@
 FROM opensuse/leap
+RUN zypper ref
 
 ARG DAPPER_HOST_ARCH
 ENV ARCH $DAPPER_HOST_ARCH
 
-RUN zypper ref
 RUN zypper in -y bash git gcc docker vim less file curl wget ca-certificates make mkisofs go1.16
 RUN go get golang.org/x/tools/cmd/goimports
 RUN if [ "${ARCH}" == "amd64" ]; then \
@@ -16,6 +16,7 @@ ENV DAPPER_ENV REPO TAG DRONE_TAG CROSS DOCKER_USERNAME DOCKER_PASSWORD AWS_ACCE
 ENV DAPPER_SOURCE /go/src/github.com/rancher/os/
 ENV DAPPER_OUTPUT ./bin ./dist
 ENV DAPPER_DOCKER_SOCKET true
+ENV DAPPER_RUN_ARGS "-v ros-go16-pkg-1:/go/pkg -v ros-go16-cache-1:/root/.cache/go-build"
 WORKDIR ${DAPPER_SOURCE}
 
 ENTRYPOINT ["./scripts/entry"]
diff --git a/Makefile b/Makefile
index 7553f3c0..009ba569 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-.DEFAULT_GOAL := build
+.DEFAULT_GOAL := package
 REPO?=rancher/os
 TAG?=dev
 IMAGE=${REPO}:${TAG}
@@ -10,13 +10,17 @@ IMAGE=${REPO}:${TAG}
 	@./.dapper.tmp -v
 	@mv .dapper.tmp .dapper
 
-.PHONY: validate
+.PHONY: ci
 ci: .dapper
 	./.dapper ci
 
+.PHONY: package
+package: .dapper
+	./.dapper package
+
 .PHONY: clean
 clean:
-	rm -rf build
+	rm -rf build dist
 
 .PHONY: build-framework
 build-framework:
@@ -43,12 +47,12 @@ push-framework: build-framework
 	docker push ${REPO}-framework:${TAG}
 
 .PHONY: iso
-iso: build
+iso:
 	./ros-image-build ${IMAGE} iso
 	@echo "INFO: ISO available at build/output.iso"
 
 .PHONY: qcow
-qcow: build
+qcow:
 	./ros-image-build ${IMAGE} qcow
 	@echo "INFO: QCOW image available at build/output.qcow.gz"
 
diff --git a/framework/files/etc/luet/luet.yaml.aarch64 b/framework/files/etc/luet/luet.yaml.aarch64
new file mode 100644
index 00000000..fb084e32
--- /dev/null
+++ b/framework/files/etc/luet/luet.yaml.aarch64
@@ -0,0 +1,12 @@
+logging:
+  color: false
+  enable_emoji: false
+general:
+   debug: false
+   spinner_charset: 9
+repositories:
+- name: "cos-toolkit-green"
+  type: "docker"
+  enable: true
+  urls:
+  - "quay.io/costoolkit/releases-green-arm64"
diff --git a/ros-image-build b/ros-image-build
index 2b3df87a..c2c49298 100755
--- a/ros-image-build
+++ b/ros-image-build
@@ -14,19 +14,27 @@ ARG IMAGE=rancher/os:dev
 FROM ${IMAGE} AS os
 
 FROM opensuse/leap:15.3 AS tools
+RUN zypper ref
 ENV LUET_NOLOCK=true
 # Copy luet from the official images
-RUN zypper in -y squashfs xorriso curl unzip git qemu-kvm qemu-tools tar pigz
+RUN zypper in -y squashfs xorriso curl unzip git qemu-arm qemu-x86 qemu-tools tar pigz go1.16 qemu-uefi-aarch64
 RUN cd /usr/sbin && \
     rm packer && \
-    curl https://releases.hashicorp.com/packer/1.7.4/packer_1.7.4_linux_amd64.zip > tmp && \
+    SUFFIX=amd64 && \
+    if [ "$(uname -m)" = "aarch64" ]; then SUFFIX=arm64; fi && \
+    curl https://releases.hashicorp.com/packer/1.7.4/packer_1.7.4_linux_${SUFFIX}.zip > tmp && \
     unzip tmp && \
     rm tmp
 RUN cd /usr/src && \
     git clone https://github.com/rancher-sandbox/cOS-toolkit
-COPY --from=quay.io/luet/base:0.17.8 /usr/bin/luet /usr/bin/luet
+RUN curl -Lo /usr/bin/luet https://github.com/mudler/luet/releases/download/0.18.1/luet-0.18.1-linux-$(go env GOARCH) && \
+    chmod +x /usr/bin/luet
 RUN mkdir -p /iso/iso-overlay/boot/grub2 /etc/luet
-RUN echo -e \
+RUN export SUFFIX; \
+if [ "$(uname -m)" == "aarch64" ]; then \
+    SUFFIX=-arm64 \
+;fi && \
+echo -e \
 'logging:\n'\
 '  color: false\n'\
 '  enable_emoji: false\n'\
@@ -38,8 +46,8 @@ RUN echo -e \
 '  type: "docker"\n'\
 '  enable: true\n'\
 '  urls:\n'\
-'  - "quay.io/costoolkit/releases-green"\n' > /etc/luet/luet.yaml
-RUN echo -e \
+"  - \"quay.io/costoolkit/releases-green${SUFFIX}\"\n" > /etc/luet/luet.yaml && \
+echo -e \
 'packages:\n'\
 '  uefi:\n'\
 '  - live/grub2-efi-image\n'\
@@ -71,7 +79,7 @@ RUN echo -e \
 '    type: "docker"\n'\
 '    enable: true\n'\
 '    urls:\n'\
-'    - "quay.io/costoolkit/releases-green"\n' > /iso/iso.yaml
+"    - \"quay.io/costoolkit/releases-green${SUFFIX}\"\n" > /iso/iso.yaml
 RUN echo -e \
 'search --file --set=root /boot/kernel.xz\n'\
 'set default=0\n'\
@@ -116,10 +124,15 @@ RUN cd /iso && \
     luet-makeiso iso.yaml
 
 FROM iso-build AS qcow-build
-RUN packer build \
+RUN SUFFIX= && \
+    FIRMWARE= && \
+    if [ "$(uname -m)" = "aarch64" ]; then SUFFIX=-arm64; FIRMWARE=/usr/share/qemu/qemu-uefi-aarch64.bin; fi && \
+    PACKER_LOG=1 packer build \
+    -var "firmware=${FIRMWARE}" \
+    -var "memory=1024" \
     -var "iso=/iso/output.iso" \
     -var "accelerator=tcg" \
-    -only qemu.cos .
+    -only qemu.cos${SUFFIX} .
 RUN mkdir /output && \
     mv *.box /output/output.box && \
     pigz -dc *.tar.gz | tar xvf - && \
diff --git a/scripts/ci b/scripts/ci
index fe8a2df1..c0ed2cc9 100755
--- a/scripts/ci
+++ b/scripts/ci
@@ -5,4 +5,4 @@ cd $(dirname $0)
 
 ./test
 ./validate
-./package
+IMAGE_TARGETS=${IMAGE_TARGETS:-qcow} ./package
diff --git a/scripts/package b/scripts/package
index 1ad67d4a..ca5caa49 100755
--- a/scripts/package
+++ b/scripts/package
@@ -6,8 +6,8 @@ source $(dirname $0)/version
 cd $(dirname $0)/..
 
 export TAG
+make build
 make iso
-TARGETS="iso"
 
 if [ -n "$DOCKER_PASSWORD" ]; then
     docker login -u "$DOCKER_USERNAME" -p "${DOCKER_PASSWORD}"
@@ -19,14 +19,14 @@ if [ "$PUSH" = "true" ]; then
     make push-framework
 fi
 
-
-TARGETS=qcow
 if [ "$PUSH" = "true" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ]; then
-    TARGETS="${TARGETS} all-amis"
+    IMAGE_TARGETS="${IMAGE_TARGETS} all-amis"
 fi
 
 export GIT_COMMIT=${COMMIT}
-make -j8 ${TARGETS}
+if [ -n "${IMAGE_TARGETS}" ]; then
+    make -j8 ${IMAGE_TARGETS}
+fi
 
 isoinfo -x /rootfs.squashfs -R -i build/output.iso > build/output.squashfs
 isoinfo -x /boot/kernel.xz -R -i build/output.iso > build/output-kernel