Strengthen data preservation checks & update how bypass preservation is set (#931)

* Strengthen bypass data preservation variable checks
* If a file is modified locally, and '--resync' is used, there is no way to tell if this file is a failed download or 'valid' thus potentially lead to a data loss scenario. In this case, and ONLY if --resync was issued, rename the local file for data preservation
This commit is contained in:
abraunegg 2020-05-26 17:04:22 +10:00 committed by GitHub
parent f9c3ccc311
commit aee2052f1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 2 deletions

View file

@ -678,6 +678,7 @@ int main(string[] args)
if (cfg.getValueBool("bypass_data_preservation")) {
log.log("WARNING: Application has been configured to bypass local data preservation in the event of file conflict.");
log.log("WARNING: Local data loss MAY occur in this scenario.");
sync.setBypassDataPreservation();
}
// Do we need to validate the syncDir to check for the presence of a '.nosync' file

View file

@ -238,6 +238,9 @@ final class SyncEngine
private bool syncListConfigured = false;
// sync_list new folder added, trigger delta scan override
private bool oneDriveFullScanTrigger = false;
// is bypass_data_preservation set via config file
// Local data loss MAY occur in this scenario
private bool bypassDataPreservation = false;
this(Config cfg, OneDriveApi onedrive, ItemDatabase itemdb, SelectiveSync selectiveSync)
{
@ -482,6 +485,13 @@ final class SyncEngine
log.vdebug("Setting syncListConfigured = true");
}
// set bypassDataPreservation to true
void setBypassDataPreservation()
{
bypassDataPreservation = true;
log.vdebug("Setting bypassDataPreservation = true");
}
// download all new changes from OneDrive
void applyDifferences(bool performFullItemScan)
{
@ -1662,7 +1672,7 @@ final class SyncEngine
auto newPath = path.chomp(ext) ~ "-" ~ deviceName ~ ext;
// has the user configured to IGNORE local data protection rules?
if (cfg.getValueString("bypass_data_preservation")){
if (bypassDataPreservation) {
// The user has configured to ignore data safety checks and overwrite local data rather than preserve & rename
log.vlog("WARNING: Local Data Protection has been disabled. You may experience data loss on this file: ", oldPath);
} else {
@ -1741,12 +1751,14 @@ final class SyncEngine
// local file is newer than item on OneDrive based on file modified time
// Is this item id in the database?
if (itemdb.idInLocalDatabase(item.driveId, item.id)){
// item id is in the database
// no local rename
// no download needed
log.vlog("Local item modified time is newer based on UTC time conversion - keeping local item as this exists in the local database");
log.vdebug("Skipping OneDrive change as this is determined to be unwanted due to local item modified time being newer than OneDrive item and present in the sqlite database");
return;
} else {
// item id is not in the database .. maybe a --resync ?
// Should this 'download' be skipped?
// Do we need to check for .nosync? Only if --check-for-nosync was passed in
if (cfg.getValueBool("check_nosync")) {
@ -1764,6 +1776,33 @@ final class SyncEngine
}
// file exists locally but is not in the sqlite database - maybe a failed download?
log.vlog("Local item does not exist in local database - replacing with file from OneDrive - failed download?");
// was --resync issued?
if (cfg.getValueBool("resync")) {
// in a --resync scenario we have zero way of knowing IF the local file is meant to be the right file
// we have passed the following checks:
// 1. file exists locally
// 2. local modified time > remote modified time
// 3. id is not in the database
// 4. --resync was issued
auto ext = extension(path);
auto newPath = path.chomp(ext) ~ "-" ~ deviceName ~ ext;
// has the user configured to IGNORE local data protection rules?
if (bypassDataPreservation) {
// The user has configured to ignore data safety checks and overwrite local data rather than preserve & rename
log.vlog("WARNING: Local Data Protection has been disabled. You may experience data loss on this file: ", path);
} else {
// local data protection is configured, renaming local file
log.vlog("The local item is out-of-sync with OneDrive, renaming to preserve existing file and prevent data loss due to --resync: ", path, " -> ", newPath);
// perform the rename action of the local file
if (!dryRun) {
safeRename(path);
} else {
// Expectation here is that there is a new file locally (newPath) however as we don't create this, the "new file" will not be uploaded as it does not exist
log.vdebug("DRY-RUN: Skipping local file rename");
}
}
}
}
} else {
// remote file is newer than local item
@ -1772,7 +1811,7 @@ final class SyncEngine
auto newPath = path.chomp(ext) ~ "-" ~ deviceName ~ ext;
// has the user configured to IGNORE local data protection rules?
if (cfg.getValueString("bypass_data_preservation")){
if (bypassDataPreservation) {
// The user has configured to ignore data safety checks and overwrite local data rather than preserve & rename
log.vlog("WARNING: Local Data Protection has been disabled. You may experience data loss on this file: ", path);
} else {