This commit is contained in:
2020-05-22 17:30:58 +00:00
parent 6aa8cb67db
commit eb49216287
4 changed files with 97 additions and 53 deletions

View File

@@ -76,17 +76,18 @@ namespace AyaNova.Api.Controllers
/// <summary> /// <summary>
/// Get list of backup files /// Get status of backup
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet("list")] [HttpGet("status")]
public ActionResult ListBackupFiles() public ActionResult BackupStatus()
{ {
//Need size and more info
if (serverState.IsClosed) if (serverState.IsClosed)
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
if (!Authorized.HasAnyRole(HttpContext.Items, AuthorizationRoles.OpsAdminFull | AuthorizationRoles.OpsAdminLimited)) if (!Authorized.HasAnyRole(HttpContext.Items, AuthorizationRoles.OpsAdminFull | AuthorizationRoles.OpsAdminLimited))
return StatusCode(403, new ApiNotAuthorizedResponse()); return StatusCode(403, new ApiNotAuthorizedResponse());
return Ok(ApiOkResponse.Response(FileUtil.UtilityFileList())); return Ok(ApiOkResponse.Response(FileUtil.BackupStatusReport()));
} }
/// <summary> /// <summary>
@@ -124,8 +125,7 @@ namespace AyaNova.Api.Controllers
return StatusCode(403, new ApiNotAuthorizedResponse()); return StatusCode(403, new ApiNotAuthorizedResponse());
} }
var AvailableFiles = FileUtil.UtilityFileList(); if (!FileUtil.UtilityFileExists(fileName))
if (!AvailableFiles.Contains(fileName))
{ {
await Task.Delay(nFailedAuthDelay);//fishing protection await Task.Delay(nFailedAuthDelay);//fishing protection
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));

View File

@@ -25,6 +25,7 @@ namespace AyaNova.Biz
public static async Task DoWorkAsync(AyContext ct, bool OnDemand = false) public static async Task DoWorkAsync(AyContext ct, bool OnDemand = false)
{ {
if (BackupIsRunning) return; if (BackupIsRunning) return;
FileUtil.DatabaseBackupCleanUp(ServerGlobalOpsSettingsCache.Backup.BackupSetsToKeep);
//get NOW in utc //get NOW in utc
DateTime utcNow = DateTime.UtcNow; DateTime utcNow = DateTime.UtcNow;
if (!OnDemand) if (!OnDemand)
@@ -83,17 +84,12 @@ namespace AyaNova.Biz
log.LogError($"BACKUP ERROR: {Result}"); log.LogError($"BACKUP ERROR: {Result}");
//PRUNE DATA BACKUP SETS NOT KEPT
FileUtil.DatabaseBackupCleanUp(ServerGlobalOpsSettingsCache.Backup.BackupSetsToKeep);
//DO FILE BACKUP IF ATTACHMENTS BACKED UP //DO FILE BACKUP IF ATTACHMENTS BACKED UP
if (ServerGlobalOpsSettingsCache.Backup.BackupAttachments) if (ServerGlobalOpsSettingsCache.Backup.BackupAttachments)
FileUtil.BackupAttachments(); FileUtil.BackupAttachments();
//PRUNE DATA BACKUP SETS NOT KEPT //PRUNE DATA BACKUP SETS NOT KEPT
FileUtil.AttachmentBackupCleanUp(ServerGlobalOpsSettingsCache.Backup.BackupSetsToKeep); FileUtil.DatabaseBackupCleanUp(ServerGlobalOpsSettingsCache.Backup.BackupSetsToKeep);
//v.next - COPY TO ONLINE STORAGE //v.next - COPY TO ONLINE STORAGE
@@ -105,7 +101,7 @@ namespace AyaNova.Biz
var biz = GlobalOpsBackupSettingsBiz.GetBiz(ct); var biz = GlobalOpsBackupSettingsBiz.GetBiz(ct);
var OpSet = await biz.GetAsync(false); var OpSet = await biz.GetAsync(false);
await biz.PutAsync(OpSet); await biz.PutAsync(OpSet);
ServerGlobalOpsSettingsCache.Backup.LastBackup=utcNow; ServerGlobalOpsSettingsCache.Backup.LastBackup = utcNow;
} }
log.LogDebug("Backup completed"); log.LogDebug("Backup completed");
} }

View File

@@ -17,7 +17,8 @@ namespace AyaNova.Models
public GlobalOpsBackupSettings() public GlobalOpsBackupSettings()
{ {
Id = 1;//always 1 Id = 1;//always 1
BackupTime = new DateTime(2020, 5, 19, 23, 59, 0, DateTimeKind.Local).ToUniversalTime();//date doesn't matter it only uses hour BackupTime = new DateTime(2020, 5, 19, 23, 59, 0, DateTimeKind.Local).ToUniversalTime();//date doesn't matter it only uses hour
// BackupTime = DateTime.UtcNow.AddMinutes(-10);//for testing, above is regular
BackupSetsToKeep = 3; BackupSetsToKeep = 3;
} }
} }

View File

@@ -87,38 +87,89 @@ namespace AyaNova.Util
} }
/// <summary> // /// <summary>
/// Delete a utility file (backup folder file) // /// Delete a utility file (backup folder file)
/// </summary> // /// </summary>
/// <param name="fileName"></param> // /// <param name="fileName"></param>
internal static void DeleteUtilityFile(string fileName) // internal static void DeleteUtilityFile(string fileName)
// {
// var utilityFilePath = GetFullPathForUtilityFile(fileName);
// if (File.Exists(utilityFilePath))
// {
// File.Delete(utilityFilePath);
// }
// }
public class BackupFileInfo
{ {
var utilityFilePath = GetFullPathForUtilityFile(fileName); public long length { get; set; }
if (File.Exists(utilityFilePath)) public string Name { get; set; }
public DateTime Created { get; set; }
}
public class BackupStatus
{
public long AvailableFreeSpace { get; set; }
public List<BackupFileInfo> BackupFiles { get; set; }
public BackupStatus()
{ {
File.Delete(utilityFilePath); AvailableFreeSpace = 0;
BackupFiles = new List<BackupFileInfo>();
} }
} }
/// <summary> /// <summary>
/// Get a list of files in the utility folder /// Get a status report of backup
/// /// for reporting to ops user in UI
/// </summary> /// </summary>
/// <param name="searchPattern">search pattern for files desired, leave blank for any </param>
/// <returns></returns> /// <returns></returns>
internal static List<string> UtilityFileList(string searchPattern = "*") internal static BackupStatus BackupStatusReport()
{ {
List<string> returnList = new List<string>(); BackupStatus statusReport = new BackupStatus();
foreach (string file in Directory.EnumerateFiles(UtilityFilesFolder, searchPattern)) try
{ {
returnList.Add(Path.GetFileName(file)); statusReport.AvailableFreeSpace = new System.IO.DriveInfo(Path.GetPathRoot(UtilityFilesFolder)).AvailableFreeSpace;
} }
returnList.Sort(); catch (Exception ex)
return returnList; {
statusReport.AvailableFreeSpace = -1;
ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("FileUtil::BackupStatus");
log.LogError(ex, "FileUtil::BackupStatusReport error getting available space");
}
var backupFiles = Directory.EnumerateFiles(UtilityFilesFolder, "*");
foreach (string file in backupFiles)
{
var fi = new FileInfo(file);
statusReport.BackupFiles.Add(new BackupFileInfo()
{
Name = Path.GetFileName(file),
length = fi.Length,
Created = fi.CreationTimeUtc
});
}
return statusReport;
} }
// List<string> returnList = new List<string>();
// foreach (string file in Directory.EnumerateFiles(UtilityFilesFolder, "*"))
// {
// var fi = new FileInfo(file);
// returnList.Add(fi.Length);
// }
// returnList.Sort();
// return returnList;
/// <summary> /// <summary>
/// Get date of newest backup file or minvalue if not found /// Get date of newest backup file or minvalue if not found
/// ///
@@ -130,7 +181,7 @@ namespace AyaNova.Util
var BackupPath = UtilityFilesFolder; var BackupPath = UtilityFilesFolder;
foreach (string file in Directory.EnumerateFiles(UtilityFilesFolder, "*.backup")) foreach (string file in Directory.EnumerateFiles(UtilityFilesFolder, "*.backup"))
{ {
var ThisFileTime = File.GetCreationTimeUtc(Path.Combine(BackupPath, file)); var ThisFileTime = File.GetCreationTimeUtc(file);
if (ThisFileTime > LastBackup) if (ThisFileTime > LastBackup)
{ {
LastBackup = ThisFileTime; LastBackup = ThisFileTime;
@@ -180,41 +231,37 @@ namespace AyaNova.Util
internal static void DatabaseBackupCleanUp(int keepCount) internal static void DatabaseBackupCleanUp(int keepCount)
{ {
if (keepCount < 1) keepCount = 1; if (keepCount < 1) keepCount = 1;
var BackupFileList = UtilityFileList("db-*.backup");
if (BackupFileList.Count > keepCount) //Database backups
var BackupFileList = Directory.EnumerateFiles(UtilityFilesFolder, "db-*.backup");
if (BackupFileList.Count() > keepCount)
{ {
//sort, skip newest x (keepcount) delete the rest //sort, skip newest x (keepcount) delete the rest
var DeleteCount = BackupFileList.Count - keepCount; var DeleteCount = BackupFileList.Count() - keepCount;
var DeleteFileList = BackupFileList.OrderByDescending(m => m).Skip(keepCount).ToList(); var DeleteFileList = BackupFileList.OrderByDescending(m => m).Skip(keepCount).ToList();
foreach (string ExtraBackupFile in DeleteFileList) foreach (string ExtraBackupFile in DeleteFileList)
{ {
DeleteUtilityFile(ExtraBackupFile); File.Delete(ExtraBackupFile);
} }
} }
}
/// <summary> //Attachment backups
/// Cleanup excess backups (backup folder file) BackupFileList = Directory.EnumerateFiles(UtilityFilesFolder, "at-*.zip");
/// </summary> if (BackupFileList.Count() > keepCount)
/// <param name="keepCount"></param>
internal static void AttachmentBackupCleanUp(int keepCount)
{
if (keepCount < 1) keepCount = 1;
var BackupFileList = UtilityFileList("at-*.zip");
if (BackupFileList.Count > keepCount)
{ {
//sort, skip newest x (keepcount) delete the rest //sort, skip newest x (keepcount) delete the rest
var DeleteCount = BackupFileList.Count - keepCount; var DeleteCount = BackupFileList.Count() - keepCount;
var DeleteFileList = BackupFileList.OrderByDescending(m => m).Skip(keepCount).ToList(); var DeleteFileList = BackupFileList.OrderByDescending(m => m).Skip(keepCount).ToList();
foreach (string ExtraBackupFile in DeleteFileList) foreach (string ExtraBackupFile in DeleteFileList)
{ {
DeleteUtilityFile(ExtraBackupFile); File.Delete(ExtraBackupFile);
} }
} }
} }
#endregion Utility file handling #endregion Utility file handling
#region Zip handling #region Zip handling