backend-manager 2.5.13 → 2.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/cli/cli.js +14 -4
- package/src/manager/functions/core/actions/api/admin/backup.js +81 -2
- package/src/manager/functions/core/cron/daily.js +1 -0
- package/src/manager/index.js +1 -1
- package/templates/{storage-lifecycle-config.json → storage-lifecycle-config-1-day.json} +0 -0
- package/templates/storage-lifecycle-config-30-days.json +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-manager",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.14",
|
|
4
4
|
"description": "Quick tools for developing Firebase functions",
|
|
5
5
|
"main": "src/manager/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -136,4 +136,4 @@
|
|
|
136
136
|
"wonderful-fetch",
|
|
137
137
|
"yargs"
|
|
138
138
|
]
|
|
139
|
-
}
|
|
139
|
+
}
|
package/src/cli/cli.js
CHANGED
|
@@ -1322,16 +1322,26 @@ async function cmd_iamImportExport(self) {
|
|
|
1322
1322
|
async function cmd_setStorageLifecycle(self) {
|
|
1323
1323
|
return new Promise(function(resolve, reject) {
|
|
1324
1324
|
const command = `gsutil lifecycle set {config} gs://{bucket}`
|
|
1325
|
-
.replace(/{config}/ig, path.resolve(`${__dirname}/../../templates/storage-lifecycle-config.json`))
|
|
1325
|
+
.replace(/{config}/ig, path.resolve(`${__dirname}/../../templates/storage-lifecycle-config-1-day.json`))
|
|
1326
1326
|
.replace(/{bucket}/ig, `us.artifacts.${self.projectName}.appspot.com`)
|
|
1327
|
+
const command2 = `gsutil lifecycle set {config} gs://{bucket}`
|
|
1328
|
+
.replace(/{config}/ig, path.resolve(`${__dirname}/../../templates/storage-lifecycle-config-30-days.json`))
|
|
1329
|
+
.replace(/{bucket}/ig, `bm-backup-firestore-${self.projectName}`)
|
|
1327
1330
|
|
|
1328
|
-
|
|
1331
|
+
exec(command, function (error, stdout, stderr) {
|
|
1329
1332
|
if (error) {
|
|
1330
1333
|
console.log(chalk.red(`Failed to run command`, error));
|
|
1331
1334
|
reject(error);
|
|
1332
1335
|
} else {
|
|
1333
|
-
|
|
1334
|
-
|
|
1336
|
+
exec(command2, function (error, stdout, stderr) {
|
|
1337
|
+
if (error) {
|
|
1338
|
+
console.log(chalk.red(`Failed to run command`, error));
|
|
1339
|
+
reject(error);
|
|
1340
|
+
} else {
|
|
1341
|
+
// console.log(chalk.green(`Added lifecycle`));
|
|
1342
|
+
resolve(stdout);
|
|
1343
|
+
}
|
|
1344
|
+
})
|
|
1335
1345
|
}
|
|
1336
1346
|
});
|
|
1337
1347
|
});
|
|
@@ -36,7 +36,7 @@ Module.prototype.main = function () {
|
|
|
36
36
|
const bucketAddress = `gs://${bucketName}`;
|
|
37
37
|
|
|
38
38
|
await self.createBucket(bucketName, resourceZone);
|
|
39
|
-
await self.deleteOldFiles(bucketName, resourceZone);
|
|
39
|
+
// await self.deleteOldFiles(bucketName, resourceZone);
|
|
40
40
|
|
|
41
41
|
client.exportDocuments({
|
|
42
42
|
name: databaseName,
|
|
@@ -127,7 +127,86 @@ Module.prototype.createBucket = function (bucketName, resourceZone) {
|
|
|
127
127
|
};
|
|
128
128
|
|
|
129
129
|
// https://github.com/zsolt-dev/auto-delete-gcp-storage-backups/blob/master/index.js
|
|
130
|
-
Module.prototype.
|
|
130
|
+
Module.prototype.__RETRY_deleteOldFiles = function (bucketName, resourceZone) {
|
|
131
|
+
const self = this;
|
|
132
|
+
const Manager = self.Manager;
|
|
133
|
+
const Api = self.Api;
|
|
134
|
+
const assistant = self.assistant;
|
|
135
|
+
const payload = self.payload;
|
|
136
|
+
|
|
137
|
+
return new Promise(async function(resolve, reject) {
|
|
138
|
+
const now = moment();
|
|
139
|
+
const deletionRegex = payload.data.payload.deletionRegex;
|
|
140
|
+
|
|
141
|
+
// Helpers
|
|
142
|
+
const getFileObjectWithMetaData = async (bucketName, fileName) => {
|
|
143
|
+
const [metaData] = await storage.bucket(bucketName).file(fileName).getMetadata();
|
|
144
|
+
return ({ fileName, created: metaData.timeCreated });
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const deleteFileFromBucket = async (bucketName, fileName) => {
|
|
148
|
+
assistant.log(`Deleting item: ${fileName}...`, );
|
|
149
|
+
return await storage.bucket(bucketName).file(fileName).delete();
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Main
|
|
153
|
+
// get the file names as an array
|
|
154
|
+
let [allFiles] = await storage.bucket(bucketName).getFiles();
|
|
155
|
+
let deletePromises = [];
|
|
156
|
+
let foldersToDelete = [];
|
|
157
|
+
allFiles = allFiles.map(file => file.name);
|
|
158
|
+
// console.log(`all files: ${allFiles.join(', ')}`);
|
|
159
|
+
|
|
160
|
+
allFiles.forEach((filePath, i) => {
|
|
161
|
+
const fileName = filePath.split('/')[0];
|
|
162
|
+
const date = moment(fileName.split('T')[0]);
|
|
163
|
+
const day = date.date();
|
|
164
|
+
const month = date.month();
|
|
165
|
+
const age = now.diff(date, 'days', false);
|
|
166
|
+
|
|
167
|
+
if (age >= 30) {
|
|
168
|
+
if (day === 1) { return }
|
|
169
|
+
deletePromises.push(deleteFileFromBucket(bucketName, backup.fileName))
|
|
170
|
+
assistant.log(`Preparing to delete ${filePath}: date=${date.format('MMM Do, YYYY')}, day=${day}, month=${month}, age=${age}`, );
|
|
171
|
+
// if (!foldersToDelete.includes(fileName)) {
|
|
172
|
+
// assistant.log(`Preparing to delete ${fileName}: date=${date.format('MMM Do, YYYY')}, day=${day}, month=${month}, age=${age}`, );
|
|
173
|
+
// foldersToDelete = foldersToDelete.concat(fileName);
|
|
174
|
+
// deletePromises.push(deleteFileFromBucket(bucketName, fileName))
|
|
175
|
+
// }
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
console.log('---deletePromises.length', deletePromises.length);
|
|
180
|
+
|
|
181
|
+
return
|
|
182
|
+
|
|
183
|
+
// transform to array of objects with creation timestamp { fileName: abc, created: xyz }
|
|
184
|
+
allFiles = allFiles.map(fileName => getFileObjectWithMetaData(bucketName, fileName));
|
|
185
|
+
allFiles = await Promise.all(allFiles);
|
|
186
|
+
|
|
187
|
+
allFiles.forEach((backup, i) => {
|
|
188
|
+
const date = moment(backup.created);
|
|
189
|
+
const day = date.date();
|
|
190
|
+
const month = date.month();
|
|
191
|
+
const age = now.diff(date, 'days', false);
|
|
192
|
+
|
|
193
|
+
assistant.log(`Sorting item ${i}: date=${date.format('MMM Do, YYYY')}, day=${day}, month=${month}, age=${age}`, );
|
|
194
|
+
|
|
195
|
+
if (age >= 31) {
|
|
196
|
+
if (day === 1) { return }
|
|
197
|
+
deletePromises.push(deleteFileFromBucket(bucketName, backup.fileName))
|
|
198
|
+
} else if ((deletionRegex && backup.fileName.match(deletionRegex))) {
|
|
199
|
+
deletePromises.push(deleteFileFromBucket(bucketName, backup.fileName))
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
await Promise.all(deletePromises);
|
|
204
|
+
|
|
205
|
+
return resolve();
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
Module.prototype.__deleteOldFiles = function (bucketName, resourceZone) {
|
|
131
210
|
const self = this;
|
|
132
211
|
const Manager = self.Manager;
|
|
133
212
|
const Api = self.Api;
|
|
@@ -24,6 +24,7 @@ Module.prototype.main = function() {
|
|
|
24
24
|
return new Promise(async function(resolve, reject) {
|
|
25
25
|
fetch(`${Manager.project.functionsUrl}/bm_api`, {
|
|
26
26
|
method: 'post',
|
|
27
|
+
response: 'json',
|
|
27
28
|
body: {
|
|
28
29
|
backendManagerKey: Manager.config.backend_manager.key,
|
|
29
30
|
command: 'admin:backup',
|
package/src/manager/index.js
CHANGED
|
@@ -386,7 +386,7 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
386
386
|
// Cron
|
|
387
387
|
exporter.bm_cronDaily =
|
|
388
388
|
self.libraries.functions
|
|
389
|
-
.runWith({ memory: '256MB', timeoutSeconds:
|
|
389
|
+
.runWith({ memory: '256MB', timeoutSeconds: 120 })
|
|
390
390
|
.pubsub.schedule('every 24 hours')
|
|
391
391
|
.onRun(async (context) => {
|
|
392
392
|
return self._process((new (require(`${core}/cron/daily.js`))()).init(self, { context: context, }))
|
|
File without changes
|