mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add BundledExtensionUpdater class
Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
1 parent
0732346f6a
commit
9da3d06ce2
4 files changed
+137
No files matched your search
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { BundledExtensionUpdater } from "../bundled-extension-updater";
|
||||
import fs from "fs";
|
||||
import mockFs from "mock-fs";
|
||||
import nock from "nock";
|
||||
|
||||
const mockOpts = {
|
||||
"some-user-data-directory": {
|
||||
"some-file.tgz": "file content here",
|
||||
},
|
||||
"extension-updates": {
|
||||
"file.txt": "text",
|
||||
},
|
||||
};
|
||||
|
||||
describe("BundledExtensionUpdater", () => {
|
||||
afterEach(() => {
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it("Should download file from server", async () => {
|
||||
mockFs(mockOpts);
|
||||
|
||||
const scope = nock("http://my-example-url.com")
|
||||
.get("/node-menu-0.0.1.tgz")
|
||||
.replyWithFile(200, `./some-user-data-directory/some-file.tgz`, {
|
||||
"Content-Type": "application/tar",
|
||||
});
|
||||
|
||||
await new BundledExtensionUpdater({
|
||||
name: "node-menu",
|
||||
version: "0.0.1",
|
||||
downloadUrl: "http://my-example-url.com/node-menu-0.0.1.tgz",
|
||||
}, "./extension-updates").update();
|
||||
|
||||
const exist = await fs.promises.access(mockFs.bypass(() => "./extension-updates/node-menu-0.0.1.tgz"), fs.constants.F_OK);
|
||||
|
||||
expect(exist).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import { ensureDir } from "fs-extra";
|
||||
import request from "request";
|
||||
import logger from "../logger";
|
||||
import path from "path";
|
||||
import { noop } from "../../common/utils";
|
||||
|
||||
type Extension = {
|
||||
name: string
|
||||
version: string
|
||||
downloadUrl: string
|
||||
};
|
||||
|
||||
export class BundledExtensionUpdater {
|
||||
private extension: Extension;
|
||||
private updateFolderPath: string;
|
||||
|
||||
constructor(extension: Extension, updateFolderPath: string) {
|
||||
this.extension = extension;
|
||||
this.updateFolderPath = updateFolderPath;
|
||||
}
|
||||
|
||||
public async update() {
|
||||
await this.download();
|
||||
}
|
||||
|
||||
private get filePath() {
|
||||
return `${this.updateFolderPath}/${this.extension.name}-${this.extension.version}.tgz`;
|
||||
}
|
||||
|
||||
private async download() {
|
||||
const { downloadUrl, name } = this.extension;
|
||||
|
||||
await ensureDir(path.dirname(this.updateFolderPath), 0o755);
|
||||
|
||||
const file = fs.createWriteStream(this.filePath);
|
||||
|
||||
logger.info(`[EXTENSION-UPDATER]: Downloading extension ${name} from ${downloadUrl} to ${this.filePath}`);
|
||||
const requestOpts: request.UriOptions & request.CoreOptions = {
|
||||
uri: downloadUrl,
|
||||
gzip: true,
|
||||
};
|
||||
const stream = request.get(requestOpts);
|
||||
|
||||
stream.on("complete", () => {
|
||||
logger.info(`[EXTENSION-UPDATER]: Download extension ${name} tgz file completed`);
|
||||
file.end(noop);
|
||||
});
|
||||
|
||||
stream.on("error", (error) => {
|
||||
logger.error(error);
|
||||
fs.unlink(this.filePath, noop);
|
||||
throw error;
|
||||
});
|
||||
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
file.on("close", () => {
|
||||
logger.info(`[EXTENSION-UPDATER]: Download extension ${name} tgz file closed`);
|
||||
fs.chmod(downloadUrl, 0o755, (err) => {
|
||||
if (err) reject(err);
|
||||
});
|
||||
resolve();
|
||||
});
|
||||
stream.pipe(file);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user