2019-11-11 13:50:00
As a software contractor, I work on a variety of codebases and like to maintain a level of isolation between them. I’m going to talk about one of the ways in which I achieve that, which is to have an easy-to-use method which allows me to rapidly replicate the environment I work in.
All of the source code for this project is free to use and licensed under GPLv2. You can clone it from https://git.sr.ht/~esotericnonsense/autoarch.
Below I will describe some of the work that went into creating autoarch
.
archiso
The Arch Linux development team have created a tool named mkarchiso
, along with a set of scripts that can be used to build bootable Arch Linux ISOs.
The repository is available to clone or view at https://git.archlinux.org/archiso.git. It can also be installed via pacman -S archiso
.
Within the repository, in the scripts
subdirectory, two build scripts are available.
The releng
script is used to create the full automated ISO builds which are made available at the download page.
We are personally interested in the baseline
script, which produces a minimal ISO with only the packages from the base
group: https://www.archlinux.org/groups/x86_64/base.
$ pwd
/home/esotericnonsense/git/archiso
$ cd configs/baseline
$ ls
build.sh isolinux mkinitcpio.conf syslinux
$ vim build.sh
The baseline
build script contains a number of functions that use the mkarchiso
script in order to produce a working ISO.
Note that as of tag v43
, the baseline script does not actually function as is due to the removal of the linux
package and its’ dependencies from the base group. In order to fix this, add the following line to the make_basefs()
function:
mkarchiso -v -w "${work_dir}" -D "${install_dir}" -p linux install
A patch is also available to fix the issue at https://git.esotericnonsense.com/pub/archiso.git/commit/?h=esoteric/baseline-fix. It has been submitted to the arch-releng mailing list.
An image can be built by running:
$ sudo ./build.sh
The work/
and out/
folders will be populated with the working state and final ISO file respectively. Remember to remove these folders before rebuilding.
By default, the baseline
archiso does not automatically login; one must login as the root
user after booting. To rectify this, we can add a make_autologin()
function to the build script.
# Enable autologin on tty1
make_autologin() {
local gettydir
getty_dir="${work_dir}/airootfs/etc/systemd/system/getty@tty1.service.d"
mkdir -p "${getty_dir}"
cat << EOF > "${getty_dir}/autologin.conf"
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear %I 38400 linux
EOF
}
At the bottom of the build script, add the following line:
run_once make_setup_mkinitcpio
+run_once make_autologin
run_once make_boot
By default, the baseline
archiso does not connect to any network.
The baseline image includes systemd
, so we can rectify this by adding a systemd-networkd
hook.
# Enable DHCP networking on the ens1 interface
make_networking() {
local iface
iface="ens1"
cat << EOF > "${work_dir}/airootfs/etc/systemd/network/20-wired.network"
[Match]
Name=${iface}
[Network]
DHCP=ipv4
EOF
mkarchiso -v -w "${work_dir}" -D "${install_dir}" -r \
"systemctl enable systemd-networkd.service systemd-resolved.service" run
# Ensure the network is up when we hit the shell prompt
mkarchiso -v -w "${work_dir}" -D "${install_dir}" -r \
"systemctl enable systemd-networkd-wait-online.service" run
}
Again, at the bottom of the build script, add the following line:
run_once make_setup_mkinitcpio
+run_once make_networking
run_once make_boot
By default, the baseline
archiso has no mirrors listed and so pacman
is therefore unable to install anything. We can fix this:
# Uncomment the servers in the mirrorlist and randomise their order
make_pacman_mirrorlist() {
local mirrorlist
mirrorlist="${work_dir}/airootfs/etc/pacman.d/mirrorlist"
cat "${mirrorlist}" | grep "Server" | sed 's/^#Server/Server/g' | sort -R \
> "${mirrorlist}.new"
mv "${mirrorlist}.new" "${mirrorlist}"
}
run_once make_setup_mkinitcpio
+run_once make_pacman_mirrorlist
run_once make_boot
We also need to initialize pacman-key so that signed packages can be verified correctly.
# Initialize pacman-key
make_pacman_key_init() {
mkarchiso -v -w "${work_dir}" -D "${install_dir}" \
-r "pacman-key --init" run
mkarchiso -v -w "${work_dir}" -D "${install_dir}" \
-r "pacman-key --populate archlinux" run
}
run_once make_setup_mkinitcpio
+run_once make_pacman_key_init
run_once make_boot
Now that the above has been taken care of, we can get down to the business of actually having an automatic installation script running.
The following code provides for two options; either cloning the install script and building it into the ISO itself at build time; or cloning the install script on boot/runtime. The latter method may be useful if the installer is expected to change often.
You may wish to change the URL cloned to your own; the one specified here is not guaranteed to remain stable.
make_clone_installer_at_run_time() {
cat << EOF > "${work_dir}/airootfs/root/autorun.sh"
#!/usr/bin/env bash
set -uxo pipefail
git clone "https://git.esotericnonsense.com/pub/autoarch.git" \
"\${HOME}/autoarch"
bash "\${HOME}/autoarch/install/main.sh"
EOF
}
make_clone_installer_at_build_time() {
git clone "https://git.esotericnonsense.com/pub/autoarch.git" \
"${work_dir}/airootfs/root/autoarch"
cat << EOF > "${work_dir}/airootfs/root/autorun.sh"
#!/usr/bin/env bash
set -uxo pipefail
bash "\${HOME}/autoarch/install/main.sh"
EOF
}
# Set up automatic install
make_setup_automatic_install() {
mkarchiso -v -w "${work_dir}" -D "${install_dir}" \
-p arch-install-scripts -p git install
# Automatically run the installer on boot
cat << EOF > "${work_dir}/airootfs/root/.profile"
#!/usr/bin/env bash
set -uxo pipefail
if [[ \$(tty) == "/dev/tty1" ]]; then
bash "\${HOME}/autorun.sh"
fi
EOF
# Option 1
make_clone_installer_at_run_time
# Option 2
#make_clone_installer_at_build_time
chmod +x "${work_dir}/airootfs/root/autorun.sh"
}
run_once make_setup_mkinitcpio
+run_once make_setup_automatic_install
run_once make_boot
Now that the above has been taken care of, we can write the actual autoinstall script, which if you have followed the instructions above, should be placed in /root/autoarch/install/main.sh
on the finalised ISO.
autoarch
itself, a link to which is given at the top of this post.esotericnonsense (Daniel Edgecumbe) blog@esotericnonsense.com
November 11, 2019