summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Borg <jakob@kastelo.net>2024-05-24 08:51:02 +0200
committerGitHub <noreply@github.com>2024-05-24 08:51:02 +0200
commita2b8f2361ec0ccc07f46a19ed6dcc338cc96bf9a (patch)
tree5c8bff07d5e244b49f8245b7e6d939024591dcc7
parent4b60e86d0247fcca5c2117f4a1ed8eb1f9ff5d94 (diff)
lib/config: Add file inside folder marker directory (#9525)
### Purpose Avoid the issue where the folder marker is deleted by overzealous cleanup tools because it's just a useless, empty directory. We create a small file containing a an admonishment to not delete the directory, and some metadata that is just for human consumption at the moment. (But it would parse as a valid yaml file if we wanted to read this, at some point.) This will only apply when _creating_ a folder marker, that is, existing setups will not gain the file automatically. Obviously, when using a custom folder marker none of this applies. Also, slightly adjust the permission bits for the folder marker directory and file on Unixes, making sure the group & write bits are unset. ### Testing I've created and deleted a few folders and it appears to behave as I expect. ### Screenshots ``` jb@ok:~/somefolder % ls -la total 0 drwxr-xr-x 3 jb staff 96 May 1 08:52 ./ drwx------ 12 jb staff 384 May 1 08:52 ../ drwxr-xr-x 3 jb staff 96 May 1 08:52 .stfolder/ jb@ok:~/somefolder % ls -l .stfolder total 8 -rw-r--r-- 1 jb staff 122 May 1 08:52 syncthing-folder-39a4b0.txt jb@ok:~/somefolder % cat .stfolder/syncthing-folder-39a4b0.txt # This directory is a Syncthing folder marker. # Do not delete. folderID: xtdca-cudyf created: 2024-05-01T08:52:49+02:00 ```
-rw-r--r--lib/config/folderconfiguration.go46
-rw-r--r--lib/model/model.go4
2 files changed, 38 insertions, 12 deletions
diff --git a/lib/config/folderconfiguration.go b/lib/config/folderconfiguration.go
index 3079c0f4cf..8765fc4e4e 100644
--- a/lib/config/folderconfiguration.go
+++ b/lib/config/folderconfiguration.go
@@ -7,6 +7,8 @@
package config
import (
+ "bytes"
+ "crypto/sha256"
"errors"
"fmt"
"path"
@@ -90,27 +92,51 @@ func (f *FolderConfiguration) CreateMarker() error {
return nil
}
- permBits := fs.FileMode(0o777)
- if build.IsWindows {
- // Windows has no umask so we must chose a safer set of bits to
- // begin with.
- permBits = 0o700
- }
- fs := f.Filesystem(nil)
- err := fs.Mkdir(DefaultMarkerName, permBits)
+ ffs := f.Filesystem(nil)
+
+ // Create the marker as a directory
+ err := ffs.Mkdir(DefaultMarkerName, 0o755)
if err != nil {
return err
}
- if dir, err := fs.Open("."); err != nil {
+
+ // Create a file inside it, reducing the risk of the marker directory
+ // being removed by automated cleanup tools.
+ markerFile := filepath.Join(DefaultMarkerName, f.markerFilename())
+ if err := fs.WriteFile(ffs, markerFile, f.markerContents(), 0o644); err != nil {
+ return err
+ }
+
+ // Sync & hide the containing directory
+ if dir, err := ffs.Open("."); err != nil {
l.Debugln("folder marker: open . failed:", err)
} else if err := dir.Sync(); err != nil {
l.Debugln("folder marker: fsync . failed:", err)
}
- fs.Hide(DefaultMarkerName)
+ ffs.Hide(DefaultMarkerName)
return nil
}
+func (f *FolderConfiguration) RemoveMarker() error {
+ ffs := f.Filesystem(nil)
+ _ = ffs.Remove(filepath.Join(DefaultMarkerName, f.markerFilename()))
+ return ffs.Remove(DefaultMarkerName)
+}
+
+func (f *FolderConfiguration) markerFilename() string {
+ h := sha256.Sum256([]byte(f.ID))
+ return fmt.Sprintf("syncthing-folder-%x.txt", h[:3])
+}
+
+func (f *FolderConfiguration) markerContents() []byte {
+ var buf bytes.Buffer
+ buf.WriteString("# This directory is a Syncthing folder marker.\n# Do not delete.\n\n")
+ fmt.Fprintf(&buf, "folderID: %s\n", f.ID)
+ fmt.Fprintf(&buf, "created: %s\n", time.Now().Format(time.RFC3339))
+ return buf.Bytes()
+}
+
// CheckPath returns nil if the folder root exists and contains the marker file
func (f *FolderConfiguration) CheckPath() error {
return f.checkFilesystemPath(f.Filesystem(nil), ".")
diff --git a/lib/model/model.go b/lib/model/model.go
index 487dff7dca..f88118eb9c 100644
--- a/lib/model/model.go
+++ b/lib/model/model.go
@@ -464,9 +464,9 @@ func (m *model) removeFolder(cfg config.FolderConfiguration) {
if isPathUnique {
// Remove (if empty and removable) or move away (if non-empty or
// otherwise not removable) Syncthing-specific marker files.
- fs := cfg.Filesystem(nil)
- if err := fs.Remove(config.DefaultMarkerName); err != nil {
+ if err := cfg.RemoveMarker(); err != nil && !errors.Is(err, os.ErrNotExist) {
moved := config.DefaultMarkerName + time.Now().Format(".removed-20060102-150405")
+ fs := cfg.Filesystem(nil)
_ = fs.Rename(config.DefaultMarkerName, moved)
}
}