How to make a custom ISO image with mkimage: Difference between revisions

From Alpine Linux
(update link to git repo and the command to clone the git repo)
(Add info about freshness of test.)
 
(31 intermediate revisions by 11 users not shown)
Line 1: Line 1:
This document explains how to build a custom ISO image using the new mkimage scripts located in [[aports]] directory.
This document explains how to build a custom ISO image using the new mkimage scripts located in [[aports]] directory.


== Prerequisite ==
== Prerequisites ==


First make sure we have the needed tools
First make sure we have the needed tools
{{Cmd|apk add alpine-sdk build-base apk-tools alpine-conf busybox fakeroot syslinux xorriso squashfs-tools}}
{{Cmd|apk add alpine-sdk alpine-conf syslinux xorriso squashfs-tools grub grub-efi doas}}
For efi you should add
For efi you should add the following:
{{Cmd|mtools dosfstools grub-efi}}
{{Cmd|apk add mtools dosfstools grub-efi}}


Create a user (e.g. build) and add it to abuild group:
Create a user (e.g. build) and add them to the abuild group:
{{Cmd|adduser build -G abuild}}
{{Cmd|adduser build -G abuild}}
Give the user root-like permissions:
{{Cmd|vi /etc/doas.d/doas.conf}}
<pre>
permit :abuild
permit persist :abuild
</pre>
Change to the build user:
{{Cmd|su - build}}


Then create signing keys (-i installs them in /etc/apk/keys which is required for later)
Then create signing keys (-i installs them in /etc/apk/keys which is required for later)
Line 17: Line 27:
{{Cmd|ls /etc/apk/keys/}}
{{Cmd|ls /etc/apk/keys/}}


Clone (or update) the [https://github.com/alpinelinux/aports/ git repository].
Clone (or update) the [https://gitlab.alpinelinux.org/alpine/aports git repository].
{{Cmd|git clone git@github.com:alpinelinux/aports.git}}
{{Cmd|git clone --depth&#61;1 https://gitlab.alpinelinux.org/alpine/aports.git}}




Make sure the apk index is up to date (so apk finds the packages):
Make sure the apk index is up to date (so apk can find the packages):
{{Cmd|apk update}}
{{Cmd|doas apk update}}
 
Make sure your /tmp is large enough.  If you have the default 1GB /tmp, then create a local one with:
<pre>mkdir -pv ~/tmp
export TMPDIR=~/tmp</pre>


== Configuration ==
== Configuration ==
Line 30: Line 44:
The format is '''mkimg.$PROFILENAME.sh'''
The format is '''mkimg.$PROFILENAME.sh'''


So, in order to have a custom ISO, you should create your own '''mkimg.$PROFILENAME.sh''' script.
In order to have a custom ISO, you should create your own '''mkimg.$PROFILENAME.sh''' script.


This is an example used to have ZFS module, overlayfs (which allows to have /lib/modules in r/w), a serial console output and some other useful apks to build a simple NAS:
This is an example used to make a ZFS module, overlayfs (which enables r/w mode for /lib/modules), a serial console output and some other useful apks to build a simple NAS:


<pre>export PROFILENAME=nas</pre>
<pre>export PROFILENAME=nas</pre>
Line 42: Line 56:
         kernel_cmdline="unionfs_size=512M console=tty0 console=ttyS0,115200"
         kernel_cmdline="unionfs_size=512M console=tty0 console=ttyS0,115200"
         syslinux_serial="0 115200"
         syslinux_serial="0 115200"
         kernel_addons="zfs spl"
         kernel_addons="zfs"
         apks="\$apks iscsi-scst zfs-scripts zfs zfs-utils-py
         apks="\$apks iscsi-scst zfs-scripts zfs zfs-utils-py
                 cciss_vol_status lvm2 mdadm mkinitfs mtools nfs-utils
                 cciss_vol_status lvm2 mdadm mkinitfs mtools nfs-utils
                 parted rsync sfdisk syslinux unrar util-linux xfsprogs
                 parted rsync sfdisk syslinux util-linux xfsprogs
                 dosfstools ntfs-3g
                 dosfstools ntfs-3g
                 "
                 "
Line 61: Line 75:


Set the script as executable:
Set the script as executable:
{{Cmd|chmod +x mkimg.$PROFILENAME.sh}}
{{Cmd|chmod +x ~/aports/scripts/mkimg.$PROFILENAME.sh}}


== Making packages available on boot ==
== Making packages available on boot ==


A package may be made available in the live system by defining the generation of an apkovl which contains a corresponding /etc/apk/world file, and adding that overlay definition to the mkimg-profile, e.g. with `apkovl="genapkovl-mkimgoverlay.sh"`
A package may be made available in the live system by defining the generation of an apkovl which contains a corresponding /etc/apk/world file, and adding that overlay definition to the mkimg-profile, e.g. with `apkovl="genapkovl-mkimgoverlay.sh"`
Note that to *use* your added apks, you have to install them, with {{ic|apk add}}.


The definition may be done as in the [https://github.com/alpinelinux/aports/blob/master/scripts/genapkovl-dhcp.sh genapkovl-dhcp.sh] example.
The definition may be done as in the [https://github.com/alpinelinux/aports/blob/master/scripts/genapkovl-dhcp.sh genapkovl-dhcp.sh] example.
Copy the relevant parts (including the rc_add lines) into a `genapkovl-mkimgoverlay.sh` file and add the package(s) that should be installed in the live system on separate lines in the file contents for /etc/apk/world.
Copy the relevant parts (including the rc_add lines) into a `genapkovl-mkimgoverlay.sh` file and add the package(s) that should be installed in the live system on separate lines in the file contents for /etc/apk/world.
{{Cmd|cp ~/aport/scripts/genapkovl-dhcp.sh ~/aport/scripts/genapkovl-mkimgoverlay.sh}}
Edit the file to add:
<pre>
...
mkdir -p "$tmp"/etc/apk
makefile root:root 0644 "$tmp"/etc/apk/world <<EOF
alpine-base
<apk1-service>
<apk2-service>
EOF
...
rc_add <apk1-service> boot
rc_add <apk2-service> boot
...
</pre>
in the relevant locations.
Then edit the profile build script above and add:
<pre>
apkovl="aports/scripts/genapkovl-mkimgoverlay.sh"
</pre>
immediately after the last apks= line.


== Create the ISO ==
== Create the ISO ==
Line 92: Line 135:
known profiles: ali rpi uboot base minirootfs standard vanilla extended virt xen}}
known profiles: ali rpi uboot base minirootfs standard vanilla extended virt xen}}


{{Tip| You can use the --repository option multiple times, which is very useful when mixing local and official repositories. The --extra-repository option is only there for backward-compatibility.}}
{{Tip| You can use the --repository option multiple times, which is very useful when mixing local and official repositories. The --extra-repository option is there only for backward-compatibility.}}


Create a iso directory in your home dir:
Create an iso directory in your home dir:


{{Cmd|mkdir -p ~/iso}}
{{Cmd|mkdir -p ~/iso}}
Line 100: Line 143:
Then create the actual ISO.
Then create the actual ISO.
In this example we will use the edge version x86_64:
In this example we will use the edge version x86_64:
{{Cmd|sh mkimage.sh --tag edge \
{{Cmd|sh aports/scripts/mkimage.sh --tag edge \
--outdir ~/iso \
--outdir ~/iso \
--arch x86_64 \
--arch x86_64 \
--repository http://dl-cdn.alpinelinux.org/alpine/edge/main \
--repository <nowiki>https://dl-cdn.alpinelinux.org/alpine/edge/main</nowiki> \
--profile $PROFILENAME
--profile $PROFILENAME
}}
}}
Line 110: Line 153:
'''Notes:'''
'''Notes:'''


Of course, several passages of this doc can be automated with a script, like the repository/arch/outdir settings.
* If you want to make a customized installer, you need to create <code>.default_boot_services</code> which will cause <code>mkinitfs</code> to create the defaults for the live image.
This steps are left to you and to your imagination :)
 
* Several parts of this doc can be automated with a script, like the repository/arch/outdir settings.
Those steps are left to you and your imagination :)


== Testing your ISO image ==
== Testing your ISO image ==


[[Qemu#Live_mode| Qemu]] is useful for a quick test of your created ISO image.
[[QEMU#Live_mode|QEMU]] is useful for a quick test of your newly created ISO image.
This ISO build process has been tested to work and generate an ISO with auto-installed APKs as of Nov 20, 2023 with Alpine edge.  


[[Category:Package Manager]]
[[Category:Package Manager]]
[[Category:ISO]]
[[Category:ISO]]

Latest revision as of 23:11, 20 November 2023

This document explains how to build a custom ISO image using the new mkimage scripts located in aports directory.

Prerequisites

First make sure we have the needed tools

apk add alpine-sdk alpine-conf syslinux xorriso squashfs-tools grub grub-efi doas

For efi you should add the following:

apk add mtools dosfstools grub-efi

Create a user (e.g. build) and add them to the abuild group:

adduser build -G abuild

Give the user root-like permissions:

vi /etc/doas.d/doas.conf

permit :abuild
permit persist :abuild

Change to the build user:

su - build

Then create signing keys (-i installs them in /etc/apk/keys which is required for later)

abuild-keygen -i -a

Tip: Make sure your public keys are placed in /etc/apk/keys/ (example: build-xxxxxxxx.rsa.pub)

ls /etc/apk/keys/

Clone (or update) the git repository.

git clone --depth=1 https://gitlab.alpinelinux.org/alpine/aports.git


Make sure the apk index is up to date (so apk can find the packages):

doas apk update

Make sure your /tmp is large enough. If you have the default 1GB /tmp, then create a local one with:

mkdir -pv ~/tmp
export TMPDIR=~/tmp

Configuration

The mkimg scripts are shipped with pre-configured profiles.

The format is mkimg.$PROFILENAME.sh

In order to have a custom ISO, you should create your own mkimg.$PROFILENAME.sh script.

This is an example used to make a ZFS module, overlayfs (which enables r/w mode for /lib/modules), a serial console output and some other useful apks to build a simple NAS:

export PROFILENAME=nas
cat << EOF > ~/aports/scripts/mkimg.$PROFILENAME.sh
profile_$PROFILENAME() {
        profile_standard
        kernel_cmdline="unionfs_size=512M console=tty0 console=ttyS0,115200"
        syslinux_serial="0 115200"
        kernel_addons="zfs"
        apks="\$apks iscsi-scst zfs-scripts zfs zfs-utils-py
                cciss_vol_status lvm2 mdadm mkinitfs mtools nfs-utils
                parted rsync sfdisk syslinux util-linux xfsprogs
                dosfstools ntfs-3g
                "
        local _k _a
        for _k in \$kernel_flavors; do
                apks="\$apks linux-\$_k"
                for _a in \$kernel_addons; do
                        apks="\$apks \$_a-\$_k"
                done
        done
        apks="\$apks linux-firmware"
}
EOF

Set the script as executable:

chmod +x ~/aports/scripts/mkimg.$PROFILENAME.sh

Making packages available on boot

A package may be made available in the live system by defining the generation of an apkovl which contains a corresponding /etc/apk/world file, and adding that overlay definition to the mkimg-profile, e.g. with `apkovl="genapkovl-mkimgoverlay.sh"`

Note that to *use* your added apks, you have to install them, with apk add.

The definition may be done as in the genapkovl-dhcp.sh example. Copy the relevant parts (including the rc_add lines) into a `genapkovl-mkimgoverlay.sh` file and add the package(s) that should be installed in the live system on separate lines in the file contents for /etc/apk/world.

cp ~/aport/scripts/genapkovl-dhcp.sh ~/aport/scripts/genapkovl-mkimgoverlay.sh

Edit the file to add:

...
mkdir -p "$tmp"/etc/apk
makefile root:root 0644 "$tmp"/etc/apk/world <<EOF
alpine-base
<apk1-service>
<apk2-service>
EOF

...
rc_add <apk1-service> boot
rc_add <apk2-service> boot
...

in the relevant locations.

Then edit the profile build script above and add:

apkovl="aports/scripts/genapkovl-mkimgoverlay.sh"

immediately after the last apks= line.

Create the ISO

mkimage.sh [--tag RELEASE] [--outdir OUTDIR] [--workdir WORKDIR] [--arch ARCH] [--profile PROFILE] [--hostkeys] [--simulate] [--repository REPO] [--extra-repository REPO] [--yaml FILE] mkimage.sh --help options: --arch Specify which architecture images to build (default: x86_64) --hostkeys Copy system apk signing keys to created images --outdir Specify directory for the created images --profile Specify which profiles to build --repository Package repository to use for the image create --extra-repository Add repository to search packages from --simulate Don't execute commands --tag Build images for tag RELEASE --workdir Specify temporary working directory (cache) --yaml known profiles: ali rpi uboot base minirootfs standard vanilla extended virt xen

Tip: You can use the --repository option multiple times, which is very useful when mixing local and official repositories. The --extra-repository option is there only for backward-compatibility.

Create an iso directory in your home dir:

mkdir -p ~/iso

Then create the actual ISO. In this example we will use the edge version x86_64:

sh aports/scripts/mkimage.sh --tag edge \ --outdir ~/iso \ --arch x86_64 \ --repository https://dl-cdn.alpinelinux.org/alpine/edge/main \ --profile $PROFILENAME


Notes:

  • If you want to make a customized installer, you need to create .default_boot_services which will cause mkinitfs to create the defaults for the live image.
  • Several parts of this doc can be automated with a script, like the repository/arch/outdir settings.

Those steps are left to you and your imagination :)

Testing your ISO image

QEMU is useful for a quick test of your newly created ISO image. This ISO build process has been tested to work and generate an ISO with auto-installed APKs as of Nov 20, 2023 with Alpine edge.