fuse4dbricks 0.7.0__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/CHANGELOG.md +8 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/PKG-INFO +12 -1
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/README.md +11 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/main.py +23 -1
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/pyproject.toml +1 -1
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/uv.lock +1 -1
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/.env.example +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/.github/workflows/test.yml +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/.gitignore +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/__init__.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/api/__init__.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/api/errors.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/api/uc_client.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/auth/__init__.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/auth/provider.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/__init__.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/auth_manager.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/data_manager.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/inode_manager.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/metadata_manager.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/operations.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/ram_cache.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/securable_filter.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/utils.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/fs/write_buffer.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/storage/__init__.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/fuse4dbricks/storage/persistence.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_auth_manager.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_auth_provider.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_data_manager.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_e2e_mount.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_inode_manager.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_main.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_metadata_manager.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_operations.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_persistence.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_securable_filter.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_uc_client.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_uc_client_consistency.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_uc_client_live.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_utils.py +0 -0
- {fuse4dbricks-0.7.0 → fuse4dbricks-0.7.1}/tests/test_write_buffer.py +0 -0
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# 0.7.1 (2026-06-17)
|
|
2
|
+
|
|
3
|
+
- Unmount cleanly on `SIGTERM`/`SIGHUP` (e.g. `systemctl stop`). trio only turns
|
|
4
|
+
`SIGINT` (Ctrl-C) into a clean shutdown; other termination signals killed the
|
|
5
|
+
process before `pyfuse3.close()` ran, leaving the kernel with a stale mount
|
|
6
|
+
that showed up as `d?????????` in `ls`/`df`. All termination signals now run
|
|
7
|
+
the same orderly unwind that unmounts the filesystem.
|
|
8
|
+
|
|
1
9
|
# 0.7.0 (2026-06-17)
|
|
2
10
|
|
|
3
11
|
- Fix files written from a Windows application through WSL being uploaded at
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fuse4dbricks
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: FUSE driver for Databricks Unity Catalog Volumes.
|
|
5
5
|
Project-URL: Homepage, https://github.com/zeehio/fuse4dbricks
|
|
6
6
|
Author-email: Sergio Oller <sergioller@gmail.com>
|
|
@@ -261,6 +261,13 @@ user has to provide its own access token.
|
|
|
261
261
|
User=root
|
|
262
262
|
WorkingDirectory=/opt/fuse4dbricks
|
|
263
263
|
ExecStart=/opt/fuse4dbricks/fuse4dbricks_start.sh
|
|
264
|
+
# On stop, fuse4dbricks catches SIGTERM and unmounts itself. Give it time
|
|
265
|
+
# to finish before systemd escalates to SIGKILL (which cannot be caught
|
|
266
|
+
# and would leave a stale mount).
|
|
267
|
+
TimeoutStopSec=30
|
|
268
|
+
# Belt-and-suspenders: if the process was hard-killed and left a stale
|
|
269
|
+
# mount, force-unmount it. '-' ignores failure when nothing is mounted.
|
|
270
|
+
ExecStopPost=-/bin/fusermount3 -uz /Volumes
|
|
264
271
|
Restart=on-failure
|
|
265
272
|
RestartSec=5
|
|
266
273
|
|
|
@@ -268,6 +275,10 @@ user has to provide its own access token.
|
|
|
268
275
|
WantedBy=multi-user.target
|
|
269
276
|
EOF
|
|
270
277
|
|
|
278
|
+
If your mountpoint is not `/Volumes`, update it in `ExecStopPost` to match.
|
|
279
|
+
On systems that ship FUSE 2 rather than FUSE 3, use the absolute path to
|
|
280
|
+
`fusermount` (e.g. `/usr/bin/fusermount`) instead of `fusermount3`.
|
|
281
|
+
|
|
271
282
|
|
|
272
283
|
- Reload the daemon lists
|
|
273
284
|
|
|
@@ -238,6 +238,13 @@ user has to provide its own access token.
|
|
|
238
238
|
User=root
|
|
239
239
|
WorkingDirectory=/opt/fuse4dbricks
|
|
240
240
|
ExecStart=/opt/fuse4dbricks/fuse4dbricks_start.sh
|
|
241
|
+
# On stop, fuse4dbricks catches SIGTERM and unmounts itself. Give it time
|
|
242
|
+
# to finish before systemd escalates to SIGKILL (which cannot be caught
|
|
243
|
+
# and would leave a stale mount).
|
|
244
|
+
TimeoutStopSec=30
|
|
245
|
+
# Belt-and-suspenders: if the process was hard-killed and left a stale
|
|
246
|
+
# mount, force-unmount it. '-' ignores failure when nothing is mounted.
|
|
247
|
+
ExecStopPost=-/bin/fusermount3 -uz /Volumes
|
|
241
248
|
Restart=on-failure
|
|
242
249
|
RestartSec=5
|
|
243
250
|
|
|
@@ -245,6 +252,10 @@ user has to provide its own access token.
|
|
|
245
252
|
WantedBy=multi-user.target
|
|
246
253
|
EOF
|
|
247
254
|
|
|
255
|
+
If your mountpoint is not `/Volumes`, update it in `ExecStopPost` to match.
|
|
256
|
+
On systems that ship FUSE 2 rather than FUSE 3, use the absolute path to
|
|
257
|
+
`fusermount` (e.g. `/usr/bin/fusermount`) instead of `fusermount3`.
|
|
258
|
+
|
|
248
259
|
|
|
249
260
|
- Reload the daemon lists
|
|
250
261
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import argparse
|
|
3
3
|
import logging
|
|
4
4
|
import os
|
|
5
|
+
import signal
|
|
5
6
|
import traceback
|
|
6
7
|
import sys
|
|
7
8
|
|
|
@@ -145,6 +146,26 @@ def setup_logging(debug_mode):
|
|
|
145
146
|
logging.getLogger("pyfuse3").setLevel(logging.INFO)
|
|
146
147
|
|
|
147
148
|
|
|
149
|
+
async def _shutdown_on_signal(cancel_scope: trio.CancelScope):
|
|
150
|
+
"""Translate termination signals into a clean trio shutdown.
|
|
151
|
+
|
|
152
|
+
Without this, trio only converts SIGINT (Ctrl-C) into a KeyboardInterrupt;
|
|
153
|
+
SIGTERM (e.g. ``systemctl stop``) and SIGHUP kill the process outright, so
|
|
154
|
+
``start_fuse``'s ``finally`` never runs and ``pyfuse3.close()`` never gets
|
|
155
|
+
a chance to unmount. The kernel is then left with a stale mount that shows
|
|
156
|
+
up as ``d?????????`` in ``ls``/``df``. Cancelling the nursery here makes
|
|
157
|
+
every signal follow the same orderly unwind that unmounts the filesystem.
|
|
158
|
+
"""
|
|
159
|
+
with trio.open_signal_receiver(signal.SIGTERM, signal.SIGINT, signal.SIGHUP) as signals:
|
|
160
|
+
async for signum in signals:
|
|
161
|
+
logging.info(
|
|
162
|
+
"Received %s, unmounting and shutting down...",
|
|
163
|
+
signal.Signals(signum).name,
|
|
164
|
+
)
|
|
165
|
+
cancel_scope.cancel()
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
|
|
148
169
|
async def start_fuse(ops, mountpoint, allow_other, debug_mode, stopped_evt: trio.Event | None = None):
|
|
149
170
|
mount_options = ["fsname=fuse4dbricks", "noatime"]
|
|
150
171
|
if allow_other:
|
|
@@ -165,7 +186,7 @@ async def start_fuse(ops, mountpoint, allow_other, debug_mode, stopped_evt: trio
|
|
|
165
186
|
pass
|
|
166
187
|
finally:
|
|
167
188
|
try:
|
|
168
|
-
pyfuse3.close()
|
|
189
|
+
pyfuse3.close(unmount=True)
|
|
169
190
|
finally:
|
|
170
191
|
if stopped_evt is not None:
|
|
171
192
|
stopped_evt.set()
|
|
@@ -251,6 +272,7 @@ async def async_main():
|
|
|
251
272
|
async with trio.open_nursery() as nursery:
|
|
252
273
|
persistence.run_services(nursery)
|
|
253
274
|
data_manager.run_services(nursery)
|
|
275
|
+
nursery.start_soon(_shutdown_on_signal, nursery.cancel_scope)
|
|
254
276
|
nursery.start_soon(start_fuse, operations, mountpoint, args.allow_other, args.debug, stopped_evt)
|
|
255
277
|
|
|
256
278
|
await stopped_evt.wait()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|