mirror of
https://github.com/syncthing/syncthing.git
synced 2025-12-30 17:39:20 -05:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c9e87d994 | ||
|
|
f0180cb014 | ||
|
|
a99a730c0c | ||
|
|
36254473a3 | ||
|
|
800596139e | ||
|
|
f48782e4df | ||
|
|
922cc7544e | ||
|
|
9e262d84de | ||
|
|
42db6280e6 | ||
|
|
8d8adae310 | ||
|
|
12ba4b6aea |
36
.github/workflows/build-syncthing.yaml
vendored
36
.github/workflows/build-syncthing.yaml
vendored
@@ -159,6 +159,7 @@ jobs:
|
||||
needs:
|
||||
- build-test
|
||||
- package-linux
|
||||
- package-illumos
|
||||
- package-cross
|
||||
- package-source
|
||||
- package-debian
|
||||
@@ -337,6 +338,39 @@ jobs:
|
||||
*.tar.gz
|
||||
compat.json
|
||||
|
||||
package-illumos:
|
||||
runs-on: ubuntu-latest
|
||||
name: Package for illumos
|
||||
needs:
|
||||
- facts
|
||||
env:
|
||||
VERSION: ${{ needs.facts.outputs.version }}
|
||||
GO_VERSION: ${{ needs.facts.outputs.go-version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build syncthing in OmniOS VM
|
||||
uses: vmactions/omnios-vm@v1
|
||||
with:
|
||||
envs: "VERSION GO_VERSION CGO_ENABLED"
|
||||
usesh: true
|
||||
prepare: |
|
||||
pkg install developer/gcc14 web/curl archiver/gnu-tar
|
||||
run: |
|
||||
curl -L "https://go.dev/dl/go$GO_VERSION.illumos-amd64.tar.gz" | gtar xzf -
|
||||
export PATH="$GITHUB_WORKSPACE/go/bin:$PATH"
|
||||
go version
|
||||
for tgt in syncthing stdiscosrv strelaysrv ; do
|
||||
go run build.go -tags "${{env.TAGS}}" tar "$tgt"
|
||||
done
|
||||
env:
|
||||
CGO_ENABLED: "1"
|
||||
|
||||
- name: Archive artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: packages-illumos
|
||||
path: "*.tar.gz"
|
||||
#
|
||||
# macOS. The entire build runs in the release environment because code
|
||||
# signing is part of the build process, so it is limited to release
|
||||
@@ -503,6 +537,7 @@ jobs:
|
||||
| grep -v aix/ppc64 \
|
||||
| grep -v android/ \
|
||||
| grep -v darwin/ \
|
||||
| grep -v illumos/ \
|
||||
| grep -v ios/ \
|
||||
| grep -v js/ \
|
||||
| grep -v linux/ \
|
||||
@@ -588,6 +623,7 @@ jobs:
|
||||
needs:
|
||||
- codesign-windows
|
||||
- package-linux
|
||||
- package-illumos
|
||||
- package-macos
|
||||
- package-cross
|
||||
- package-source
|
||||
|
||||
@@ -164,6 +164,9 @@ type serveCmd struct {
|
||||
LogLevel slog.Level `help:"Log level for all packages (DEBUG,INFO,WARN,ERROR)" env:"STLOGLEVEL" default:"INFO"`
|
||||
LogMaxFiles int `name:"log-max-old-files" help:"Number of old files to keep (zero to keep only current)" default:"${logMaxFiles}" placeholder:"N" env:"STLOGMAXOLDFILES"`
|
||||
LogMaxSize int `help:"Maximum size of any file (zero to disable log rotation)" default:"${logMaxSize}" placeholder:"BYTES" env:"STLOGMAXSIZE"`
|
||||
LogFormatTimestamp string `name:"log-format-timestamp" help:"Format for timestamp, set to empty to disable timestamps" env:"STLOGFORMATTIMESTAMP" default:"${timestampFormat}"`
|
||||
LogFormatLevelString bool `name:"log-format-level-string" help:"Whether to include level string in log line" env:"STLOGFORMATLEVELSTRING" default:"${levelString}" negatable:""`
|
||||
LogFormatLevelSyslog bool `name:"log-format-level-syslog" help:"Whether to include level as syslog prefix in log line" env:"STLOGFORMATLEVELSYSLOG" default:"${levelSyslog}" negatable:""`
|
||||
NoBrowser bool `help:"Do not start browser" env:"STNOBROWSER"`
|
||||
NoPortProbing bool `help:"Don't try to find free ports for GUI and listen addresses on first startup" env:"STNOPORTPROBING"`
|
||||
NoRestart bool `help:"Do not restart Syncthing when exiting due to API/GUI command, upgrade, or crash" env:"STNORESTART"`
|
||||
@@ -186,10 +189,13 @@ type serveCmd struct {
|
||||
}
|
||||
|
||||
func defaultVars() kong.Vars {
|
||||
vars := kong.Vars{}
|
||||
|
||||
vars["logMaxSize"] = strconv.Itoa(10 << 20) // 10 MiB
|
||||
vars["logMaxFiles"] = "3" // plus the current one
|
||||
vars := kong.Vars{
|
||||
"logMaxSize": strconv.Itoa(10 << 20), // 10 MiB
|
||||
"logMaxFiles": "3", // plus the current one
|
||||
"levelString": strconv.FormatBool(slogutil.DefaultLineFormat.LevelString),
|
||||
"levelSyslog": strconv.FormatBool(slogutil.DefaultLineFormat.LevelSyslog),
|
||||
"timestampFormat": slogutil.DefaultLineFormat.TimestampFormat,
|
||||
}
|
||||
|
||||
// On non-Windows, we explicitly default to "-" which means stdout. On
|
||||
// Windows, the "default" options.logFile will later be replaced with the
|
||||
@@ -262,8 +268,14 @@ func (c *serveCmd) Run() error {
|
||||
osutil.HideConsole()
|
||||
}
|
||||
|
||||
// The default log level for all packages
|
||||
// Customize the logging early
|
||||
slogutil.SetLineFormat(slogutil.LineFormat{
|
||||
TimestampFormat: c.LogFormatTimestamp,
|
||||
LevelString: c.LogFormatLevelString,
|
||||
LevelSyslog: c.LogFormatLevelSyslog,
|
||||
})
|
||||
slogutil.SetDefaultLevel(c.LogLevel)
|
||||
slogutil.SetLevelOverrides(os.Getenv("STTRACE"))
|
||||
|
||||
// Treat an explicitly empty log file name as no log file
|
||||
if c.LogFile == "" {
|
||||
@@ -1039,7 +1051,7 @@ func (m migratingAPI) Serve(ctx context.Context) error {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.Write([]byte("*** Database migration in progress ***\n\n"))
|
||||
for _, line := range slogutil.GlobalRecorder.Since(time.Time{}) {
|
||||
line.WriteTo(w)
|
||||
_, _ = line.WriteTo(w, slogutil.DefaultLineFormat)
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ StartLimitBurst=4
|
||||
|
||||
[Service]
|
||||
User=%i
|
||||
Environment="STLOGFORMATTIMESTAMP="
|
||||
Environment="STLOGFORMATLEVELSTRING=false"
|
||||
Environment="STLOGFORMATLEVELSYSLOG=true"
|
||||
ExecStart=/usr/bin/syncthing serve --no-browser --no-restart
|
||||
Restart=on-failure
|
||||
RestartSec=1
|
||||
|
||||
@@ -5,7 +5,10 @@ StartLimitIntervalSec=60
|
||||
StartLimitBurst=4
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/syncthing serve --no-browser --no-restart --logflags=0
|
||||
Environment="STLOGFORMATTIMESTAMP="
|
||||
Environment="STLOGFORMATLEVELSTRING=false"
|
||||
Environment="STLOGFORMATLEVELSYSLOG=true"
|
||||
ExecStart=/usr/bin/syncthing serve --no-browser --no-restart
|
||||
Restart=on-failure
|
||||
RestartSec=1
|
||||
SuccessExitStatus=3 4
|
||||
|
||||
@@ -25,7 +25,11 @@ import (
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
|
||||
const currentSchemaVersion = 4
|
||||
const (
|
||||
currentSchemaVersion = 4
|
||||
applicationIDMain = 0x53546d6e // "STmn", Syncthing main database
|
||||
applicationIDFolder = 0x53546664 // "STfd", Syncthing folder database
|
||||
)
|
||||
|
||||
//go:embed sql/**
|
||||
var embedded embed.FS
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -52,6 +53,7 @@ func Open(path string, opts ...Option) (*DB, error) {
|
||||
"journal_mode = WAL",
|
||||
"optimize = 0x10002",
|
||||
"auto_vacuum = INCREMENTAL",
|
||||
fmt.Sprintf("application_id = %d", applicationIDMain),
|
||||
}
|
||||
schemas := []string{
|
||||
"sql/schema/common/*",
|
||||
@@ -100,6 +102,7 @@ func OpenForMigration(path string) (*DB, error) {
|
||||
"foreign_keys = 0",
|
||||
"synchronous = 0",
|
||||
"locking_mode = EXCLUSIVE",
|
||||
fmt.Sprintf("application_id = %d", applicationIDMain),
|
||||
}
|
||||
schemas := []string{
|
||||
"sql/schema/common/*",
|
||||
|
||||
@@ -14,5 +14,5 @@ import (
|
||||
|
||||
const (
|
||||
dbDriver = "sqlite3"
|
||||
commonOptions = "_fk=true&_rt=true&_cache_size=-65536&_sync=1&_txlock=immediate"
|
||||
commonOptions = "_fk=true&_rt=true&_sync=1&_txlock=immediate"
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
const (
|
||||
dbDriver = "sqlite"
|
||||
commonOptions = "_pragma=foreign_keys(1)&_pragma=recursive_triggers(1)&_pragma=cache_size(-65536)&_pragma=synchronous(1)"
|
||||
commonOptions = "_pragma=foreign_keys(1)&_pragma=recursive_triggers(1)&_pragma=synchronous(1)"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
@@ -25,6 +26,7 @@ func openFolderDB(folder, path string, deleteRetention time.Duration) (*folderDB
|
||||
"journal_mode = WAL",
|
||||
"optimize = 0x10002",
|
||||
"auto_vacuum = INCREMENTAL",
|
||||
fmt.Sprintf("application_id = %d", applicationIDFolder),
|
||||
}
|
||||
schemas := []string{
|
||||
"sql/schema/common/*",
|
||||
@@ -65,6 +67,7 @@ func openFolderDBForMigration(folder, path string, deleteRetention time.Duration
|
||||
"foreign_keys = 0",
|
||||
"synchronous = 0",
|
||||
"locking_mode = EXCLUSIVE",
|
||||
fmt.Sprintf("application_id = %d", applicationIDFolder),
|
||||
}
|
||||
schemas := []string{
|
||||
"sql/schema/common/*",
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
|
||||
-- Schema migrations hold the list of historical migrations applied
|
||||
CREATE TABLE IF NOT EXISTS schemamigrations (
|
||||
schema_version INTEGER NOT NULL,
|
||||
schema_version INTEGER NOT NULL PRIMARY KEY,
|
||||
applied_at INTEGER NOT NULL, -- unix nanos
|
||||
syncthing_version TEXT NOT NULL COLLATE BINARY,
|
||||
PRIMARY KEY(schema_version)
|
||||
syncthing_version TEXT NOT NULL COLLATE BINARY
|
||||
) STRICT
|
||||
;
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
CREATE TABLE IF NOT EXISTS kv (
|
||||
key TEXT NOT NULL PRIMARY KEY COLLATE BINARY,
|
||||
value BLOB NOT NULL
|
||||
) STRICT
|
||||
) STRICT, WITHOUT ROWID
|
||||
;
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
|
||||
-- indexids holds the index ID and maximum sequence for a given device and folder
|
||||
CREATE TABLE IF NOT EXISTS indexids (
|
||||
device_idx INTEGER NOT NULL,
|
||||
device_idx INTEGER NOT NULL PRIMARY KEY,
|
||||
index_id TEXT NOT NULL COLLATE BINARY,
|
||||
sequence INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(device_idx),
|
||||
FOREIGN KEY(device_idx) REFERENCES devices(idx) ON DELETE CASCADE
|
||||
) STRICT, WITHOUT ROWID
|
||||
;
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
|
||||
--- Backing for the MtimeFS
|
||||
CREATE TABLE IF NOT EXISTS mtimes (
|
||||
name TEXT NOT NULL,
|
||||
name TEXT NOT NULL PRIMARY KEY,
|
||||
ondisk INTEGER NOT NULL, -- unix nanos
|
||||
virtual INTEGER NOT NULL, -- unix nanos
|
||||
PRIMARY KEY(name)
|
||||
virtual INTEGER NOT NULL -- unix nanos
|
||||
) STRICT, WITHOUT ROWID
|
||||
;
|
||||
|
||||
@@ -18,14 +18,30 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type formattingHandler struct {
|
||||
attrs []slog.Attr
|
||||
groups []string
|
||||
type LineFormat struct {
|
||||
TimestampFormat string
|
||||
LevelString bool
|
||||
LevelSyslog bool
|
||||
}
|
||||
|
||||
type formattingOptions struct {
|
||||
LineFormat
|
||||
|
||||
out io.Writer
|
||||
recs []*lineRecorder
|
||||
timeOverride time.Time
|
||||
}
|
||||
|
||||
type formattingHandler struct {
|
||||
attrs []slog.Attr
|
||||
groups []string
|
||||
opts *formattingOptions
|
||||
}
|
||||
|
||||
func SetLineFormat(f LineFormat) {
|
||||
globalFormatter.LineFormat = f
|
||||
}
|
||||
|
||||
var _ slog.Handler = (*formattingHandler)(nil)
|
||||
|
||||
func (h *formattingHandler) Enabled(context.Context, slog.Level) bool {
|
||||
@@ -83,19 +99,19 @@ func (h *formattingHandler) Handle(_ context.Context, rec slog.Record) error {
|
||||
}
|
||||
|
||||
line := Line{
|
||||
When: cmp.Or(h.timeOverride, rec.Time),
|
||||
When: cmp.Or(h.opts.timeOverride, rec.Time),
|
||||
Message: sb.String(),
|
||||
Level: rec.Level,
|
||||
}
|
||||
|
||||
// If there is a recorder, record the line.
|
||||
for _, rec := range h.recs {
|
||||
for _, rec := range h.opts.recs {
|
||||
rec.record(line)
|
||||
}
|
||||
|
||||
// If there's an output, print the line.
|
||||
if h.out != nil {
|
||||
_, _ = line.WriteTo(h.out)
|
||||
if h.opts.out != nil {
|
||||
_, _ = line.WriteTo(h.opts.out, h.opts.LineFormat)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -143,11 +159,9 @@ func (h *formattingHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
}
|
||||
}
|
||||
return &formattingHandler{
|
||||
attrs: append(h.attrs, attrs...),
|
||||
groups: h.groups,
|
||||
recs: h.recs,
|
||||
out: h.out,
|
||||
timeOverride: h.timeOverride,
|
||||
attrs: append(h.attrs, attrs...),
|
||||
groups: h.groups,
|
||||
opts: h.opts,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,11 +170,9 @@ func (h *formattingHandler) WithGroup(name string) slog.Handler {
|
||||
return h
|
||||
}
|
||||
return &formattingHandler{
|
||||
attrs: h.attrs,
|
||||
groups: append([]string{name}, h.groups...),
|
||||
recs: h.recs,
|
||||
out: h.out,
|
||||
timeOverride: h.timeOverride,
|
||||
attrs: h.attrs,
|
||||
groups: append([]string{name}, h.groups...),
|
||||
opts: h.opts,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,11 @@ import (
|
||||
func TestFormattingHandler(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
h := &formattingHandler{
|
||||
out: buf,
|
||||
timeOverride: time.Unix(1234567890, 0).In(time.UTC),
|
||||
opts: &formattingOptions{
|
||||
LineFormat: DefaultLineFormat,
|
||||
out: buf,
|
||||
timeOverride: time.Unix(1234567890, 0).In(time.UTC),
|
||||
},
|
||||
}
|
||||
|
||||
l := slog.New(h).With("a", "a")
|
||||
|
||||
@@ -9,6 +9,7 @@ package slogutil
|
||||
import (
|
||||
"log/slog"
|
||||
"maps"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -39,6 +40,24 @@ func SetDefaultLevel(level slog.Level) {
|
||||
globalLevels.SetDefault(level)
|
||||
}
|
||||
|
||||
func SetLevelOverrides(sttrace string) {
|
||||
pkgs := strings.Split(sttrace, ",")
|
||||
for _, pkg := range pkgs {
|
||||
pkg = strings.TrimSpace(pkg)
|
||||
if pkg == "" {
|
||||
continue
|
||||
}
|
||||
level := slog.LevelDebug
|
||||
if cutPkg, levelStr, ok := strings.Cut(pkg, ":"); ok {
|
||||
pkg = cutPkg
|
||||
if err := level.UnmarshalText([]byte(levelStr)); err != nil {
|
||||
slog.Warn("Bad log level requested in STTRACE", slog.String("pkg", pkg), slog.String("level", levelStr), Error(err))
|
||||
}
|
||||
}
|
||||
globalLevels.Set(pkg, level)
|
||||
}
|
||||
}
|
||||
|
||||
type levelTracker struct {
|
||||
mut sync.RWMutex
|
||||
defLevel slog.Level
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
package slogutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -22,13 +23,22 @@ type Line struct {
|
||||
Level slog.Level `json:"level"`
|
||||
}
|
||||
|
||||
func (l *Line) WriteTo(w io.Writer) (int64, error) {
|
||||
n, err := fmt.Fprintf(w, "%s %s %s\n", l.timeStr(), l.levelStr(), l.Message)
|
||||
return int64(n), err
|
||||
}
|
||||
|
||||
func (l *Line) timeStr() string {
|
||||
return l.When.Format("2006-01-02 15:04:05")
|
||||
func (l *Line) WriteTo(w io.Writer, f LineFormat) (int64, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
if f.LevelSyslog {
|
||||
_, _ = fmt.Fprintf(buf, "<%d>", l.syslogPriority())
|
||||
}
|
||||
if f.TimestampFormat != "" {
|
||||
buf.WriteString(l.When.Format(f.TimestampFormat))
|
||||
buf.WriteRune(' ')
|
||||
}
|
||||
if f.LevelString {
|
||||
buf.WriteString(l.levelStr())
|
||||
buf.WriteRune(' ')
|
||||
}
|
||||
buf.WriteString(l.Message)
|
||||
buf.WriteRune('\n')
|
||||
return buf.WriteTo(w)
|
||||
}
|
||||
|
||||
func (l *Line) levelStr() string {
|
||||
@@ -51,6 +61,19 @@ func (l *Line) levelStr() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Line) syslogPriority() int {
|
||||
switch {
|
||||
case l.Level < slog.LevelInfo:
|
||||
return 7
|
||||
case l.Level < slog.LevelWarn:
|
||||
return 6
|
||||
case l.Level < slog.LevelError:
|
||||
return 4
|
||||
default:
|
||||
return 3
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Line) MarshalJSON() ([]byte, error) {
|
||||
// Custom marshal to get short level strings instead of default JSON serialisation
|
||||
return json.Marshal(map[string]any{
|
||||
|
||||
@@ -10,20 +10,26 @@ import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
GlobalRecorder = &lineRecorder{level: -1000}
|
||||
ErrorRecorder = &lineRecorder{level: slog.LevelError}
|
||||
globalLevels = &levelTracker{
|
||||
GlobalRecorder = &lineRecorder{level: -1000}
|
||||
ErrorRecorder = &lineRecorder{level: slog.LevelError}
|
||||
DefaultLineFormat = LineFormat{
|
||||
TimestampFormat: time.DateTime,
|
||||
LevelString: true,
|
||||
}
|
||||
globalLevels = &levelTracker{
|
||||
levels: make(map[string]slog.Level),
|
||||
descrs: make(map[string]string),
|
||||
}
|
||||
slogDef = slog.New(&formattingHandler{
|
||||
recs: []*lineRecorder{GlobalRecorder, ErrorRecorder},
|
||||
out: logWriter(),
|
||||
})
|
||||
globalFormatter = &formattingOptions{
|
||||
LineFormat: DefaultLineFormat,
|
||||
recs: []*lineRecorder{GlobalRecorder, ErrorRecorder},
|
||||
out: logWriter(),
|
||||
}
|
||||
slogDef = slog.New(&formattingHandler{opts: globalFormatter})
|
||||
)
|
||||
|
||||
func logWriter() io.Writer {
|
||||
@@ -38,21 +44,4 @@ func logWriter() io.Writer {
|
||||
|
||||
func init() {
|
||||
slog.SetDefault(slogDef)
|
||||
|
||||
// Handle legacy STTRACE var
|
||||
pkgs := strings.Split(os.Getenv("STTRACE"), ",")
|
||||
for _, pkg := range pkgs {
|
||||
pkg = strings.TrimSpace(pkg)
|
||||
if pkg == "" {
|
||||
continue
|
||||
}
|
||||
level := slog.LevelDebug
|
||||
if cutPkg, levelStr, ok := strings.Cut(pkg, ":"); ok {
|
||||
pkg = cutPkg
|
||||
if err := level.UnmarshalText([]byte(levelStr)); err != nil {
|
||||
slog.Warn("Bad log level requested in STTRACE", slog.String("pkg", pkg), slog.String("level", levelStr), Error(err))
|
||||
}
|
||||
}
|
||||
globalLevels.Set(pkg, level)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,15 @@ func getRedactedConfig(s *service) config.Configuration {
|
||||
if rawConf.GUI.User != "" {
|
||||
rawConf.GUI.User = "REDACTED"
|
||||
}
|
||||
|
||||
for folderIdx, folderCfg := range rawConf.Folders {
|
||||
for deviceIdx, deviceCfg := range folderCfg.Devices {
|
||||
if deviceCfg.EncryptionPassword != "" {
|
||||
rawConf.Folders[folderIdx].Devices[deviceIdx].EncryptionPassword = "REDACTED"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rawConf
|
||||
}
|
||||
|
||||
|
||||
@@ -491,15 +491,26 @@ nextFile:
|
||||
continue nextFile
|
||||
}
|
||||
|
||||
// Verify there is some availability for the file before we start
|
||||
// processing it
|
||||
devices := f.model.fileAvailability(f.FolderConfiguration, fi)
|
||||
if len(devices) > 0 {
|
||||
if err := f.handleFile(fi, copyChan); err != nil {
|
||||
f.newPullError(fileName, err)
|
||||
}
|
||||
if len(devices) == 0 {
|
||||
f.newPullError(fileName, errNotAvailable)
|
||||
f.queue.Done(fileName)
|
||||
continue
|
||||
}
|
||||
f.newPullError(fileName, errNotAvailable)
|
||||
f.queue.Done(fileName)
|
||||
|
||||
// Verify we have space to handle the file before we start
|
||||
// creating temp files etc.
|
||||
if err := f.CheckAvailableSpace(uint64(fi.Size)); err != nil { //nolint:gosec
|
||||
f.newPullError(fileName, err)
|
||||
f.queue.Done(fileName)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := f.handleFile(fi, copyChan); err != nil {
|
||||
f.newPullError(fileName, err)
|
||||
}
|
||||
}
|
||||
|
||||
return changed, fileDeletions, dirDeletions, nil
|
||||
@@ -1327,13 +1338,6 @@ func (f *sendReceiveFolder) copierRoutine(in <-chan copyBlocksState, pullChan ch
|
||||
}
|
||||
|
||||
for state := range in {
|
||||
if err := f.CheckAvailableSpace(uint64(state.file.Size)); err != nil { //nolint:gosec
|
||||
state.fail(err)
|
||||
// Nothing more to do for this failed file, since it would use to much disk space
|
||||
out <- state.sharedPullerState
|
||||
continue
|
||||
}
|
||||
|
||||
if f.Type != config.FolderTypeReceiveEncrypted {
|
||||
f.model.progressEmitter.Register(state.sharedPullerState)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/internal/slogutil"
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
)
|
||||
|
||||
@@ -125,11 +126,12 @@ func (s *stateTracker) setState(newState folderState) {
|
||||
eventData["duration"] = time.Since(s.changed).Seconds()
|
||||
}
|
||||
|
||||
slog.Debug("Folder changed state", "folder", s.folderID, "state", newState, "from", s.current)
|
||||
|
||||
s.current = newState
|
||||
s.changed = time.Now().Truncate(time.Second)
|
||||
|
||||
s.evLogger.Log(events.StateChanged, eventData)
|
||||
slog.Info("Folder changed state", "folder", s.folderID, "state", newState)
|
||||
}
|
||||
|
||||
// getState returns the current state, the time when it last changed, and the
|
||||
@@ -156,6 +158,12 @@ func (s *stateTracker) setError(err error) {
|
||||
"from": s.current.String(),
|
||||
}
|
||||
|
||||
if err != nil && s.current != FolderError {
|
||||
slog.Warn("Folder is in error state", slog.String("folder", s.folderID), slogutil.Error(err))
|
||||
} else if err == nil && s.current == FolderError {
|
||||
slog.Info("Folder error state was cleared", slog.String("folder", s.folderID))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
eventData["error"] = err.Error()
|
||||
s.current = FolderError
|
||||
|
||||
@@ -83,6 +83,8 @@ func SecureDefaultWithTLS12() *tls.Config {
|
||||
// We've put some thought into this choice and would like it to
|
||||
// matter.
|
||||
PreferServerCipherSuites: true,
|
||||
// We support HTTP/2 and HTTP/1.1
|
||||
NextProtos: []string{"h2", "http/1.1"},
|
||||
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(0),
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
cross compilation with SQLite:
|
||||
|
||||
- dragonfly/amd64
|
||||
- illumos/amd64 and solaris/amd64
|
||||
- solaris/amd64
|
||||
- linux/ppc64
|
||||
- netbsd/*
|
||||
- openbsd/386 and openbsd/arm
|
||||
|
||||
Reference in New Issue
Block a user