Repository navigation
Migrate the platform to Alpine for root volume immutability #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
bgshacklett
wants to merge
54
commits into
main
Choose a base branch
from
alpine
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
51b3c62
WIP
bgshacklett 40eddef
Move unattended.sh script into separate file
bgshacklett 7e3fcb6
WIP
bgshacklett e5e92ab
download headless-apkovl using raw url
bgshacklett 716e3a6
Move cmdline.txt and usercfg.txt setup to prep script
bgshacklett 169b518
Move lbu commit
bgshacklett f64073a
Don't set up /dev/sda for now
bgshacklett d8dcb9e
remove superfluous `main` function
bgshacklett 1efb350
Move K8s manifests to separate directory
bgshacklett 339b77d
Add script for running alpine in qemu on raspi4b 'machine'
bgshacklett fb5997d
Set up untattended config files
bgshacklett b2b5f28
Set up makefile skeleton
bgshacklett 5e6654e
Update .gitignore
bgshacklett 4587d39
Update script name
bgshacklett f08b540
WIP
bgshacklett 24bf297
Output unattended.sh script logging to console
bgshacklett 0d8b5ef
Handle WPA_SUPPLICANT
bgshacklett 00a9022
Rename main script
bgshacklett 4e801c0
WIP
bgshacklett 7e8eaf1
WIP
bgshacklett 6940b84
WIP
bgshacklett 83e5f17
WIP
bgshacklett e56b309
WIP
bgshacklett a9c0fc2
Initial working WIFI simulation
bgshacklett bb5568e
Finish what alpine-setup could not
bgshacklett 0a9d401
Default to pi3 hardware until pi4 is more usable
bgshacklett a4e6b01
Re-Arrange variables
bgshacklett ee17c69
Specify $boot path outside of _populate_config
bgshacklett 00ddd11
cleanup
bgshacklett 6f0f7c5
clean up comments
bgshacklett 8649df4
Prep for writing to SD Card
bgshacklett 2c561b0
Fix: don't mangle backslashes in WIFI settings
bgshacklett 257c854
Set up answer file; use usb0 for networking after install
bgshacklett d59a14f
Enable admin user
bgshacklett 67efcd6
verbose output for downloads
bgshacklett 3e74b3e
Work on populating SD card
bgshacklett a0e4640
make unmount and removal of loop devide more robust
bgshacklett 8fa0aac
Don't run with_p1_sd as subshell
bgshacklett 17b303b
cleanup
bgshacklett f610483
Improve make sdcard logic
bgshacklett 770e5d0
add hostname to alpine-setup.any.conf.example
bgshacklett 9ad5924
Remove answers.txt from repo; create example of same
bgshacklett d3aa975
Separate default answers files for RPI and QEMU
bgshacklett 80cbb52
Found `-e` option. Rely on setup-alpine for most of setup
bgshacklett 7330f9f
Update device requests
bgshacklett 86cac53
Merge branch 'main' into alpine
bgshacklett bd14297
fix: address 12 review issues across shell scripts and config files
c297322
Add unattended.lib.sh; gate WiFi prompts on tty
bgshacklett a48f76d
Pin Alpine release + verify tarball checksum
bgshacklett 12d5413
Add init-config to scaffold etc/ from extras/ templates
bgshacklett cdcf2a3
Add shellcheck CI + fix existing findings; drop dead sdcard stub
bgshacklett 815b9f5
Fix four cubic-flagged runtime correctness issues
bgshacklett ce2b384
Address cubic-flagged security issues
bgshacklett a9aa2ee
Rewrite README around the Alpine image-build pipeline
bgshacklett File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| name: lint | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main, alpine] | ||
| pull_request: | ||
|
|
||
| jobs: | ||
| shellcheck: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Install shellcheck | ||
| run: sudo apt-get update && sudo apt-get install -y shellcheck | ||
| - name: Run shellcheck | ||
| run: find scripts etc -type f -name '*.sh' -print0 | xargs -0 shellcheck |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| .devrootfs/* | ||
| dist/* | ||
| build/* | ||
| **/*.orig | ||
| cache/* | ||
|
|
||
| etc/* | ||
| !etc/pre-network.d | ||
| !etc/unattended.sh | ||
| !etc/unattended.lib.sh | ||
| !etc/alpine.lock | ||
| !etc/unattended.exec.d | ||
| !etc/unattended.conf.d | ||
| etc/unattended.conf.d/* | ||
| !etc/unattended.conf.d/README.md | ||
| !**/README.md | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # This Makefile is a wrapper around scripts in the <repo_root>/scripts | ||
| # directory, meant to enable tab completion and generally make life a little | ||
| # easier. You do not need `make` to use the contents of this repo. | ||
|
|
||
|
|
||
| .PHONY: image | ||
| image: | ||
| @sudo -E scripts/alpine-rpi.sh make-image | ||
|
|
||
| .PHONY: populate-boot-qemu | ||
| populate-boot-qemu: | ||
| @sudo -E scripts/alpine-rpi.sh populate-boot-qemu | ||
|
|
||
| .PHONY: populate-config-qemu | ||
| populate-config-qemu: | ||
| @sudo -E scripts/alpine-rpi.sh populate-config-qemu | ||
|
|
||
| .PHONY: verify | ||
| verify: | ||
| @scripts/alpine-rpi.sh verify | ||
|
|
||
| .PHONY: qemu | ||
| qemu: image populate-boot-qemu populate-config-qemu | ||
|
|
||
| .PHONY: launch | ||
| launch: | ||
| @sudo -E scripts/alpine-rpi.sh launch | ||
|
|
||
| .PHONY: test | ||
| test: | ||
| @sudo -E scripts/alpine-rpi.sh test | ||
|
|
||
| .PHONY: populate-boot-sd | ||
| populate-boot-sd: | ||
| @sudo -E scripts/alpine-rpi.sh populate-boot-sd | ||
|
|
||
| .PHONY: populate-config-sd | ||
| populate-config-sd: | ||
| @sudo -E scripts/alpine-rpi.sh populate-config-sd | ||
|
|
||
| .PHONY: sdcard | ||
| sdcard: populate-boot-sd populate-config-sd | ||
|
|
||
| .PHONY: refresh-lock | ||
| refresh-lock: | ||
| @scripts/alpine-rpi.sh refresh-lock | ||
|
|
||
| .PHONY: init-config | ||
| init-config: | ||
| @scripts/alpine-rpi.sh init-config | ||
|
|
||
| .PHONY: lint | ||
| lint: | ||
| @find scripts etc -type f -name '*.sh' -print0 | xargs -0 shellcheck | ||
|
|
||
| .PHONY: clean | ||
| clean: | ||
| @scripts/alpine-rpi.sh clean |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # etc/alpine.lock — pinned Alpine RPi build inputs. | ||
| # Generated by: ./scripts/alpine-rpi.sh refresh-lock | ||
| # Regenerate to pull in newer Alpine releases or firmware. | ||
|
|
||
| ALPINE_BRANCH=v3.23 | ||
| ALPINE_TARBALL_NAME=alpine-rpi-3.23.0-aarch64.tar.gz | ||
| ALPINE_TARBALL_SHA256=fbbbb77f7269f4ca4beff01a2c8116f6668f92f6a8cd607c6ef0a9a89715a7a3 | ||
|
|
||
| # raspberrypi/firmware is fetched via raw.githubusercontent.com, which is | ||
| # byte-deterministic per commit sha — the commit itself is the integrity | ||
| # guarantee, so no separate sha256 is recorded for the DTB. | ||
| RPI_FW_COMMIT=8fce67a9ec5668fb8d42d215c9ec4c199340bf41 |
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| #!/bin/sh | ||
| # shellcheck shell=dash | ||
|
|
||
| # shellcheck source=etc/unattended.lib.sh | ||
| . "$OVLPATH/unattended.lib.sh" | ||
|
|
||
|
|
||
| init_pre_setup_networking() { | ||
| set -x | ||
| dmesg | grep -E -i 'usb|cdc|rndis|eth' | ||
| lsmod | grep -E 'usbnet|cdc_ether|cdc_subset|rndis_host' || true | ||
| modprobe usbnet cdc_ether cdc_subset rndis_host # harmless if already present | ||
|
|
||
|
|
||
| # Set up initial network connectivity to retrieve required packages | ||
| ip link show | ||
| ip link set usb0 up | ||
|
|
||
| # continues only if a lease was obtained | ||
| udhcpc -i usb0 -n -q -t 5 -T 3 | ||
|
|
||
| set +x | ||
| } | ||
|
|
||
|
|
||
| setup_prereqs() { | ||
| set -x | ||
| ntpd -n -q -p pool.ntp.org | ||
| date -u # sanity-check it's roughly correct now | ||
|
|
||
| # Temporarily point to HTTP so we can install CA certs. APK still verifies | ||
| # package signatures via /etc/apk/keys, but the index could be tampered with | ||
| # (e.g. served older vulnerable versions), so we flip back to HTTPS as soon | ||
| # as ca-certificates-bundle is in place. | ||
| echo 'http://dl-cdn.alpinelinux.org/alpine/latest-stable/main' >/etc/apk/repositories | ||
|
cubic-dev-ai[bot] marked this conversation as resolved.
|
||
|
|
||
| apk update | ||
| apk add ca-certificates-bundle | ||
|
|
||
| # ensure BusyBox sees the right file (usually created by the pkg already) | ||
| ls -l /etc/ssl/cert.pem /etc/ssl/certs/ca-certificates.crt | ||
| # if /etc/ssl/cert.pem is missing for some reason: | ||
| ln -sf /etc/ssl/certs/ca-certificates.crt /etc/ssl/cert.pem | ||
|
|
||
| # Now that we have a trust store, switch to HTTPS for all subsequent apk ops. | ||
| echo 'https://dl-cdn.alpinelinux.org/alpine/latest-stable/main' >/etc/apk/repositories | ||
| apk update | ||
|
|
||
| set +x | ||
| } | ||
|
|
||
|
|
||
| wait_for_wpa() { # iface timeout | ||
| iface="$1" | ||
| timeout="${2:-30}" # default: 30s | ||
| t=0 | ||
| while [ "$t" -lt "$timeout" ]; do | ||
| state=$(wpa_cli -i "$iface" status 2>/dev/null | awk -F= '/^wpa_state=/{print $2}') | ||
| if [ "$state" = "COMPLETED" ]; then | ||
| echo "wpa_supplicant: authenticated on $iface" | ||
| return 0 | ||
| fi | ||
| sleep 1 | ||
| t=$((t + 1)) | ||
| done | ||
| echo "wpa_supplicant: timeout waiting for authentication on $iface" >&2 | ||
| return 1 | ||
| } | ||
|
|
||
|
|
||
| set -x | ||
| init_pre_setup_networking | ||
| setup_prereqs | ||
| # ################################ | ||
| # Setup wifi hardware simulation # | ||
| # ################################ | ||
|
|
||
| # Add required packages | ||
| apk add --force-overwrite --no-cache iproute2-minimal iproute2 | ||
| apk add --no-cache iw hostapd wpa_supplicant busybox-extras iptables | ||
|
|
||
| # Use full iproute2; you've got iproute2-minimal so /sbin/ip is fine | ||
| IP=/sbin/ip | ||
|
|
||
| # Radios | ||
| modprobe mac80211_hwsim radios=2 | ||
|
|
||
| # “Router/AP” namespace owns wlan0 + usb0 | ||
| # Take usb0 down and reconfigure it in an isolated network namespace | ||
| $IP link set usb0 down | ||
|
|
||
|
|
||
| # Make sure radios exist | ||
| _have_wlan=0 | ||
| for _iface in /sys/class/net/wlan[0-9]*; do | ||
| [ -e "$_iface" ] && _have_wlan=1 && break | ||
| done | ||
| if [ "$_have_wlan" -eq 0 ]; then | ||
| echo "No wlan* found. Did modprobe mac80211_hwsim radios=2 succeed?" | ||
| exit 1 | ||
| fi | ||
|
|
||
| # pick radios (as you already do) | ||
| WLAN_LIST="$($IP -o link show | awk -F': ' '{print $2}' | grep -E '^wlan[0-9]+$' | sort)" | ||
| AP_WLAN="$(echo "$WLAN_LIST" | sed -n '1p')" # e.g., wlan0 | ||
| STA_WLAN="$(echo "$WLAN_LIST" | sed -n '2p')" # e.g., wlan1 | ||
|
|
||
| if [ -z "$AP_WLAN" ] || [ -z "$STA_WLAN" ]; then | ||
| echo "Need two wlan* from hwsim; found: $WLAN_LIST" | ||
| exit 1 | ||
| fi | ||
|
|
||
| # create namespace, move uplink with ip | ||
| $IP netns add ap 2>/dev/null || true | ||
| UPLINK="$($IP -o link show | awk -F': ' '{print $2}' \ | ||
| | awk '/^usb0$/ {print; exit} /^eth[0-9]+$/ && !seen[$0]++ {print; exit}')" | ||
| [ -n "$UPLINK" ] || { echo "No uplink (usb0/ethX) found"; exit 1; } | ||
|
|
||
| $IP link set "$UPLINK" down | ||
| $IP link set "$UPLINK" netns ap | ||
|
|
||
| $IP link set "$AP_WLAN" down | ||
| AP_PHY="$(basename "$(readlink -f "/sys/class/net/$AP_WLAN/phy80211")")" | ||
| iw phy "$AP_PHY" set netns name ap | ||
|
|
||
|
|
||
| /sbin/ip netns exec ap /bin/sh -xc ". $OVLPATH/unattended.lib.sh; config_sim_ap $IP $OVLPATH" | ||
| $IP netns exec ap $IP -br link | sed 's/^/ ap : /' | ||
|
|
||
|
|
||
| $IP link set "$STA_WLAN" up | ||
| install -m600 "$OVLPATH/wpa_supplicant.conf" /etc/wpa_supplicant/wpa_supplicant.conf | ||
| # rc-service wpa_supplicant restart | ||
|
|
||
| _logger "hwsim up: STA (root ns, wlan1) ↔ AP (ap ns, wlan0) with NAT via usb0." | ||
|
|
||
| set +x | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Configuration Files for Headless Setup | ||
|
|
||
| Place configuration files here. They will be ignored by Git. | ||
|
|
||
| foo |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.