From 277a0285067376440fa52488aa196e68cc86dbd8 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 5 Nov 2021 14:49:00 -0400 Subject: [PATCH] Broadcast cluster's disconnected state before stopping KubeAuthProxy Signed-off-by: Sebastian Malton --- src/main/__test__/cluster.test.ts | 21 +++++++++++++++++ .../__test__/kubeconfig-sync.test.ts | 1 + src/main/cluster.ts | 23 ++++++++----------- src/main/kube-auth-proxy.ts | 4 ++-- .../components/cluster-manager/lens-views.ts | 2 ++ 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/main/__test__/cluster.test.ts b/src/main/__test__/cluster.test.ts index ffd77da3d2..d2853b63d8 100644 --- a/src/main/__test__/cluster.test.ts +++ b/src/main/__test__/cluster.test.ts @@ -36,6 +36,8 @@ jest.mock("winston", () => ({ label: jest.fn(), timestamp: jest.fn(), printf: jest.fn(), + padLevels: jest.fn(), + ms: jest.fn(), }, createLogger: jest.fn().mockReturnValue(logger), transports: { @@ -49,12 +51,31 @@ jest.mock("../context-handler"); jest.mock("request"); 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 mockFs from "mock-fs"; +import { AppPaths } from "../../common/app-paths"; import { Cluster } from "../cluster"; import { Kubectl } from "../kubectl"; console = new Console(process.stdout, process.stderr); // fix mockFS +AppPaths.init(); describe("create clusters", () => { beforeEach(() => { diff --git a/src/main/catalog-sources/__test__/kubeconfig-sync.test.ts b/src/main/catalog-sources/__test__/kubeconfig-sync.test.ts index 5c3a7094ae..de18704049 100644 --- a/src/main/catalog-sources/__test__/kubeconfig-sync.test.ts +++ b/src/main/catalog-sources/__test__/kubeconfig-sync.test.ts @@ -42,6 +42,7 @@ jest.mock("electron", () => ({ }, ipcMain: { on: jest.fn(), + once: jest.fn(), handle: jest.fn(), }, })); diff --git a/src/main/cluster.ts b/src/main/cluster.ts index 1cbf4f980c..0ffb175a02 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -34,7 +34,7 @@ import { DetectorRegistry } from "./cluster-detectors/detector-registry"; import plimit from "p-limit"; 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 { storedKubeConfigFolder, toJS } from "../common/utils"; +import { disposer, storedKubeConfigFolder, toJS } from "../common/utils"; import type { Response } from "request"; /** @@ -53,7 +53,7 @@ export class Cluster implements ClusterModel, ClusterState { */ public contextHandler: ContextHandler; protected kubeconfigManager: KubeconfigManager; - protected eventDisposers: Function[] = []; + protected eventDisposers = disposer(); protected activated = false; private resourceAccessStatuses: Map = new Map(); @@ -324,15 +324,6 @@ export class Cluster implements ClusterModel, ClusterState { 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 * @internal @@ -395,8 +386,13 @@ export class Cluster implements ClusterModel, ClusterState { * @internal */ @action disconnect() { - this.unbindEvents(); - this.contextHandler?.stopServer(); + logger.info(`[CLUSTER]: disconnecting cluster`, { id: this.id }); + + ipcMain.once(`cluster:${this.id}:frame-removed`, () => { + this.contextHandler?.stopServer(); + }); + + this.eventDisposers(); this.disconnected = true; this.online = false; this.accessible = false; @@ -405,7 +401,6 @@ export class Cluster implements ClusterModel, ClusterState { this.allowedNamespaces = []; this.resourceAccessStatuses.clear(); this.pushState(); - logger.info(`[CLUSTER]: disconnect`, this.getMeta()); } /** diff --git a/src/main/kube-auth-proxy.ts b/src/main/kube-auth-proxy.ts index c52f97d4b1..e79c356ef7 100644 --- a/src/main/kube-auth-proxy.ts +++ b/src/main/kube-auth-proxy.ts @@ -129,11 +129,11 @@ export class KubeAuthProxy { this.ready = false; 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.stderr.removeAllListeners(); this.proxyProcess.stdout.removeAllListeners(); - this.proxyProcess.kill(); this.proxyProcess = null; } } diff --git a/src/renderer/components/cluster-manager/lens-views.ts b/src/renderer/components/cluster-manager/lens-views.ts index 947fa387f1..1c12a1843d 100644 --- a/src/renderer/components/cluster-manager/lens-views.ts +++ b/src/renderer/components/cluster-manager/lens-views.ts @@ -21,6 +21,7 @@ import { action, IReactionDisposer, makeObservable, observable, reaction, when } from "mobx"; import logger from "../../../main/logger"; +import { broadcastMessage } from "../../../common/ipc"; import { clusterVisibilityHandler } from "../../../common/cluster-ipc"; import { ClusterStore } from "../../../common/cluster-store"; import type { ClusterId } from "../../../common/cluster-types"; @@ -90,6 +91,7 @@ export class ClusterFrameHandler extends Singleton { logger.info(`[LENS-VIEW]: remove dashboard, clusterId=${clusterId}`); this.views.delete(clusterId); iframe.parentNode.removeChild(iframe); + broadcastMessage(`cluster:${clusterId}:frame-removed`); dispose(); }, );