Initial commit
commit
9d2c710be9
|
@ -0,0 +1 @@
|
|||
/_build
|
|
@ -0,0 +1,32 @@
|
|||
# Network-Booted Jenkins Agent
|
||||
|
||||
## Required Build Host Configuration
|
||||
|
||||
```sh
|
||||
sudo dnf install -y \
|
||||
ncurses-devel \
|
||||
perl-ExtUtils-MakeMaker \
|
||||
perl-FindBin \
|
||||
perl-Thread-Queue \
|
||||
--
|
||||
```
|
||||
|
||||
```sh
|
||||
git clone git://git.buildroot.net/buildroot ~/src/buildroot
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
### Build the Initramfs
|
||||
|
||||
```sh
|
||||
make -C ~/src/buildroot O=${PWD}/_build/initramfs BR2_EXTERNAL=${PWD} jenkinsagent_initramfs_defconfig
|
||||
make -C _build/initramfs -j $(nproc)
|
||||
```
|
||||
|
||||
### Build the Rootfs
|
||||
|
||||
```sh
|
||||
make -C ~/src/buildroot O=${PWD}/_build/rootfs BR2_EXTERNAL=${PWD} jenkinsagent_defconfig
|
||||
make -C _build/rootfs -j $(nproc)
|
||||
```
|
|
@ -0,0 +1 @@
|
|||
audit=0 panic=5 console=ttyAMA0 root=nbd:rosalina.pyrocufflink.blue:jenkinsagent rsyslog.dest=rosalina.pyrocufflink.blue sshkeys.root=http://rosalina.pyrocufflink.blue/~dustin/id_ed25519.pub
|
|
@ -0,0 +1,23 @@
|
|||
# See http://buildroot.org/manual.html#rootfs-custom
|
||||
# and http://elinux.org/RPiconfig for a description of config.txt syntax
|
||||
|
||||
start_file=start4.elf
|
||||
fixup_file=fixup4.dat
|
||||
|
||||
kernel=Image
|
||||
|
||||
# To use an external initramfs file
|
||||
initramfs rootfs.cpio.lz4
|
||||
|
||||
# Disable overscan assuming the display supports displaying the full resolution
|
||||
# If the text shown on the screen disappears off the edge, comment this out
|
||||
disable_overscan=1
|
||||
|
||||
dtoverlay=vc4-kms-v3d-pi4
|
||||
dtoverlay=imx219
|
||||
#dtoverlay=ov5647
|
||||
|
||||
dtoverlay=disable-bt
|
||||
|
||||
# enable 64bits support
|
||||
arm_64bit=1
|
|
@ -0,0 +1,49 @@
|
|||
BR2_aarch64=y
|
||||
BR2_cortex_a72=y
|
||||
BR2_ARM_FPU_VFPV4=y
|
||||
BR2_TOOLCHAIN_BUILDROOT_GLIBC=y
|
||||
BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_5_10=y
|
||||
BR2_TOOLCHAIN_BUILDROOT_CXX=y
|
||||
BR2_INIT_SYSTEMD=y
|
||||
# BR2_TARGET_ENABLE_ROOT_LOGIN is not set
|
||||
BR2_SYSTEM_DEFAULT_PATH="/bin:/sbin:/usr/bin:/usr/sbin"
|
||||
BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_jenkinsagent_PATH)/rootfs/overlay"
|
||||
BR2_ROOTFS_POST_FAKEROOT_SCRIPT="$(BR2_EXTERNAL_jenkinsagent_PATH)/rootfs/post-fakeroot.sh"
|
||||
BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_jenkinsagent_PATH)/rootfs/post-image.sh"
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_TARBALL=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION="$(call github,raspberrypi,linux,0b54dbda3cca2beb51e236a25738784e90853b64)/linux-0b54dbda3cca2beb51e236a25738784e90853b64.tar.gz"
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_jenkinsagent_PATH)/rootfs/linux.config"
|
||||
BR2_LINUX_KERNEL_DTS_SUPPORT=y
|
||||
BR2_LINUX_KERNEL_INTREE_DTS_NAME="broadcom/bcm2711-rpi-4-b"
|
||||
BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
|
||||
# BR2_PACKAGE_BUSYBOX is not set
|
||||
BR2_PACKAGE_GIT=y
|
||||
BR2_PACKAGE_XORG7=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI4=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE="$(BR2_EXTERNAL_jenkinsagent_PATH)/config.txt"
|
||||
BR2_PACKAGE_OPENJDK=y
|
||||
BR2_PACKAGE_LIBCURL=y
|
||||
BR2_PACKAGE_LIBCURL_CURL=y
|
||||
# BR2_PACKAGE_LIBCURL_EXTRA_PROTOCOLS_FEATURES is not set
|
||||
BR2_PACKAGE_DHCPCD=y
|
||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||
BR2_PACKAGE_IPROUTE2=y
|
||||
BR2_PACKAGE_OPENSSH=y
|
||||
BR2_PACKAGE_COREUTILS=y
|
||||
BR2_PACKAGE_COREUTILS_INDIVIDUAL_BINARIES=y
|
||||
BR2_PACKAGE_DOCKER_CLI=y
|
||||
BR2_PACKAGE_DOCKER_ENGINE=y
|
||||
BR2_PACKAGE_HTOP=y
|
||||
BR2_PACKAGE_PROCPS_NG=y
|
||||
BR2_PACKAGE_PSMISC=y
|
||||
BR2_PACKAGE_RSYSLOG=y
|
||||
# BR2_PACKAGE_SYSTEMD_HWDB is not set
|
||||
# BR2_PACKAGE_SYSTEMD_NETWORKD is not set
|
||||
# BR2_PACKAGE_SYSTEMD_RESOLVED is not set
|
||||
BR2_PACKAGE_UTIL_LINUX_LOGIN=y
|
||||
BR2_TARGET_ROOTFS_SQUASHFS=y
|
||||
BR2_TARGET_ROOTFS_SQUASHFS4_LZ4=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
|
@ -0,0 +1,21 @@
|
|||
BR2_aarch64=y
|
||||
BR2_cortex_a72=y
|
||||
BR2_ARM_FPU_VFPV4=y
|
||||
BR2_TOOLCHAIN_BUILDROOT_MUSL=y
|
||||
BR2_KERNEL_HEADERS_5_10=y
|
||||
BR2_TOOLCHAIN_BUILDROOT_CXX=y
|
||||
BR2_INIT_NONE=y
|
||||
# BR2_TARGET_GENERIC_GETTY is not set
|
||||
# BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set
|
||||
BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_jenkinsagent_PATH)/initramfs/overlay"
|
||||
BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_jenkinsagent_PATH)/initramfs/busybox.config"
|
||||
BR2_PACKAGE_RPI_FIRMWARE=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI4=y
|
||||
BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE="board/raspberrypi4-64/config_4_64bit.txt"
|
||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||
BR2_PACKAGE_NBD=y
|
||||
BR2_TARGET_ROOTFS_CPIO=y
|
||||
BR2_TARGET_ROOTFS_CPIO_LZ4=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
||||
BR2_PACKAGE_HOST_KMOD=y
|
||||
BR2_PACKAGE_HOST_UTIL_LINUX=y
|
|
@ -0,0 +1,2 @@
|
|||
name: jenkinsagent
|
||||
desc: Jenkins Worker Agent OS
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,40 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
# shellcheck disable=SC2046
|
||||
set -- $(cat /proc/cmdline)
|
||||
while [ $# -ge 1 ]; do
|
||||
case "$1" in
|
||||
root=nbd:*)
|
||||
arg=${1#*:}
|
||||
name=${arg#*:}
|
||||
host=${arg%:*}
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
mkdir -p /proc /run /sys
|
||||
mount -t sysfs sysfs /sys
|
||||
mount -t proc proc /proc
|
||||
mount -t tmpfs tmpfs /run
|
||||
|
||||
for path in /sys/class/net/*; do
|
||||
[ -e "${path}" ] || continue
|
||||
ip link set "${path##*/}" up
|
||||
done
|
||||
sleep 5
|
||||
udhcpc -q
|
||||
|
||||
@bd-client -N "${name}" -R -p "${host}" /dev/nbd0
|
||||
mkdir -p /sysroot
|
||||
mount -o ro -t squashfs /dev/nbd0 /sysroot || nbd-client -c /dev/nbd0
|
||||
|
||||
cd /sysroot
|
||||
mount --move /proc /sysroot/proc
|
||||
mount --move /sys /sysroot/sys
|
||||
mount --move /dev /sysroot/dev
|
||||
mount --move /run /sysroot/run
|
||||
|
||||
exec switch_root /sysroot /lib/systemd/systemd
|
|
@ -0,0 +1 @@
|
|||
nbd-client
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh
|
||||
|
||||
|
||||
case "$1" in
|
||||
deconfig|nak)
|
||||
;;
|
||||
renew|bound)
|
||||
if [ -n "${ip}" ]; then
|
||||
# shellcheck disable=SC2154 # interface is is an environment variable
|
||||
ip addr add "${ip}"/"${mask:-32}" dev "${interface}"
|
||||
fi
|
||||
if [ -n "${staticroutes}" ]; then
|
||||
# shellcheck disable=SC2086 # we WANT word splitting here!
|
||||
set -- ${staticroutes}
|
||||
ip route add "$1" via "$2" dev "${interface}"
|
||||
elif [ -n "${router}" ]; then
|
||||
for gw in ${router}; do
|
||||
ip route add default via "${gw}" dev "${interface}"
|
||||
done
|
||||
fi
|
||||
: > /etc/resolv.conf
|
||||
if [ -n "${search}" ]; then
|
||||
printf 'search %s\n' "${search}" >> /etc/resolv.conf
|
||||
elif [ -n "${domain}" ]; then
|
||||
printf 'search %s\n' "${domain}" >> /etc/resolv.conf
|
||||
fi
|
||||
if [ -n "${dns}" ]; then
|
||||
for ns in ${dns}; do
|
||||
printf 'nameserver %s\n' "${ns}" >> /etc/resolv.conf
|
||||
done
|
||||
fi
|
||||
;;
|
||||
esac
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
|||
# A sample configuration for dhcpcd.
|
||||
# See dhcpcd.conf(5) for details.
|
||||
|
||||
# Allow users of this group to interact with dhcpcd via the control socket.
|
||||
#controlgroup wheel
|
||||
|
||||
# Inform the DHCP server of our hostname for DDNS.
|
||||
#hostname
|
||||
|
||||
# Use the hardware address of the interface for the Client ID.
|
||||
clientid
|
||||
# or
|
||||
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
|
||||
# Some non-RFC compliant DHCP servers do not reply with this set.
|
||||
# In this case, comment out duid and enable clientid above.
|
||||
#duid
|
||||
|
||||
# Persist interface configuration when dhcpcd exits.
|
||||
persistent
|
||||
|
||||
# vendorclassid is set to blank to avoid sending the default of
|
||||
# dhcpcd-<version>:<os>:<machine>:<platform>
|
||||
vendorclassid
|
||||
|
||||
# A list of options to request from the DHCP server.
|
||||
option domain_name_servers, domain_name, domain_search
|
||||
option classless_static_routes
|
||||
# Respect the network MTU. This is applied to DHCP routes.
|
||||
option interface_mtu
|
||||
|
||||
# Request a hostname from the network
|
||||
option host_name
|
||||
|
||||
# Most distributions have NTP support.
|
||||
#option ntp_servers
|
||||
|
||||
# Rapid commit support.
|
||||
# Safe to enable by default because it requires the equivalent option set
|
||||
# on the server to actually work.
|
||||
option rapid_commit
|
||||
|
||||
# A ServerID is required by RFC2131.
|
||||
require dhcp_server_identifier
|
||||
|
||||
# Generate SLAAC address using the Hardware Address of the interface
|
||||
#slaac hwaddr
|
||||
# OR generate Stable Private IPv6 Addresses based from the DUID
|
||||
slaac private
|
||||
|
||||
denyinterfaces dummy*
|
|
@ -0,0 +1,5 @@
|
|||
tmpfs /var tmpfs mode=0755,noexec,nosuid,nodev 0 0
|
||||
tmpfs /root tmpfs size=1M,mode=550 0 0
|
||||
/dev/mmcblk0 /run/storage ext4 ro,noexec,nosuid,nodev 0 2
|
||||
overlay /etc/ssh overlay ro,lowerdir=/etc/ssh:/run/storage/ssh,noexec,nodev,nosuid,x-systemd.requires-mounts-for=/run/storage 0 0
|
||||
/run/storage/docker/key.json /etc/docker/key.json none bind 0 0
|
|
@ -0,0 +1,6 @@
|
|||
global(workDirectory="/var/lib/rsyslog")
|
||||
module(load="imjournal"
|
||||
StateFile="imjournal.state")
|
||||
|
||||
include(file="/etc/rsyslog.d/*.conf" mode="optional")
|
||||
include(file="/run/rsyslog.d/*.conf" mode="optional")
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Copy /var contents to writable storage
|
||||
DefaultDependencies=no
|
||||
After=var.mount
|
||||
Before=local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/libexec/copy-var.sh
|
|
@ -0,0 +1,2 @@
|
|||
[Unit]
|
||||
Before=network-online.target
|
|
@ -0,0 +1,2 @@
|
|||
[Service]
|
||||
PIDFile=/run/dhcpcd/pid
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Fetch SSH authorized_keys for %I
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/libexec/fetch-sshkeys.sh
|
||||
User=%I
|
|
@ -0,0 +1,7 @@
|
|||
[Unit]
|
||||
Description=Generate rsyslog.conf
|
||||
Before=rsyslog.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/libexec/gen-rsyslog-conf.sh
|
|
@ -0,0 +1,19 @@
|
|||
[Unit]
|
||||
Description=htop process viewer
|
||||
Conflicts=gtty@tty1.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/htop --readonly
|
||||
TTYPath=/dev/tty1
|
||||
StandardInput=tty
|
||||
StandardOutput=tty
|
||||
StandardError=journal
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
PrivateTmp=true
|
||||
#PrivateDevices=true
|
||||
PrivateNetwork=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
CapabilityBoundingSet=
|
||||
NoNewPrivileges=true
|
|
@ -0,0 +1 @@
|
|||
../copy-var.service
|
|
@ -0,0 +1 @@
|
|||
../fetch-sshkeys@.service
|
|
@ -0,0 +1 @@
|
|||
../htop.service
|
|
@ -0,0 +1 @@
|
|||
../gen-rsyslog-conf.service
|
|
@ -0,0 +1 @@
|
|||
d /run/rsyslog.d 0755 root root -
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cleanup() {
|
||||
if [ -n "${tmpdir}" ] && [ -d "${tmpdir}" ] && [ / != "${tmpdir}" ]; then
|
||||
if mountpoint -q "${tmpdir}"; then
|
||||
umount "${tmpdir}"
|
||||
fi
|
||||
rm -rf "${tmpdir}"
|
||||
fi
|
||||
unset tmpdir
|
||||
}
|
||||
|
||||
tmpdir=$(TMPDIR=/run mktemp -d)
|
||||
trap cleanup INT QUIT TERM EXIT
|
||||
|
||||
mount -o bind / "${tmpdir}"
|
||||
cp -a "${tmpdir}"/var/. /var/
|
||||
|
||||
if [ -x "$(command -v selinuxenabled)" ] && selinuxenabled; then
|
||||
restorecon -RF /var
|
||||
fi
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
umask 0077
|
||||
mkdir -p ~/.ssh
|
||||
: > ~/.ssh/authorized_keys
|
||||
|
||||
fetch_keys() {
|
||||
curl -fsSL "${1}" >> ~/.ssh/authorized_keys
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2046
|
||||
set -- $(cat /proc/cmdline)
|
||||
while [ $# -ge 1 ]; do
|
||||
case "$1" in
|
||||
sshkeys.*=*)
|
||||
arg=${1#*.}
|
||||
user=${arg%=*}
|
||||
url=${arg#*=}
|
||||
if [ "${user}" = "${USER}" ]; then
|
||||
fetch_keys "${url}"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ -x "$(command -v selinuxenabled)" ] && selinuxenabled; then
|
||||
restorecon -RF ~/.ssh
|
||||
fi
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# shellcheck disable=SC2046
|
||||
set -- $(cat /proc/cmdline)
|
||||
while [ $# -ge 1 ]; do
|
||||
case "$1" in
|
||||
rsyslog.dest=*)
|
||||
printf '*.* @%s\n' "${1#*=}" >> /run/rsyslog.d/remote.conf
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
"${HOST_DIR}"/bin/systemctl --root="${TARGET_DIR}" disable \
|
||||
cups-lpd.socket \
|
||||
cups.service \
|
||||
cups.socket \
|
||||
systemd-networkd.service \
|
||||
systemd-resolved.service \
|
||||
--
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC2154
|
||||
cp -v "${BR2_EXTERNAL_jenkinsagent_PATH}"/cmdline.txt \
|
||||
"${BINARIES_DIR}"/rpi-firmware/cmdline.txt
|
Reference in New Issue