From 0fde4b3b2ec6949086d5f8b810e1ea35141377a2 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Mon, 1 Dec 2014 10:24:13 +0100 Subject: [PATCH] Use runtime info to determine ARM version for upgrade (fixes #1051) --- build.go | 18 ++--------- cmd/syncthing/gui.go | 2 +- cmd/syncthing/main.go | 5 ++- internal/upgrade/releasename_darwin.go | 25 +++++++++++++++ internal/upgrade/releasename_linux_arm.go | 38 +++++++++++++++++++++++ internal/upgrade/releasename_other.go | 27 ++++++++++++++++ internal/upgrade/upgrade_common.go | 4 +-- internal/upgrade/upgrade_supported.go | 11 ++----- internal/upgrade/upgrade_unsupp.go | 2 +- internal/upgrade/upgrade_windows.go | 5 ++- 10 files changed, 103 insertions(+), 34 deletions(-) create mode 100644 internal/upgrade/releasename_darwin.go create mode 100644 internal/upgrade/releasename_linux_arm.go create mode 100644 internal/upgrade/releasename_other.go diff --git a/build.go b/build.go index 32639b8ee..5b75f318e 100644 --- a/build.go +++ b/build.go @@ -72,17 +72,8 @@ func main() { flag.Parse() switch goarch { - case "386", "amd64", "armv5", "armv6", "armv7": + case "386", "amd64", "arm", "armv5", "armv6", "armv7": break - case "arm": - switch os.Getenv("GOARM") { - case "5", "6", "7": - goarch += "v" + os.Getenv("GOARM") - break - default: - log.Println("Invalid goarch \"arm\". Use one of \"armv5\", \"armv6\", \"armv7\".") - log.Fatalln("Note that producing a correct \"armv5\" binary requires a rebuilt stdlib.") - } default: log.Printf("Unknown goarch %q; proceed with caution!", goarch) } @@ -161,7 +152,7 @@ func checkRequiredGoVersion() { // This is a standard go build. Verify that it's new enough. f, err := strconv.ParseFloat(vs, 64) if err != nil { - log.Printf("*** Could parse Go version out of %q.\n*** This isn't known to work, proceed on your own risk.", vs) + log.Printf("*** Couldn't parse Go version out of %q.\n*** This isn't known to work, proceed on your own risk.", vs) return } if f < minGoVersion { @@ -269,7 +260,7 @@ func listFiles(dir string) []string { func setBuildEnv() { os.Setenv("GOOS", goos) - if strings.HasPrefix(goarch, "arm") { + if strings.HasPrefix(goarch, "armv") { os.Setenv("GOARCH", "arm") os.Setenv("GOARM", goarch[4:]) } else { @@ -334,9 +325,6 @@ func ldflags() string { b.WriteString(fmt.Sprintf(" -X main.BuildUser %s", buildUser())) b.WriteString(fmt.Sprintf(" -X main.BuildHost %s", buildHost())) b.WriteString(fmt.Sprintf(" -X main.BuildEnv %s", buildEnvironment())) - if strings.HasPrefix(goarch, "arm") { - b.WriteString(fmt.Sprintf(" -X main.GoArchExtra %s", goarch[3:])) - } return b.String() } diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index 19395b6b2..22eecad45 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -598,7 +598,7 @@ func restPostUpgrade(w http.ResponseWriter, r *http.Request) { } if upgrade.CompareVersions(rel.Tag, Version) == 1 { - err = upgrade.UpgradeTo(rel, GoArchExtra) + err = upgrade.UpgradeTo(rel) if err != nil { l.Warnln("upgrading:", err) http.Error(w, err.Error(), 500) diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index 28919b496..9fcf5a41d 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -62,7 +62,6 @@ var ( IsRelease bool IsBeta bool LongVersion string - GoArchExtra string // "", "v5", "v6", "v7" ) const ( @@ -329,7 +328,7 @@ func main() { l.Fatalln("Cannot upgrade, database seems to be locked. Is another copy of Syncthing already running?") } - err = upgrade.UpgradeTo(rel, GoArchExtra) + err = upgrade.UpgradeTo(rel) if err != nil { l.Fatalln("Upgrade:", err) // exits 1 } @@ -1246,7 +1245,7 @@ func autoUpgrade() { } l.Infof("Automatic upgrade (current %q < latest %q)", Version, rel.Tag) - err = upgrade.UpgradeTo(rel, GoArchExtra) + err = upgrade.UpgradeTo(rel) if err != nil { l.Warnln("Automatic upgrade:", err) continue diff --git a/internal/upgrade/releasename_darwin.go b/internal/upgrade/releasename_darwin.go new file mode 100644 index 000000000..6ae1c28a3 --- /dev/null +++ b/internal/upgrade/releasename_darwin.go @@ -0,0 +1,25 @@ +// Copyright (C) 2014 The Syncthing Authors. +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see . + +package upgrade + +import ( + "fmt" + "runtime" +) + +func releaseName(tag string) string { + return fmt.Sprintf("syncthing-macosx-%s-%s.", runtime.GOARCH, tag) +} diff --git a/internal/upgrade/releasename_linux_arm.go b/internal/upgrade/releasename_linux_arm.go new file mode 100644 index 000000000..8f2f64860 --- /dev/null +++ b/internal/upgrade/releasename_linux_arm.go @@ -0,0 +1,38 @@ +// Copyright (C) 2014 The Syncthing Authors. +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see . + +package upgrade + +import ( + "fmt" + "strings" + "syscall" +) + +func releaseName(tag string) string { + return fmt.Sprintf("syncthing-linux-armv%s-%s.", goARM(), tag) +} + +// Get the current ARM architecture version for upgrade purposes. If we can't +// figure it out from the uname, default to ARMv6 (same as Go distribution). +func goARM() string { + var name syscall.Utsname + syscall.Uname(&name) + machine := string(name.Machine[:5]) + if strings.HasPrefix(machine, "armv") { + return machine[4:] + } + return "6" +} diff --git a/internal/upgrade/releasename_other.go b/internal/upgrade/releasename_other.go new file mode 100644 index 000000000..791cd6180 --- /dev/null +++ b/internal/upgrade/releasename_other.go @@ -0,0 +1,27 @@ +// Copyright (C) 2014 The Syncthing Authors. +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see . + +// +build !arm,!darwin + +package upgrade + +import ( + "fmt" + "runtime" +) + +func releaseName(tag string) string { + return fmt.Sprintf("syncthing-%s-%s-%s.", runtime.GOOS, runtime.GOARCH, tag) +} diff --git a/internal/upgrade/upgrade_common.go b/internal/upgrade/upgrade_common.go index bcbe283cb..6cc6d9582 100644 --- a/internal/upgrade/upgrade_common.go +++ b/internal/upgrade/upgrade_common.go @@ -48,7 +48,7 @@ func init() { } // A wrapper around actual implementations -func UpgradeTo(rel Release, archExtra string) error { +func UpgradeTo(rel Release) error { select { case <-upgradeUnlocked: path, err := osext.Executable() @@ -56,7 +56,7 @@ func UpgradeTo(rel Release, archExtra string) error { upgradeUnlocked <- true return err } - err = upgradeTo(path, rel, archExtra) + err = upgradeTo(path, rel) // If we've failed to upgrade, unlock so that another attempt could be made if err != nil { upgradeUnlocked <- true diff --git a/internal/upgrade/upgrade_supported.go b/internal/upgrade/upgrade_supported.go index 1616f3798..dc2ec719d 100644 --- a/internal/upgrade/upgrade_supported.go +++ b/internal/upgrade/upgrade_supported.go @@ -28,19 +28,12 @@ import ( "os" "path" "path/filepath" - "runtime" "strings" ) // Upgrade to the given release, saving the previous binary with a ".old" extension. -func upgradeTo(path string, rel Release, archExtra string) error { - osName := runtime.GOOS - if osName == "darwin" { - // We call the darwin release bundles macosx because that makes more - // sense for people downloading them - osName = "macosx" - } - expectedRelease := fmt.Sprintf("syncthing-%s-%s%s-%s.", osName, runtime.GOARCH, archExtra, rel.Tag) +func upgradeTo(path string, rel Release) error { + expectedRelease := releaseName(rel.Tag) if debug { l.Debugf("expected release asset %q", expectedRelease) } diff --git a/internal/upgrade/upgrade_unsupp.go b/internal/upgrade/upgrade_unsupp.go index 444089ed7..8f6c7314c 100644 --- a/internal/upgrade/upgrade_unsupp.go +++ b/internal/upgrade/upgrade_unsupp.go @@ -17,7 +17,7 @@ package upgrade -func upgradeTo(path string, rel Release, extra string) error { +func upgradeTo(path string, rel Release) error { return ErrUpgradeUnsupported } diff --git a/internal/upgrade/upgrade_windows.go b/internal/upgrade/upgrade_windows.go index d30c6e493..9627f7cf9 100644 --- a/internal/upgrade/upgrade_windows.go +++ b/internal/upgrade/upgrade_windows.go @@ -28,13 +28,12 @@ import ( "os" "path" "path/filepath" - "runtime" "strings" ) // Upgrade to the given release, saving the previous binary with a ".old" extension. -func upgradeTo(path string, rel Release, archExtra string) error { - expectedRelease := fmt.Sprintf("syncthing-%s-%s%s-%s.", runtime.GOOS, runtime.GOARCH, archExtra, rel.Tag) +func upgradeTo(path string, rel Release) error { + expectedRelease := releaseName(rel.Tag) if debug { l.Debugf("expected release asset %q", expectedRelease) }