Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
env:
script: "./tmp/build/install_rubikpi3.sh"
base_image: "https://people.canonical.com/~platform/images/qualcomm-iot/rubikpi3/ubuntu-server-24.04/x00/ubuntu-24.04-preinstalled-server-arm64+rubikpi3-20250912-127.yaml"
image_name: "rubikpi3"

runs-on: ubuntu-24.04-arm

Expand All @@ -31,7 +32,7 @@ jobs:
- name: Build rubikpi3 with mounting
run: |
chmod +x ./mount_rubikpi3.sh
./mount_rubikpi3.sh ${{ env.base_image }} ${{ env.script }} ${{ github.ref_name }}
./mount_rubikpi3.sh ${{ env.base_image }} ${{ env.script }}

- name: Compress built image
run: |
Expand All @@ -45,7 +46,7 @@ jobs:
retention-days: 1

build:
runs-on: ubuntu-24.04
runs-on: ubuntu-24.04-arm

strategy:
fail-fast: false
Expand Down Expand Up @@ -95,6 +96,8 @@ jobs:
base_image: https://github.com/Joshua-Riek/ubuntu-rockchip/releases/download/v2.4.0/ubuntu-24.04-preinstalled-server-arm64-rock-5c.img.xz

name: "Build for ${{ matrix.name }}"
env:
image_name: "${{ matrix.name }}"

steps:
- uses: actions/checkout@v4.1.7
Expand All @@ -103,19 +106,11 @@ jobs:
- name: Fetch tags
run: git fetch --tags --force

- uses: pguyot/arm-runner-action@HEAD
- name: Install dependencies and build image
id: install_deps
with:
image_additional_mb: 1500
bind_mount_repository: true
base_image: ${{ matrix.base_image }}
commands: |
chmod +x ${{matrix.script}}
${{ matrix.script }}
chmod +x ./install_common.sh
./install_common.sh
mkdir -p /opt/photonvision/
echo "${{ github.ref_name }};${{ matrix.name }}" > /opt/photonvision/image-version
run: |
sudo chmod +x ./mount_image.sh
sudo -E ./mount_image.sh ${{ matrix.base_image }} ${{ matrix.script }} 1000 2

- name: Compress built image
run: |
Expand Down
4 changes: 2 additions & 2 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ install_if_missing() {

debug "Installing $1..."
if [[ -z $TEST ]]; then
apt-get install --yes "$1"
apt-get --yes install "$1"
# Always mark our upstream apt deps as held back, which will prevent the package
# from being automatically installed, upgraded or removed
apt-mark manual "$1"
Expand Down Expand Up @@ -245,7 +245,7 @@ fi

debug "Updating package list..."
if [[ -z $TEST ]]; then
apt-get update
apt-get -q update
fi
debug "Updated package list."

Expand Down
7 changes: 5 additions & 2 deletions install_common.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/bin/bash -v

#!/bin/bash
# Verbose and exit on errors
set -ex

Expand Down Expand Up @@ -29,3 +28,7 @@ echo "photon:vision" | chpasswd
cp -f ./files/issue.txt /etc/issue
cp -f /etc/issue /etc/issue.net
sed -i 's/#Banner none/Banner \/etc\/issue.net/g' /etc/ssh/sshd_config

# Add photon version file
mkdir -p /opt/photonvision/
echo "${GITHUB_REF_NAME};${image_name}" > /opt/photonvision/image-version
8 changes: 8 additions & 0 deletions install_dev_pi.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

# Verbose and exit on errors
set -ex

# silence log spam from dpkg
cat > /etc/apt/apt.conf.d/99dpkg.conf << EOF
Dpkg::Progress-Fancy "0";
APT::Color "0";
Dpkg::Use-Pty "0";
EOF

# Run normal photon installer
chmod +x ./install.sh
./install.sh --install-nm=yes --arch=aarch64
Expand Down
7 changes: 7 additions & 0 deletions install_limelight.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
# Verbose and exit on errors
set -ex

# silence log spam from dpkg
cat > /etc/apt/apt.conf.d/99dpkg.conf << EOF
Dpkg::Progress-Fancy "0";
APT::Color "0";
Dpkg::Use-Pty "0";
EOF

# Run normal photon installer
chmod +x ./install.sh
./install.sh --install-nm=yes --arch=aarch64
Expand Down
33 changes: 22 additions & 11 deletions install_opi5.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash -v
#!/bin/bash

# Verbose and exit on errors
set -ex
Expand All @@ -15,7 +15,14 @@ else
fi
echo "pi:raspberry" | chpasswd

apt-get update --quiet
# silence log spam from dpkg
cat > /etc/apt/apt.conf.d/99dpkg.conf << EOF
Dpkg::Progress-Fancy "0";
APT::Color "0";
Dpkg::Use-Pty "0";
EOF

apt-get -q update

before=$(df --output=used / | tail -n1)
# clean up stuff
Expand All @@ -24,13 +31,13 @@ before=$(df --output=used / | tail -n1)
echo "Purging snaps"
rm -rf /var/lib/snapd/seed/snaps/*
rm -f /var/lib/snapd/seed/seed.yaml
apt-get purge --yes --quiet lxd-installer lxd-agent-loader
apt-get purge --yes --quiet snapd
apt-get --yes -q purge lxd-installer lxd-agent-loader
apt-get --yes -q purge snapd

# remove bluetooth daemon
apt-get purge --yes --quiet bluez
apt-get --yes -q purge bluez

apt-get --yes --quiet autoremove
apt-get --yes -q autoremove

# remove firmware that (probably) isn't needed
rm -rf /usr/lib/firmware/mrvl
Expand All @@ -49,16 +56,20 @@ chmod +x ./install.sh
./install.sh --install-nm=yes --arch=aarch64

echo "Installing additional things"
apt-get install --yes --quiet libc6 libstdc++6
apt-get --yes -qq install libc6 libstdc++6

# let netplan create the config during cloud-init
rm -f /etc/netplan/00-default-nm-renderer.yaml

mkdir --parents /mnt/CIDATA
mount "${loopdev}p1" /mnt/CIDATA
# set NetworkManager as the renderer in cloud-init
cp -f ./OPi5_CIDATA/network-config /boot/network-config

cp -f ./OPi5_CIDATA/network-config /mnt/CIDATA/network-config
# add customized user-data file for cloud-init
cp -f ./OPi5_CIDATA/user-data /boot/user-data
cp -f ./OPi5_CIDATA/user-data /mnt/CIDATA/user-data

umount /mnt/CIDATA
rmdir /mnt/CIDATA

# modify photonvision.service to enable big cores
sed -i 's/# AllowedCPUs=4-7/AllowedCPUs=4-7/g' /lib/systemd/system/photonvision.service
Expand Down Expand Up @@ -86,7 +97,7 @@ for btservice in $btservices; do
done

rm -rf /var/lib/apt/lists/*
apt-get --yes --quiet clean
apt-get --yes -qq clean

rm -rf /usr/share/doc
rm -rf /usr/share/locale/
7 changes: 7 additions & 0 deletions install_pi.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
# Verbose and exit on errors
set -ex

# silence log spam from dpkg
cat > /etc/apt/apt.conf.d/99dpkg.conf << EOF
Dpkg::Progress-Fancy "0";
APT::Color "0";
Dpkg::Use-Pty "0";
EOF

# Run normal photon installer
chmod +x ./install.sh
./install.sh --install-nm=yes --arch=aarch64
Expand Down
4 changes: 0 additions & 4 deletions install_rubikpi3.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,3 @@ rm -rf /usr/share/locale/
echo '=== Running install_common.sh ==='
chmod +x ./install_common.sh
./install_common.sh
echo '=== Creating version file ==='
mkdir -p /opt/photonvision/
echo '{$1};rubikpi3' > /opt/photonvision/image-version
echo '=== Installation complete ==='
162 changes: 162 additions & 0 deletions mount_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/bin/bash
set -exuo pipefail

rootdir="./rootfs"
rootdir="$(realpath ${rootdir})"
echo "Root directory will be: ${rootdir}"

url=$1
install_script=$2
additional_mb=$3
rootpartition=$4

if [[ $# -ge 5 ]]; then
bootpartition=$5
if [[ "x$rootpartion" = "x$bootpartition" ]]; then
echo "Boot partition cannot be equal to root partition"
exit 1
fi
else
bootpartition=
fi

image="base_image.img"

####
# Download the image
####
wget -nv -O ${image}.xz "${url}"
xz -T0 -d ${image}.xz

####
# Prepare and mount the image
####

if [[ ${additional_mb} -gt 0 ]]; then
dd if=/dev/zero bs=1M count=${additional_mb} >> ${image}
fi

export loopdev=$(losetup --find --show --partscan ${image})
# echo "loopdev=${loopdev}" >> $GITHUB_OUTPUT

part_type=$(blkid -o value -s PTTYPE "${loopdev}")
echo "Image is using ${part_type} partition table"

if [[ ${additional_mb} -gt 0 ]]; then
if [[ "${part_type}" == "gpt" ]]; then
sgdisk -e "${loopdev}"
fi
parted --script "${loopdev}" resizepart ${rootpartition} 100%
e2fsck -p -f "${loopdev}p${rootpartition}"
resize2fs "${loopdev}p${rootpartition}"
echo "Finished resizing disk image."
fi

sync

echo "Partitions in the mounted image:"
lsblk "${loopdev}"

if [[ -n "$bootpartition" ]]; then
bootdev="${loopdev}p${bootpartition}"
else
bootdev=
fi
rootdev="${loopdev}p${rootpartition}"

mkdir --parents ${rootdir}
# echo "rootdir=${rootdir}" >> "$GITHUB_OUTPUT"
mount "${rootdev}" "${rootdir}"
if [[ -n "$bootdev" ]]; then
mkdir --parents "${rootdir}/boot"
mount "${bootdev}" "${rootdir}/boot"
fi

# Set up the environment
mount -t proc /proc "${rootdir}/proc"
mount -t sysfs /sys "${rootdir}/sys"
mount --rbind /dev "${rootdir}/dev"

# Temporarily replace resolv.conf for networking
mv -v "${rootdir}/etc/resolv.conf" "${rootdir}/etc/resolv.conf.bak"
cp -v /etc/resolv.conf "${rootdir}/etc/resolv.conf"

####
# Modify the image in chroot
####
chrootscriptdir=/tmp/build
scriptdir=${rootdir}${chrootscriptdir}
mkdir --parents "${scriptdir}"
mount --bind "$(pwd)" "${scriptdir}"

cat >> "${scriptdir}/commands.sh" << EOF
set -ex
export DEBIAN_FRONTEND=noninteractive
cd "${chrootscriptdir}"
echo "Running ${install_script}"
chmod +x "${install_script}"
"./${install_script}"
echo "Running install_common.sh"
chmod +x "./install_common.sh"
"./install_common.sh"
EOF

cat -n "${scriptdir}/commands.sh"
chmod +x "${scriptdir}/commands.sh"

sudo -E chroot "${rootdir}" /bin/bash -c "${chrootscriptdir}/commands.sh"

####
# Clean up and shrink image
####

if [[ -e "${rootdir}/etc/resolv.conf.bak" ]]; then
mv "${rootdir}/etc/resolv.conf.bak" "${rootdir}/etc/resolv.conf"
fi

echo "Zero filling empty space"
if mountpoint "${rootdir}/boot"; then
(cat /dev/zero > "${rootdir}/boot/zeros" 2>/dev/null || true); sync; rm "${rootdir}/boot/zeros";
fi

(cat /dev/zero > "${rootdir}/zeros" 2>/dev/null || true); sync; rm "${rootdir}/zeros";

umount --recursive "${rootdir}"

echo "Resizing root filesystem to minimal size."
e2fsck -v -f -p -E discard "${rootdev}"
resize2fs -M "${rootdev}"
rootfs_blocksize=$(tune2fs -l ${rootdev} | grep "^Block size" | awk '{print $NF}')
rootfs_blockcount=$(tune2fs -l ${rootdev} | grep "^Block count" | awk '{print $NF}')

echo "Resizing rootfs partition."
rootfs_partstart=$(parted -m --script "${loopdev}" unit B print | grep "^${rootpartition}:" | awk -F ":" '{print $2}' | tr -d 'B')
rootfs_partsize=$((${rootfs_blockcount} * ${rootfs_blocksize}))
rootfs_partend=$((${rootfs_partstart} + ${rootfs_partsize} - 1))
rootfs_partoldend=$(parted -m --script "${loopdev}" unit B print | grep "^${rootpartition}:" | awk -F ":" '{print $3}' | tr -d 'B')
if [ "$rootfs_partoldend" -gt "$rootfs_partend" ]; then
echo y | parted ---pretend-input-tty "${loopdev}" unit B resizepart "${rootpartition}" "${rootfs_partend}"
else
echo "Rootfs partition not resized as it was not shrunk"
fi

free_space=$(parted -m --script "${loopdev}" unit B print free | tail -1)
if [[ "${free_space}" =~ "free" ]]; then
initial_image_size=$(stat -L --printf="%s" "${image}")
image_size=$(echo "${free_space}" | awk -F ":" '{print $2}' | tr -d 'B')
if [[ "${part_type}" == "gpt" ]]; then
# for GPT partition table, leave space at the end for the secondary GPT
# it requires 33 sectors, which is 16896 bytes
image_size=$((image_size + 16896))
fi
echo "Shrinking image from ${initial_image_size} to ${image_size} bytes."
truncate -s "${image_size}" "${image}"
if [[ "${part_type}" == "gpt" ]]; then
# use sgdisk to fix the secondary GPT after truncation
sgdisk -e "${image}"
fi
fi

losetup --detach "${loopdev}"

echo "image=${image}" >> "$GITHUB_OUTPUT"
Loading