#!/bin/sh set -eu install_ssh_key() { if [ -z "${ssh_authorized_keys_base64}" ]; then return 0 fi install -d -m 0700 -o ${template_user} -g ${template_user} /home/${template_user}/.ssh printf '%s' '${ssh_authorized_keys_base64}' | base64 -d >/home/${template_user}/.ssh/authorized_keys chown ${template_user}:${template_user} /home/${template_user}/.ssh/authorized_keys chmod 0600 /home/${template_user}/.ssh/authorized_keys } configure_sudo() { printf '%s ALL=(ALL) NOPASSWD:ALL\n' '${template_user}' >/etc/sudoers.d/90-homelab-${template_user} chmod 0440 /etc/sudoers.d/90-homelab-${template_user} } configure_dns() { dns_servers="${node_dns_servers}" if [ -z "$dns_servers" ]; then return 0 fi if systemctl list-unit-files systemd-resolved.service >/dev/null 2>&1; then mkdir -p /etc/systemd/resolved.conf.d { echo "[Resolve]" printf 'DNS=%s\n' "$dns_servers" printf 'FallbackDNS=%s\n' "$dns_servers" echo "DNSSEC=no" } >/etc/systemd/resolved.conf.d/homelab-k8s.conf fi } configure_kubernetes_prereqs() { swapoff -a || true systemctl mask swap.target >/dev/null 2>&1 || true awk ' /^[[:space:]]*#/ { print; next } $3 == "swap" { next } { print } ' /etc/fstab >/etc/fstab.homelab mv /etc/fstab.homelab /etc/fstab printf 'overlay\nbr_netfilter\nip_vs\nip_vs_rr\nip_vs_wrr\nip_vs_sh\nnf_conntrack\n' >/etc/modules-load.d/k8s.conf modprobe overlay || true modprobe br_netfilter || true modprobe ip_vs || true modprobe ip_vs_rr || true modprobe ip_vs_wrr || true modprobe ip_vs_sh || true modprobe nf_conntrack || true cat >/etc/sysctl.d/99-kubernetes-cri.conf <<'SYSCTL' net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 SYSCTL sysctl --system >/dev/null || true } configure_kernel_boot_options() { boot_options="${kernel_cgroup_boot_options}" if [ -z "$boot_options" ] || [ ! -f /etc/default/grub ]; then return 0 fi current_options="$(sed -n 's/^GRUB_CMDLINE_LINUX_DEFAULT=//p' /etc/default/grub | tail -n 1 | sed 's/^"//; s/"$//')" for option in $boot_options; do case " $current_options " in *" $option "*) ;; *) current_options="$current_options $option" ;; esac done current_options="$(printf '%s' "$current_options" | awk '{$1=$1; print}')" escaped_options="$(printf '%s' "$current_options" | sed 's/[\/&]/\\&/g')" if grep -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub; then sed -i "s/^GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"$escaped_options\"/" /etc/default/grub else printf 'GRUB_CMDLINE_LINUX_DEFAULT="%s"\n' "$current_options" >>/etc/default/grub fi if command -v update-grub >/dev/null 2>&1; then update-grub elif command -v grub-mkconfig >/dev/null 2>&1 && [ -d /boot/grub ]; then grub-mkconfig -o /boot/grub/grub.cfg fi } install_kubernetes_tools() { install -d -m 0755 /etc/apt/keyrings curl -fsSL "https://pkgs.k8s.io/core:/stable:/${kubernetes_minor_version}/deb/Release.key" | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg printf 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/${kubernetes_minor_version}/deb/ /\n' >/etc/apt/sources.list.d/kubernetes.list apt-get update apt-get install -y --no-install-recommends kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl } configure_containerd() { mkdir -p /etc/containerd /etc/containerd/certs.d/${registry_endpoint} containerd config default >/etc/containerd/config.toml sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml config_version="$(awk -F= '/^[[:space:]]*version[[:space:]]*=/ { gsub(/[[:space:]]/, "", $2); print $2; exit }' /etc/containerd/config.toml)" if [ "$config_version" = "3" ]; then registry_table='[plugins."io.containerd.cri.v1.images".registry]' else registry_table='[plugins."io.containerd.grpc.v1.cri".registry]' fi awk -v registry_table="$registry_table" ' $0 == registry_table { in_registry = 1; found = 1; print; next } in_registry && /^\[/ { if (!wrote) { print " config_path = \"/etc/containerd/certs.d\"" } in_registry = 0 wrote = 0 } in_registry && /^[[:space:]]*config_path[[:space:]]*=/ { print " config_path = \"/etc/containerd/certs.d\"" wrote = 1 next } { print } END { if (in_registry && !wrote) { print " config_path = \"/etc/containerd/certs.d\"" } if (!found) { print "" print registry_table print " config_path = \"/etc/containerd/certs.d\"" } } ' /etc/containerd/config.toml >/etc/containerd/config.toml.homelab mv /etc/containerd/config.toml.homelab /etc/containerd/config.toml cat >/etc/containerd/certs.d/${registry_endpoint}/hosts.toml <<'HOSTS' server = "http://${registry_endpoint}" [host."http://${registry_endpoint}"] capabilities = ["pull", "resolve", "push"] skip_verify = true HOSTS cat >/etc/crictl.yaml <<'CRICTL' runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false CRICTL } enable_services() { systemctl enable qemu-guest-agent >/dev/null 2>&1 || true systemctl enable containerd >/dev/null 2>&1 || true systemctl enable kubelet >/dev/null 2>&1 || true systemctl enable iscsid >/dev/null 2>&1 || true systemctl enable ssh >/dev/null 2>&1 || true } install_ssh_key configure_sudo configure_dns configure_kubernetes_prereqs configure_kernel_boot_options install_kubernetes_tools configure_containerd enable_services