Compare commits

...

7 Commits

Author SHA1 Message Date
Dustin 3aa291904b resolved: Disable mDNS
dustin/airplaypi/pipeline/head This commit looks good Details
`avahi-daemon` complains:

> WARNING: Detected another IPv4 mDNS stack running on this host. This
> makes mDNS unreliable and is thus not recommended.
2025-09-09 07:40:11 -05:00
Dustin 78687b48dc ci: Fetch Aimee OS Git tags
Need the tags to build the correct version string for Aimee OS.
2025-09-09 07:40:11 -05:00
Dustin 87dded162e ci: Fix pod UIDs/GIDs
Now that we have _democratic-csi_ for storage management, the old manual
iSCSI volumes are being replaced with dynamically provisioned volumes.
ThiThe new _buildroot-airplaypi_ volume is completely blank, so _root_
owns everything.  The old volume had the correct ownership because it
was originally mounted in a pod that had the default `securityContext`,
before we changed the merge strategy.  We now need to explicitly set the
UIDs and GIDs, since we're not inheriting the default `securityContext`
anymore.
2025-09-09 07:40:11 -05:00
Dustin fa7548cacc Install shairport-sync
`shairport-sync` provides the AirPlay functionality for _airplaypi_.
2025-09-09 07:40:11 -05:00
Dustin 607af90e0c ci: Skip SELinux relabel on start
By default, CRI-O assigns a random SELinux category to every pod, and
then must adjust the label of every file and directory in the persistent
volume to match.  For very large volumes like a Buildroot output
directory, this can take quite some time.  Fortunately, if we assign a
static category, we can tell CRI-O to skip the relabel step.

Unfortunately, Jenkins does not merge the `securityContext` field of the
pod spec when the `yamlMergeStrategy` is set to `merge`.  For our custom
settings to apply, we have to leave the merge strategy at the default,
`override`.
2025-09-09 07:40:11 -05:00
Dustin 9dd4a16e2b Enable WiFi, SSH 2025-09-09 07:40:11 -05:00
Dustin 153a8071a9 Add a root shell on UART console
Until I implement some kind of self-provisioning process for these
machines (supposing I ever do), I need a way to log in and
configure/troubleshoot.  I don't think there's any particular security
concern by having an auto-logged-in root shell on the UART console, as
accessing it needs physical access to the machine.
2025-09-09 07:40:03 -05:00
8 changed files with 90 additions and 1 deletions

View File

@ -2,10 +2,12 @@ BR2_arm=y
BR2_cortex_a53=y
BR2_ARM_FPU_NEON_VFPV4=y
BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_6_12=y
BR2_TOOLCHAIN_BUILDROOT_CXX=y
BR2_GLOBAL_PATCH_DIR="board/raspberrypi/patches"
BR2_DOWNLOAD_FORCE_CHECK_HASHES=y
BR2_TARGET_GENERIC_HOSTNAME="airplaypi"
BR2_INIT_SYSTEMD=y
BR2_ROOTFS_OVERLAY="$(WORKSPACE)/rootfs-overlay"
BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_AIMEEOS_PATH)/board/raspberrypi3/post-image.sh"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_CUSTOM_TARBALL=y
@ -16,11 +18,26 @@ BR2_LINUX_KERNEL_INTREE_DTS_NAME="broadcom/bcm2710-rpi-3-b broadcom/bcm2710-rpi-
BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
# BR2_PACKAGE_BUSYBOX is not set
BR2_PACKAGE_XZ=y
BR2_PACKAGE_BRCMFMAC_SDIO_FIRMWARE_RPI=y
BR2_PACKAGE_BRCMFMAC_SDIO_FIRMWARE_RPI_BT=y
BR2_PACKAGE_BRCMFMAC_SDIO_FIRMWARE_RPI_WIFI=y
BR2_PACKAGE_READLINE=y
BR2_PACKAGE_RPI_FIRMWARE=y
BR2_PACKAGE_RPI_FIRMWARE_BOOTCODE_BIN=y
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI=y
BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE="$(BR2_EXTERNAL_AIMEEOS_PATH)/board/raspberrypi3/config.txt"
BR2_PACKAGE_RPI_FIRMWARE_CMDLINE_FILE="$(BR2_EXTERNAL_AIMEEOS_PATH)/board/raspberrypi3/cmdline.txt"
BR2_PACKAGE_AVAHI=y
# BR2_PACKAGE_AVAHI_AUTOIPD is not set
BR2_PACKAGE_AVAHI_DAEMON=y
BR2_PACKAGE_IPROUTE2=y
BR2_PACKAGE_IWD=y
BR2_PACKAGE_OPENSSH=y
# BR2_PACKAGE_OPENSSH_CLIENT is not set
BR2_PACKAGE_SHAIRPORT_SYNC=y
BR2_PACKAGE_SHAIRPORT_SYNC_CONVOLUTION=y
BR2_PACKAGE_SHAIRPORT_SYNC_DBUS=y
BR2_PACKAGE_SHAIRPORT_SYNC_LIBSOXR=y
# BR2_TARGET_ROOTFS_TAR is not set
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="rpi_3_32b"
BR2_PACKAGE_HOST_KMOD_XZ=y

2
ci/Jenkinsfile vendored
View File

@ -11,7 +11,6 @@ pipeline {
agent {
kubernetes {
yamlFile 'ci/podTemplate.yaml'
yamlMergeStrategy merge()
workspaceVolume persistentVolumeClaimWorkspaceVolume(
claimName: 'buildroot-airplaypi'
)
@ -71,6 +70,7 @@ pipeline {
relativeTargetDir: 'aimee-os',
],
cloneOption(
noTags: false,
shallow: true,
depth: 1,
),

View File

@ -1,4 +1,15 @@
metadata:
annotations:
io.kubernetes.cri-o.TrySkipVolumeSELinuxLabel: 'true'
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: node-role.kubernetes.io/jenkins
operator: Exists
containers:
- name: build
image: git.pyrocufflink.net/containerimages/buildroot
@ -11,8 +22,17 @@ spec:
- mountPath: /etc/ssh/ssh_known_hosts
name: ssh-known-hosts
subPath: ssh_known_hosts
nodeSelector:
kubernetes.io/arch: amd64
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
seLinuxOptions:
level: s0:c596,c675
tolerations:
- key: du5t1n.me/jenkins
volumes:
- name: ssh-known-hosts
configMap:

View File

@ -0,0 +1,2 @@
[Resolve]
MulticastDNS=no

View File

@ -0,0 +1,2 @@
enable root-shell@.service ttyAMA0
enable shairport-sync.service

View File

@ -0,0 +1,26 @@
[Unit]
Description=root shell on %I
After=sshd.service
Conflicts=shutdown.target
Conflicts=getty@%i.service serial-getty@%i.service
[Service]
Type=idle
Environment=TERM=linux
ExecStart=/bin/sh
Restart=always
RestartSec=0
StandardInput=tty
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
KillMode=process
IgnoreSIGPIPE=no
KillSignal=SIGHUP
# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,20 @@
[Unit]
Description=Shairport Sync - AirPlay Audio Receiver
Documentation=man:shairport-sync(7)
Documentation=file:///usr/share/doc/shairport-sync/README.md.gz
Documentation=https://github.com/mikebrady/shairport-sync
After=sound.target
Requires=avahi-daemon.service
After=avahi-daemon.service
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=simple
Restart=on-failure
ExecStart=/usr/bin/shairport-sync
User=shairport-sync
Group=shairport-sync
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,2 @@
u shairport-sync - "Shairport Sync"
m shairport-sync audio