mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
commit
a9d2a9ea0d
@ -2,7 +2,7 @@
|
||||
"name": "kontena-lens",
|
||||
"productName": "Lens",
|
||||
"description": "Lens - The Kubernetes IDE",
|
||||
"version": "4.0.6",
|
||||
"version": "4.0.7",
|
||||
"main": "static/build/main.js",
|
||||
"copyright": "© 2020, Mirantis, Inc.",
|
||||
"license": "MIT",
|
||||
|
||||
@ -36,6 +36,13 @@ describe("workspace store tests", () => {
|
||||
expect(ws.getById(WorkspaceStore.defaultId)).not.toBe(null);
|
||||
});
|
||||
|
||||
it("default workspace should be enabled", () => {
|
||||
const ws = WorkspaceStore.getInstance<WorkspaceStore>();
|
||||
|
||||
expect(ws.workspaces.size).toBe(1);
|
||||
expect(ws.getById(WorkspaceStore.defaultId).enabled).toBe(true);
|
||||
});
|
||||
|
||||
it("cannot remove the default workspace", () => {
|
||||
const ws = WorkspaceStore.getInstance<WorkspaceStore>();
|
||||
|
||||
|
||||
@ -58,14 +58,7 @@ export class Workspace implements WorkspaceModel, WorkspaceState {
|
||||
* @observable
|
||||
*/
|
||||
@observable ownerRef?: string;
|
||||
/**
|
||||
* Is workspace enabled
|
||||
*
|
||||
* Workspaces that don't have ownerRef will be enabled by default. Workspaces with ownerRef need to explicitly enable a workspace.
|
||||
*
|
||||
* @observable
|
||||
*/
|
||||
@observable enabled: boolean;
|
||||
|
||||
/**
|
||||
* Last active cluster id
|
||||
*
|
||||
@ -73,6 +66,9 @@ export class Workspace implements WorkspaceModel, WorkspaceState {
|
||||
*/
|
||||
@observable lastActiveClusterId?: ClusterId;
|
||||
|
||||
|
||||
@observable private _enabled: boolean;
|
||||
|
||||
constructor(data: WorkspaceModel) {
|
||||
Object.assign(this, data);
|
||||
|
||||
@ -83,6 +79,21 @@ export class Workspace implements WorkspaceModel, WorkspaceState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is workspace enabled
|
||||
*
|
||||
* Workspaces that don't have ownerRef will be enabled by default. Workspaces with ownerRef need to explicitly enable a workspace.
|
||||
*
|
||||
* @observable
|
||||
*/
|
||||
get enabled(): boolean {
|
||||
return !this.isManaged || this._enabled;
|
||||
}
|
||||
|
||||
set enabled(enabled: boolean) {
|
||||
this._enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is workspace managed by an extension
|
||||
*/
|
||||
@ -134,10 +145,18 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
||||
static readonly defaultId: WorkspaceId = "default";
|
||||
private static stateRequestChannel = "workspace:states";
|
||||
|
||||
@observable currentWorkspaceId = WorkspaceStore.defaultId;
|
||||
@observable workspaces = observable.map<WorkspaceId, Workspace>();
|
||||
|
||||
private constructor() {
|
||||
super({
|
||||
configName: "lens-workspace-store",
|
||||
});
|
||||
|
||||
this.workspaces.set(WorkspaceStore.defaultId, new Workspace({
|
||||
id: WorkspaceStore.defaultId,
|
||||
name: "default"
|
||||
}));
|
||||
}
|
||||
|
||||
async load() {
|
||||
@ -186,15 +205,6 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
||||
ipcRenderer.removeAllListeners("workspace:state");
|
||||
}
|
||||
|
||||
@observable currentWorkspaceId = WorkspaceStore.defaultId;
|
||||
|
||||
@observable workspaces = observable.map<WorkspaceId, Workspace>({
|
||||
[WorkspaceStore.defaultId]: new Workspace({
|
||||
id: WorkspaceStore.defaultId,
|
||||
name: "default"
|
||||
})
|
||||
});
|
||||
|
||||
@computed get currentWorkspace(): Workspace {
|
||||
return this.getById(this.currentWorkspaceId);
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ export class ClusterManager extends Singleton {
|
||||
// auto-init clusters
|
||||
autorun(() => {
|
||||
clusterStore.enabledClustersList.forEach(cluster => {
|
||||
if (!cluster.initialized) {
|
||||
if (!cluster.initialized && !cluster.initializing) {
|
||||
logger.info(`[CLUSTER-MANAGER]: init cluster`, cluster.getMeta());
|
||||
cluster.init(port);
|
||||
}
|
||||
|
||||
@ -84,6 +84,14 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
whenInitialized = when(() => this.initialized);
|
||||
whenReady = when(() => this.ready);
|
||||
|
||||
/**
|
||||
* Is cluster object initializinng on-going
|
||||
*
|
||||
* @observable
|
||||
*/
|
||||
@observable initializing = false;
|
||||
|
||||
|
||||
/**
|
||||
* Is cluster object initialized
|
||||
*
|
||||
@ -273,6 +281,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
*/
|
||||
@action async init(port: number) {
|
||||
try {
|
||||
this.initializing = true;
|
||||
this.contextHandler = new ContextHandler(this);
|
||||
this.kubeconfigManager = await KubeconfigManager.create(this, this.contextHandler, port);
|
||||
this.kubeProxyUrl = `http://localhost:${port}${apiKubePrefix}`;
|
||||
@ -287,6 +296,8 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
id: this.id,
|
||||
error: err,
|
||||
});
|
||||
} finally {
|
||||
this.initializing = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -75,8 +75,8 @@ export class PrometheusLens implements PrometheusProvider {
|
||||
`sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}", status=~"${statuses}"}[${this.rateAccuracy}])) by (ingress)`;
|
||||
|
||||
return {
|
||||
bytesSentSuccess: bytesSent(opts.igress, "^2\\\\d*"),
|
||||
bytesSentFailure: bytesSent(opts.ingres, "^5\\\\d*"),
|
||||
bytesSentSuccess: bytesSent(opts.ingress, "^2\\\\d*"),
|
||||
bytesSentFailure: bytesSent(opts.ingress, "^5\\\\d*"),
|
||||
requestDurationSeconds: `sum(rate(nginx_ingress_controller_request_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)`,
|
||||
responseDurationSeconds: `sum(rate(nginx_ingress_controller_response_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)`
|
||||
};
|
||||
|
||||
@ -85,8 +85,8 @@ export class PrometheusOperator implements PrometheusProvider {
|
||||
`sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}", status=~"${statuses}"}[${this.rateAccuracy}])) by (ingress)`;
|
||||
|
||||
return {
|
||||
bytesSentSuccess: bytesSent(opts.igress, "^2\\\\d*"),
|
||||
bytesSentFailure: bytesSent(opts.ingres, "^5\\\\d*"),
|
||||
bytesSentSuccess: bytesSent(opts.ingress, "^2\\\\d*"),
|
||||
bytesSentFailure: bytesSent(opts.ingress, "^5\\\\d*"),
|
||||
requestDurationSeconds: `sum(rate(nginx_ingress_controller_request_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)`,
|
||||
responseDurationSeconds: `sum(rate(nginx_ingress_controller_response_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)`
|
||||
};
|
||||
|
||||
@ -75,8 +75,8 @@ export class PrometheusStacklight implements PrometheusProvider {
|
||||
`sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}", status=~"${statuses}"}[${this.rateAccuracy}])) by (ingress)`;
|
||||
|
||||
return {
|
||||
bytesSentSuccess: bytesSent(opts.igress, "^2\\\\d*"),
|
||||
bytesSentFailure: bytesSent(opts.ingres, "^5\\\\d*"),
|
||||
bytesSentSuccess: bytesSent(opts.ingress, "^2\\\\d*"),
|
||||
bytesSentFailure: bytesSent(opts.ingress, "^5\\\\d*"),
|
||||
requestDurationSeconds: `sum(rate(nginx_ingress_controller_request_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)`,
|
||||
responseDurationSeconds: `sum(rate(nginx_ingress_controller_response_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)`
|
||||
};
|
||||
|
||||
@ -10,7 +10,7 @@ import { workspaceStore } from "../common/workspace-store";
|
||||
import { preferencesURL } from "../renderer/components/+preferences/preferences.route";
|
||||
import { clusterViewURL } from "../renderer/components/cluster-manager/cluster-view.route";
|
||||
import logger from "./logger";
|
||||
import { isDevelopment } from "../common/vars";
|
||||
import { isDevelopment, isWindows } from "../common/vars";
|
||||
import { exitApp } from "./exit-app";
|
||||
|
||||
// note: instance of Tray should be saved somewhere, otherwise it disappears
|
||||
@ -29,7 +29,7 @@ export function initTray(windowManager: WindowManager) {
|
||||
try {
|
||||
const menu = createTrayMenu(windowManager);
|
||||
|
||||
buildTray(getTrayIcon(), menu);
|
||||
buildTray(getTrayIcon(), menu, windowManager);
|
||||
} catch (err) {
|
||||
logger.error(`[TRAY]: building failed: ${err}`);
|
||||
}
|
||||
@ -42,20 +42,25 @@ export function initTray(windowManager: WindowManager) {
|
||||
};
|
||||
}
|
||||
|
||||
export function buildTray(icon: string | NativeImage, menu: Menu) {
|
||||
function buildTray(icon: string | NativeImage, menu: Menu, windowManager: WindowManager) {
|
||||
if (!tray) {
|
||||
tray = new Tray(icon);
|
||||
tray.setToolTip(packageInfo.description);
|
||||
tray.setIgnoreDoubleClickEvents(true);
|
||||
}
|
||||
tray.setImage(icon);
|
||||
tray.setContextMenu(menu);
|
||||
|
||||
tray.setImage(icon);
|
||||
tray.setContextMenu(menu);
|
||||
if (isWindows) {
|
||||
tray.on("click", () => {
|
||||
windowManager.ensureMainWindow();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return tray;
|
||||
}
|
||||
|
||||
export function createTrayMenu(windowManager: WindowManager): Menu {
|
||||
function createTrayMenu(windowManager: WindowManager): Menu {
|
||||
return Menu.buildFromTemplate([
|
||||
{
|
||||
label: "About Lens",
|
||||
|
||||
@ -18,7 +18,7 @@ export const resourceApplierApi = {
|
||||
.post<KubeJsonApiData[]>("/stack", { data: resource })
|
||||
.then(data => {
|
||||
const items = data.map(obj => {
|
||||
const api = apiManager.getApi(obj.metadata.selfLink);
|
||||
const api = apiManager.getApiByKind(obj.kind, obj.apiVersion);
|
||||
|
||||
if (api) {
|
||||
return new api.objectConstructor(obj);
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
height: 18px; // Must be equal to lineHeight variable in pod-log-list.tsx
|
||||
font-family: $font-monospace;
|
||||
font-size: smaller;
|
||||
white-space: pre;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
background: $logRowHoverBackground;
|
||||
|
||||
@ -130,10 +130,17 @@ export class Terminal {
|
||||
fit = () => {
|
||||
// Since this function is debounced we need to read this value as late as possible
|
||||
if (!this.isActive) return;
|
||||
this.fitAddon.fit();
|
||||
const { cols, rows } = this.xterm;
|
||||
|
||||
this.api.sendTerminalSize(cols, rows);
|
||||
try {
|
||||
this.fitAddon.fit();
|
||||
const { cols, rows } = this.xterm;
|
||||
|
||||
this.api.sendTerminalSize(cols, rows);
|
||||
} catch(error) {
|
||||
console.error(error);
|
||||
|
||||
return; // see https://github.com/lensapp/lens/issues/1891
|
||||
}
|
||||
};
|
||||
|
||||
fitLazy = debounce(this.fit, 250);
|
||||
|
||||
@ -2,7 +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!
|
||||
|
||||
## 4.0.6 (current version)
|
||||
## 4.0.7 (current version)
|
||||
|
||||
- Fix: typo in Prometheus Ingress metrics
|
||||
- Fix: catch xterm.js fit error
|
||||
- Fix: Windows tray icon click
|
||||
- Fix: error on Kubernetes >= 1.20 on object edit
|
||||
- Fix: multiline log wrapping
|
||||
- Fix: prevent clusters from initializing multiple times
|
||||
- Fix: show default workspace on first boot
|
||||
|
||||
## 4.0.6
|
||||
|
||||
- Don't open Lens at OS login by default
|
||||
- Disable GPU acceleration by setting an env variable
|
||||
|
||||
@ -7756,9 +7756,9 @@ inherits@2.0.3:
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||
|
||||
init-package-json@^1.10.3:
|
||||
version "1.10.3"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user