sketch: add multi-architecture binary support

Build both amd64 and arm64 Linux binaries and embed them both.
Simplify API to use single LinuxBinary(arch) function for architecture
selection. Update copyEmbeddedLinuxBinaryToContainer to detect Docker
server architecture using 'docker version --format' and automatically
use the correct binary.

This enables sketch to work correctly on both x86_64 and ARM64
Docker environments without requiring architecture-specific builds.
Unsupported architectures return nil instead of panicking.

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: sd498605bf58e984ek
diff --git a/Makefile b/Makefile
index 2b31b66..69192e6 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,8 @@
 	go build -ldflags="$(LDFLAGS)" -tags=outie -o sketch ./cmd/sketch
 
 innie: webui-assets
-	CGO_ENABLED=0 GOOS=linux go build -ldflags="$(LDFLAGS)" -tags=innie -o embedded/sketch-linux/sketch-linux ./cmd/sketch
+	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="$(LDFLAGS)" -tags=innie -o embedded/sketch-linux/sketch-linux-amd64 ./cmd/sketch
+	CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="$(LDFLAGS)" -tags=innie -o embedded/sketch-linux/sketch-linux-arm64 ./cmd/sketch
 
 webui-assets:
 	rm -rf embedded/webui-dist
diff --git a/dockerimg/dockerimg.go b/dockerimg/dockerimg.go
index 728175c..4cba98f 100644
--- a/dockerimg/dockerimg.go
+++ b/dockerimg/dockerimg.go
@@ -1161,9 +1161,15 @@
 
 // copyEmbeddedLinuxBinaryToContainer copies the embedded linux binary to the container
 func copyEmbeddedLinuxBinaryToContainer(ctx context.Context, containerName string) error {
-	bin := embedded.LinuxBinary()
+	out, err := combinedOutput(ctx, "docker", "version", "--format", "{{.Server.Arch}}")
+	if err != nil {
+		return fmt.Errorf("failed to detect Docker server architecture: %s: %w", out, err)
+	}
+	arch := strings.TrimSpace(string(out))
+
+	bin := embedded.LinuxBinary(arch)
 	if bin == nil {
-		return fmt.Errorf("nil embedded linux binary reader, did you build using `make`?")
+		return fmt.Errorf("no embedded linux binary for architecture %q", arch)
 	}
 
 	// Stream a tarball to docker cp.
diff --git a/embedded/embedded.go b/embedded/embedded.go
index a5b8c49..70b82cf 100644
--- a/embedded/embedded.go
+++ b/embedded/embedded.go
@@ -10,7 +10,7 @@
 )
 
 // LinuxBinary returns the embedded linux binary.
-func LinuxBinary() []byte {
+func LinuxBinary(arch string) []byte {
 	return nil
 }
 
diff --git a/embedded/embedded_innie.go b/embedded/embedded_innie.go
index 475e7a2..8aa4789 100644
--- a/embedded/embedded_innie.go
+++ b/embedded/embedded_innie.go
@@ -11,7 +11,7 @@
 var webUIAssets embed.FS
 
 // LinuxBinary returns the embedded linux binary.
-func LinuxBinary() []byte {
+func LinuxBinary(arch string) []byte {
 	return nil
 }
 
diff --git a/embedded/embedded_outie.go b/embedded/embedded_outie.go
index a89ff4b..42b32b7 100644
--- a/embedded/embedded_outie.go
+++ b/embedded/embedded_outie.go
@@ -7,12 +7,21 @@
 	"io/fs"
 )
 
-//go:embed sketch-linux/sketch-linux
-var sketchLinuxBinary []byte
+//go:embed sketch-linux/sketch-linux-amd64
+var sketchLinuxBinaryAmd64 []byte
+
+//go:embed sketch-linux/sketch-linux-arm64
+var sketchLinuxBinaryArm64 []byte
 
 // LinuxBinary returns the embedded linux binary.
-func LinuxBinary() []byte {
-	return sketchLinuxBinary
+func LinuxBinary(arch string) []byte {
+	switch arch {
+	case "amd64", "x86_64":
+		return sketchLinuxBinaryAmd64
+	case "arm64", "aarch64":
+		return sketchLinuxBinaryArm64
+	}
+	return nil
 }
 
 // WebUIFS returns the embedded webui filesystem.