Bug 1796878 - Port osfile.jsm usage to IOUtils in services/ r=markh

Differential Revision: https://phabricator.services.mozilla.com/D163410
This commit is contained in:
Barret Rennie 2023-01-16 17:55:19 +00:00
parent e6db75f93c
commit 34e5ec560b
4 changed files with 67 additions and 124 deletions

View file

@ -42,7 +42,6 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
Svc: "resource://services-sync/util.js", Svc: "resource://services-sync/util.js",
FxAccountsClient: "resource://gre/modules/FxAccountsClient.jsm", FxAccountsClient: "resource://gre/modules/FxAccountsClient.jsm",
FxAccountsConfig: "resource://gre/modules/FxAccountsConfig.jsm", FxAccountsConfig: "resource://gre/modules/FxAccountsConfig.jsm",
OS: "resource://gre/modules/osfile.jsm",
}); });
XPCOMUtils.defineLazyGetter(lazy, "fxAccounts", () => { XPCOMUtils.defineLazyGetter(lazy, "fxAccounts", () => {
@ -293,10 +292,7 @@ var Authentication = {
*/ */
var Sync = { var Sync = {
getSyncLogsDirectory() { getSyncLogsDirectory() {
return lazy.OS.Path.join( return PathUtils.join(PathUtils.profileDir, "weave", "logs");
lazy.OS.Constants.Path.profileDir,
...["weave", "logs"]
);
}, },
async init() { async init() {
@ -361,19 +357,12 @@ var Sync = {
async wipeLogs() { async wipeLogs() {
let outputDirectory = this.getSyncLogsDirectory(); let outputDirectory = this.getSyncLogsDirectory();
if (!(await lazy.OS.File.exists(outputDirectory))) { if (!(await IOUtils.exists(outputDirectory))) {
return; return;
} }
LOG("Wiping existing Sync logs"); LOG("Wiping existing Sync logs");
try { try {
let iterator = new lazy.OS.File.DirectoryIterator(outputDirectory); await IOUtils.remove(outputDirectory, { recursive: true });
await iterator.forEach(async entry => {
try {
await lazy.OS.File.remove(entry.path);
} catch (error) {
LOG("wipeLogs() could not remove " + entry.path, error);
}
});
} catch (error) { } catch (error) {
LOG("wipeLogs() failed", error); LOG("wipeLogs() failed", error);
} }
@ -383,27 +372,25 @@ var Sync = {
let outputDirectory = this.getSyncLogsDirectory(); let outputDirectory = this.getSyncLogsDirectory();
let entries = []; let entries = [];
if (await lazy.OS.File.exists(outputDirectory)) { if (await IOUtils.exists(outputDirectory)) {
// Iterate through the directory // Iterate through the directory
let iterator = new lazy.OS.File.DirectoryIterator(outputDirectory); for (const path of await IOUtils.getChildren(outputDirectory)) {
const info = await IOUtils.stat(path);
await iterator.forEach(async entry => {
let info = await lazy.OS.File.stat(entry.path);
entries.push({ entries.push({
path: entry.path, path,
name: entry.name, name: PathUtils.filename(path),
lastModificationDate: info.lastModificationDate, lastModified: info.lastModified,
}); });
}); }
entries.sort(function(a, b) { entries.sort(function(a, b) {
return b.lastModificationDate - a.lastModificationDate; return b.lastModified - a.lastModified;
}); });
} }
const promises = entries.map(async entry => { const promises = entries.map(async entry => {
let content = await lazy.OS.File.read(entry.path, { const content = await IOUtils.readUTF8(entry.path);
encoding: "utf-8",
});
return { return {
name: entry.name, name: entry.name,
content, content,

View file

@ -12,7 +12,11 @@ const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, { ChromeUtils.defineESModuleGetters(lazy, {
FileUtils: "resource://gre/modules/FileUtils.sys.mjs", FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
}); });
ChromeUtils.defineModuleGetter(lazy, "OS", "resource://gre/modules/osfile.jsm"); ChromeUtils.defineModuleGetter(
lazy,
"NetUtil",
"resource://gre/modules/NetUtil.jsm"
);
const { Preferences } = ChromeUtils.importESModule( const { Preferences } = ChromeUtils.importESModule(
"resource://gre/modules/Preferences.sys.mjs" "resource://gre/modules/Preferences.sys.mjs"
@ -182,45 +186,26 @@ class FlushableStorageAppender extends StorageStreamAppender {
* Returns a promise that is resolved on completion or rejected with an error. * Returns a promise that is resolved on completion or rejected with an error.
*/ */
async _copyStreamToFile(inputStream, subdirArray, outputFileName, log) { async _copyStreamToFile(inputStream, subdirArray, outputFileName, log) {
// The log data could be large, so we don't want to pass it all in a single let outputDirectory = PathUtils.join(PathUtils.profileDir, ...subdirArray);
// message, so use BUFFER_SIZE chunks. await IOUtils.makeDirectory(outputDirectory);
const BUFFER_SIZE = 8192; let fullOutputFileName = PathUtils.join(outputDirectory, outputFileName);
// get a binary stream let outputStream = Cc[
let binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( "@mozilla.org/network/file-output-stream;1"
Ci.nsIBinaryInputStream ].createInstance(Ci.nsIFileOutputStream);
);
binaryStream.setInputStream(inputStream);
let outputDirectory = lazy.OS.Path.join( outputStream.init(
lazy.OS.Constants.Path.profileDir, new lazy.FileUtils.File(fullOutputFileName),
...subdirArray -1,
-1,
Ci.nsIFileOutputStream.DEFER_OPEN
); );
await lazy.OS.File.makeDir(outputDirectory, {
ignoreExisting: true, await new Promise(resolve =>
from: lazy.OS.Constants.Path.profileDir, lazy.NetUtil.asyncCopy(inputStream, outputStream, () => resolve())
}); );
let fullOutputFileName = lazy.OS.Path.join(outputDirectory, outputFileName);
let output = await lazy.OS.File.open(fullOutputFileName, { write: true }); outputStream.close();
try {
while (true) {
let available = binaryStream.available();
if (!available) {
break;
}
let chunk = binaryStream.readByteArray(
Math.min(available, BUFFER_SIZE)
);
await output.write(new Uint8Array(chunk));
}
} finally {
try {
binaryStream.close(); // inputStream is closed by the binaryStream
await output.close();
} catch (ex) {
log.error("Failed to close the input stream", ex);
}
}
log.trace("finished copy to", fullOutputFileName); log.trace("finished copy to", fullOutputFileName);
} }
} }
@ -420,7 +405,7 @@ LogManager.prototype = {
this._log.debug("Log cleanup threshold time: " + threshold); this._log.debug("Log cleanup threshold time: " + threshold);
let shouldDelete = fileInfo => { let shouldDelete = fileInfo => {
return fileInfo.lastModificationDate.getTime() < threshold; return fileInfo.lastModified < threshold;
}; };
return this._deleteLogFiles(shouldDelete); return this._deleteLogFiles(shouldDelete);
}, },
@ -440,46 +425,28 @@ LogManager.prototype = {
"ProfD", "ProfD",
this._logFileSubDirectoryEntries this._logFileSubDirectoryEntries
); );
let iterator = new lazy.OS.File.DirectoryIterator(logDir.path); for (const path of await IOUtils.getChildren(logDir.path)) {
const name = PathUtils.filename(path);
await iterator.forEach(async entry => { if (!name.startsWith("error-") && !name.startsWith("success-")) {
// Note that we don't check this.logFilePrefix is in the name - we cleanup continue;
// all files in this directory regardless of that prefix so old logfiles
// for prefixes no longer in use are still cleaned up. See bug 1279145.
if (
!entry.name.startsWith("error-") &&
!entry.name.startsWith("success-")
) {
return;
} }
try { try {
// need to call .stat() as the enumerator doesn't give that to us on *nix. const info = await IOUtils.stat(path);
let info = await lazy.OS.File.stat(entry.path);
if (!cbShouldDelete(info)) { if (!cbShouldDelete(info)) {
return; continue;
} }
this._log.trace(
" > Cleanup removing " + this._log.trace(` > Cleanup removing ${name} (${info.lastModified})`);
entry.name + await IOUtils.remove(path);
" (" + this._log.trace(`Deleted ${name}`);
info.lastModificationDate.getTime() +
")"
);
await lazy.OS.File.remove(entry.path);
this._log.trace("Deleted " + entry.name);
} catch (ex) { } catch (ex) {
this._log.debug( this._log.debug(
"Encountered error trying to clean up old log file " + entry.name, `Encountered error trying to clean up old log file ${name}`,
ex ex
); );
} }
});
// Wait for this to close if we need to (but it might fail if OS.File has
// shut down)
try {
await iterator.close();
} catch (e) {
this._log.warn("Failed to close directory iterator", e);
} }
this._cleaningUpFileLogs = false; this._cleaningUpFileLogs = false;
this._log.debug("Done deleting files."); this._log.debug("Done deleting files.");

View file

@ -12,7 +12,6 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
RemoteSettingsWorker: "resource://services-settings/RemoteSettingsWorker.jsm", RemoteSettingsWorker: "resource://services-settings/RemoteSettingsWorker.jsm",
Utils: "resource://services-settings/Utils.jsm", Utils: "resource://services-settings/Utils.jsm",
}); });
ChromeUtils.defineModuleGetter(lazy, "OS", "resource://gre/modules/osfile.jsm");
class DownloadError extends Error { class DownloadError extends Error {
constructor(url, resp) { constructor(url, resp) {
@ -313,16 +312,12 @@ class Downloader {
const { const {
attachment: { filename, size, hash }, attachment: { filename, size, hash },
} = record; } = record;
const localFilePath = lazy.OS.Path.join( const localFilePath = PathUtils.join(
lazy.OS.Constants.Path.localProfileDir, PathUtils.localProfileDir,
...this.folders, ...this.folders,
filename filename
); );
const localFileUrl = `file://${[ const localFileUrl = PathUtils.toFileURI(localFilePath);
...lazy.OS.Path.split(lazy.OS.Constants.Path.localProfileDir).components,
...this.folders,
filename,
].join("/")}`;
await this._makeDirs(); await this._makeDirs();
@ -413,8 +408,8 @@ class Downloader {
const { const {
attachment: { filename }, attachment: { filename },
} = record; } = record;
const path = lazy.OS.Path.join( const path = PathUtils.join(
lazy.OS.Constants.Path.localProfileDir, PathUtils.localProfileDir,
...this.folders, ...this.folders,
filename filename
); );
@ -500,17 +495,14 @@ class Downloader {
static _RESOURCE_BASE_URL = "resource://app/defaults"; static _RESOURCE_BASE_URL = "resource://app/defaults";
async _makeDirs() { async _makeDirs() {
const dirPath = lazy.OS.Path.join( const dirPath = PathUtils.join(PathUtils.localProfileDir, ...this.folders);
lazy.OS.Constants.Path.localProfileDir,
...this.folders
);
await IOUtils.makeDirectory(dirPath, { createAncestors: true }); await IOUtils.makeDirectory(dirPath, { createAncestors: true });
} }
async _rmDirs() { async _rmDirs() {
for (let i = this.folders.length; i > 0; i--) { for (let i = this.folders.length; i > 0; i--) {
const dirPath = lazy.OS.Path.join( const dirPath = PathUtils.join(
lazy.OS.Constants.Path.localProfileDir, PathUtils.localProfileDir,
...this.folders.slice(0, i) ...this.folders.slice(0, i)
); );
try { try {

View file

@ -12,7 +12,6 @@ const { Downloader } = ChromeUtils.import(
const { TelemetryTestUtils } = ChromeUtils.importESModule( const { TelemetryTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/TelemetryTestUtils.sys.mjs" "resource://testing-common/TelemetryTestUtils.sys.mjs"
); );
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
const RECORD = { const RECORD = {
id: "1f3a0802-648d-11ea-bd79-876a8b69c377", id: "1f3a0802-648d-11ea-bd79-876a8b69c377",
@ -46,9 +45,7 @@ function pathFromURL(url) {
return file.path; return file.path;
} }
const PROFILE_URL = const PROFILE_URL = PathUtils.toFileURI(PathUtils.localProfileDir);
"file://" +
OS.Path.split(OS.Constants.Path.localProfileDir).components.join("/");
function run_test() { function run_test() {
server = new HttpServer(); server = new HttpServer();
@ -156,7 +153,7 @@ add_task(async function test_download_writes_file_in_profile() {
Assert.equal( Assert.equal(
fileURL, fileURL,
PROFILE_URL + "/settings/main/some-collection/test_file.pem" PROFILE_URL + "settings/main/some-collection/test_file.pem"
); );
Assert.ok(await IOUtils.exists(localFilePath)); Assert.ok(await IOUtils.exists(localFilePath));
const stat = await IOUtils.stat(localFilePath); const stat = await IOUtils.stat(localFilePath);
@ -265,8 +262,8 @@ add_task(async function test_delete_removes_local_file() {
Assert.ok(!(await IOUtils.exists(localFilePath))); Assert.ok(!(await IOUtils.exists(localFilePath)));
// And removes parent folders. // And removes parent folders.
const parentFolder = OS.Path.join( const parentFolder = PathUtils.join(
OS.Constants.Path.localProfileDir, PathUtils.localProfileDir,
...downloader.folders ...downloader.folders
); );
Assert.ok(!(await IOUtils.exists(parentFolder))); Assert.ok(!(await IOUtils.exists(parentFolder)));
@ -295,13 +292,13 @@ add_task(async function test_downloader_is_accessible_via_client() {
Assert.equal( Assert.equal(
fileURL, fileURL,
[ PROFILE_URL +
PROFILE_URL, [
"settings", "settings",
client.bucketName, client.bucketName,
client.collectionName, client.collectionName,
RECORD.attachment.filename, RECORD.attachment.filename,
].join("/") ].join("/")
); );
}); });
add_task(clear_state); add_task(clear_state);