package client import ( "errors" "fmt" "os" "path/filepath" ) // lockFile marks a mirror directory as being synchronized by one agent. Two // agents on one directory would each think the other's writes were local // saves and push them back, so the tray, `keeporg run` and a service unit // started side by side must not all sync. const lockFile = ".keeporg.lock" // ErrMirrorBusy means another agent already holds the mirror directory. var ErrMirrorBusy = errors.New("another keeporg agent is already synchronizing this directory") // LockDir takes the mirror directory's lock for this process. The operating // system releases it when the process exits, however it exits, so a crash // never leaves a directory locked. func LockDir(dir string) (unlock func(), err error) { if err := os.MkdirAll(dir, 0o700); err != nil { return nil, err } path := filepath.Join(dir, lockFile) unlock, err = lockPath(path) if errors.Is(err, ErrMirrorBusy) { return nil, fmt.Errorf("%s: %w", dir, err) } return unlock, err }