├── .gitlab-ci.yml ├── .gitmodules ├── README.md ├── build-packages.sh ├── build.sh ├── clean.sh ├── patches ├── python-inotify-disable-test_renames.patch └── vyos-live-build-traverse-only-disable-iso-secure-boot.patch ├── repos.development.txt ├── repos.txt ├── runjenkins.lua └── testimg.sh /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | build: 2 | stage: build 3 | tags: 4 | - arm64 5 | - dynamic 6 | - dynamic_runner_arm64_aws_shell 7 | script: 8 | - sudo ./build.sh 9 | artifacts: 10 | when: always 11 | paths: 12 | - vyos-build/build/*.iso 13 | - vyos-build/packages/*.deb 14 | except: 15 | - merge_requests 16 | variables: 17 | GIT_SUBMODULE_STRATEGY: recursive -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vyos-build"] 2 | path = vyos-build 3 | url = ../vyos-build.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ARM64 Bootstrap for VyOS 2 | 3 | **Updated 2023-12-20** 4 | 5 | This repo can assist in bootstrapping a VyOS image for arm64, without 6 | depending on the artifacts already generated by Jenkins. 7 | 8 | The generated image is an ISO that will boot on ARM 9 | Embedded and Server Base Boot systems (e.g those 10 | that use EFI) 11 | 12 | There are also a few minor hacks/patches applied which 13 | should be upstreamed shortly. 14 | 15 | If you are unfamiliar with the VyOS build process, see 16 | the [Build VyOS](https://docs.vyos.io/en/latest/contributing/build-vyos.html) 17 | page in the documentation. 18 | 19 | Current hardware targets: 20 | * QEMU ARM64 Virtual Machine with EDKII 21 | * Traverse Technologies Ten64 22 | 23 | **Note: only basic routing and NAT functionality 24 | has been tested at this time.** 25 | 26 | Build requirements: 27 | * ARM64 host (no cross compiling) 28 | 29 | * It is best to use a Debian machine as the 30 | build host. Issues have been encountered with 31 | AppArmor on Ubuntu 32 | 33 | * Working docker or podman-docker installation 34 | 35 | * sudo access from the current user 36 | 37 | Due to the need to do some privileged operations, the build process can't be done in a 'rootless' container. You must use sudo to execute docker/podman. 38 | 39 | # Other efforts: 40 | 41 | Graham Hayes built his own version here: [https://github.com/grahamhayes/vyos-build/](https://github.com/grahamhayes/vyos-build/). The main difference is that this one doesn't use a container to do builds. See [Ten64 forum discussion](https://forum.traverse.com.au/t/vyos-build-my-repo/181) 42 | 43 | 44 | # Usage: 45 | My `vyos-build` branch is setup as a submodule of this repository, so you should do a 46 | recursive clone first: 47 | 48 | ``` 49 | git clone --recursive https://github.com/mcbridematt/vyos-arm64-builder.git 50 | ``` 51 | 52 | Run ./build.sh (as root or sudo) to build the 'vyos-build' container 53 | and then packages and image. 54 | 55 | ``` 56 | sudo ./build.sh 57 | ``` 58 | 59 | An ISO image will be generated under `vyos-build/build/vyos-{VYOS_VERSION}.{YYYYMMDDHHMM}-arm64.iso` 60 | 61 | # Package commit pinning 62 | The source versions of each component are "pinned" to a commit or branch in `repos.txt` to ensure this 63 | environment will produce a working image. To use the latest available current/development versions, 64 | copy `repos.development.txt` in its place. 65 | 66 | # Testing inside a VM 67 | The `./testimg.sh` script can be used to boot 68 | the generated ISO image as a QEMU/KVM virtual machine. 69 | 70 | You need to run the script on a genuine arm64 host with virtualization 71 | capabilities. 72 | 73 | (It is possible to run it under emulation, but YMMV). 74 | 75 | An EDK2 "bios" binary is required, under Debian you can use 76 | the [qemu-efi-aarch64](https://packages.debian.org/buster/qemu-efi-aarch64) package 77 | or grab a build from [retrage/edk2-nightly](https://retrage.github.io/edk2-nightly/). 78 | 79 | ``` 80 | cp vyos-build/build/vyos-{VYOS_VERSION}.{YYYYMMDDHHMM}-arm64.iso vyos.iso 81 | sudo ./testimg.sh 82 | ``` 83 | (Hint: Use Ctrl-X to immediately exit qemu). 84 | 85 | # Running on real hardware (Ten64) 86 | On a Ten64 a suitable block medium (NVMe SSD, USB drive or SD card) is needed. 87 | It might be possible to fit VyOS into the onboard NAND/ubifs in the future. 88 | 89 | Write the VyOS ISO to a USB drive using dd or a similar tool: 90 | 91 | ``` 92 | dd if=vyos.iso of=/dev/sda 93 | ``` 94 | 95 | Then boot into the 'live' VyOS system and do an install: 96 | 97 | ``` 98 | vyos@vyos:~$ install image 99 | ``` 100 | 101 | See the [VyOS Installation doc](https://docs.vyos.io/en/latest/installation/install.html#live-installation) for more 102 | information. 103 | 104 | # Known issues: 105 | * There are some hacks to bypass or remove certain aspects that can cause trouble: 106 | * udev interface renaming rules and biosdevname handling - need to debug issues with this not working properly. 107 | * The GRUB configuration has been modified so console= is never specified. On most Arm hosts that 108 | specify the system console in the device tree (chosen node) or ACPI this will mean the correct 109 | serial console is chosen out of the box. 110 | * Previously this repository generated a qcow2 image, but this is currently 111 | not possible due to recent changes in vyos-build. Hopefully it can be 112 | bought back soon. 113 | -------------------------------------------------------------------------------- /build-packages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | export DEBEMAIL="test@example.com" 4 | BASEDIR=$(dirname $(readlink -f "$0")) 5 | PATCHES_DIR=$(readlink -f "${BASEDIR}/patches") 6 | 7 | sudo apt-get install -y clang llvm libpcap-dev xz-utils python-is-python3 libbpf-dev linux-libc-dev 8 | # Do linux kernel first as we need our kernel headers 9 | # for XDP 10 | pwd 11 | if [ ! -d "vyos-build" ]; then 12 | echo "ERROR: No vyos-build found" 13 | pwd 14 | ls -la . 15 | exit 1 16 | git clone https://github.com/vyos/vyos-build 17 | fi 18 | 19 | git config --global --add safe.directory $(readlink -f "vyos-build") 20 | 21 | PACKAGES_DIR=$(readlink -f "vyos-build/packages") 22 | DEBS_DIR=$(readlink -f "vyos-build/debs") 23 | mkdir -p "${DEBS_DIR}" 24 | cd "${PACKAGES_DIR}" 25 | 26 | for d in $(find -name Jenkinsfile -exec dirname {} \;); do 27 | echo "BUILDING PACKAGE ${d}" 28 | cd "${d}" 29 | lua "${BASEDIR}/runjenkins.lua" || (echo "ERROR: Package ${d} failed" && exit 1) 30 | find -name \*.deb -exec cp {} "${DEBS_DIR}" \; 31 | cd "${PACKAGES_DIR}" 32 | done 33 | 34 | cd "${BASEDIR}" 35 | REPOS=$(cat repos.txt) 36 | mkdir -p build 37 | eval $(opam env --root=/opt/opam --set-root) 38 | for i in $REPOS; do 39 | PACKAGENAME=$(echo "${i}" | awk -F ';' '{print $1}') 40 | PACKAGECOMMIT=$(echo "${i}" | awk -F ';' '{print $2}') 41 | if [[ "${PACKAGENAME}" = https://* ]]; then 42 | PACKAGE_FOLDER_NAME=$(echo "${PACKAGENAME}" | awk -F '/' '{print $NF}' | sed "s/\.git//g") 43 | git clone "${PACKAGENAME}" "build/${PACKAGE_FOLDER_NAME}" 44 | PACKAGENAME="${PACKAGE_FOLDER_NAME}" 45 | else 46 | git clone "https://github.com/vyos/${PACKAGENAME}.git" "build/${PACKAGENAME}" 47 | fi 48 | cd "build/${PACKAGENAME}" 49 | if [ -n "${PACKAGECOMMIT}" ]; then 50 | git checkout "${PACKAGECOMMIT}" 51 | fi 52 | if [ "${PACKAGENAME}" = "ipaddrcheck" ]; then 53 | rm src/*.o 54 | elif [ "${PACKAGENAME}" = "python-inotify" ]; then 55 | patch -p1 -i "${PATCHES_DIR}/python-inotify-disable-test_renames.patch" 56 | elif [ "${PACKAGENAME}" = "vyos-live-build" ]; then 57 | patch -p1 -i "${PATCHES_DIR}/vyos-live-build-traverse-only-disable-iso-secure-boot.patch" 58 | fi 59 | echo "y" | mk-build-deps --install --remove 60 | dpkg-buildpackage -b -us -uc -tc 61 | cd "${BASEDIR}" 62 | done 63 | 64 | # Use our copy of live-build to do image building 65 | dpkg -i build/live-build*.deb 66 | cp build/*.deb vyos-build/debs/ 67 | find vyos-build/packages/ -name '*-build-deps*deb' -exec rm {} \; 68 | 69 | find vyos-build/debs -name '*build-deps*' -exec rm {} \; 70 | 71 | echo "LIST OF BUILT DEBS: " 72 | ls -la "vyos-build/debs/" 73 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | BUILD_BY="matt@traverse.com.au" 4 | 5 | #apt-get install -y kpartx make pbuilder devscripts python3-pystache python3-git python3-setuptools parted dosfstools python3-toml python3-jinja2 6 | #CONTAINER_NAME="vyos/vyos-build:current-arm64" 7 | CONTAINER_NAME="vyos-build-arm64" 8 | docker build -t "${CONTAINER_NAME}" vyos-build/docker/ 9 | PKGBUILD_CONTAINER=$(docker create -it --privileged --sysctl net.ipv6.conf.lo.disable_ipv6=0 --entrypoint "/bin/bash" -v $(pwd):/tmp/vyos-build-arm64 "${CONTAINER_NAME}") 10 | docker start "${PKGBUILD_CONTAINER}" 11 | docker exec "${PKGBUILD_CONTAINER}" /bin/bash -c 'cd /tmp/vyos-build-arm64 && ./build-packages.sh' 12 | docker exec "${PKGBUILD_CONTAINER}" /bin/bash -c "cd /tmp/vyos-build-arm64/vyos-build && ./build-vyos-image --architecture=arm64 --build-by="${BUILD_BY}" --debug --build-type=development iso" 13 | docker stop "${PKGBUILD_CONTAINER}" 14 | docker rm "${PKGBUILD_CONTAINER}" 15 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | rm -rf build vyos-build/build vyos-build/packages vyos-build/debs 2 | (cd vyos-build && git checkout packages) 3 | -------------------------------------------------------------------------------- /patches/python-inotify-disable-test_renames.patch: -------------------------------------------------------------------------------- 1 | From a786ddea4b0c07031a233a534fb132743711fe1c Mon Sep 17 00:00:00 2001 2 | From: Mathew McBride 3 | Date: Mon, 7 Nov 2022 08:29:37 +0000 4 | Subject: [PATCH] python-inotify: disable test_renames 5 | 6 | Fails when building under a container 7 | --- 8 | debian/rules | 2 +- 9 | 1 file changed, 1 insertion(+), 1 deletion(-) 10 | 11 | diff --git a/debian/rules b/debian/rules 12 | index 686b0c1..8d27fea 100755 13 | --- a/debian/rules 14 | +++ b/debian/rules 15 | @@ -1,7 +1,7 @@ 16 | #!/usr/bin/make -f 17 | 18 | export PYBUILD_NAME=python-inotify 19 | -export PYBUILD_TEST_ARGS=-k 'not test__cycle' --reruns 3 --reruns-delay 1 20 | +export PYBUILD_TEST_ARGS=-k 'not test__cycle and not test__renames' --reruns 3 --reruns-delay 1 21 | 22 | %: 23 | dh $@ --with python3 --buildsystem=pybuild 24 | -- 25 | 2.30.2 26 | 27 | -------------------------------------------------------------------------------- /patches/vyos-live-build-traverse-only-disable-iso-secure-boot.patch: -------------------------------------------------------------------------------- 1 | From 835a7645ee844160e3d4cd657148bf7eaac71c79 Mon Sep 17 00:00:00 2001 2 | From: Mathew McBride 3 | Date: Thu, 10 Nov 2022 05:16:55 +0000 4 | Subject: [PATCH] (Traverse only) disable secure boot generation 5 | 6 | Temporary, current Ten64 firmware doesn't support the UEFI secure boot protocol 7 | --- 8 | scripts/build/binary_grub-efi | 3 ++- 9 | 1 file changed, 2 insertions(+), 1 deletion(-) 10 | 11 | diff --git a/scripts/build/binary_grub-efi b/scripts/build/binary_grub-efi 12 | index bd7d75f02..2be0e06ac 100755 13 | --- a/scripts/build/binary_grub-efi 14 | +++ b/scripts/build/binary_grub-efi 15 | @@ -90,7 +90,8 @@ case "${LB_ARCHITECTURE}" in 16 | esac 17 | 18 | _PRE_SB_PACKAGES="${_LB_PACKAGES}" 19 | -_LB_PACKAGES="shim-signed grub-efi-${_SB_EFI_DEB}-signed" 20 | +_LB_PACKAGES="" 21 | +LB_UEFI_SECURE_BOOT=disable 22 | case "${LB_UEFI_SECURE_BOOT}" in 23 | auto) 24 | # Use Check_installed, as Check_package will error out immediately 25 | -- 26 | 2.30.2 27 | 28 | -------------------------------------------------------------------------------- /repos.development.txt: -------------------------------------------------------------------------------- 1 | libvyosconfig 2 | https://github.com/mcbridematt/vyos-1x.git;d591cacbde61bf71af7b8941a784d21367d1ba0c 3 | vyatta-op 4 | https://github.com/mcbridematt/vyatta-cfg-system.git;fix-grub-arm64 5 | vyatta-cfg-qos 6 | vyatta-op-qos 7 | vyatta-cluster 8 | vyatta-config-mgmt 9 | vyos-world 10 | libpam-radius-auth 11 | ipaddrcheck 12 | vyatta-bash 13 | mdns-repeater 14 | hvinfo 15 | libnss-mapuser 16 | vyatta-cfg 17 | vyatta-wanloadbalance 18 | vyos-utils 19 | vyos-user-utils 20 | vyos-http-api-tools 21 | vyatta-biosdevname 22 | udp-broadcast-relay 23 | vyos-live-build 24 | live-boot 25 | https://salsa.debian.org/python-team/packages/python-inotify.git 26 | -------------------------------------------------------------------------------- /repos.txt: -------------------------------------------------------------------------------- 1 | libvyosconfig;c6141d97c85b2902d45b12ec81d8e4a48da03519 2 | https://github.com/mcbridematt/vyos-1x.git;408c82da0f4318acf27a41726aed764cc01b6856 3 | vyatta-op;fe13cfa6f5560197cb69b185994165cacc534c0d 4 | vyatta-cfg-system;de3ba58f8be2bf402e882dbe1aa16f8559d150a2 5 | vyatta-cluster;eaed25b1d45b159bff2c35a56f68c9e583017faa 6 | vyos-world;9421bada981a2f5ea143d84204aa9ae373db2150 7 | libpam-radius-auth;c14d4c2359b6c507467051a67935603038528889 8 | ipaddrcheck;258753a9d848e0157457086b0d6fa17ee6900786 9 | vyatta-bash;0b5c632e466c12eefa8570f4260f2303902e90b6 10 | hvinfo;f5b670d4048778cb490a2b56035c5d79e8fbc817 11 | libnss-mapuser;3f11d8263d0272f544254b21335f8b517f745aa0 12 | vyatta-cfg;ecc7310a9642618c67acf5551eb6aef740313571 13 | vyatta-wanloadbalance;448d12e6103e6ff86a3244dfe0b1f0eaae088f46 14 | vyos-utils;ee09423fe66af387317122d0b60368025b5f881f 15 | vyos-user-utils;59ce060c8523b5eb72ff0e89cb3e00833692cea1 16 | vyos-http-api-tools;1ebf87886fcf481fcc2a923be9b865f99452e481 17 | vyatta-biosdevname;cf142dc74ebdfedb52a03696946eca537a8409c6 18 | udp-broadcast-relay;a5c2740e2eabf127f1228b6c323a2bd17222513b 19 | vyos-live-build;0784b726c7dff36f783ea9910a85381a5e065516 20 | live-boot;2cb0416743abdac7b31687f619e15510de79c36d 21 | https://salsa.debian.org/python-team/packages/python-inotify.git;0129d56d7f10c6fb2b2e4055fb9023fd8d1c9f23 22 | -------------------------------------------------------------------------------- /runjenkins.lua: -------------------------------------------------------------------------------- 1 | require "pl" 2 | 3 | function extractValue(packagestring, key) 4 | local matchsequence = "'"..key.."':%s?'+([%w%-_%/:%.%%]+)'+," 5 | local valueit = string.gmatch(packagestring,matchsequence) 6 | local thismatch = nil 7 | for match in valueit do 8 | thismatch = match 9 | break 10 | end 11 | return thismatch 12 | end 13 | 14 | function extractBuildCmd(packagestring) 15 | local startit = string.gmatch(packagestring, "'buildCmd':[%s%c]?'+(.+)") 16 | for match in startit do 17 | local endpos = match:find("'+]") 18 | local substr = match:sub(0, endpos-1) 19 | -- fix any escape sequences 20 | substr = substr:gsub("\\","") 21 | return substr 22 | end 23 | end 24 | jenkinsfile = file.read("Jenkinsfile") 25 | pkgListStart = jenkinsfile:find("def pkgList = %[") 26 | endPkgList = stringx.rfind(jenkinsfile, "]") 27 | pkgList = jenkinsfile:sub(pkgListStart,endPkgList) 28 | print(pkgList) 29 | 30 | curidx = 0 31 | hasnextpackage = pkgList:find("%[",curidx) 32 | packages = {} 33 | 34 | while hasnextpackage do 35 | thispkgend = pkgList:find("],", hasnextpackage+1) 36 | thispkg = pkgList:sub(hasnextpackage,thispkgend) 37 | print(thispkg) 38 | hasnextpackage = pkgList:find("%[",thispkgend) 39 | packagename = extractValue(thispkg,"name") 40 | local scmurl = extractValue(thispkg,"scmUrl") 41 | local scmcommit = extractValue(thispkg,"scmCommit") 42 | local package_clone_success = false 43 | if (scmurl ~= nil) and (scmcommit ~= nil) then 44 | print(string.format("[%s] Need to clone %s commit %s", packagename, scmurl, scmcommit)) 45 | if (scmcommit:find("^%x+") ~= nil) then 46 | package_clone_success = utils.execute("git clone " .. scmurl .. " " .. packagename .. " && cd " .. packagename .. " && git reset --hard " .. scmcommit) 47 | else 48 | local git_clone_command = "git clone --depth=1 --branch='" .. scmcommit .. "' " .. scmurl .. " " .. packagename 49 | print(git_clone_command) 50 | package_clone_success = utils.execute(git_clone_command) 51 | end 52 | else 53 | print("scmurl or commit nil, check this: " .. tostring(scmurl) .. " commit=" .. tostring(scmcommit)) 54 | dir.makepath(packagename) 55 | package_clone_success = true 56 | end 57 | if (package_clone_success) then 58 | local buildcmd = "yes | mk-build-deps --install --remove\n" .. extractBuildCmd(thispkg) 59 | utils.writefile(packagename .. "/jenkins_build_cmd.sh",buildcmd) 60 | packages[#packages+1] = packagename 61 | else 62 | print("WARNING: package " .. packagename .. " did not clone successfully") 63 | end 64 | end 65 | for i,packagename in ipairs(packages) do 66 | print("Doing compile for " .. packagename) 67 | local package_build_success,package_build_ret,package_build_stdout,package_build_stderr = utils.executeex("cd " .. packagename .. " && sh jenkins_build_cmd.sh 2>&1") 68 | if (package_build_success ~= true) then 69 | print("Error: " .. packagename .. " did not build successfully") 70 | print("Return code: " .. tostring(package_build_ret)) 71 | print("stdout: ") 72 | print(package_build_stdout) 73 | print("------------------------------------------------------") 74 | os.exit(1) 75 | end 76 | print("Compile task for " .. packagename .. " done") 77 | end 78 | -------------------------------------------------------------------------------- /testimg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | qemu-system-aarch64 -nographic \ 3 | --enable-kvm \ 4 | -cpu host -machine virt \ 5 | -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd \ 6 | -smp 2 -m 1024 \ 7 | -device virtio-rng-pci \ 8 | -hda vyos-drive.qcow2 \ 9 | -cdrom vyos.iso \ # Remove this after VyOS install 10 | -netdev user,id=testlan -net nic,netdev=testlan \ 11 | -netdev user,id=testwan -net nic,netdev=testwan 12 | 13 | # -cdrom vyos.iso \ 14 | --------------------------------------------------------------------------------