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

Fully remove helmCli, move associated variable to vars

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-03-01 11:38:53 -05:00
parent f1b0a6f699
commit d1a7e034d7
9 changed files with 50 additions and 93 deletions

View File

@ -75,6 +75,11 @@ export const baseBinariesDir = onceCell(() => (
) )
)); ));
export const helmBinaryName = getBinaryName("helm");
export const helmBinaryPath = onceCell(() => path.join(baseBinariesDir.get(), helmBinaryName));
export const kubectlBinaryName = getBinaryName("kubectl");
export const kubectlBinaryPath = onceCell(() => path.join(baseBinariesDir.get(), kubectlBinaryName));
// Webpack build paths // Webpack build paths
export const contextDir = process.cwd(); export const contextDir = process.cwd();
export const buildDir = path.join(contextDir, "static", publicPath); export const buildDir = path.join(contextDir, "static", publicPath);

23
src/main/helm/exec.ts Normal file
View File

@ -0,0 +1,23 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { promiseExecFile } from "../../common/utils/promise-exec";
import type { BaseEncodingOptions } from "fs";
import type { ExecFileOptions } from "child_process";
import { helmBinaryPath } from "../../common/vars";
/**
* ExecFile the bundled helm CLI
* @returns STDOUT
*/
export async function execHelm(args: string[], options?: BaseEncodingOptions & ExecFileOptions): Promise<string> {
try {
const { stdout } = await promiseExecFile(helmBinaryPath.get(), args, options);
return stdout;
} catch (error) {
throw error?.stderr || error;
}
}

View File

@ -8,10 +8,9 @@ import v8 from "v8";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import type { HelmRepo } from "./helm-repo-manager"; import type { HelmRepo } from "./helm-repo-manager";
import logger from "../logger"; import logger from "../logger";
import { promiseExecFile } from "../../common/utils/promise-exec";
import { helmCli } from "./helm-cli";
import type { RepoHelmChartList } from "../../common/k8s-api/endpoints/helm-charts.api"; import type { RepoHelmChartList } from "../../common/k8s-api/endpoints/helm-charts.api";
import { iter, sortCharts } from "../../common/utils"; import { iter, sortCharts } from "../../common/utils";
import { execHelm } from "./exec";
interface ChartCacheEntry { interface ChartCacheEntry {
data: Buffer; data: Buffer;
@ -49,21 +48,13 @@ export class HelmChartManager {
} }
private async executeCommand(args: string[], name: string, version?: string) { private async executeCommand(args: string[], name: string, version?: string) {
const helm = await helmCli.binaryPath();
args.push(`${this.repo.name}/${name}`); args.push(`${this.repo.name}/${name}`);
if (version) { if (version) {
args.push("--version", version); args.push("--version", version);
} }
try { return execHelm(args);
const { stdout } = await promiseExecFile(helm, args);
return stdout;
} catch (error) {
throw error.stderr || error;
}
} }
public async getReadme(name: string, version?: string) { public async getReadme(name: string, version?: string) {

View File

@ -1,22 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import path from "path";
import { onceCell } from "../../common/utils/once-cell";
import { baseBinariesDir, getBinaryName } from "../../common/vars";
export const helmBinaryPath = onceCell(() => path.join(baseBinariesDir.get(), getBinaryName("helm")));
/**
* @deprecated use `helmBinaryPath` or its injection equivalent instead
*/
export const helmCli = {
binaryPath: (): Promise<string> => Promise.resolve(helmBinaryPath.get()),
getBinaryPath: (): string => helmBinaryPath.get(),
getBinaryDir: (): string => baseBinariesDir.get(),
setLogger: (logger: any): void => void logger,
ensureBinary: (): Promise<void> => Promise.resolve(),
};

View File

@ -6,23 +6,9 @@
import tempy from "tempy"; import tempy from "tempy";
import fse from "fs-extra"; import fse from "fs-extra";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import { promiseExecFile } from "../../common/utils/promise-exec";
import { helmCli } from "./helm-cli";
import { toCamelCase } from "../../common/utils/camelCase"; import { toCamelCase } from "../../common/utils/camelCase";
import type { BaseEncodingOptions } from "fs"; import { execFile } from "child_process";
import { execFile, ExecFileOptions } from "child_process"; import { execHelm } from "./exec";
async function execHelm(args: string[], options?: BaseEncodingOptions & ExecFileOptions): Promise<string> {
const helmCliPath = await helmCli.binaryPath();
try {
const { stdout } = await promiseExecFile(helmCliPath, args, options);
return stdout;
} catch (error) {
throw error?.stderr || error;
}
}
export async function listReleases(pathToKubeconfig: string, namespace?: string): Promise<Record<string, any>[]> { export async function listReleases(pathToKubeconfig: string, namespace?: string): Promise<Record<string, any>[]> {
const args = [ const args = [

View File

@ -4,14 +4,12 @@
*/ */
import yaml from "js-yaml"; import yaml from "js-yaml";
import { BaseEncodingOptions, readFile } from "fs-extra"; import { readFile } from "fs-extra";
import { promiseExecFile } from "../../common/utils/promise-exec";
import { helmCli } from "./helm-cli";
import { Singleton } from "../../common/utils/singleton"; import { Singleton } from "../../common/utils/singleton";
import { customRequestPromise } from "../../common/request"; import { customRequestPromise } from "../../common/request";
import orderBy from "lodash/orderBy"; import orderBy from "lodash/orderBy";
import logger from "../logger"; import logger from "../logger";
import type { ExecFileOptions } from "child_process"; import { execHelm } from "./exec";
export type HelmEnv = Record<string, string> & { export type HelmEnv = Record<string, string> & {
HELM_REPOSITORY_CACHE?: string; HELM_REPOSITORY_CACHE?: string;
@ -34,18 +32,6 @@ export interface HelmRepo {
password?: string; password?: string;
} }
async function execHelm(args: string[], options?: BaseEncodingOptions & ExecFileOptions): Promise<string> {
const helmCliPath = await helmCli.binaryPath();
try {
const { stdout } = await promiseExecFile(helmCliPath, args, options);
return stdout;
} catch (error) {
throw error?.stderr || error;
}
}
export class HelmRepoManager extends Singleton { export class HelmRepoManager extends Singleton {
protected repos: HelmRepo[]; protected repos: HelmRepo[];
protected helmEnv: HelmEnv; protected helmEnv: HelmEnv;
@ -63,9 +49,6 @@ export class HelmRepoManager extends Singleton {
} }
private async ensureInitialized() { private async ensureInitialized() {
helmCli.setLogger(logger);
await helmCli.ensureBinary();
this.helmEnv ??= await this.parseHelmEnv(); this.helmEnv ??= await this.parseHelmEnv();
const repos = await this.list(); const repos = await this.list();

View File

@ -9,16 +9,14 @@ import { promiseExecFile } from "../../common/utils/promise-exec";
import logger from "../logger"; import logger from "../logger";
import { ensureDir, pathExists } from "fs-extra"; import { ensureDir, pathExists } from "fs-extra";
import * as lockFile from "proper-lockfile"; import * as lockFile from "proper-lockfile";
import { helmCli } from "../helm/helm-cli";
import { getBundledKubectlVersion } from "../../common/utils/app-version"; import { getBundledKubectlVersion } from "../../common/utils/app-version";
import { normalizedPlatform, normalizedArch, getBinaryName, baseBinariesDir } from "../../common/vars"; import { normalizedPlatform, normalizedArch, kubectlBinaryName, kubectlBinaryPath, baseBinariesDir } from "../../common/vars";
import { SemVer } from "semver"; import { SemVer } from "semver";
import { defaultPackageMirror, packageMirrors } from "../../common/user-store/preferences-helpers"; import { defaultPackageMirror, packageMirrors } from "../../common/user-store/preferences-helpers";
import got from "got/dist/source"; import got from "got/dist/source";
import { promisify } from "util"; import { promisify } from "util";
import stream from "stream"; import stream from "stream";
import { noop } from "lodash/fp"; import { noop } from "lodash/fp";
import { onceCell } from "../../common/utils/once-cell";
const bundledVersion = getBundledKubectlVersion(); const bundledVersion = getBundledKubectlVersion();
const kubectlMap: Map<string, string> = new Map([ const kubectlMap: Map<string, string> = new Map([
@ -40,13 +38,8 @@ const kubectlMap: Map<string, string> = new Map([
["1.22", "1.22.6"], ["1.22", "1.22.6"],
["1.23", bundledVersion], ["1.23", bundledVersion],
]); ]);
const binaryName = getBinaryName("kubectl");
const initScriptVersionString = "# lens-initscript v3"; const initScriptVersionString = "# lens-initscript v3";
export const bundledKubectlPath = onceCell(() => (
path.join(baseBinariesDir.get(), binaryName)
));
interface Dependencies { interface Dependencies {
directoryForKubectlBinaries: string; directoryForKubectlBinaries: string;
@ -89,13 +82,13 @@ export class Kubectl {
logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using fallback`); logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using fallback`);
} }
this.url = `${this.getDownloadMirror()}/v${this.kubectlVersion}/bin/${normalizedPlatform}/${normalizedArch}/${binaryName}`; this.url = `${this.getDownloadMirror()}/v${this.kubectlVersion}/bin/${normalizedPlatform}/${normalizedArch}/${kubectlBinaryName}`;
this.dirname = path.normalize(path.join(this.getDownloadDir(), this.kubectlVersion)); this.dirname = path.normalize(path.join(this.getDownloadDir(), this.kubectlVersion));
this.path = path.join(this.dirname, binaryName); this.path = path.join(this.dirname, kubectlBinaryName);
} }
public getBundledPath() { public getBundledPath() {
return bundledKubectlPath.get(); return kubectlBinaryPath.get();
} }
public getPathFromPreferences() { public getPathFromPreferences() {
@ -289,7 +282,7 @@ export class Kubectl {
? this.dirname ? this.dirname
: path.dirname(this.getPathFromPreferences()); : path.dirname(this.getPathFromPreferences());
const helmPath = helmCli.getBinaryDir(); const binariesDir = baseBinariesDir.get();
const bashScriptPath = path.join(this.dirname, ".bash_set_path"); const bashScriptPath = path.join(this.dirname, ".bash_set_path");
const bashScript = [ const bashScript = [
@ -303,7 +296,7 @@ export class Kubectl {
"elif test -f \"$HOME/.profile\"; then", "elif test -f \"$HOME/.profile\"; then",
" . \"$HOME/.profile\"", " . \"$HOME/.profile\"",
"fi", "fi",
`export PATH="${helmPath}:${kubectlPath}:$PATH"`, `export PATH="${binariesDir}:${kubectlPath}:$PATH"`,
'export KUBECONFIG="$tempkubeconfig"', 'export KUBECONFIG="$tempkubeconfig"',
`NO_PROXY=",\${NO_PROXY:-localhost},"`, `NO_PROXY=",\${NO_PROXY:-localhost},"`,
`NO_PROXY="\${NO_PROXY//,localhost,/,}"`, `NO_PROXY="\${NO_PROXY//,localhost,/,}"`,
@ -329,12 +322,12 @@ export class Kubectl {
// voodoo to replace any previous occurrences of kubectl path in the PATH // voodoo to replace any previous occurrences of kubectl path in the PATH
`kubectlpath="${kubectlPath}"`, `kubectlpath="${kubectlPath}"`,
`helmpath="${helmPath}"`, `binariesDir="${binariesDir}"`,
"p=\":$kubectlpath:\"", "p=\":$kubectlpath:\"",
"d=\":$PATH:\"", "d=\":$PATH:\"",
`d=\${d//$p/:}`, `d=\${d//$p/:}`,
`d=\${d/#:/}`, `d=\${d/#:/}`,
`export PATH="$helmpath:$kubectlpath:\${d/%:/}"`, `export PATH="$binariesDir:$kubectlpath:\${d/%:/}"`,
"export KUBECONFIG=\"$tempkubeconfig\"", "export KUBECONFIG=\"$tempkubeconfig\"",
`NO_PROXY=",\${NO_PROXY:-localhost},"`, `NO_PROXY=",\${NO_PROXY:-localhost},"`,
`NO_PROXY="\${NO_PROXY//,localhost,/,}"`, `NO_PROXY="\${NO_PROXY//,localhost,/,}"`,

View File

@ -5,12 +5,12 @@
import type WebSocket from "ws"; import type WebSocket from "ws";
import path from "path"; import path from "path";
import { helmCli } from "../../helm/helm-cli";
import { UserStore } from "../../../common/user-store"; import { UserStore } from "../../../common/user-store";
import type { Cluster } from "../../../common/cluster/cluster"; import type { Cluster } from "../../../common/cluster/cluster";
import type { ClusterId } from "../../../common/cluster-types"; import type { ClusterId } from "../../../common/cluster-types";
import { ShellSession } from "../shell-session"; import { ShellSession } from "../shell-session";
import type { Kubectl } from "../../kubectl/kubectl"; import type { Kubectl } from "../../kubectl/kubectl";
import { baseBinariesDir } from "../../../common/vars";
export class LocalShellSession extends ShellSession { export class LocalShellSession extends ShellSession {
ShellType = "shell"; ShellType = "shell";
@ -18,9 +18,9 @@ export class LocalShellSession extends ShellSession {
constructor(protected shellEnvModify: (clusterId: ClusterId, env: Record<string, string>) => Record<string, string>, kubectl: Kubectl, websocket: WebSocket, cluster: Cluster, terminalId: string) { constructor(protected shellEnvModify: (clusterId: ClusterId, env: Record<string, string>) => Record<string, string>, kubectl: Kubectl, websocket: WebSocket, cluster: Cluster, terminalId: string) {
super(kubectl, websocket, cluster, terminalId); super(kubectl, websocket, cluster, terminalId);
} }
protected getPathEntries(): string[] { protected getPathEntries(): string[] {
return [helmCli.getBinaryDir()]; return [baseBinariesDir.get()];
} }
protected get cwd(): string | undefined { protected get cwd(): string | undefined {
@ -40,17 +40,16 @@ export class LocalShellSession extends ShellSession {
} }
protected async getShellArgs(shell: string): Promise<string[]> { protected async getShellArgs(shell: string): Promise<string[]> {
const helmpath = helmCli.getBinaryDir();
const pathFromPreferences = UserStore.getInstance().kubectlBinariesPath || this.kubectl.getBundledPath(); const pathFromPreferences = UserStore.getInstance().kubectlBinariesPath || this.kubectl.getBundledPath();
const kubectlPathDir = UserStore.getInstance().downloadKubectlBinaries ? await this.kubectlBinDirP : path.dirname(pathFromPreferences); const kubectlPathDir = UserStore.getInstance().downloadKubectlBinaries ? await this.kubectlBinDirP : path.dirname(pathFromPreferences);
switch(path.basename(shell)) { switch(path.basename(shell)) {
case "powershell.exe": case "powershell.exe":
return ["-NoExit", "-command", `& {$Env:PATH="${helmpath};${kubectlPathDir};$Env:PATH"}`]; return ["-NoExit", "-command", `& {$Env:PATH="${baseBinariesDir.get()};${kubectlPathDir};$Env:PATH"}`];
case "bash": case "bash":
return ["--init-file", path.join(await this.kubectlBinDirP, ".bash_set_path")]; return ["--init-file", path.join(await this.kubectlBinDirP, ".bash_set_path")];
case "fish": case "fish":
return ["--login", "--init-command", `export PATH="${helmpath}:${kubectlPathDir}:$PATH"; export KUBECONFIG="${await this.kubeconfigPathP}"`]; return ["--login", "--init-command", `export PATH="${baseBinariesDir.get()}:${kubectlPathDir}:$PATH"; export KUBECONFIG="${await this.kubeconfigPathP}"`];
case "zsh": case "zsh":
return ["--login"]; return ["--login"];
default: default:

View File

@ -8,13 +8,12 @@ import { observer } from "mobx-react";
import { Input, InputValidators } from "../input"; import { Input, InputValidators } from "../input";
import { SubTitle } from "../layout/sub-title"; import { SubTitle } from "../layout/sub-title";
import { UserStore } from "../../../common/user-store"; import { UserStore } from "../../../common/user-store";
import { bundledKubectlPath } from "../../../main/kubectl/kubectl";
import { SelectOption, Select } from "../select"; import { SelectOption, Select } from "../select";
import { Switch } from "../switch"; import { Switch } from "../switch";
import { packageMirrors } from "../../../common/user-store/preferences-helpers"; import { packageMirrors } from "../../../common/user-store/preferences-helpers";
import directoryForBinariesInjectable import directoryForBinariesInjectable from "../../../common/app-paths/directory-for-binaries/directory-for-binaries.injectable";
from "../../../common/app-paths/directory-for-binaries/directory-for-binaries.injectable";
import { withInjectables } from "@ogre-tools/injectable-react"; import { withInjectables } from "@ogre-tools/injectable-react";
import { kubectlBinaryPath } from "../../../common/vars";
interface Dependencies { interface Dependencies {
defaultPathForKubectlBinaries: string; defaultPathForKubectlBinaries: string;
@ -80,7 +79,7 @@ const NonInjectedKubectlBinaries: React.FC<Dependencies> = observer(({ defaultPa
<SubTitle title="Path to kubectl binary" /> <SubTitle title="Path to kubectl binary" />
<Input <Input
theme="round-black" theme="round-black"
placeholder={bundledKubectlPath.get()} placeholder={kubectlBinaryPath.get()}
value={binariesPath} value={binariesPath}
validators={pathValidator} validators={pathValidator}
onChange={setBinariesPath} onChange={setBinariesPath}