feat(installer): arch detection + checksum verification
- Fix Windows config path in template (carry-over from Fix 1) - Add runtime arch detection in Linux installer (uname -m) - Add runtime arch detection in Windows installer - Add ?arch= query param to install endpoint - Serve X-Content-SHA256 header with binary downloads - Verify checksum in Linux and Windows installers - Warn (not fail) if server does not provide checksum 166 tests pass (106 server + 60 agent). No regressions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
147
docs/Installer_Fix2_Implementation.md
Normal file
147
docs/Installer_Fix2_Implementation.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# Installer Fix2 Implementation — Arch Detection + Checksum Verification
|
||||
|
||||
**Date:** 2026-03-29
|
||||
**Branch:** culurien
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Added runtime architecture detection and binary checksum verification to both Linux and Windows installer templates. Fixed carry-over Windows config path issue from Fix 1.
|
||||
|
||||
## Files Changed
|
||||
|
||||
### 1. `windows.ps1.tmpl` — Config path carry-over fix
|
||||
|
||||
**Problem:** Template wrote config to `C:\ProgramData\RedFlag\config.json` but the agent reads from `C:\ProgramData\RedFlag\agent\config.json` (canonical path from `constants.GetAgentConfigPath()`).
|
||||
|
||||
**Fix:**
|
||||
- Added `$AgentConfigDir = "C:\ProgramData\RedFlag\agent"` variable
|
||||
- Changed `$ConfigPath` to use `$AgentConfigDir` instead of `$ConfigDir`
|
||||
- Added `New-Item -ItemType Directory -Force -Path $AgentConfigDir` to directory creation
|
||||
- Removed redundant `$ConfigPath` re-assignment in Step 4
|
||||
|
||||
### 2. `windows.ps1.tmpl` — Architecture detection
|
||||
|
||||
**Added** runtime architecture detection using `$env:PROCESSOR_ARCHITECTURE`:
|
||||
```powershell
|
||||
switch ($Arch) {
|
||||
"AMD64" { $ArchTag = "amd64" }
|
||||
"ARM64" { $ArchTag = "arm64" }
|
||||
default { exit 1 }
|
||||
}
|
||||
```
|
||||
Download URL now uses the detected arch: `{{.ServerURL}}/api/v1/downloads/windows-${ArchTag}?version={{.Version}}`
|
||||
|
||||
### 3. `windows.ps1.tmpl` — Checksum verification
|
||||
|
||||
**Added** SHA256 verification after download:
|
||||
- Downloads to temp file first, uses `Invoke-WebRequest -PassThru` to capture headers
|
||||
- Reads `X-Content-SHA256` from response headers
|
||||
- Uses `Get-FileHash` with `.ToLower()` normalization for comparison
|
||||
- If checksum present and mismatches: error + exit
|
||||
- If checksum missing: warn + continue (backward compatible)
|
||||
- Moves verified binary to install dir after validation
|
||||
|
||||
### 4. `linux.sh.tmpl` — Architecture detection
|
||||
|
||||
**Added** runtime architecture detection using `uname -m`:
|
||||
```bash
|
||||
case $ARCH in
|
||||
x86_64) ARCH_TAG="amd64" ;;
|
||||
aarch64) ARCH_TAG="arm64" ;;
|
||||
armv7l) ARCH_TAG="armv7" ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
```
|
||||
Download URL overridden with detected arch: `{{.ServerURL}}/api/v1/downloads/linux-${ARCH_TAG}?version={{.Version}}`
|
||||
|
||||
### 5. `linux.sh.tmpl` — Checksum verification
|
||||
|
||||
**Added** SHA256 verification after download:
|
||||
- Downloads to temp file, saves response headers with `curl -D`
|
||||
- Extracts `X-Content-SHA256` from response headers
|
||||
- Compares with `sha256sum` output
|
||||
- If checksum present and mismatches: error + exit
|
||||
- If checksum missing: warn + continue
|
||||
- Moves verified binary to install dir after validation
|
||||
|
||||
### 6. `downloads.go` — Server-side checksum + arch support
|
||||
|
||||
**Checksum header:** Added `computeFileSHA256()` helper function and `X-Content-SHA256` + `X-Content-Length` headers to `DownloadAgent` handler. The checksum is computed on-the-fly from the binary file.
|
||||
|
||||
**Arch query param:** `generateInstallScript()` now reads optional `?arch=` query parameter (validated against `amd64`, `arm64`, `armv7`; defaults to `amd64`). This sets the arch in template data, but since templates now auto-detect at runtime, this serves as a fallback/hint.
|
||||
|
||||
### 7. `AgentManagement.tsx` — Dashboard updates
|
||||
|
||||
Updated platform descriptions to note ARM64 support:
|
||||
- Linux: "Ubuntu, Debian, RHEL, CentOS, AlmaLinux, Rocky Linux (AMD64 + ARM64)"
|
||||
- Windows: "Windows 10/11, Server 2019/2022 (AMD64 + ARM64)"
|
||||
|
||||
Extensions arrays updated to `['amd64', 'arm64']`.
|
||||
|
||||
### 8. `downloads_checksum_test.go` — New tests
|
||||
|
||||
3 new tests:
|
||||
- `TestChecksumComputesCorrectSHA256` — verifies known content produces expected hash
|
||||
- `TestChecksumIsLowercase` — confirms hex output is lowercase (PowerShell compatibility)
|
||||
- `TestChecksumEmptyFileProducesValidHash` — confirms empty files produce valid 64-char hash
|
||||
|
||||
## Design Decisions
|
||||
|
||||
### Arch Detection: Template Runtime vs Server Hint
|
||||
|
||||
Both approaches are used:
|
||||
- **Server-side:** `?arch=` query param on `/install/:platform` endpoint (default `amd64`)
|
||||
- **Template runtime:** `uname -m` / `$env:PROCESSOR_ARCHITECTURE` overrides the server-suggested download URL
|
||||
|
||||
The runtime detection is authoritative because the install script runs on the target machine and knows its actual architecture. The server hint is a fallback for programmatic use.
|
||||
|
||||
### Checksum: Warn Not Fail
|
||||
|
||||
If the server does not provide the `X-Content-SHA256` header (e.g., old server version), the installer warns but continues. This maintains backward compatibility with servers that haven't been updated.
|
||||
|
||||
## Test Results
|
||||
|
||||
```
|
||||
Server: 106 passed, 0 failed (7 packages)
|
||||
Agent: 60 passed, 0 failed (10 packages)
|
||||
Total: 166 tests, 0 failures
|
||||
TypeScript: 0 errors
|
||||
```
|
||||
|
||||
## Manual Test Plan Additions
|
||||
|
||||
### Linux Arch Detection
|
||||
- [ ] Run install on x86_64 — confirm downloads `linux-amd64` binary
|
||||
- [ ] Run install on aarch64 (Raspberry Pi, ARM VM) — confirm downloads `linux-arm64`
|
||||
- [ ] Run install on unsupported arch — confirm error message and exit
|
||||
|
||||
### Windows Arch Detection
|
||||
- [ ] Run install on AMD64 Windows — confirm downloads `windows-amd64`
|
||||
- [ ] Run install on ARM64 Windows — confirm downloads `windows-arm64`
|
||||
|
||||
### Checksum Verification
|
||||
- [ ] Download binary from server — confirm `X-Content-SHA256` header present
|
||||
- [ ] Corrupt downloaded binary, re-run verification — confirm failure detected
|
||||
- [ ] Run against server without checksum header — confirm warning but install proceeds
|
||||
|
||||
### Windows Config Path
|
||||
- [ ] Fresh Windows install — confirm config written to `C:\ProgramData\RedFlag\agent\config.json`
|
||||
- [ ] Registration step reads config from same path
|
||||
|
||||
## ETHOS Checklist
|
||||
|
||||
- [x] Windows config path fixed in template (carry-over)
|
||||
- [x] Arch auto-detected in Linux template (uname -m)
|
||||
- [x] Arch auto-detected in Windows template ($env:PROCESSOR_ARCHITECTURE)
|
||||
- [x] Server install endpoint accepts optional ?arch= param
|
||||
- [x] X-Content-SHA256 header served with binary downloads
|
||||
- [x] Linux installer verifies checksum (warns if missing)
|
||||
- [x] Windows installer verifies checksum (warns if missing)
|
||||
- [x] Checksum comparison is lowercase-normalized
|
||||
- [x] Checksum header test written and passing
|
||||
- [x] All 166 Go tests pass
|
||||
- [x] No emoji in new Go server code
|
||||
- [x] No banned words in new template text
|
||||
- [x] Backward compatible: missing checksum = warn not fail
|
||||
Reference in New Issue
Block a user