diff --git a/bastion/src/bastion/src/templates/asahi-firstboot.sh.ts b/bastion/src/bastion/src/templates/asahi-firstboot.sh.ts index cbc1062..1f3d00b 100644 --- a/bastion/src/bastion/src/templates/asahi-firstboot.sh.ts +++ b/bastion/src/bastion/src/templates/asahi-firstboot.sh.ts @@ -111,6 +111,29 @@ mount_lv() { fi } +# ── Write fstab function (idempotent) ──────────────────────────── +write_lab_fstab() { + # Remove any previous lab LVM entries (clean slate) + sed -i '/# lab-lvm:/d' /etc/fstab + sed -i '/# Lab LVM volumes/d' /etc/fstab + grep -v "/dev/labvg/" /etc/fstab > /etc/fstab.tmp && mv /etc/fstab.tmp /etc/fstab + # Comment out non-LVM entries for mount points we manage + for mp in "/var " "/var/log " "/home " "/srv "; do + if grep -q "$mp" /etc/fstab; then + awk -v m="$mp" '{if($0 !~ /^#/ && index($0,m)) print "# lab-lvm: " $0; else print}' /etc/fstab > /etc/fstab.tmp + mv /etc/fstab.tmp /etc/fstab + fi + done + # Add fresh LVM entries + echo "# Lab LVM volumes" >> /etc/fstab + echo "/dev/labvg/swap none swap defaults 0 0" >> /etc/fstab + echo "/dev/labvg/var /var xfs defaults 0 0" >> /etc/fstab + echo "/dev/labvg/varlog /var/log xfs defaults 0 0" >> /etc/fstab + echo "/dev/labvg/home /home xfs defaults 0 0" >> /etc/fstab + echo "/dev/labvg/srv /srv xfs defaults 0 0" >> /etc/fstab + ${roleFstabLines.join('\n ')} +} + # ── Check for existing VG ──────────────────────────────────────── if vgs labvg &>/dev/null; then echo "Volume group 'labvg' already exists — reprovision detected." @@ -129,16 +152,8 @@ ${roleMountLines.map(l => ` ${l}`).join('\n')} echo " Enabled swap" fi - # Ensure fstab entries exist - grep -q "labvg" /etc/fstab || { - echo "# Lab LVM volumes (re-added after reprovision)" >> /etc/fstab - echo "/dev/labvg/swap none swap defaults 0 0" >> /etc/fstab - echo "/dev/labvg/var /var xfs defaults 0 0" >> /etc/fstab - echo "/dev/labvg/varlog /var/log xfs defaults 0 0" >> /etc/fstab - echo "/dev/labvg/home /home xfs defaults 0 0" >> /etc/fstab - echo "/dev/labvg/srv /srv xfs defaults 0 0" >> /etc/fstab -${roleFstabLines.map(l => ` ${l}`).join('\n')} - } + # Ensure fstab entries exist — comment out conflicting btrfs subvol entries + write_lab_fstab echo "Existing LVM volumes re-mounted." else @@ -207,15 +222,7 @@ echo "NOTE: /var and /var/log will switch to LVM on next reboot." # Enable swap swapon /dev/labvg/swap 2>/dev/null || true -# Write fstab entries -echo "" >> /etc/fstab -echo "# Lab LVM volumes" >> /etc/fstab -echo "/dev/labvg/swap none swap defaults 0 0" >> /etc/fstab -echo "/dev/labvg/var /var xfs defaults 0 0" >> /etc/fstab -echo "/dev/labvg/varlog /var/log xfs defaults 0 0" >> /etc/fstab -echo "/dev/labvg/home /home xfs defaults 0 0" >> /etc/fstab -echo "/dev/labvg/srv /srv xfs defaults 0 0" >> /etc/fstab -${roleFstabLines.join('\n')} +write_lab_fstab echo "LVM setup complete." lvs labvg @@ -256,8 +263,8 @@ ${rootSshKeyBlock} chmod 600 /root/.ssh/authorized_keys # ── Harden SSH (takes effect on next sshd restart/reboot) ──────── -sed -i 's/^#\\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config -sed -i 's/^#\\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config +sed -i 's/^#*PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config +sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config # ── Write provisioning metadata ────────────────────────────────── cat > /etc/lab-provisioned << LABMETA diff --git a/bastion/src/modules/modules/k3s/src/operations/iscsi.ts b/bastion/src/modules/modules/k3s/src/operations/iscsi.ts index 50e137a..7b5f38c 100644 --- a/bastion/src/modules/modules/k3s/src/operations/iscsi.ts +++ b/bastion/src/modules/modules/k3s/src/operations/iscsi.ts @@ -17,7 +17,7 @@ export const enableIscsi: Operation = async (ctx): Promise => { const isFedora = osLower.includes("fedora") || osLower.includes("rhel") || osLower.includes("centos"); const pkg = isFedora ? "iscsi-initiator-utils" : "open-iscsi"; - const installCmd = isFedora ? `dnf install -y ${pkg}` : `apt-get install -y ${pkg}`; + const installCmd = isFedora ? `sudo dnf install -y ${pkg}` : `sudo apt-get install -y ${pkg}`; const install = await ctx.ssh.exec(installCmd, { timeoutMs: 120_000 }); if (install.exitCode !== 0) { @@ -25,7 +25,7 @@ export const enableIscsi: Operation = async (ctx): Promise => { } // Enable and start - await ctx.ssh.exec("systemctl enable --now iscsid", sshOpts(ctx)); + await ctx.ssh.exec("sudo systemctl enable --now iscsid", sshOpts(ctx)); return { success: true, changed: true, message: `Installed ${pkg} and enabled iscsid` }; }; diff --git a/bastion/src/modules/modules/k3s/src/operations/k3s-config.ts b/bastion/src/modules/modules/k3s/src/operations/k3s-config.ts index 57cec6b..be43c60 100644 --- a/bastion/src/modules/modules/k3s/src/operations/k3s-config.ts +++ b/bastion/src/modules/modules/k3s/src/operations/k3s-config.ts @@ -9,8 +9,9 @@ function isServerRole(role: string): boolean { function generateServerConfig(config: K3sConfig): string { const tlsSans = [config.hostname, config.ip, ...(config.tlsSans ?? [])]; + const serverLine = config.k3sServerUrl ? `server: "${config.k3sServerUrl}"\ntoken: "${config.k3sToken}"\n` : ""; return `# k3s server configuration — CIS hardened -protect-kernel-defaults: true +${serverLine}protect-kernel-defaults: true secrets-encryption: true write-kubeconfig-mode: "0640" diff --git a/bastion/src/modules/modules/k3s/src/operations/k3s-install.ts b/bastion/src/modules/modules/k3s/src/operations/k3s-install.ts index 1f74da5..c2bb6e9 100644 --- a/bastion/src/modules/modules/k3s/src/operations/k3s-install.ts +++ b/bastion/src/modules/modules/k3s/src/operations/k3s-install.ts @@ -15,8 +15,12 @@ export const installK3sBinary: Operation = async (ctx): Promise const alreadyInstalled = version.exitCode === 0; if (isServer) { + // If joining an existing cluster, pass K3S_URL and K3S_TOKEN + const joinEnv = ctx.config.k3sServerUrl && ctx.config.k3sToken + ? `K3S_URL="${ctx.config.k3sServerUrl}" K3S_TOKEN="${ctx.config.k3sToken}"` + : ""; const result = await ctx.ssh.exec( - 'curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server" INSTALL_K3S_SKIP_SELINUX_RPM=true sh -', + `curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server" INSTALL_K3S_SKIP_SELINUX_RPM=true ${joinEnv} sh -`, { timeoutMs: 300_000 }, ); if (result.exitCode !== 0) {