mirror of
https://github.com/syncthing/syncthing.git
synced 2026-09-08 12:13:23 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ca95cf149 | ||
|
|
62f6060ceb | ||
|
|
c10408263e | ||
|
|
6c25cdebf6 | ||
|
|
ed8d87f251 | ||
|
|
9af3c75f37 | ||
|
|
e009ec07ff | ||
|
|
38ac58c82e | ||
|
|
82f3e86424 | ||
|
|
305162e0af | ||
|
|
a907594914 | ||
|
|
db2b02c44d | ||
|
|
34b3603052 | ||
|
|
bb9dac4f75 | ||
|
|
0fc519fac7 | ||
|
|
058bcd7334 | ||
|
|
42ea7231c5 | ||
|
|
328d910aee | ||
|
|
d7df27a367 | ||
|
|
8ea09c0094 |
No files matched your search
@@ -7,7 +7,7 @@ on:
|
||||
- infra-*
|
||||
|
||||
env:
|
||||
GO_VERSION: "~1.26.0"
|
||||
GO_VERSION: "~1.27.0"
|
||||
CGO_ENABLED: "0"
|
||||
BUILD_USER: docker
|
||||
BUILD_HOST: github.syncthing.net
|
||||
@@ -15,6 +15,7 @@ env:
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
docker-syncthing:
|
||||
@@ -30,11 +31,11 @@ jobs:
|
||||
- stupgrades
|
||||
- ursrv
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # was: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-go@v6
|
||||
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # was: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
@@ -77,6 +78,7 @@ jobs:
|
||||
echo "TAGS=$tags" >> $GITHUB_ENV
|
||||
|
||||
- name: Build and push
|
||||
id: build
|
||||
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5
|
||||
with:
|
||||
context: .
|
||||
@@ -86,3 +88,11 @@ jobs:
|
||||
tags: ${{ env.TAGS }}
|
||||
labels: |
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
|
||||
- name: Install Cosign
|
||||
if: github.ref == 'refs/heads/infrastructure'
|
||||
uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0
|
||||
|
||||
- name: Sign image
|
||||
if: github.ref == 'refs/heads/infrastructure'
|
||||
run: cosign sign --yes --recursive ghcr.io/syncthing/infra/${{ matrix.pkg }}:latest@${{ steps.build.outputs.digest }}
|
||||
@@ -18,7 +18,7 @@ env:
|
||||
# The go version to use for builds. We set check-latest to true when
|
||||
# installing, so we get the latest patch version that matches the
|
||||
# expression.
|
||||
GO_VERSION: "~1.26.0"
|
||||
GO_VERSION: "~1.27.0"
|
||||
|
||||
# Optimize compatibility on the slow architectures.
|
||||
GOMIPS: softfloat
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
runner: ["windows-latest", "ubuntu-latest", "macos-latest"]
|
||||
# The oldest version in this list should match what we have in our go.mod.
|
||||
# Variables don't seem to be supported here, or we could have done something nice.
|
||||
go: ["~1.25.0", "~1.26.0"]
|
||||
go: ["~1.26.0", "~1.27.0"]
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Set git to use LF
|
||||
@@ -445,7 +445,7 @@ jobs:
|
||||
CERTIFICATE_PATH=$RUNNER_TEMP/codesign.p12
|
||||
echo "$DEVELOPER_ID_CERTIFICATE_BASE64" | base64 -d -o "$CERTIFICATE_PATH"
|
||||
security import "$CERTIFICATE_PATH" -k "$KEYCHAIN_PATH" -P "$DEVELOPER_ID_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/productsign
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k actions "$KEYCHAIN_PATH"
|
||||
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
|
||||
# Set the codesign identity for following steps
|
||||
echo "CODESIGN_IDENTITY=$CODESIGN_IDENTITY" >> $GITHUB_ENV
|
||||
@@ -1012,6 +1012,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
needs:
|
||||
- facts
|
||||
env:
|
||||
@@ -1115,6 +1116,7 @@ jobs:
|
||||
mv bin/* script ctx
|
||||
|
||||
- name: Build and push Docker image
|
||||
id: build
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
||||
with:
|
||||
context: ctx
|
||||
@@ -1126,6 +1128,22 @@ jobs:
|
||||
org.opencontainers.image.version=${{ env.VERSION }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
|
||||
- name: Install Cosign
|
||||
if: github.event_name == 'push'
|
||||
uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0
|
||||
|
||||
- name: Sign image
|
||||
if: github.event_name == 'push'
|
||||
env:
|
||||
DIGEST: ${{ steps.build.outputs.digest }}
|
||||
run: |
|
||||
IFS="," read -ra tags <<< $DOCKER_TAGS
|
||||
images=""
|
||||
for tag in ${tags[@]}; do
|
||||
images+="${tag}@${DIGEST} "
|
||||
done
|
||||
cosign sign --yes --recursive ${images}
|
||||
|
||||
#
|
||||
# Sync images to Docker hub. This takes the images already pushed to GHCR
|
||||
# and copies them to Docker hub. Runs for releases only.
|
||||
|
||||
@@ -17,10 +17,10 @@ import (
|
||||
)
|
||||
|
||||
type event struct {
|
||||
ID int `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Time time.Time `json:"time"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
ID int `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Time time.Time `json:"time"`
|
||||
Data map[string]any `json:"data"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -60,7 +60,6 @@ func checkServers(deviceID protocol.DeviceID, servers ...string) {
|
||||
t0 := time.Now()
|
||||
resc := make(chan checkResult)
|
||||
for _, srv := range servers {
|
||||
srv := srv
|
||||
go func() {
|
||||
res := checkServer(deviceID, srv)
|
||||
res.server = srv
|
||||
|
||||
@@ -34,7 +34,7 @@ func generateFiles(dir string, files, maxexp int, srcname string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < files; i++ {
|
||||
for range files {
|
||||
n := randomName()
|
||||
|
||||
if rand.Float64() < 0.05 {
|
||||
@@ -51,10 +51,7 @@ func generateFiles(dir string, files, maxexp int, srcname string) error {
|
||||
p1 := filepath.Join(p0, n)
|
||||
|
||||
s := int64(1 << uint(rand.Intn(maxexp)))
|
||||
a := int64(128 * 1024)
|
||||
if a > s {
|
||||
a = s
|
||||
}
|
||||
a := min(int64(128*1024), s)
|
||||
s += rand.Int63n(a)
|
||||
|
||||
if err := generateOneFile(fd, p1, s); err != nil {
|
||||
|
||||
@@ -138,7 +138,7 @@ func printProgress(prefix string, count *atomic.Int64) {
|
||||
}
|
||||
}
|
||||
|
||||
func saveCert(priv interface{}, derBytes []byte) {
|
||||
func saveCert(priv any, derBytes []byte) {
|
||||
certOut, err := os.Create("cert.pem")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -179,7 +179,7 @@ func saveCert(priv interface{}, derBytes []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
func pemBlockForKey(priv interface{}) (*pem.Block, error) {
|
||||
func pemBlockForKey(priv any) (*pem.Block, error) {
|
||||
switch k := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}, nil
|
||||
|
||||
@@ -203,7 +203,7 @@ func loadIgnorePatterns(path string) (*ignorePatterns, error) {
|
||||
}
|
||||
|
||||
var patterns []*regexp.Regexp
|
||||
for _, line := range strings.Split(string(bs), "\n") {
|
||||
for line := range strings.SplitSeq(string(bs), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build noassets
|
||||
// +build noassets
|
||||
|
||||
package auto
|
||||
|
||||
|
||||
@@ -587,7 +587,7 @@ func loadRelays(file string, geoip *geoip.Provider) []*relay {
|
||||
}
|
||||
|
||||
var relays []*relay
|
||||
for _, line := range strings.Split(string(content), "\n") {
|
||||
for line := range strings.SplitSeq(string(content), "\n") {
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
for i := 0; i < 10; i++ {
|
||||
for i := range 10 {
|
||||
u := fmt.Sprintf("permanent%d", i)
|
||||
permanentRelays = append(permanentRelays, &relay{URL: u})
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -20,6 +21,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
@@ -31,11 +33,12 @@ import (
|
||||
)
|
||||
|
||||
type cli struct {
|
||||
Listen string `default:":8080" help:"Listen address"`
|
||||
MetricsListen string `default:":8082" help:"Listen address for metrics"`
|
||||
URL string `short:"u" default:"https://api.github.com/repos/syncthing/syncthing/releases?per_page=25" help:"GitHub releases url"`
|
||||
Forward []string `short:"f" help:"Forwarded pages, format: /path->https://example/com/url"`
|
||||
CacheTime time.Duration `default:"15m" help:"Cache time"`
|
||||
Listen string `default:":8080" help:"Listen address"`
|
||||
MetricsListen string `default:":8082" help:"Listen address for metrics"`
|
||||
URL string `short:"u" default:"https://api.github.com/repos/syncthing/syncthing/releases?per_page=25" help:"GitHub releases url"`
|
||||
Forward []string `short:"f" help:"Forwarded pages, format: /path->https://example/com/url"`
|
||||
CacheTime time.Duration `default:"15m" help:"Cache time"`
|
||||
AssetURLTemplate string `help:"Template for asset URLs, blank to use GitHub default" env:"ASSET_URL_TEMPLATE"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -69,7 +72,7 @@ func server(params *cli) error {
|
||||
}()
|
||||
}
|
||||
|
||||
cache := &cachedReleases{url: params.URL}
|
||||
cache := &cachedReleases{url: params.URL, assetURLTemplate: params.AssetURLTemplate}
|
||||
if err := cache.Update(context.Background()); err != nil {
|
||||
return fmt.Errorf("initial cache update: %w", err)
|
||||
} else {
|
||||
@@ -188,7 +191,7 @@ func (p *proxy) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
if strings.HasPrefix(ct, "application/json") {
|
||||
// Special JSON handling; clean it up a bit.
|
||||
var v interface{}
|
||||
var v any
|
||||
if err := json.NewDecoder(resp.Body).Decode(&v); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
@@ -224,7 +227,7 @@ func filterForLatest(rels []upgrade.Release) []upgrade.Release {
|
||||
return filtered
|
||||
}
|
||||
|
||||
var userAgentOSArchExp = regexp.MustCompile(`^syncthing.*\(.+ (\w+)-(\w+)\)$`)
|
||||
var userAgentOSArchExp = regexp.MustCompile(`^[Ss]yncthing.*\(.+ (\w+)-(\w+)\)$`)
|
||||
|
||||
func filterForCompatibility(rels []upgrade.Release, ua, osv string) []upgrade.Release {
|
||||
osArch := userAgentOSArchExp.FindStringSubmatch(ua)
|
||||
@@ -266,6 +269,7 @@ func filterForCompatibility(rels []upgrade.Release, ua, osv string) []upgrade.Re
|
||||
|
||||
type cachedReleases struct {
|
||||
url string
|
||||
assetURLTemplate string
|
||||
mut sync.RWMutex
|
||||
current []upgrade.Release
|
||||
latestRel, latestPre string
|
||||
@@ -278,7 +282,7 @@ func (c *cachedReleases) Releases() []upgrade.Release {
|
||||
}
|
||||
|
||||
func (c *cachedReleases) Update(ctx context.Context) error {
|
||||
rels, err := fetchGithubReleases(ctx, c.url)
|
||||
rels, err := fetchGithubReleases(ctx, c.url, c.assetURLTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -306,7 +310,7 @@ func (c *cachedReleases) Update(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func fetchGithubReleases(ctx context.Context, url string) ([]upgrade.Release, error) {
|
||||
func fetchGithubReleases(ctx context.Context, url, assetURLTemplate string) ([]upgrade.Release, error) {
|
||||
req, err := http.NewRequestWithContext(context.TODO(), http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
metricHTTPRequests.WithLabelValues("github-releases", "error").Inc()
|
||||
@@ -325,12 +329,25 @@ func fetchGithubReleases(ctx context.Context, url string) ([]upgrade.Release, er
|
||||
}
|
||||
metricHTTPRequests.WithLabelValues("github-releases", "success").Inc()
|
||||
|
||||
tpl, err := template.New("asset").Parse(assetURLTemplate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Move the URL used for browser downloads to the URL field, and remove
|
||||
// the browser URL field. This avoids going via the GitHub API for
|
||||
// downloads, since Syncthing uses the URL field.
|
||||
for _, rel := range rels {
|
||||
for j, asset := range rel.Assets {
|
||||
rel.Assets[j].URL = asset.BrowserURL
|
||||
if assetURLTemplate != "" {
|
||||
buf := new(bytes.Buffer)
|
||||
if err := tpl.Execute(buf, map[string]any{"Release": rel, "Asset": asset}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rel.Assets[j].URL = buf.String()
|
||||
} else {
|
||||
rel.Assets[j].URL = asset.BrowserURL
|
||||
}
|
||||
rel.Assets[j].BrowserURL = ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ func (s *server) handleNewData(w http.ResponseWriter, r *http.Request) {
|
||||
bs, _ := io.ReadAll(lr)
|
||||
if err := json.Unmarshal(bs, &rep); err != nil {
|
||||
log.Error("Failed to decode JSON", slogutil.Error(err))
|
||||
http.Error(w, "JSON Decode Error", http.StatusInternalServerError)
|
||||
http.Error(w, "JSON Decode Error", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ func (s *server) handleNewData(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if err := rep.Validate(); err != nil {
|
||||
log.Error("Failed to validate report", slogutil.Error(err))
|
||||
http.Error(w, "Validation Error", http.StatusInternalServerError)
|
||||
http.Error(w, "Validation Error", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+26
-19
@@ -23,6 +23,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -154,21 +155,10 @@ func (s *apiSrv) handler(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
slog.Debug("Handling request", "id", reqID, "method", req.Method, "url", req.URL, "proto", req.Proto)
|
||||
|
||||
remoteAddr := &net.TCPAddr{
|
||||
IP: nil,
|
||||
Port: -1,
|
||||
}
|
||||
|
||||
var remoteAddr *net.TCPAddr
|
||||
if s.useHTTP {
|
||||
// X-Forwarded-For can have multiple client IPs; split using the comma separator
|
||||
forwardIP, _, _ := strings.Cut(req.Header.Get("X-Forwarded-For"), ",")
|
||||
|
||||
// net.ParseIP will return nil if leading/trailing whitespace exists; use strings.TrimSpace()
|
||||
remoteAddr.IP = net.ParseIP(strings.TrimSpace(forwardIP))
|
||||
|
||||
if parsedPort, err := strconv.ParseInt(req.Header.Get("X-Client-Port"), 10, 0); err == nil {
|
||||
remoteAddr.Port = int(parsedPort)
|
||||
}
|
||||
remoteAddr = forwardedRemoteAddr(req)
|
||||
} else {
|
||||
var err error
|
||||
remoteAddr, err = net.ResolveTCPAddr("tcp", req.RemoteAddr)
|
||||
@@ -191,6 +181,21 @@ func (s *apiSrv) handler(w http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func forwardedRemoteAddr(req *http.Request) *net.TCPAddr {
|
||||
forwardIP, _, _ := strings.Cut(req.Header.Get("X-Forwarded-For"), ",")
|
||||
|
||||
remoteAddr := &net.TCPAddr{
|
||||
IP: net.ParseIP(strings.TrimSpace(forwardIP)),
|
||||
Port: -1,
|
||||
}
|
||||
|
||||
if parsedPort, err := strconv.ParseInt(req.Header.Get("X-Client-Port"), 10, 0); err == nil {
|
||||
remoteAddr.Port = int(parsedPort)
|
||||
}
|
||||
|
||||
return remoteAddr
|
||||
}
|
||||
|
||||
func (s *apiSrv) handleGET(w http.ResponseWriter, req *http.Request) {
|
||||
reqID := req.Context().Value(idKey).(requestID)
|
||||
|
||||
@@ -206,6 +211,7 @@ func (s *apiSrv) handleGET(w http.ResponseWriter, req *http.Request) {
|
||||
rec, err := s.db.get(&deviceID)
|
||||
if err != nil {
|
||||
// some sort of internal error
|
||||
slog.Warn("Failed to handle GET request", "id", reqID, "error", err)
|
||||
lookupRequestsTotal.WithLabelValues("internal_error").Inc()
|
||||
w.Header().Set("Retry-After", errorRetryAfterString())
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
@@ -284,7 +290,7 @@ func (s *apiSrv) handlePOST(remoteAddr *net.TCPAddr, w http.ResponseWriter, req
|
||||
}
|
||||
|
||||
if err := s.handleAnnounce(deviceID, addresses); err != nil {
|
||||
slog.Debug("Failed to handle request", "id", reqID, "error", err)
|
||||
slog.Warn("Failed to handle POST request", "id", reqID, "error", err)
|
||||
announceRequestsTotal.WithLabelValues("internal_error").Inc()
|
||||
w.Header().Set("Retry-After", errorRetryAfterString())
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
@@ -326,7 +332,11 @@ func (s *apiSrv) handleAnnounce(deviceID protocol.DeviceID, addresses []string)
|
||||
return s.db.merge(&deviceID, dbAddrs, seen)
|
||||
}
|
||||
|
||||
func handlePing(w http.ResponseWriter, _ *http.Request) {
|
||||
func handlePing(w http.ResponseWriter, req *http.Request) {
|
||||
hostname, _ := os.Hostname()
|
||||
w.Header().Set("Discovery-Server-Instance", hostname)
|
||||
w.Header().Set("Discovery-Client-Address", req.RemoteAddr)
|
||||
w.Header().Set("Discovery-Client-Remote", forwardedRemoteAddr(req).String())
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
@@ -402,10 +412,7 @@ func (s *apiSrv) certificateBytes(req *http.Request) ([]byte, error) {
|
||||
b.WriteByte('\n')
|
||||
|
||||
for i := 0; i < len(cert); i += 64 {
|
||||
end := i + 64
|
||||
if end > len(cert) {
|
||||
end = len(cert)
|
||||
}
|
||||
end := min(i+64, len(cert))
|
||||
b.WriteString(cert[i:end])
|
||||
b.WriteByte('\n')
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -120,7 +119,7 @@ func TestRetryAfterSHistogram(t *testing.T) {
|
||||
numBuckets := (notFoundRetryUnknownMaxSeconds + bucketSize - 1) / bucketSize
|
||||
buckets := make([]int, numBuckets)
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
for range n {
|
||||
v := tracker.retryAfterS()
|
||||
if v < notFoundRetryUnknownMinSeconds || v > notFoundRetryUnknownMaxSeconds {
|
||||
t.Fatalf("retryAfterS() = %d, out of range [%d, %d]", v, notFoundRetryUnknownMinSeconds, notFoundRetryUnknownMaxSeconds)
|
||||
@@ -142,10 +141,7 @@ func TestRetryAfterSHistogram(t *testing.T) {
|
||||
barWidth := 60
|
||||
for i, c := range buckets {
|
||||
lo := i*bucketSize + 1
|
||||
hi := (i + 1) * bucketSize
|
||||
if hi > notFoundRetryUnknownMaxSeconds {
|
||||
hi = notFoundRetryUnknownMaxSeconds
|
||||
}
|
||||
hi := min((i+1)*bucketSize, notFoundRetryUnknownMaxSeconds)
|
||||
bar := ""
|
||||
if maxCount > 0 {
|
||||
bar = strings.Repeat("#", c*barWidth/maxCount)
|
||||
@@ -156,8 +152,7 @@ func TestRetryAfterSHistogram(t *testing.T) {
|
||||
|
||||
func BenchmarkAPIRequests(b *testing.B) {
|
||||
db := newInMemoryStore(b.TempDir(), 0, nil)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx := b.Context()
|
||||
go db.Serve(ctx)
|
||||
api := newAPISrv("127.0.0.1:0", tls.Certificate{}, db, nil, true, true, 1000, 1000)
|
||||
srv := httptest.NewServer(http.HandlerFunc(api.handler))
|
||||
|
||||
@@ -35,10 +35,10 @@ const (
|
||||
|
||||
// Reannounce-After is set to reannounceAfterSeconds +
|
||||
// random(reannounzeFuzzSeconds), similar for Retry-After
|
||||
reannounceAfterSeconds = 3300
|
||||
reannounzeFuzzSeconds = 300
|
||||
errorRetryAfterSeconds = 1500
|
||||
errorRetryFuzzSeconds = 300
|
||||
reannounceAfterSeconds = 2400
|
||||
reannounzeFuzzSeconds = 1800
|
||||
errorRetryAfterSeconds = 1800
|
||||
errorRetryFuzzSeconds = 900
|
||||
|
||||
// Retry for not found is notFoundRetrySeenSeconds for records we have
|
||||
// seen an announcement for (but it's not active right now) and
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
|
||||
var (
|
||||
outboxesMut = sync.RWMutex{}
|
||||
outboxes = make(map[syncthingprotocol.DeviceID]chan interface{})
|
||||
outboxes = make(map[syncthingprotocol.DeviceID]chan any)
|
||||
numConnections atomic.Int64
|
||||
)
|
||||
|
||||
@@ -97,9 +97,9 @@ func protocolConnectionHandler(tcpConn net.Conn, config *tls.Config, token strin
|
||||
|
||||
id := syncthingprotocol.NewDeviceID(certs[0].Raw)
|
||||
|
||||
messages := make(chan interface{})
|
||||
messages := make(chan any)
|
||||
errors := make(chan error, 1)
|
||||
outbox := make(chan interface{})
|
||||
outbox := make(chan any)
|
||||
|
||||
// Read messages from the connection and send them on the messages
|
||||
// channel. When there is an error, send it on the error channel and
|
||||
@@ -364,7 +364,7 @@ func sessionConnectionHandler(conn net.Conn) {
|
||||
}
|
||||
}
|
||||
|
||||
func messageReader(conn net.Conn, messages chan<- interface{}, errors chan<- error) {
|
||||
func messageReader(conn net.Conn, messages chan<- any, errors chan<- error) {
|
||||
numConnections.Add(1)
|
||||
defer numConnections.Add(-1)
|
||||
|
||||
|
||||
@@ -330,10 +330,7 @@ func take(tokens int, ls ...*rate.Limiter) {
|
||||
|
||||
for tokens > 0 {
|
||||
// chunk is how many tokens we can consume at a time
|
||||
chunk := tokens
|
||||
if chunk > minBurst {
|
||||
chunk = minBurst
|
||||
}
|
||||
chunk := min(tokens, minBurst)
|
||||
|
||||
// maxDelay is the longest delay mandated by any of the limiters for
|
||||
// the chosen chunk size.
|
||||
|
||||
@@ -38,7 +38,7 @@ func statusService(addr string) {
|
||||
|
||||
func getStatus(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
status := make(map[string]interface{})
|
||||
status := make(map[string]any)
|
||||
|
||||
sessionMut.Lock()
|
||||
// This can potentially be double the number of pending sessions, as each session has two keys, one for each side.
|
||||
@@ -67,7 +67,7 @@ func getStatus(w http.ResponseWriter, _ *http.Request) {
|
||||
rc.rate(30*60/10) * 8 / 1000,
|
||||
rc.rate(60*60/10) * 8 / 1000,
|
||||
}
|
||||
status["options"] = map[string]interface{}{
|
||||
status["options"] = map[string]any{
|
||||
"network-timeout": networkTimeout / time.Second,
|
||||
"ping-interval": pingInterval / time.Second,
|
||||
"message-timeout": messageTimeout / time.Second,
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/build"
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
"github.com/syncthing/syncthing/lib/locations"
|
||||
@@ -27,7 +28,7 @@ import (
|
||||
type APIClient interface {
|
||||
Get(url string) (*http.Response, error)
|
||||
Post(url, body string) (*http.Response, error)
|
||||
PutJSON(url string, o interface{}) (*http.Response, error)
|
||||
PutJSON(url string, o any) (*http.Response, error)
|
||||
}
|
||||
|
||||
type apiClient struct {
|
||||
@@ -115,6 +116,7 @@ func (c *apiClient) Endpoint() string {
|
||||
|
||||
func (c *apiClient) Do(req *http.Request) (*http.Response, error) {
|
||||
req.Header.Set("X-Api-Key", c.apikey)
|
||||
req.Header.Set("User-Agent", build.UserAgent())
|
||||
resp, err := c.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -134,7 +136,7 @@ func (c *apiClient) RequestString(url, method, data string) (*http.Response, err
|
||||
return c.Request(url, method, bytes.NewBufferString(data))
|
||||
}
|
||||
|
||||
func (c *apiClient) RequestJSON(url, method string, o interface{}) (*http.Response, error) {
|
||||
func (c *apiClient) RequestJSON(url, method string, o any) (*http.Response, error) {
|
||||
data, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -150,7 +152,7 @@ func (c *apiClient) Post(url, body string) (*http.Response, error) {
|
||||
return c.RequestString(url, "POST", body)
|
||||
}
|
||||
|
||||
func (c *apiClient) PutJSON(url string, o interface{}) (*http.Response, error) {
|
||||
func (c *apiClient) PutJSON(url string, o any) (*http.Response, error) {
|
||||
return c.RequestJSON(url, "PUT", o)
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ func (c *configCommand) Run(ctx Context, outerCtx *kong.Context) error {
|
||||
app.Name = "syncthing cli config"
|
||||
app.HelpName = "syncthing cli config"
|
||||
app.Description = outerCtx.Selected().Help
|
||||
app.Metadata = map[string]interface{}{
|
||||
app.Metadata = map[string]any{
|
||||
"clientFactory": ctx.clientFactory,
|
||||
}
|
||||
app.CustomAppHelpTemplate = customAppHelpTemplate
|
||||
|
||||
@@ -112,7 +112,7 @@ func getConfig(c APIClient) (config.Configuration, error) {
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func prettyPrintJSON(data interface{}) error {
|
||||
func prettyPrintJSON(data any) error {
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", " ")
|
||||
return enc.Encode(data)
|
||||
@@ -123,7 +123,7 @@ func prettyPrintResponse(response *http.Response) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var data interface{}
|
||||
var data any
|
||||
if err := json.Unmarshal(bytes, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/internal/slogutil"
|
||||
"github.com/syncthing/syncthing/lib/build"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -81,6 +82,7 @@ func uploadPanicLog(ctx context.Context, urlBase, file string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
headReq.Header.Set("User-Agent", build.UserAgent())
|
||||
|
||||
// Set a reasonable timeout on the HEAD request
|
||||
headCtx, headCancel := context.WithTimeout(ctx, headRequestTimeout)
|
||||
@@ -101,6 +103,7 @@ func uploadPanicLog(ctx context.Context, urlBase, file string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
putReq.Header.Set("User-Agent", build.UserAgent())
|
||||
|
||||
// Set a reasonable timeout on the PUT request
|
||||
putCtx, putCancel := context.WithTimeout(ctx, putRequestTimeout)
|
||||
@@ -125,7 +128,7 @@ func uploadPanicLog(ctx context.Context, urlBase, file string) error {
|
||||
func filterLogLines(data []byte) []byte {
|
||||
filtered := data[:0]
|
||||
matched := false
|
||||
for _, line := range bytes.Split(data, []byte("\n")) {
|
||||
for line := range bytes.SplitSeq(data, []byte("\n")) {
|
||||
switch {
|
||||
case !matched && bytes.HasPrefix(line, []byte("Panic ")):
|
||||
// This begins the panic trace, set the matched flag and append.
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
|
||||
+57
-35
@@ -313,21 +313,6 @@ func (c *serveCmd) Run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func openGUI() error {
|
||||
cfg, err := loadOrDefaultConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if guiCfg := cfg.GUI(); guiCfg.Enabled {
|
||||
if err := openURL(guiCfg.URL()); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
slog.Error("Browser: GUI is currently disabled")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func logPackages() string {
|
||||
packages := slogutil.PackageDescrs()
|
||||
|
||||
@@ -389,6 +374,7 @@ func upgradeViaRest() error {
|
||||
target := u.String()
|
||||
r, _ := http.NewRequest(http.MethodPost, target, nil)
|
||||
r.Header.Set("X-Api-Key", cfg.GUI().APIKey)
|
||||
r.Header.Set("User-Agent", build.UserAgent())
|
||||
|
||||
tr := &http.Transport{
|
||||
DialContext: dialer.DialContext,
|
||||
@@ -418,6 +404,28 @@ func upgradeViaRest() error {
|
||||
}
|
||||
|
||||
func (c *serveCmd) syncthingMain() {
|
||||
// Ensure we are the only running instance
|
||||
lf := flock.New(locations.Get(locations.LockFile))
|
||||
locked, err := lf.TryLock()
|
||||
switch {
|
||||
case err != nil:
|
||||
slog.Error("Failed to acquire lock", slogutil.Error(err))
|
||||
os.Exit(svcutil.ExitError.AsInt())
|
||||
|
||||
case !locked && c.NoBrowser:
|
||||
slog.Error("Failed to acquire lock: is another Syncthing instance already running?")
|
||||
os.Exit(svcutil.ExitError.AsInt())
|
||||
|
||||
case !locked:
|
||||
slog.Info("Seems to already be running, launching GUI instead (use --no-browser to prevent)")
|
||||
cmd := browserCmd{Verify: true}
|
||||
if err := cmd.Run(); err != nil {
|
||||
slog.Error("Failed to open browser", slogutil.Error(err))
|
||||
os.Exit(svcutil.ExitNoRestart.AsInt())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if c.DebugProfileBlock {
|
||||
startBlockProfiler()
|
||||
}
|
||||
@@ -436,18 +444,7 @@ func (c *serveCmd) syncthingMain() {
|
||||
)
|
||||
if err != nil {
|
||||
slog.Error("Failed to load/generate certificate", slogutil.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Ensure we are the only running instance
|
||||
lf := flock.New(locations.Get(locations.LockFile))
|
||||
locked, err := lf.TryLock()
|
||||
if err != nil {
|
||||
slog.Error("Failed to acquire lock", slogutil.Error(err))
|
||||
os.Exit(1)
|
||||
} else if !locked {
|
||||
slog.Error("Failed to acquire lock: is another Syncthing instance already running?")
|
||||
os.Exit(1)
|
||||
os.Exit(svcutil.ExitError.AsInt())
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@@ -502,13 +499,13 @@ func (c *serveCmd) syncthingMain() {
|
||||
|
||||
if err := syncthing.TryMigrateDatabase(ctx, c.DBDeleteRetentionInterval); err != nil {
|
||||
slog.Error("Failed to migrate old-style database", slogutil.Error(err))
|
||||
os.Exit(1)
|
||||
os.Exit(svcutil.ExitError.AsInt())
|
||||
}
|
||||
|
||||
sdb, err := syncthing.OpenDatabase(locations.Get(locations.Database), c.DBDeleteRetentionInterval)
|
||||
if err != nil {
|
||||
slog.Error("Error opening database", slogutil.Error(err))
|
||||
os.Exit(1)
|
||||
os.Exit(svcutil.ExitError.AsInt())
|
||||
}
|
||||
|
||||
if c.DebugPerfStats {
|
||||
@@ -915,7 +912,7 @@ func (u upgradeCmd) Run() error {
|
||||
switch {
|
||||
case err != nil && !os.IsNotExist(err):
|
||||
slog.Error("Failed to lock for upgrade", slogutil.Error(err))
|
||||
os.Exit(1)
|
||||
os.Exit(svcutil.ExitError.AsInt())
|
||||
case locked || os.IsNotExist(err):
|
||||
// We got the lock, or the config directory didn't exist, so we
|
||||
// can do a direct upgrade
|
||||
@@ -935,14 +932,39 @@ func (u upgradeCmd) Run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type browserCmd struct{}
|
||||
type browserCmd struct {
|
||||
Verify bool `help:"Verify that the GUI is reachable before launching browser"`
|
||||
}
|
||||
|
||||
func (browserCmd) Run() error {
|
||||
if err := openGUI(); err != nil {
|
||||
slog.Error("Failed to open web UI", slogutil.Error(err))
|
||||
func (c browserCmd) Run() error {
|
||||
cfg, err := loadOrDefaultConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
guiCfg := cfg.GUI()
|
||||
if !guiCfg.Enabled {
|
||||
slog.Error("Browser: GUI is currently disabled")
|
||||
os.Exit(svcutil.ExitError.AsInt())
|
||||
}
|
||||
return nil
|
||||
url := guiCfg.URL()
|
||||
|
||||
if c.Verify {
|
||||
// Do an HTTP request to verify the GUI/API is up and available
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("User-Agent", build.UserAgent())
|
||||
_, err = http.DefaultClient.Do(req) //nolint:bodyclose // we're exiting in a millisecond
|
||||
if err != nil {
|
||||
slog.Error("GUI not available", slogutil.Error(err))
|
||||
os.Exit(svcutil.ExitError.AsInt()) //nolint:gocritic // deferred cancel
|
||||
}
|
||||
}
|
||||
|
||||
return openURL(url)
|
||||
}
|
||||
|
||||
type debugCmd struct {
|
||||
|
||||
@@ -171,10 +171,11 @@ func (c *serveCmd) monitorMain() {
|
||||
exiterr := &exec.ExitError{}
|
||||
if errors.As(err, &exiterr) {
|
||||
exitCode := exiterr.ExitCode()
|
||||
if stopped || c.NoRestart {
|
||||
switch {
|
||||
case stopped || c.NoRestart:
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
if exitCode == svcutil.ExitUpgrade.AsInt() {
|
||||
|
||||
case exitCode == svcutil.ExitUpgrade.AsInt():
|
||||
// Restart the monitor process to release the .old
|
||||
// binary as part of the upgrade process.
|
||||
slog.Info("Restarting monitor...")
|
||||
@@ -182,6 +183,10 @@ func (c *serveCmd) monitorMain() {
|
||||
slog.Error("Failed to restart monitor", slogutil.Error(err))
|
||||
}
|
||||
os.Exit(exitCode)
|
||||
|
||||
case exitCode == svcutil.ExitNoRestart.AsInt():
|
||||
// Requested to not restart the child
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !solaris && !windows
|
||||
// +build !solaris,!windows
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build solaris || windows
|
||||
// +build solaris windows
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build go1.7
|
||||
// +build go1.7
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -46,3 +46,8 @@
|
||||
linux: "3.2"
|
||||
windows: "10.0"
|
||||
|
||||
- runtime: go1.27
|
||||
requirements:
|
||||
darwin: "22" # macOS 13 (Ventura)
|
||||
linux: "3.2"
|
||||
windows: "10.0"
|
||||
@@ -1,10 +1,10 @@
|
||||
module github.com/syncthing/syncthing
|
||||
|
||||
go 1.25.0
|
||||
go 1.26.2
|
||||
|
||||
require (
|
||||
github.com/AudriusButkevicius/recli v0.0.7
|
||||
github.com/alecthomas/kong v1.16.0
|
||||
github.com/alecthomas/kong v1.16.1
|
||||
github.com/aws/aws-sdk-go v1.55.8
|
||||
github.com/calmh/incontainer v1.0.0
|
||||
github.com/calmh/xdr v1.2.0
|
||||
@@ -16,23 +16,23 @@ require (
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gofrs/flock v0.13.0
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
github.com/jackpal/gateway v1.1.1
|
||||
github.com/jackpal/gateway v1.2.0
|
||||
github.com/jackpal/go-nat-pmp v1.0.2
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/julienschmidt/httprouter v1.3.0
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
github.com/maruel/panicparse/v2 v2.5.0
|
||||
github.com/mattn/go-sqlite3 v1.14.48
|
||||
github.com/mattn/go-sqlite3 v1.14.50
|
||||
github.com/maxmind/geoipupdate/v6 v6.1.0
|
||||
github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75
|
||||
github.com/oschwald/geoip2-golang v1.13.0
|
||||
github.com/pierrec/lz4/v4 v4.1.27
|
||||
github.com/prometheus/client_golang v1.24.0
|
||||
github.com/pierrec/lz4/v4 v4.1.29
|
||||
github.com/prometheus/client_golang v1.24.1
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1
|
||||
github.com/quic-go/quic-go v0.60.0
|
||||
github.com/rabbitmq/amqp091-go v1.13.0
|
||||
github.com/quic-go/quic-go v0.61.0
|
||||
github.com/rabbitmq/amqp091-go v1.14.0
|
||||
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9
|
||||
github.com/shirou/gopsutil/v4 v4.26.6
|
||||
github.com/shirou/gopsutil/v4 v4.26.7
|
||||
github.com/syncthing/notify v0.0.0-20250528144937-c7027d4f7465
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d
|
||||
github.com/thejerf/suture/v4 v4.0.6
|
||||
@@ -40,14 +40,14 @@ require (
|
||||
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0
|
||||
github.com/willabides/kongplete v0.4.0
|
||||
github.com/wlynxg/anet v0.0.5
|
||||
golang.org/x/crypto v0.54.0
|
||||
golang.org/x/exp v0.0.0-20260718201538-764159d718ef
|
||||
golang.org/x/net v0.57.0
|
||||
golang.org/x/crypto v0.55.0
|
||||
golang.org/x/exp v0.0.0-20260813180055-c1d0aacb2297
|
||||
golang.org/x/net v0.58.0
|
||||
golang.org/x/sys v0.47.0
|
||||
golang.org/x/text v0.40.0
|
||||
golang.org/x/text v0.41.0
|
||||
golang.org/x/time v0.15.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
modernc.org/sqlite v1.54.0
|
||||
google.golang.org/protobuf v1.36.12
|
||||
modernc.org/sqlite v1.57.0
|
||||
sigs.k8s.io/yaml v1.6.0
|
||||
)
|
||||
|
||||
@@ -58,48 +58,41 @@ require (
|
||||
github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/ebitengine/purego v0.10.0 // indirect
|
||||
github.com/ebitengine/purego v0.10.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/pprof v0.0.0-20250423184734-337e5dd93bb4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-isatty v0.0.24 // indirect
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.12.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/ncruces/go-strftime v1.0.0 // indirect
|
||||
github.com/nxadm/tail v1.4.11 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/posener/complete v1.2.3 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.70.0 // indirect
|
||||
github.com/prometheus/common v0.70.1 // indirect
|
||||
github.com/prometheus/procfs v0.21.1 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/stretchr/testify v1.11.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.16 // indirect
|
||||
github.com/tklauser/numcpus v0.11.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
||||
golang.org/x/mod v0.38.0 // indirect
|
||||
golang.org/x/mod v0.39.0 // indirect
|
||||
golang.org/x/sync v0.22.0 // indirect
|
||||
golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 // indirect
|
||||
golang.org/x/tools v0.48.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/libc v1.74.1 // indirect
|
||||
golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5 // indirect
|
||||
golang.org/x/tools v0.49.0 // indirect
|
||||
modernc.org/libc v1.74.4 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
)
|
||||
|
||||
@@ -7,8 +7,8 @@ github.com/Azure/go-ntlmssp v0.1.1/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/kong v1.16.0 h1:g92/kUxBcdcTPOM79yE63viJgtcp5dNyrB3/O2cjYT4=
|
||||
github.com/alecthomas/kong v1.16.0/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I=
|
||||
github.com/alecthomas/kong v1.16.1 h1:ixhCt93XkJ98kGposQ54+bl0IK6XwqB40AsMynU7Z8E=
|
||||
github.com/alecthomas/kong v1.16.1/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I=
|
||||
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
|
||||
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI=
|
||||
@@ -45,8 +45,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
|
||||
github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/ebitengine/purego v0.10.2 h1:W809HbnvzAxgdm+aOvlSekrM16wGCdT/e76+9tS7gzE=
|
||||
github.com/ebitengine/purego v0.10.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
@@ -86,8 +86,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20250423184734-337e5dd93bb4 h1:gD0vax+4I+mAj+jEChEf25Ia07Jq7kYOFO5PPhAxFl4=
|
||||
github.com/google/pprof v0.0.0-20250423184734-337e5dd93bb4/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
||||
github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=
|
||||
github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -104,6 +104,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jackpal/gateway v1.2.0 h1:euPRe4t7JfTaqC5Lr78HXl2wSHo54XndTtiAcIxkb5g=
|
||||
github.com/jackpal/gateway v1.2.0/go.mod h1:/jchvRi4HukAqV24da70iaBMFcSrX3rNWdR5K9VHd0A=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
@@ -128,27 +130,21 @@ github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4d
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ=
|
||||
github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
|
||||
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0=
|
||||
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
|
||||
github.com/marbens-arch/gateway v1.1.2-0.20260308173556-c567cc04e7d4 h1:8TAc8a26Pp0+8I6rj43BqhMi84D1zvtY0sPzO3IKnBw=
|
||||
github.com/marbens-arch/gateway v1.1.2-0.20260308173556-c567cc04e7d4/go.mod h1:Tl1vZVtUaXx5j6P5HFmv45alhEi4yHHLfT4PRbB7eyw=
|
||||
github.com/maruel/panicparse/v2 v2.5.0 h1:yCtuS0FWjfd0RTYMXGpDvWcb0kINm8xJGu18/xMUh00=
|
||||
github.com/maruel/panicparse/v2 v2.5.0/go.mod h1:DA2fDiBk63bKfBf4CVZP9gb4fuvzdPbLDsSI873hweQ=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
|
||||
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.48 h1:7XHIgl0a8HwOaiK4E47ozLkST78rR9+OtNGx27D/TFs=
|
||||
github.com/mattn/go-sqlite3 v1.14.48/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
|
||||
github.com/mattn/go-sqlite3 v1.14.50 h1:dmdFvo1XG4MPzA4IkAmE9upVz/Nj31uRoM5+jC8hYbY=
|
||||
github.com/mattn/go-sqlite3 v1.14.50/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.12.0 h1:aOeI7xAOVdK+R6xbVsZuU9HmCZYmQVmZgPf9xJUd2Sg=
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.12.0/go.mod h1:0hZWbtfeCYUQeAQdPLUzETiBhUSns7O6LDj9vH88xKA=
|
||||
github.com/maxmind/geoipupdate/v6 v6.1.0 h1:sdtTHzzQNJlXF5+fd/EoPTucRHyMonYt/Cok8xzzfqA=
|
||||
@@ -179,8 +175,8 @@ github.com/oschwald/geoip2-golang v1.13.0 h1:Q44/Ldc703pasJeP5V9+aFSZFmBN7DKHbNs
|
||||
github.com/oschwald/geoip2-golang v1.13.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
|
||||
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
|
||||
github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
|
||||
github.com/pierrec/lz4/v4 v4.1.27 h1:+PhzhWDrjRj89TH2sw43nE3+4+W8lSxIuQadEHZyjUk=
|
||||
github.com/pierrec/lz4/v4 v4.1.27/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
|
||||
github.com/pierrec/lz4/v4 v4.1.29 h1:CDQY6qZOLI4DW0Nx6R1vRrifrCeQHnNXkMb0hZWXFjg=
|
||||
github.com/pierrec/lz4/v4 v4.1.29/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -190,41 +186,40 @@ github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXq
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prometheus/client_golang v1.24.0 h1:5XStIklKuAtJSNpdD3s8XJj/Yv78IQmE1kbNk87JrAI=
|
||||
github.com/prometheus/client_golang v1.24.0/go.mod h1:QcsNdotprC2nS4BTM2ucbcqxd2CeXTEa9jW7zHO9iDE=
|
||||
github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU=
|
||||
github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.70.0 h1:bcpru3tWPVnxGnETLgOV5jbp/JRXgYEyv65CuBLAMMI=
|
||||
github.com/prometheus/common v0.70.0/go.mod h1:S/SFasQmgGiYH6C81LKCtYa8QACgthGg5zxL2udV7SY=
|
||||
github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY=
|
||||
github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc=
|
||||
github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
|
||||
github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
||||
github.com/quic-go/go-ossfuzz-seeds v0.1.0 h1:APacT+iIaNF6fd8AGEiN3bT/Jtkd2jz4v4TzM7MFjy0=
|
||||
github.com/quic-go/go-ossfuzz-seeds v0.1.0/go.mod h1:3IOHRbJIc+L6YKMwfDtJAM9Vj9k0YY4muhuyUYk5tbk=
|
||||
github.com/quic-go/quic-go v0.60.0 h1:xcQioE8OM66UQLeUMHltK1CCcOu3JbVB4JAQdDQSB+0=
|
||||
github.com/quic-go/quic-go v0.60.0/go.mod h1:wpKpjmPpftl30sL6pFh7REVpjbcCVy4zt2vDyK1TuJk=
|
||||
github.com/rabbitmq/amqp091-go v1.13.0 h1:L8NA1WtF76C6KA3LAoufjfLgbist/If1UQYcsOjtxXA=
|
||||
github.com/rabbitmq/amqp091-go v1.13.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
||||
github.com/quic-go/quic-go v0.61.0 h1:ui88A53s8MSVYLC56en0KQ17HARk+9986Dn0SBfKNvA=
|
||||
github.com/quic-go/quic-go v0.61.0/go.mod h1:9So2anK4Tp22URSQq00k+Vo2PNkle96ycDPDHL4s9vs=
|
||||
github.com/rabbitmq/amqp091-go v1.14.0 h1:RSaT7aOKt/OrkVUyswPDW29lnRz9psuGmfZFBmLqLek=
|
||||
github.com/rabbitmq/amqp091-go v1.14.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 h1:bsUq1dX0N8AOIL7EB/X911+m4EHsnWEHeJ0c+3TTBrg=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab h1:ZjX6I48eZSFetPb41dHudEyVr5v953N15TsNZXlkcWY=
|
||||
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab/go.mod h1:/PfPXh0EntGc3QAAyUaviy4S9tzy4Zp0e2ilq4voC6E=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
|
||||
github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM=
|
||||
github.com/shirou/gopsutil/v4 v4.26.6 h1:Mzr/npDtQC/xpeEuQKHZt8Zo9CmPvhTj8nkR8w5TLDs=
|
||||
github.com/shirou/gopsutil/v4 v4.26.6/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
|
||||
github.com/shirou/gopsutil/v4 v4.26.7 h1:IXzpHz/dkMRYAhKkOXr1HB6SuzWU3eoyyeWe7g3bNZc=
|
||||
github.com/shirou/gopsutil/v4 v4.26.7/go.mod h1:5O9FjBiXoTDFatIWjZZosqj4pV0DRtLx598xGbBehzM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
|
||||
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
@@ -267,13 +262,13 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
|
||||
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
|
||||
golang.org/x/exp v0.0.0-20260718201538-764159d718ef h1:LkZ48HFgy/TvhTI0bcWkjgFkgLyKUwcTbDjS0DUjw+A=
|
||||
golang.org/x/exp v0.0.0-20260718201538-764159d718ef/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q=
|
||||
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
|
||||
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
|
||||
golang.org/x/exp v0.0.0-20260813180055-c1d0aacb2297 h1:YXnL44eJ77R+ji4/ooy8UsXIhz+lbi2Qgdlc8iRN0gY=
|
||||
golang.org/x/exp v0.0.0-20260813180055-c1d0aacb2297/go.mod h1:Mkmymgv+uMpSQ/XxJ/7GpdrdYoqm3u72jEbpCLiJmNk=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
|
||||
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
|
||||
golang.org/x/mod v0.39.0 h1:UF5zwQdCRRUpHfyPwr7d4UrGiVeldIsogtzWVnczL74=
|
||||
golang.org/x/mod v0.39.0/go.mod h1:bvIbwjQ0HUFFf5AKukeeYQG4ZBUG9yxQbR9aEweIwYY=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -282,8 +277,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
|
||||
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
|
||||
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
|
||||
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -310,26 +305,25 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 h1:RJhm5l6Fo4rmEIcndxDllNhhf/fAx8qIm4t6A7vpm2A=
|
||||
golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959/go.mod h1:LV7u5Oco+Z/g6XI7PqN+EUUUGGkEcmB1uj2ceI0fOVg=
|
||||
golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5 h1:ZUSxONxc981v7AW7QUg+I9WwZzSTTJ019ENBYr5pV/Q=
|
||||
golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5/go.mod h1:LVehoXe41cL5SCVQilsV7Gg6BNG+Js6P9PhSbYTIUkQ=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
|
||||
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
|
||||
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
|
||||
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
|
||||
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
|
||||
golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
|
||||
golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI=
|
||||
golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -343,11 +337,9 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
||||
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
@@ -360,8 +352,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
modernc.org/cc/v4 v4.29.0 h1:CXgwL8cvxmyzBQZzbSl/6xFtMCryb6u8IOqDci39cgc=
|
||||
modernc.org/cc/v4 v4.29.0/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
|
||||
modernc.org/cc/v4 v4.29.1 h1:MKgdCV3WykTSPqpVrnxdEDS0HEd2FHpKZDzxzU5LyeI=
|
||||
modernc.org/cc/v4 v4.29.1/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
|
||||
modernc.org/ccgo/v4 v4.34.6 h1:sBgfIwyN0TQ9C5hwIeuqyeAKyMWnbvj2fvpF4L11uzU=
|
||||
modernc.org/ccgo/v4 v4.34.6/go.mod h1:SZ8YcN9NG7XVsQYdm6jYBvi8PQP1qi+kqB6OhjqI3Fk=
|
||||
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
|
||||
@@ -372,8 +364,8 @@ modernc.org/gc/v3 v3.1.4 h1:2g65LGVSmFQrXeITAw97x7hCRvZFcyE1uDP+7Vng7JI=
|
||||
modernc.org/gc/v3 v3.1.4/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
|
||||
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
||||
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||
modernc.org/libc v1.74.1 h1:bdR4VTKFMC4966QSNZ05XLGI/VwzVa2kTUX51Dm0riQ=
|
||||
modernc.org/libc v1.74.1/go.mod h1:uH4t5bOx3G3g9Xcmj10YKlTcVISlRDwv8VoQJG9n8Os=
|
||||
modernc.org/libc v1.74.4 h1:fX1Omw4o2/1C2iRkkIsrQTasJQldLhRmuPreXLoWs9k=
|
||||
modernc.org/libc v1.74.4/go.mod h1:eeQAS9W3sZeKYMFubydxJpII9ybHWshk+7or7bLG9co=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
||||
@@ -382,8 +374,8 @@ modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg=
|
||||
modernc.org/opt v0.2.0/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||
modernc.org/sqlite v1.54.0 h1:JCxR4qwkJvOaqAoYcgDoO25Nc+ROg6EJ2LfBVzdrgog=
|
||||
modernc.org/sqlite v1.54.0/go.mod h1:4ntCLuNmnH8+GNqjka1wNg7KJd5/Hi5FYp8K+XQ7GZw=
|
||||
modernc.org/sqlite v1.57.0 h1:qNQP6xnx5M0ISNtlnxoOX0+cD5bJ0/gr9aMmndFczzg=
|
||||
modernc.org/sqlite v1.57.0/go.mod h1:yCJ2cmAaIkHQ25oXWrF8H4O1lIfPYPR26yCEDj2P3pQ=
|
||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
||||
@@ -125,6 +125,8 @@
|
||||
"Discovery Status": "حالة الاكتشاف",
|
||||
"Dismiss": "رفض",
|
||||
"Do not add it to the ignore list, so this notification may recur.": "لا تقم بإضافته إلى قائمة التجاهل، لذلك قد يتكرر هذا الإشعار.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device connects again.": "لا تقم بإضافته إلى قائمة التجاهل، حتى يتم اخطارك عند اعادة اتصال الجهاز.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device offering this folder connects again.": "لا تقم بإضافته إلى قائمة التجاهل، حتى يتم اخطارك عند اعادة اتصال الجهاز المزوّد لهذا المجلد.",
|
||||
"Do not restore": "الغاء الاستعادة",
|
||||
"Do not restore all": "الغاء استعادة الكل",
|
||||
"Do you want to enable watching for changes for all your folders?": "هل تريد تفعيل مراقبة التغيرات على كل المجلدات؟",
|
||||
|
||||
@@ -125,6 +125,8 @@
|
||||
"Discovery Status": "Discovery Status",
|
||||
"Dismiss": "Dismiss",
|
||||
"Do not add it to the ignore list, so this notification may recur.": "Do not add it to the ignore list, so this notification may recur.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device connects again.": "Do not add it to the ignore list, so this notification will reappear if the device connects again.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device offering this folder connects again.": "Do not add it to the ignore list, so this notification will reappear if the device offering this folder connects again.",
|
||||
"Do not restore": "Do not restore",
|
||||
"Do not restore all": "Do not restore all",
|
||||
"Do you want to enable watching for changes for all your folders?": "Do you want to enable watching for changes for all your folders?",
|
||||
|
||||
@@ -1,2 +1,31 @@
|
||||
{
|
||||
"A device with that ID is already added.": "یک دستگاه با این شناسه قبلاً اضافه شده است.",
|
||||
"A negative number of days doesn't make sense.": "تعداد روزهای منفی قابل قبول نیست.",
|
||||
"A new major version may not be compatible with previous versions.": "نسخه جدید اصلی ممکن است با نسخه قبلی سازگار نباشد.",
|
||||
"API Key": "کلید API",
|
||||
"About": "درباره",
|
||||
"Action": "عمل",
|
||||
"Actions": "اعمال",
|
||||
"Active filter rules": "قوانین فیلتر فعال",
|
||||
"Add": "افزودن",
|
||||
"Add Device": "افزودن دستگاه",
|
||||
"Add Folder": "افزودن پوشه",
|
||||
"Add Remote Device": "افزودن دستگاه دیگر",
|
||||
"Add filter entry": "افزودن ورودی فیلتر",
|
||||
"Add ignore patterns": "افزودن الگوی نادیده گرفتن",
|
||||
"Add new folder?": "افزودن پوشه جدید؟",
|
||||
"Address": "نشانی",
|
||||
"Addresses": "نشانیها",
|
||||
"Advanced": "پیشرفته",
|
||||
"Advanced Configuration": "پیکربندی پیشرفته",
|
||||
"All Data": "تمام دادهها",
|
||||
"All Time": "تمام زمان",
|
||||
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "تمام پوشههای به اشتراک گذاشته در این دستگاه باید با یک گذرواژه محافظت شوند، دادههای ارسال شده بدون گذرواژه غیرقابل خواندن هستند.",
|
||||
"Allow Anonymous Usage Reporting?": "اجازه دادن به ارسال ناشناس گزارش استفاده؟",
|
||||
"Allowed Networks": "شبکههای مجاز",
|
||||
"Alphabetic": "الفبایی",
|
||||
"Altered by ignoring deletes.": "با نادیده گرفتن حذفها تغییر داده شد.",
|
||||
"LDAP": "LDAP",
|
||||
"TCP WAN": "TCPWAN",
|
||||
"Take me back": "برگرداندن"
|
||||
}
|
||||
@@ -47,7 +47,7 @@
|
||||
"Automatic upgrade now offers the choice between stable releases and release candidates.": "Le système de mise à jour automatique propose le choix entre versions stables et versions préliminaires.",
|
||||
"Automatic upgrades": "Mises à jour automatiques",
|
||||
"Automatic upgrades are always enabled for candidate releases.": "Les mises à jour automatiques sont toujours activées pour les versions mineures.",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Automatiquement créer dans le chemin par défaut les partages auxquels cet appareil vous propose de participer, ou accepter leur partage s'ils pré-existent.",
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Accepter automatiquement ses propositions de partage. Si le partage n'existe pas déjà ici, le répertoire correspondant sera créé dans le chemin par défaut.",
|
||||
"Available debug logging facilities:": "Outils de débogage disponibles :",
|
||||
"Be careful!": "Faites attention !",
|
||||
"Block Indexing": "Indexation des blocs",
|
||||
|
||||
@@ -125,6 +125,8 @@
|
||||
"Discovery Status": "탐지 현황",
|
||||
"Dismiss": "나중에",
|
||||
"Do not add it to the ignore list, so this notification may recur.": "무시 항목에 추가되지 않으니 이 알림이 다시 표시될 수 있습니다.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device connects again.": "무시 항목에 추가되지 않으니 해당 기기가 다시 연결되면 이 알림은 다시 표시될 것입니다.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device offering this folder connects again.": "무시 항목에 추가되지 않으니 이 폴더를 공유하는 기가가 연결되면 이 알림은 다시 표시될 것입니다.",
|
||||
"Do not restore": "복구하지 않기",
|
||||
"Do not restore all": "모두 복구하지 않기",
|
||||
"Do you want to enable watching for changes for all your folders?": "변경 항목 감시를 모든 폴더에서 활성화하시겠습니까?",
|
||||
@@ -395,6 +397,7 @@
|
||||
"Staggered": "시차제",
|
||||
"Staggered File Versioning": "시차제 파일 버전 관리",
|
||||
"Start Browser": "브라우저 열기",
|
||||
"Starting": "시작 중",
|
||||
"Statistics": "통계",
|
||||
"Stay logged in": "로그인 상태 유지",
|
||||
"Stopped": "중지됨",
|
||||
|
||||
@@ -125,8 +125,8 @@
|
||||
"Discovery Status": "Stan odnajdywania",
|
||||
"Dismiss": "Odrzuć",
|
||||
"Do not add it to the ignore list, so this notification may recur.": "Nie dodaje do listy ignorowanych, więc powiadomienie to może się powtórzyć.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device connects again.": "Nie dodaje do listy ignorowanych, więc powiadomienie pojawi się ponownie, gdy urządzenie połączy się ponownie.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device offering this folder connects again.": "Nie dodaje do listy ignorowanych, więc powiadomienie pojawi się ponownie, gdy urządzenie oferujące ten folder ponownie się połączy.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device connects again.": "Nie dodaje do listy ignorowanych, więc powiadomienie pojawi się ponownie, gdy urządzenie po raz kolejny się połączy.",
|
||||
"Do not add it to the ignore list, so this notification will reappear if the device offering this folder connects again.": "Nie dodaje do listy ignorowanych, więc powiadomienie pojawi się ponownie, gdy urządzenie oferujące ten folder po raz kolejny się połączy.",
|
||||
"Do not restore": "Nie przywracaj",
|
||||
"Do not restore all": "Nie przywracaj wszystkich",
|
||||
"Do you want to enable watching for changes for all your folders?": "Czy chcesz włączyć obserwowanie zmian we wszystkich folderach?",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"Automatically create or share folders that this device advertises at the default path.": "Crează sau partajează automat mapele anunțate de acest dispozitiv la calea implicită.",
|
||||
"Available debug logging facilities:": "Facilități disponibile pentru registrul de depanare:",
|
||||
"Be careful!": "Fii atent!",
|
||||
"Block Indexing": "Blochează indexarea",
|
||||
"Body:": "Corp:",
|
||||
"Bugs": "Bug-uri",
|
||||
"Cancel": "Renunță",
|
||||
@@ -82,6 +83,7 @@
|
||||
"Custom Range": "Interval Personalizat",
|
||||
"Danger!": "Pericol!",
|
||||
"Database Location": "Locația Bazei de Date",
|
||||
"Debug": "Depanează",
|
||||
"Debugging Facilities": "Facilități de Depanare",
|
||||
"Default": "Implicit",
|
||||
"Default Configuration": "Configurare implicită",
|
||||
@@ -97,6 +99,7 @@
|
||||
"Device": "Dispozitiv",
|
||||
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Dispozitivul \"{{name}}\" ({{device}} la {{address}}) vrea să se conecteze. Adaugă un dispozitiv nou?",
|
||||
"Device Certificate": "Certificatul dispozitivului",
|
||||
"Device Group": "Grup de dispozitive",
|
||||
"Device ID": "ID Dispozitiv",
|
||||
"Device Identification": "Identificare Dispozitiv",
|
||||
"Device Name": "Nume Dispozitiv",
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
"Edit Device Defaults": "Изменить настройки устройств",
|
||||
"Edit Folder": "Редактирование папки",
|
||||
"Edit Folder Defaults": "Изменить настройки папок",
|
||||
"Editing {%path%}.": "Правка {{path}}.",
|
||||
"Editing {%path%}.": "Редактирование {{path}}.",
|
||||
"Enable Crash Reporting": "Включить отчёты о сбоях",
|
||||
"Enable NAT traversal": "Использовать обход NAT",
|
||||
"Enable Relaying": "Использовать ретрансляторы",
|
||||
@@ -396,6 +396,7 @@
|
||||
"Staggered": "Ступенчато",
|
||||
"Staggered File Versioning": "Ступенчатое управление версиями файлов",
|
||||
"Start Browser": "Запускать браузер",
|
||||
"Starting": "Запуск",
|
||||
"Statistics": "Статистика",
|
||||
"Stay logged in": "Оставаться в системе",
|
||||
"Stopped": "Остановлено",
|
||||
|
||||
@@ -59,7 +59,6 @@ Jakob Borg, Audrius Butkevicius, Simon Frei, Tomasz Wilczyński, Alexander Graf,
|
||||
<li><a href="https://github.com/ccding/go-stun">ccding/go-stun</a>, Copyright © 2016 Cong Ding.</li>
|
||||
<li><a href="https://github.com/cespare/xxhash/v2">cespare/xxhash/v2</a>, Copyright © 2016 Caleb Spare.</li>
|
||||
<li><a href="https://github.com/cpuguy83/go-md2man/v2">cpuguy83/go-md2man/v2</a>, Copyright © 2014 Brian Goff.</li>
|
||||
<li><a href="https://github.com/davecgh/go-spew">davecgh/go-spew</a>, Copyright © 2012-2016 Dave Collins.</li>
|
||||
<li><a href="https://github.com/go-asn1-ber/asn1-ber">go-asn1-ber/asn1-ber</a>, Copyright © 2011-2015 Michael Mitton (mmitton@gmail.com).</li>
|
||||
<li><a href="https://github.com/go-ldap/ldap">go-ldap/ldap</a>, Copyright © 2011-2015 Michael Mitton (mmitton@gmail.com).</li>
|
||||
<li><a href="https://github.com/gobwas/glob">gobwas/glob</a>, Copyright © 2016 Sergey Kamardin.</li>
|
||||
@@ -67,7 +66,6 @@ Jakob Borg, Audrius Butkevicius, Simon Frei, Tomasz Wilczyński, Alexander Graf,
|
||||
<li><a href="https://github.com/golang/snappy">golang/snappy</a>, Copyright © 2011 The Snappy-Go Authors.</li>
|
||||
<li><a href="https://github.com/protocolbuffers/protobuf-go">google.golang.org/protobuf</a>, Copyright © 2018 The Go Authors.</li>
|
||||
<li><a href="https://github.com/google/uuid">google/uuid</a>, Copyright © 2009,2014 Google Inc.</li>
|
||||
<li><a href="https://gopkg.in/yaml.v3">gopkg.in/yaml.v3</a>, Copyright © 2025, the gopkg.in/yaml.v3 authors.</li>
|
||||
<li><a href="https://github.com/hashicorp/errwrap">hashicorp/errwrap</a>, Copyright © 2014 HashiCorp, Inc.</li>
|
||||
<li><a href="https://github.com/hashicorp/go-multierror">hashicorp/go-multierror</a>, Copyright © 2014 HashiCorp, Inc.</li>
|
||||
<li><a href="https://github.com/hashicorp/golang-lru">hashicorp/golang-lru</a>, Copyright © 2014 HashiCorp, Inc.</li>
|
||||
@@ -81,7 +79,6 @@ Jakob Borg, Audrius Butkevicius, Simon Frei, Tomasz Wilczyński, Alexander Graf,
|
||||
<li><a href="https://github.com/munnerz/goautoneg">munnerz/goautoneg</a>, Copyright © 2011, Open Knowledge Foundation Ltd.</li>
|
||||
<li><a href="https://github.com/pierrec/lz4">pierrec/lz4</a>, Copyright © 2015 Pierre Curto.</li>
|
||||
<li><a href="https://github.com/pkg/errors">pkg/errors</a>, Copyright © 2015, Dave Cheney.</li>
|
||||
<li><a href="https://github.com/pmezard/go-difflib">pmezard/go-difflib</a>, Copyright © 2013, Patrick Mezard.</li>
|
||||
<li><a href="https://github.com/posener/complete">posener/complete</a>, Copyright © 2017 Eyal Posener.</li>
|
||||
<li><a href="https://github.com/prometheus/client_golang">prometheus/client_golang</a>, Copyright 2012-2015 The Prometheus Authors.</li>
|
||||
<li><a href="https://github.com/prometheus/client_model">prometheus/client_model</a>, Copyright © 2025, the prometheus/client_model authors.</li>
|
||||
@@ -92,8 +89,6 @@ Jakob Borg, Audrius Butkevicius, Simon Frei, Tomasz Wilczyński, Alexander Graf,
|
||||
<li><a href="https://github.com/riywo/loginshell">riywo/loginshell</a>, Copyright © 2019 Ryosuke IWANAGA.</li>
|
||||
<li><a href="https://github.com/russross/blackfriday/v2">russross/blackfriday/v2</a>, Copyright © 2011 Russ Ross.</li>
|
||||
<li><a href="https://github.com/shirou/gopsutil">shirou/gopsutil</a>, Copyright © 2014, WAKAYAMA Shirou.</li>
|
||||
<li><a href="https://github.com/stretchr/objx">stretchr/objx</a>, Copyright © 2014 Stretchr, Inc.</li>
|
||||
<li><a href="https://github.com/stretchr/testify">stretchr/testify</a>, Copyright © 2012-2020 Mat Ryer, Tyler Bunnell and contributors.</li>
|
||||
<li><a href="https://github.com/syndtr/goleveldb">syndtr/goleveldb</a>, Copyright © 2012 Suryandaru Triandana.</li>
|
||||
<li><a href="https://github.com/thejerf/suture">thejerf/suture</a>, Copyright © 2014-2015 Barracuda Networks, Inc.</li>
|
||||
<li><a href="https://github.com/tklauser/go-sysconf">tklauser/go-sysconf</a>, Copyright © 2018-2022, Tobias Klauser.</li>
|
||||
|
||||
@@ -313,7 +313,7 @@ nextScript:
|
||||
// files on lines containing only a semicolon and execute them
|
||||
// separately. We require it on a separate line because there are
|
||||
// also statement-internal semicolons in the triggers.
|
||||
for _, stmt := range strings.Split(string(bs), "\n;") {
|
||||
for stmt := range strings.SplitSeq(string(bs), "\n;") {
|
||||
if _, err := tx.Exec(s.expandTemplateVars(stmt)); err != nil {
|
||||
if strings.Contains(stmt, "syncthing:ignore-failure") {
|
||||
// We're ok with this failing. Just note it.
|
||||
|
||||
@@ -474,10 +474,7 @@ func (s *folderDB) recalcGlobalForFile(txp *txPreparedStmts, file string) error
|
||||
// The global version is the first one in the list that is not invalid,
|
||||
// or just the first one in the list if all are invalid.
|
||||
var global fileRow
|
||||
globIdx := slices.IndexFunc(es, func(e fileRow) bool { return !e.IsInvalid() })
|
||||
if globIdx < 0 {
|
||||
globIdx = 0
|
||||
}
|
||||
globIdx := max(slices.IndexFunc(es, func(e fileRow) bool { return !e.IsInvalid() }), 0)
|
||||
global = es[globIdx]
|
||||
|
||||
// We "have" the file if the position in the list of versions is at the
|
||||
|
||||
@@ -41,8 +41,8 @@ func SetDefaultLevel(level slog.Level) {
|
||||
}
|
||||
|
||||
func SetLevelOverrides(sttrace string) {
|
||||
pkgs := strings.Split(sttrace, ",")
|
||||
for _, pkg := range pkgs {
|
||||
pkgs := strings.SplitSeq(sttrace, ",")
|
||||
for pkg := range pkgs {
|
||||
pkg = strings.TrimSpace(pkg)
|
||||
if pkg == "" {
|
||||
continue
|
||||
|
||||
@@ -45,11 +45,11 @@ type adapter struct {
|
||||
l *slog.Logger
|
||||
}
|
||||
|
||||
func (a adapter) Debugln(vals ...interface{}) {
|
||||
func (a adapter) Debugln(vals ...any) {
|
||||
a.log(strings.TrimSpace(fmt.Sprintln(vals...)), slog.LevelDebug)
|
||||
}
|
||||
|
||||
func (a adapter) Debugf(format string, vals ...interface{}) {
|
||||
func (a adapter) Debugf(format string, vals ...any) {
|
||||
a.log(fmt.Sprintf(format, vals...), slog.LevelDebug)
|
||||
}
|
||||
|
||||
|
||||
+28
-20
@@ -202,7 +202,7 @@ func (s *service) getListener(guiCfg config.GUIConfiguration) (net.Listener, err
|
||||
return listener, nil
|
||||
}
|
||||
|
||||
func sendJSON(w http.ResponseWriter, jsonObject interface{}) {
|
||||
func sendJSON(w http.ResponseWriter, jsonObject any) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
// Marshalling might fail, in which case we should return a 500 with the
|
||||
// actual error.
|
||||
@@ -696,7 +696,7 @@ func (*service) getSystemPaths(w http.ResponseWriter, _ *http.Request) {
|
||||
}
|
||||
|
||||
func (s *service) getJSMetadata(w http.ResponseWriter, _ *http.Request) {
|
||||
meta, _ := json.Marshal(map[string]interface{}{
|
||||
meta, _ := json.Marshal(map[string]any{
|
||||
"deviceID": s.id.String(),
|
||||
"deviceIDShort": s.id.Short().String(),
|
||||
"authenticated": true,
|
||||
@@ -706,7 +706,7 @@ func (s *service) getJSMetadata(w http.ResponseWriter, _ *http.Request) {
|
||||
}
|
||||
|
||||
func (*service) getSystemVersion(w http.ResponseWriter, _ *http.Request) {
|
||||
sendJSON(w, map[string]interface{}{
|
||||
sendJSON(w, map[string]any{
|
||||
"version": build.Version,
|
||||
"codename": build.Codename,
|
||||
"longVersion": build.LongVersion,
|
||||
@@ -838,7 +838,7 @@ func (s *service) getDBNeed(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Convert the struct to a more loose structure, and inject the size.
|
||||
sendJSON(w, map[string]interface{}{
|
||||
sendJSON(w, map[string]any{
|
||||
"progress": toJsonFileInfoSlice(progress),
|
||||
"queued": toJsonFileInfoSlice(queued),
|
||||
"rest": toJsonFileInfoSlice(rest),
|
||||
@@ -866,7 +866,7 @@ func (s *service) getDBRemoteNeed(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
sendJSON(w, map[string]interface{}{
|
||||
sendJSON(w, map[string]any{
|
||||
"files": toJsonFileInfoSlice(files),
|
||||
"page": page,
|
||||
"perpage": perpage,
|
||||
@@ -886,7 +886,7 @@ func (s *service) getDBLocalChanged(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
sendJSON(w, map[string]interface{}{
|
||||
sendJSON(w, map[string]any{
|
||||
"files": toJsonFileInfoSlice(files),
|
||||
"page": page,
|
||||
"perpage": perpage,
|
||||
@@ -951,7 +951,7 @@ func (s *service) getDBFile(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
sendJSON(w, map[string]interface{}{
|
||||
sendJSON(w, map[string]any{
|
||||
"global": jsonFileInfo(gf),
|
||||
"local": jsonFileInfo(lf),
|
||||
"availability": av,
|
||||
@@ -967,7 +967,7 @@ func (s *service) getDebugFile(w http.ResponseWriter, r *http.Request) {
|
||||
gf, _, _ := s.model.CurrentGlobalFile(folder, file)
|
||||
av, _ := s.model.Availability(folder, protocol.FileInfo{Name: file}, protocol.BlockInfo{})
|
||||
|
||||
sendJSON(w, map[string]interface{}{
|
||||
sendJSON(w, map[string]any{
|
||||
"global": jsonFileInfo(gf),
|
||||
"local": jsonFileInfo(lf),
|
||||
"availability": av,
|
||||
@@ -1037,7 +1037,7 @@ func (s *service) getSystemStatus(w http.ResponseWriter, _ *http.Request) {
|
||||
runtime.ReadMemStats(&m)
|
||||
|
||||
tilde, _ := fs.ExpandTilde("~")
|
||||
res := make(map[string]interface{})
|
||||
res := make(map[string]any)
|
||||
res["myID"] = s.id.String()
|
||||
res["goroutines"] = runtime.NumGoroutine()
|
||||
res["alloc"] = m.Alloc
|
||||
@@ -1184,10 +1184,7 @@ func (s *service) getSupportBundle(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Metrics data as text
|
||||
var metricsBuf bytes.Buffer
|
||||
wr := bufferedResponseWriter{Writer: &metricsBuf}
|
||||
promhttp.Handler().ServeHTTP(wr, &http.Request{Method: http.MethodGet})
|
||||
files = append(files, fileEntry{name: "metrics.txt", data: metricsBuf.Bytes()})
|
||||
files = append(files, fileEntry{name: "metrics.txt", data: prometheusMetrics()})
|
||||
|
||||
// Connection data as JSON
|
||||
connStats := s.model.ConnectionStats()
|
||||
@@ -1258,6 +1255,16 @@ func (s *service) getSupportBundle(w http.ResponseWriter, r *http.Request) {
|
||||
io.Copy(w, &zipFilesBuffer)
|
||||
}
|
||||
|
||||
func prometheusMetrics() []byte {
|
||||
var metricsBuf bytes.Buffer
|
||||
wr := bufferedResponseWriter{Writer: &metricsBuf}
|
||||
promhttp.Handler().ServeHTTP(wr, &http.Request{
|
||||
Method: http.MethodGet,
|
||||
URL: &url.URL{Scheme: "http://", Host: "localhost", Path: "/metrics"},
|
||||
})
|
||||
return metricsBuf.Bytes()
|
||||
}
|
||||
|
||||
func (s *service) getSystemDiscovery(w http.ResponseWriter, _ *http.Request) {
|
||||
devices := make(map[string]discover.CacheEntry)
|
||||
|
||||
@@ -1302,7 +1309,7 @@ func (s *service) getDBIgnores(w http.ResponseWriter, r *http.Request) {
|
||||
folder := qs.Get("folder")
|
||||
|
||||
lines, patterns, err := s.model.LoadIgnores(folder)
|
||||
sendJSON(w, map[string]interface{}{
|
||||
sendJSON(w, map[string]any{
|
||||
"ignore": lines,
|
||||
"expanded": patterns,
|
||||
"error": errorString(err),
|
||||
@@ -1411,7 +1418,7 @@ func (s *service) getSystemUpgrade(w http.ResponseWriter, _ *http.Request) {
|
||||
httpError(w, err)
|
||||
return
|
||||
}
|
||||
res := make(map[string]interface{})
|
||||
res := make(map[string]any)
|
||||
res["running"] = build.Version
|
||||
res["latest"] = rel.Tag
|
||||
res["newer"] = upgrade.CompareVersions(rel.Tag, build.Version) == upgrade.Newer
|
||||
@@ -1439,7 +1446,7 @@ func (*service) getDeviceID(w http.ResponseWriter, r *http.Request) {
|
||||
func (*service) getLang(w http.ResponseWriter, r *http.Request) {
|
||||
lang := r.Header.Get("Accept-Language")
|
||||
weights := make(map[string]float64)
|
||||
for _, l := range strings.Split(lang, ",") {
|
||||
for l := range strings.SplitSeq(lang, ",") {
|
||||
parts := strings.SplitN(l, ";", 2)
|
||||
code := strings.ToLower(strings.TrimSpace(parts[0]))
|
||||
weights[code] = 1.0
|
||||
@@ -1638,7 +1645,7 @@ func (s *service) getFolderErrors(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
sendJSON(w, map[string]interface{}{
|
||||
sendJSON(w, map[string]any{
|
||||
"folder": folder,
|
||||
"errors": errors,
|
||||
"page": page,
|
||||
@@ -1770,8 +1777,8 @@ func (f jsonFileInfo) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
func fileIntfJSONMap(f protocol.FileInfo) map[string]interface{} {
|
||||
out := map[string]interface{}{
|
||||
func fileIntfJSONMap(f protocol.FileInfo) map[string]any {
|
||||
out := map[string]any{
|
||||
"name": f.FileName(),
|
||||
"type": f.FileType().String(),
|
||||
"size": f.Size,
|
||||
@@ -1946,7 +1953,8 @@ func sanitizedHostname(name string) (string, error) {
|
||||
return r > unicode.MaxASCII ||
|
||||
!unicode.IsLetter(r) && !unicode.IsNumber(r) &&
|
||||
r != '.' && r != '-'
|
||||
})))
|
||||
})),
|
||||
)
|
||||
name, _, err := transform.String(t, name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
+1
-4
@@ -311,10 +311,7 @@ func authLDAP(username string, password string, cfg config.LDAPConfiguration) bo
|
||||
|
||||
func formatOptionalPercentS(template string, username string) string {
|
||||
var replacements []any
|
||||
nReps := strings.Count(template, "%s") - strings.Count(template, "%%s")
|
||||
if nReps < 0 {
|
||||
nReps = 0
|
||||
}
|
||||
nReps := max(strings.Count(template, "%s")-strings.Count(template, "%%s"), 0)
|
||||
for range nReps {
|
||||
replacements = append(replacements, username)
|
||||
}
|
||||
|
||||
+9
-2
@@ -433,7 +433,6 @@ func TestAPIServiceRequests(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
tc := tc
|
||||
t.Run(tc.URL, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
testHTTPRequest(t, baseURL, tc, testAPIKey)
|
||||
@@ -1723,7 +1722,7 @@ func TestConfigChanges(t *testing.T) {
|
||||
return resp
|
||||
}
|
||||
|
||||
mod := func(method, path string, data interface{}) {
|
||||
mod := func(method, path string, data any) {
|
||||
t.Helper()
|
||||
bs, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
@@ -1830,6 +1829,14 @@ func TestSanitizedHostname(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrometheusMetrics(t *testing.T) {
|
||||
// We should get some form of reasonable metrics response
|
||||
bs := prometheusMetrics()
|
||||
if !bytes.Contains(bs, []byte("TYPE go_info gauge")) {
|
||||
t.Error("metrics should include go_info gauge")
|
||||
}
|
||||
}
|
||||
|
||||
// runningInContainer returns true if we are inside Docker or LXC. It might
|
||||
// be prone to false negatives if things change in the future, but likely
|
||||
// not false positives.
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build noassets
|
||||
// +build noassets
|
||||
|
||||
package auto
|
||||
|
||||
|
||||
@@ -441,7 +441,7 @@ func (c *configMuxBuilder) adjustLDAP(w http.ResponseWriter, r *http.Request, ld
|
||||
}
|
||||
|
||||
// Unmarshals the content of the given body and stores it in to (i.e. to must be a pointer).
|
||||
func unmarshalTo(body io.ReadCloser, to interface{}) error {
|
||||
func unmarshalTo(body io.ReadCloser, to any) error {
|
||||
bs, err := io.ReadAll(body)
|
||||
body.Close()
|
||||
if err != nil {
|
||||
|
||||
@@ -127,6 +127,10 @@ func LongVersionFor(program string) string {
|
||||
return v
|
||||
}
|
||||
|
||||
func UserAgent() string {
|
||||
return fmt.Sprintf(`Syncthing/%s (%s %s-%s)`, strings.TrimPrefix(Version, "v"), runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
||||
func TagsList() []string {
|
||||
tags := strings.Split(Tags, ",")
|
||||
if len(tags) == 1 && tags[0] == "" {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build race
|
||||
// +build race
|
||||
|
||||
package build
|
||||
|
||||
|
||||
@@ -664,7 +664,7 @@ func (defaults *Defaults) prepare(myID protocol.DeviceID, existingDevices map[pr
|
||||
defaults.Device.prepare(nil)
|
||||
}
|
||||
|
||||
func ensureZeroForNodefault(empty interface{}, target interface{}) {
|
||||
func ensureZeroForNodefault(empty any, target any) {
|
||||
copyMatchingTag(empty, target, "nodefault", func(v string) bool {
|
||||
if len(v) > 0 && v != "true" {
|
||||
panic(fmt.Sprintf(`unexpected tag value: %s. expected untagged or "true"`, v))
|
||||
@@ -674,7 +674,7 @@ func ensureZeroForNodefault(empty interface{}, target interface{}) {
|
||||
}
|
||||
|
||||
// copyMatchingTag copies fields tagged tag:"value" from "from" struct onto "to" struct.
|
||||
func copyMatchingTag(from interface{}, to interface{}, tag string, shouldCopy func(value string) bool) {
|
||||
func copyMatchingTag(from any, to any, tag string, shouldCopy func(value string) bool) {
|
||||
fromStruct := reflect.ValueOf(from).Elem()
|
||||
fromType := fromStruct.Type()
|
||||
|
||||
|
||||
@@ -1158,8 +1158,8 @@ func TestInvalidDeviceIDRejected(t *testing.T) {
|
||||
|
||||
// Change the device ID of the first device to "invalid". Fast and loose
|
||||
// with the type assertions as we know what the JSON decoder returns.
|
||||
devs := cfg["devices"].([]interface{})
|
||||
dev0 := devs[0].(map[string]interface{})
|
||||
devs := cfg["devices"].([]any)
|
||||
dev0 := devs[0].(map[string]any)
|
||||
dev0["deviceID"] = tc.id
|
||||
devs[0] = dev0
|
||||
|
||||
@@ -1197,8 +1197,8 @@ func TestInvalidFolderIDRejected(t *testing.T) {
|
||||
// Change the folder ID of the first folder to the empty string.
|
||||
// Fast and loose with the type assertions as we know what the JSON
|
||||
// decoder returns.
|
||||
devs := cfg["folders"].([]interface{})
|
||||
dev0 := devs[0].(map[string]interface{})
|
||||
devs := cfg["folders"].([]any)
|
||||
dev0 := devs[0].(map[string]any)
|
||||
dev0["id"] = tc.id
|
||||
devs[0] = dev0
|
||||
|
||||
@@ -1324,7 +1324,7 @@ func adjustFolderConfiguration(cfg *FolderConfiguration, id, label string, fsTyp
|
||||
// defaultConfigAsMap returns a valid default config as a JSON-decoded
|
||||
// map[string]interface{}. This is useful to override random elements and
|
||||
// re-encode into JSON.
|
||||
func defaultConfigAsMap() map[string]interface{} {
|
||||
func defaultConfigAsMap() map[string]any {
|
||||
cfg := New(device1)
|
||||
dev := cfg.Defaults.Device.Copy()
|
||||
adjustDeviceConfiguration(&dev, device2, "name")
|
||||
@@ -1337,7 +1337,7 @@ func defaultConfigAsMap() map[string]interface{} {
|
||||
// can't happen
|
||||
panic(err)
|
||||
}
|
||||
var tmp map[string]interface{}
|
||||
var tmp map[string]any
|
||||
if err := json.Unmarshal(bs, &tmp); err != nil {
|
||||
// can't happen
|
||||
panic(err)
|
||||
|
||||
@@ -9,6 +9,7 @@ package config
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"maps"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
@@ -45,9 +46,7 @@ type internalParam struct {
|
||||
func (c VersioningConfiguration) Copy() VersioningConfiguration {
|
||||
cp := c
|
||||
cp.Params = make(map[string]string, len(c.Params))
|
||||
for k, v := range c.Params {
|
||||
cp.Params[k] = v
|
||||
}
|
||||
maps.Copy(cp.Params, c.Params)
|
||||
return cp
|
||||
}
|
||||
|
||||
|
||||
@@ -401,7 +401,7 @@ func TestConnectionEstablishment(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func withConnectionPair(b interface{ Fatal(...interface{}) }, connUri string, h func(client, server internalConn)) {
|
||||
func withConnectionPair(b interface{ Fatal(...any) }, connUri string, h func(client, server internalConn)) {
|
||||
// Root of the service tree.
|
||||
supervisor := suture.New("main", suture.Spec{
|
||||
PassThroughPanics: true,
|
||||
@@ -494,7 +494,7 @@ func withConnectionPair(b interface{ Fatal(...interface{}) }, connUri string, h
|
||||
_ = serverConn.Close()
|
||||
}
|
||||
|
||||
func mustGetCert(b interface{ Fatal(...interface{}) }) tls.Certificate {
|
||||
func mustGetCert(b interface{ Fatal(...any) }) tls.Certificate {
|
||||
cert, err := tlsutil.NewCertificateInMemory("bench", 10)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
|
||||
@@ -54,7 +54,7 @@ func TestDialQueueSort(t *testing.T) {
|
||||
|
||||
var seen1, seen2 int
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
for range 100 {
|
||||
queue.Sort()
|
||||
res := shortDevices(queue)
|
||||
if reflect.DeepEqual(res, expected1) {
|
||||
@@ -90,7 +90,7 @@ func TestDialQueueSort(t *testing.T) {
|
||||
|
||||
var seen1, seen2 int
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
for range 100 {
|
||||
queue.Sort()
|
||||
res := shortDevices(queue)
|
||||
if reflect.DeepEqual(res, expected1) {
|
||||
|
||||
@@ -256,18 +256,14 @@ func (w *limitedWriter) Write(buf []byte) (int, error) {
|
||||
// try to be a bit adaptable. We range from the minimum write size of 1
|
||||
// KiB up to the limiter burst size, aiming for about a write every
|
||||
// 10ms.
|
||||
singleWriteSize := int(w.waiter.Limit() / 100) // 10ms worth of data
|
||||
singleWriteSize = ((singleWriteSize / 1024) + 1) * 1024 // round up to the next kibibyte
|
||||
if singleWriteSize > limiterBurstSize {
|
||||
singleWriteSize = limiterBurstSize
|
||||
}
|
||||
singleWriteSize := int(w.waiter.Limit() / 100) // 10ms worth of data
|
||||
singleWriteSize = min(
|
||||
// round up to the next kibibyte
|
||||
((singleWriteSize/1024)+1)*1024, limiterBurstSize)
|
||||
|
||||
written := 0
|
||||
for written < len(buf) {
|
||||
toWrite := singleWriteSize
|
||||
if toWrite > len(buf)-written {
|
||||
toWrite = len(buf) - written
|
||||
}
|
||||
toWrite := min(singleWriteSize, len(buf)-written)
|
||||
w.take(toWrite)
|
||||
n, err := w.writer.Write(buf[written : written+toWrite])
|
||||
written += n
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build go1.15 && !noquic
|
||||
// +build go1.15,!noquic
|
||||
|
||||
package connections
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !noquic
|
||||
// +build !noquic
|
||||
|
||||
package connections
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !noquic
|
||||
// +build !noquic
|
||||
|
||||
package connections
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build noquic
|
||||
// +build noquic
|
||||
|
||||
package connections
|
||||
|
||||
|
||||
@@ -18,23 +18,23 @@ import (
|
||||
|
||||
type Registry struct {
|
||||
mut sync.Mutex
|
||||
available map[string][]interface{}
|
||||
available map[string][]any
|
||||
}
|
||||
|
||||
func New() *Registry {
|
||||
return &Registry{
|
||||
available: make(map[string][]interface{}),
|
||||
available: make(map[string][]any),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Registry) Register(scheme string, item interface{}) {
|
||||
func (r *Registry) Register(scheme string, item any) {
|
||||
r.mut.Lock()
|
||||
defer r.mut.Unlock()
|
||||
|
||||
r.available[scheme] = append(r.available[scheme], item)
|
||||
}
|
||||
|
||||
func (r *Registry) Unregister(scheme string, item interface{}) {
|
||||
func (r *Registry) Unregister(scheme string, item any) {
|
||||
r.mut.Lock()
|
||||
defer r.mut.Unlock()
|
||||
|
||||
@@ -49,12 +49,12 @@ func (r *Registry) Unregister(scheme string, item interface{}) {
|
||||
|
||||
// Get returns an item for a schema compatible with the given scheme.
|
||||
// If any item satisfies preferred, that has precedence over other items.
|
||||
func (r *Registry) Get(scheme string, preferred func(interface{}) bool) interface{} {
|
||||
func (r *Registry) Get(scheme string, preferred func(any) bool) any {
|
||||
r.mut.Lock()
|
||||
defer r.mut.Unlock()
|
||||
|
||||
var (
|
||||
best interface{}
|
||||
best any
|
||||
bestPref bool
|
||||
bestScheme string
|
||||
)
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
func TestRegistry(t *testing.T) {
|
||||
r := New()
|
||||
|
||||
want := func(i int) func(interface{}) bool {
|
||||
return func(x interface{}) bool { return x.(int) == i }
|
||||
want := func(i int) func(any) bool {
|
||||
return func(x any) bool { return x.(int) == i }
|
||||
}
|
||||
|
||||
if res := r.Get("int", want(1)); res != nil {
|
||||
@@ -73,7 +73,7 @@ func TestShortSchemeFirst(t *testing.T) {
|
||||
r.Register("foobar", 1)
|
||||
|
||||
// If we don't care about the value, we should get the one with "foo".
|
||||
res := r.Get("foo", func(interface{}) bool { return false })
|
||||
res := r.Get("foo", func(any) bool { return false })
|
||||
if res != 0 {
|
||||
t.Error("unexpected", res)
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func BenchmarkGet(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
r.Get("tcp", func(x interface{}) bool {
|
||||
r.Get("tcp", func(x any) bool {
|
||||
return x.(*net.TCPAddr).IP.IsUnspecified()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"math"
|
||||
"net"
|
||||
"net/url"
|
||||
@@ -817,7 +818,7 @@ func (s *service) createListener(factory listenerFactory, uri *url.URL) bool {
|
||||
}
|
||||
|
||||
func (s *service) logListenAddressesChangedEvent(l ListenerAddresses) {
|
||||
s.evLogger.Log(events.ListenAddressesChanged, map[string]interface{}{
|
||||
s.evLogger.Log(events.ListenAddressesChanged, map[string]any{
|
||||
"address": l.URI,
|
||||
"lan": l.LANAddresses,
|
||||
"wan": l.WANAddresses,
|
||||
@@ -995,9 +996,7 @@ func newConnectionStatusHandler() connectionStatusHandler {
|
||||
func (s *connectionStatusHandler) ConnectionStatus() map[string]ConnectionStatusEntry {
|
||||
result := make(map[string]ConnectionStatusEntry)
|
||||
s.connectionStatusMut.RLock()
|
||||
for k, v := range s.connectionStatus {
|
||||
result[k] = v
|
||||
}
|
||||
maps.Copy(result, s.connectionStatus)
|
||||
s.connectionStatusMut.RUnlock()
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !solaris && !windows
|
||||
// +build !solaris,!windows
|
||||
|
||||
package dialer
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build solaris
|
||||
// +build solaris
|
||||
|
||||
package dialer
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package dialer
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ func DialContextReusePortFunc(registry *registry.Registry) func(ctx context.Cont
|
||||
return DialContext(ctx, network, addr)
|
||||
}
|
||||
|
||||
localAddrInterface := registry.Get(network, func(addr interface{}) bool {
|
||||
localAddrInterface := registry.Get(network, func(addr any) bool {
|
||||
return addr.(*net.TCPAddr).IP.IsUnspecified()
|
||||
})
|
||||
if localAddrInterface == nil {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
package discover
|
||||
|
||||
import (
|
||||
"maps"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -60,9 +61,7 @@ func (c *cache) Get(id protocol.DeviceID) (CacheEntry, bool) {
|
||||
func (c *cache) Cache() map[protocol.DeviceID]CacheEntry {
|
||||
c.mut.Lock()
|
||||
m := make(map[protocol.DeviceID]CacheEntry, len(c.entries))
|
||||
for k, v := range c.entries {
|
||||
m[k] = v
|
||||
}
|
||||
maps.Copy(m, c.entries)
|
||||
c.mut.Unlock()
|
||||
return m
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"golang.org/x/net/http2"
|
||||
|
||||
"github.com/syncthing/syncthing/internal/slogutil"
|
||||
"github.com/syncthing/syncthing/lib/build"
|
||||
"github.com/syncthing/syncthing/lib/connections/registry"
|
||||
"github.com/syncthing/syncthing/lib/dialer"
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
@@ -454,6 +455,7 @@ func (c *contextClient) Get(ctx context.Context, url string) (*http.Response, er
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("User-Agent", build.UserAgent())
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
@@ -463,6 +465,7 @@ func (c *contextClient) Post(ctx context.Context, url, ctype string, data io.Rea
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", ctype)
|
||||
req.Header.Set("User-Agent", build.UserAgent())
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ func (c *localClient) registerDevice(src net.Addr, device *discoproto.Announce)
|
||||
})
|
||||
|
||||
if isNewDevice {
|
||||
c.evLogger.Log(events.DeviceDiscovered, map[string]interface{}{
|
||||
c.evLogger.Log(events.DeviceDiscovered, map[string]any{
|
||||
"device": id.String(),
|
||||
"addrs": validAddresses,
|
||||
})
|
||||
|
||||
@@ -235,7 +235,7 @@ const BufferSize = 64
|
||||
|
||||
type Logger interface {
|
||||
suture.Service
|
||||
Log(t EventType, data interface{})
|
||||
Log(t EventType, data any)
|
||||
Subscribe(mask EventType) Subscription
|
||||
}
|
||||
|
||||
@@ -253,10 +253,10 @@ type Event struct {
|
||||
// Per-subscription sequential event ID. Named "id" for backwards compatibility with the REST API
|
||||
SubscriptionID int `json:"id"`
|
||||
// Global ID of the event across all subscriptions
|
||||
GlobalID int `json:"globalID"`
|
||||
Time time.Time `json:"time"`
|
||||
Type EventType `json:"type"`
|
||||
Data interface{} `json:"data"`
|
||||
GlobalID int `json:"globalID"`
|
||||
Time time.Time `json:"time"`
|
||||
Type EventType `json:"type"`
|
||||
Data any `json:"data"`
|
||||
}
|
||||
|
||||
type Subscription interface {
|
||||
@@ -325,7 +325,7 @@ loop:
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *logger) Log(t EventType, data interface{}) {
|
||||
func (l *logger) Log(t EventType, data any) {
|
||||
l.events <- Event{
|
||||
Time: time.Now(), // intentionally high precision
|
||||
Type: t,
|
||||
@@ -559,7 +559,7 @@ var NoopLogger Logger = &noopLogger{}
|
||||
|
||||
func (*noopLogger) Serve(_ context.Context) error { return nil }
|
||||
|
||||
func (*noopLogger) Log(_ EventType, _ interface{}) {}
|
||||
func (*noopLogger) Log(_ EventType, _ any) {}
|
||||
|
||||
func (*noopLogger) Subscribe(_ EventType) Subscription {
|
||||
return &noopSubscription{}
|
||||
|
||||
@@ -127,7 +127,7 @@ func TestBufferOverflow(t *testing.T) {
|
||||
|
||||
t0 := time.Now()
|
||||
const nEvents = BufferSize * 2
|
||||
for i := 0; i < nEvents; i++ {
|
||||
for range nEvents {
|
||||
l.Log(DeviceConnected, "foo")
|
||||
}
|
||||
if d := time.Since(t0); d > 15*time.Second {
|
||||
@@ -237,7 +237,7 @@ func TestBufferedSub(t *testing.T) {
|
||||
bs := NewBufferedSubscription(s, 10*BufferSize)
|
||||
|
||||
go func() {
|
||||
for i := 0; i < 10*BufferSize; i++ {
|
||||
for i := range 10 * BufferSize {
|
||||
l.Log(DeviceConnected, fmt.Sprintf("event-%d", i))
|
||||
if i%30 == 0 {
|
||||
// Give the buffer routine time to pick up the events
|
||||
@@ -378,7 +378,7 @@ func TestUnsubscribeContention(t *testing.T) {
|
||||
|
||||
stopListeners := make(chan struct{})
|
||||
var listenerWg sync.WaitGroup
|
||||
for i := 0; i < listeners; i++ {
|
||||
for range listeners {
|
||||
listenerWg.Go(func() {
|
||||
s := l.Subscribe(AllEvents)
|
||||
defer s.Unsubscribe()
|
||||
@@ -400,7 +400,7 @@ func TestUnsubscribeContention(t *testing.T) {
|
||||
stopSenders := make(chan struct{})
|
||||
defer close(stopSenders)
|
||||
var senderWg sync.WaitGroup
|
||||
for i := 0; i < senders; i++ {
|
||||
for range senders {
|
||||
senderWg.Go(func() {
|
||||
t := time.NewTicker(time.Millisecond)
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build linux || solaris
|
||||
// +build linux solaris
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build linux || android
|
||||
// +build linux android
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !linux && !android && !windows
|
||||
// +build !linux,!android,!windows
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -580,7 +580,7 @@ func TestXattr(t *testing.T) {
|
||||
|
||||
// Create a set of random attributes that we will set and read back
|
||||
var attrs []protocol.Xattr
|
||||
for i := 0; i < 10; i++ {
|
||||
for i := range 10 {
|
||||
key := fmt.Sprintf("user.test-%d", i)
|
||||
value := make([]byte, xattrSize())
|
||||
rand.Read(value)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build darwin && !kqueue && cgo && !ios
|
||||
// +build darwin,!kqueue,cgo,!ios
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build solaris && cgo
|
||||
// +build solaris,cgo
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build dragonfly || freebsd || netbsd || openbsd || ios || kqueue
|
||||
// +build dragonfly freebsd netbsd openbsd ios kqueue
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !linux && !windows && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !darwin && !cgo && !ios
|
||||
// +build !linux,!windows,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!darwin,!cgo,!ios
|
||||
|
||||
// Catch all platforms that are not specifically handled to use the generic
|
||||
// event types.
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build !dragonfly && !freebsd && !netbsd && !openbsd && !kqueue && !ios
|
||||
// +build !dragonfly,!freebsd,!netbsd,!openbsd,!kqueue,!ios
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build (!solaris && !darwin) || (solaris && cgo) || (darwin && cgo)
|
||||
// +build !solaris,!darwin solaris,cgo darwin,cgo
|
||||
|
||||
package fs
|
||||
|
||||
@@ -364,8 +363,7 @@ func TestWatchSymlinkedRoot(t *testing.T) {
|
||||
|
||||
linkedFs := NewFilesystem(FilesystemTypeBasic, filepath.Join(testFs.URI(), link))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
ctx := t.Context()
|
||||
if _, _, err := linkedFs.Watch(".", fakeMatcher{}, ctx, false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -635,6 +633,6 @@ func (fakeEventInfo) Event() notify.Event {
|
||||
return notify.Write
|
||||
}
|
||||
|
||||
func (fakeEventInfo) Sys() interface{} {
|
||||
func (fakeEventInfo) Sys() any {
|
||||
return nil
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build (solaris && !cgo) || (darwin && !cgo) || (darwin && kqueue)
|
||||
// +build solaris,!cgo darwin,!cgo darwin,kqueue
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build freebsd || netbsd
|
||||
// +build freebsd netbsd
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
//go:build linux || darwin
|
||||
// +build linux darwin
|
||||
|
||||
package fs
|
||||
|
||||
|
||||
Loaded 100 of 184 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user