Added safe restore

This commit is contained in:
Szum123321 2022-06-17 23:14:14 +02:00
parent b4597f6f1f
commit 3f1f1704b1
6 changed files with 58 additions and 48 deletions

View File

@ -85,12 +85,16 @@ public class TextileLogger {
log(Level.ERROR, msg, data);
}
void error(String message, Throwable throwable) {
logger.error(prefix + message, throwable);
}
public void fatal(String msg, Object... data) {
log(Level.FATAL, msg, data);
}
boolean sendFeedback(Level level, ServerCommandSource source, String msg, Object... args) {
if(source != null && source.getEntity() instanceof PlayerEntity) {
if(source != null && source.isExecutedByPlayer()) {
MutableText text = Text.literal(messageFactory.newMessage(msg, args).getFormattedMessage());
if(level.intLevel() == Level.TRACE.intLevel()) text.formatted(Formatting.GREEN);

View File

@ -32,18 +32,20 @@ import net.szum123321.textile_backup.config.ConfigPOJO;
import net.szum123321.textile_backup.Statics;
import net.szum123321.textile_backup.mixin.MinecraftServerSessionAccessor;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.file.SimplePathVisitor;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
public class Utilities {
private final static ConfigHelper config = ConfigHelper.INSTANCE;
@ -80,6 +82,22 @@ public class Utilities {
return path;
}
public static void deleteDirectory(Path path) throws IOException {
Files.walkFileTree(path, new SimplePathVisitor() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
public static void updateTMPFSFlag(MinecraftServer server) {
boolean flag = false;
Path tmp_dir = Path.of(System.getProperty("java.io.tmpdir"));

View File

@ -31,7 +31,7 @@ import net.szum123321.textile_backup.core.create.BackupHelper;
import net.szum123321.textile_backup.core.restore.decompressors.GenericTarDecompressor;
import net.szum123321.textile_backup.core.restore.decompressors.ZipDecompressor;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@ -51,54 +51,60 @@ public class RestoreBackupRunnable implements Runnable {
log.info("Shutting down server...");
ctx.getServer().stop(false);
ctx.server().stop(false);
awaitServerShutdown();
if(config.get().backupOldWorlds) {
BackupHelper.create(
BackupContext.Builder
.newBackupContextBuilder()
.setServer(ctx.getServer())
.setServer(ctx.server())
.setInitiator(ActionInitiator.Restore)
.setComment("Old_World" + (ctx.getComment() != null ? "_" + ctx.getComment() : ""))
.setComment("Old_World" + (ctx.comment() != null ? "_" + ctx.comment() : ""))
.build()
).run();
}
Path worldFile = Utilities.getWorldFolder(ctx.getServer()).toPath();
Path worldFile = Utilities.getWorldFolder(ctx.server());
log.info("Deleting old world...");
try {
Path tmp = Files.createTempDirectory (
worldFile.getParent(),
ctx.restoreableFile().getFile().getFileName().toString()
);
if(!deleteDirectory(worldFile))
log.error("Something went wrong while deleting old world!");
tmp.toFile().deleteOnExit();
Files.createDirectories(worldFile);
log.info("Starting decompression...");
log.info("Starting decompression...");
if (ctx.restoreableFile().getArchiveFormat() == ConfigPOJO.ArchiveFormat.ZIP)
ZipDecompressor.decompress(ctx.restoreableFile().getFile(), tmp);
else
GenericTarDecompressor.decompress(ctx.restoreableFile().getFile(), tmp);
if(ctx.getFile().getArchiveFormat() == ConfigPOJO.ArchiveFormat.ZIP)
ZipDecompressor.decompress(ctx.getFile().getFile().toPath(), worldFile);
else
GenericTarDecompressor.decompress(ctx.getFile().getFile().toPath(), worldFile);
log.info("Deleting old world...");
if(config.get().deleteOldBackupAfterRestore) {
log.info("Deleting old backup");
Utilities.deleteDirectory(worldFile);
if(!ctx.getFile().getFile().delete()) log.info("Something went wrong while deleting old backup");
Files.move(tmp, worldFile);
if (config.get().deleteOldBackupAfterRestore) {
log.info("Deleting old backup");
Files.delete(ctx.restoreableFile().getFile());
}
} catch (IOException e) {
log.error("An exception occurred while trying to restore a backup!", e);
}
//in case we're playing on client
Statics.globalShutdownBackupFlag.set(true);
log.info("Done!");
//Might solve #37
//Idk if it's a good idea...
//Runtime.getRuntime().exit(0);
}
private void awaitServerShutdown() {
while(((LivingServer)ctx.getServer()).isAlive()) {
while(((LivingServer)ctx.server()).isAlive()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
@ -106,15 +112,4 @@ public class RestoreBackupRunnable implements Runnable {
}
}
}
private static boolean deleteDirectory(File f) {
boolean state = true;
if(f.isDirectory()) {
for(File f2 : f.listFiles())
state &= deleteDirectory(f2);
}
return f.delete() && state;
}
}

View File

@ -98,9 +98,9 @@ public class RestoreHelper {
private RestoreableFile(Path file) throws NoSuchElementException {
this.file = file;
archiveFormat = Utilities.getArchiveExtension(file).orElseThrow(() -> new NoSuchElementException("Couldn't get restoreableFile extension!"));
archiveFormat = Utilities.getArchiveExtension(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file extension!"));
String extension = archiveFormat.getCompleteString();
creationTime = Utilities.getFileCreationTime(file).orElseThrow(() -> new NoSuchElementException("Couldn't get restoreableFile creation time!"));
creationTime = Utilities.getFileCreationTime(file).orElseThrow(() -> new NoSuchElementException("Couldn't get file creation time!"));
final String filename = file.getFileName().toString();

View File

@ -36,7 +36,7 @@ import java.time.Instant;
public class GenericTarDecompressor {
private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
public static void decompress(Path input, Path target) {
public static void decompress(Path input, Path target) throws IOException {
Instant start = Instant.now();
try (InputStream fileInputStream = Files.newInputStream(input);
@ -60,13 +60,11 @@ public class GenericTarDecompressor {
try (OutputStream outputStream = Files.newOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream)) {
IOUtils.copy(archiveInputStream, bufferedOutputStream);
} catch (IOException e) {
log.error("An exception occurred while trying to decompress file: {}", file.getFileName().toString(), e);
}
}
}
} catch (IOException | CompressorException e) {
log.error("An exception occurred! ", e);
} catch (CompressorException e) {
throw new IOException(e);
}
log.info("Decompression took {} seconds.", Utilities.formatDuration(Duration.between(start, Instant.now())));

View File

@ -35,7 +35,7 @@ import java.util.Iterator;
public class ZipDecompressor {
private final static TextileLogger log = new TextileLogger(TextileBackup.MOD_NAME);
public static void decompress(Path inputFile, Path target) {
public static void decompress(Path inputFile, Path target) throws IOException {
Instant start = Instant.now();
try(ZipFile zipFile = new ZipFile(inputFile.toFile())) {
@ -50,14 +50,9 @@ public class ZipDecompressor {
try (OutputStream outputStream = Files.newOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream)) {
IOUtils.copy(zipFile.getInputStream(entry), bufferedOutputStream);
} catch (IOException e) {
log.error("An exception occurred while trying to decompress file: {}", entry.getName(), e);
}
}
}
} catch (IOException e) {
log.error("An exception occurred! ", e);
}
log.info("Decompression took: {} seconds.", Utilities.formatDuration(Duration.between(start, Instant.now())));