diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
commit | 8dd16259287f58f9273002717ec4d27e97127719 (patch) | |
tree | 3863e62a53829a84037444beab3abd4ed9dfc7d0 /browser/components/backup/resources/BackupResource.sys.mjs | |
parent | Releasing progress-linux version 126.0.1-1~progress7.99u1. (diff) | |
download | firefox-8dd16259287f58f9273002717ec4d27e97127719.tar.xz firefox-8dd16259287f58f9273002717ec4d27e97127719.zip |
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/backup/resources/BackupResource.sys.mjs')
-rw-r--r-- | browser/components/backup/resources/BackupResource.sys.mjs | 170 |
1 files changed, 164 insertions, 6 deletions
diff --git a/browser/components/backup/resources/BackupResource.sys.mjs b/browser/components/backup/resources/BackupResource.sys.mjs index d851eb5199..5be6314a60 100644 --- a/browser/components/backup/resources/BackupResource.sys.mjs +++ b/browser/components/backup/resources/BackupResource.sys.mjs @@ -2,6 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + Sqlite: "resource://gre/modules/Sqlite.sys.mjs", +}); + // Convert from bytes to kilobytes (not kibibytes). export const BYTES_IN_KB = 1000; @@ -50,6 +58,19 @@ export class BackupResource { } /** + * This can be overridden to return a number indicating the priority the + * resource should have in the backup order. + * + * Resources with a higher priority will be backed up first. + * The default priority of 0 indicates it can be processed in any order. + * + * @returns {number} + */ + static get priority() { + return 0; + } + + /** * Get the size of a file. * * @param {string} filePath - path to a file. @@ -129,6 +150,75 @@ export class BackupResource { return size; } + /** + * Copy a set of SQLite databases safely from a source directory to a + * destination directory. A new read-only connection is opened for each + * database, and then a backup is created. If the source database does not + * exist, it is ignored. + * + * @param {string} sourcePath + * Path to the source directory of the SQLite databases. + * @param {string} destPath + * Path to the destination directory where the SQLite databases should be + * copied to. + * @param {Array<string>} sqliteDatabases + * An array of filenames of the SQLite databases to copy. + * @returns {Promise<undefined>} + */ + static async copySqliteDatabases(sourcePath, destPath, sqliteDatabases) { + for (let fileName of sqliteDatabases) { + let sourceFilePath = PathUtils.join(sourcePath, fileName); + + if (!(await IOUtils.exists(sourceFilePath))) { + continue; + } + + let destFilePath = PathUtils.join(destPath, fileName); + let connection; + + try { + connection = await lazy.Sqlite.openConnection({ + path: sourceFilePath, + readOnly: true, + }); + + await connection.backup( + destFilePath, + BackupResource.SQLITE_PAGES_PER_STEP, + BackupResource.SQLITE_STEP_DELAY_MS + ); + } finally { + await connection?.close(); + } + } + } + + /** + * A helper function to copy a set of files from a source directory to a + * destination directory. Callers should ensure that the source files can be + * copied safely before invoking this function. Files that do not exist will + * be ignored. Callers that wish to copy SQLite databases should use + * copySqliteDatabases() instead. + * + * @param {string} sourcePath + * Path to the source directory of the files to be copied. + * @param {string} destPath + * Path to the destination directory where the files should be + * copied to. + * @param {string[]} fileNames + * An array of filenames of the files to copy. + * @returns {Promise<undefined>} + */ + static async copyFiles(sourcePath, destPath, fileNames) { + for (let fileName of fileNames) { + let sourceFilePath = PathUtils.join(sourcePath, fileName); + let destFilePath = PathUtils.join(destPath, fileName); + if (await IOUtils.exists(sourceFilePath)) { + await IOUtils.copy(sourceFilePath, destFilePath, { recursive: true }); + } + } + } + constructor() {} /** @@ -144,12 +234,12 @@ export class BackupResource { } /** - * Perform a safe copy of the resource(s) and write them into the backup - * database. The Promise should resolve with an object that can be serialized - * to JSON, as it will be written to the manifest file. This same object will - * be deserialized and passed to restore() when restoring the backup. This - * object can be null if no additional information is needed to restore the - * backup. + * Perform a safe copy of the datastores that this resource manages and write + * them into the backup database. The Promise should resolve with an object + * that can be serialized to JSON, as it will be written to the manifest file. + * This same object will be deserialized and passed to restore() when + * restoring the backup. This object can be null if no additional information + * is needed to restore the backup. * * @param {string} stagingPath * The path to the staging folder where copies of the datastores for this @@ -167,4 +257,72 @@ export class BackupResource { async backup(stagingPath, profilePath = null) { throw new Error("BackupResource::backup must be overridden"); } + + /** + * Recovers the datastores that this resource manages from a backup archive + * that has been decompressed into the recoveryPath. A pre-existing unlocked + * user profile should be available to restore into, and destProfilePath + * should point at its location on the file system. + * + * This method is not expected to be running in an app connected to the + * destProfilePath. If the BackupResource needs to run some operations + * while attached to the recovery profile, it should do that work inside of + * postRecovery(). If data needs to be transferred to postRecovery(), it + * should be passed as a JSON serializable object in the return value of this + * method. + * + * @see BackupResource.postRecovery() + * @param {object|null} manifestEntry + * The object that was returned by the backup() method when the backup was + * created. This object can be null if no additional information was needed + * for recovery. + * @param {string} recoveryPath + * The path to the resource directory where the backup archive has been + * decompressed. + * @param {string} destProfilePath + * The path to the profile directory where the backup should be restored to. + * @returns {Promise<object|null>} + * This should return a JSON serializable object that will be passed to + * postRecovery() if any data needs to be passed to it. This object can be + * null if no additional information is needed for postRecovery(). + */ + // eslint-disable-next-line no-unused-vars + async recover(manifestEntry, recoveryPath, destProfilePath) { + throw new Error("BackupResource::recover must be overridden"); + } + + /** + * Perform any post-recovery operations that need to be done after the + * recovery has been completed and the recovered profile has been attached + * to. + * + * This method is running in an app connected to the recovered profile. The + * profile is locked, but this postRecovery method can be used to insert + * data into connected datastores, or perform any other operations that can + * only occur within the context of the recovered profile. + * + * @see BackupResource.recover() + * @param {object|null} postRecoveryEntry + * The object that was returned by the recover() method when the recovery + * was originally done. This object can be null if no additional information + * is needed for post-recovery. + */ + // eslint-disable-next-line no-unused-vars + async postRecovery(postRecoveryEntry) { + // no-op by default + } } + +XPCOMUtils.defineLazyPreferenceGetter( + BackupResource, + "SQLITE_PAGES_PER_STEP", + "browser.backup.sqlite.pages_per_step", + 5 +); + +XPCOMUtils.defineLazyPreferenceGetter( + BackupResource, + "SQLITE_STEP_DELAY_MS", + "browser.backup.sqlite.step_delay_ms", + 250 +); |