mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
* Turn on strict mode in tsconfig.json - Add route, clusterRoute, and payloadValidatedClusterRoute helper functions to improve types with backend routes - Turn on the following new lints: - react/jsx-first-prop-new-line - react/jsx-wrap-multilines - react/jsx-one-expression-per-line - react/jsx-max-props-per-line - react/jsx-indent - react/jsx-indent-props Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix build Signed-off-by: Sebastian Malton <sebastian@malton.name> * Replace KubeObject scope strings with enum Signed-off-by: Sebastian Malton <sebastian@malton.name> * Revert package.json version changes Signed-off-by: Sebastian Malton <sebastian@malton.name> * revert move hostedCluster(Id) Signed-off-by: Sebastian Malton <sebastian@malton.name> * change some type param names to be not single letters Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove copy-extension-themes Signed-off-by: Sebastian Malton <sebastian@malton.name> * add new make clean action Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix build to not use webpack for generating types Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube-object-menu.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix select.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * revert move fileNameMigration to index Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix ref logic error Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix log-resource-selector.test.tsx tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-store.test.ts test by overriding createStorage to not touch file system Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cluster.test.ts tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube=api.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fixed hotbar-store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kubeconfig-manager.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cluster-role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix pods.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix delete-cluster-dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix daemonset.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix replicaset.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix statefulsets/dialog/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix replicasets/scale-dialog/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix deployments.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix deployments/scale/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cronjob.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix stateful-set.api.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix deployment.api.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix api-manager.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix statefulset.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix job.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix pods.store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix scroll-spy.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix hotbar-remove-command.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog-entity-registry.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix welcome.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix verify-that-all-routes-have-route-component.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix pod-tolerations.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * better fix for previous 3 fixes, plus also select.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube-object-menu.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix app-paths.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-tabs.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix isReactNode typing Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix sub-title.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix drawer.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix list-layout.tsx and header.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix error-boundary.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix upgrade-chart/store.ts and dock-tab.store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix install-chart/store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix edit-resource/store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix create-resource/store.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix namespace-select.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix namespace-select-filter.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix crd-list.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix wrong types for extensions Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix circular dependency Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix circular dependency on catalogCategoryRegistry Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix api-kube Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix type errors, most <Select /> errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * fixing more type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * some more fixing type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * convert all KubeApis to injectable with legacy global backups Signed-off-by: Sebastian Malton <sebastian@malton.name> * factor out into a common file all the exports Signed-off-by: Sebastian Malton <sebastian@malton.name> * convert all KubeObjectStores to injectable with legacy global backups Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix lint Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove unused legacy KubeApi globals Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix bad previous commit Signed-off-by: Sebastian Malton <sebastian@malton.name> * more crash fixing Signed-off-by: Sebastian Malton <sebastian@malton.name> * try and fix behavioural tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix sidebar-and-tab-navigation-for-core.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix sidebar-and-tab-navigation-for-extensions.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-using-application-menu.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make ThemeStore non-singleton and fix navigation-to-terminal-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * extensions.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix catalog-entity-registry.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-using-application-menu.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix log-resource-selector.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-tabs.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix delete-cluster-dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-kubernetes-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-editor-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-proxy-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-using-application-menu.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-application-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix dock-store.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix select.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix hotbar-remove-command.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix cluster-role-bindings/__tests__/dialog.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-extension-specific-preferences.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-telemetry-preferences.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix closing-preferences.test.tsx Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-editor-preferences.test.ts Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix navigation-to-proxy-preferences.test.ts - Fix other type errors too Signed-off-by: Sebastian Malton <sebastian@malton.name> * final tweaks Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add more tsconfig files, fix bug in <Catalog> - Make all of history, navigation injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * Convert all of kube-details-params/ and navigate/ to injectable - This fixes a runtime error that was encountered during testing Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix runtime errors on renderer - remove all static uses of `createPageParam` (and then removed the legacy global) - Made LensRendererExtension and LensMainExtension just used dependencies and not the getLegacyDi - Fixed circular dep in extension-loader Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move registerStore calls to after injectMany Signed-off-by: Sebastian Malton <sebastian@malton.name> * replace all the rest of the legacy uses of apiManager Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix stack overflow and cycles in DI Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix NamespaceSelectFilter not opening Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix WizardStep and AddNamespaceDialog Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix KubeApi's not being registered Signed-off-by: Sebastian Malton <sebastian@malton.name> * cleanup WindowManager Signed-off-by: Sebastian Malton <sebastian@malton.name> * Proper fix for Wizard, fix NamespaceStore.subscribe Signed-off-by: Sebastian Malton <sebastian@malton.name> * Rewrite withTooltip to be more type correct - Fixes mobx related "too many recursive actions" error - Change all the uses of withTooltips to be functional components Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add e2e test to cover kube api registration Signed-off-by: Sebastian Malton <sebastian@malton.name> * cleanup internal-commands Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove cast in <Animate> Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix command-palette e2e test Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix type error after rebase Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix test name Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix lint Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix code to help CodeQL scanner Signed-off-by: Sebastian Malton <sebastian@malton.name> * update intree extension lock files Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix build-extensions picking wrong @types/react Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix tests from rebase Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix type error Signed-off-by: Sebastian Malton <sebastian@malton.name> * Make KubeconfigSyncManager more injectable Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix crash in test mode for Dialog Signed-off-by: Sebastian Malton <sebastian@malton.name> * make Select snapshots deterministic Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix new type error Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix kube-object.store.test.ts typing Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix merge build issues Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix snapshots after merge Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix lint after merge Signed-off-by: Sebastian Malton <sebastian@malton.name> * reexport BaseKubeJsonApiObjectMetadata Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix typo in terminalSpawningPool Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove duplicate license header Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix typo to waitUntilDefined Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove iter use from getLegacyGlobalDiForExtensionApi Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove complex createStorage override Signed-off-by: Sebastian Malton <sebastian@malton.name> * override logger with mocks only when needed for tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove specialized overrideStore flags for getDiForUnitTesting Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove unnecessary | undefined types from the exactOptionalFieldTypes experiment Signed-off-by: Sebastian Malton <sebastian@malton.name> * use more descriptive name for local test mocks Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove unnecessary addition to 'make clean' target Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove oddity of KubeObjectStore.getById(undefined) being allowed Signed-off-by: Sebastian Malton <sebastian@malton.name> * rename KubeObject.getDescriptor in favour of name without fundemental JS meaning Signed-off-by: Sebastian Malton <sebastian@malton.name> * Simplify legacyRegisterApi when working in behaviour unit tests - Don't emit within main environment as there should be no auto registering there Signed-off-by: Sebastian Malton <sebastian@malton.name> * change confusing variable name in ReactiveDuration Signed-off-by: Sebastian Malton <sebastian@malton.name> * make visitor pattern more explicit for Entity contextMenuOpen Signed-off-by: Sebastian Malton <sebastian@malton.name> * toggleDetails -> toggleKubeDetailsPane is more specific Signed-off-by: Sebastian Malton <sebastian@malton.name> * remove outdated comment Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix bug where LensExtension dependencies are not set Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests from the revert of react 18 Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix more tests from merge Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix typings with new is-compatible-extension tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * more type fixing Signed-off-by: Sebastian Malton <sebastian@malton.name> * Revert in-tree extension versions Signed-off-by: Sebastian Malton <sebastian@malton.name> * Improve name of guarding injectable for stores and apis - New name better implies that it is just a guard state and does not do anything Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add helper for <Select>.isMulti for storing in a Set<Value> Signed-off-by: Sebastian Malton <sebastian@malton.name> * fix is-compatible-extension.test.ts types Signed-off-by: Sebastian Malton <sebastian@malton.name>
358 lines
11 KiB
TypeScript
358 lines
11 KiB
TypeScript
/**
|
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
*/
|
|
|
|
import path from "path";
|
|
import fs from "fs";
|
|
import { promiseExecFile } from "../../common/utils/promise-exec";
|
|
import logger from "../logger";
|
|
import { ensureDir, pathExists } from "fs-extra";
|
|
import * as lockFile from "proper-lockfile";
|
|
import { getBundledKubectlVersion } from "../../common/utils/app-version";
|
|
import { normalizedPlatform, normalizedArch, kubectlBinaryName, kubectlBinaryPath, baseBinariesDir } from "../../common/vars";
|
|
import { SemVer } from "semver";
|
|
import { defaultPackageMirror, packageMirrors } from "../../common/user-store/preferences-helpers";
|
|
import got from "got/dist/source";
|
|
import { promisify } from "util";
|
|
import stream from "stream";
|
|
import { noop } from "lodash/fp";
|
|
|
|
const bundledVersion = getBundledKubectlVersion();
|
|
const kubectlMap: Map<string, string> = new Map([
|
|
["1.7", "1.8.15"],
|
|
["1.8", "1.9.10"],
|
|
["1.9", "1.10.13"],
|
|
["1.10", "1.11.10"],
|
|
["1.11", "1.12.10"],
|
|
["1.12", "1.13.12"],
|
|
["1.13", "1.13.12"],
|
|
["1.14", "1.14.10"],
|
|
["1.15", "1.15.11"],
|
|
["1.16", "1.16.15"],
|
|
["1.17", "1.17.17"],
|
|
["1.18", "1.18.20"],
|
|
["1.19", "1.19.12"],
|
|
["1.20", "1.20.8"],
|
|
["1.21", "1.21.9"],
|
|
["1.22", "1.22.6"],
|
|
["1.23", bundledVersion],
|
|
]);
|
|
const initScriptVersionString = "# lens-initscript v3";
|
|
|
|
interface Dependencies {
|
|
directoryForKubectlBinaries: string;
|
|
|
|
userStore: {
|
|
kubectlBinariesPath?: string;
|
|
downloadBinariesPath?: string;
|
|
downloadKubectlBinaries: boolean;
|
|
downloadMirror: string;
|
|
};
|
|
}
|
|
|
|
export class Kubectl {
|
|
public kubectlVersion: string;
|
|
protected url: string;
|
|
protected path: string;
|
|
protected dirname: string;
|
|
|
|
public static readonly bundledKubectlVersion = bundledVersion;
|
|
public static invalidBundle = false;
|
|
|
|
constructor(private dependencies: Dependencies, clusterVersion: string) {
|
|
let version: SemVer;
|
|
|
|
try {
|
|
version = new SemVer(clusterVersion, { includePrerelease: false });
|
|
} catch {
|
|
version = new SemVer(Kubectl.bundledKubectlVersion);
|
|
}
|
|
|
|
const fromMajorMinor = kubectlMap.get(`${version.major}.${version.minor}`);
|
|
|
|
/**
|
|
* minorVersion is the first two digits of kube server version if the version map includes that,
|
|
* use that version, if not, fallback to the exact x.y.z of kube version
|
|
*/
|
|
if (fromMajorMinor) {
|
|
this.kubectlVersion = fromMajorMinor;
|
|
logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using version map`);
|
|
} else {
|
|
this.kubectlVersion = version.format();
|
|
logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using fallback`);
|
|
}
|
|
|
|
this.url = `${this.getDownloadMirror()}/v${this.kubectlVersion}/bin/${normalizedPlatform}/${normalizedArch}/${kubectlBinaryName}`;
|
|
this.dirname = path.normalize(path.join(this.getDownloadDir(), this.kubectlVersion));
|
|
this.path = path.join(this.dirname, kubectlBinaryName);
|
|
}
|
|
|
|
public getBundledPath() {
|
|
return kubectlBinaryPath.get();
|
|
}
|
|
|
|
public getPathFromPreferences() {
|
|
return this.dependencies.userStore.kubectlBinariesPath || this.getBundledPath();
|
|
}
|
|
|
|
protected getDownloadDir() {
|
|
if (this.dependencies.userStore.downloadBinariesPath) {
|
|
return path.join(this.dependencies.userStore.downloadBinariesPath, "kubectl");
|
|
}
|
|
|
|
return this.dependencies.directoryForKubectlBinaries;
|
|
}
|
|
|
|
public getPath = async (bundled = false): Promise<string> => {
|
|
if (bundled) {
|
|
return this.getBundledPath();
|
|
}
|
|
|
|
if (this.dependencies.userStore.downloadKubectlBinaries === false) {
|
|
return this.getPathFromPreferences();
|
|
}
|
|
|
|
// return binary name if bundled path is not functional
|
|
if (!await this.checkBinary(this.getBundledPath(), false)) {
|
|
Kubectl.invalidBundle = true;
|
|
|
|
return path.basename(this.getBundledPath());
|
|
}
|
|
|
|
try {
|
|
if (!await this.ensureKubectl()) {
|
|
logger.error("Failed to ensure kubectl, fallback to the bundled version");
|
|
|
|
return this.getBundledPath();
|
|
}
|
|
|
|
return this.path;
|
|
} catch (err) {
|
|
logger.error("Failed to ensure kubectl, fallback to the bundled version");
|
|
logger.error(err);
|
|
|
|
return this.getBundledPath();
|
|
}
|
|
};
|
|
|
|
public async binDir() {
|
|
try {
|
|
await this.ensureKubectl();
|
|
await this.writeInitScripts();
|
|
|
|
return this.dirname;
|
|
} catch (err) {
|
|
logger.error(err);
|
|
|
|
return "";
|
|
}
|
|
}
|
|
|
|
public async checkBinary(path: string, checkVersion = true) {
|
|
const exists = await pathExists(path);
|
|
|
|
if (exists) {
|
|
try {
|
|
const args = [
|
|
"version",
|
|
"--client", "true",
|
|
"--output", "json",
|
|
];
|
|
const { stdout } = await promiseExecFile(path, args);
|
|
const output = JSON.parse(stdout);
|
|
|
|
if (!checkVersion) {
|
|
return true;
|
|
}
|
|
let version: string = output.clientVersion.gitVersion;
|
|
|
|
if (version[0] === "v") {
|
|
version = version.slice(1);
|
|
}
|
|
|
|
if (version === this.kubectlVersion) {
|
|
logger.debug(`Local kubectl is version ${this.kubectlVersion}`);
|
|
|
|
return true;
|
|
}
|
|
logger.error(`Local kubectl is version ${version}, expected ${this.kubectlVersion}, unlinking`);
|
|
} catch (error) {
|
|
logger.error(`Local kubectl failed to run properly (${error}), unlinking`);
|
|
}
|
|
await fs.promises.unlink(this.path);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected async checkBundled(): Promise<boolean> {
|
|
if (this.kubectlVersion === Kubectl.bundledKubectlVersion) {
|
|
try {
|
|
const exist = await pathExists(this.path);
|
|
|
|
if (!exist) {
|
|
await fs.promises.copyFile(this.getBundledPath(), this.path);
|
|
await fs.promises.chmod(this.path, 0o755);
|
|
}
|
|
|
|
return true;
|
|
} catch (err) {
|
|
logger.error(`Could not copy the bundled kubectl to app-data: ${err}`);
|
|
|
|
return false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async ensureKubectl(): Promise<boolean> {
|
|
if (this.dependencies.userStore.downloadKubectlBinaries === false) {
|
|
return true;
|
|
}
|
|
|
|
if (Kubectl.invalidBundle) {
|
|
logger.error(`Detected invalid bundle binary, returning ...`);
|
|
|
|
return false;
|
|
}
|
|
|
|
await ensureDir(this.dirname, 0o755);
|
|
|
|
try {
|
|
const release = await lockFile.lock(this.dirname);
|
|
|
|
logger.debug(`Acquired a lock for ${this.kubectlVersion}`);
|
|
const bundled = await this.checkBundled();
|
|
let isValid = await this.checkBinary(this.path, !bundled);
|
|
|
|
if (!isValid && !bundled) {
|
|
try {
|
|
await this.downloadKubectl();
|
|
} catch (error) {
|
|
logger.error(`[KUBECTL]: failed to download kubectl`, error);
|
|
logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
|
|
await release();
|
|
|
|
return false;
|
|
}
|
|
|
|
isValid = await this.checkBinary(this.path, false);
|
|
}
|
|
|
|
if (!isValid) {
|
|
logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
|
|
await release();
|
|
|
|
return false;
|
|
}
|
|
|
|
logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
|
|
await release();
|
|
|
|
return true;
|
|
} catch (error) {
|
|
logger.error(`[KUBECTL]: Failed to get a lock for ${this.kubectlVersion}`, error);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async downloadKubectl() {
|
|
await ensureDir(path.dirname(this.path), 0o755);
|
|
|
|
logger.info(`Downloading kubectl ${this.kubectlVersion} from ${this.url} to ${this.path}`);
|
|
|
|
const downloadStream = got.stream({ url: this.url, decompress: true });
|
|
const fileWriteStream = fs.createWriteStream(this.path, { mode: 0o755 });
|
|
const pipeline = promisify(stream.pipeline);
|
|
|
|
try {
|
|
await pipeline(downloadStream, fileWriteStream);
|
|
await fs.promises.chmod(this.path, 0o755);
|
|
logger.debug("kubectl binary download finished");
|
|
} catch (error) {
|
|
await fs.promises.unlink(this.path).catch(noop);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
protected async writeInitScripts() {
|
|
const kubectlPath = this.dependencies.userStore.downloadKubectlBinaries
|
|
? this.dirname
|
|
: path.dirname(this.getPathFromPreferences());
|
|
|
|
const binariesDir = baseBinariesDir.get();
|
|
|
|
const bashScriptPath = path.join(this.dirname, ".bash_set_path");
|
|
const bashScript = [
|
|
initScriptVersionString,
|
|
"tempkubeconfig=\"$KUBECONFIG\"",
|
|
"test -f \"/etc/profile\" && . \"/etc/profile\"",
|
|
"if test -f \"$HOME/.bash_profile\"; then",
|
|
" . \"$HOME/.bash_profile\"",
|
|
"elif test -f \"$HOME/.bash_login\"; then",
|
|
" . \"$HOME/.bash_login\"",
|
|
"elif test -f \"$HOME/.profile\"; then",
|
|
" . \"$HOME/.profile\"",
|
|
"fi",
|
|
`export PATH="${binariesDir}:${kubectlPath}:$PATH"`,
|
|
'export KUBECONFIG="$tempkubeconfig"',
|
|
`NO_PROXY=",\${NO_PROXY:-localhost},"`,
|
|
`NO_PROXY="\${NO_PROXY//,localhost,/,}"`,
|
|
`NO_PROXY="\${NO_PROXY//,127.0.0.1,/,}"`,
|
|
`NO_PROXY="localhost,127.0.0.1\${NO_PROXY%,}"`,
|
|
"export NO_PROXY",
|
|
"unset tempkubeconfig",
|
|
].join("\n");
|
|
|
|
const zshScriptPath = path.join(this.dirname, ".zlogin");
|
|
const zshScript = [
|
|
initScriptVersionString,
|
|
"tempkubeconfig=\"$KUBECONFIG\"",
|
|
|
|
// restore previous ZDOTDIR
|
|
"export ZDOTDIR=\"$OLD_ZDOTDIR\"",
|
|
|
|
// source all the files
|
|
"test -f \"$OLD_ZDOTDIR/.zshenv\" && . \"$OLD_ZDOTDIR/.zshenv\"",
|
|
"test -f \"$OLD_ZDOTDIR/.zprofile\" && . \"$OLD_ZDOTDIR/.zprofile\"",
|
|
"test -f \"$OLD_ZDOTDIR/.zlogin\" && . \"$OLD_ZDOTDIR/.zlogin\"",
|
|
"test -f \"$OLD_ZDOTDIR/.zshrc\" && . \"$OLD_ZDOTDIR/.zshrc\"",
|
|
|
|
// voodoo to replace any previous occurrences of kubectl path in the PATH
|
|
`kubectlpath="${kubectlPath}"`,
|
|
`binariesDir="${binariesDir}"`,
|
|
"p=\":$kubectlpath:\"",
|
|
"d=\":$PATH:\"",
|
|
`d=\${d//$p/:}`,
|
|
`d=\${d/#:/}`,
|
|
`export PATH="$binariesDir:$kubectlpath:\${d/%:/}"`,
|
|
"export KUBECONFIG=\"$tempkubeconfig\"",
|
|
`NO_PROXY=",\${NO_PROXY:-localhost},"`,
|
|
`NO_PROXY="\${NO_PROXY//,localhost,/,}"`,
|
|
`NO_PROXY="\${NO_PROXY//,127.0.0.1,/,}"`,
|
|
`NO_PROXY="localhost,127.0.0.1\${NO_PROXY%,}"`,
|
|
"export NO_PROXY",
|
|
"unset tempkubeconfig",
|
|
"unset OLD_ZDOTDIR",
|
|
].join("\n");
|
|
|
|
await Promise.all([
|
|
fs.promises.writeFile(bashScriptPath, bashScript, { mode: 0o644 }),
|
|
fs.promises.writeFile(zshScriptPath, zshScript, { mode: 0o644 }),
|
|
]);
|
|
}
|
|
|
|
protected getDownloadMirror(): string {
|
|
// MacOS packages are only available from default
|
|
|
|
const { url } = packageMirrors.get(this.dependencies.userStore.downloadMirror)
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
?? packageMirrors.get(defaultPackageMirror)!;
|
|
|
|
return url;
|
|
}
|
|
}
|