Changelog
=========

Version 0.5.5 (2026-07-10)
--------------------------

Fixes:

- rest (stdio-over-ssh): recover from a lost ssh connection instead of hanging forever. The ssh
  command now uses keepalive (ServerAliveInterval/CountMax) so a dead peer is noticed, and on a
  broken connection the client transparently restarts the ssh + server process and retries the
  request (giving up with a BackendError if it can't be reestablished), #167
- rest (stdio-over-ssh): raise BackendConnectionError on unexpected EOF during response headers
  or response body transfer, preventing silent data truncation.
- defrag: check for short/long reads in range requests and raise ReadRangeError exception in
  case of a size mismatch, #194



Version 0.5.4 (2026-07-09)
--------------------------

Fixes:

- sftp: recover from a lost connection instead of hanging forever. Operations now use a
  socket timeout and, on a broken/dead connection, transparently reconnect and retry (and
  give up with a BackendError if the connection can't be reestablished), #167
- Spawn rclone and ssh ignoring SIGINT, so they don't get interrupted by Ctrl-C.


Version 0.5.3 (2026-06-30)
--------------------------

Fixes:

- caching: serve partial reads directly from the cache instead of always
  doing a full load from cache and slicing afterwards, #182


Version 0.5.2 (2026-06-26)
--------------------------

Fixes:

- REST client: fix info() size for nonexistent objects
- REST client: fix hang on HEAD requests
- REST server: allow HEAD requests for root directory
- REST client/server: add atime support
- nesting: fix root directory nesting

Other changes:

- require python 3.11+
- posixfs: use more efficient hashlib.file_digest (available since py311)
- docs: misc. updates (atime, rest, env vars)
- docs generation with sphinx: use importlib.metadata to derive version


Version 0.5.1 (2026-06-02)
--------------------------

New features:

- borgstore.server.rest: support REST http via stdio (so one can, for example,
  invoke borgstore-server-rest --stdio via ssh). Speaks http over stdin/stdout,
  stderr is used for log output.
- Store now supports "rest:" backend URLs:

  - rest://user@host:port/relative/path - creates an ssh connection to a
    remote system, starts a borgstore-server-rest process there with a posixfs
    backend at ./relative/path on the remote system.
  - rest:///relative/path - creates and connects to a borgstore-server-rest
    process with a posixfs backend at ./relative/path on the local system,
    without using ssh (good for testing).


Version 0.5.0 (2026-05-28)
--------------------------

New features:

- implement an optional cache (modes: off, mirror, writethrough; max_age and
  size LRU eviction need atime support), see the store_caching.rst docs
- rclone: add BORGSTORE_RCLONE_DEBUG env var

Other changes:

- Store: remove "levels" argument, replaced by new "config" argument
- Store: optimize / speed up .find method (no backend.info calls when there
  is only 1 level, as usual)
- docs: split README, real docs, sphinx


Version 0.4.1 (2026-04-26)
--------------------------

New features:

- quota: implement quota tracking and enforcement (posixfs), #19
- load: implement tail loading support (negative offset)
- store: hashsum content verification (REST server/client), #148
- hash: item content hashing, e.g. sha256
- defrag: defragmentation helper (copies blocks from source to target items)
- sftp: try to use "check-file" for SFTP server-side hashing (not supported
  by OpenSSH and also not tested by us; please give feedback if you use it)
- REST backend (client): support sub-paths, #155, #156
- REST server:

  - server-side implementation of defrag and hash
  - --socket-activation - add systemd socket activation support, enabling
    on-demand per-repo startup without port management.
  - contrib/server/nginx-systemd/ has a nginx reverse proxy setup
    example that can support multiple stores at different sub-paths.
  - support quotas (via posixfs backend)

Fixes:

- rclone: fix process leak in close()
- REST server:

  - sanitize error messages to avoid leaking absolute storage paths
  - harden authentication against timing attacks
  - slightly optimize directory listing memory usage
- sftp:

  - fix SSH connection leak
  - host_config["port"] is a str
  - Store paramiko.SSHClient in self.ssh and ensure it is closed in
    _disconnect, _connect calls _disconnect on any failure during setup.


Version 0.4.0 (2026-03-15)
--------------------------

New features:

- REST (http/https) backend, REST server, #18

Fixes:

- fix permissions check, #139
- posixfs/sftp: do not raise if base_path can not be deleted, #133
- list: do not yield invalid names, #130
- posixfs, s3, sftp: URL-unquote, #129

Other changes:

- add "rclone" and "rest" extras, "requests" is now an optional requirement


Version 0.3.1 (2026-02-09)
--------------------------

Bug fixes:

- s3 URL: ensure s3 endpoint is optional

Other changes:

- add support for Python 3.14, remove 3.9
- backends: have separate exceptions for invalid URL and dependency missing
- posixfs: better exception message if not absolute path
- use SPDX license identifier, require a recent setuptools
- CI:

  - add sftp store testing, #64
  - add s3 store testing
- docs:

  - describe the posixfs permissions system
  - updates, typos and grammar fixes
  - mention the permissions system of posixfs backend


Version 0.3.0 2025-05-22
------------------------

New features:

- posixfs: add a permissions system, #105
- Store: add permissions argument (only supported by posixfs)
- Store: add logging for Store ops, #104. It logs:

  - operation
  - name(s)
  - parameters such as deleted
  - size and timing

  Please note:

  - logging is done at DEBUG level, so log output is not visible with a default logger.
  - borgstore does not configure logging; that is the task of the application that uses borgstore.


Version 0.2.0 2025-04-21
------------------------

Breaking changes:

- Store.list: changed deleted argument semantics, #83:

  - True: list ONLY soft-deleted items
  - False: list ONLY non-deleted items

New features:

- new s3/b2 backend that uses the boto3 library, #96
- posixfs/sftp: create missing parent directories of the base path
- rclone: add a way to specify the path to the rclone binary for custom installations

Bug fixes:

- rclone: fix discard thread issues, #92
- rclone: check rclone regex before raising rclone-related exceptions

Other changes:

- posixfs: also support Windows file:/// URLs, #82
- posixfs / sftp: optimize mkdir usage, add retries, #85
- posixfs / sftp: change .precreate_dirs default to False
- rclone init: use a random port instead of relying on rclone to pick one


Version 0.1.0 2024-10-15
------------------------

Breaking changes:

- accepted store URLs: see README
- Store: require complete levels configuration, #46

Other changes:

- sftp/posixfs backends: remove ad hoc mkdir calls, #46
- optimize Sftp._mkdir, #80
- sftp backend is now optional, avoiding dependency issues on some platforms, #74.
  Use pip install "borgstore[sftp]" to install with the sftp backend.


Version 0.0.5 2024-10-01
------------------------

Fixes:

- backend.create: only reject non-empty storage, #57
- backends.sftp: fix _mkdir edge case
- backends.sftp: raise BackendDoesNotExist if base path is not found

- rclone backend:

  - don't error on create if source directory is empty, #57
  - fix hang on termination, #54

New features:

- rclone backend: retry errors on load and store 3 times

Other changes:

- remove MStore for now, see commit 6a6fb334.
- refactor Store tests, add Store.set_levels method
- move types-requests to tox.ini, only needed for development


Version 0.0.4 2024-09-22
------------------------

- rclone: new backend to access any of the 100s of cloud backends that rclone
  supports; needs rclone >= v1.57.0.

  See the rclone docs for installing rclone and creating remotes.
  After that, borgstore will support URLs like:

  - rclone://remote:
  - rclone://remote:path
  - rclone:///tmp/testdir (local fs, for testing)
- Store.list: give up trying to do anything with a directory's "size"
- .info / .list: return st.st_size for a directory "as-is"
- tests: BORGSTORE_TEST_RCLONE_URL to set rclone test URL
- tests: allow BORGSTORE_TEST_*_URL in the testenv to make tox work
  for testing sftp, rclone, or other URLs.


Version 0.0.3 2024-09-17
------------------------

- sftp: add support for ~/.ssh/config, #37
- sftp: username is optional, #27
- load known_hosts, remove AutoAddPolicy, #39
- store: raise backend-specific exceptions, #34
- add Store.stats property, #25
- bandwidth emulation via BORGSTORE_BANDWIDTH [bit/s], #24
- latency emulation via BORGSTORE_LATENCY [us], #24
- fix demo code, also output stats
- tests: BORGSTORE_TEST_SFTP_URL to set sftp test URL


Version 0.0.2 2024-09-10
------------------------

- sftp backend: use paramiko's client.posix_rename, #17
- posixfs backend: hack: accept file://relative/path, #23
- support and test on Python 3.13, #21


Version 0.0.1 2024-08-23
------------------------

First PyPI release.
