mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
more work
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
d6177a64f2
commit
0660d74dad
@ -43,9 +43,9 @@ export class ExtensionInstaller {
|
|||||||
mode: 0o600
|
mode: 0o600
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info(`${logModule} installing dependencies at ${extensionPackagesRoot()}`);
|
logger.info(`${logModule}: installing dependencies at ${this.extensionPackagesRoot}`);
|
||||||
await this.npm(["install", "--no-audit", "--only=prod", "--prefer-offline", "--no-package-lock"]);
|
await this.npm(["install", "--no-audit", "--only=prod", "--prefer-offline", "--no-package-lock"]);
|
||||||
logger.info(`${logModule} dependencies installed at ${extensionPackagesRoot()}`);
|
logger.info(`${logModule}: dependencies installed at ${this.extensionPackagesRoot}`);
|
||||||
} finally {
|
} finally {
|
||||||
this.installLock.release();
|
this.installLock.release();
|
||||||
}
|
}
|
||||||
@ -59,9 +59,9 @@ export class ExtensionInstaller {
|
|||||||
await this.installLock.acquireAsync();
|
await this.installLock.acquireAsync();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.info(`${logModule} installing package from ${name} to ${extensionPackagesRoot()}`);
|
logger.info(`${logModule}: installing package from ${name} to ${this.extensionPackagesRoot}`);
|
||||||
await this.npm(["install", "--no-audit", "--only=prod", "--prefer-offline", "--no-package-lock", "--no-save", name]);
|
await this.npm(["install", "--no-audit", "--only=prod", "--prefer-offline", "--no-package-lock", "--no-save", name]);
|
||||||
logger.info(`${logModule} package ${name} installed to ${extensionPackagesRoot()}`);
|
logger.info(`${logModule}: package ${name} installed to ${this.extensionPackagesRoot}`);
|
||||||
} finally {
|
} finally {
|
||||||
this.installLock.release();
|
this.installLock.release();
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ export class ExtensionInstaller {
|
|||||||
private npm(args: string[]): Promise<void> {
|
private npm(args: string[]): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const child = child_process.fork(this.npmPath, args, {
|
const child = child_process.fork(this.npmPath, args, {
|
||||||
cwd: extensionPackagesRoot(),
|
cwd: this.extensionPackagesRoot,
|
||||||
silent: true,
|
silent: true,
|
||||||
env: {}
|
env: {}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import type { LensMainExtension } from "./lens-main-extension";
|
|||||||
import type { LensRendererExtension } from "./lens-renderer-extension";
|
import type { LensRendererExtension } from "./lens-renderer-extension";
|
||||||
import * as registries from "./registries";
|
import * as registries from "./registries";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
import { delay } from "../common/utils";
|
||||||
|
|
||||||
// lazy load so that we get correct userData
|
// lazy load so that we get correct userData
|
||||||
export function extensionPackagesRoot() {
|
export function extensionPackagesRoot() {
|
||||||
@ -87,7 +88,7 @@ export class ExtensionLoader {
|
|||||||
this.extensions.set(extension.id, extension);
|
this.extensions.set(extension.id, extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeInstance(lensExtensionId: LensExtensionId) {
|
async removeInstance(lensExtensionId: LensExtensionId) {
|
||||||
logger.info(`${logModule} deleting extension instance ${lensExtensionId}`);
|
logger.info(`${logModule} deleting extension instance ${lensExtensionId}`);
|
||||||
const instance = this.instances.get(lensExtensionId);
|
const instance = this.instances.get(lensExtensionId);
|
||||||
|
|
||||||
@ -96,13 +97,12 @@ export class ExtensionLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
instance.disable();
|
await Promise.race([instance.disable(), delay(15 * 1000)]); // allow at most 15s to disable the instace
|
||||||
this.events.emit("remove", instance);
|
this.events.emit("remove", instance);
|
||||||
this.instances.delete(lensExtensionId);
|
this.instances.delete(lensExtensionId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`${logModule}: deactivation extension error`, { lensExtensionId, error });
|
logger.error(`${logModule}: deactivation extension error`, { lensExtensionId, error });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeExtension(lensExtensionId: LensExtensionId) {
|
removeExtension(lensExtensionId: LensExtensionId) {
|
||||||
|
|||||||
@ -57,7 +57,7 @@ export class LensExtension {
|
|||||||
async enable() {
|
async enable() {
|
||||||
if (this.isEnabled) return;
|
if (this.isEnabled) return;
|
||||||
this.isEnabled = true;
|
this.isEnabled = true;
|
||||||
this.onActivate();
|
await this.onActivate();
|
||||||
logger.info(`[EXTENSION]: enabled ${this.name}@${this.version}`);
|
logger.info(`[EXTENSION]: enabled ${this.name}@${this.version}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ export class LensExtension {
|
|||||||
async disable() {
|
async disable() {
|
||||||
if (!this.isEnabled) return;
|
if (!this.isEnabled) return;
|
||||||
this.isEnabled = false;
|
this.isEnabled = false;
|
||||||
this.onDeactivate();
|
await this.onDeactivate();
|
||||||
logger.info(`[EXTENSION]: disabled ${this.name}@${this.version}`);
|
logger.info(`[EXTENSION]: disabled ${this.name}@${this.version}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,11 +101,11 @@ export class LensExtension {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onActivate() {
|
protected onActivate(): Promise<void> | void {
|
||||||
// mock
|
// mock
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onDeactivate() {
|
protected onDeactivate(): Promise<void> | void {
|
||||||
// mock
|
// mock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,9 @@ type CachedYaml = {
|
|||||||
|
|
||||||
export class HelmChartManager {
|
export class HelmChartManager {
|
||||||
protected cache: any = {};
|
protected cache: any = {};
|
||||||
protected repo: HelmRepo;
|
|
||||||
|
|
||||||
constructor(repo: HelmRepo){
|
constructor(protected repo: HelmRepo){
|
||||||
this.cache = HelmRepoManager.cache;
|
this.cache = HelmRepoManager.cache;
|
||||||
this.repo = repo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async chart(name: string) {
|
public async chart(name: string) {
|
||||||
|
|||||||
@ -46,6 +46,10 @@ function parseLensExtensionManifest(buf: Buffer): LensExtensionManifest {
|
|||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function notifyOnAction(displayName: string, action: string): void {
|
||||||
|
Notifications.ok(<p>Extension <b>{displayName}</b> successfully {action}!</p>);
|
||||||
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class Extensions extends React.Component {
|
export class Extensions extends React.Component {
|
||||||
private static supportedFormats = ["tar", "tgz"];
|
private static supportedFormats = ["tar", "tgz"];
|
||||||
@ -95,9 +99,7 @@ export class Extensions extends React.Component {
|
|||||||
disposeOnUnmount(this,
|
disposeOnUnmount(this,
|
||||||
reaction(() => this.extensions, () => {
|
reaction(() => this.extensions, () => {
|
||||||
this.removedUninstalling.forEach(({ id, displayName }) => {
|
this.removedUninstalling.forEach(({ id, displayName }) => {
|
||||||
Notifications.ok(
|
notifyOnAction(displayName, "uninstalled");
|
||||||
<p>Extension <b>{displayName}</b> successfully uninstalled!</p>
|
|
||||||
);
|
|
||||||
this.extensionStateStore.extensionState.delete(id);
|
this.extensionStateStore.extensionState.delete(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -108,9 +110,7 @@ export class Extensions extends React.Component {
|
|||||||
throw new Error("Extension not found");
|
throw new Error("Extension not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
Notifications.ok(
|
notifyOnAction(displayName, "installed");
|
||||||
<p>Extension <b>{displayName}</b> successfully installed!</p>
|
|
||||||
);
|
|
||||||
this.extensionStateStore.extensionState.delete(id);
|
this.extensionStateStore.extensionState.delete(id);
|
||||||
this.installPath = "";
|
this.installPath = "";
|
||||||
|
|
||||||
@ -205,36 +205,33 @@ export class Extensions extends React.Component {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
async preloadExtensions(requests: InstallRequest[], { showError = true } = {}) {
|
async preloadExtensions(requests: InstallRequest[], { showError = true } = {}): Promise<InstallRequestPreloaded[]> {
|
||||||
const preloadedRequests = requests.filter(request => request.data);
|
const res = await Promise.all(
|
||||||
|
requests.map(async ({ data, fileName, filePath }) => {
|
||||||
|
if (data) {
|
||||||
|
return { data, fileName, filePath };
|
||||||
|
}
|
||||||
|
|
||||||
await Promise.all(
|
if (filePath) {
|
||||||
requests
|
|
||||||
.filter(request => !request.data && request.filePath)
|
|
||||||
.map(async request => {
|
|
||||||
try {
|
try {
|
||||||
const data = await fse.readFile(request.filePath);
|
return { data: await fse.readFile(filePath), fileName, filePath };
|
||||||
|
|
||||||
request.data = data;
|
|
||||||
preloadedRequests.push(request);
|
|
||||||
|
|
||||||
return request;
|
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
if (showError) {
|
if (showError) {
|
||||||
Notifications.error(`Error while reading "${request.filePath}": ${String(error)}`);
|
Notifications.error(`Error while reading "${filePath}": ${String(error)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
return preloadedRequests as InstallRequestPreloaded[];
|
return res.filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
async validatePackage(filePath: string): Promise<LensExtensionManifest> {
|
async validatePackage(filePath: string): Promise<LensExtensionManifest> {
|
||||||
const tarFiles = await listTarEntries(filePath);
|
const tarFiles = await listTarEntries(filePath);
|
||||||
|
|
||||||
// tarball from npm contains single root folder "package/*"
|
// tarball from npm contains single root folder "package/*"
|
||||||
const firstFile = tarFiles[0];
|
const [firstFile] = tarFiles;
|
||||||
|
|
||||||
if (!firstFile) {
|
if (!firstFile) {
|
||||||
throw new Error(`invalid extension bundle, ${manifestFilename} not found`);
|
throw new Error(`invalid extension bundle, ${manifestFilename} not found`);
|
||||||
@ -255,7 +252,7 @@ export class Extensions extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!manifest.lens && !manifest.renderer) {
|
if (!manifest.lens && !manifest.renderer) {
|
||||||
throw new Error(`${manifestFilename} must specify "main" and/or "renderer" fields`);
|
throw new Error(`${manifestFilename} must specify at least one of: ["main", "renderer"]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return manifest;
|
return manifest;
|
||||||
@ -267,11 +264,9 @@ export class Extensions extends React.Component {
|
|||||||
// copy files to temp
|
// copy files to temp
|
||||||
await fse.ensureDir(this.getExtensionPackageTemp());
|
await fse.ensureDir(this.getExtensionPackageTemp());
|
||||||
|
|
||||||
for (const request of requests) {
|
await Promise.all(
|
||||||
const tempFile = this.getExtensionPackageTemp(request.fileName);
|
requests.map(request => fse.writeFile(this.getExtensionPackageTemp(request.fileName), request.data))
|
||||||
|
);
|
||||||
await fse.writeFile(tempFile, request.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate packages
|
// validate packages
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user