Skip to content

Commit b304d08

Browse files
committed
Fixes SSHFS folder being removed from project even when unmount failed
1 parent b473972 commit b304d08

File tree

4 files changed

+40
-13
lines changed

4 files changed

+40
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
### Fixed
1515

1616
- Unmount on macOS
17+
- Unmount failure leading to SSHFS folder being removed from project
1718
- Unmount race conditions related to SSHFS mount point still present in project opened folders
1819

1920
### Removed

sshubl/actions.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -349,18 +349,28 @@ def run(self):
349349
mount_path = mount_sshfs(
350350
self.identifier, typing.cast(PurePath, self.remote_path), self.mount_path
351351
)
352-
if mount_path is None:
353-
return
354-
add_to_project_folders(
355-
str(mount_path), f"{ssh_session}{self.remote_path}", self.view.window()
356-
)
352+
folder_was_in_project = False
353+
is_ok = mount_path is not None
357354
else:
358355
mount_path = typing.cast(Path, self.mount_path)
359-
remove_from_project_folders(str(mount_path), self.view.window())
360-
umount_sshfs(mount_path)
356+
folder_was_in_project = remove_from_project_folders(
357+
str(mount_path), self.view.window()
358+
)
359+
is_ok = umount_sshfs(mount_path)
361360
finally:
362361
self.view.erase_status("zz_mounting_sshfs")
363362

363+
# in case of mounting success, add folder to project
364+
# in case of unmounting failure, re-add folder to project (if it was present)
365+
if (self.do_mount and is_ok) or (not self.do_mount and not is_ok and folder_was_in_project):
366+
add_to_project_folders(
367+
str(mount_path), f"{ssh_session}{self.remote_path}", self.view.window()
368+
)
369+
370+
# don't update project data if action failed
371+
if not is_ok:
372+
return
373+
364374
# store/remove mount path in/from SSH session metadata
365375
with project_data_lock:
366376
if self.do_mount:

sshubl/project_data.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,12 @@ def add_to_project_folders(
8181
def remove_from_project_folders(
8282
old_folder: str,
8383
window: typing.Optional[sublime.Window] = None,
84-
) -> None:
85-
"""Mirror function of `add_folder_to_project` (see above)"""
84+
) -> bool:
85+
"""
86+
Mirror function of `add_folder_to_project` (see above).
87+
88+
:returns bool: `True` when project has been actually removed, `False` otherwise
89+
"""
8690
if window is None:
8791
window = sublime.active_window()
8892

@@ -94,6 +98,10 @@ def remove_from_project_folders(
9498
project_data["folders"] = filtered_folders
9599
window.set_project_data(project_data)
96100

101+
return True
102+
103+
return False
104+
97105

98106
@dataclasses.dataclass
99107
class SshSession: # pylint: disable=too-many-instance-attributes

sshubl/ssh_utils.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,12 +316,17 @@ def mount_sshfs(
316316
return mount_path
317317

318318

319-
def umount_sshfs(mount_path: Path) -> None:
319+
def umount_sshfs(mount_path: Path) -> bool:
320+
"""
321+
Unmount `mount_path`, considering it has been mounted using sshfs.
322+
323+
:returns bool: `True` on success and `False` on error
324+
"""
320325
if umount_program is None:
321326
_logger.warning(
322327
"%s has not been found, skipping unmounting of %s...", umount_program, mount_path
323328
)
324-
return
329+
return False
325330

326331
_logger.debug("unmounting %s...", mount_path)
327332

@@ -335,12 +340,15 @@ def umount_sshfs(mount_path: Path) -> None:
335340
_logger.warning(
336341
"could not unmount %s : %s", mount_path, (error.stderr or "Unknown error").rstrip()
337342
)
338-
else:
339-
_logger.debug("successfully unmounted %s, removing mount point...", mount_path)
343+
return False
344+
345+
_logger.debug("successfully unmounted %s, removing mount point...", mount_path)
340346

341347
with contextlib.suppress(FileNotFoundError):
342348
mount_path.rmdir()
343349

350+
return True
351+
344352

345353
def _remove_unix_domain_socket(
346354
identifier: uuid.UUID, socket_path: str, *, is_reverse: bool

0 commit comments

Comments
 (0)