mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-24 04:33:17 +00:00
fix(updates): select ARM release archive from build variant
ARMv6 and ARMv7 server binaries both report GOARCH=arm. Read the release binary GOARM build setting and fail closed when it does not name a published server archive, rather than offering an ARMv7 update to ARMv6 installations. Cover the architecture mapping and document the installability boundary. Change-source: pulse-maintainer
This commit is contained in:
@@ -4048,6 +4048,10 @@ running architecture and tag. A missing exact archive leaves the download URL
|
||||
empty and the update unavailable; it must not fall back to another component,
|
||||
architecture or version. This keeps an incomplete release visible as metadata
|
||||
without presenting an unusable or wrong installation path.
|
||||
ARMv6 and ARMv7 are separate server archives despite both binaries reporting
|
||||
`GOARCH=arm`; the updater uses the release binary's embedded `GOARM` build
|
||||
setting to choose between them, and offers neither if that setting is missing
|
||||
or unrecognised. It must not assume ARMv7 for every ARM installation.
|
||||
Malformed metadata stays a hard error and only the typed over-limit condition
|
||||
may fall through to the feed. Proof:
|
||||
`internal/updates/issue2282_release_metadata_stream_test.go`.
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -112,12 +113,20 @@ func updateReleaseDownloadPrefix() string {
|
||||
}
|
||||
|
||||
func updateReleaseAssetForRuntime(tagName string) (ReleaseAsset, bool) {
|
||||
targetArch, ok := map[string]string{
|
||||
"amd64": "amd64",
|
||||
"arm64": "arm64",
|
||||
"arm": "armv7",
|
||||
"386": "386",
|
||||
}[runtime.GOARCH]
|
||||
armVariant := ""
|
||||
if runtime.GOARCH == "arm" {
|
||||
// GOARCH alone cannot distinguish the separately published ARMv6 and
|
||||
// ARMv7 server binaries. Release builds record their GOARM setting.
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
for _, setting := range info.Settings {
|
||||
if setting.Key == "GOARM" {
|
||||
armVariant = setting.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetArch, ok := updateReleaseArchitecture(runtime.GOARCH, armVariant)
|
||||
if !ok {
|
||||
return ReleaseAsset{}, false
|
||||
}
|
||||
@@ -132,6 +141,20 @@ func updateReleaseAssetForRuntime(tagName string) (ReleaseAsset, bool) {
|
||||
return ReleaseAsset{Name: assetName, BrowserDownloadURL: downloadURL}, true
|
||||
}
|
||||
|
||||
func updateReleaseArchitecture(goarch, goarm string) (string, bool) {
|
||||
switch goarch {
|
||||
case "amd64", "arm64", "386":
|
||||
return goarch, true
|
||||
case "arm":
|
||||
// GOARM=5 has no server archive. An absent or unknown variant must not
|
||||
// silently select ARMv7, which may not run on an ARMv6 host.
|
||||
if goarm == "6" || goarm == "7" {
|
||||
return "armv" + goarm, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func updateReleaseAPIPath() string {
|
||||
return fmt.Sprintf("/repos/%s/releases", updateReleaseRepo())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package updates
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestUpdateReleaseArchitectureRequiresMatchingARMVariant(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
goarch, goarm, want string
|
||||
ok bool
|
||||
}{
|
||||
{goarch: "amd64", want: "amd64", ok: true},
|
||||
{goarch: "arm64", want: "arm64", ok: true},
|
||||
{goarch: "386", want: "386", ok: true},
|
||||
{goarch: "arm", goarm: "6", want: "armv6", ok: true},
|
||||
{goarch: "arm", goarm: "7", want: "armv7", ok: true},
|
||||
{goarch: "arm", goarm: "5"},
|
||||
{goarch: "arm"},
|
||||
{goarch: "arm", goarm: "unknown"},
|
||||
{goarch: "riscv64"},
|
||||
} {
|
||||
got, ok := updateReleaseArchitecture(tc.goarch, tc.goarm)
|
||||
if got != tc.want || ok != tc.ok {
|
||||
t.Errorf("updateReleaseArchitecture(%q, %q) = (%q, %t), want (%q, %t)", tc.goarch, tc.goarm, got, ok, tc.want, tc.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user