in app/services/NewProjectBackup.scala [328:380]
def conditionalBackup(projectAndFiles:(ProjectEntry, Seq[FileEntry]), storageDrivers:Map[Int, StorageDriver], storages:Map[Int, StorageEntry]):Future[Either[String, Boolean]] = {
val p = projectAndFiles._1
val nonBackupFiles = projectAndFiles._2.filter(_.backupOf.isEmpty)
if(nonBackupFiles.isEmpty) {
logger.warn(s"Project ${p.projectTitle} (${p.id}) has no current file")
Future(Left(s"Project ${p.projectTitle} (${p.id}) has no current file"))
} else {
if(nonBackupFiles.length>1) {
logger.warn(s"Project ${p.projectTitle} (${p.id}) has multiple non-backup files:")
nonBackupFiles.foreach(f=>logger.warn(s"\t${p.projectTitle} (${p.id}) ${f.filepath} on storage ${f.storageId}"))
}
val sourceFile = nonBackupFiles.head
validateExistingBackups(
sourceFile,
projectAndFiles._2.filter(_.backupOf.isDefined).sortBy(_.version)(Ordering.Int.reverse),
p,
storageDrivers
) match {
case Failure(err)=>
Future.failed(err)
case Success(Left(msg))=>
logger.info(s"Project ${p.projectTitle} (${p.id}): $msg")
Future(Right(false))
case Success(Right(maybeMostRecentBackup))=>
logger.debug(s"I will back up project ${p.projectTitle} (${p.id})")
val maybeDestStorage = for {
sourceStorage <- storages.get(sourceFile.storageId)
destStorageId <- sourceStorage.backsUpTo
destStorage <- storages.get(destStorageId)
} yield destStorage
maybeDestStorage match {
case None=>
Future(
Left(s"Cannot back up ${p.projectTitle} (${p.id}) because either the source file id ${sourceFile.storageId} is not valid or there is no backup storage configured for it")
)
case Some(destStorage)=>
if(sourceFile.storageId==destStorage.id.get) {
Future.failed(new RuntimeException(s"Cannot back up ${p.projectTitle} (${p.id}) because storage ${sourceFile.storageId} is configured to back up to itself. This is not supported and can lead to data loss, please fix."))
} else {
performBackup(sourceFile, maybeMostRecentBackup, destStorage)
.map(_=>Right(true))
.recover({
case err: Throwable =>
Left(s"Cannot back up ${p.projectTitle} (${p.id}) because ${err.getMessage} occurred while copying ${sourceFile.filepath} v${sourceFile.version} from storage ${sourceFile.storageId}")
})
}
}
}
}
}