This plugin allows you to build or extend ARM system image. It operates in two modes:
- new - creates empty disk image and populates the rootfs on it
- reuse - uses already existing image as the base
Plugin mimics standard image creation process, such as:
- builing base empty image (dd)
- partitioning (sgdisk / sfdisk)
- filesystem creation (mkfs.type)
- partition mapping (losetup)
- filesystem mount (mount)
- populate rootfs (tar/unzip/xz etc)
- setup qemu + chroot
- customize installation within chroot
The virtualization works via binfmt_misc kernel feature and qemu.
Since the setup varies a lot for different hardware types, the example configuration is available per "board". Currently the following boards are supported (feel free to add more):
- bananapi-r1 (Archlinux ARM)
- beaglebone-black (Archlinux ARM, Debian)
- jetson-nano (Ubuntu)
- odroid-u3 (Archlinux ARM)
- odroid-xu4 (Archlinux ARM, Ubuntu)
- parallella (Ubuntu)
- raspberry-pi (Archlinux ARM, Raspbian)
- wandboard (Archlinux ARM)
git clone https://github.com/mkaczanowski/packer-builder-arm
cd packer-builder-arm
go mod download
go build
sudo packer build boards/odroid-u3/archlinuxarm.json
This method is primarily for macOS users where is no native way to use qemu-user-static.
docker build -t packer-builder-arm -f docker/Dockerfile .
Run packer build:
docker run --rm --privileged -v /dev:/dev -v ${PWD}:/build packer-builder-arm build boards/raspberry-pi/raspbian.json
sfdisk / sgdisk
e2fsprogs
Configuration is split into 3 parts:
- remote file config
- image config
- qemu config
Describes the remote file that is going to be used as base image or rootfs archive (depending on image_build_method
)
"file_urls" : ["http://os.archlinuxarm.org/os/ArchLinuxARM-odroid-xu3-latest.tar.gz"],
"file_checksum_url": "http://hu.mirror.archlinuxarm.org/os/ArchLinuxARM-odroid-xu3-latest.tar.gz.md5",
"file_checksum_type": "md5",
"file_unarchive_cmd": ["bsdtar", "-xpf", "$ARCHIVE_PATH", "-C", "$MOUNTPOINT"],
"file_target_extension": "tar.gz",
The file_unarchive_cmd
is optional and should be used if the standard golang archiver can't handle the archive format.
Raw images format (.img
or .iso
) can be used by defining the file_target_extension
appropriately.
The base image description (size, partitions, mountpoints etc).
"image_build_method": "new",
"image_path": "odroid-xu4.img",
"image_size": "2G",
"image_type": "dos",
"image_partitions": [
{
"name": "root",
"type": "8300",
"start_sector": "4096",
"filesystem": "ext4",
"size": "0",
"mountpoint": "/"
}
],
The plugin doesn't try to detect the image partitions because that varies a lot. Instead it solely depend on image_partitions
specification, so you should set that even if you reuse the image (method
= reuse).
Anything qemu related:
"qemu_binary_source_path": "/usr/bin/qemu-arm-static",
"qemu_binary_destination_path": "/usr/bin/qemu-arm-static"
To execute command within chroot environment you should use chroot communicator:
"provisioners": [
{
"type": "shell",
"inline": [
"pacman-key --init",
"pacman-key --populate archlinuxarm"
]
}
]
To dump image on device you can use custom postprocessor (really wrapper around dd
with some sanity checks):
"post-processors": [
{
"type": "flasher",
"device": "/dev/sdX",
"block_size": "4096",
"interactive": true
}
]
While image (.img
) format is useful for most cases, you might want to use
rootfs for other purposes (ex. export to docker). This is how you can generate
rootfs archive instead of image:
"image_path": "odroid-xu4.img" # generates image
"image_path": "odroid-xu4.img.tar.gz" # generates rootfs archive
With artifice
plugin you can pass rootfs archive to docker plugins
"post-processors": [
[{
"type": "artifice",
"files": ["rootfs.tar.gz"]
},
{
"type": "docker-import",
"repository": "mkaczanowski/archlinuxarm",
"tag": "latest"
}],
...
]
This is the live example on how to use github actions to push image to docker image registry:
cat .github/workflows/archlinuxarm-armv7-docker.yml
For more examples please see:
tree boards/