PXEless

repository·develop·Indexed 41 days ago

https://github.com/cloudymax/pxeless

An automated tool for creating customized Ubuntu auto-install ISOs. PXEless enables cloud-native infrastructure management on-premise by leveraging cloud-init and Ubuntu's Subiquity installer to provision machines without a PXE server.

Tokens
2.2K
Snippets
3
Records
6
Agent score
0%

What's inside PXEless

  1. What is PXEless?

    develop

    PXEless is an automated system installation and image-creation tool designed for environments where PXE (Preboot Execution Environment) provisioning is unavailable. It generates customized Ubuntu auto-install ISOs by leveraging cloud-init and Ubuntu's Subiquity installer (which wraps Curtin).

    The tool follows these steps:

    1. Downloads a chosen Ubuntu ISO (daily build or release).
    2. Extracts EFI, MBR, and the File-System.
    3. Injects kernel command line parameters.
    4. Adds customized autoinstall and cloud-init configuration files.
    5. (Optional) Copies arbitrary files to / or runs scripts against the squashfs.
    6. Repacks the data into a new ISO.

    Note on Configuration: The user-data file contains both autoinstall and cloud-init configurations. The user-data key within the file marks the transition from autoinstall syntax to cloud-init syntax.

  2. Quickstart: Run PXEless using Docker

    develop

    It is recommended to run PXEless in a Docker container because it relies on Linux-only packages.

    1. Setup

    Clone the repository and enter the directory:

    git clone https://github.com/cloudymax/pxeless.git
    cd pxeless

    2. Basic Usage

    To generate an ISO with baked-in user-data using a specific Ubuntu code name (e.g., jammy) and a release ISO:

    docker run --rm --volume "$(pwd):/data" \
      --user $(id -u):$(id -g) deserializeme/pxeless \
      --all-in-one  \
      --user-data user-data.basic \
      --code-name jammy \
      --use-release-iso 

    3. Adding Extra Files

    To include static files in the ISO, use the --extra-files flag. When running in Docker, files in your local directory must be mapped to /data/ via a volume. The contents of the specified folder will be copied to the /media directory of the resulting image's filesystem.

    Warning: Using --extra-files requires root access (or the --privileged flag in Docker) to chroot the squashfs.

    docker run --rm --volume "$(pwd):/data" deserializeme/pxeless \
      --all-in-one \
      --user-data user-data.basic \
      --code-name jammy \
      --use-release-iso \
      --extra-files /data/extras

    4. Offline Installation (Customization Scripts)

    To run a bash script to customize the image during the build process (e.g., installing packages), place the script in your extras directory and pass it using the --offline-installer flag.

    docker run --rm --volume "$(pwd):/data" deserializeme/pxeless \
      --all-in-one \
      --user-data user-data.basic \
      --code-name jammy \
      --use-release-iso \
      --extra-files /data/extras \
      --offline-installer installer-sample.sh
  3. Test your ISO with QEMU

    develop

    You can verify your generated PXEless ISO by running it in a QEMU virtual machine. This requires a VNC client (like TigerVNC or Remmina) and several system packages.

    Prerequisites

    Install the necessary packages on your host:

    sudo apt-get install -y qemu-kvm bridge-utils virtinst ovmf qemu-utils cloud-image-utils ubuntu-drivers-common whois git guestfs-tools

    Setup Steps

    1. Clone the repository: Perform a fresh clone of the pxeless repo.
    2. Generate the ISO: Use Docker to create the ISO. Replace user-data.basic with your actual user-data file and jammy with your target release.
      docker run --rm --volume "$(pwd):/data" --user $(id -u):$(id -g) deserializeme/pxeless -a -u user-data.basic -n jammy
    3. Create a virtual disk: Create a 8GB qcow2 disk for the VM.
      qemu-img create -f qcow2 hdd.img 8G
    4. Launch the VM: Run the qemu-system-x86_64 command.

    Note on customization:

    • Replace the host IP (192.168.50.100) in the -vnc flag with your own.
    • Update the -cdrom path to point to your generated ISO.
    • The example uses -netdev user,id=network0,hostfwd=tcp::1234-:22 which forwards SSH from port 1234 on your host to port 22 in the VM.

    Running the Installation

    1. Start the VM and select "Try or install Ubuntu" from the GRUB menu.
    2. Use a VNC client to connect to the VM to monitor the GRUB process and installation progress.
    3. Once the installation completes and the VM reboots, select "Boot from next volume" in GRUB to boot from the newly installed disk instead of the ISO.
    4. Log in using the credentials defined in your user-data (the example uses vmadmin / password).
    5. Access the machine via SSH using the forwarded port (e.g., ssh vmadmin@localhost -p 1234).
    # 1. Create ISO
    docker run --rm --volume "$(pwd):/data" --user $(id -u):$(id -g) deserializeme/pxeless -a -u user-data.basic -n jammy
    
    # 2. Create disk
    qemu-img create -f qcow2 hdd.img 8G
    
    # 3. Run VM
    sudo qemu-system-x86_64 -machine accel=kvm,type=q35 \
    -cpu host,kvm=off,hv_vendor_id=null \
    -smp 2,sockets=1,cores=1,threads=2,maxcpus=2 \
    -m 2G \
    -cdrom /path/to/your/ubuntu-autoinstall.iso \
    -object iothread,id=io1 \
    -device virtio-blk-pci,drive=disk0,iothread=io1 \
    -drive if=none,id=disk0,cache=none,format=qcow2,aio=threads,file=hdd.img \
    -netdev user,id=network0,hostfwd=tcp::1234-:22 \
    -device virtio-net-pci,netdev=network0 \
    -serial stdio -vga virtio -parallel none \
    -bios /usr/share/ovmf/OVMF.fd \
    -usbdevice tablet \
    -vnc YOUR_HOST_IP:0
  4. Write the generated ISO to a USB drive

    develop

    Once the ISO is generated, you can write it to a physical USB drive.

    On Linux

    Use the dd command. Caution: Ensure you identify the correct disk name to avoid overwriting other drives.

    # /dev/sdb is assumed for the sake of the example
    
    export IMAGE_FILE="ubuntu-autoinstall.iso"
    
    # Identify your disk
    sudo fdisk -l | grep "Disk /dev/"
    
    # Set the target disk (e.g., /dev/sdb)
    export DISK_NAME="/dev/sdb"
    
    # Unmount the disk before writing
    sudo umount "$DISK_NAME"
    
    # Write the image
    sudo dd bs=4M if=$IMAGE_FILE of="$DISK_NAME" status=progress oflag=sync

    On MacOS

    It is recommended to use Etcher.

    export IMAGE_FILE="ubuntu-autoinstall.iso"
    export DISK_NAME="/dev/sdb"
    
    sudo umount "$DISK_NAME"
    sudo dd bs=4M if=$IMAGE_FILE of="$DISK_NAME" status=progress oflag=sync
  5. Troubleshoot PXEless installation issues

    develop

    If your installation does not behave as expected, check for these common causes:

    • Improperly formatted YAML: Ensure your user-data file is valid YAML. Errors here often cause the installation to fail or behave unexpectedly.
    • ISO Burning Errors: If you are using a physical USB drive, errors during the burning process can lead to a partial installation.

    Symptom of failure: If the machine performs a partial install, the login prompt will display ubuntu login: instead of the expected pxeless login: (where pxeless is the hostname defined in your configuration).

  6. Reference: PXEless Command-line Options

    develop

    The following flags are available for the PXEless CLI tool:

    ShortLongDescription
    -h--helpPrint this help and exit
    -v--verbosePrint script debug info
    -n--code-nameThe Code Name of the Ubuntu release to download (bionic, focal, jammy etc...)
    -a--all-in-oneBake user-data and meta-data into the generated ISO. Requires --user-data
    -e--use-hwe-kernelForce the generated ISO to boot using the hardware enablement (HWE) kernel
    -u--user-dataPath to user-data file. Required if using -a
    -m--meta-dataPath to meta-data file. Will be an empty file if not specified
    -x--extra-filesSpecifies a folder with files/folders to be copied into the root of the iso image. Requires --privileged in Docker
    -k--no-verifyDisable GPG verification of the source ISO file
    -o--offline-installerRun a bash script to customize image (must be in the same directory as --extra-files)
    -r--use-release-isoUse the current release ISO instead of the daily ISO
    -s--sourceSource ISO file. Defaults to the latest daily Ubuntu 20.04 ISO
    -t--timeoutSet the GRUB timeout. Defaults to 30
    -d--destinationDestination ISO file. Defaults to script directory/ubuntu-autoinstall-current date.iso