Never touch CloudSync tasks; restore the logger the async cleanup path dropped
create_snapshot is module-global in plugins/cloud/snapshot.py, and cloud_sync.py imports it as well as cloud_backup/sync.py. So the wrapper sat in the path of every rclone/Storj CloudSync task with snapshot=true, and ran a zfs.dataset.query before concluding it had nothing to do -- a new failure mode for jobs that worked before this patch existed. Worse: a CloudSync task that ever got staged would never be torn down. The teardown is wired into cloud_backup's restic_backup finally, and CRUD_BLOCK deliberately leaves CloudSync's guard intact, so the bind mounts would pin the snapshot forever. The staging path now bails out unless the snapshot is named cloud_backup-*, before any middleware call. Separately: the async wrapper's finally dropped logger=, which the sync one passes. run_in_thread forwards **kwargs, so a cleanup that failed to unmount a bind mount or delete a snapshot tree logged nothing at all -- on the only platform anyone runs.
This commit is contained in:
@@ -526,6 +526,28 @@ if _tc_nested is not None:
|
||||
|
||||
def _tc_stage(middleware, path, name, snapshot, snap_path):
|
||||
# Synchronous, and always called from a worker thread (see above).
|
||||
#
|
||||
# ONLY cloud_backup. Bail out before touching anything otherwise.
|
||||
#
|
||||
# create_snapshot is module-global in plugins/cloud/snapshot.py and is
|
||||
# imported by cloud_sync.py as well as cloud_backup/sync.py -- so this
|
||||
# wrapper sits in the path of every rclone/Storj CloudSync task with
|
||||
# snapshot=true, not just ours. Two consequences, and the second is worse:
|
||||
#
|
||||
# * everything below is a NEW failure mode for tasks that worked before we
|
||||
# were installed. A `zfs.dataset.query` that errors would break a
|
||||
# CloudSync job we have no business touching.
|
||||
# * if a CloudSync task ever were staged, nothing would ever tear it down:
|
||||
# the teardown is wired into cloud_backup's restic_backup finally, and
|
||||
# CRUD_BLOCK deliberately leaves CloudSync's nesting guard intact. The
|
||||
# bind mounts would pin the snapshot forever.
|
||||
#
|
||||
# cloud_backup names its snapshot "cloud_backup-<id>"; cloud_sync names it
|
||||
# "cloud_sync-<id>"; the stock default is "cloud_task-onetime". Anything that
|
||||
# is not ours gets stock behaviour, untouched, with no extra middleware call.
|
||||
if not name.startswith("cloud_backup"):
|
||||
return snapshot, snap_path
|
||||
|
||||
_logger = getattr(middleware, "logger", None)
|
||||
try:
|
||||
# Enumerate datasets AFTER the snapshot, never before. The snapshot is
|
||||
|
||||
Reference in New Issue
Block a user