scripts
This commit is contained in:
257
build-image.sh
Executable file
257
build-image.sh
Executable file
@@ -0,0 +1,257 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Netboot image builder for diskless K3s nodes
|
||||||
|
# Builds Ubuntu Noble base system with SquashFS
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BUILD_DIR="/srv/netboot/build"
|
||||||
|
IMAGE_DIR="/srv/netboot/images"
|
||||||
|
HTTP_DIR="/srv/netboot/http"
|
||||||
|
VERSION=$(date +%Y%m%d-%H%M)
|
||||||
|
|
||||||
|
echo "Building netboot image version $VERSION"
|
||||||
|
|
||||||
|
# Clean previous build - unmount any stray mounts first
|
||||||
|
if [ -d "$BUILD_DIR/rootfs" ]; then
|
||||||
|
echo "Cleaning up previous build mounts..."
|
||||||
|
mount | grep "$BUILD_DIR/rootfs" | awk '{print $3}' | while read mount; do
|
||||||
|
umount -l "$mount" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf $BUILD_DIR/rootfs
|
||||||
|
mkdir -p $BUILD_DIR/rootfs
|
||||||
|
|
||||||
|
# Create base Ubuntu system
|
||||||
|
echo "Running debootstrap (this will take several minutes)..."
|
||||||
|
debootstrap --arch=amd64 --variant=minbase --components=main,universe,multiverse \
|
||||||
|
noble $BUILD_DIR/rootfs \
|
||||||
|
http://archive.ubuntu.com/ubuntu
|
||||||
|
|
||||||
|
# Chroot and configure
|
||||||
|
cat << 'CHROOT_SCRIPT' > $BUILD_DIR/rootfs/setup.sh
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Set keyboard layout and encoding to Norwegian UTF-8 (non-interactive)
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
export DEBCONF_NONINTERACTIVE_SEEN=true
|
||||||
|
echo "keyboard-configuration keyboard-configuration/layout select Norwegian" | debconf-set-selections
|
||||||
|
echo "keyboard-configuration keyboard-configuration/variant select Norwegian" | debconf-set-selections
|
||||||
|
echo "locales locales/default_environment_locale select en_US.UTF-8" | debconf-set-selections
|
||||||
|
echo "locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8, nb_NO.UTF-8 UTF-8" | debconf-set-selections
|
||||||
|
|
||||||
|
# Update and upgrade
|
||||||
|
apt-get update
|
||||||
|
apt-get upgrade -y
|
||||||
|
|
||||||
|
# Install essential packages
|
||||||
|
apt-get install -y \
|
||||||
|
linux-image-generic \
|
||||||
|
linux-firmware \
|
||||||
|
cloud-initramfs-rooturl \
|
||||||
|
busybox-initramfs \
|
||||||
|
initramfs-tools \
|
||||||
|
keyboard-configuration \
|
||||||
|
systemd \
|
||||||
|
systemd-sysv \
|
||||||
|
dbus \
|
||||||
|
udev \
|
||||||
|
kmod \
|
||||||
|
iproute2 \
|
||||||
|
iputils-ping \
|
||||||
|
netplan.io \
|
||||||
|
openssh-server \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
ca-certificates \
|
||||||
|
gnupg \
|
||||||
|
sudo \
|
||||||
|
locales
|
||||||
|
|
||||||
|
# K3s prerequisites
|
||||||
|
apt-get install -y \
|
||||||
|
apparmor \
|
||||||
|
apparmor-utils \
|
||||||
|
iptables \
|
||||||
|
nftables \
|
||||||
|
conntrack \
|
||||||
|
socat \
|
||||||
|
ethtool \
|
||||||
|
nfs-common
|
||||||
|
|
||||||
|
# Container runtime prerequisites
|
||||||
|
apt-get install -y \
|
||||||
|
containerd \
|
||||||
|
runc
|
||||||
|
|
||||||
|
# Useful tools
|
||||||
|
apt-get install -y \
|
||||||
|
htop \
|
||||||
|
iotop \
|
||||||
|
vim \
|
||||||
|
less \
|
||||||
|
rsync \
|
||||||
|
git
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
apt-get clean
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
rm -rf /tmp/*
|
||||||
|
rm -rf /var/tmp/*
|
||||||
|
|
||||||
|
# Configure hostname (will be overridden by netplan)
|
||||||
|
echo "k3s-node" > /etc/hostname
|
||||||
|
|
||||||
|
# Configure network with netplan
|
||||||
|
cat > /etc/netplan/01-netcfg.yaml <<EOF
|
||||||
|
network:
|
||||||
|
version: 2
|
||||||
|
renderer: networkd
|
||||||
|
ethernets:
|
||||||
|
all-en:
|
||||||
|
match:
|
||||||
|
name: en*
|
||||||
|
dhcp4: true
|
||||||
|
dhcp6: false
|
||||||
|
dhcp4-overrides:
|
||||||
|
use-hostname: true
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Enable systemd-networkd
|
||||||
|
systemctl enable systemd-networkd
|
||||||
|
systemctl enable systemd-resolved
|
||||||
|
|
||||||
|
# Configure SSH
|
||||||
|
sed -i 's/#PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
|
||||||
|
sed -i 's/#PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
|
||||||
|
systemctl enable ssh
|
||||||
|
|
||||||
|
# Create SSH directory for root
|
||||||
|
mkdir -p /root/.ssh
|
||||||
|
chmod 700 /root/.ssh
|
||||||
|
|
||||||
|
# Add your SSH public key here
|
||||||
|
cat >> /root/.ssh/authorized_keys <<SSHKEY
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMuTf8duvWFhU3CTlLFqr1+EeszA1Cu4e5Q07A9xKy1J lindahl@lindahl-Legion-5-Pro-16ACH6H
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILpyobN2sYtxnFFZCvl1nNK4MLc9oVTKgGhkgHy2u0tX lindahl@phoenix.home
|
||||||
|
SSHKEY
|
||||||
|
|
||||||
|
chmod 600 /root/.ssh/authorized_keys
|
||||||
|
|
||||||
|
# Disable password authentication completely
|
||||||
|
echo "root:*" | chpasswd -e
|
||||||
|
|
||||||
|
# Configure tmpfs mounts for ephemeral data
|
||||||
|
cat >> /etc/fstab <<FSTAB
|
||||||
|
# Ephemeral filesystems (RAM-based)
|
||||||
|
tmpfs /tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777,size=2G 0 0
|
||||||
|
tmpfs /var/tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777,size=1G 0 0
|
||||||
|
tmpfs /var/log tmpfs defaults,noatime,nosuid,nodev,noexec,mode=0755,size=1G 0 0
|
||||||
|
tmpfs /run tmpfs defaults,noatime,nosuid,nodev,noexec,mode=0755,size=512M 0 0
|
||||||
|
FSTAB
|
||||||
|
|
||||||
|
# Configure journald to use tmpfs
|
||||||
|
mkdir -p /etc/systemd/journald.conf.d
|
||||||
|
cat > /etc/systemd/journald.conf.d/tmpfs.conf <<JOURNAL
|
||||||
|
[Journal]
|
||||||
|
Storage=volatile
|
||||||
|
RuntimeMaxUse=256M
|
||||||
|
JOURNAL
|
||||||
|
|
||||||
|
# Configure systemd to not wait for network
|
||||||
|
systemctl disable systemd-networkd-wait-online.service
|
||||||
|
|
||||||
|
# Disable unnecessary services
|
||||||
|
systemctl disable apt-daily.timer
|
||||||
|
systemctl disable apt-daily-upgrade.timer
|
||||||
|
systemctl disable motd-news.timer
|
||||||
|
|
||||||
|
# Set timezone
|
||||||
|
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
||||||
|
|
||||||
|
# Generate locales
|
||||||
|
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
|
||||||
|
locale-gen
|
||||||
|
|
||||||
|
# Build initramfs will be done outside the chroot after mount cleanup
|
||||||
|
echo "Initramfs build will be done after chroot cleanup"
|
||||||
|
|
||||||
|
CHROOT_SCRIPT
|
||||||
|
|
||||||
|
# Make script executable and run in chroot with proper mounts
|
||||||
|
chmod +x $BUILD_DIR/rootfs/setup.sh
|
||||||
|
|
||||||
|
# Mount required filesystems for DKMS compilation
|
||||||
|
mount -t proc proc $BUILD_DIR/rootfs/proc
|
||||||
|
mount -t sysfs sysfs $BUILD_DIR/rootfs/sys
|
||||||
|
mount -t devtmpfs devtmpfs $BUILD_DIR/rootfs/dev
|
||||||
|
mount -t devpts devpts $BUILD_DIR/rootfs/dev/pts
|
||||||
|
|
||||||
|
# Run setup script in chroot
|
||||||
|
chroot $BUILD_DIR/rootfs /setup.sh
|
||||||
|
|
||||||
|
# Unmount filesystems
|
||||||
|
umount -l $BUILD_DIR/rootfs/dev/pts
|
||||||
|
umount -l $BUILD_DIR/rootfs/dev
|
||||||
|
umount -l $BUILD_DIR/rootfs/sys
|
||||||
|
umount -l $BUILD_DIR/rootfs/proc
|
||||||
|
|
||||||
|
rm $BUILD_DIR/rootfs/setup.sh
|
||||||
|
|
||||||
|
# Build initramfs with dracut using the rootfs modules
|
||||||
|
echo "Building initramfs with dracut using rootfs kernel and modules..."
|
||||||
|
KERNEL_VERSION=$(ls -1 $BUILD_DIR/rootfs/boot/vmlinuz-* | sed 's|.*/vmlinuz-||' | head -1)
|
||||||
|
|
||||||
|
# Mount proc/sys temporarily for dracut if needed
|
||||||
|
mount -t proc proc $BUILD_DIR/rootfs/proc 2>/dev/null || true
|
||||||
|
|
||||||
|
dracut -f \
|
||||||
|
--add "network" \
|
||||||
|
--hostonly \
|
||||||
|
--hostonly-cmdline \
|
||||||
|
--include "/usr/share/initramfs-tools/hooks/rooturl" "/usr/share/initramfs-tools/hooks/" \
|
||||||
|
--include "/usr/share/initramfs-tools/scripts/local-top/rooturl" "/usr/share/initramfs-tools/scripts/local-top/" \
|
||||||
|
-k $KERNEL_VERSION \
|
||||||
|
-r $BUILD_DIR/rootfs \
|
||||||
|
$BUILD_DIR/rootfs/boot/initrd-netboot.img
|
||||||
|
|
||||||
|
umount -l $BUILD_DIR/rootfs/proc 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "Initramfs build complete. Size: $(du -h $BUILD_DIR/rootfs/boot/initrd-netboot.img | cut -f1)"
|
||||||
|
|
||||||
|
# Copy kernel and netboot initramfs
|
||||||
|
mkdir -p $IMAGE_DIR/$VERSION
|
||||||
|
cp $BUILD_DIR/rootfs/boot/vmlinuz-* $IMAGE_DIR/$VERSION/vmlinuz
|
||||||
|
cp $BUILD_DIR/rootfs/boot/initrd-netboot.img $IMAGE_DIR/$VERSION/initrd-netboot.img
|
||||||
|
|
||||||
|
echo "Creating squashfs image..."
|
||||||
|
mksquashfs $BUILD_DIR/rootfs \
|
||||||
|
$IMAGE_DIR/$VERSION/filesystem.squashfs \
|
||||||
|
-comp xz \
|
||||||
|
-Xbcj x86 \
|
||||||
|
-b 1M \
|
||||||
|
-noappend \
|
||||||
|
-no-progress
|
||||||
|
|
||||||
|
# Create version info file
|
||||||
|
cat > $IMAGE_DIR/$VERSION/version.txt <<EOF
|
||||||
|
Build Date: $(date)
|
||||||
|
Ubuntu Version: Noble (24.04)
|
||||||
|
Kernel: $(chroot $BUILD_DIR/rootfs dpkg -l | grep linux-image-generic | awk '{print $3}')
|
||||||
|
Image Size: $(du -h $IMAGE_DIR/$VERSION/filesystem.squashfs | awk '{print $1}')
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Image created successfully: $IMAGE_DIR/$VERSION/"
|
||||||
|
ls -lh $IMAGE_DIR/$VERSION/
|
||||||
|
|
||||||
|
# Create symlink to latest
|
||||||
|
ln -sfn $VERSION $IMAGE_DIR/latest
|
||||||
|
|
||||||
|
# Copy to HTTP directory
|
||||||
|
echo "Deploying to HTTP directory..."
|
||||||
|
rsync -av $IMAGE_DIR/$VERSION/ $HTTP_DIR/
|
||||||
|
ln -sfn $VERSION $HTTP_DIR/latest
|
||||||
|
|
||||||
|
echo "Build complete! Version: $VERSION"
|
||||||
|
echo "Files available at: $HTTP_DIR/"
|
||||||
40
chroot-rootfs.sh
Executable file
40
chroot-rootfs.sh
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Helper script to chroot into the netboot rootfs for testing/tweaking
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ROOTFS="/srv/netboot/build/rootfs"
|
||||||
|
|
||||||
|
if [ ! -d "$ROOTFS" ]; then
|
||||||
|
echo "Error: $ROOTFS does not exist"
|
||||||
|
echo "Run build-image.sh first to create the rootfs"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Function to cleanup mounts on exit
|
||||||
|
cleanup() {
|
||||||
|
echo ""
|
||||||
|
echo "Cleaning up mounts..."
|
||||||
|
umount "$ROOTFS/proc" 2>/dev/null || true
|
||||||
|
umount "$ROOTFS/sys" 2>/dev/null || true
|
||||||
|
umount "$ROOTFS/dev/pts" 2>/dev/null || true
|
||||||
|
umount "$ROOTFS/dev" 2>/dev/null || true
|
||||||
|
echo "Unmounted. You can now rebuild the squashfs image."
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
echo "Mounting filesystems for chroot..."
|
||||||
|
mount -t proc /proc "$ROOTFS/proc"
|
||||||
|
mount -t sysfs /sys "$ROOTFS/sys"
|
||||||
|
mount --bind /dev "$ROOTFS/dev"
|
||||||
|
mount --bind /dev/pts "$ROOTFS/dev/pts"
|
||||||
|
|
||||||
|
echo "Entering chroot environment..."
|
||||||
|
echo "Type 'exit' when done to return and cleanup mounts"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Enter chroot
|
||||||
|
chroot "$ROOTFS" /bin/bash
|
||||||
|
|
||||||
|
# cleanup() will run automatically on exit
|
||||||
56
rebuild-squashfs.sh
Executable file
56
rebuild-squashfs.sh
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Rebuild squashfs image from existing rootfs (after making changes)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BUILD_DIR="/srv/netboot/build"
|
||||||
|
IMAGE_DIR="/srv/netboot/images"
|
||||||
|
HTTP_DIR="/srv/netboot/http"
|
||||||
|
VERSION=$(date +%Y%m%d-%H%M)
|
||||||
|
|
||||||
|
if [ ! -d "$BUILD_DIR/rootfs" ]; then
|
||||||
|
echo "Error: $BUILD_DIR/rootfs does not exist"
|
||||||
|
echo "Run build-image.sh first to create the rootfs"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Rebuilding squashfs image version $VERSION"
|
||||||
|
|
||||||
|
# Copy kernel and initrd
|
||||||
|
mkdir -p $IMAGE_DIR/$VERSION
|
||||||
|
cp $BUILD_DIR/rootfs/boot/vmlinuz-* $IMAGE_DIR/$VERSION/vmlinuz
|
||||||
|
cp $BUILD_DIR/rootfs/boot/initrd.img-* $IMAGE_DIR/$VERSION/initrd.img
|
||||||
|
|
||||||
|
echo "Creating squashfs image..."
|
||||||
|
mksquashfs $BUILD_DIR/rootfs \
|
||||||
|
$IMAGE_DIR/$VERSION/filesystem.squashfs \
|
||||||
|
-comp xz \
|
||||||
|
-Xbcj x86 \
|
||||||
|
-b 1M \
|
||||||
|
-noappend
|
||||||
|
|
||||||
|
# Create version info
|
||||||
|
cat > $IMAGE_DIR/$VERSION/version.txt <<EOF
|
||||||
|
Build Date: $(date)
|
||||||
|
Ubuntu Version: Noble (24.04)
|
||||||
|
Kernel: $(ls $BUILD_DIR/rootfs/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
|
||||||
|
Image Size: $(du -h $IMAGE_DIR/$VERSION/filesystem.squashfs | awk '{print $1}')
|
||||||
|
Rebuilt from modified rootfs
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Image created: $IMAGE_DIR/$VERSION/"
|
||||||
|
ls -lh $IMAGE_DIR/$VERSION/
|
||||||
|
|
||||||
|
# Update latest symlink
|
||||||
|
ln -sfn $VERSION $IMAGE_DIR/latest
|
||||||
|
|
||||||
|
# Deploy to HTTP directory
|
||||||
|
echo "Deploying to HTTP directory..."
|
||||||
|
rsync -av $IMAGE_DIR/$VERSION/ $HTTP_DIR/
|
||||||
|
ln -sfn $VERSION $HTTP_DIR/latest
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Build complete! Version: $VERSION"
|
||||||
|
echo "Files available at: $HTTP_DIR/"
|
||||||
|
echo ""
|
||||||
|
echo "Old versions kept in: $IMAGE_DIR/"
|
||||||
Reference in New Issue
Block a user