mirror of
https://github.com/syncthing/syncthing.git
synced 2026-01-03 03:19:04 -05:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1be4b8bb5d | ||
|
|
c832fc9917 | ||
|
|
4797a94689 | ||
|
|
6948903084 | ||
|
|
94164611ae | ||
|
|
ae298e8902 | ||
|
|
3d8771ecb0 | ||
|
|
28db264e90 | ||
|
|
6af9fa4b81 | ||
|
|
c45b18cc75 |
@@ -153,7 +153,7 @@ func init() {
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["logo-text-64.png"] = bs
|
||||
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ff7c91416eac300c86f7ef1451166f5688cdac5ae8a62731c4402493a0c48c8410776f0269caa84c171013fbf3efdf544a3f444be07d2d47ab8044070ae5c73f217ea50aa5816c2f85e98b74bfde8e0cf5b73741e07adc76f68a6ead61349cf2571503066d2780d0f1f12ed6d533f0ecb72d73811ceecf206b263c1584123f818983eaae963a48cb6fa2a7651ae28dc851508947d4a8ca089e3badebde7ddb7ee4cbe19e4d94c1c56b478d55cbbe2f76607c4bb3c2d7649ab625eb513ef7e9ac6574e715343373f0c0cb84b53c3e32d3b011e129147630134ba18021fc3d3feadc3258dd57f4c7561c8ef6817927ff71f4d3fb679cae2a0fc50b2f394c413abe000000ffff010000ffffe37f5ed168020000")
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ff7c91b16e84300c86f73e4594a13721969bdae3963e89210622990425e6248478f72690a69cca758098d89fedffe7a6f4433404de5772b00a48b4a050dedf84f8932a9406b29d14a62bd2fd72d933d45d3e0481eb70ddd833bab186d170ca9f55f418663b01848ef777b12c9e8127bfae990b647f7d065933e1a12094f8114c5c54b795d461b4fc213a9ac73ede881c8529f188336e65048f9d9665ebbeaebfe3cbfe9a459441c56b45b555f3e6173b30bea149e16b326ddb90f5289ffbb4d632baa305f5c41c34f03c6225f78fccd46c44780a852d4cc4522860087fcf0f3ab70c52378bfe71c5e1601f983d79c7c18f9f3bb5c92160bc7fc56d53c5addc17399198c314a4e31b0000ffff010000ffff3e1bbdca7f020000")
|
||||
gr, _ = gzip.NewReader(bytes.NewBuffer(bs))
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["modal.html"] = bs
|
||||
|
||||
@@ -515,7 +515,7 @@ func restPostUpgrade(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if upgrade.CompareVersions(rel.Tag, Version) == 1 {
|
||||
err = upgrade.UpgradeTo(rel)
|
||||
err = upgrade.UpgradeTo(rel, GoArchExtra)
|
||||
if err != nil {
|
||||
l.Warnln(err)
|
||||
http.Error(w, err.Error(), 500)
|
||||
|
||||
@@ -47,6 +47,7 @@ var (
|
||||
BuildHost = "unknown"
|
||||
BuildUser = "unknown"
|
||||
LongVersion string
|
||||
GoArchExtra string // "", "v5", "v6", "v7"
|
||||
)
|
||||
|
||||
var l = logger.DefaultLogger
|
||||
@@ -194,7 +195,7 @@ func main() {
|
||||
l.Infof("Upgrade available (current %q < latest %q)", Version, rel.Tag)
|
||||
|
||||
if doUpgrade {
|
||||
err = upgrade.UpgradeTo(rel)
|
||||
err = upgrade.UpgradeTo(rel, GoArchExtra)
|
||||
if err != nil {
|
||||
l.Fatalln("Upgrade:", err) // exits 1
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package files
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"runtime"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
@@ -121,6 +122,8 @@ type deletionHandler func(db dbReader, batch dbWriter, repo, node, name []byte,
|
||||
type fileIterator func(f protocol.FileInfo) bool
|
||||
|
||||
func ldbGenericReplace(db *leveldb.DB, repo, node []byte, fs []protocol.FileInfo, deleteFn deletionHandler) uint64 {
|
||||
defer runtime.GC()
|
||||
|
||||
sort.Sort(fileList(fs)) // sort list on name, same as on disk
|
||||
|
||||
start := nodeKey(repo, node, nil) // before all repo/node files
|
||||
@@ -246,6 +249,8 @@ func ldbReplaceWithDelete(db *leveldb.DB, repo, node []byte, fs []protocol.FileI
|
||||
}
|
||||
|
||||
func ldbUpdate(db *leveldb.DB, repo, node []byte, fs []protocol.FileInfo) uint64 {
|
||||
defer runtime.GC()
|
||||
|
||||
batch := new(leveldb.Batch)
|
||||
snap, err := db.GetSnapshot()
|
||||
if err != nil {
|
||||
@@ -414,6 +419,8 @@ func ldbWithHave(db *leveldb.DB, repo, node []byte, fn fileIterator) {
|
||||
}
|
||||
|
||||
func ldbWithAllRepo(db *leveldb.DB, repo []byte, fn func(node []byte, f protocol.FileInfo) bool) {
|
||||
defer runtime.GC()
|
||||
|
||||
start := nodeKey(repo, nil, nil) // before all repo/node files
|
||||
limit := nodeKey(repo, protocol.LocalNodeID[:], []byte{0xff, 0xff, 0xff, 0xff}) // after all repo/node files
|
||||
snap, err := db.GetSnapshot()
|
||||
@@ -530,6 +537,8 @@ func ldbGetGlobal(db *leveldb.DB, repo, file []byte) protocol.FileInfo {
|
||||
}
|
||||
|
||||
func ldbWithGlobal(db *leveldb.DB, repo []byte, fn fileIterator) {
|
||||
defer runtime.GC()
|
||||
|
||||
start := globalKey(repo, nil)
|
||||
limit := globalKey(repo, []byte{0xff, 0xff, 0xff, 0xff})
|
||||
snap, err := db.GetSnapshot()
|
||||
@@ -597,6 +606,8 @@ func ldbAvailability(db *leveldb.DB, repo, file []byte) []protocol.NodeID {
|
||||
}
|
||||
|
||||
func ldbWithNeed(db *leveldb.DB, repo, node []byte, fn fileIterator) {
|
||||
defer runtime.GC()
|
||||
|
||||
start := globalKey(repo, nil)
|
||||
limit := globalKey(repo, []byte{0xff, 0xff, 0xff, 0xff})
|
||||
snap, err := db.GetSnapshot()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="modal-body" ng-transclude>
|
||||
</div>
|
||||
<div ng-if="close" class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span> Close</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span> <span translate>Close</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -441,7 +441,9 @@ func (p *puller) handleBlock(b bqBlock) bool {
|
||||
err = os.MkdirAll(dirName, 0777)
|
||||
} else {
|
||||
// We need to make sure the directory is writeable so we can create files in it
|
||||
err = os.Chmod(dirName, 0777)
|
||||
if (dirName != p.repoCfg.Directory) {
|
||||
err = os.Chmod(dirName, 0777)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
l.Infof("mkdir: error: %q / %q: %v", p.repoCfg.ID, f.Name, err)
|
||||
@@ -600,9 +602,13 @@ func (p *puller) handleEmptyBlock(b bqBlock) {
|
||||
l.Debugf("pull: delete %q", f.Name)
|
||||
}
|
||||
os.Remove(of.temp)
|
||||
|
||||
// Ensure the file and the directory it is in is writeable so we can remove the file
|
||||
dirName := filepath.Dir(of.filepath)
|
||||
os.Chmod(of.filepath, 0666)
|
||||
os.Chmod(filepath.Dir(of.filepath), 0777)
|
||||
if (dirName != p.repoCfg.Directory) {
|
||||
os.Chmod(dirName, 0777)
|
||||
}
|
||||
if p.versioner != nil {
|
||||
if debug {
|
||||
l.Debugln("pull: deleting with versioner")
|
||||
|
||||
17
upgrade/debug.go
Normal file
17
upgrade/debug.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/syncthing/syncthing/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
debug = strings.Contains(os.Getenv("STTRACE"), "upgrade") || os.Getenv("STTRACE") == "all"
|
||||
l = logger.DefaultLogger
|
||||
)
|
||||
@@ -23,10 +23,8 @@ import (
|
||||
"bitbucket.org/kardianos/osext"
|
||||
)
|
||||
|
||||
var GoArchExtra string // "", "v5", "v6", "v7"
|
||||
|
||||
// Upgrade to the given release, saving the previous binary with a ".old" extension.
|
||||
func UpgradeTo(rel Release) error {
|
||||
func UpgradeTo(rel Release, archExtra string) error {
|
||||
path, err := osext.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -38,8 +36,14 @@ func UpgradeTo(rel Release) error {
|
||||
// sense for people downloading them
|
||||
osName = "macosx"
|
||||
}
|
||||
expectedRelease := fmt.Sprintf("syncthing-%s-%s%s-%s.", osName, runtime.GOARCH, GoArchExtra, rel.Tag)
|
||||
expectedRelease := fmt.Sprintf("syncthing-%s-%s%s-%s.", osName, runtime.GOARCH, archExtra, rel.Tag)
|
||||
if debug {
|
||||
l.Debugf("expected release asset %q", expectedRelease)
|
||||
}
|
||||
for _, asset := range rel.Assets {
|
||||
if debug {
|
||||
l.Debugln("considering release", asset)
|
||||
}
|
||||
if strings.HasPrefix(asset.Name, expectedRelease) {
|
||||
if strings.HasSuffix(asset.Name, ".tar.gz") {
|
||||
fname, err := readTarGZ(asset.URL, filepath.Dir(path))
|
||||
@@ -97,6 +101,10 @@ func LatestRelease(prerelease bool) (Release, error) {
|
||||
}
|
||||
|
||||
func readTarGZ(url string, dir string) (string, error) {
|
||||
if debug {
|
||||
l.Debugf("loading %q", url)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -129,6 +137,9 @@ func readTarGZ(url string, dir string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if debug {
|
||||
l.Debugf("considering file %q", hdr.Name)
|
||||
}
|
||||
|
||||
if path.Base(hdr.Name) == "syncthing" {
|
||||
of, err := ioutil.TempFile(dir, "syncthing")
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows solaris noupgrade
|
||||
// +build solaris noupgrade
|
||||
|
||||
package upgrade
|
||||
|
||||
func UpgradeTo(rel Release) error {
|
||||
func UpgradeTo(rel Release, extra string) error {
|
||||
return ErrUpgradeUnsupported
|
||||
}
|
||||
|
||||
|
||||
166
upgrade/upgrade_windows.go
Executable file
166
upgrade/upgrade_windows.go
Executable file
@@ -0,0 +1,166 @@
|
||||
// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
|
||||
// All rights reserved. Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows,!noupgrade
|
||||
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"bitbucket.org/kardianos/osext"
|
||||
)
|
||||
|
||||
// Upgrade to the given release, saving the previous binary with a ".old" extension.
|
||||
func UpgradeTo(rel Release, archExtra string) error {
|
||||
path, err := osext.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
expectedRelease := fmt.Sprintf("syncthing-%s-%s%s-%s.", runtime.GOOS, runtime.GOARCH, archExtra, rel.Tag)
|
||||
if debug {
|
||||
l.Debugf("expected release asset %q", expectedRelease)
|
||||
}
|
||||
for _, asset := range rel.Assets {
|
||||
if debug {
|
||||
l.Debugln("considering release", asset)
|
||||
}
|
||||
if strings.HasPrefix(asset.Name, expectedRelease) {
|
||||
if strings.HasSuffix(asset.Name, ".zip") {
|
||||
fname, err := readZip(asset.URL, filepath.Dir(path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
old := path + ".old"
|
||||
|
||||
os.Remove(old)
|
||||
err = os.Rename(path, old)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Rename(fname, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ErrVersionUnknown
|
||||
}
|
||||
|
||||
// Returns the latest release, including prereleases or not depending on the argument
|
||||
func LatestRelease(prerelease bool) (Release, error) {
|
||||
resp, err := http.Get("https://api.github.com/repos/syncthing/syncthing/releases?per_page=10")
|
||||
if err != nil {
|
||||
return Release{}, err
|
||||
}
|
||||
if resp.StatusCode > 299 {
|
||||
return Release{}, fmt.Errorf("API call returned HTTP error: %s", resp.Status)
|
||||
}
|
||||
|
||||
var rels []Release
|
||||
json.NewDecoder(resp.Body).Decode(&rels)
|
||||
resp.Body.Close()
|
||||
|
||||
if len(rels) == 0 {
|
||||
return Release{}, ErrVersionUnknown
|
||||
}
|
||||
|
||||
if prerelease {
|
||||
// We are a beta version. Use the latest.
|
||||
return rels[0], nil
|
||||
} else {
|
||||
// We are a regular release. Only consider non-prerelease versions for upgrade.
|
||||
for _, rel := range rels {
|
||||
if !rel.Prerelease {
|
||||
return rel, nil
|
||||
}
|
||||
}
|
||||
return Release{}, ErrVersionUnknown
|
||||
}
|
||||
}
|
||||
|
||||
func readZip(url, dir string) (string, error) {
|
||||
if debug {
|
||||
l.Debugf("loading %q", url)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req.Header.Add("Accept", "application/octet-stream")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
archive, err := zip.NewReader(bytes.NewReader(body), resp.ContentLength)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Iterate through the files in the archive.
|
||||
for _, file := range archive.File {
|
||||
|
||||
if debug {
|
||||
l.Debugf("considering file %q", file.Name)
|
||||
}
|
||||
|
||||
if path.Base(file.Name) == "syncthing.exe" {
|
||||
infile, err := file.Open()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
outfile, err := ioutil.TempFile(dir, "syncthing")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, err = io.Copy(outfile, infile)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = infile.Close()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = outfile.Close()
|
||||
if err != nil {
|
||||
os.Remove(outfile.Name())
|
||||
return "", err
|
||||
}
|
||||
|
||||
os.Chmod(outfile.Name(), file.Mode())
|
||||
return outfile.Name(), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("No upgrade found")
|
||||
}
|
||||
Reference in New Issue
Block a user