sql backup
This commit is contained in:
parent
2037cfd6d7
commit
054a23bc9d
11 changed files with 40 additions and 24 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
configs/**/data/**
|
configs/**/data/**
|
||||||
|
*.bak
|
||||||
**/node_modules
|
**/node_modules
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
logs/
|
logs/
|
||||||
|
|
@ -59,12 +59,12 @@ public class BackgroundWorkerAppService : PlatformAppService
|
||||||
|
|
||||||
foreach (var worker in workers)
|
foreach (var worker in workers)
|
||||||
{
|
{
|
||||||
var w = LazyServiceProvider.GetRequiredService<PlatformBackgroundWorker>();
|
var workerId = worker.Id;
|
||||||
|
|
||||||
RecurringJob.AddOrUpdate(
|
RecurringJob.AddOrUpdate<IPlatformBackgroundWorker>(
|
||||||
$"{worker.WorkerType}:{worker.Name}",
|
$"{worker.WorkerType}:{worker.Name}",
|
||||||
"platform",
|
"platform",
|
||||||
() => w.StartAsync(worker.Id, default),
|
(w) => w.StartAsync(workerId, default),
|
||||||
worker.Cron,
|
worker.Cron,
|
||||||
new RecurringJobOptions
|
new RecurringJobOptions
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
|
||||||
// BlobContainerNames.Import,
|
// BlobContainerNames.Import,
|
||||||
// BlobContainerNames.Note,
|
// BlobContainerNames.Note,
|
||||||
// BlobContainerNames.Intranet
|
// BlobContainerNames.Intranet
|
||||||
|
// BlobContainerNames.Backup
|
||||||
};
|
};
|
||||||
|
|
||||||
public FileManagementAppService(
|
public FileManagementAppService(
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ public class BackgroundWorkerSeedDto
|
||||||
public string WorkerType { get; set; }
|
public string WorkerType { get; set; }
|
||||||
public bool IsActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
public string DataSourceCode { get; set; }
|
public string DataSourceCode { get; set; }
|
||||||
|
public string BeforeSp { get; set; }
|
||||||
|
public string AfterSp { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NotificationRuleSeedDto
|
public class NotificationRuleSeedDto
|
||||||
|
|
@ -435,7 +437,9 @@ public class HostDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
Cron = item.Cron,
|
Cron = item.Cron,
|
||||||
WorkerType = Enum.Parse<WorkerTypeEnum>(item.WorkerType),
|
WorkerType = Enum.Parse<WorkerTypeEnum>(item.WorkerType),
|
||||||
IsActive = item.IsActive,
|
IsActive = item.IsActive,
|
||||||
DataSourceCode = item.DataSourceCode
|
DataSourceCode = item.DataSourceCode,
|
||||||
|
BeforeSp = item.BeforeSp,
|
||||||
|
AfterSp = item.AfterSp
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ using Volo.Abp.Settings;
|
||||||
using Volo.Abp.Users;
|
using Volo.Abp.Users;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Volo.Abp.Uow;
|
||||||
|
|
||||||
namespace Sozsoft.Platform.BackgroundWorkers;
|
namespace Sozsoft.Platform.BackgroundWorkers;
|
||||||
|
|
||||||
|
|
@ -56,6 +57,8 @@ public class PlatformBackgroundWorker : PlatformDomainService, IPlatformBackgrou
|
||||||
|
|
||||||
public async Task StartAsync(Guid WorkerId, CancellationToken cancellationToken = default)
|
public async Task StartAsync(Guid WorkerId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
using var uow = LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>().Begin(requiresNew: true, isTransactional: false);
|
||||||
|
|
||||||
var Worker = await Repository.GetAsync(a => a.Id == WorkerId);
|
var Worker = await Repository.GetAsync(a => a.Id == WorkerId);
|
||||||
|
|
||||||
var LogPrefix = $"{Clock.Now:s}_{Worker.Name}: {{0}}";
|
var LogPrefix = $"{Clock.Now:s}_{Worker.Name}: {{0}}";
|
||||||
|
|
@ -80,7 +83,7 @@ public class PlatformBackgroundWorker : PlatformDomainService, IPlatformBackgrou
|
||||||
// Backup Worker için yedeklerin saklanacağı klasörün oluşturulması
|
// Backup Worker için yedeklerin saklanacağı klasörün oluşturulması
|
||||||
if (Worker.WorkerType == WorkerTypeEnum.BackupWorker)
|
if (Worker.WorkerType == WorkerTypeEnum.BackupWorker)
|
||||||
{
|
{
|
||||||
backupPath = Path.Combine(Configuration["App:CdnPath"], "host", "backup");
|
backupPath = Configuration["App:BackupPath"];
|
||||||
if (!Directory.Exists(backupPath))
|
if (!Directory.Exists(backupPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(backupPath);
|
Directory.CreateDirectory(backupPath);
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ public static class BlobContainerNames
|
||||||
public const string Avatar = "avatar";
|
public const string Avatar = "avatar";
|
||||||
public const string Import = "import";
|
public const string Import = "import";
|
||||||
public const string Note = "note";
|
public const string Note = "note";
|
||||||
|
public const string Backup = "backup";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
"AttachmentsPath": "/etc/api/mail-queue/attachments",
|
"AttachmentsPath": "/etc/api/mail-queue/attachments",
|
||||||
"CdnPath": "/etc/api/cdn",
|
"CdnPath": "/etc/api/cdn",
|
||||||
"BaseDomain": "sozsoft.com",
|
"BaseDomain": "sozsoft.com",
|
||||||
|
"BackupPath": "/var/opt/mssql/backup",
|
||||||
"BackupDeleteAfterDays": 3
|
"BackupDeleteAfterDays": 3
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ networks:
|
||||||
volumes:
|
volumes:
|
||||||
cdn:
|
cdn:
|
||||||
api-keys:
|
api-keys:
|
||||||
|
sql-backups:
|
||||||
|
external: true
|
||||||
|
name: sozsoft-platform-data_sql-backups
|
||||||
|
|
||||||
services:
|
services:
|
||||||
migrator:
|
migrator:
|
||||||
|
|
@ -31,6 +34,7 @@ services:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
volumes:
|
volumes:
|
||||||
- cdn:/etc/api/cdn
|
- cdn:/etc/api/cdn
|
||||||
|
- sql-backups:/etc/api/cdn/host/backup
|
||||||
- api-keys:/root/.aspnet/DataProtection-Keys
|
- api-keys:/root/.aspnet/DataProtection-Keys
|
||||||
networks:
|
networks:
|
||||||
- db
|
- db
|
||||||
|
|
@ -53,7 +57,8 @@ services:
|
||||||
profiles: ["ui"]
|
profiles: ["ui"]
|
||||||
working_dir: /srv/http-server
|
working_dir: /srv/http-server
|
||||||
volumes:
|
volumes:
|
||||||
- cdn:/public:ro
|
- cdn:/public
|
||||||
|
- sql-backups:/public/host/backup
|
||||||
command: "/public -c10 --cors"
|
command: "/public -c10 --cors"
|
||||||
ports:
|
ports:
|
||||||
- 8081:8080
|
- 8081:8080
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ networks:
|
||||||
volumes:
|
volumes:
|
||||||
pg:
|
pg:
|
||||||
mssql:
|
mssql:
|
||||||
|
sql-backups:
|
||||||
|
|
||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
|
|
@ -46,5 +47,6 @@ services:
|
||||||
- 1433:1433
|
- 1433:1433
|
||||||
volumes:
|
volumes:
|
||||||
- mssql:/var/opt/mssql
|
- mssql:/var/opt/mssql
|
||||||
|
- sql-backups:/var/opt/mssql/backup
|
||||||
networks:
|
networks:
|
||||||
- db
|
- db
|
||||||
|
|
|
||||||
|
|
@ -46,4 +46,4 @@ services:
|
||||||
- 1433:1433
|
- 1433:1433
|
||||||
volumes:
|
volumes:
|
||||||
- mssql:/var/opt/mssql
|
- mssql:/var/opt/mssql
|
||||||
- /etc/api/cdn/host/backup:/var/opt/mssql/backup
|
- ./data/cdn/host/backup:/var/opt/mssql/backup
|
||||||
|
|
@ -39,6 +39,8 @@ import type {
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import { APP_NAME } from '@/constants/app.constant'
|
import { APP_NAME } from '@/constants/app.constant'
|
||||||
|
|
||||||
|
const { VITE_CDN_URL } = import.meta.env
|
||||||
|
|
||||||
// Select options for sorting
|
// Select options for sorting
|
||||||
|
|
||||||
const FileManager = () => {
|
const FileManager = () => {
|
||||||
|
|
@ -134,7 +136,7 @@ const FileManager = () => {
|
||||||
const items = response.data.items || []
|
const items = response.data.items || []
|
||||||
// Manual protection for system folders
|
// Manual protection for system folders
|
||||||
const protectedItems = items.map((item) => {
|
const protectedItems = items.map((item) => {
|
||||||
const isSystemFolder = ['avatar', 'import', 'note'].includes(item.name.toLowerCase())
|
const isSystemFolder = ['intranet', 'avatar', 'import', 'note', 'backup'].includes(item.name.toLowerCase())
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
isReadOnly: item.isReadOnly || isSystemFolder,
|
isReadOnly: item.isReadOnly || isSystemFolder,
|
||||||
|
|
@ -373,21 +375,18 @@ const FileManager = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDownload = async (item: FileItemType) => {
|
const handleDownload = (item: FileItemType) => {
|
||||||
try {
|
const tenantSegment = selectedTenant?.id ? `tenants/${selectedTenant.id}` : 'host'
|
||||||
const blob = await fileManagementService.downloadFile(item.id, selectedTenant?.id)
|
const filePath = item.id.replace(/\|/g, '/')
|
||||||
const url = URL.createObjectURL(blob)
|
const url = `${VITE_CDN_URL}/${tenantSegment}/${filePath}`
|
||||||
const a = document.createElement('a')
|
const a = document.createElement('a')
|
||||||
a.href = url
|
a.href = url
|
||||||
a.download = item.name
|
a.download = item.name
|
||||||
|
a.target = '_blank'
|
||||||
|
a.rel = 'noopener noreferrer'
|
||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Download failed:', error)
|
|
||||||
toast.push(<Notification type="danger">Failed to download file</Notification>)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action handlers
|
// Action handlers
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue