1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Broadcast cluster's disconnected state before stopping KubeAuthProxy (#4273)

This commit is contained in:
Sebastian Malton 2021-11-23 14:34:37 -05:00 committed by GitHub
parent 8c9e3b2fdc
commit 8081d35f9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 47 additions and 24 deletions

View File

@ -328,6 +328,8 @@ utils.describeIf(minikubeReady(TEST_NAMESPACE))("Minikube based tests", () => {
}, 10*60*1000); }, 10*60*1000);
afterEach(async () => { afterEach(async () => {
await frame.click(`[data-testid="sidebar-cluster-dropdown"]`);
await frame.click(`.Menu >> text="Disconnect"`);
await cleanup(); await cleanup();
}, 10*60*1000); }, 10*60*1000);
@ -337,6 +339,7 @@ utils.describeIf(minikubeReady(TEST_NAMESPACE))("Minikube based tests", () => {
await frame.waitForSelector(`.Menu >> text="Settings"`); await frame.waitForSelector(`.Menu >> text="Settings"`);
await frame.waitForSelector(`.Menu >> text="Disconnect"`); await frame.waitForSelector(`.Menu >> text="Disconnect"`);
await frame.waitForSelector(`.Menu >> text="Delete"`); await frame.waitForSelector(`.Menu >> text="Delete"`);
await frame.click(`[data-testid="sidebar-cluster-dropdown"]`);
}); });
it("should navigate around common cluster pages", async () => { it("should navigate around common cluster pages", async () => {

View File

@ -72,7 +72,12 @@ export async function start() {
...process.env, ...process.env,
}, },
timeout: 100_000, timeout: 100_000,
} as Parameters<typeof electron["launch"]>[0]); });
const cleanup = async () => {
await app.close();
await remove(CICD).catch(noop);
};
try { try {
const window = await getMainWindow(app); const window = await getMainWindow(app);
@ -80,14 +85,10 @@ export async function start() {
return { return {
app, app,
window, window,
cleanup: async () => { cleanup,
await app.close();
await remove(CICD).catch(noop);
},
}; };
} catch (error) { } catch (error) {
await app.close(); await cleanup();
await remove(CICD).catch(noop);
throw error; throw error;
} }
} }

View File

@ -36,6 +36,8 @@ jest.mock("winston", () => ({
label: jest.fn(), label: jest.fn(),
timestamp: jest.fn(), timestamp: jest.fn(),
printf: jest.fn(), printf: jest.fn(),
padLevels: jest.fn(),
ms: jest.fn(),
}, },
createLogger: jest.fn().mockReturnValue(logger), createLogger: jest.fn().mockReturnValue(logger),
transports: { transports: {
@ -49,12 +51,31 @@ jest.mock("../context-handler");
jest.mock("request"); jest.mock("request");
jest.mock("request-promise-native"); jest.mock("request-promise-native");
jest.mock("electron", () => ({
app: {
getVersion: () => "99.99.99",
getName: () => "lens",
setName: jest.fn(),
setPath: jest.fn(),
getPath: () => "tmp",
getLocale: () => "en",
setLoginItemSettings: jest.fn(),
},
ipcMain: {
on: jest.fn(),
once: jest.fn(),
handle: jest.fn(),
},
}));
import { Console } from "console"; import { Console } from "console";
import mockFs from "mock-fs"; import mockFs from "mock-fs";
import { AppPaths } from "../../common/app-paths";
import { Cluster } from "../cluster"; import { Cluster } from "../cluster";
import { Kubectl } from "../kubectl"; import { Kubectl } from "../kubectl";
console = new Console(process.stdout, process.stderr); // fix mockFS console = new Console(process.stdout, process.stderr); // fix mockFS
AppPaths.init();
describe("create clusters", () => { describe("create clusters", () => {
beforeEach(() => { beforeEach(() => {

View File

@ -42,6 +42,7 @@ jest.mock("electron", () => ({
}, },
ipcMain: { ipcMain: {
on: jest.fn(), on: jest.fn(),
once: jest.fn(),
handle: jest.fn(), handle: jest.fn(),
}, },
})); }));

View File

@ -34,7 +34,7 @@ import { DetectorRegistry } from "./cluster-detectors/detector-registry";
import plimit from "p-limit"; import plimit from "p-limit";
import type { ClusterState, ClusterRefreshOptions, ClusterMetricsResourceType, ClusterId, ClusterMetadata, ClusterModel, ClusterPreferences, ClusterPrometheusPreferences, UpdateClusterModel, KubeAuthUpdate } from "../common/cluster-types"; import type { ClusterState, ClusterRefreshOptions, ClusterMetricsResourceType, ClusterId, ClusterMetadata, ClusterModel, ClusterPreferences, ClusterPrometheusPreferences, UpdateClusterModel, KubeAuthUpdate } from "../common/cluster-types";
import { ClusterMetadataKey, initialNodeShellImage, ClusterStatus } from "../common/cluster-types"; import { ClusterMetadataKey, initialNodeShellImage, ClusterStatus } from "../common/cluster-types";
import { storedKubeConfigFolder, toJS } from "../common/utils"; import { disposer, storedKubeConfigFolder, toJS } from "../common/utils";
import type { Response } from "request"; import type { Response } from "request";
/** /**
@ -53,7 +53,7 @@ export class Cluster implements ClusterModel, ClusterState {
*/ */
public contextHandler: ContextHandler; public contextHandler: ContextHandler;
protected kubeconfigManager: KubeconfigManager; protected kubeconfigManager: KubeconfigManager;
protected eventDisposers: Function[] = []; protected eventDisposers = disposer();
protected activated = false; protected activated = false;
private resourceAccessStatuses: Map<KubeApiResource, boolean> = new Map(); private resourceAccessStatuses: Map<KubeApiResource, boolean> = new Map();
@ -324,15 +324,6 @@ export class Cluster implements ClusterModel, ClusterState {
this.getProxyKubeconfig(); this.getProxyKubeconfig();
} }
/**
* internal
*/
protected unbindEvents() {
logger.info(`[CLUSTER]: unbind events`, this.getMeta());
this.eventDisposers.forEach(dispose => dispose());
this.eventDisposers.length = 0;
}
/** /**
* @param force force activation * @param force force activation
* @internal * @internal
@ -395,8 +386,13 @@ export class Cluster implements ClusterModel, ClusterState {
* @internal * @internal
*/ */
@action disconnect() { @action disconnect() {
this.unbindEvents(); logger.info(`[CLUSTER]: disconnecting cluster`, { id: this.id });
ipcMain.once(`cluster:${this.id}:frame-removed`, () => {
this.contextHandler?.stopServer(); this.contextHandler?.stopServer();
});
this.eventDisposers();
this.disconnected = true; this.disconnected = true;
this.online = false; this.online = false;
this.accessible = false; this.accessible = false;
@ -405,7 +401,6 @@ export class Cluster implements ClusterModel, ClusterState {
this.allowedNamespaces = []; this.allowedNamespaces = [];
this.resourceAccessStatuses.clear(); this.resourceAccessStatuses.clear();
this.pushState(); this.pushState();
logger.info(`[CLUSTER]: disconnect`, this.getMeta());
} }
/** /**

View File

@ -129,11 +129,11 @@ export class KubeAuthProxy {
this.ready = false; this.ready = false;
if (this.proxyProcess) { if (this.proxyProcess) {
logger.debug("[KUBE-AUTH]: stopping local proxy", this.cluster.getMeta()); logger.info("[KUBE-AUTH]: stopping local proxy", { clusterId: this.cluster.id });
this.proxyProcess.kill();
this.proxyProcess.removeAllListeners(); this.proxyProcess.removeAllListeners();
this.proxyProcess.stderr.removeAllListeners(); this.proxyProcess.stderr.removeAllListeners();
this.proxyProcess.stdout.removeAllListeners(); this.proxyProcess.stdout.removeAllListeners();
this.proxyProcess.kill();
this.proxyProcess = null; this.proxyProcess = null;
} }
} }

View File

@ -21,6 +21,7 @@
import { action, IReactionDisposer, makeObservable, observable, when } from "mobx"; import { action, IReactionDisposer, makeObservable, observable, when } from "mobx";
import logger from "../../../main/logger"; import logger from "../../../main/logger";
import { broadcastMessage } from "../../../common/ipc";
import { clusterVisibilityHandler } from "../../../common/cluster-ipc"; import { clusterVisibilityHandler } from "../../../common/cluster-ipc";
import { ClusterStore } from "../../../common/cluster-store"; import { ClusterStore } from "../../../common/cluster-store";
import type { ClusterId } from "../../../common/cluster-types"; import type { ClusterId } from "../../../common/cluster-types";
@ -88,6 +89,7 @@ export class ClusterFrameHandler extends Singleton {
logger.info(`[LENS-VIEW]: remove dashboard, clusterId=${clusterId}`); logger.info(`[LENS-VIEW]: remove dashboard, clusterId=${clusterId}`);
this.views.delete(clusterId); this.views.delete(clusterId);
iframe.parentNode.removeChild(iframe); iframe.parentNode.removeChild(iframe);
broadcastMessage(`cluster:${clusterId}:frame-removed`);
dispose(); dispose();
}, },
); );