replaced FUPFMS

with more generic set of used mount services
This commit is contained in:
Sebastian Stenzel
2023-12-21 09:40:43 +01:00
parent 55ba255651
commit a0fcb63a1a
4 changed files with 35 additions and 31 deletions

View File

@@ -14,7 +14,6 @@ import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.common.vaults.VaultComponent;
import org.cryptomator.common.vaults.VaultListModule;
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.integrations.mount.MountService;
import org.cryptomator.integrations.revealpath.RevealPathService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,7 +29,6 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
@Module(subcomponents = {VaultComponent.class}, includes = {VaultListModule.class, KeychainModule.class, MountModule.class})
public abstract class CommonsModule {
@@ -134,11 +132,4 @@ public abstract class CommonsModule {
LOG.error("Uncaught exception in " + thread.getName(), throwable);
}
@Provides
@Singleton
@Named("FUPFMS")
static AtomicReference<MountService> provideFirstUsedProblematicFuseMountService() {
return new AtomicReference<>(null);
}
}

View File

@@ -6,9 +6,12 @@ import org.cryptomator.common.ObservableUtil;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.integrations.mount.MountService;
import javax.inject.Named;
import javax.inject.Singleton;
import javafx.beans.value.ObservableValue;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Module
public class MountModule {
@@ -28,4 +31,12 @@ public class MountModule {
fallbackProvider);
}
@Provides
@Singleton
@Named("usedMountServices")
static Set<MountService> provideSetOfUsedMountServices() {
return ConcurrentHashMap.newKeySet();
}
}

View File

@@ -16,7 +16,8 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.Map;
import java.util.Set;
import static org.cryptomator.integrations.mount.MountCapability.MOUNT_AS_DRIVE_LETTER;
import static org.cryptomator.integrations.mount.MountCapability.MOUNT_TO_EXISTING_DIR;
@@ -27,12 +28,17 @@ import static org.cryptomator.integrations.mount.MountCapability.UNMOUNT_FORCED;
@Singleton
public class Mounter {
private static final List<String> CONFLICTING_MOUNT_SERVICES = List.of("org.cryptomator.frontend.fuse.mount.MacFuseMountProvider", "org.cryptomator.frontend.fuse.mount.FuseTMountProvider");
// mount providers (key) can not be used if any of the conflicting mount providers (values) are already in use
private static final Map<String, Set<String>> CONFLICTING_MOUNT_SERVICES = Map.of(
"org.cryptomator.frontend.fuse.mount.MacFuseMountProvider", Set.of("org.cryptomator.frontend.fuse.mount.FuseTMountProvider"),
"org.cryptomator.frontend.fuse.mount.FuseTMountProvider", Set.of("org.cryptomator.frontend.fuse.mount.MacFuseMountProvider")
);
private final Environment env;
private final Settings settings;
private final WindowsDriveLetters driveLetters;
private final List<MountService> mountProviders;
private final AtomicReference<MountService> firstUsedProblematicFuseMountService;
private final Set<MountService> usedMountServices;
private final ObservableValue<MountService> defaultMountService;
@Inject
@@ -40,13 +46,13 @@ public class Mounter {
Settings settings, //
WindowsDriveLetters driveLetters, //
List<MountService> mountProviders, //
@Named("FUPFMS") AtomicReference<MountService> firstUsedProblematicFuseMountService, //
@Named("usedMountServices") Set<MountService> usedMountServices, //
ObservableValue<MountService> defaultMountService) {
this.env = env;
this.settings = settings;
this.driveLetters = driveLetters;
this.mountProviders = mountProviders;
this.firstUsedProblematicFuseMountService = firstUsedProblematicFuseMountService;
this.usedMountServices = usedMountServices;
this.defaultMountService = defaultMountService;
}
@@ -149,23 +155,24 @@ public class Mounter {
}
public MountHandle mount(VaultSettings vaultSettings, Path cryptoFsRoot) throws IOException, MountFailedException {
var selMntServ = mountProviders.stream().filter(s -> s.getClass().getName().equals(vaultSettings.mountService.getValue())).findFirst().orElse(defaultMountService.getValue());
var mountService = mountProviders.stream().filter(s -> s.getClass().getName().equals(vaultSettings.mountService.getValue())).findFirst().orElse(defaultMountService.getValue());
var targetIsProblematicFuse = isProblematicFuseService(selMntServ);
if (targetIsProblematicFuse && firstUsedProblematicFuseMountService.get() == null) {
firstUsedProblematicFuseMountService.set(selMntServ);
} else if (targetIsProblematicFuse && !firstUsedProblematicFuseMountService.get().equals(selMntServ)) {
if (isConflictingMountService(mountService)) {
// TODO: neither message displayed in UI nor exception is specific to FUSE, so rename this class
throw new FuseRestartRequiredException("Failed to mount the specified mount service.");
}
var builder = selMntServ.forFileSystem(cryptoFsRoot);
var internal = new SettledMounter(selMntServ, builder, vaultSettings);
usedMountServices.add(mountService);
var builder = mountService.forFileSystem(cryptoFsRoot);
var internal = new SettledMounter(mountService, builder, vaultSettings); // FIXME: no need for an inner class
var cleanup = internal.prepare();
return new MountHandle(builder.mount(), selMntServ.hasCapability(UNMOUNT_FORCED), cleanup);
return new MountHandle(builder.mount(), mountService.hasCapability(UNMOUNT_FORCED), cleanup);
}
public static boolean isProblematicFuseService(MountService service) {
return CONFLICTING_MOUNT_SERVICES.contains(service.getClass().getName());
public boolean isConflictingMountService(MountService service) {
var conflictingServices = CONFLICTING_MOUNT_SERVICES.getOrDefault(service.getClass().getName(), Set.of());
return usedMountServices.stream().map(MountService::getClass).map(Class::getName).anyMatch(conflictingServices::contains);
}
public record MountHandle(Mount mountObj, boolean supportsUnmountForced, Runnable specialCleanup) {

View File

@@ -38,7 +38,6 @@ import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
@VaultOptionsScoped
public class MountOptionsController implements FxController {
@@ -87,7 +86,7 @@ public class MountOptionsController implements FxController {
FxApplicationWindows applicationWindows, //
Lazy<Application> application, //
List<MountService> mountProviders, //
@Named("FUPFMS") AtomicReference<MountService> firstUsedProblematicFuseMountService, //
Mounter mounter, //
ObservableValue<MountService> defaultMountService) {
this.window = window;
this.vaultSettings = vault.getVaultSettings();
@@ -99,11 +98,7 @@ public class MountOptionsController implements FxController {
this.mountProviders = mountProviders;
this.defaultMountService = defaultMountService;
this.selectedMountService = Bindings.createObjectBinding(this::reselectMountService, defaultMountService, vaultSettings.mountService);
this.fuseRestartRequired = selectedMountService.map(s -> {
return firstUsedProblematicFuseMountService.get() != null //
&& Mounter.isProblematicFuseService(s) //
&& !firstUsedProblematicFuseMountService.get().equals(s);
});
this.fuseRestartRequired = selectedMountService.map(mounter::isConflictingMountService);
this.defaultMountFlags = selectedMountService.map(s -> {
if (s.hasCapability(MountCapability.MOUNT_FLAGS)) {