Skip to content

Commit

Permalink
Switch to vagrant, enable cgroups, fix readdir issues
Browse files Browse the repository at this point in the history
  • Loading branch information
timebertt committed Mar 10, 2021
1 parent 00b4a59 commit 21b5239
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 55 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.img
*.zip
/.vagrant
46 changes: 18 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,43 +32,33 @@ This repo features a custom image based on Raspberry Pi OS Lite built with [pi-g
You can build the image yourself and customize the build along the way by following these steps.
1. Setup a Ubuntu VM using [multipass](https://multipass.run/) which will build the image. This provides a clean build environment and additionally works on Linux as well as macOS.
1. Setup a Debian VM using [vagrant](https://www.vagrantup.com/) which will build the image. This provides a clean build environment and additionally works on a Linux as well as macOS.
```bash
multipass launch --name raspios-builder --cpus 8 --mem 16G --disk 25G
multipass transfer install.sh raspios-builder:/home/ubuntu/install.sh
multipass transfer prepare-build.sh raspios-builder:/home/ubuntu/prepare-build.sh
vagrant up
```
1. Shell into the build VM and prepare the pi-gen build:
```bash
multipass shell raspios-builder
2. Start pi-gen build in the VM. This is going to take some time...
```
```bash
chmod +x prepare-build.sh install.sh
./install.sh # clone pi-gen and install dependencies
./prepare-build.sh # add cloud-init build steps
vagrant ssh -c /home/vagrant/pi-cloud-init/build.sh
```
1. Start pi-gen build in the VM. This is going to take some time...
```
cd ~/pi-gen
sudo ./build.sh
```
1. Transfer produced image to the host machine and unzip:
3. Transfer produced image to the host machine and unzip.
This requires the `vagrant-scp` plugin, install it first by running:
```bash
vagrant plugin install vagrant-scp
```
vm_zip_file=$(multipass exec raspios-builder -- find /home/ubuntu/pi-gen/deploy -name 'image_*.zip' -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1)
host_zip_file="${vm_zip_file##*/image_}"
multipass transfer raspios-builder:"$vm_zip_file" "$host_zip_file"
unzip -o "$host_zip_file"
```bash
zip_file=$(date +%Y-%m-%d)-raspios-buster-armhf-lite-cloud-init.zip
vagrant scp raspios-builder:/home/vagrant/pi-cloud-init/$zip_file $zip_file
unzip -o "$zip_file"
```
1. Customize `user-data.yaml`, `meta-data.yaml` and `network-config.yaml` for the instance you're setting up.
4. Customize `user-data.yaml`, `meta-data.yaml` and `network-config.yaml` for the instance you're setting up.

1. Mount boot partition to inject `user-data`, `meta-data` and `network-config`.
5. Mount boot partition to inject `user-data`, `meta-data` and `network-config`.
(It's assuming a macOS machine, but you should be able to accomplish the same using `mount` and `umount` on Linux.)
```
img_file="${host_zip_file%.zip}.img"
img_file="${zip_file%.zip}.img"
volume="$(hdiutil mount "$img_file" | egrep -o '/Volumes/.+')"
cp meta-data.yaml "$volume"/meta-data
cp user-data.yaml "$volume"/user-data
Expand All @@ -78,7 +68,7 @@ You can build the image yourself and customize the build along the way by follow
diskutil eject "$device"
```
1. Optionally, you can verify the image and cloud-init functionality using [dockerpi](https://github.com/lukechilds/dockerpi). It start a Docker container with QEMU in it emulating a Pi. This way you can already verify, that the image and the provided `user-data` is working without flashing a new SD card everytime.
6. Optionally, you can verify the image and cloud-init functionality using [dockerpi](https://github.com/lukechilds/dockerpi). It start a Docker container with QEMU in it emulating a Pi. This way you can already verify, that the image and the provided `user-data` is working without flashing a new SD card everytime.
```
docker run -it -v $PWD/$img_file:/sdcard/filesystem.img lukechilds/dockerpi:vm
...
Expand All @@ -92,9 +82,9 @@ You can build the image yourself and customize the build along the way by follow
cloud-init[620]: Cloud-init v. 20.2 finished at Mon, 08 Mar 2021 19:56:08 +0000. Datasource DataSourceNoCloud [seed=/dev/sda1][dsmode=net]. Up 179.17 seconds
```
1. Now, flash the image including cloud-init data to SD card, using [balena etcher](https://www.balena.io/etcher/), [Raspberry Pi Imager](https://www.raspberrypi.org/software/) or similar.
7. Now, flash the image including cloud-init data to SD card, using [balena etcher](https://www.balena.io/etcher/), [Raspberry Pi Imager](https://www.raspberrypi.org/software/) or similar.
2. Finally, SSH into your Pi and verify cloud-init functionality. By default, the `pi` user is locked and SSH password authentication is disabled, so make sure to use the custom user with `ssh_authorized_keys` from your `user-data`.
8. Finally, SSH into your Pi and verify cloud-init functionality. By default, the `pi` user is locked and SSH password authentication is disabled, so make sure to use the custom user with `ssh_authorized_keys` from your `user-data`.
```
ssh your-user@your-pi
cat /var/log/cloud-init-output.log
Expand Down
19 changes: 19 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
VM_NAME = "raspios-builder"

Vagrant.configure("2") do |config|
config.vm.box = "debian/buster64"

config.vm.define VM_NAME
config.vm.hostname = VM_NAME

config.vm.provider "virtualbox" do |v|
v.cpus = 8
v.memory = 16000
v.name = VM_NAME
end

config.vm.provision "shell", path: "bootstrap.sh"

config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.synced_folder ".", "/home/vagrant/pi-cloud-init", type: "rsync", rsync__auto: true, rsync__exclude: ['*.zip', '*.img']
end
15 changes: 15 additions & 0 deletions bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash -ex

# workaround for building on 64-bit host (https://github.com/RPi-Distro/pi-gen/issues/271),
# also see https://github.com/RPi-Distro/pi-gen/pull/307
dpkg --add-architecture i386

# Bring system current
apt-get update

# Install required pi-gen dependencies
apt-get install -y coreutils quilt parted qemu-user-static:i386 debootstrap zerofree zip \
dosfstools libarchive-tools libcap2-bin grep rsync xz-utils file git curl bc \
qemu-utils kpartx

mkdir -p /home/vagrant/pi-cloud-init
49 changes: 46 additions & 3 deletions prepare-build.sh → build.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
#!/bin/bash -ex

# go to home
cd
# go to home and fetch pi-gen
cd /home/vagrant

if [ -d pi-gen ] ; then
echo "found pi-gen, skipping clone"
else
echo "cloning pi-gen"

git clone https://github.com/RPi-Distro/pi-gen.git
pushd pi-gen
chmod +x build.sh
popd
fi

pushd pi-gen

Expand Down Expand Up @@ -39,7 +50,7 @@ EOF
### add cloud-init step to stage2
step="10-cloud-init"
if [ -d "$step" ]; then
rm -Rf $step
rm -Rf $step
fi
mkdir $step && pushd $step

Expand Down Expand Up @@ -163,3 +174,35 @@ EOF
chmod +x 01-run-chroot.sh

popd

### add cgroups step to stage2
step="11-cgroups"
if [ -d "$step" ]; then
rm -Rf $step
fi
mkdir $step && pushd $step

cat > 00-run-chroot.sh <<"EOF"
#!/bin/bash
# Raspberry Pi OS doesn't enable cgroups by default
cmdline_string="cgroup_memory=1 cgroup_enable=memory"
if ! grep -q "$cmdline_string" /boot/cmdline.txt ; then
sed -i "1 s/\$/ $cmdline_string/" /boot/cmdline.txt
fi
EOF
chmod +x 00-run-chroot.sh

popd

# end modifying stage2
popd

### start pi-gen build
sudo ./build.sh

### copy image back to project dir
zip_file=$(find deploy -name 'image_*.zip' -printf '%T@ %p\n' | sort -n | cut -d' ' -f 2- | tail -n 1)
copied_zip_file="${zip_file##*/image_}"
cp "$zip_file" "/home/vagrant/pi-cloud-init/$copied_zip_file"
24 changes: 0 additions & 24 deletions install.sh

This file was deleted.

0 comments on commit 21b5239

Please sign in to comment.