mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-18 02:31:27 +00:00
Delete automatically generated mount point after locking, attempt to fix #773
This commit is contained in:
@@ -1,14 +1,5 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryNotEmptyException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystem;
|
||||
@@ -20,65 +11,84 @@ import org.cryptomator.frontend.fuse.mount.Mount;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryNotEmptyException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NotDirectoryException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class FuseVolume implements Volume {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FuseVolume.class);
|
||||
|
||||
/**
|
||||
* TODO: dont use fixed Strings and rather set them in some system environment variables in the cryptomator installer and load those!
|
||||
*/
|
||||
// TODO: dont use fixed Strings and rather set them in some system environment variables in the cryptomator installer and load those!
|
||||
private static final String DEFAULT_MOUNTROOTPATH_MAC = System.getProperty("user.home") + "/Library/Application Support/Cryptomator";
|
||||
private static final String DEFAULT_MOUNTROOTPATH_LINUX = System.getProperty("user.home") + "/.Cryptomator";
|
||||
private static final int MAX_TMPMOUNTPOINT_CREATION_RETRIES = 10;
|
||||
|
||||
private final VaultSettings vaultSettings;
|
||||
|
||||
private Mount fuseMnt;
|
||||
private Path mountPath;
|
||||
private boolean extraDirCreated;
|
||||
private Path mountPoint;
|
||||
private boolean createdTemporaryMountPoint;
|
||||
|
||||
@Inject
|
||||
public FuseVolume(VaultSettings vaultSettings) {
|
||||
this.vaultSettings = vaultSettings;
|
||||
this.extraDirCreated = false;
|
||||
this.createdTemporaryMountPoint = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mount(CryptoFileSystem fs) throws IOException, FuseNotSupportedException, VolumeException {
|
||||
String mountPath;
|
||||
if (vaultSettings.usesIndividualMountPath().get()) {
|
||||
//specific path given
|
||||
mountPath = vaultSettings.individualMountPath().get();
|
||||
Path customMountPoint = Paths.get(vaultSettings.individualMountPath().get());
|
||||
checkProvidedMountPoint(customMountPoint);
|
||||
this.mountPoint = customMountPoint;
|
||||
LOG.debug("Successfully checked custom mount point: {}", mountPoint);
|
||||
} else {
|
||||
//choose default path & create extra directory
|
||||
mountPath = createDirIfNotExist(SystemUtils.IS_OS_MAC ? DEFAULT_MOUNTROOTPATH_MAC : DEFAULT_MOUNTROOTPATH_LINUX, vaultSettings.mountName().get());
|
||||
extraDirCreated = true;
|
||||
this.mountPoint = createTemporaryMountPoint();
|
||||
createdTemporaryMountPoint = true;
|
||||
LOG.debug("Successfully created mount point: {}", mountPoint);
|
||||
}
|
||||
this.mountPath = Paths.get(mountPath).toAbsolutePath();
|
||||
mount(fs.getPath("/"));
|
||||
}
|
||||
|
||||
private String createDirIfNotExist(String prefix, String dirName) throws IOException {
|
||||
Path p = Paths.get(prefix, dirName + vaultSettings.getId());
|
||||
if (Files.isDirectory(p)) {
|
||||
try (DirectoryStream<Path> emptyCheck = Files.newDirectoryStream(p)) {
|
||||
if (emptyCheck.iterator().hasNext()) {
|
||||
throw new DirectoryNotEmptyException("Mount point is not empty.");
|
||||
} else {
|
||||
LOG.info("Directory already exists and is empty. Using it as mount point.");
|
||||
return p.toString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Files.createDirectory(p);
|
||||
return p.toString();
|
||||
private void checkProvidedMountPoint(Path mountPoint) throws IOException {
|
||||
if (!Files.isDirectory(mountPoint)) {
|
||||
throw new NotDirectoryException(mountPoint.toString());
|
||||
}
|
||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(mountPoint)) {
|
||||
if (ds.iterator().hasNext()) {
|
||||
throw new DirectoryNotEmptyException(mountPoint.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Path createTemporaryMountPoint() throws IOException {
|
||||
Path parent = Paths.get(SystemUtils.IS_OS_MAC ? DEFAULT_MOUNTROOTPATH_MAC : DEFAULT_MOUNTROOTPATH_LINUX);
|
||||
String basename = vaultSettings.getId();
|
||||
for (int i = 0; i < MAX_TMPMOUNTPOINT_CREATION_RETRIES; i++) {
|
||||
try {
|
||||
Path mountPath = parent.resolve(basename + "_" + i);
|
||||
Files.createDirectory(mountPath);
|
||||
return mountPath;
|
||||
} catch (FileAlreadyExistsException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
LOG.error("Failed to create mount path at {}/{}_x. Giving up after {} attempts.", parent, basename, MAX_TMPMOUNTPOINT_CREATION_RETRIES);
|
||||
throw new FileAlreadyExistsException(parent.toString() + "/" + basename);
|
||||
}
|
||||
|
||||
private void mount(Path root) throws VolumeException {
|
||||
try {
|
||||
EnvironmentVariables envVars = EnvironmentVariables.create()
|
||||
.withMountName(vaultSettings.mountName().getValue())
|
||||
.withMountPath(mountPath)
|
||||
EnvironmentVariables envVars = EnvironmentVariables.create() //
|
||||
.withMountName(vaultSettings.mountName().getValue()) //
|
||||
.withMountPath(mountPoint) //
|
||||
.build();
|
||||
this.fuseMnt = FuseMountFactory.getMounter().mount(root, envVars);
|
||||
} catch (CommandFailedException e) {
|
||||
@@ -91,7 +101,7 @@ public class FuseVolume implements Volume {
|
||||
try {
|
||||
fuseMnt.revealInFileManager();
|
||||
} catch (CommandFailedException e) {
|
||||
LOG.info("Revealing the vault in file manger failed: " + e.getMessage());
|
||||
LOG.debug("Revealing the vault in file manger failed: " + e.getMessage());
|
||||
throw new VolumeException(e);
|
||||
}
|
||||
}
|
||||
@@ -103,15 +113,16 @@ public class FuseVolume implements Volume {
|
||||
} catch (CommandFailedException e) {
|
||||
throw new VolumeException(e);
|
||||
}
|
||||
cleanup();
|
||||
deleteTemporaryMountPoint();
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
if (extraDirCreated) {
|
||||
private void deleteTemporaryMountPoint() {
|
||||
if (createdTemporaryMountPoint) {
|
||||
try {
|
||||
Files.delete(mountPath);
|
||||
Files.delete(mountPoint);
|
||||
LOG.debug("Successfully deleted mount point: {}", mountPoint);
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Could not delete mounting directory:" + e.getMessage());
|
||||
LOG.warn("Could not delete mount point: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user