Backup manager update : improved code handling file filtering + refactored PaperBackupManager + new Bungee backup manager

This commit is contained in:
Marc Baloup 2022-12-20 01:06:40 +01:00
parent 52467dc556
commit a7aa012fa4
Signed by: marcbal
GPG Key ID: BBC0FE3ABC30B893
10 changed files with 200 additions and 64 deletions

View File

@ -27,6 +27,12 @@
<version>${bungeecord.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>fr.pandacube.lib</groupId>
<artifactId>pandalib-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,16 @@
package fr.pandacube.lib.bungee.backup;
import fr.pandacube.lib.core.backup.BackupCleaner;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class BungeeBackupConfig {
public boolean workdirBackupEnabled = true;
public boolean logsBackupEnabled = true;
public String scheduling = "0 2 * * *"; // cron format, here is everyday at 2am
public File backupDirectory = null;
public BackupCleaner workdirBackupCleaner = BackupCleaner.KEEPING_1_EVERY_N_MONTH(3).merge(BackupCleaner.KEEPING_N_LAST(5));
public List<String> workdirIgnoreList = new ArrayList<>();
}

View File

@ -0,0 +1,46 @@
package fr.pandacube.lib.bungee.backup;
import fr.pandacube.lib.core.backup.BackupManager;
import fr.pandacube.lib.core.backup.BackupProcess;
import fr.pandacube.lib.core.backup.RotatedLogsBackupProcess;
import java.io.File;
public class BungeeBackupManager extends BackupManager {
BungeeBackupConfig config;
public BungeeBackupManager(BungeeBackupConfig config) {
super(config.backupDirectory);
setConfig(config);
addProcess(new BungeeWorkdirProcess(this));
addProcess(new RotatedLogsBackupProcess(this, false, new File("logs"), "[0-9]{4}-[0-9]{2}-[0-9]{2}(-[0-9]+)?\\.log\\.gz"));
}
@Override
protected void addProcess(BackupProcess process) {
updateProcessConfig(process);
super.addProcess(process);
}
public void setConfig(BungeeBackupConfig config) {
this.config = config;
backupQueue.forEach(this::updateProcessConfig);
}
public void updateProcessConfig(BackupProcess process) {
if (process instanceof BungeeWorkdirProcess) {
process.setEnabled(config.workdirBackupEnabled);
process.setBackupCleaner(config.workdirBackupCleaner);
process.setScheduling(config.scheduling);
process.setIgnoreList(config.workdirIgnoreList);
}
else if (process instanceof RotatedLogsBackupProcess) {
process.setEnabled(config.logsBackupEnabled);
}
}
}

View File

@ -0,0 +1,69 @@
package fr.pandacube.lib.bungee.backup;
import fr.pandacube.lib.core.backup.BackupProcess;
import fr.pandacube.lib.util.Log;
import net.md_5.bungee.api.ChatColor;
import java.io.File;
import java.text.DateFormat;
import java.util.Date;
import java.util.function.BiPredicate;
public class BungeeWorkdirProcess extends BackupProcess {
protected BungeeWorkdirProcess(BungeeBackupManager bm) {
super(bm, "workdir");
}
@Override
public BungeeBackupManager getBackupManager() {
return (BungeeBackupManager) super.getBackupManager();
}
public BiPredicate<File, String> getFilenameFilter() {
return new BiPredicate<File, String>() {
@Override
public boolean test(File file, String path) {
if (new File(getSourceDir(), "logs").equals(file))
return false;
if (file.isFile() && file.getName().endsWith(".lck"))
return false;
return BungeeWorkdirProcess.super.getFilenameFilter().test(file, path);
}
};
}
@Override
public File getSourceDir() {
return new File(".");
}
@Override
protected void onBackupStart() { }
@Override
protected void onBackupEnd(boolean success) {
if (success)
setDirtySinceNow();
}
@Override
protected File getTargetDir() {
return new File(getBackupManager().getBackupDirectory(), "workdir");
}
@Override
protected String getDisplayName() {
return "workdir";
}
public void displayNextSchedule() {
Log.info("[Backup] " + ChatColor.GRAY + getDisplayName() + ChatColor.RESET + " next backup on "
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(new Date(getNext())));
}
}

View File

@ -59,7 +59,22 @@ public abstract class BackupProcess implements Comparable<BackupProcess>, Runnab
public abstract BiPredicate<File, String> getFilenameFilter();
public BiPredicate<File, String> getFilenameFilter() {
return (file, path) -> {
for (String exclude : ignoreList) {
if (exclude.startsWith("/")) { // relative to source of workdir
if (path.matches(exclude.substring(1)))
return false;
}
else {
String name = path.substring(path.lastIndexOf("/") + 1);
if (name.matches(exclude))
return false;
}
}
return true;
};
}
public abstract File getSourceDir();
@ -98,6 +113,13 @@ public abstract class BackupProcess implements Comparable<BackupProcess>, Runnab
this.backupCleaner = backupCleaner;
}
public List<String> getIgnoreList() {
return ignoreList;
}
public void setIgnoreList(List<String> ignoreList) {
this.ignoreList = ignoreList;
}

View File

@ -27,7 +27,7 @@ public class RotatedLogsBackupProcess extends BackupProcess {
@Override
public void run() {
// do not call super. We override the zip archive process, we just want to copy log files, here
// do not call super. We override the zip archive process, we just want to copy already-zipped log files.
if (inNewThread) {
new Thread(this::actuallyRun, "Backup Thread " + identifier).start();
}
@ -40,6 +40,9 @@ public class RotatedLogsBackupProcess extends BackupProcess {
private void actuallyRun() {
if (!getSourceDir().isDirectory())
return;
Log.info("[Backup] Starting for " + ChatColor.GRAY + getDisplayName() + ChatColor.RESET + " ...");
try {

View File

@ -6,7 +6,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class BackupConfig {
public class PaperBackupConfig {
public boolean worldBackupEnabled = true;
public boolean workdirBackupEnabled = true;
public boolean logsBackupEnabled = true;

View File

@ -26,41 +26,48 @@ public class PaperBackupManager extends BackupManager implements Listener {
private final Map<String, PaperWorldProcess> compressWorlds = new HashMap<>();
BackupConfig config;
PaperBackupConfig config;
public PaperBackupManager(BackupConfig config) {
public PaperBackupManager(PaperBackupConfig config) {
super(config.backupDirectory);
setConfig(config);
for (final World world : Bukkit.getWorlds()) {
initWorldProcess(world.getName());
}
initWorkdirProcess();
addProcess(new PaperWorkdirProcess(this));
addProcess(new RotatedLogsBackupProcess(this, true, new File("logs"), "[0-9]{4}-[0-9]{2}-[0-9]{2}(-[0-9]+)?\\.log\\.gz"));
Bukkit.getServer().getPluginManager().registerEvents(this, PandaLibPaper.getPlugin());
}
public void setConfig(BackupConfig config) {
@Override
protected void addProcess(BackupProcess process) {
updateProcessConfig(process);
super.addProcess(process);
}
public void setConfig(PaperBackupConfig config) {
this.config = config;
for (BackupProcess process : backupQueue) {
if (process instanceof PaperWorkdirProcess) {
process.setEnabled(config.workdirBackupEnabled);
process.setBackupCleaner(config.workdirBackupCleaner);
process.setScheduling(config.scheduling);
}
else if (process instanceof PaperWorldProcess) {
process.setEnabled(config.worldBackupEnabled);
process.setBackupCleaner(config.worldBackupCleaner);
process.setScheduling(config.scheduling);
}
else if (process instanceof RotatedLogsBackupProcess) {
process.setEnabled(config.logsBackupEnabled);
}
backupQueue.forEach(this::updateProcessConfig);
}
public void updateProcessConfig(BackupProcess process) {
if (process instanceof PaperWorkdirProcess) {
process.setEnabled(config.workdirBackupEnabled);
process.setBackupCleaner(config.workdirBackupCleaner);
process.setScheduling(config.scheduling);
process.setIgnoreList(config.workdirIgnoreList);
}
else if (process instanceof PaperWorldProcess) {
process.setEnabled(config.worldBackupEnabled);
process.setBackupCleaner(config.worldBackupCleaner);
process.setScheduling(config.scheduling);
}
else if (process instanceof RotatedLogsBackupProcess) {
process.setEnabled(config.logsBackupEnabled);
}
}
@ -90,20 +97,10 @@ public class PaperBackupManager extends BackupManager implements Listener {
if (compressWorlds.containsKey(worldName))
return;
PaperWorldProcess process = new PaperWorldProcess(this, worldName);
process.setEnabled(config.worldBackupEnabled);
process.setBackupCleaner(config.worldBackupCleaner);
process.setScheduling(config.scheduling);
addProcess(process);
compressWorlds.put(worldName, process);
}
private void initWorkdirProcess() {
PaperWorkdirProcess process = new PaperWorkdirProcess(this);
process.setEnabled(config.workdirBackupEnabled);
process.setBackupCleaner(config.workdirBackupCleaner);
process.setScheduling(config.scheduling);
addProcess(process);
}

View File

@ -12,37 +12,19 @@ public class PaperWorkdirProcess extends PaperBackupProcess {
protected PaperWorkdirProcess(PaperBackupManager bm) {
super(bm, "workdir");
}
public BiPredicate<File, String> getFilenameFilter() {
return new BiPredicate<File, String>() {
@Override
public boolean test(File file, String path) {
if (globalExcluded(file, path))
return false;
for (String exclude : getBackupManager().config.workdirIgnoreList) {
if (exclude.startsWith("/")) { // relative to source of workdir
if (path.matches(exclude.substring(1)))
return false;
}
else {
String name = path.substring(path.lastIndexOf("/") + 1);
if (name.matches(exclude))
return false;
}
}
return true;
}
public boolean globalExcluded(File file, String path) {
if (file.isDirectory() && new File(file, "level.dat").exists())
return true;
return false;
if (new File(getSourceDir(), "logs").equals(file))
return true;
return false;
if (file.isFile() && file.getName().endsWith(".lck"))
return true;
return false;
return false;
return PaperWorkdirProcess.super.getFilenameFilter().test(file, path);
}
};
}

View File

@ -27,11 +27,6 @@ public class PaperWorldProcess extends PaperBackupProcess {
}
public BiPredicate<File, String> getFilenameFilter() {
return (f, s) -> true;
}
@Override
public File getSourceDir() {
return WorldUtil.worldDir(worldName);