all: Use new reflect based CLI (#5487)

This commit is contained in:
Audrius Butkevicius
2019-02-12 06:58:24 +00:00
committed by Jakob Borg
parent 7bac927ac8
commit dc929946fe
37 changed files with 944 additions and 1723 deletions

View File

@@ -1,13 +0,0 @@
// Copyright (C) 2017 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
//+build noupgrade
package main
func init() {
BuildTags = append(BuildTags, "noupgrade")
}

View File

@@ -1,13 +0,0 @@
// Copyright (C) 2017 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
//+build race
package main
func init() {
BuildTags = append(BuildTags, "race")
}

View File

@@ -28,12 +28,14 @@ import (
"time"
metrics "github.com/rcrowley/go-metrics"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/connections"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/discover"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/locations"
"github.com/syncthing/syncthing/lib/logger"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/protocol"
@@ -567,7 +569,7 @@ func noCacheMiddleware(h http.Handler) http.Handler {
func withDetailsMiddleware(id protocol.DeviceID, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Syncthing-Version", Version)
w.Header().Set("X-Syncthing-Version", build.Version)
w.Header().Set("X-Syncthing-ID", id.String())
h.ServeHTTP(w, r)
})
@@ -609,14 +611,14 @@ func (s *apiService) getJSMetadata(w http.ResponseWriter, r *http.Request) {
func (s *apiService) getSystemVersion(w http.ResponseWriter, r *http.Request) {
sendJSON(w, map[string]interface{}{
"version": Version,
"codename": Codename,
"longVersion": LongVersion,
"version": build.Version,
"codename": build.Codename,
"longVersion": build.LongVersion,
"os": runtime.GOOS,
"arch": runtime.GOARCH,
"isBeta": IsBeta,
"isCandidate": IsCandidate,
"isRelease": IsRelease,
"isBeta": build.IsBeta,
"isCandidate": build.IsCandidate,
"isRelease": build.IsRelease,
})
}
@@ -1080,7 +1082,7 @@ func (s *apiService) getSupportBundle(w http.ResponseWriter, r *http.Request) {
}
// Panic files
if panicFiles, err := filepath.Glob(filepath.Join(baseDirs["config"], "panic*")); err == nil {
if panicFiles, err := filepath.Glob(filepath.Join(locations.GetBaseDir(locations.ConfigBaseDir), "panic*")); err == nil {
for _, f := range panicFiles {
if panicFile, err := ioutil.ReadFile(f); err != nil {
l.Warnf("Support bundle: failed to load %s: %s", filepath.Base(f), err)
@@ -1091,16 +1093,16 @@ func (s *apiService) getSupportBundle(w http.ResponseWriter, r *http.Request) {
}
// Archived log (default on Windows)
if logFile, err := ioutil.ReadFile(locations[locLogFile]); err == nil {
if logFile, err := ioutil.ReadFile(locations.Get(locations.LogFile)); err == nil {
files = append(files, fileEntry{name: "log-ondisk.txt", data: logFile})
}
// Version and platform information as a JSON
if versionPlatform, err := json.MarshalIndent(map[string]string{
"now": time.Now().Format(time.RFC3339),
"version": Version,
"codename": Codename,
"longVersion": LongVersion,
"version": build.Version,
"codename": build.Codename,
"longVersion": build.LongVersion,
"os": runtime.GOOS,
"arch": runtime.GOARCH,
}, "", " "); err == nil {
@@ -1118,14 +1120,14 @@ func (s *apiService) getSupportBundle(w http.ResponseWriter, r *http.Request) {
// Heap and CPU Proofs as a pprof extension
var heapBuffer, cpuBuffer bytes.Buffer
filename := fmt.Sprintf("syncthing-heap-%s-%s-%s-%s.pprof", runtime.GOOS, runtime.GOARCH, Version, time.Now().Format("150405")) // hhmmss
filename := fmt.Sprintf("syncthing-heap-%s-%s-%s-%s.pprof", runtime.GOOS, runtime.GOARCH, build.Version, time.Now().Format("150405")) // hhmmss
runtime.GC()
if err := pprof.WriteHeapProfile(&heapBuffer); err == nil {
files = append(files, fileEntry{name: filename, data: heapBuffer.Bytes()})
}
const duration = 4 * time.Second
filename = fmt.Sprintf("syncthing-cpu-%s-%s-%s-%s.pprof", runtime.GOOS, runtime.GOARCH, Version, time.Now().Format("150405")) // hhmmss
filename = fmt.Sprintf("syncthing-cpu-%s-%s-%s-%s.pprof", runtime.GOOS, runtime.GOARCH, build.Version, time.Now().Format("150405")) // hhmmss
if err := pprof.StartCPUProfile(&cpuBuffer); err == nil {
time.Sleep(duration)
pprof.StopCPUProfile()
@@ -1142,7 +1144,7 @@ func (s *apiService) getSupportBundle(w http.ResponseWriter, r *http.Request) {
// Set zip file name and path
zipFileName := fmt.Sprintf("support-bundle-%s-%s.zip", s.id.Short().String(), time.Now().Format("2006-01-02T150405"))
zipFilePath := filepath.Join(baseDirs["config"], zipFileName)
zipFilePath := filepath.Join(locations.GetBaseDir(locations.ConfigBaseDir), zipFileName)
// Write buffer zip to local zip file (back up)
if err := ioutil.WriteFile(zipFilePath, zipFilesBuffer.Bytes(), 0600); err != nil {
@@ -1323,16 +1325,16 @@ func (s *apiService) getSystemUpgrade(w http.ResponseWriter, r *http.Request) {
return
}
opts := s.cfg.Options()
rel, err := upgrade.LatestRelease(opts.ReleasesURL, Version, opts.UpgradeToPreReleases)
rel, err := upgrade.LatestRelease(opts.ReleasesURL, build.Version, opts.UpgradeToPreReleases)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
res := make(map[string]interface{})
res["running"] = Version
res["running"] = build.Version
res["latest"] = rel.Tag
res["newer"] = upgrade.CompareVersions(rel.Tag, Version) == upgrade.Newer
res["majorNewer"] = upgrade.CompareVersions(rel.Tag, Version) == upgrade.MajorNewer
res["newer"] = upgrade.CompareVersions(rel.Tag, build.Version) == upgrade.Newer
res["majorNewer"] = upgrade.CompareVersions(rel.Tag, build.Version) == upgrade.MajorNewer
sendJSON(w, res)
}
@@ -1365,14 +1367,14 @@ func (s *apiService) getLang(w http.ResponseWriter, r *http.Request) {
func (s *apiService) postSystemUpgrade(w http.ResponseWriter, r *http.Request) {
opts := s.cfg.Options()
rel, err := upgrade.LatestRelease(opts.ReleasesURL, Version, opts.UpgradeToPreReleases)
rel, err := upgrade.LatestRelease(opts.ReleasesURL, build.Version, opts.UpgradeToPreReleases)
if err != nil {
l.Warnln("getting latest release:", err)
http.Error(w, err.Error(), 500)
return
}
if upgrade.CompareVersions(rel.Tag, Version) > upgrade.Equal {
if upgrade.CompareVersions(rel.Tag, build.Version) > upgrade.Equal {
err = upgrade.To(rel)
if err != nil {
l.Warnln("upgrading:", err)
@@ -1641,7 +1643,7 @@ func (s *apiService) getCPUProf(w http.ResponseWriter, r *http.Request) {
duration = 30 * time.Second
}
filename := fmt.Sprintf("syncthing-cpu-%s-%s-%s-%s.pprof", runtime.GOOS, runtime.GOARCH, Version, time.Now().Format("150405")) // hhmmss
filename := fmt.Sprintf("syncthing-cpu-%s-%s-%s-%s.pprof", runtime.GOOS, runtime.GOARCH, build.Version, time.Now().Format("150405")) // hhmmss
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Disposition", "attachment; filename="+filename)
@@ -1653,7 +1655,7 @@ func (s *apiService) getCPUProf(w http.ResponseWriter, r *http.Request) {
}
func (s *apiService) getHeapProf(w http.ResponseWriter, r *http.Request) {
filename := fmt.Sprintf("syncthing-heap-%s-%s-%s-%s.pprof", runtime.GOOS, runtime.GOARCH, Version, time.Now().Format("150405")) // hhmmss
filename := fmt.Sprintf("syncthing-heap-%s-%s-%s-%s.pprof", runtime.GOOS, runtime.GOARCH, build.Version, time.Now().Format("150405")) // hhmmss
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Disposition", "attachment; filename="+filename)

View File

@@ -14,6 +14,7 @@ import (
"strings"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/locations"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/rand"
"github.com/syncthing/syncthing/lib/sync"
@@ -115,7 +116,7 @@ func saveCsrfTokens() {
// We're ignoring errors in here. It's not super critical and there's
// nothing relevant we can do about them anyway...
name := locations[locCsrfTokens]
name := locations.Get(locations.CsrfTokens)
f, err := osutil.CreateAtomic(name)
if err != nil {
return
@@ -129,7 +130,7 @@ func saveCsrfTokens() {
}
func loadCsrfTokens() {
f, err := os.Open(locations[locCsrfTokens])
f, err := os.Open(locations.Get(locations.CsrfTokens))
if err != nil {
return
}

View File

@@ -1,125 +0,0 @@
// Copyright (C) 2015 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
import (
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/syncthing/syncthing/lib/fs"
)
type locationEnum string
// Use strings as keys to make printout and serialization of the locations map
// more meaningful.
const (
locConfigFile locationEnum = "config"
locCertFile locationEnum = "certFile"
locKeyFile locationEnum = "keyFile"
locHTTPSCertFile locationEnum = "httpsCertFile"
locHTTPSKeyFile locationEnum = "httpsKeyFile"
locDatabase locationEnum = "database"
locLogFile locationEnum = "logFile"
locCsrfTokens locationEnum = "csrfTokens"
locPanicLog locationEnum = "panicLog"
locAuditLog locationEnum = "auditLog"
locGUIAssets locationEnum = "GUIAssets"
locDefFolder locationEnum = "defFolder"
)
// Platform dependent directories
var baseDirs = map[string]string{
"config": defaultConfigDir(), // Overridden by -home flag
"home": homeDir(), // User's home directory, *not* -home flag
}
// Use the variables from baseDirs here
var locations = map[locationEnum]string{
locConfigFile: "${config}/config.xml",
locCertFile: "${config}/cert.pem",
locKeyFile: "${config}/key.pem",
locHTTPSCertFile: "${config}/https-cert.pem",
locHTTPSKeyFile: "${config}/https-key.pem",
locDatabase: "${config}/index-v0.14.0.db",
locLogFile: "${config}/syncthing.log", // -logfile on Windows
locCsrfTokens: "${config}/csrftokens.txt",
locPanicLog: "${config}/panic-${timestamp}.log",
locAuditLog: "${config}/audit-${timestamp}.log",
locGUIAssets: "${config}/gui",
locDefFolder: "${home}/Sync",
}
// expandLocations replaces the variables in the location map with actual
// directory locations.
func expandLocations() error {
for key, dir := range locations {
for varName, value := range baseDirs {
dir = strings.Replace(dir, "${"+varName+"}", value, -1)
}
var err error
dir, err = fs.ExpandTilde(dir)
if err != nil {
return err
}
locations[key] = dir
}
return nil
}
// defaultConfigDir returns the default configuration directory, as figured
// out by various the environment variables present on each platform, or dies
// trying.
func defaultConfigDir() string {
switch runtime.GOOS {
case "windows":
if p := os.Getenv("LocalAppData"); p != "" {
return filepath.Join(p, "Syncthing")
}
return filepath.Join(os.Getenv("AppData"), "Syncthing")
case "darwin":
dir, err := fs.ExpandTilde("~/Library/Application Support/Syncthing")
if err != nil {
l.Fatalln(err)
}
return dir
default:
if xdgCfg := os.Getenv("XDG_CONFIG_HOME"); xdgCfg != "" {
return filepath.Join(xdgCfg, "syncthing")
}
dir, err := fs.ExpandTilde("~/.config/syncthing")
if err != nil {
l.Fatalln(err)
}
return dir
}
}
// homeDir returns the user's home directory, or dies trying.
func homeDir() string {
home, err := fs.ExpandTilde("~")
if err != nil {
l.Fatalln(err)
}
return home
}
func timestampedLoc(key locationEnum) string {
// We take the roundtrip via "${timestamp}" instead of passing the path
// directly through time.Format() to avoid issues when the path we are
// expanding contains numbers; otherwise for example
// /home/user2006/.../panic-20060102-150405.log would get both instances of
// 2006 replaced by 2015...
tpl := locations[key]
now := time.Now().Format("20060102-150405")
return strings.Replace(tpl, "${timestamp}", now, -1)
}

View File

@@ -16,12 +16,12 @@ import (
"io/ioutil"
"log"
"net/http"
_ "net/http/pprof" // Need to import this to support STPROFILER.
"net/url"
"os"
"os/signal"
"path"
"path/filepath"
"regexp"
"runtime"
"runtime/pprof"
"sort"
@@ -30,6 +30,7 @@ import (
"syscall"
"time"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/connections"
"github.com/syncthing/syncthing/lib/db"
@@ -37,6 +38,7 @@ import (
"github.com/syncthing/syncthing/lib/discover"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/locations"
"github.com/syncthing/syncthing/lib/logger"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/osutil"
@@ -47,23 +49,6 @@ import (
"github.com/syncthing/syncthing/lib/upgrade"
"github.com/thejerf/suture"
_ "net/http/pprof" // Need to import this to support STPROFILER.
)
var (
Version = "unknown-dev"
Codename = "Erbium Earthworm"
BuildStamp = "0"
BuildDate time.Time
BuildHost = "unknown"
BuildUser = "unknown"
IsRelease bool
IsCandidate bool
IsBeta bool
LongVersion string
BuildTags []string
allowedVersionExp = regexp.MustCompile(`^v\d+\.\d+\.\d+(-[a-z0-9]+)*(\.\d+)*(\+\d+-g[0-9a-f]+)?(-[^\s]+)?$`)
)
const (
@@ -83,46 +68,6 @@ const (
maxSystemLog = 250
)
func init() {
if Version != "unknown-dev" {
// If not a generic dev build, version string should come from git describe
if !allowedVersionExp.MatchString(Version) {
l.Fatalf("Invalid version string %q;\n\tdoes not match regexp %v", Version, allowedVersionExp)
}
}
}
func setBuildMetadata() {
// Check for a clean release build. A release is something like
// "v0.1.2", with an optional suffix of letters and dot separated
// numbers like "-beta3.47". If there's more stuff, like a plus sign and
// a commit hash and so on, then it's not a release. If it has a dash in
// it, it's some sort of beta, release candidate or special build. If it
// has "-rc." in it, like "v0.14.35-rc.42", then it's a candidate build.
//
// So, every build that is not a stable release build has IsBeta = true.
// This is used to enable some extra debugging (the deadlock detector).
//
// Release candidate builds are also "betas" from this point of view and
// will have that debugging enabled. In addition, some features are
// forced for release candidates - auto upgrade, and usage reporting.
exp := regexp.MustCompile(`^v\d+\.\d+\.\d+(-[a-z]+[\d\.]+)?$`)
IsRelease = exp.MatchString(Version)
IsCandidate = strings.Contains(Version, "-rc.")
IsBeta = strings.Contains(Version, "-")
stamp, _ := strconv.Atoi(BuildStamp)
BuildDate = time.Unix(int64(stamp), 0)
date := BuildDate.UTC().Format("2006-01-02 15:04:05 MST")
LongVersion = fmt.Sprintf(`syncthing %s "%s" (%s %s-%s) %s@%s %s`, Version, Codename, runtime.Version(), runtime.GOOS, runtime.GOARCH, BuildUser, BuildHost, date)
if len(BuildTags) > 0 {
LongVersion = fmt.Sprintf("%s [%s]", LongVersion, strings.Join(BuildTags, ", "))
}
}
var (
myID protocol.DeviceID
stop = make(chan int)
@@ -320,8 +265,6 @@ func parseCommandLineOptions() RuntimeOptions {
}
func main() {
setBuildMetadata()
options := parseCommandLineOptions()
l.SetFlags(options.logFlags)
@@ -355,27 +298,25 @@ func main() {
l.Fatalln(err)
}
}
baseDirs["config"] = options.confDir
}
if err := expandLocations(); err != nil {
l.Fatalln(err)
if err := locations.SetBaseDir(locations.ConfigBaseDir, options.confDir); err != nil {
l.Fatalln(err)
}
}
if options.logFile == "" {
// Blank means use the default logfile location. We must set this
// *after* expandLocations above.
options.logFile = locations[locLogFile]
options.logFile = locations.Get(locations.LogFile)
}
if options.assetDir == "" {
// The asset dir is blank if STGUIASSETS wasn't set, in which case we
// should look for extra assets in the default place.
options.assetDir = locations[locGUIAssets]
options.assetDir = locations.Get(locations.GUIAssets)
}
if options.showVersion {
fmt.Println(LongVersion)
fmt.Println(build.LongVersion)
return
}
@@ -390,7 +331,10 @@ func main() {
}
if options.showDeviceId {
cert, err := tls.LoadX509KeyPair(locations[locCertFile], locations[locKeyFile])
cert, err := tls.LoadX509KeyPair(
locations.Get(locations.CertFile),
locations.Get(locations.KeyFile),
)
if err != nil {
l.Fatalln("Error reading device ID:", err)
}
@@ -411,7 +355,7 @@ func main() {
}
// Ensure that our home directory exists.
ensureDir(baseDirs["config"], 0700)
ensureDir(locations.GetBaseDir(locations.ConfigBaseDir), 0700)
if options.upgradeTo != "" {
err := upgrade.ToURL(options.upgradeTo)
@@ -521,24 +465,24 @@ func debugFacilities() string {
func checkUpgrade() upgrade.Release {
cfg, _ := loadOrDefaultConfig()
opts := cfg.Options()
release, err := upgrade.LatestRelease(opts.ReleasesURL, Version, opts.UpgradeToPreReleases)
release, err := upgrade.LatestRelease(opts.ReleasesURL, build.Version, opts.UpgradeToPreReleases)
if err != nil {
l.Fatalln("Upgrade:", err)
}
if upgrade.CompareVersions(release.Tag, Version) <= 0 {
if upgrade.CompareVersions(release.Tag, build.Version) <= 0 {
noUpgradeMessage := "No upgrade available (current %q >= latest %q)."
l.Infof(noUpgradeMessage, Version, release.Tag)
l.Infof(noUpgradeMessage, build.Version, release.Tag)
os.Exit(exitNoUpgradeAvailable)
}
l.Infof("Upgrade available (current %q < latest %q)", Version, release.Tag)
l.Infof("Upgrade available (current %q < latest %q)", build.Version, release.Tag)
return release
}
func performUpgrade(release upgrade.Release) {
// Use leveldb database locks to protect against concurrent upgrades
_, err := db.Open(locations[locDatabase])
_, err := db.Open(locations.Get(locations.Database))
if err == nil {
err = upgrade.To(release)
if err != nil {
@@ -636,10 +580,17 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
osutil.MaximizeOpenFileLimit()
// Ensure that we have a certificate and key.
cert, err := tls.LoadX509KeyPair(locations[locCertFile], locations[locKeyFile])
cert, err := tls.LoadX509KeyPair(
locations.Get(locations.CertFile),
locations.Get(locations.KeyFile),
)
if err != nil {
l.Infof("Generating ECDSA key and certificate for %s...", tlsDefaultCommonName)
cert, err = tlsutil.NewCertificate(locations[locCertFile], locations[locKeyFile], tlsDefaultCommonName)
cert, err = tlsutil.NewCertificate(
locations.Get(locations.CertFile),
locations.Get(locations.KeyFile),
tlsDefaultCommonName,
)
if err != nil {
l.Fatalln(err)
}
@@ -648,7 +599,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
myID = protocol.NewDeviceID(cert.Certificate[0])
l.SetPrefix(fmt.Sprintf("[%s] ", myID.String()[:5]))
l.Infoln(LongVersion)
l.Infoln(build.LongVersion)
l.Infoln("My ID:", myID)
// Select SHA256 implementation and report. Affected by the
@@ -659,7 +610,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
// Emit the Starting event, now that we know who we are.
events.Default.Log(events.Starting, map[string]string{
"home": baseDirs["config"],
"home": locations.GetBaseDir(locations.ConfigBaseDir),
"myID": myID.String(),
})
@@ -683,7 +634,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
perf := cpuBench(3, 150*time.Millisecond, true)
l.Infof("Hashing performance is %.02f MB/s", perf)
dbFile := locations[locDatabase]
dbFile := locations.Get(locations.Database)
ldb, err := db.Open(dbFile)
if err != nil {
l.Fatalln("Error opening database:", err)
@@ -698,10 +649,10 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
}
protectedFiles := []string{
locations[locDatabase],
locations[locConfigFile],
locations[locCertFile],
locations[locKeyFile],
locations.Get(locations.Database),
locations.Get(locations.ConfigFile),
locations.Get(locations.CertFile),
locations.Get(locations.KeyFile),
}
// Remove database entries for folders that no longer exist in the config
@@ -723,10 +674,10 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
// 0.14.45-pineapple is not.
prevParts := strings.Split(prevVersion, "-")
curParts := strings.Split(Version, "-")
curParts := strings.Split(build.Version, "-")
if prevParts[0] != curParts[0] {
if prevVersion != "" {
l.Infoln("Detected upgrade from", prevVersion, "to", Version)
l.Infoln("Detected upgrade from", prevVersion, "to", build.Version)
}
// Drop delta indexes in case we've changed random stuff we
@@ -734,16 +685,16 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
db.DropDeltaIndexIDs(ldb)
// Remember the new version.
miscDB.PutString("prevVersion", Version)
miscDB.PutString("prevVersion", build.Version)
}
m := model.NewModel(cfg, myID, "syncthing", Version, ldb, protectedFiles)
m := model.NewModel(cfg, myID, "syncthing", build.Version, ldb, protectedFiles)
if t := os.Getenv("STDEADLOCKTIMEOUT"); t != "" {
if secs, _ := strconv.Atoi(t); secs > 0 {
m.StartDeadlockDetector(time.Duration(secs) * time.Second)
}
} else if !IsRelease || IsBeta {
} else if !build.IsRelease || build.IsBeta {
m.StartDeadlockDetector(20 * time.Minute)
}
@@ -842,7 +793,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
// Candidate builds always run with usage reporting.
if opts := cfg.Options(); IsCandidate {
if opts := cfg.Options(); build.IsCandidate {
l.Infoln("Anonymous usage reporting is always enabled for candidate releases.")
if opts.URAccepted != usageReportVersion {
opts.URAccepted = usageReportVersion
@@ -870,7 +821,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
// unless we are in a build where it's disabled or the STNOUPGRADE
// environment variable is set.
if IsCandidate && !upgrade.DisabledByCompilation && !noUpgradeFromEnv {
if build.IsCandidate && !upgrade.DisabledByCompilation && !noUpgradeFromEnv {
l.Infoln("Automatic upgrade is always enabled for candidate releases.")
if opts := cfg.Options(); opts.AutoUpgradeIntervalH == 0 || opts.AutoUpgradeIntervalH > 24 {
opts.AutoUpgradeIntervalH = 12
@@ -943,7 +894,7 @@ func setupSignalHandling() {
}
func loadOrDefaultConfig() (*config.Wrapper, error) {
cfgFile := locations[locConfigFile]
cfgFile := locations.Get(locations.ConfigFile)
cfg, err := config.Load(cfgFile, myID)
if err != nil {
@@ -954,7 +905,7 @@ func loadOrDefaultConfig() (*config.Wrapper, error) {
}
func loadConfigAtStartup() *config.Wrapper {
cfgFile := locations[locConfigFile]
cfgFile := locations.Get(locations.ConfigFile)
cfg, err := config.Load(cfgFile, myID)
if os.IsNotExist(err) {
cfg = defaultConfig(cfgFile)
@@ -1018,7 +969,7 @@ func startAuditing(mainService *suture.Supervisor, auditFile string) {
auditDest = "stderr"
} else {
if auditFile == "" {
auditFile = timestampedLoc(locAuditLog)
auditFile = locations.GetTimestamped(locations.AuditLog)
auditFlags = os.O_WRONLY | os.O_CREATE | os.O_EXCL
} else {
auditFlags = os.O_WRONLY | os.O_CREATE | os.O_APPEND
@@ -1054,7 +1005,7 @@ func setupGUI(mainService *suture.Supervisor, cfg *config.Wrapper, m *model.Mode
cpu := newCPUService()
mainService.Add(cpu)
api := newAPIService(myID, cfg, locations[locHTTPSCertFile], locations[locHTTPSKeyFile], runtimeOptions.assetDir, m, defaultSub, diskSub, discoverer, connectionsService, errors, systemLog, cpu)
api := newAPIService(myID, cfg, locations.Get(locations.HTTPSCertFile), locations.Get(locations.HTTPSKeyFile), runtimeOptions.assetDir, m, defaultSub, diskSub, discoverer, connectionsService, errors, systemLog, cpu)
cfg.Subscribe(api)
mainService.Add(api)
@@ -1074,13 +1025,13 @@ func defaultConfig(cfgFile string) *config.Wrapper {
return config.Wrap(cfgFile, newCfg)
}
newCfg.Folders = append(newCfg.Folders, config.NewFolderConfiguration(myID, "default", "Default Folder", fs.FilesystemTypeBasic, locations[locDefFolder]))
newCfg.Folders = append(newCfg.Folders, config.NewFolderConfiguration(myID, "default", "Default Folder", fs.FilesystemTypeBasic, locations.Get(locations.DefFolder)))
l.Infoln("Default folder created and/or linked to new config")
return config.Wrap(cfgFile, newCfg)
}
func resetDB() error {
return os.RemoveAll(locations[locDatabase])
return os.RemoveAll(locations.Get(locations.Database))
}
func restart() {
@@ -1142,10 +1093,10 @@ func autoUpgrade(cfg *config.Wrapper) {
select {
case event := <-sub.C():
data, ok := event.Data.(map[string]string)
if !ok || data["clientName"] != "syncthing" || upgrade.CompareVersions(data["clientVersion"], Version) != upgrade.Newer {
if !ok || data["clientName"] != "syncthing" || upgrade.CompareVersions(data["clientVersion"], build.Version) != upgrade.Newer {
continue
}
l.Infof("Connected to device %s with a newer version (current %q < remote %q). Checking for upgrades.", data["id"], Version, data["clientVersion"])
l.Infof("Connected to device %s with a newer version (current %q < remote %q). Checking for upgrades.", data["id"], build.Version, data["clientVersion"])
case <-timer.C:
}
@@ -1157,7 +1108,7 @@ func autoUpgrade(cfg *config.Wrapper) {
checkInterval = time.Hour
}
rel, err := upgrade.LatestRelease(opts.ReleasesURL, Version, opts.UpgradeToPreReleases)
rel, err := upgrade.LatestRelease(opts.ReleasesURL, build.Version, opts.UpgradeToPreReleases)
if err == upgrade.ErrUpgradeUnsupported {
events.Default.Unsubscribe(sub)
return
@@ -1170,13 +1121,13 @@ func autoUpgrade(cfg *config.Wrapper) {
continue
}
if upgrade.CompareVersions(rel.Tag, Version) != upgrade.Newer {
if upgrade.CompareVersions(rel.Tag, build.Version) != upgrade.Newer {
// Skip equal, older or majorly newer (incompatible) versions
timer.Reset(checkInterval)
continue
}
l.Infof("Automatic upgrade (current %q < latest %q)", Version, rel.Tag)
l.Infof("Automatic upgrade (current %q < latest %q)", build.Version, rel.Tag)
err = upgrade.To(rel)
if err != nil {
l.Warnln("Automatic upgrade:", err)
@@ -1209,7 +1160,7 @@ func cleanConfigDirectory() {
}
for pat, dur := range patterns {
fs := fs.NewFilesystem(fs.FilesystemTypeBasic, baseDirs["config"])
fs := fs.NewFilesystem(fs.FilesystemTypeBasic, locations.GetBaseDir(locations.ConfigBaseDir))
files, err := fs.Glob(pat)
if err != nil {
l.Infoln("Cleaning:", err)
@@ -1250,13 +1201,13 @@ func checkShortIDs(cfg *config.Wrapper) error {
}
func showPaths(options RuntimeOptions) {
fmt.Printf("Configuration file:\n\t%s\n\n", locations[locConfigFile])
fmt.Printf("Database directory:\n\t%s\n\n", locations[locDatabase])
fmt.Printf("Device private key & certificate files:\n\t%s\n\t%s\n\n", locations[locKeyFile], locations[locCertFile])
fmt.Printf("HTTPS private key & certificate files:\n\t%s\n\t%s\n\n", locations[locHTTPSKeyFile], locations[locHTTPSCertFile])
fmt.Printf("Configuration file:\n\t%s\n\n", locations.Get(locations.ConfigFile))
fmt.Printf("Database directory:\n\t%s\n\n", locations.Get(locations.Database))
fmt.Printf("Device private key & certificate files:\n\t%s\n\t%s\n\n", locations.Get(locations.KeyFile), locations.Get(locations.CertFile))
fmt.Printf("HTTPS private key & certificate files:\n\t%s\n\t%s\n\n", locations.Get(locations.HTTPSKeyFile), locations.Get(locations.HTTPSCertFile))
fmt.Printf("Log file:\n\t%s\n\n", options.logFile)
fmt.Printf("GUI override directory:\n\t%s\n\n", options.assetDir)
fmt.Printf("Default sync folder directory:\n\t%s\n\n", locations[locDefFolder])
fmt.Printf("Default sync folder directory:\n\t%s\n\n", locations.Get(locations.DefFolder))
}
func setPauseState(cfg *config.Wrapper, paused bool) {

View File

@@ -36,29 +36,3 @@ func TestShortIDCheck(t *testing.T) {
t.Error("Should have gotten an error")
}
}
func TestAllowedVersions(t *testing.T) {
testcases := []struct {
ver string
allowed bool
}{
{"v0.13.0", true},
{"v0.12.11+22-gabcdef0", true},
{"v0.13.0-beta0", true},
{"v0.13.0-beta47", true},
{"v0.13.0-beta47+1-gabcdef0", true},
{"v0.13.0-beta.0", true},
{"v0.13.0-beta.47", true},
{"v0.13.0-beta.0+1-gabcdef0", true},
{"v0.13.0-beta.47+1-gabcdef0", true},
{"v0.13.0-some-weird-but-allowed-tag", true},
{"v0.13.0-allowed.to.do.this", true},
{"v0.13.0+not.allowed.to.do.this", false},
}
for i, c := range testcases {
if allowed := allowedVersionExp.MatchString(c.ver); allowed != c.allowed {
t.Errorf("%d: incorrect result %v != %v for %q", i, allowed, c.allowed, c.ver)
}
}
}

View File

@@ -17,6 +17,7 @@ import (
"syscall"
"time"
"github.com/syncthing/syncthing/lib/locations"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/sync"
)
@@ -198,7 +199,7 @@ func copyStderr(stderr io.Reader, dst io.Writer) {
}
if strings.HasPrefix(line, "panic:") || strings.HasPrefix(line, "fatal error:") {
panicFd, err = os.Create(timestampedLoc(locPanicLog))
panicFd, err = os.Create(locations.GetTimestamped(locations.PanicLog))
if err != nil {
l.Warnln("Create panic log:", err)
continue

View File

@@ -20,6 +20,7 @@ import (
"sync"
"time"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/connections"
"github.com/syncthing/syncthing/lib/dialer"
@@ -41,8 +42,8 @@ func reportData(cfg configIntf, m modelIntf, connectionsService connectionsIntf,
res := make(map[string]interface{})
res["urVersion"] = version
res["uniqueID"] = opts.URUniqueID
res["version"] = Version
res["longVersion"] = LongVersion
res["version"] = build.Version
res["longVersion"] = build.LongVersion
res["platform"] = runtime.GOOS + "-" + runtime.GOARCH
res["numFolders"] = len(cfg.Folders())
res["numDevices"] = len(cfg.Devices())