automatically create customized FreeBSD images in minutes
Packmule is a tool I wrote to customize FreeBSD images without recompiling
anything. It can:
- Add individual files and packages to an existing image.
- Turn a regular image into a unattended image. (automatically installs without any user input)
- Add packages or files to the Live CD itself.
- Operate on ISO or Memstick images.
It's also perfect for organizing large scale VM or server installations. Let's assume you are the proud owner of 30 servers, each of which needs to be set up with an identical installation of FreeBSD containing the same packages and configuration files. It's relatively easy to set up a tool like Ansible to manage each server, but you are not looking forward to manually installing Ansible's base dependencies 30 times. What you really need is a unattended installation image that installs FreeBSD and Ansible's dependencies for you.
Packmule is now a part of the ports tree, meaning installing is as simple as:
pkg install packmule
man packmule once you've installed for the complete rundown.
Packmule packs a FreeBSD installation image with custom content,
making it useful for generating install images with all your normal
utilities included. The added packages are installed along with the
regular contents of FreeBSD. Generated images have the form
FreeBSD-*-packed.iso. Installation can proceed as normal with the packed software
showing up on the newly installed system alongside the FreeBSD base.
Simply burn the
FreeBSD-*-packed.iso image to a CD and install it as you would with
a regular FreeBSD installation:
As shown above, the
packmule-pkgs distribution archive is being installed alongside
the base system and kernel. When complete, the machine will appear as though the user
logged in and manually installed the software.
Packmule is configured using the YAML configuration language. The default
configuration file is
./packmule.yml but it is recommended to specify a
specific file using the
-y argument. The three main sections are as
This section holds names of packages to be installed through the pkg(8) tool.
Individual files or directories to be copied into the new image.
Values are separated by
:, with the value on the left being the
source file and the value on the right being the destination. (
/path/to/src : /install/location)
Same as PKGS, but installs packages onto the live cd image instead of the host. This provides an easy way to add software to a live usb image, which is really useful for testing on laptops where you can't install a new operating system. Or for adding vim to a live usb because you can't stand vi.
Same as LIVE_CD_PKGS, but installs individual files instead of packages.
A path to an installerconfig script to be used for an unattended installation. More information about unattended installations and installerconfigs can be found in bsdinstall(8)
Here is an example configuration (config.yml):
# example config.yml PKGS: - perl5-5.24.3 - nethack36 - gnome3 # Format: /host/location : /install/location CUSTOM: /root/.shrc : /root/.shrc /etc/hosts : /etc/hosts INSTALLERCONFIG : ~user/installerconfig
The above example is much smaller than what is useful. This configuration will install perl, nethack, and gnome3 in the installation image. It also copies individual files such as resolv.conf and hosts. This is useful for installing custom configuration files automatically on a system. An installation image can use this method to install arbitrary configuration files.
Here's a simple usage example to walk you through using Packmule. To perform this task you will need a FreeBSD image, preferably a 12.0-RELEASE one. For simplicity, I assume all the files mentioned will be in your home directory. Let's begin with our initial problem of automatically installing Ansible.
Unattended installation for Ansible management
Although it is agentless, Ansible requires a few basic things like a python interpreter
and sudo. It also requires a user with access to the
wheel group (gid 0). The user is added
through the installerconfig.
First we need to create an installerconfig file to tell the FreeBSD installer what actions
to perform. More information about unattended installer configurations can be found in the
bsdinstall(8) manpage. Our configuration should look something like:
# ~/installerconfig # # Configure the partition to install to and select distributions to add # vtbd0 is the bhyve default. You will have to pick an appropriate value for # your machine PARTITIONS=vtbd0 DISTRIBUTIONS="kernel.txz base.txz packmule-pkgs.txz"` #! /bin/sh # -- This portion of the installerconfig is run after installation -- # set a new root user password echo "example-pass" | pw usermod root -h 0 # add a user for ansible to manage echo "user-pass" | pw useradd -n example -u 1001 -g 0 -h 0
The YAML configuration file for this example is very simple:
# config.yml # select python 3.6 for ansible PKGS: - python36 - sudo # select our installerconfig from above INSTALLERCONFIG : ~/installerconfig
The following command puts it all together:
$ cd ~/ $ packmule -y ~/config.yml FreeBSD-12.0-RELEASE-amd64-dvd1.iso
The resulting image will have the name
FreeBSD-12.0-RELEASE-amd64-dvd1-packed.iso. Boot the image on
whatever target machine you want FreeBSD on, at it will take care of the rest. Don't accidentally install
on the wrong machine, as the installerconfig you wrote will most likely just overwrite the disk.
Adding support for Memstick images and live CD upgrades opened new doors for the tool. I wrote the features so I could replace the kernel on a live USB stick in order to test some driver fixes on a friend's laptop without overwriting his OS.
If you find the tool useful, and happen to be a port committer, please consider pushing the bugzilla issue along!
Packmule gets updated whenever I need a new feature, which is not very often. Currently I have no features planned, but if you have any suggestions or pull requests please comment on the GitHub repository!