# nobodd-prep

Customizes an OS image to prepare it for netbooting via TFTP. Specifically, this expands the image to a specified size (the assumption being the image is a copy of a minimally sized template image), then updates the kernel command line on the boot partition to point to an NBD server.

## Synopsis

    usage: nobodd-prep [-h] [--version] [-s SIZE] [--nbd-host HOST]
                       [--nbd-name NAME] [--cmdline NAME]
                       [--boot-partition NUM] [--root-partition NUM]
                       [-C PATH] [-R PATH] image

## Options

image

  The target image to customize

-h, --help

  Show the help message and exit

--version

  Show program’s version number and exit

-s SIZE, --size SIZE

  The size to expand the image to; default: 16GB

--nbd-host HOST

  The hostname of the nbd server to connect to for the root device; defaults to the local machine’s FQDN

--nbd-name NAME

  The name of the nbd share to use as the root device; defaults to the stem of the image name

--cmdline NAME

  The name of the file containing the kernel command line on the boot partition; default: `cmdline.txt`

--boot-partition NUM

  Which partition is the boot partition within the image; default is the first FAT partition (identified by partition type) found in the image

--root-partition NUM

  Which partition is the root partition within the image default is the first non-FAT partition (identified by partition type) found in the image

-C PATH, --copy PATH

  Copy the specified file or directory into the boot partition. This may be given multiple times to specify multiple items to copy

-R PATH, --remove PATH

  Delete the specified file or directory within the boot partition. This may be given multiple times to specify multiple items to delete

--serial HEX

  Defines the serial number of the Raspberry Pi that will be served this image. When this option is given, a board configuration compatible with nobodd-tftpd may be output with `--tftpd-conf`

--tftpd-conf FILE

  If specified, write a board configuration compatible with nobodd-tftpd to the specified file; requires `--serial` to be given. If “-” is given, output is written to stdout.

--nbd-conf FILE

  If specified, write a share configuration compatible with nbd-server(1) to the specified file. If “-” is given, output is written to stdout.

## Usage

Typically nobodd-prep is called with a base OS image. For example, if `ubuntu-24.04-server.img.xz` is the Ubuntu 24.04 Server for Raspberry image, we would decompress it (we can only work on uncompressed images), use the tool to expand it to a reasonable disk size (e.g. 16GB like an SD card), and customize the kernel command line to look for the rootfs on our NBD server:

    $ ls -l ubuntu-24.04-server.img.xz
    -rw-rw-r-- 1 dave dave 1189280360 Oct 12 00:44 ubuntu-24.04-server.img.xz
    $ unxz ubuntu-24.04-server.img.xz
    $ ls -l ubuntu-24.04-server.img
    -rw-rw-r-- 1 dave dave 3727687680 Oct 12 00:44 ubuntu-24.04-server.img
    $ fdisk -l ubuntu-24.04-server.img
    Disk ubuntu-24.04-server.img: 3.47 GiB, 3727687680 bytes, 7280640 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x1634ec00

    Device                   Boot   Start     End Sectors  Size Id Type
    ubuntu-24.04-server.img1 *       2048 1050623 1048576  512M  c W95 FAT32 (LBA)
    ubuntu-24.04-server.img2      1050624 7247259 6196636    3G 83 Linux
    $ mkdir mnt
    $ sudo mount -o loop,offset=$((2048*512)),sizelimit=$((1048576*512)) ubuntu-24.04-server.img mnt/
    [sudo] Password:
    $ cat mnt/cmdline.txt
    console=serial0,115200 multipath=off dwc_otg.lpm_enable=0 console=tty1 root=LABEL=writable rootfstype=ext4 rootwait fixrtc
    $ sudo umount mnt/
    $ nobodd-prep --size 16GB ubuntu-24.04-server.img
    $ ls -l ubuntu-24.04-server.img --nbd-host myserver --nbd-name ubuntu
    -rw-rw-r-- 1 dave dave 17179869184 Feb 27 13:11 ubuntu-24.04-server.img
    $ sudo mount -o loop,offset=$((2048*512)),sizelimit=$((1048576*512)) ubuntu-24.04-server.img mnt/
    [sudo] Password:
    $ cat mnt/cmdline.txt
    ip=dhcp nbdroot=myserver/ubuntu root=/dev/nbd0p2 console=serial0,115200 multipath=off dwc_otg.lpm_enable=0 console=tty1 rootfstype=ext4 rootwait fixrtc
    $ sudo umount mnt/

Note, the only reason we are listing partitions and mounting the boot partition above is to demonstrate the change to the kernel command line in `cmdline.txt`. Ordinarily, usage of nobodd-prep is as simple as:

    $ unxz ubuntu-24.04-server.img.xz
    $ nobodd-prep --size 16GB ubuntu-24.04-server.img

Typically nobodd-prep will detect the boot and root partitions of the image automatically. The boot partition is defined as the first partition that has a FAT partition type (on MBR-partitioned images), or Basic Data or EFI System partition type (on GPT-partitioned images), which contains a valid FAT file-system (the script tries to determine the FAT-type of the contained file-system, and only counts those partitions on which it can determine a valid FAT-type).

The root partition is the exact opposite; it is defined as the first partition that doesn’t have a FAT partition type (on MBR-partitioned images), or Basic Data or EFI System partition type (on GPT-partitioned images), which contains something other than a valid FAT file-system (again, the script tries to determine the FAT-type of the contained file-system, and only counts those partitions on which it cannot determine a valid FAT-type).

There may be images for which these simplistic definitions do not work. For example, images derived from a NOOBS/PINN install may well have several boot partitions for different installed OS’. In this case the boot or root partition (or both) may be specified manually on the command line:

    $ fdisk -l pinn-test.img
    Disk pinn-test.img: 29.72 GiB, 31914983424 bytes, 62333952 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x2e779525

    Device          Boot    Start      End  Sectors  Size Id Type
    pinn-test.img1           8192   137215   129024   63M  e W95 FAT16 (LBA)
    pinn-test.img2         137216 62333951 62196736 29.7G  5 Extended
    pinn-test.img5         139264   204797    65534   32M 83 Linux
    pinn-test.img6         204800   464895   260096  127M  c W95 FAT32 (LBA)
    pinn-test.img7         466944  4661247  4194304    2G 83 Linux
    pinn-test.img8        4669440  5193727   524288  256M 83 Linux
    pinn-test.img9        5201920 34480125 29278206   14G 83 Linux
    pinn-test.img10      34480128 34998271   518144  253M  c W95 FAT32 (LBA)
    pinn-test.img11      35004416 62333951 27329536   13G 83 Linux
    $ nobodd-prep --boot-partition 10 --root-partition 11 pinn-test.img

nobodd-prep also includes several facilities for customizing the boot partition beyond re-writing the kernel’s `cmdline.txt`. Specifically, the `--remove` and `--copy` options.

The `--remove` option can be given multiple times, and tells nobodd-prep to remove the specified files or directories from the boot partition. The `--copy` option can also be given multiple times, and tells nobodd-prep to copy the specified files or directories into the root of the boot partition. In both cases, directories that are specified are removed or copied recursively.

The `--copy` option is particularly useful for overwriting the cloud-init seeds on the boot partition of Ubuntu Server images, in case you want to provide an initial network configuration, user setup, or list of packages to install on first boot:

    $ cat user-data
    chpasswd:
      expire: true
      users:
      - name: ubuntu
        password: raspberry
        type: text

    ssh_pwauth: false

    package_update: true
    package_upgrade: true
    packages:
    - avahi-daemon
    $ nobodd-prep --copy user-data ubuntu-24.04-server.img

There is no need to `--remove` files you wish to `--copy`; the latter option will overwrite where necessary. The exception to this is copying directories; if you are copying a directory that already exists in the boot partition, the new content will be merged with the existing content. Files under the directory that share a name will be overwritten, files that do not will be left in place. If you wish to replace the directory wholesale, specify it with `--remove` as well.

The ordering of options on the command line does not affect the order of operations in the utility. The order of operations in nobodd-prep is strictly as follows:

1. Detect partitions, if necessary

2. Re-size the image, if necessary

3. Remove all items on the boot partition specified by `--remove`

4. Copy all items specified by `--copy` into the boot partition

5. Re-write the `root=` option in the `cmdline.txt` file

This ordering is deliberate, firstly to ensure directories can be replaced (as noted above), and secondly to ensure `cmdline.txt` can be customized by `--copy` prior to the customization performed by the utility.

## See Also

nobodd-sh, nobodd-tftpd, nbd-server(1)

## Bugs

Please report bugs at: https://github.com/waveform80/nobodd/issues