From 40888c1a662256054da34d7b9eb223daf7a8ccc3 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Sat, 12 Apr 2025 05:46:57 -0700 Subject: [PATCH 1/3] fix(syncthing): use separate lock file instead of locking the certificate (fixes #10053) (#10054) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently that nukes the cert under some circumstances on some Windows 🤷 --- cmd/syncthing/main.go | 10 ++++++++-- lib/locations/locations.go | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index 1faff628e..943d11dc8 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -376,7 +376,7 @@ func (options serveOptions) Run() error { if options.Upgrade { release, err := checkUpgrade() if err == nil { - lf := flock.New(locations.Get(locations.CertFile)) + lf := flock.New(locations.Get(locations.LockFile)) locked, err := lf.TryLock() if err != nil { l.Warnln("Upgrade:", err) @@ -386,6 +386,8 @@ func (options serveOptions) Run() error { } else { err = upgrade.To(release) } + _ = lf.Unlock() + _ = os.Remove(locations.Get(locations.LockFile)) } if err != nil { l.Warnln("Upgrade:", err) @@ -546,7 +548,7 @@ func syncthingMain(options serveOptions) { } // Ensure we are the only running instance - lf := flock.New(locations.Get(locations.CertFile)) + lf := flock.New(locations.Get(locations.LockFile)) locked, err := lf.TryLock() if err != nil { l.Warnln("Failed to acquire lock:", err) @@ -692,6 +694,10 @@ func syncthingMain(options serveOptions) { pprof.StopCPUProfile() } + // Best effort remove lockfile, doesn't matter if it succeeds + _ = lf.Unlock() + _ = os.Remove(locations.Get(locations.LockFile)) + os.Exit(int(status)) } diff --git a/lib/locations/locations.go b/lib/locations/locations.go index 197c686eb..bbf11d919 100644 --- a/lib/locations/locations.go +++ b/lib/locations/locations.go @@ -33,6 +33,7 @@ const ( AuditLog LocationEnum = "auditLog" GUIAssets LocationEnum = "guiAssets" DefFolder LocationEnum = "defFolder" + LockFile LocationEnum = "lockFile" ) type BaseDirEnum string @@ -124,6 +125,7 @@ var locationTemplates = map[LocationEnum]string{ AuditLog: "${data}/audit-%{timestamp}.log", GUIAssets: "${config}/gui", DefFolder: "${userHome}/Sync", + LockFile: "${data}/syncthing.lock", } var locations = make(map[LocationEnum]string) From 190a59842c6908f99ccfcf8ae9b4d2548c3d4cbd Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Sat, 12 Apr 2025 05:46:57 -0700 Subject: [PATCH 2/3] fix(syncthing): use separate lock file instead of locking the certificate (fixes #10053) (#10054) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently that nukes the cert under some circumstances on some Windows 🤷 --- cmd/syncthing/main.go | 10 ++++++++-- lib/locations/locations.go | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index 1faff628e..943d11dc8 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -376,7 +376,7 @@ func (options serveOptions) Run() error { if options.Upgrade { release, err := checkUpgrade() if err == nil { - lf := flock.New(locations.Get(locations.CertFile)) + lf := flock.New(locations.Get(locations.LockFile)) locked, err := lf.TryLock() if err != nil { l.Warnln("Upgrade:", err) @@ -386,6 +386,8 @@ func (options serveOptions) Run() error { } else { err = upgrade.To(release) } + _ = lf.Unlock() + _ = os.Remove(locations.Get(locations.LockFile)) } if err != nil { l.Warnln("Upgrade:", err) @@ -546,7 +548,7 @@ func syncthingMain(options serveOptions) { } // Ensure we are the only running instance - lf := flock.New(locations.Get(locations.CertFile)) + lf := flock.New(locations.Get(locations.LockFile)) locked, err := lf.TryLock() if err != nil { l.Warnln("Failed to acquire lock:", err) @@ -692,6 +694,10 @@ func syncthingMain(options serveOptions) { pprof.StopCPUProfile() } + // Best effort remove lockfile, doesn't matter if it succeeds + _ = lf.Unlock() + _ = os.Remove(locations.Get(locations.LockFile)) + os.Exit(int(status)) } diff --git a/lib/locations/locations.go b/lib/locations/locations.go index 197c686eb..bbf11d919 100644 --- a/lib/locations/locations.go +++ b/lib/locations/locations.go @@ -33,6 +33,7 @@ const ( AuditLog LocationEnum = "auditLog" GUIAssets LocationEnum = "guiAssets" DefFolder LocationEnum = "defFolder" + LockFile LocationEnum = "lockFile" ) type BaseDirEnum string @@ -124,6 +125,7 @@ var locationTemplates = map[LocationEnum]string{ AuditLog: "${data}/audit-%{timestamp}.log", GUIAssets: "${config}/gui", DefFolder: "${userHome}/Sync", + LockFile: "${data}/syncthing.lock", } var locations = make(map[LocationEnum]string) From f0b666269b6bdd1e8000e56e421367260e807479 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Tue, 8 Apr 2025 00:43:19 -0700 Subject: [PATCH 3/3] build: push artifacts to Azure (#10044) Provider migration --- .github/workflows/build-syncthing.yaml | 64 ++++++++++---------------- 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/.github/workflows/build-syncthing.yaml b/.github/workflows/build-syncthing.yaml index 40810699c..84c52fff8 100644 --- a/.github/workflows/build-syncthing.yaml +++ b/.github/workflows/build-syncthing.yaml @@ -726,15 +726,12 @@ jobs: - name: Push artifacts uses: docker://docker.io/rclone/rclone:latest env: - RCLONE_CONFIG_OBJSTORE_TYPE: s3 - RCLONE_CONFIG_OBJSTORE_PROVIDER: ${{ secrets.S3_PROVIDER }} - RCLONE_CONFIG_OBJSTORE_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} - RCLONE_CONFIG_OBJSTORE_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} - RCLONE_CONFIG_OBJSTORE_ENDPOINT: ${{ secrets.S3_ENDPOINT }} - RCLONE_CONFIG_OBJSTORE_REGION: ${{ secrets.S3_REGION }} - RCLONE_CONFIG_OBJSTORE_ACL: public-read + RCLONE_CONFIG_OBJSTORE_TYPE: ${{ secrets.AZUREBLOB_TYPE }} + RCLONE_CONFIG_OBJSTORE_ACCOUNT: ${{ secrets.AZUREBLOB_ACCOUNT }} + RCLONE_CONFIG_OBJSTORE_KEY: ${{ secrets.AZUREBLOB_KEY }} + RCLONE_AZUREBLOB_ACCESS_TIER: hot with: - args: sync packages objstore:${{ secrets.S3_BUCKET }}/nightly + args: sync -v packages objstore:nightly # # Push release artifacts to Spaces @@ -780,28 +777,22 @@ jobs: - name: Push to object store (${{ env.VERSION }}) uses: docker://docker.io/rclone/rclone:latest env: - RCLONE_CONFIG_OBJSTORE_TYPE: s3 - RCLONE_CONFIG_OBJSTORE_PROVIDER: ${{ secrets.S3_PROVIDER }} - RCLONE_CONFIG_OBJSTORE_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} - RCLONE_CONFIG_OBJSTORE_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} - RCLONE_CONFIG_OBJSTORE_ENDPOINT: ${{ secrets.S3_ENDPOINT }} - RCLONE_CONFIG_OBJSTORE_REGION: ${{ secrets.S3_REGION }} - RCLONE_CONFIG_OBJSTORE_ACL: public-read + RCLONE_CONFIG_OBJSTORE_TYPE: ${{ secrets.AZUREBLOB_TYPE }} + RCLONE_CONFIG_OBJSTORE_ACCOUNT: ${{ secrets.AZUREBLOB_ACCOUNT }} + RCLONE_CONFIG_OBJSTORE_KEY: ${{ secrets.AZUREBLOB_KEY }} + RCLONE_AZUREBLOB_ACCESS_TIER: cool with: - args: sync packages objstore:${{ secrets.S3_BUCKET }}/release/${{ env.VERSION }} + args: sync -v packages objstore:release/${{ env.VERSION }} - name: Push to object store (latest) uses: docker://docker.io/rclone/rclone:latest env: - RCLONE_CONFIG_OBJSTORE_TYPE: s3 - RCLONE_CONFIG_OBJSTORE_PROVIDER: ${{ secrets.S3_PROVIDER }} - RCLONE_CONFIG_OBJSTORE_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} - RCLONE_CONFIG_OBJSTORE_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} - RCLONE_CONFIG_OBJSTORE_ENDPOINT: ${{ secrets.S3_ENDPOINT }} - RCLONE_CONFIG_OBJSTORE_REGION: ${{ secrets.S3_REGION }} - RCLONE_CONFIG_OBJSTORE_ACL: public-read + RCLONE_CONFIG_OBJSTORE_TYPE: ${{ secrets.AZUREBLOB_TYPE }} + RCLONE_CONFIG_OBJSTORE_ACCOUNT: ${{ secrets.AZUREBLOB_ACCOUNT }} + RCLONE_CONFIG_OBJSTORE_KEY: ${{ secrets.AZUREBLOB_KEY }} + RCLONE_AZUREBLOB_ACCESS_TIER: hot with: - args: sync objstore:${{ secrets.S3_BUCKET }}/release/${{ env.VERSION }} objstore:${{ secrets.S3_BUCKET }}/release/latest + args: sync -v objstore:release/${{ env.VERSION }} objstore:release/latest # # Push Debian/APT archive @@ -848,15 +839,11 @@ jobs: - name: Pull archive uses: docker://docker.io/rclone/rclone:latest env: - RCLONE_CONFIG_OBJSTORE_TYPE: s3 - RCLONE_CONFIG_OBJSTORE_PROVIDER: ${{ secrets.S3_PROVIDER }} - RCLONE_CONFIG_OBJSTORE_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} - RCLONE_CONFIG_OBJSTORE_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} - RCLONE_CONFIG_OBJSTORE_ENDPOINT: ${{ secrets.S3_ENDPOINT }} - RCLONE_CONFIG_OBJSTORE_REGION: ${{ secrets.S3_REGION }} - RCLONE_CONFIG_OBJSTORE_ACL: public-read + RCLONE_CONFIG_OBJSTORE_TYPE: ${{ secrets.AZUREBLOB_TYPE }} + RCLONE_CONFIG_OBJSTORE_ACCOUNT: ${{ secrets.AZUREBLOB_ACCOUNT }} + RCLONE_CONFIG_OBJSTORE_KEY: ${{ secrets.AZUREBLOB_KEY }} with: - args: sync objstore:syncthing-apt/dists dists + args: sync objstore:apt/dists dists - name: Update archive uses: docker://ghcr.io/kastelo/ezapt:latest @@ -871,15 +858,12 @@ jobs: - name: Push archive uses: docker://docker.io/rclone/rclone:latest env: - RCLONE_CONFIG_OBJSTORE_TYPE: s3 - RCLONE_CONFIG_OBJSTORE_PROVIDER: ${{ secrets.S3_PROVIDER }} - RCLONE_CONFIG_OBJSTORE_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} - RCLONE_CONFIG_OBJSTORE_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} - RCLONE_CONFIG_OBJSTORE_ENDPOINT: ${{ secrets.S3_ENDPOINT }} - RCLONE_CONFIG_OBJSTORE_REGION: ${{ secrets.S3_REGION }} - RCLONE_CONFIG_OBJSTORE_ACL: public-read + RCLONE_CONFIG_OBJSTORE_TYPE: ${{ secrets.AZUREBLOB_TYPE }} + RCLONE_CONFIG_OBJSTORE_ACCOUNT: ${{ secrets.AZUREBLOB_ACCOUNT }} + RCLONE_CONFIG_OBJSTORE_KEY: ${{ secrets.AZUREBLOB_KEY }} + RCLONE_AZUREBLOB_ACCESS_TIER: hot with: - args: sync dists -v objstore:syncthing-apt/dists + args: sync -v dists objstore:apt/dists # # Build and push to Docker Hub