Fix Proxmox VM login — force user creation via runcmd
The Arch Linux cloud image ignores Proxmox's --ciuser/--cipassword and the cloud-init chpasswd module depending on version. The previous approach had three conflicting methods fighting each other. Fixed by: - Removed --ciuser/--cipassword from qm set (they conflict with snippet) - Removed chpasswd cloud-init module (unreliable on Arch) - Set users: [] to disable cloud-init's default user module - ALL user setup now done via runcmd (runs as root, always works): - Sets root password to 'darkforge' as fallback - Creates darkforge user via useradd + chpasswd - Grants passwordless sudo via /etc/sudoers.d/ - Enables PermitRootLogin yes as safety net - Package install via explicit pacman commands instead of packages: module (Arch cloud-init packages module can be unreliable) - Added pacman-key --init/--populate before package install Login credentials: user: darkforge password: darkforge user: root password: darkforge (fallback) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -108,8 +108,9 @@ qm set "${VMID}" --scsihw virtio-scsi-single
|
|||||||
echo ">>> Configuring cloud-init..."
|
echo ">>> Configuring cloud-init..."
|
||||||
|
|
||||||
qm set "${VMID}" --ide2 "${STORAGE}:cloudinit"
|
qm set "${VMID}" --ide2 "${STORAGE}:cloudinit"
|
||||||
qm set "${VMID}" --ciuser "darkforge"
|
|
||||||
qm set "${VMID}" --cipassword "darkforge"
|
# Don't use --ciuser/--cipassword — they conflict with the snippet on Arch.
|
||||||
|
# We handle ALL user creation in the cloud-init snippet runcmd instead.
|
||||||
qm set "${VMID}" --ipconfig0 "ip=dhcp"
|
qm set "${VMID}" --ipconfig0 "ip=dhcp"
|
||||||
|
|
||||||
# Enable nested virtualization (for QEMU-in-QEMU boot tests)
|
# Enable nested virtualization (for QEMU-in-QEMU boot tests)
|
||||||
@@ -120,67 +121,64 @@ echo ">>> Resizing disk to ${DISK_SIZE}..."
|
|||||||
qm resize "${VMID}" scsi0 "${DISK_SIZE}" 2>/dev/null || true
|
qm resize "${VMID}" scsi0 "${DISK_SIZE}" 2>/dev/null || true
|
||||||
|
|
||||||
# --- Generate cloud-init user-data snippet -----------------------------------
|
# --- Generate cloud-init user-data snippet -----------------------------------
|
||||||
# This runs on first boot inside the VM
|
# NOTE: The Arch Linux cloud image has quirks with user/password handling.
|
||||||
|
# We do EVERYTHING via runcmd to guarantee it works regardless of cloud-init
|
||||||
|
# version or Proxmox's cloud-init integration behavior.
|
||||||
SNIPPET_DIR="/var/lib/vz/snippets"
|
SNIPPET_DIR="/var/lib/vz/snippets"
|
||||||
mkdir -p "${SNIPPET_DIR}"
|
mkdir -p "${SNIPPET_DIR}"
|
||||||
|
|
||||||
cat > "${SNIPPET_DIR}/darkforge-test-init.yaml" << 'CLOUDINIT'
|
cat > "${SNIPPET_DIR}/darkforge-test-init.yaml" << 'CLOUDINIT'
|
||||||
#cloud-config
|
#cloud-config
|
||||||
|
|
||||||
# Enable SSH password authentication (cloud images disable it by default)
|
# Disable the default user module to avoid conflicts
|
||||||
ssh_pwauth: true
|
# We create our user manually via runcmd below
|
||||||
chpasswd:
|
users: []
|
||||||
expire: false
|
|
||||||
users:
|
ssh_pwauth: true
|
||||||
- name: darkforge
|
|
||||||
password: darkforge
|
|
||||||
type: text
|
|
||||||
|
|
||||||
# Ensure sshd allows password auth
|
|
||||||
write_files:
|
write_files:
|
||||||
- path: /etc/ssh/sshd_config.d/99-darkforge.conf
|
- path: /etc/ssh/sshd_config.d/99-darkforge.conf
|
||||||
content: |
|
content: |
|
||||||
PasswordAuthentication yes
|
PasswordAuthentication yes
|
||||||
PermitRootLogin no
|
PermitRootLogin yes
|
||||||
|
|
||||||
package_update: true
|
|
||||||
packages:
|
|
||||||
- base-devel
|
|
||||||
- git
|
|
||||||
- wget
|
|
||||||
- curl
|
|
||||||
- rust
|
|
||||||
- cargo
|
|
||||||
- qemu-full
|
|
||||||
- edk2-ovmf
|
|
||||||
- squashfs-tools
|
|
||||||
- xorriso
|
|
||||||
- dosfstools
|
|
||||||
- mtools
|
|
||||||
- python
|
|
||||||
- bc
|
|
||||||
- rsync
|
|
||||||
- openssh
|
|
||||||
- tmux
|
|
||||||
|
|
||||||
runcmd:
|
runcmd:
|
||||||
# Restart sshd to pick up the password auth config
|
# --- USER SETUP (do this first, before anything else) ----------------------
|
||||||
|
# Set root password so we always have a fallback login
|
||||||
|
- echo 'root:darkforge' | chpasswd
|
||||||
|
|
||||||
|
# Create the darkforge user if it doesn't exist
|
||||||
|
- id darkforge &>/dev/null || useradd -m -G wheel -s /bin/bash darkforge
|
||||||
|
- echo 'darkforge:darkforge' | chpasswd
|
||||||
|
|
||||||
|
# Give darkforge sudo/wheel access without password
|
||||||
|
- echo 'darkforge ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/darkforge
|
||||||
|
- chmod 440 /etc/sudoers.d/darkforge
|
||||||
|
|
||||||
|
# Enable and restart sshd
|
||||||
|
- systemctl enable sshd
|
||||||
- systemctl restart sshd
|
- systemctl restart sshd
|
||||||
|
|
||||||
# Grow the partition to fill the disk
|
# --- DISK RESIZE -----------------------------------------------------------
|
||||||
- growpart /dev/sda 2 || true
|
- growpart /dev/sda 2 || growpart /dev/vda 2 || true
|
||||||
- resize2fs /dev/sda2 || btrfs filesystem resize max / || true
|
- resize2fs /dev/sda2 || resize2fs /dev/vda2 || btrfs filesystem resize max / || true
|
||||||
|
|
||||||
# Clone the DarkForge project
|
# --- PACKAGE INSTALL -------------------------------------------------------
|
||||||
|
- pacman-key --init
|
||||||
|
- pacman-key --populate archlinux
|
||||||
|
- pacman -Syu --noconfirm
|
||||||
|
- pacman -S --noconfirm --needed base-devel git wget curl rust cargo qemu-full edk2-ovmf squashfs-tools xorriso dosfstools mtools python bc rsync openssh tmux
|
||||||
|
|
||||||
|
# --- CLONE PROJECT ---------------------------------------------------------
|
||||||
- |
|
- |
|
||||||
su - darkforge -c '
|
su - darkforge -c '
|
||||||
cd /home/darkforge
|
cd /home/darkforge
|
||||||
git clone --recurse-submodules https://git.dannyhaslund.dk/danny8632/darkforge.git 2>/dev/null || \
|
git clone --recurse-submodules https://git.dannyhaslund.dk/danny8632/darkforge.git 2>/dev/null || \
|
||||||
git clone --recurse-submodules https://github.com/danny8632/darkforge.git 2>/dev/null || \
|
git clone --recurse-submodules https://github.com/danny8632/darkforge.git 2>/dev/null || \
|
||||||
echo "CLONE FAILED — manually clone the repo"
|
echo "CLONE FAILED — manually clone the repo after login"
|
||||||
'
|
'
|
||||||
|
|
||||||
# Create the darkforge-test convenience command
|
# --- INSTALL CONVENIENCE COMMAND -------------------------------------------
|
||||||
- |
|
- |
|
||||||
cat > /usr/local/bin/darkforge-test << 'DTEOF'
|
cat > /usr/local/bin/darkforge-test << 'DTEOF'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
@@ -197,7 +195,7 @@ runcmd:
|
|||||||
DTEOF
|
DTEOF
|
||||||
chmod +x /usr/local/bin/darkforge-test
|
chmod +x /usr/local/bin/darkforge-test
|
||||||
|
|
||||||
# Signal that provisioning is done
|
# --- SIGNAL DONE -----------------------------------------------------------
|
||||||
- touch /home/darkforge/.provisioned
|
- touch /home/darkforge/.provisioned
|
||||||
- chown darkforge:darkforge /home/darkforge/.provisioned
|
- chown darkforge:darkforge /home/darkforge/.provisioned
|
||||||
CLOUDINIT
|
CLOUDINIT
|
||||||
|
|||||||
Reference in New Issue
Block a user