cmd/tailscale/cli: add 'tailscale configure flash-appliance'

Adds a CLI subcommand that downloads a signed Tailscale appliance
image (Gokrazy archive format, GAF) from pkgs.tailscale.com,
constructs a fresh GPT-partitioned disk from it (mbr.img + a
synthesized partition table + boot.img + root.img), formats /perm
as ext4 in pure Go via go-diskfs, and ejects the disk so a user
running on a regular workstation can flash an SD card or homelab
VM disk in one command without installing e2fsprogs.

On macOS the target disk is auto-discovered via diskutil, skipping
the boot disk and anything bigger than 256 GB out of paranoia. On
Linux the user passes --disk=/dev/sdX explicitly. Windows is not
supported yet and the command returns an error.

The GPT layout matches monogok's full-disk layout via the new
public github.com/bradfitz/monogok/disklayout package; a drift-
guard test inside monogok asserts the two implementations stay
byte-identical so OTA updates against monogok-built images keep
working.

Behind a ts_omit_flashappliance build tag (on by default).

Updates #1866

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: Ic1a8cd185e7039edccb7702ab4104544fcb58d29
This commit is contained in:
Brad Fitzpatrick
2026-07-01 08:09:50 -07:00
committed by Brad Fitzpatrick
parent 64422f274d
commit d0fcb668d5
26 changed files with 2015 additions and 101 deletions
+8
View File
@@ -148,6 +148,14 @@ sshintegrationtest: ## Run the SSH integration tests in various Docker container
generate: ## Generate code
./tool/go generate ./...
.PHONY: tsapp-build-and-flash-pi
tsapp-build-and-flash-pi: ## Build a tsapp-pi.arm64 GAF from HEAD and flash a local SD card (macOS auto-detects the disk; pass DISK=/dev/sdX on Linux)
cd gokrazy && ../tool/go run build.go --gaf --app=tsapp-pi.arm64
./tool/go run --exec=sudo ./cmd/tailscale configure flash-appliance \
--variant=pi-arm64 \
--gaf=gokrazy/tsapp-pi.arm64.gaf \
$(if $(DISK),--disk=$(DISK))
.PHONY: pin-github-actions
pin-github-actions:
./tool/go tool github.com/stacklok/frizbee actions .github/workflows