This commit is contained in:
@@ -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));
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user