support backing up data directory on windows with shut down #996

This commit is contained in:
woodser 2024-06-05 08:36:41 -04:00
parent f6c35ba6f3
commit e12ec197bf
2 changed files with 52 additions and 22 deletions

View File

@ -89,6 +89,8 @@ public class HavenoApp extends Application implements UncaughtExceptionHandler {
private static Consumer<Application> appLaunchedHandler; private static Consumer<Application> appLaunchedHandler;
@Getter @Getter
private static Runnable shutDownHandler; private static Runnable shutDownHandler;
@Setter
private static Runnable onGracefulShutDownHandler;
@Setter @Setter
private Injector injector; private Injector injector;
@ -145,6 +147,7 @@ public class HavenoApp extends Application implements UncaughtExceptionHandler {
new Thread(() -> { new Thread(() -> {
gracefulShutDownHandler.gracefulShutDown(() -> { gracefulShutDownHandler.gracefulShutDown(() -> {
log.info("App shutdown complete"); log.info("App shutdown complete");
if (onGracefulShutDownHandler != null) onGracefulShutDownHandler.run();
}); });
}).start(); }).start();
shutDownRequested = true; shutDownRequested = true;

View File

@ -18,6 +18,7 @@
package haveno.desktop.main.account.content.backup; package haveno.desktop.main.account.content.backup;
import com.google.inject.Inject; import com.google.inject.Inject;
import haveno.common.UserThread;
import haveno.common.config.Config; import haveno.common.config.Config;
import haveno.common.file.FileUtil; import haveno.common.file.FileUtil;
import haveno.common.persistence.PersistenceManager; import haveno.common.persistence.PersistenceManager;
@ -27,6 +28,7 @@ import haveno.core.api.XmrLocalNode;
import haveno.core.locale.Res; import haveno.core.locale.Res;
import haveno.core.user.Preferences; import haveno.core.user.Preferences;
import haveno.core.xmr.wallet.XmrWalletService; import haveno.core.xmr.wallet.XmrWalletService;
import haveno.desktop.app.HavenoApp;
import haveno.desktop.common.view.ActivatableView; import haveno.desktop.common.view.ActivatableView;
import haveno.desktop.common.view.FxmlView; import haveno.desktop.common.view.FxmlView;
import haveno.desktop.main.overlays.popups.Popup; import haveno.desktop.main.overlays.popups.Popup;
@ -40,6 +42,8 @@ import java.io.IOException;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.concurrent.TimeUnit;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
@ -125,33 +129,56 @@ public class BackupView extends ActivatableView<GridPane, Void> {
openFileOrShowWarning(openLogsButton, logFile); openFileOrShowWarning(openLogsButton, logFile);
backupNow.setOnAction(event -> { backupNow.setOnAction(event -> {
String backupDirectory = preferences.getBackupDirectory();
if (backupDirectory != null && backupDirectory.length() > 0) { // We need to flush data to disk
PersistenceManager.flushAllDataToDiskAtBackup(() -> {
try {
// copy data directory to backup directory // windows requires closing wallets for read access
String dateString = new SimpleDateFormat("yyyy-MM-dd-HHmmss").format(new Date()); if (Utilities.isWindows()) {
String destination = Paths.get(backupDirectory, "haveno_backup_" + dateString).toString(); new Popup().information(Res.get("settings.net.needRestart"))
File destinationFile = new File(destination); .actionButtonText(Res.get("shared.applyAndShutDown"))
FileUtil.copyDirectory(dataDir, new File(destination)); .onAction(() -> {
UserThread.runAfter(() -> {
// delete monerod and monero-wallet-rpc binaries from backup so they're reinstalled with permissions HavenoApp.setOnGracefulShutDownHandler(() -> doBackup());
File monerod = new File(destinationFile, XmrLocalNode.MONEROD_NAME); HavenoApp.getShutDownHandler().run();
if (monerod.exists()) monerod.delete(); }, 500, TimeUnit.MILLISECONDS);
File moneroWalletRpc = new File(destinationFile, XmrWalletService.MONERO_WALLET_RPC_NAME); })
if (moneroWalletRpc.exists()) moneroWalletRpc.delete(); .closeButtonText(Res.get("shared.cancel"))
new Popup().feedback(Res.get("account.backup.success", destination)).show(); .onClose(() -> {
} catch (IOException e) { // nothing to do
e.printStackTrace(); })
log.error(e.getMessage()); .show();
showWrongPathWarningAndReset(e); } else {
} doBackup();
});
} }
}); });
} }
private void doBackup() {
log.info("Backing up data directory");
String backupDirectory = preferences.getBackupDirectory();
if (backupDirectory != null && backupDirectory.length() > 0) { // We need to flush data to disk
PersistenceManager.flushAllDataToDiskAtBackup(() -> {
try {
// copy data directory to backup directory
String dateString = new SimpleDateFormat("yyyy-MM-dd-HHmmss").format(new Date());
String destination = Paths.get(backupDirectory, "haveno_backup_" + dateString).toString();
File destinationFile = new File(destination);
FileUtil.copyDirectory(dataDir, new File(destination));
// delete monerod and monero-wallet-rpc binaries from backup so they're reinstalled with permissions
File monerod = new File(destinationFile, XmrLocalNode.MONEROD_NAME);
if (monerod.exists()) monerod.delete();
File moneroWalletRpc = new File(destinationFile, XmrWalletService.MONERO_WALLET_RPC_NAME);
if (moneroWalletRpc.exists()) moneroWalletRpc.delete();
new Popup().feedback(Res.get("account.backup.success", destination)).show();
} catch (IOException e) {
e.printStackTrace();
log.error(e.getMessage());
showWrongPathWarningAndReset(e);
}
});
}
}
private void openFileOrShowWarning(Button button, File dataDir) { private void openFileOrShowWarning(Button button, File dataDir) {
button.setOnAction(event -> { button.setOnAction(event -> {
try { try {