mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
commit
48188be37b
@ -2,7 +2,7 @@
|
|||||||
"name": "kontena-lens",
|
"name": "kontena-lens",
|
||||||
"productName": "Lens",
|
"productName": "Lens",
|
||||||
"description": "Lens - The Kubernetes IDE",
|
"description": "Lens - The Kubernetes IDE",
|
||||||
"version": "4.0.3",
|
"version": "4.0.4",
|
||||||
"main": "static/build/main.js",
|
"main": "static/build/main.js",
|
||||||
"copyright": "© 2020, Mirantis, Inc.",
|
"copyright": "© 2020, Mirantis, Inc.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -44,7 +44,7 @@
|
|||||||
"typedocs-extensions-api": "yarn run typedoc --ignoreCompilerErrors --readme docs/extensions/typedoc-readme.md.tpl --name @k8slens/extensions --out docs/extensions/api --mode library --excludePrivate --hideBreadcrumbs --includes src/ src/extensions/extension-api.ts"
|
"typedocs-extensions-api": "yarn run typedoc --ignoreCompilerErrors --readme docs/extensions/typedoc-readme.md.tpl --name @k8slens/extensions --out docs/extensions/api --mode library --excludePrivate --hideBreadcrumbs --includes src/ src/extensions/extension-api.ts"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"bundledKubectlVersion": "1.17.11",
|
"bundledKubectlVersion": "1.17.15",
|
||||||
"bundledHelmVersion": "3.3.4"
|
"bundledHelmVersion": "3.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@ -56,12 +56,12 @@ export class DistributionDetector extends BaseClusterDetector {
|
|||||||
return { value: "docker-desktop", accuracy: 80};
|
return { value: "docker-desktop", accuracy: 80};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isCustom()) {
|
if (this.isCustom() && await this.isOpenshift()) {
|
||||||
return { value: "custom", accuracy: 10};
|
return { value: "openshift", accuracy: 90};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await this.isOpenshift()) {
|
if (this.isCustom()) {
|
||||||
return { value: "openshift", accuracy: 90};
|
return { value: "custom", accuracy: 10};
|
||||||
}
|
}
|
||||||
|
|
||||||
return { value: "unknown", accuracy: 10};
|
return { value: "unknown", accuracy: 10};
|
||||||
@ -88,7 +88,7 @@ export class DistributionDetector extends BaseClusterDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected isAKS() {
|
protected isAKS() {
|
||||||
return this.cluster.apiUrl.endsWith("azmk8s.io");
|
return this.cluster.apiUrl.includes("azmk8s.io");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected isMirantis() {
|
protected isMirantis() {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { randomBytes } from "crypto";
|
import { randomBytes } from "crypto";
|
||||||
import { SHA256 } from "crypto-js";
|
import { SHA256 } from "crypto-js";
|
||||||
import { app } from "electron";
|
import { app, remote } from "electron";
|
||||||
import fse from "fs-extra";
|
import fse from "fs-extra";
|
||||||
import { action, observable, toJS } from "mobx";
|
import { action, observable, toJS } from "mobx";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
@ -31,7 +31,7 @@ export class FilesystemProvisionerStore extends BaseStore<FSProvisionModel> {
|
|||||||
if (!this.registeredExtensions.has(extensionName)) {
|
if (!this.registeredExtensions.has(extensionName)) {
|
||||||
const salt = randomBytes(32).toString("hex");
|
const salt = randomBytes(32).toString("hex");
|
||||||
const hashedName = SHA256(`${extensionName}/${salt}`).toString();
|
const hashedName = SHA256(`${extensionName}/${salt}`).toString();
|
||||||
const dirPath = path.resolve(app.getPath("userData"), "extension_data", hashedName);
|
const dirPath = path.resolve((app || remote.app).getPath("userData"), "extension_data", hashedName);
|
||||||
|
|
||||||
this.registeredExtensions.set(extensionName, dirPath);
|
this.registeredExtensions.set(extensionName, dirPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import "../common/system-ca";
|
|||||||
import "../common/prometheus-providers";
|
import "../common/prometheus-providers";
|
||||||
import * as Mobx from "mobx";
|
import * as Mobx from "mobx";
|
||||||
import * as LensExtensions from "../extensions/core-api";
|
import * as LensExtensions from "../extensions/core-api";
|
||||||
import { app, dialog } from "electron";
|
import { app, dialog, powerMonitor } from "electron";
|
||||||
import { appName } from "../common/vars";
|
import { appName } from "../common/vars";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { LensProxy } from "./lens-proxy";
|
import { LensProxy } from "./lens-proxy";
|
||||||
@ -59,6 +59,10 @@ app.on("ready", async () => {
|
|||||||
logger.info(`🚀 Starting Lens from "${workingDir}"`);
|
logger.info(`🚀 Starting Lens from "${workingDir}"`);
|
||||||
await shellSync();
|
await shellSync();
|
||||||
|
|
||||||
|
powerMonitor.on("shutdown", () => {
|
||||||
|
app.exit();
|
||||||
|
});
|
||||||
|
|
||||||
const updater = new AppUpdater();
|
const updater = new AppUpdater();
|
||||||
|
|
||||||
updater.start();
|
updater.start();
|
||||||
|
|||||||
@ -17,6 +17,10 @@ export class ApiManager {
|
|||||||
return Array.from(this.apis.values()).find(pathOrCallback ?? (() => true));
|
return Array.from(this.apis.values()).find(pathOrCallback ?? (() => true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getApiByKind(kind: string, apiVersion: string) {
|
||||||
|
return Array.from(this.apis.values()).find((api) => api.kind === kind && api.apiVersion === apiVersion);
|
||||||
|
}
|
||||||
|
|
||||||
registerApi(apiBase: string, api: KubeApi) {
|
registerApi(apiBase: string, api: KubeApi) {
|
||||||
if (!this.apis.has(apiBase)) {
|
if (!this.apis.has(apiBase)) {
|
||||||
this.apis.set(apiBase, api);
|
this.apis.set(apiBase, api);
|
||||||
|
|||||||
@ -79,6 +79,18 @@ export function forCluster<T extends KubeObject>(cluster: IKubeApiCluster, kubeC
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function ensureObjectSelfLink(api: KubeApi, object: KubeJsonApiData) {
|
||||||
|
if (!object.metadata.selfLink) {
|
||||||
|
object.metadata.selfLink = createKubeApiURL({
|
||||||
|
apiPrefix: api.apiPrefix,
|
||||||
|
apiVersion: api.apiVersionWithGroup,
|
||||||
|
resource: api.apiResource,
|
||||||
|
namespace: api.isNamespaced ? object.metadata.namespace : undefined,
|
||||||
|
name: object.metadata.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class KubeApi<T extends KubeObject = any> {
|
export class KubeApi<T extends KubeObject = any> {
|
||||||
static parseApi = parseKubeApi;
|
static parseApi = parseKubeApi;
|
||||||
|
|
||||||
@ -260,7 +272,11 @@ export class KubeApi<T extends KubeObject = any> {
|
|||||||
const KubeObjectConstructor = this.objectConstructor;
|
const KubeObjectConstructor = this.objectConstructor;
|
||||||
|
|
||||||
if (KubeObject.isJsonApiData(data)) {
|
if (KubeObject.isJsonApiData(data)) {
|
||||||
return new KubeObjectConstructor(data);
|
const object = new KubeObjectConstructor(data);
|
||||||
|
|
||||||
|
ensureObjectSelfLink(this, object);
|
||||||
|
|
||||||
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
// process items list response
|
// process items list response
|
||||||
@ -270,11 +286,17 @@ export class KubeApi<T extends KubeObject = any> {
|
|||||||
this.setResourceVersion(namespace, metadata.resourceVersion);
|
this.setResourceVersion(namespace, metadata.resourceVersion);
|
||||||
this.setResourceVersion("", metadata.resourceVersion);
|
this.setResourceVersion("", metadata.resourceVersion);
|
||||||
|
|
||||||
return items.map(item => new KubeObjectConstructor({
|
return items.map((item) => {
|
||||||
kind: this.kind,
|
const object = new KubeObjectConstructor({
|
||||||
apiVersion,
|
kind: this.kind,
|
||||||
...item,
|
apiVersion,
|
||||||
}));
|
...item,
|
||||||
|
});
|
||||||
|
|
||||||
|
ensureObjectSelfLink(this, object);
|
||||||
|
|
||||||
|
return object;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// custom apis might return array for list response, e.g. users, groups, etc.
|
// custom apis might return array for list response, e.g. users, groups, etc.
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { stringify } from "querystring";
|
|||||||
import { autobind, EventEmitter } from "../utils";
|
import { autobind, EventEmitter } from "../utils";
|
||||||
import { KubeJsonApiData } from "./kube-json-api";
|
import { KubeJsonApiData } from "./kube-json-api";
|
||||||
import type { KubeObjectStore } from "../kube-object.store";
|
import type { KubeObjectStore } from "../kube-object.store";
|
||||||
import { KubeApi } from "./kube-api";
|
import { ensureObjectSelfLink, KubeApi } from "./kube-api";
|
||||||
import { apiManager } from "./api-manager";
|
import { apiManager } from "./api-manager";
|
||||||
import { apiPrefix, isDevelopment } from "../../common/vars";
|
import { apiPrefix, isDevelopment } from "../../common/vars";
|
||||||
import { getHostedCluster } from "../../common/cluster-store";
|
import { getHostedCluster } from "../../common/cluster-store";
|
||||||
@ -158,12 +158,14 @@ export class KubeWatchApi {
|
|||||||
|
|
||||||
addListener(store: KubeObjectStore, callback: (evt: IKubeWatchEvent) => void) {
|
addListener(store: KubeObjectStore, callback: (evt: IKubeWatchEvent) => void) {
|
||||||
const listener = (evt: IKubeWatchEvent<KubeJsonApiData>) => {
|
const listener = (evt: IKubeWatchEvent<KubeJsonApiData>) => {
|
||||||
const { selfLink, namespace, resourceVersion } = evt.object.metadata;
|
const { namespace, resourceVersion } = evt.object.metadata;
|
||||||
const api = apiManager.getApi(selfLink);
|
const api = apiManager.getApiByKind(evt.object.kind, evt.object.apiVersion);
|
||||||
|
|
||||||
api.setResourceVersion(namespace, resourceVersion);
|
api.setResourceVersion(namespace, resourceVersion);
|
||||||
api.setResourceVersion("", resourceVersion);
|
api.setResourceVersion("", resourceVersion);
|
||||||
|
|
||||||
|
ensureObjectSelfLink(api, evt.object);
|
||||||
|
|
||||||
if (store == apiManager.getStore(api)) {
|
if (store == apiManager.getStore(api)) {
|
||||||
callback(evt);
|
callback(evt);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,7 +93,7 @@ export class CrdResources extends React.Component<Props> {
|
|||||||
isNamespaced && crdInstance.getNs(),
|
isNamespaced && crdInstance.getNs(),
|
||||||
...extraColumns.map(column => ({
|
...extraColumns.map(column => ({
|
||||||
renderBoolean: true,
|
renderBoolean: true,
|
||||||
children: jsonPath.value(crdInstance, column.jsonPath.slice(1)),
|
children: JSON.stringify(jsonPath.value(crdInstance, column.jsonPath.slice(1))),
|
||||||
})),
|
})),
|
||||||
crdInstance.getAge(),
|
crdInstance.getAge(),
|
||||||
]}
|
]}
|
||||||
|
|||||||
@ -195,10 +195,9 @@ export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemSt
|
|||||||
const items = this.items.toJS();
|
const items = this.items.toJS();
|
||||||
|
|
||||||
for (const {type, object} of this.eventsBuffer.clear()) {
|
for (const {type, object} of this.eventsBuffer.clear()) {
|
||||||
const { uid, selfLink } = object.metadata;
|
const index = items.findIndex(item => item.getId() === object.metadata?.uid);
|
||||||
const index = items.findIndex(item => item.getId() === uid);
|
|
||||||
const item = items[index];
|
const item = items[index];
|
||||||
const api = apiManager.getApi(selfLink);
|
const api = apiManager.getApiByKind(object.kind, object.apiVersion);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "ADDED":
|
case "ADDED":
|
||||||
|
|||||||
@ -2,10 +2,17 @@
|
|||||||
|
|
||||||
Here you can find description of changes we've built into each release. While we try our best to make each upgrade automatic and as smooth as possible, there may be some cases where you might need to do something to ensure the application works smoothly. So please read through the release highlights!
|
Here you can find description of changes we've built into each release. While we try our best to make each upgrade automatic and as smooth as possible, there may be some cases where you might need to do something to ensure the application works smoothly. So please read through the release highlights!
|
||||||
|
|
||||||
## 4.0.3 (current version)
|
## 4.0.4 (current version)
|
||||||
|
|
||||||
We are aware some users are encountering issues and regressions from previous version. Many of these issues are something we have not seen as part of our automated or manual testing process. To make it worse, some of them are really difficult to reproduce. We want to ensure we are putting all our energy and effort trying to resolve these issues. We hope you are patient. Expect to see new patch releases still in the coming days! Fixes in this version:
|
We are aware some users are encountering issues and regressions from previous version. Many of these issues are something we have not seen as part of our automated or manual testing process. To make it worse, some of them are really difficult to reproduce. We want to ensure we are putting all our energy and effort trying to resolve these issues. We hope you are patient. Expect to see new patch releases still in the coming days! Fixes in this version:
|
||||||
|
|
||||||
|
- Fix errors on Kubernetes v1.20
|
||||||
|
- Update bundled kubectl to v1.17.15
|
||||||
|
- Fix: MacOS error on shutdown
|
||||||
|
- Fix: Kubernetes distribution detection
|
||||||
|
- Fix: error while displaying CRDs with column which type is an object
|
||||||
|
## 4.0.3
|
||||||
|
|
||||||
- Fix: install in-tree extensions before others
|
- Fix: install in-tree extensions before others
|
||||||
- Fix: bundle all dependencies in in-tree extensions
|
- Fix: bundle all dependencies in in-tree extensions
|
||||||
- Fix: display error dialog if extensions couldn't be loaded
|
- Fix: display error dialog if extensions couldn't be loaded
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user