From 0e4957e4c7480b737b562b43b2778e078d55d248 Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Sat, 12 Nov 2022 18:10:12 +0100 Subject: [PATCH] Make a backup of the config directory on startup On each start the config is backed up in a separate directory. 5 backups are kept, older backups get deleted. --- CHANGELOG.md | 9 ++++++ common/src/main/java/ctbrec/Config.java | 43 ++++++++++++++++--------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dff285d..bed7e134 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ object from the persisted groups.json file. Now the model state is updated before performing the check. * Fixed: File handles not released for failed segments +* Changed config backup mechanism: Instead of creating a backup of the config + in case of an error, ctbrec now creates a backup of the config on each start. + Up to 5 backups are kept, older backups will be deleted automatically + The backup will be created right next to the current config dir. E.g.: + ``` + ctbrec + |- 4.7.13 + |- 4.7.13_backup_2022-11-12_18-03-35_712 + ``` 4.7.13 ======================== diff --git a/common/src/main/java/ctbrec/Config.java b/common/src/main/java/ctbrec/Config.java index 75f5bf63..8bbdde0f 100644 --- a/common/src/main/java/ctbrec/Config.java +++ b/common/src/main/java/ctbrec/Config.java @@ -17,8 +17,6 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.StandardCopyOption; -import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.LocalTime; @@ -61,6 +59,8 @@ public class Config { configDir = new File(OS.getConfigDir(), Version.getVersion().toString()); } + backupConfig(configDir); + if (System.getProperty("ctbrec.config") != null) { filename = System.getProperty("ctbrec.config"); } else { @@ -68,6 +68,30 @@ public class Config { } } + private void backupConfig(File currentConfigDir) throws IOException { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(RECORDING_DATE_FORMAT); + File src = currentConfigDir; + File target = new File(src.getParentFile(), src.getName() + "_backup_" + dateTimeFormatter.format(LocalDateTime.now())); + LOG.info("Creating a backup of the config in {}", target); + FileUtils.copyDirectory(src, target, pathname -> !(pathname.toString().contains("minimal-browser") && pathname.toString().contains("Cache")), true); + deleteOldBackups(currentConfigDir); + } + + private void deleteOldBackups(File currentConfigDir) { + File parent = currentConfigDir.getParentFile(); + File[] backupDirectories = parent.listFiles(file -> file.isDirectory() && file.getName().matches(".*?_backup_\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}_\\d{3}")); + Arrays.sort(backupDirectories, Comparator.comparing(File::getName)); + for (int i = 0; i < backupDirectories.length - 5; i++) { + File dirToDelete = backupDirectories[i]; + try { + LOG.info("Delete old config backup {}", dirToDelete); + IoUtils.deleteDirectory(dirToDelete); + } catch (IOException e) { + LOG.error("Couldn't delete old config backup {}. You might have to delete it manually.", dirToDelete, e); + } + } + } + private void copyConfigIfNewVersion() throws IOException { File configDirectory; if (System.getProperty(SYSPROP_CONFIG_DIR) != null) { @@ -146,7 +170,6 @@ public class Config { for (Site site : sites) { site.setEnabled(!settings.disabledSites.contains(site.getName())); } - makeBackup(configFile); throw e; } } else { @@ -238,23 +261,11 @@ public class Config { if (settings.modelsIgnored != null && !settings.modelsIgnored.isEmpty()) { settings.ignoredModels = settings.modelsIgnored.stream() .map(Model::getUrl) - .collect(Collectors.toList()); + .collect(Collectors.toList()); // NOSONAR modifiable list desired here settings.modelsIgnored = null; } } - private void makeBackup(File source) { - try { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); - String timestamp = sdf.format(new Date()); - String backup = source.getName() + '.' + timestamp; - File target = new File(source.getParentFile(), backup); - Files.copy(source.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); - } catch (Exception e) { - LOG.error("Couldn't create backup of settings file", e); - } - } - public static synchronized void init(List sites) throws IOException { if (instance == null) { instance = new Config(sites);