mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Restructure to monorepo (#6907)
* wip: restructure to monorepo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor create-release-pr to a package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * github workflow fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix typo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * add webpack-env types to core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix github workflows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor/fix integration tests Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * lint fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * yarn run dev Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * eslint settings for vscode Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * move templates to right package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * open-lens build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * integration test fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix nx task dependencies Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * use bash shell for unit tests in test workflow Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix test:unit for windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix build:app on windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove ELECTRON_BUILDER_EXTRA_ARGS Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * sync src/ from master Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove Makefile from core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
1 parent
0066ca4ea2
commit
2657df2293
3321 files changed
+28699
-11447
No files matched your search
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import emitAppEventInjectable from "../../common/app-event-bus/emit-event.injectable";
|
||||
import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable";
|
||||
import { kubectlApplyAllChannel } from "../../common/kube-helpers/channels";
|
||||
import createResourceApplierInjectable from "../resource-applier/create-resource-applier.injectable";
|
||||
import { getRequestChannelListenerInjectable } from "../utils/channel/channel-listeners/listener-tokens";
|
||||
|
||||
const kubectlApplyAllChannelHandlerInjectable = getRequestChannelListenerInjectable({
|
||||
channel: kubectlApplyAllChannel,
|
||||
handler: (di) => {
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||
const createResourceApplier = di.inject(createResourceApplierInjectable);
|
||||
|
||||
return async ({
|
||||
clusterId,
|
||||
extraArgs,
|
||||
resources,
|
||||
}) => {
|
||||
emitAppEvent({ name: "cluster", action: "kubectl-apply-all" });
|
||||
const cluster = getClusterById(clusterId);
|
||||
|
||||
if (!cluster) {
|
||||
return {
|
||||
callWasSuccessful: false,
|
||||
error: `No cluster found for clusterId="${clusterId}"`,
|
||||
};
|
||||
}
|
||||
|
||||
return createResourceApplier(cluster).kubectlApplyAll(resources, extraArgs);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default kubectlApplyAllChannelHandlerInjectable;
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import binaryNameInjectable from "../../common/utils/binary-name.injectable";
|
||||
|
||||
const kubectlBinaryNameInjectable = getInjectable({
|
||||
id: "kubectl-binary-name",
|
||||
instantiate: (di) => di.inject(binaryNameInjectable, "kubectl"),
|
||||
});
|
||||
|
||||
export default kubectlBinaryNameInjectable;
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import bundledBinaryPathInjectable from "../../common/utils/bundled-binary-path.injectable";
|
||||
|
||||
const bundledKubectlBinaryPathInjectable = getInjectable({
|
||||
id: "bundled-kubectl-binary-path",
|
||||
instantiate: (di) => di.inject(bundledBinaryPathInjectable, "kubectl"),
|
||||
});
|
||||
|
||||
export default bundledKubectlBinaryPathInjectable;
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import bundledKubectlVersionInjectable from "../../common/vars/bundled-kubectl-version.injectable";
|
||||
import createKubectlInjectable from "./create-kubectl.injectable";
|
||||
|
||||
const bundledKubectlInjectable = getInjectable({
|
||||
id: "bundled-kubectl",
|
||||
|
||||
instantiate: (di) => {
|
||||
const createKubectl = di.inject(createKubectlInjectable);
|
||||
const bundledKubectlVersion = di.inject(bundledKubectlVersionInjectable);
|
||||
|
||||
return createKubectl(bundledKubectlVersion);
|
||||
},
|
||||
});
|
||||
|
||||
export default bundledKubectlInjectable;
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { KubectlDependencies } from "./kubectl";
|
||||
import { Kubectl } from "./kubectl";
|
||||
import directoryForKubectlBinariesInjectable from "../../common/app-paths/directory-for-kubectl-binaries/directory-for-kubectl-binaries.injectable";
|
||||
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
||||
import kubectlDownloadingNormalizedArchInjectable from "./normalized-arch.injectable";
|
||||
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
||||
import kubectlBinaryNameInjectable from "./binary-name.injectable";
|
||||
import bundledKubectlBinaryPathInjectable from "./bundled-binary-path.injectable";
|
||||
import baseBundledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||
import bundledKubectlVersionInjectable from "../../common/vars/bundled-kubectl-version.injectable";
|
||||
import kubectlVersionMapInjectable from "./version-map.injectable";
|
||||
import getDirnameOfPathInjectable from "../../common/path/get-dirname.injectable";
|
||||
import joinPathsInjectable from "../../common/path/join-paths.injectable";
|
||||
import getBasenameOfPathInjectable from "../../common/path/get-basename.injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
|
||||
const createKubectlInjectable = getInjectable({
|
||||
id: "create-kubectl",
|
||||
|
||||
instantiate: (di) => {
|
||||
const dependencies: KubectlDependencies = {
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
directoryForKubectlBinaries: di.inject(directoryForKubectlBinariesInjectable),
|
||||
normalizedDownloadArch: di.inject(kubectlDownloadingNormalizedArchInjectable),
|
||||
normalizedDownloadPlatform: di.inject(normalizedPlatformInjectable),
|
||||
kubectlBinaryName: di.inject(kubectlBinaryNameInjectable),
|
||||
bundledKubectlBinaryPath: di.inject(bundledKubectlBinaryPathInjectable),
|
||||
baseBundeledBinariesDirectory: di.inject(baseBundledBinariesDirectoryInjectable),
|
||||
bundledKubectlVersion: di.inject(bundledKubectlVersionInjectable),
|
||||
kubectlVersionMap: di.inject(kubectlVersionMapInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
getDirnameOfPath: di.inject(getDirnameOfPathInjectable),
|
||||
joinPaths: di.inject(joinPathsInjectable),
|
||||
getBasenameOfPath: di.inject(getBasenameOfPathInjectable),
|
||||
};
|
||||
|
||||
return (clusterVersion: string) => new Kubectl(dependencies, clusterVersion);
|
||||
},
|
||||
});
|
||||
|
||||
export default createKubectlInjectable;
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import emitAppEventInjectable from "../../common/app-event-bus/emit-event.injectable";
|
||||
import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable";
|
||||
import { kubectlDeleteAllChannel } from "../../common/kube-helpers/channels";
|
||||
import createResourceApplierInjectable from "../resource-applier/create-resource-applier.injectable";
|
||||
import { getRequestChannelListenerInjectable } from "../utils/channel/channel-listeners/listener-tokens";
|
||||
|
||||
const kubectlDeleteAllChannelHandlerInjectable = getRequestChannelListenerInjectable({
|
||||
channel: kubectlDeleteAllChannel,
|
||||
handler: (di) => {
|
||||
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
const createResourceApplier = di.inject(createResourceApplierInjectable);
|
||||
|
||||
return async ({
|
||||
clusterId,
|
||||
extraArgs,
|
||||
resources,
|
||||
}) => {
|
||||
emitAppEvent({ name: "cluster", action: "kubectl-delete-all" });
|
||||
|
||||
const cluster = getClusterById(clusterId);
|
||||
|
||||
if (!cluster) {
|
||||
return {
|
||||
callWasSuccessful: false,
|
||||
error: `No cluster found for clusterId="${clusterId}"`,
|
||||
};
|
||||
}
|
||||
|
||||
return createResourceApplier(cluster).kubectlDeleteAll(resources, extraArgs);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default kubectlDeleteAllChannelHandlerInjectable;
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { kubectlApplyAllInjectionToken } from "../../common/kube-helpers/channels";
|
||||
import kubectlApplyAllChannelHandlerInjectable from "./apply-all-handler.injectable";
|
||||
|
||||
const kubectlApplyAllInjectable = getInjectable({
|
||||
id: "kubectl-apply-all",
|
||||
instantiate: (di) => {
|
||||
const channelHandler = di.inject(kubectlApplyAllChannelHandlerInjectable);
|
||||
|
||||
return async (req) => channelHandler.handler(req);
|
||||
},
|
||||
injectionToken: kubectlApplyAllInjectionToken,
|
||||
});
|
||||
|
||||
export default kubectlApplyAllInjectable;
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { kubectlDeleteAllInjectionToken } from "../../common/kube-helpers/channels";
|
||||
import kubectlDeleteAllChannelHandlerInjectable from "./delete-all-handler.injectable";
|
||||
|
||||
const kubectlDeleteAllInjectable = getInjectable({
|
||||
id: "kubectl-delete-all",
|
||||
instantiate: (di) => {
|
||||
const channel = di.inject(kubectlDeleteAllChannelHandlerInjectable);
|
||||
|
||||
return async (req) => channel.handler(req);
|
||||
},
|
||||
injectionToken: kubectlDeleteAllInjectionToken,
|
||||
});
|
||||
|
||||
export default kubectlDeleteAllInjectable;
|
||||
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import { promiseExecFile } from "../../common/utils/promise-exec";
|
||||
import { ensureDir, pathExists } from "fs-extra";
|
||||
import * as lockFile from "proper-lockfile";
|
||||
import { SemVer, coerce } 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";
|
||||
import type { JoinPaths } from "../../common/path/join-paths.injectable";
|
||||
import type { GetDirnameOfPath } from "../../common/path/get-dirname.injectable";
|
||||
import type { GetBasenameOfPath } from "../../common/path/get-basename.injectable";
|
||||
import type { NormalizedPlatform } from "../../common/vars/normalized-platform.injectable";
|
||||
import type { Logger } from "../../common/logger";
|
||||
|
||||
const initScriptVersionString = "# lens-initscript v3";
|
||||
|
||||
export interface KubectlDependencies {
|
||||
readonly directoryForKubectlBinaries: string;
|
||||
readonly normalizedDownloadPlatform: NormalizedPlatform;
|
||||
readonly normalizedDownloadArch: "amd64" | "arm64" | "386";
|
||||
readonly kubectlBinaryName: string;
|
||||
readonly bundledKubectlBinaryPath: string;
|
||||
readonly baseBundeledBinariesDirectory: string;
|
||||
readonly userStore: {
|
||||
readonly kubectlBinariesPath?: string;
|
||||
readonly downloadBinariesPath?: string;
|
||||
readonly downloadKubectlBinaries: boolean;
|
||||
readonly downloadMirror: string;
|
||||
};
|
||||
readonly bundledKubectlVersion: string;
|
||||
readonly kubectlVersionMap: Map<string, string>;
|
||||
readonly logger: Logger;
|
||||
joinPaths: JoinPaths;
|
||||
getDirnameOfPath: GetDirnameOfPath;
|
||||
getBasenameOfPath: GetBasenameOfPath;
|
||||
}
|
||||
|
||||
export class Kubectl {
|
||||
public readonly kubectlVersion: string;
|
||||
protected readonly url: string;
|
||||
protected readonly path: string;
|
||||
protected readonly dirname: string;
|
||||
|
||||
public static invalidBundle = false;
|
||||
|
||||
constructor(protected readonly dependencies: KubectlDependencies, clusterVersion: string) {
|
||||
let version: SemVer;
|
||||
const bundledVersion = new SemVer(this.dependencies.bundledKubectlVersion);
|
||||
|
||||
try {
|
||||
version = new SemVer(clusterVersion);
|
||||
} catch {
|
||||
version = bundledVersion;
|
||||
}
|
||||
|
||||
const fromMajorMinor = this.dependencies.kubectlVersionMap.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;
|
||||
this.dependencies.logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using version map`);
|
||||
} else {
|
||||
/* this is the version (without possible prelease tag) to get from the download mirror */
|
||||
const ver = coerce(version.format()) ?? bundledVersion;
|
||||
|
||||
this.kubectlVersion = ver.format();
|
||||
this.dependencies.logger.debug(`Set kubectl version ${this.kubectlVersion} for cluster version ${clusterVersion} using fallback`);
|
||||
}
|
||||
|
||||
this.url = `${this.getDownloadMirror()}/v${this.kubectlVersion}/bin/${this.dependencies.normalizedDownloadPlatform}/${this.dependencies.normalizedDownloadArch}/${this.dependencies.kubectlBinaryName}`;
|
||||
this.dirname = this.dependencies.joinPaths(this.getDownloadDir(), this.kubectlVersion);
|
||||
this.path = this.dependencies.joinPaths(this.dirname, this.dependencies.kubectlBinaryName);
|
||||
}
|
||||
|
||||
public getBundledPath() {
|
||||
return this.dependencies.bundledKubectlBinaryPath;
|
||||
}
|
||||
|
||||
public getPathFromPreferences() {
|
||||
return this.dependencies.userStore.kubectlBinariesPath || this.getBundledPath();
|
||||
}
|
||||
|
||||
protected getDownloadDir() {
|
||||
if (this.dependencies.userStore.downloadBinariesPath) {
|
||||
return this.dependencies.joinPaths(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 this.dependencies.getBasenameOfPath(this.getBundledPath());
|
||||
}
|
||||
|
||||
try {
|
||||
if (!await this.ensureKubectl()) {
|
||||
this.dependencies.logger.error("Failed to ensure kubectl, fallback to the bundled version");
|
||||
|
||||
return this.getBundledPath();
|
||||
}
|
||||
|
||||
return this.path;
|
||||
} catch (err) {
|
||||
this.dependencies.logger.error("Failed to ensure kubectl, fallback to the bundled version", err);
|
||||
|
||||
return this.getBundledPath();
|
||||
}
|
||||
};
|
||||
|
||||
public async binDir() {
|
||||
try {
|
||||
await this.ensureKubectl();
|
||||
await this.writeInitScripts();
|
||||
|
||||
return this.dirname;
|
||||
} catch (err) {
|
||||
this.dependencies.logger.error("Failed to get biniary directory", err);
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public async checkBinary(path: string, checkVersion = true) {
|
||||
const exists = await pathExists(path);
|
||||
|
||||
if (exists) {
|
||||
try {
|
||||
const args = [
|
||||
"version",
|
||||
"--client",
|
||||
"--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) {
|
||||
this.dependencies.logger.debug(`Local kubectl is version ${this.kubectlVersion}`);
|
||||
|
||||
return true;
|
||||
}
|
||||
this.dependencies.logger.error(`Local kubectl is version ${version}, expected ${this.kubectlVersion}, unlinking`);
|
||||
} catch (error) {
|
||||
this.dependencies.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 === this.dependencies.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) {
|
||||
this.dependencies.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) {
|
||||
this.dependencies.logger.error(`Detected invalid bundle binary, returning ...`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
await ensureDir(this.dirname, 0o755);
|
||||
|
||||
try {
|
||||
const release = await lockFile.lock(this.dirname);
|
||||
|
||||
this.dependencies.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) {
|
||||
this.dependencies.logger.error(`[KUBECTL]: failed to download kubectl`, error);
|
||||
this.dependencies.logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
|
||||
await release();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
isValid = await this.checkBinary(this.path, false);
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
this.dependencies.logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
|
||||
await release();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this.dependencies.logger.debug(`[KUBECTL]: Releasing lock for ${this.kubectlVersion}`);
|
||||
await release();
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
this.dependencies.logger.error(`[KUBECTL]: Failed to get a lock for ${this.kubectlVersion}`, error);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async downloadKubectl() {
|
||||
await ensureDir(this.dependencies.getDirnameOfPath(this.path), 0o755);
|
||||
|
||||
this.dependencies.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);
|
||||
this.dependencies.logger.debug("kubectl binary download finished");
|
||||
} catch (error) {
|
||||
await fs.promises.unlink(this.path).catch(noop);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
protected async writeInitScripts() {
|
||||
const binariesDir = this.dependencies.baseBundeledBinariesDirectory;
|
||||
const kubectlPath = this.dependencies.userStore.downloadKubectlBinaries
|
||||
? this.dirname
|
||||
: this.dependencies.getDirnameOfPath(this.getPathFromPreferences());
|
||||
|
||||
const bashScriptPath = this.dependencies.joinPaths(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="${kubectlPath}:${binariesDir}:$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 = this.dependencies.joinPaths(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="$kubectlpath:$binariesDir:\${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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import processArchInjectable from "../../common/vars/process-arch.injectable";
|
||||
|
||||
const kubectlDownloadingNormalizedArchInjectable = getInjectable({
|
||||
id: "kubectl-downloading-normalized-arch",
|
||||
instantiate: (di) => {
|
||||
const processArch = di.inject(processArchInjectable);
|
||||
|
||||
switch (processArch) {
|
||||
case "arm64":
|
||||
return "arm64";
|
||||
case "x64":
|
||||
case "amd64":
|
||||
return "amd64";
|
||||
case "386":
|
||||
case "x32":
|
||||
case "ia32":
|
||||
return "386";
|
||||
default:
|
||||
throw new Error(`arch=${processArch} is unsupported`);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export default kubectlDownloadingNormalizedArchInjectable;
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import bundledKubectlVersionInjectable from "../../common/vars/bundled-kubectl-version.injectable";
|
||||
|
||||
const kubectlVersionMapInjectable = getInjectable({
|
||||
id: "kubectl-version-map",
|
||||
instantiate: (di) => {
|
||||
const bundledKubectlVersion = di.inject(bundledKubectlVersionInjectable);
|
||||
|
||||
return 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", bundledKubectlVersion],
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
export default kubectlVersionMapInjectable;
|
||||
Reference in new issue
Block a user