mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix kubeconfig-sync issues (#2692)
- Removed `getFreePort` as its use is always a race condition. Change all uses of it to retrive the port after listening - Added `getPortFrom` as a helper function to read a port from a stream - Remove `Cluster.ownerRef` as it is outdated and no longer needed for 5.0 - Remove `Cluster.enabled`, no longer needed because of above - Removed `Cluster.init`, moved its contents into `Cluster.constructor` as nothing in that function is asyncronous. Currently only being run on `main` as a stop gap until `renderer` gets its own version of `Cluster` - Refactored `LensProxy` so as to prevent `pty.node` (a NodeJS extension) being included in `webpack.extension.ts`'s run - Removed the passing around of the proxy port as that can now be accessed from an instance of `LensProxy` - purge ContextHandler's cache on disconnect Co-authored-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
bf96e6ef4c
commit
8fff064e0c
35 files changed
+563
-893
No files matched your search
@@ -4,6 +4,7 @@ import { LensApi } from "../lens-api";
|
||||
import { Cluster, ClusterMetadataKey } from "../cluster";
|
||||
import { ClusterPrometheusMetadata } from "../../common/cluster-store";
|
||||
import logger from "../logger";
|
||||
import { getMetrics } from "../k8s-request";
|
||||
|
||||
export type IMetricsQuery = string | string[] | {
|
||||
[metricName: string]: string;
|
||||
@@ -22,7 +23,7 @@ async function loadMetrics(promQueries: string[], cluster: Cluster, prometheusPa
|
||||
async function loadMetricHelper(): Promise<any> {
|
||||
for (const [attempt, lastAttempt] of ATTEMPTS.entries()) { // retry
|
||||
try {
|
||||
return await cluster.getMetrics(prometheusPath, { query, ...queryParams });
|
||||
return await getMetrics(cluster, prometheusPath, { query, ...queryParams });
|
||||
} catch (error) {
|
||||
if (lastAttempt || (error?.statusCode >= 400 && error?.statusCode < 500)) {
|
||||
logger.error("[Metrics]: metrics not available", { error });
|
||||
|
||||
@@ -2,48 +2,58 @@ import { LensApiRequest } from "../router";
|
||||
import { LensApi } from "../lens-api";
|
||||
import { spawn, ChildProcessWithoutNullStreams } from "child_process";
|
||||
import { Kubectl } from "../kubectl";
|
||||
import { getFreePort } from "../port";
|
||||
import { shell } from "electron";
|
||||
import * as tcpPortUsed from "tcp-port-used";
|
||||
import logger from "../logger";
|
||||
import { getPortFrom } from "../utils/get-port";
|
||||
|
||||
interface PortForwardArgs {
|
||||
clusterId: string;
|
||||
kind: string;
|
||||
namespace: string;
|
||||
name: string;
|
||||
port: string;
|
||||
}
|
||||
|
||||
const internalPortRegex = /^forwarding from (?<address>.+) ->/i;
|
||||
|
||||
class PortForward {
|
||||
public static portForwards: PortForward[] = [];
|
||||
|
||||
static getPortforward(forward: {clusterId: string; kind: string; name: string; namespace: string; port: string}) {
|
||||
return PortForward.portForwards.find((pf) => {
|
||||
return (
|
||||
pf.clusterId == forward.clusterId &&
|
||||
pf.kind == forward.kind &&
|
||||
pf.name == forward.name &&
|
||||
pf.namespace == forward.namespace &&
|
||||
pf.port == forward.port
|
||||
);
|
||||
});
|
||||
static getPortforward(forward: PortForwardArgs) {
|
||||
return PortForward.portForwards.find((pf) => (
|
||||
pf.clusterId == forward.clusterId &&
|
||||
pf.kind == forward.kind &&
|
||||
pf.name == forward.name &&
|
||||
pf.namespace == forward.namespace &&
|
||||
pf.port == forward.port
|
||||
));
|
||||
}
|
||||
|
||||
public clusterId: string;
|
||||
public process: ChildProcessWithoutNullStreams;
|
||||
public kubeConfig: string;
|
||||
public clusterId: string;
|
||||
public kind: string;
|
||||
public namespace: string;
|
||||
public name: string;
|
||||
public port: string;
|
||||
public localPort: number;
|
||||
public internalPort?: number;
|
||||
|
||||
constructor(obj: any) {
|
||||
Object.assign(this, obj);
|
||||
constructor(public kubeConfig: string, args: PortForwardArgs) {
|
||||
this.clusterId = args.clusterId;
|
||||
this.kind = args.kind;
|
||||
this.namespace = args.namespace;
|
||||
this.name = args.name;
|
||||
this.port = args.port;
|
||||
}
|
||||
|
||||
public async start() {
|
||||
this.localPort = await getFreePort();
|
||||
const kubectlBin = await Kubectl.bundled().getPath();
|
||||
const args = [
|
||||
"--kubeconfig", this.kubeConfig,
|
||||
"port-forward",
|
||||
"-n", this.namespace,
|
||||
`${this.kind}/${this.name}`,
|
||||
`${this.localPort}:${this.port}`
|
||||
`:${this.port}`
|
||||
];
|
||||
|
||||
this.process = spawn(kubectlBin, args, {
|
||||
@@ -58,8 +68,12 @@ class PortForward {
|
||||
}
|
||||
});
|
||||
|
||||
this.internalPort = await getPortFrom(this.process.stdout, {
|
||||
lineRegex: internalPortRegex,
|
||||
});
|
||||
|
||||
try {
|
||||
await tcpPortUsed.waitUntilUsed(this.localPort, 500, 15000);
|
||||
await tcpPortUsed.waitUntilUsed(this.internalPort, 500, 15000);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
@@ -70,7 +84,14 @@ class PortForward {
|
||||
}
|
||||
|
||||
public open() {
|
||||
shell.openExternal(`http://localhost:${this.localPort}`);
|
||||
shell.openExternal(`http://localhost:${this.internalPort}`)
|
||||
.catch(error => logger.error(`[PORT-FORWARD]: failed to open external shell: ${error}`, {
|
||||
clusterId: this.clusterId,
|
||||
port: this.port,
|
||||
kind: this.kind,
|
||||
namespace: this.namespace,
|
||||
name: this.name,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,13 +107,12 @@ class PortForwardRoute extends LensApi {
|
||||
|
||||
if (!portForward) {
|
||||
logger.info(`Creating a new port-forward ${namespace}/${resourceType}/${resourceName}:${port}`);
|
||||
portForward = new PortForward({
|
||||
portForward = new PortForward(await cluster.getProxyKubeconfigPath(), {
|
||||
clusterId: cluster.id,
|
||||
kind: resourceType,
|
||||
namespace,
|
||||
name: resourceName,
|
||||
port,
|
||||
kubeConfig: await cluster.getProxyKubeconfigPath()
|
||||
});
|
||||
const started = await portForward.start();
|
||||
|
||||
|
||||
Reference in new issue
Block a user