# packer The rustkrazy image generator. # Supported hardware The images created by this program should work on the following machines: * Raspberry Pi 3 (any model) * Raspberry Pi 4 (any model) * x86_64 hardware supporting legacy boot UEFI support (for x86_64) is not planned, but contributions are welcome. # System package requirements For the packer to work you need to install the following packages: * nasm * squashfs-tools-ng * musl * gcc * ld * (optional) clang * (optional) kernel-headers-musl If you want to build images for the Raspberry Pi, the aarch64 versions of the musl related packages (musl itself and optionally clang and the kernel headers) and the compiler and linker (gcc becomes aarch64-linux-musl, ld becomes aarch64-linux-gnu-binutils) are required as well. Clang and the kernel headers are needed for some small sys crates to compile. Many crates will compile without them but there are a few that won't. Then, add the musl targets: ``` rustup target add x86_64-unknown-linux-musl rustup target add aarch64-unknown-linux-musl ``` # Supported crates Most Rust crates should compile if the packer is set up correctly. Larger sys crates that dynamically link to system libraries cannot easily be supported. Most notably OpenSSL is not supported. Check if your dependencies offer Cargo features to disable OpenSSL and replace it with rustls. In general simple crates are more likely to work but more complex crates can be built if the correct dependencies are installed. # Usage Invoke the packer with `-h` or `--help` to view a list of all available options. ## --overwrite The overwrite argument specifies where to write the image to. It can be a device file (loop or real) as long as you have permission to write to it. To grant yourself write access to a device, use the following command (as root): ``` setfacl -m u::rw ``` If the target file is a device this is sufficient. If it's an image file you have to pass `-n` or `--size`. You can use a tool like `fdisk` to get the size of your image file in bytes and use that number with the packer. This is needed because the packer needs to know the size of the image for partitioning but can't call ioctl on regular files to get it. Alternatively you can create a loop device for your image and write to it instead. ## --crates This is a list of crate names to install from the crates.io registry. To install more than one crate you can pass this argument multiple times. Example: ``` rustkrazy_packer -o /dev/some_device -c crate1 -c crate2 ``` The name is assumed to be the same as the name of the resulting binary. As a result you may need to swap hyphens with underscores or vice versa. ## --git This is similar to `--crates`, but allows you to install crates from any git repository. Just like `--crates` it can be passed multiple times. It expects the argument to be in the following format: ``` % ``` where `REPO_URL` is the location of the repository and `CRATE_NAME` is the name of the crate defined in its Cargo.toml. Like `--crates` this argument expects `CRATE_NAME` to match the binary file name. Example: ``` rustkrazy_packer -o /dev/some_device -g https://github.com/rustkrazy/init%rustkrazy_init ``` ## --init Use this flag to tell the packer which one of the crates is the init system. It will be moved to `/bin/init` in the image and start on boot. It is responsible for starting the other binaries as needed. The argument is the name of one of the crates listed in `--crates` or `--git`. The rustkrazy project comes with its own small init system that oneshots all services and logs startup information to the primary display. It also mounts essential file systems like /boot or /proc. You can however use your own init system if it's better for your use case. If you're only installing a single crate an init may not be needed, allowing you to set the init argument to that crate. However this is not guruanteed to work since the program can fail if it tries to access pseudo file systems that have not been mounted. # Building the packer Make sure you have `cargo-make` installed: ``` cargo install cargo-make ``` Since the packer requires the compiled MBR for the x86_64 architecture it needs to be built by running: ``` cargo make ``` if you want to build x86_64 images. This assembles the MBR and builds the packer. You may skip this step if you're only interested in building images for the Raspberry Pi.