@topgroup/diginext
Version:
A BUILD SERVER & CLI to deploy apps to any Kubernetes clusters.
163 lines (162 loc) • 7.33 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CloudDatabaseBackupService = void 0;
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const app_config_1 = require("../app.config");
const CloudDatabaseBackup_1 = require("../entities/CloudDatabaseBackup");
const mongodb_1 = require("../plugins/mongodb");
const BaseService_1 = __importDefault(require("./BaseService"));
const SystemLogService_1 = require("./SystemLogService");
const WorkspaceService_1 = require("./WorkspaceService");
class CloudDatabaseBackupService extends BaseService_1.default {
constructor(ownership) {
super(CloudDatabaseBackup_1.cloudDatabaseBackupSchema, ownership);
}
async create(data) {
try {
const backup = await super.create(data);
console.log("CloudDatabaseBackupService > create > backup :>> ", backup);
// check expired backups and deleted expired ones
this.deleteExpiredBackups(mongodb_1.MongoDB.toString(this.workspace._id));
return backup;
}
catch (e) {
const logSvc = new SystemLogService_1.SystemLogService();
await logSvc.saveError(e, {
level: 3,
name: "[DB_BK_SERVICE] Unable to create new database backup",
type: "error",
workspace: this.workspace,
});
return;
}
}
async updateStatus(id, data) {
const updateData = { status: data.status };
if (data.path) {
updateData.path = data.path;
updateData.url = `${app_config_1.Config.BASE_URL}/storage/${data.path.split("storage/")[1]}`;
}
const backup = await this.updateOne({ _id: id }, updateData);
return backup;
}
async delete(filter, options) {
const backups = await this.find(filter);
if (backups) {
try {
backups.forEach((backup) => {
const bkPath = backup.path;
if ((0, fs_1.existsSync)(bkPath))
(0, promises_1.rm)(bkPath, { recursive: true, force: true });
});
}
catch (e) {
console.error(`[DB_BK_SERVICE]`, e);
const logSvc = new SystemLogService_1.SystemLogService();
logSvc.saveError(e, { level: 3, name: "[DB_BK_SERVICE] Unable to delete database backup", type: "error", workspace: this.workspace });
}
}
return super.delete(filter, options);
}
async softDelete(filter, options) {
const backups = await this.find(filter);
if (backups) {
try {
backups.forEach((backup) => {
const bkPath = backup.path;
if ((0, fs_1.existsSync)(bkPath))
(0, promises_1.rm)(bkPath, { recursive: true, force: true });
});
}
catch (e) {
console.error(`[DB_BK_SERVICE]`, e);
const logSvc = new SystemLogService_1.SystemLogService();
logSvc.saveError(e, { level: 3, name: "[DB_BK_SERVICE] Unable to delete database backup", type: "error", workspace: this.workspace });
}
}
return super.softDelete(filter, options);
}
async deleteExpiredBackups(workspaceId) {
var _a, _b;
console.log("[DB_BACKUP] deleteExpiredBackups > workspaceId :>> ", workspaceId);
const workspaceSvc = new WorkspaceService_1.WorkspaceService();
const workspace = await workspaceSvc.findOne({ _id: workspaceId });
if (!workspace)
throw new Error(`Unable to delete expired db backups of "${workspaceId}" workspace: Workspace not found.`);
console.log("[DB_BACKUP] deleteExpiredBackups > workspace :>> ", workspace);
const { type, value } = ((_b = (_a = workspace.settings) === null || _a === void 0 ? void 0 : _a.database_backup) === null || _b === void 0 ? void 0 : _b.retention) || {};
if (!type && !value)
return;
console.log(`[DB_BACKUP] Deleting expired database backups...`);
const now = new Date();
if (type === "duration") {
// Mark as deleted based on duration
const thresholdDate = new Date(Date.now() - value);
// Count backups that would be marked as deleted
return this.model
.countDocuments({
createdAt: { $lt: thresholdDate },
deletedAt: null,
})
.then(async (toDeleteCount) => {
console.log(`${toDeleteCount} backups will be marked as deleted based on duration.`);
// Now, perform the update if there are any backups to be marked as deleted
if (toDeleteCount > 0) {
return this.softDelete({
createdAt: { $lt: thresholdDate },
deletedAt: null,
}, {
$set: { deletedAt: new Date() },
});
}
})
.catch((e) => {
console.error(`Unable to delete expired DB backups (by DURATION):`, e);
const logSvc = new SystemLogService_1.SystemLogService();
logSvc.saveError(e, {
level: 3,
name: "[DB_BK_SERVICE] Unable to delete expired DB backups (by DURATION)",
type: "error",
workspace: this.workspace,
});
});
}
else if (type === "limit") {
// Mark as deleted based on item count
return this.model
.countDocuments({ deletedAt: null })
.then((count) => {
const itemsToDelete = count - value;
if (itemsToDelete > 0) {
// We need to delete the oldest items, so we sort by 'createdAt'
return this.model
.find({ deletedAt: null })
.sort({ createdAt: 1 })
.limit(itemsToDelete)
.then((docs) => {
const idsToDelete = docs.map((doc) => doc._id);
return this.softDelete({ _id: { $in: idsToDelete } }, { $set: { deletedAt: now } });
})
.catch((e) => {
console.error(`Unable to delete DB backups:`, e);
});
}
})
.catch((e) => {
console.error(`Unable to delete expired DB backups (by LIMIT):`, e);
const logSvc = new SystemLogService_1.SystemLogService();
logSvc.saveError(e, {
level: 3,
name: "[DB_BK_SERVICE] Unable to delete expired DB backups (by LIMIT)",
type: "error",
workspace: this.workspace,
});
});
}
}
}
exports.CloudDatabaseBackupService = CloudDatabaseBackupService;