mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix downloading cluster specific kubectl (#5399)
This commit is contained in:
parent
ac27077ef9
commit
e1c1e00a2b
@ -22,6 +22,9 @@ import getConfigurationFileModelInjectable from "../get-configuration-file-model
|
|||||||
import appVersionInjectable from "../get-configuration-file-model/app-version/app-version.injectable";
|
import appVersionInjectable from "../get-configuration-file-model/app-version/app-version.injectable";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import directoryForTempInjectable from "../app-paths/directory-for-temp/directory-for-temp.injectable";
|
import directoryForTempInjectable from "../app-paths/directory-for-temp/directory-for-temp.injectable";
|
||||||
|
import kubectlBinaryNameInjectable from "../../main/kubectl/binary-name.injectable";
|
||||||
|
import kubectlDownloadingNormalizedArchInjectable from "../../main/kubectl/normalized-arch.injectable";
|
||||||
|
import normalizedPlatformInjectable from "../vars/normalized-platform.injectable";
|
||||||
|
|
||||||
console = new Console(stdout, stderr);
|
console = new Console(stdout, stderr);
|
||||||
|
|
||||||
@ -84,6 +87,9 @@ describe("cluster-store", () => {
|
|||||||
|
|
||||||
mainDi.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
mainDi.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
||||||
mainDi.override(directoryForTempInjectable, () => "some-temp-directory");
|
mainDi.override(directoryForTempInjectable, () => "some-temp-directory");
|
||||||
|
mainDi.override(kubectlBinaryNameInjectable, () => "kubectl");
|
||||||
|
mainDi.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
|
||||||
|
mainDi.override(normalizedPlatformInjectable, () => "darwin");
|
||||||
|
|
||||||
mainDi.permitSideEffects(getConfigurationFileModelInjectable);
|
mainDi.permitSideEffects(getConfigurationFileModelInjectable);
|
||||||
mainDi.permitSideEffects(appVersionInjectable);
|
mainDi.permitSideEffects(appVersionInjectable);
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 { baseBinariesDir } from "../../vars";
|
|
||||||
|
|
||||||
const directoryForBundledBinariesInjectable = getInjectable({
|
|
||||||
id: "directory-for-bundled-binaries",
|
|
||||||
instantiate: () => baseBinariesDir.get(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default directoryForBundledBinariesInjectable;
|
|
||||||
@ -57,6 +57,9 @@ export const defaultThemeId: ThemeId = "lens-dark";
|
|||||||
export const defaultFontSize = 12;
|
export const defaultFontSize = 12;
|
||||||
export const defaultTerminalFontFamily = "RobotoMono";
|
export const defaultTerminalFontFamily = "RobotoMono";
|
||||||
export const defaultEditorFontFamily = "RobotoMono";
|
export const defaultEditorFontFamily = "RobotoMono";
|
||||||
|
/**
|
||||||
|
* @deprecated use `di.inject(normalizedPlatformInjectable)` instead
|
||||||
|
*/
|
||||||
export const normalizedPlatform = (() => {
|
export const normalizedPlatform = (() => {
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case "darwin":
|
case "darwin":
|
||||||
@ -69,6 +72,9 @@ export const normalizedPlatform = (() => {
|
|||||||
throw new Error(`platform=${process.platform} is unsupported`);
|
throw new Error(`platform=${process.platform} is unsupported`);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
/**
|
||||||
|
* @deprecated use `di.inject(bundledBinariesNormalizedArchInjectable)` instead
|
||||||
|
*/
|
||||||
export const normalizedArch = (() => {
|
export const normalizedArch = (() => {
|
||||||
switch (process.arch) {
|
switch (process.arch) {
|
||||||
case "arm64":
|
case "arm64":
|
||||||
@ -119,16 +125,6 @@ export const helmBinaryName = getBinaryName("helm");
|
|||||||
*/
|
*/
|
||||||
export const helmBinaryPath = lazyInitialized(() => path.join(baseBinariesDir.get(), helmBinaryName));
|
export const helmBinaryPath = lazyInitialized(() => path.join(baseBinariesDir.get(), helmBinaryName));
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated for being explicit side effect.
|
|
||||||
*/
|
|
||||||
export const kubectlBinaryName = getBinaryName("kubectl");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated for being explicit side effect.
|
|
||||||
*/
|
|
||||||
export const kubectlBinaryPath = lazyInitialized(() => path.join(baseBinariesDir.get(), kubectlBinaryName));
|
|
||||||
|
|
||||||
// Apis
|
// Apis
|
||||||
export const apiPrefix = "/api"; // local router apis
|
export const apiPrefix = "/api"; // local router apis
|
||||||
export const apiKubePrefix = "/api-kube"; // k8s cluster apis
|
export const apiKubePrefix = "/api-kube"; // k8s cluster apis
|
||||||
|
|||||||
18
src/common/vars/base-bundled-binaries-dir.injectable.ts
Normal file
18
src/common/vars/base-bundled-binaries-dir.injectable.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* 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 path from "path";
|
||||||
|
import bundledBinariesNormalizedArchInjectable from "./bundled-binaries-normalized-arch.injectable";
|
||||||
|
import bundledResourcesDirectoryInjectable from "./bundled-resources-dir.injectable";
|
||||||
|
|
||||||
|
const baseBundeledBinariesDirectoryInjectable = getInjectable({
|
||||||
|
id: "base-bundeled-binaries-directory",
|
||||||
|
instantiate: (di) => path.join(
|
||||||
|
di.inject(bundledResourcesDirectoryInjectable),
|
||||||
|
di.inject(bundledBinariesNormalizedArchInjectable),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default baseBundeledBinariesDirectoryInjectable;
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* 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";
|
||||||
|
|
||||||
|
const bundledBinariesNormalizedArchInjectable = getInjectable({
|
||||||
|
id: "bundled-binaries-normalized-arch",
|
||||||
|
instantiate: () => {
|
||||||
|
switch (process.arch) {
|
||||||
|
case "arm64":
|
||||||
|
return "arm64";
|
||||||
|
case "x64":
|
||||||
|
case "amd64":
|
||||||
|
return "x64";
|
||||||
|
case "386":
|
||||||
|
case "x32":
|
||||||
|
case "ia32":
|
||||||
|
return "ia32";
|
||||||
|
default:
|
||||||
|
throw new Error(`arch=${process.arch} is unsupported`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default bundledBinariesNormalizedArchInjectable;
|
||||||
22
src/common/vars/bundled-resources-dir.injectable.ts
Normal file
22
src/common/vars/bundled-resources-dir.injectable.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* 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 path from "path";
|
||||||
|
import isProductionInjectable from "./is-production.injectable";
|
||||||
|
import normalizedPlatformInjectable from "./normalized-platform.injectable";
|
||||||
|
|
||||||
|
const bundledResourcesDirectoryInjectable = getInjectable({
|
||||||
|
id: "bundled-resources-directory",
|
||||||
|
instantiate: (di) => {
|
||||||
|
const isProduction = di.inject(isProductionInjectable);
|
||||||
|
const normalizedPlatform = di.inject(normalizedPlatformInjectable);
|
||||||
|
|
||||||
|
return isProduction
|
||||||
|
? process.resourcesPath
|
||||||
|
: path.join(process.cwd(), "binaries", "client", normalizedPlatform);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default bundledResourcesDirectoryInjectable;
|
||||||
24
src/common/vars/normalized-platform.injectable.ts
Normal file
24
src/common/vars/normalized-platform.injectable.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 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";
|
||||||
|
|
||||||
|
const normalizedPlatformInjectable = getInjectable({
|
||||||
|
id: "normalized-platform",
|
||||||
|
instantiate: () => {
|
||||||
|
switch (process.platform) {
|
||||||
|
case "darwin":
|
||||||
|
return "darwin";
|
||||||
|
case "linux":
|
||||||
|
return "linux";
|
||||||
|
case "win32":
|
||||||
|
return "windows";
|
||||||
|
default:
|
||||||
|
throw new Error(`platform=${process.platform} is unsupported`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default normalizedPlatformInjectable;
|
||||||
@ -21,6 +21,9 @@ import type { ClusterContextHandler } from "../context-handler/context-handler";
|
|||||||
import { parse } from "url";
|
import { parse } from "url";
|
||||||
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
import directoryForTempInjectable from "../../common/app-paths/directory-for-temp/directory-for-temp.injectable";
|
import directoryForTempInjectable from "../../common/app-paths/directory-for-temp/directory-for-temp.injectable";
|
||||||
|
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
||||||
|
import kubectlBinaryNameInjectable from "../kubectl/binary-name.injectable";
|
||||||
|
import kubectlDownloadingNormalizedArchInjectable from "../kubectl/normalized-arch.injectable";
|
||||||
|
|
||||||
console = new Console(process.stdout, process.stderr); // fix mockFS
|
console = new Console(process.stdout, process.stderr); // fix mockFS
|
||||||
|
|
||||||
@ -59,6 +62,9 @@ describe("create clusters", () => {
|
|||||||
|
|
||||||
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
||||||
di.override(directoryForTempInjectable, () => "some-directory-for-temp");
|
di.override(directoryForTempInjectable, () => "some-directory-for-temp");
|
||||||
|
di.override(kubectlBinaryNameInjectable, () => "kubectl");
|
||||||
|
di.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
|
||||||
|
di.override(normalizedPlatformInjectable, () => "darwin");
|
||||||
di.override(authorizationReviewInjectable, () => () => () => Promise.resolve(true));
|
di.override(authorizationReviewInjectable, () => () => () => Promise.resolve(true));
|
||||||
di.override(listNamespacesInjectable, () => () => () => Promise.resolve([ "default" ]));
|
di.override(listNamespacesInjectable, () => () => () => Promise.resolve([ "default" ]));
|
||||||
di.override(createContextHandlerInjectable, () => (cluster) => ({
|
di.override(createContextHandlerInjectable, () => (cluster) => ({
|
||||||
|
|||||||
@ -59,6 +59,9 @@ import getConfigurationFileModelInjectable from "../../common/get-configuration-
|
|||||||
import appVersionInjectable from "../../common/get-configuration-file-model/app-version/app-version.injectable";
|
import appVersionInjectable from "../../common/get-configuration-file-model/app-version/app-version.injectable";
|
||||||
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
import directoryForTempInjectable from "../../common/app-paths/directory-for-temp/directory-for-temp.injectable";
|
import directoryForTempInjectable from "../../common/app-paths/directory-for-temp/directory-for-temp.injectable";
|
||||||
|
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
||||||
|
import kubectlBinaryNameInjectable from "../kubectl/binary-name.injectable";
|
||||||
|
import kubectlDownloadingNormalizedArchInjectable from "../kubectl/normalized-arch.injectable";
|
||||||
|
|
||||||
console = new Console(stdout, stderr);
|
console = new Console(stdout, stderr);
|
||||||
|
|
||||||
@ -105,6 +108,9 @@ describe("kube auth proxy tests", () => {
|
|||||||
di.override(directoryForTempInjectable, () => "some-directory-for-temp");
|
di.override(directoryForTempInjectable, () => "some-directory-for-temp");
|
||||||
|
|
||||||
di.override(spawnInjectable, () => mockSpawn);
|
di.override(spawnInjectable, () => mockSpawn);
|
||||||
|
di.override(kubectlBinaryNameInjectable, () => "kubectl");
|
||||||
|
di.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
|
||||||
|
di.override(normalizedPlatformInjectable, () => "darwin");
|
||||||
|
|
||||||
di.permitSideEffects(getConfigurationFileModelInjectable);
|
di.permitSideEffects(getConfigurationFileModelInjectable);
|
||||||
di.permitSideEffects(appVersionInjectable);
|
di.permitSideEffects(appVersionInjectable);
|
||||||
|
|||||||
@ -20,6 +20,9 @@ import loggerInjectable from "../../common/logger.injectable";
|
|||||||
import type { Logger } from "../../common/logger";
|
import type { Logger } from "../../common/logger";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
|
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
||||||
|
import kubectlBinaryNameInjectable from "../kubectl/binary-name.injectable";
|
||||||
|
import kubectlDownloadingNormalizedArchInjectable from "../kubectl/normalized-arch.injectable";
|
||||||
|
|
||||||
console = new Console(process.stdout, process.stderr); // fix mockFS
|
console = new Console(process.stdout, process.stderr); // fix mockFS
|
||||||
|
|
||||||
@ -34,6 +37,9 @@ describe("kubeconfig manager tests", () => {
|
|||||||
|
|
||||||
di.override(directoryForTempInjectable, () => "some-directory-for-temp");
|
di.override(directoryForTempInjectable, () => "some-directory-for-temp");
|
||||||
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
||||||
|
di.override(kubectlBinaryNameInjectable, () => "kubectl");
|
||||||
|
di.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
|
||||||
|
di.override(normalizedPlatformInjectable, () => "darwin");
|
||||||
|
|
||||||
loggerMock = {
|
loggerMock = {
|
||||||
warn: jest.fn(),
|
warn: jest.fn(),
|
||||||
|
|||||||
@ -20,6 +20,9 @@ import appVersionInjectable from "../../../common/get-configuration-file-model/a
|
|||||||
import clusterManagerInjectable from "../../cluster-manager.injectable";
|
import clusterManagerInjectable from "../../cluster-manager.injectable";
|
||||||
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
import directoryForTempInjectable from "../../../common/app-paths/directory-for-temp/directory-for-temp.injectable";
|
import directoryForTempInjectable from "../../../common/app-paths/directory-for-temp/directory-for-temp.injectable";
|
||||||
|
import kubectlBinaryNameInjectable from "../../kubectl/binary-name.injectable";
|
||||||
|
import kubectlDownloadingNormalizedArchInjectable from "../../kubectl/normalized-arch.injectable";
|
||||||
|
import normalizedPlatformInjectable from "../../../common/vars/normalized-platform.injectable";
|
||||||
|
|
||||||
jest.mock("electron", () => ({
|
jest.mock("electron", () => ({
|
||||||
app: {
|
app: {
|
||||||
@ -47,6 +50,9 @@ describe("kubeconfig-sync.source tests", () => {
|
|||||||
|
|
||||||
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
||||||
di.override(directoryForTempInjectable, () => "some-directory-for-temp");
|
di.override(directoryForTempInjectable, () => "some-directory-for-temp");
|
||||||
|
di.override(kubectlBinaryNameInjectable, () => "kubectl");
|
||||||
|
di.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
|
||||||
|
di.override(normalizedPlatformInjectable, () => "darwin");
|
||||||
|
|
||||||
di.override(clusterStoreInjectable, () =>
|
di.override(clusterStoreInjectable, () =>
|
||||||
ClusterStore.createInstance({ createCluster: () => null as never }),
|
ClusterStore.createInstance({ createCluster: () => null as never }),
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import glob from "glob";
|
import glob from "glob";
|
||||||
import { kebabCase, memoize, noop } from "lodash/fp";
|
import { kebabCase, memoize } from "lodash/fp";
|
||||||
import type { DiContainer } from "@ogre-tools/injectable";
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
import { createContainer } from "@ogre-tools/injectable";
|
import { createContainer } from "@ogre-tools/injectable";
|
||||||
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
@ -13,7 +13,6 @@ import registerChannelInjectable from "./app-paths/register-channel/register-cha
|
|||||||
import writeJsonFileInjectable from "../common/fs/write-json-file.injectable";
|
import writeJsonFileInjectable from "../common/fs/write-json-file.injectable";
|
||||||
import readJsonFileInjectable from "../common/fs/read-json-file.injectable";
|
import readJsonFileInjectable from "../common/fs/read-json-file.injectable";
|
||||||
import readFileInjectable from "../common/fs/read-file.injectable";
|
import readFileInjectable from "../common/fs/read-file.injectable";
|
||||||
import directoryForBundledBinariesInjectable from "../common/app-paths/directory-for-bundled-binaries/directory-for-bundled-binaries.injectable";
|
|
||||||
import loggerInjectable from "../common/logger.injectable";
|
import loggerInjectable from "../common/logger.injectable";
|
||||||
import spawnInjectable from "./child-process/spawn.injectable";
|
import spawnInjectable from "./child-process/spawn.injectable";
|
||||||
import extensionsStoreInjectable from "../extensions/extensions-store/extensions-store.injectable";
|
import extensionsStoreInjectable from "../extensions/extensions-store/extensions-store.injectable";
|
||||||
@ -76,6 +75,8 @@ import broadcastMessageInjectable from "../common/ipc/broadcast-message.injectab
|
|||||||
import getElectronThemeInjectable from "./electron-app/features/get-electron-theme.injectable";
|
import getElectronThemeInjectable from "./electron-app/features/get-electron-theme.injectable";
|
||||||
import syncThemeFromOperatingSystemInjectable from "./electron-app/features/sync-theme-from-operating-system.injectable";
|
import syncThemeFromOperatingSystemInjectable from "./electron-app/features/sync-theme-from-operating-system.injectable";
|
||||||
import platformInjectable from "../common/vars/platform.injectable";
|
import platformInjectable from "../common/vars/platform.injectable";
|
||||||
|
import { noop } from "../renderer/utils";
|
||||||
|
import baseBundeledBinariesDirectoryInjectable from "../common/vars/base-bundled-binaries-dir.injectable";
|
||||||
|
|
||||||
export function getDiForUnitTesting(opts: GetDiForUnitTestingOptions = {}) {
|
export function getDiForUnitTesting(opts: GetDiForUnitTestingOptions = {}) {
|
||||||
const {
|
const {
|
||||||
@ -126,12 +127,10 @@ export function getDiForUnitTesting(opts: GetDiForUnitTestingOptions = {}) {
|
|||||||
|
|
||||||
di.override(appNameInjectable, () => "some-app-name");
|
di.override(appNameInjectable, () => "some-app-name");
|
||||||
di.override(registerChannelInjectable, () => () => undefined);
|
di.override(registerChannelInjectable, () => () => undefined);
|
||||||
di.override(directoryForBundledBinariesInjectable, () => "some-bin-directory");
|
|
||||||
|
|
||||||
di.override(broadcastMessageInjectable, () => (channel) => {
|
di.override(broadcastMessageInjectable, () => (channel) => {
|
||||||
throw new Error(`Tried to broadcast message to channel "${channel}" over IPC without explicit override.`);
|
throw new Error(`Tried to broadcast message to channel "${channel}" over IPC without explicit override.`);
|
||||||
});
|
});
|
||||||
|
di.override(baseBundeledBinariesDirectoryInjectable, () => "some-bin-directory");
|
||||||
di.override(spawnInjectable, () => () => {
|
di.override(spawnInjectable, () => () => {
|
||||||
return {
|
return {
|
||||||
stderr: { on: jest.fn(), removeAllListeners: jest.fn() },
|
stderr: { on: jest.fn(), removeAllListeners: jest.fn() },
|
||||||
|
|||||||
@ -9,10 +9,10 @@ import type { Cluster } from "../../common/cluster/cluster";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import selfsigned from "selfsigned";
|
import selfsigned from "selfsigned";
|
||||||
import { getBinaryName } from "../../common/vars";
|
import { getBinaryName } from "../../common/vars";
|
||||||
import directoryForBundledBinariesInjectable from "../../common/app-paths/directory-for-bundled-binaries/directory-for-bundled-binaries.injectable";
|
|
||||||
import spawnInjectable from "../child-process/spawn.injectable";
|
import spawnInjectable from "../child-process/spawn.injectable";
|
||||||
import { getKubeAuthProxyCertificate } from "./get-kube-auth-proxy-certificate";
|
import { getKubeAuthProxyCertificate } from "./get-kube-auth-proxy-certificate";
|
||||||
import loggerInjectable from "../../common/logger.injectable";
|
import loggerInjectable from "../../common/logger.injectable";
|
||||||
|
import baseBundeledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||||
|
|
||||||
export type CreateKubeAuthProxy = (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => KubeAuthProxy;
|
export type CreateKubeAuthProxy = (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => KubeAuthProxy;
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ const createKubeAuthProxyInjectable = getInjectable({
|
|||||||
return (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => {
|
return (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => {
|
||||||
const clusterUrl = new URL(cluster.apiUrl);
|
const clusterUrl = new URL(cluster.apiUrl);
|
||||||
const dependencies: KubeAuthProxyDependencies = {
|
const dependencies: KubeAuthProxyDependencies = {
|
||||||
proxyBinPath: path.join(di.inject(directoryForBundledBinariesInjectable), binaryName),
|
proxyBinPath: path.join(di.inject(baseBundeledBinariesDirectoryInjectable), binaryName),
|
||||||
proxyCert: getKubeAuthProxyCertificate(clusterUrl.hostname, selfsigned.generate),
|
proxyCert: getKubeAuthProxyCertificate(clusterUrl.hostname, selfsigned.generate),
|
||||||
spawn: di.inject(spawnInjectable),
|
spawn: di.inject(spawnInjectable),
|
||||||
logger: di.inject(loggerInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
|
|||||||
19
src/main/kubectl/binary-name.injectable.ts
Normal file
19
src/main/kubectl/binary-name.injectable.ts
Normal file
@ -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 normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
||||||
|
|
||||||
|
const kubectlBinaryNameInjectable = getInjectable({
|
||||||
|
id: "kubectl-binary-name",
|
||||||
|
instantiate: (di) => {
|
||||||
|
const platform = di.inject(normalizedPlatformInjectable);
|
||||||
|
|
||||||
|
return platform === "windows"
|
||||||
|
? "kubectl.exe"
|
||||||
|
: "kubectl";
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default kubectlBinaryNameInjectable;
|
||||||
18
src/main/kubectl/bundled-binary-path.injectable.ts
Normal file
18
src/main/kubectl/bundled-binary-path.injectable.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* 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 path from "path";
|
||||||
|
import baseBundeledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||||
|
import kubectlBinaryNameInjectable from "./binary-name.injectable";
|
||||||
|
|
||||||
|
const bundledKubectlBinaryPathInjectable = getInjectable({
|
||||||
|
id: "bundled-kubectl-binary-path",
|
||||||
|
instantiate: (di) => path.join(
|
||||||
|
di.inject(baseBundeledBinariesDirectoryInjectable),
|
||||||
|
di.inject(kubectlBinaryNameInjectable),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default bundledKubectlBinaryPathInjectable;
|
||||||
@ -3,24 +3,31 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { KubectlDependencies } from "./kubectl";
|
||||||
import { Kubectl } from "./kubectl";
|
import { Kubectl } from "./kubectl";
|
||||||
import directoryForKubectlBinariesInjectable from "../../common/app-paths/directory-for-kubectl-binaries/directory-for-kubectl-binaries.injectable";
|
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 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 baseBundeledBinariesDirectoryInjectable from "../../common/vars/base-bundled-binaries-dir.injectable";
|
||||||
|
|
||||||
const createKubectlInjectable = getInjectable({
|
const createKubectlInjectable = getInjectable({
|
||||||
id: "create-kubectl",
|
id: "create-kubectl",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const dependencies = {
|
const dependencies: KubectlDependencies = {
|
||||||
userStore: di.inject(userStoreInjectable),
|
userStore: di.inject(userStoreInjectable),
|
||||||
|
directoryForKubectlBinaries: di.inject(directoryForKubectlBinariesInjectable),
|
||||||
directoryForKubectlBinaries: di.inject(
|
normalizedDownloadArch: di.inject(kubectlDownloadingNormalizedArchInjectable),
|
||||||
directoryForKubectlBinariesInjectable,
|
normalizedDownloadPlatform: di.inject(normalizedPlatformInjectable),
|
||||||
),
|
kubectlBinaryName: di.inject(kubectlBinaryNameInjectable),
|
||||||
|
bundledKubectlBinaryPath: di.inject(bundledKubectlBinaryPathInjectable),
|
||||||
|
baseBundeledBinariesDirectory: di.inject(baseBundeledBinariesDirectoryInjectable),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (clusterVersion: string) =>
|
return (clusterVersion: string) => new Kubectl(dependencies, clusterVersion);
|
||||||
new Kubectl(dependencies, clusterVersion);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,6 @@ 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 { getBundledKubectlVersion } from "../../common/utils/app-version";
|
import { getBundledKubectlVersion } from "../../common/utils/app-version";
|
||||||
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";
|
||||||
@ -40,27 +39,31 @@ const kubectlMap: Map<string, string> = new Map([
|
|||||||
]);
|
]);
|
||||||
const initScriptVersionString = "# lens-initscript v3";
|
const initScriptVersionString = "# lens-initscript v3";
|
||||||
|
|
||||||
interface Dependencies {
|
export interface KubectlDependencies {
|
||||||
directoryForKubectlBinaries: string;
|
readonly directoryForKubectlBinaries: string;
|
||||||
|
readonly normalizedDownloadPlatform: "darwin" | "linux" | "windows";
|
||||||
userStore: {
|
readonly normalizedDownloadArch: "amd64" | "arm64" | "386";
|
||||||
kubectlBinariesPath?: string;
|
readonly kubectlBinaryName: string;
|
||||||
downloadBinariesPath?: string;
|
readonly bundledKubectlBinaryPath: string;
|
||||||
downloadKubectlBinaries: boolean;
|
readonly baseBundeledBinariesDirectory: string;
|
||||||
downloadMirror: string;
|
readonly userStore: {
|
||||||
|
readonly kubectlBinariesPath?: string;
|
||||||
|
readonly downloadBinariesPath?: string;
|
||||||
|
readonly downloadKubectlBinaries: boolean;
|
||||||
|
readonly downloadMirror: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Kubectl {
|
export class Kubectl {
|
||||||
public kubectlVersion: string;
|
public readonly kubectlVersion: string;
|
||||||
protected url: string;
|
protected readonly url: string;
|
||||||
protected path: string;
|
protected readonly path: string;
|
||||||
protected dirname: string;
|
protected readonly dirname: string;
|
||||||
|
|
||||||
public static readonly bundledKubectlVersion = bundledVersion;
|
public static readonly bundledKubectlVersion = bundledVersion;
|
||||||
public static invalidBundle = false;
|
public static invalidBundle = false;
|
||||||
|
|
||||||
constructor(private dependencies: Dependencies, clusterVersion: string) {
|
constructor(protected readonly dependencies: KubectlDependencies, clusterVersion: string) {
|
||||||
let version: SemVer;
|
let version: SemVer;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -83,13 +86,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}/${kubectlBinaryName}`;
|
this.url = `${this.getDownloadMirror()}/v${this.kubectlVersion}/bin/${this.dependencies.normalizedDownloadPlatform}/${this.dependencies.normalizedDownloadArch}/${this.dependencies.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, kubectlBinaryName);
|
this.path = path.join(this.dirname, this.dependencies.kubectlBinaryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getBundledPath() {
|
public getBundledPath() {
|
||||||
return kubectlBinaryPath.get();
|
return this.dependencies.bundledKubectlBinaryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPathFromPreferences() {
|
public getPathFromPreferences() {
|
||||||
@ -279,12 +282,11 @@ export class Kubectl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async writeInitScripts() {
|
protected async writeInitScripts() {
|
||||||
|
const binariesDir = this.dependencies.baseBundeledBinariesDirectory;
|
||||||
const kubectlPath = this.dependencies.userStore.downloadKubectlBinaries
|
const kubectlPath = this.dependencies.userStore.downloadKubectlBinaries
|
||||||
? this.dirname
|
? this.dirname
|
||||||
: path.dirname(this.getPathFromPreferences());
|
: path.dirname(this.getPathFromPreferences());
|
||||||
|
|
||||||
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 = [
|
||||||
initScriptVersionString,
|
initScriptVersionString,
|
||||||
@ -297,7 +299,7 @@ export class Kubectl {
|
|||||||
"elif test -f \"$HOME/.profile\"; then",
|
"elif test -f \"$HOME/.profile\"; then",
|
||||||
" . \"$HOME/.profile\"",
|
" . \"$HOME/.profile\"",
|
||||||
"fi",
|
"fi",
|
||||||
`export PATH="${binariesDir}:${kubectlPath}:$PATH"`,
|
`export PATH="${kubectlPath}:${binariesDir}:$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,/,}"`,
|
||||||
@ -328,7 +330,7 @@ export class Kubectl {
|
|||||||
"d=\":$PATH:\"",
|
"d=\":$PATH:\"",
|
||||||
`d=\${d//$p/:}`,
|
`d=\${d//$p/:}`,
|
||||||
`d=\${d/#:/}`,
|
`d=\${d/#:/}`,
|
||||||
`export PATH="$binariesDir:$kubectlpath:\${d/%:/}"`,
|
`export PATH="$kubectlpath:$binariesDir:\${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,/,}"`,
|
||||||
|
|||||||
27
src/main/kubectl/normalized-arch.injectable.ts
Normal file
27
src/main/kubectl/normalized-arch.injectable.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* 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";
|
||||||
|
|
||||||
|
const kubectlDownloadingNormalizedArchInjectable = getInjectable({
|
||||||
|
id: "kubectl-downloading-normalized-arch",
|
||||||
|
instantiate: () => {
|
||||||
|
switch (process.arch) {
|
||||||
|
case "arm64":
|
||||||
|
return "arm64";
|
||||||
|
case "x64":
|
||||||
|
case "amd64":
|
||||||
|
return "amd64";
|
||||||
|
case "386":
|
||||||
|
case "x32":
|
||||||
|
case "ia32":
|
||||||
|
return "386";
|
||||||
|
default:
|
||||||
|
throw new Error(`arch=${process.arch} is unsupported`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default kubectlDownloadingNormalizedArchInjectable;
|
||||||
@ -17,6 +17,9 @@ import mockFs from "mock-fs";
|
|||||||
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||||
import type { Route } from "./route";
|
import type { Route } from "./route";
|
||||||
import type { SetRequired } from "type-fest";
|
import type { SetRequired } from "type-fest";
|
||||||
|
import normalizedPlatformInjectable from "../../common/vars/normalized-platform.injectable";
|
||||||
|
import kubectlBinaryNameInjectable from "../kubectl/binary-name.injectable";
|
||||||
|
import kubectlDownloadingNormalizedArchInjectable from "../kubectl/normalized-arch.injectable";
|
||||||
|
|
||||||
describe("router", () => {
|
describe("router", () => {
|
||||||
let router: Router;
|
let router: Router;
|
||||||
@ -31,6 +34,9 @@ describe("router", () => {
|
|||||||
|
|
||||||
di.override(parseRequestInjectable, () => () => Promise.resolve({ payload: "some-payload" }));
|
di.override(parseRequestInjectable, () => () => Promise.resolve({ payload: "some-payload" }));
|
||||||
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
||||||
|
di.override(kubectlBinaryNameInjectable, () => "kubectl");
|
||||||
|
di.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
|
||||||
|
di.override(normalizedPlatformInjectable, () => "darwin");
|
||||||
|
|
||||||
const injectable = getInjectable({
|
const injectable = getInjectable({
|
||||||
id: "some-route",
|
id: "some-route",
|
||||||
|
|||||||
@ -50,11 +50,11 @@ export class LocalShellSession extends ShellSession {
|
|||||||
|
|
||||||
switch(path.basename(shell)) {
|
switch(path.basename(shell)) {
|
||||||
case "powershell.exe":
|
case "powershell.exe":
|
||||||
return ["-NoExit", "-command", `& {$Env:PATH="${baseBinariesDir.get()};${kubectlPathDir};$Env:PATH"}`];
|
return ["-NoExit", "-command", `& {$Env:PATH="${kubectlPathDir};${baseBinariesDir.get()};$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="${baseBinariesDir.get()}:${kubectlPathDir}:$PATH"; export KUBECONFIG="${await this.kubeconfigPathP}"`];
|
return ["--login", "--init-command", `export PATH="${kubectlPathDir}:${baseBinariesDir.get()}:$PATH"; export KUBECONFIG="${await this.kubeconfigPathP}"`];
|
||||||
case "zsh":
|
case "zsh":
|
||||||
return ["--login"];
|
return ["--login"];
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -311,7 +311,7 @@ export abstract class ShellSession {
|
|||||||
|
|
||||||
protected async getShellEnv() {
|
protected async getShellEnv() {
|
||||||
const env = clearKubeconfigEnvVars(JSON.parse(JSON.stringify(await shellEnv())));
|
const env = clearKubeconfigEnvVars(JSON.parse(JSON.stringify(await shellEnv())));
|
||||||
const pathStr = [...this.getPathEntries(), await this.kubectlBinDirP, process.env.PATH].join(path.delimiter);
|
const pathStr = [await this.kubectlBinDirP, ...this.getPathEntries(), process.env.PATH].join(path.delimiter);
|
||||||
const shell = UserStore.getInstance().resolvedShell;
|
const shell = UserStore.getInstance().resolvedShell;
|
||||||
|
|
||||||
delete env.DEBUG; // don't pass DEBUG into shells
|
delete env.DEBUG; // don't pass DEBUG into shells
|
||||||
|
|||||||
@ -26,6 +26,9 @@ import { computed } from "mobx";
|
|||||||
import { routeSpecificComponentInjectionToken } from "../../../routes/route-specific-component-injection-token";
|
import { routeSpecificComponentInjectionToken } from "../../../routes/route-specific-component-injection-token";
|
||||||
import { navigateToRouteInjectionToken } from "../../../../common/front-end-routing/navigate-to-route-injection-token";
|
import { navigateToRouteInjectionToken } from "../../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||||
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
|
import hotbarStoreInjectable from "../../../../common/hotbars/store.injectable";
|
||||||
|
import normalizedPlatformInjectable from "../../../../common/vars/normalized-platform.injectable";
|
||||||
|
import kubectlBinaryNameInjectable from "../../../../main/kubectl/binary-name.injectable";
|
||||||
|
import kubectlDownloadingNormalizedArchInjectable from "../../../../main/kubectl/normalized-arch.injectable";
|
||||||
|
|
||||||
jest.mock("electron", () => ({
|
jest.mock("electron", () => ({
|
||||||
app: {
|
app: {
|
||||||
@ -101,8 +104,11 @@ describe("<DeleteClusterDialog />", () => {
|
|||||||
applicationBuilder = getApplicationBuilder();
|
applicationBuilder = getApplicationBuilder();
|
||||||
|
|
||||||
applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => {
|
applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => {
|
||||||
mainDi.override(createContextHandlerInjectable, () => () => undefined as any);
|
mainDi.override(createContextHandlerInjectable, () => () => undefined as never);
|
||||||
mainDi.override(createKubeconfigManagerInjectable, () => () => undefined as any);
|
mainDi.override(createKubeconfigManagerInjectable, () => () => undefined as never);
|
||||||
|
mainDi.override(kubectlBinaryNameInjectable, () => "kubectl");
|
||||||
|
mainDi.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
|
||||||
|
mainDi.override(normalizedPlatformInjectable, () => "darwin");
|
||||||
|
|
||||||
rendererDi.override(hotbarStoreInjectable, () => ({}));
|
rendererDi.override(hotbarStoreInjectable, () => ({}));
|
||||||
rendererDi.override(storesAndApisCanBeCreatedInjectable, () => true);
|
rendererDi.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user