mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Remove BaseStore<T> and replace with composition of dependencies (#7002)
* Rename ExtensionStore -> BaseExtensionStore - The name was too close to ExtensionsStore Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move ExtensionsStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move ClusterStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move UserStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Cleanup types to remove multiple cast locations Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move HotbarStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move WeblinkStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Move FileSystemProvisionerStore to new format Signed-off-by: Sebastian Malton <sebastian@malton.name> * Update snapshots Signed-off-by: Sebastian Malton <sebastian@malton.name> * Clean up impl and rename to better describe intent Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix remaining type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the enabled extensions storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the clusters storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the hotbar storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the weblinks storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fully split apart the user preferences storage Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix crashing Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests and snapshots Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix integration test failures Signed-off-by: Sebastian Malton <sebastian@malton.name> * Improve typing to prevent errors in the future. Signed-off-by: Sebastian Malton <sebastian@malton.name> * Cleanup @k8slens/messaging and friends - To fix type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix lint issue Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix type errors Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix global override not being complete enough causing tests to fail Signed-off-by: Sebastian Malton <sebastian@malton.name> * Bump memory for unit tests on CI Signed-off-by: Sebastian Malton <sebastian@malton.name> * Attempt to fix memory issue on CI again Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fixup test because of new injectables Signed-off-by: Sebastian Malton <sebastian@malton.name> * Upgrade Jest Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix unit tests falling over Signed-off-by: Sebastian Malton <sebastian@malton.name> * Back out jest config change Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove console log Signed-off-by: Sebastian Malton <sebastian@malton.name> * Update snapshot Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests by matching equality instead of snapshots Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests by forcing specific snapshot style - Ubuntu CI seems to format arrays in snapshots differently than macOS locally Signed-off-by: Sebastian Malton <sebastian@malton.name> --------- Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
ba4a283af9
commit
49f0a1af9c
365 files changed
+6733
-3972
No files matched your search
@@ -3,12 +3,12 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { shouldBaseStoreDisableSyncInIpcListenerInjectionToken } from "../../common/base-store/disable-sync";
|
||||
import { shouldPersistentStorageDisableSyncInIpcListenerInjectionToken } from "../../common/persistent-storage/disable-sync";
|
||||
|
||||
const shouldBaseStoreDisableSyncInIpcListenerInjectable = getInjectable({
|
||||
id: "should-base-store-disable-sync-in-ipc-listener",
|
||||
instantiate: () => false,
|
||||
injectionToken: shouldBaseStoreDisableSyncInIpcListenerInjectionToken,
|
||||
injectionToken: shouldPersistentStorageDisableSyncInIpcListenerInjectionToken,
|
||||
});
|
||||
|
||||
export default shouldBaseStoreDisableSyncInIpcListenerInjectable;
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { baseStoreIpcChannelPrefixesInjectionToken } from "../../common/base-store/channel-prefix";
|
||||
import { persistentStorageIpcChannelPrefixesInjectionToken } from "../../common/persistent-storage/channel-prefix";
|
||||
|
||||
const baseStoreIpcChannelPrefixInjectable = getInjectable({
|
||||
id: "base-store-ipc-channel-prefix",
|
||||
@@ -11,7 +11,7 @@ const baseStoreIpcChannelPrefixInjectable = getInjectable({
|
||||
local: "store-sync-main",
|
||||
remote: "store-sync-renderer",
|
||||
}),
|
||||
injectionToken: baseStoreIpcChannelPrefixesInjectionToken,
|
||||
injectionToken: persistentStorageIpcChannelPrefixesInjectionToken,
|
||||
});
|
||||
|
||||
export default baseStoreIpcChannelPrefixInjectable;
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { persistStateToConfigInjectionToken } from "../../common/base-store/save-to-file";
|
||||
import { persistStateToConfigInjectionToken } from "../../common/persistent-storage/save-to-file";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
|
||||
const persistStateToConfigInjectable = getInjectable({
|
||||
|
||||
@@ -17,9 +17,6 @@ import type { ConfigToModels } from "../kubeconfig-sync/config-to-models.injecta
|
||||
import configToModelsInjectable from "../kubeconfig-sync/config-to-models.injectable";
|
||||
import kubeconfigSyncManagerInjectable from "../kubeconfig-sync/manager.injectable";
|
||||
import type { KubeconfigSyncManager } from "../kubeconfig-sync/manager";
|
||||
import type { KubeconfigSyncValue } from "../../../common/user-store";
|
||||
import kubeconfigSyncsInjectable from "../../../common/user-store/kubeconfig-syncs.injectable";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import type { AsyncFnMock } from "@async-fn/jest";
|
||||
import type { Stat } from "../../../common/fs/stat.injectable";
|
||||
@@ -36,12 +33,13 @@ import readJsonSyncInjectable from "../../../common/fs/read-json-sync.injectable
|
||||
import writeJsonSyncInjectable from "../../../common/fs/write-json-sync.injectable";
|
||||
import type { KubeconfigManager } from "../../kubeconfig-manager/kubeconfig-manager";
|
||||
import kubeconfigManagerInjectable from "../../kubeconfig-manager/kubeconfig-manager.injectable";
|
||||
import type { KubeconfigSyncValue } from "../../../features/user-preferences/common/preferences-helpers";
|
||||
import kubeconfigSyncsInjectable from "../../../features/user-preferences/common/kubeconfig-syncs.injectable";
|
||||
|
||||
describe("kubeconfig-sync.source tests", () => {
|
||||
let computeKubeconfigDiff: ComputeKubeconfigDiff;
|
||||
let configToModels: ConfigToModels;
|
||||
let kubeconfigSyncs: ObservableMap<string, KubeconfigSyncValue>;
|
||||
let clusters: Map<string, Cluster>;
|
||||
let di: DiContainer;
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -58,9 +56,6 @@ describe("kubeconfig-sync.source tests", () => {
|
||||
ensurePath: async () => "/some-proxy-kubeconfig-file",
|
||||
} as Partial<KubeconfigManager> as KubeconfigManager));
|
||||
|
||||
clusters = new Map();
|
||||
di.override(getClusterByIdInjectable, () => id => clusters.get(id));
|
||||
|
||||
kubeconfigSyncs = observable.map();
|
||||
|
||||
di.override(kubeconfigSyncsInjectable, () => kubeconfigSyncs);
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
export { syncWeblinks } from "./weblinks";
|
||||
@@ -9,7 +9,6 @@ import { action } from "mobx";
|
||||
import { homedir } from "os";
|
||||
import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
||||
import type { CatalogEntity } from "../../../common/catalog";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import { Cluster } from "../../../common/cluster/cluster";
|
||||
import { loadConfigFromString } from "../../../common/kube-helpers";
|
||||
import clustersThatAreBeingDeletedInjectable from "../../cluster/are-being-deleted.injectable";
|
||||
@@ -17,6 +16,7 @@ import { catalogEntityFromCluster } from "../../cluster/manager";
|
||||
import configToModelsInjectable from "./config-to-models.injectable";
|
||||
import kubeconfigSyncLoggerInjectable from "./logger.injectable";
|
||||
import clusterConnectionInjectable from "../../cluster/cluster-connection.injectable";
|
||||
import getClusterByIdInjectable from "../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
|
||||
export type ComputeKubeconfigDiff = (contents: string, source: ObservableMap<string, [Cluster, CatalogEntity]>, filePath: string) => void;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import directoryForKubeConfigsInjectable from "../../../common/app-paths/directo
|
||||
import { KubeconfigSyncManager } from "./manager";
|
||||
import kubeconfigSyncLoggerInjectable from "./logger.injectable";
|
||||
import watchKubeconfigFileChangesInjectable from "./watch-file-changes.injectable";
|
||||
import kubeconfigSyncsInjectable from "../../../common/user-store/kubeconfig-syncs.injectable";
|
||||
import kubeconfigSyncsInjectable from "../../../features/user-preferences/common/kubeconfig-syncs.injectable";
|
||||
|
||||
const kubeconfigSyncManagerInjectable = getInjectable({
|
||||
id: "kubeconfig-sync-manager",
|
||||
|
||||
@@ -8,9 +8,9 @@ import { action, observable, computed, makeObservable, observe } from "mobx";
|
||||
import type { CatalogEntity } from "../../../common/catalog";
|
||||
import type { Disposer } from "@k8slens/utilities";
|
||||
import { iter } from "@k8slens/utilities";
|
||||
import type { KubeconfigSyncValue } from "../../../common/user-store";
|
||||
import type { Logger } from "../../../common/logger";
|
||||
import type { WatchKubeconfigFileChanges } from "./watch-file-changes.injectable";
|
||||
import type { KubeconfigSyncValue } from "../../../features/user-preferences/common/preferences-helpers";
|
||||
|
||||
interface KubeconfigSyncManagerDependencies {
|
||||
readonly directoryForKubeConfigs: string;
|
||||
|
||||
@@ -1,19 +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 { syncWeblinks } from "./weblinks";
|
||||
import weblinkStoreInjectable from "../../common/weblinks-store/weblink-store.injectable";
|
||||
import catalogEntityRegistryInjectable from "../catalog/entity-registry.injectable";
|
||||
|
||||
const syncWeblinksInjectable = getInjectable({
|
||||
id: "sync-weblinks",
|
||||
|
||||
instantiate: (di) => syncWeblinks({
|
||||
weblinkStore: di.inject(weblinkStoreInjectable),
|
||||
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
export default syncWeblinksInjectable;
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { computed, observable, reaction } from "mobx";
|
||||
import type { WeblinkStore } from "../../common/weblinks-store/weblink-store";
|
||||
import { WebLink } from "../../common/catalog-entities";
|
||||
import type { CatalogEntityRegistry } from "../catalog";
|
||||
import got from "got";
|
||||
import type { Disposer } from "@k8slens/utilities";
|
||||
import { random } from "lodash";
|
||||
|
||||
async function validateLink(link: WebLink) {
|
||||
try {
|
||||
const response = await got.get(link.spec.url, {
|
||||
throwHttpErrors: false,
|
||||
timeout: 20_000,
|
||||
});
|
||||
|
||||
if (response.statusCode >= 200 && response.statusCode < 500) {
|
||||
link.status.phase = "available";
|
||||
} else {
|
||||
link.status.phase = "unavailable";
|
||||
}
|
||||
} catch {
|
||||
link.status.phase = "unavailable";
|
||||
}
|
||||
}
|
||||
|
||||
interface Dependencies {
|
||||
weblinkStore: WeblinkStore;
|
||||
catalogEntityRegistry: CatalogEntityRegistry;
|
||||
}
|
||||
|
||||
export const syncWeblinks = ({ weblinkStore, catalogEntityRegistry }: Dependencies) => () => {
|
||||
const webLinkEntities = observable.map<string, [WebLink, Disposer]>();
|
||||
|
||||
function periodicallyCheckLink(link: WebLink): Disposer {
|
||||
validateLink(link);
|
||||
|
||||
let interval: NodeJS.Timeout;
|
||||
const timeout = setTimeout(() => {
|
||||
interval = setInterval(() => validateLink(link), 60 * 60 * 1000); // every 60 minutes
|
||||
}, random(0, 5 * 60 * 1000, false)); // spread out over 5 minutes
|
||||
|
||||
return () => {
|
||||
clearTimeout(timeout);
|
||||
clearInterval(interval);
|
||||
};
|
||||
}
|
||||
|
||||
reaction(() => weblinkStore.weblinks, (links) => {
|
||||
const seenWeblinks = new Set<string>();
|
||||
|
||||
for (const weblinkData of links) {
|
||||
seenWeblinks.add(weblinkData.id);
|
||||
|
||||
if (!webLinkEntities.has(weblinkData.id)) {
|
||||
const link = new WebLink({
|
||||
metadata: {
|
||||
uid: weblinkData.id,
|
||||
name: weblinkData.name,
|
||||
source: "local",
|
||||
labels: {},
|
||||
},
|
||||
spec: {
|
||||
url: weblinkData.url,
|
||||
},
|
||||
status: {
|
||||
phase: "available",
|
||||
active: true,
|
||||
},
|
||||
});
|
||||
|
||||
webLinkEntities.set(weblinkData.id, [
|
||||
link,
|
||||
periodicallyCheckLink(link),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop checking and remove weblinks that are no longer in the store
|
||||
for (const [weblinkId, [, disposer]] of webLinkEntities) {
|
||||
if (!seenWeblinks.has(weblinkId)) {
|
||||
disposer();
|
||||
webLinkEntities.delete(weblinkId);
|
||||
}
|
||||
}
|
||||
}, { fireImmediately: true });
|
||||
|
||||
catalogEntityRegistry.addComputedSource("weblinks", computed(() => Array.from(webLinkEntities.values(), ([link]) => link)));
|
||||
};
|
||||
@@ -3,8 +3,10 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import clusterStoreInjectable from "../../common/cluster-store/cluster-store.injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import addClusterInjectable from "../../features/cluster/storage/common/add.injectable";
|
||||
import clustersInjectable from "../../features/cluster/storage/common/clusters.injectable";
|
||||
import getClusterByIdInjectable from "../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import catalogEntityRegistryInjectable from "../catalog/entity-registry.injectable";
|
||||
import clustersThatAreBeingDeletedInjectable from "./are-being-deleted.injectable";
|
||||
import clusterConnectionInjectable from "./cluster-connection.injectable";
|
||||
@@ -17,11 +19,13 @@ const clusterManagerInjectable = getInjectable({
|
||||
id: "cluster-manager",
|
||||
|
||||
instantiate: (di) => new ClusterManager({
|
||||
store: di.inject(clusterStoreInjectable),
|
||||
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
clustersThatAreBeingDeleted: di.inject(clustersThatAreBeingDeletedInjectable),
|
||||
visibleCluster: di.inject(visibleClusterInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
addCluster: di.inject(addClusterInjectable),
|
||||
clusters: di.inject(clustersInjectable),
|
||||
getClusterById: di.inject(getClusterByIdInjectable),
|
||||
updateEntityMetadata: di.inject(updateEntityMetadataInjectable),
|
||||
updateEntitySpec: di.inject(updateEntitySpecInjectable),
|
||||
getClusterConnection: (cluster) => di.inject(clusterConnectionInjectable, cluster),
|
||||
|
||||
@@ -4,34 +4,37 @@
|
||||
*/
|
||||
|
||||
import "../../common/ipc/cluster";
|
||||
import type { IObservableValue, ObservableSet } from "mobx";
|
||||
import type { IComputedValue, IObservableValue, ObservableSet } from "mobx";
|
||||
import { action, makeObservable, observe, reaction, toJS } from "mobx";
|
||||
import type { Cluster } from "../../common/cluster/cluster";
|
||||
import { isErrnoException } from "@k8slens/utilities";
|
||||
import { isKubernetesCluster, KubernetesCluster, LensKubernetesClusterStatus } from "../../common/catalog-entities/kubernetes-cluster";
|
||||
import { ipcMainOn } from "../../common/ipc";
|
||||
import { once } from "lodash";
|
||||
import type { ClusterStore } from "../../common/cluster-store/cluster-store";
|
||||
import type { ClusterId } from "../../common/cluster-types";
|
||||
import type { CatalogEntityRegistry } from "../catalog";
|
||||
import type { Logger } from "../../common/logger";
|
||||
import type { UpdateEntityMetadata } from "./update-entity-metadata.injectable";
|
||||
import type { UpdateEntitySpec } from "./update-entity-spec.injectable";
|
||||
import type { ClusterConnection } from "./cluster-connection.injectable";
|
||||
import type { GetClusterById } from "../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import type { AddCluster } from "../../features/cluster/storage/common/add.injectable";
|
||||
|
||||
const logPrefix = "[CLUSTER-MANAGER]:";
|
||||
|
||||
const lensSpecificClusterStatuses: Set<string> = new Set(Object.values(LensKubernetesClusterStatus));
|
||||
|
||||
interface Dependencies {
|
||||
readonly store: ClusterStore;
|
||||
readonly catalogEntityRegistry: CatalogEntityRegistry;
|
||||
readonly clustersThatAreBeingDeleted: ObservableSet<ClusterId>;
|
||||
readonly visibleCluster: IObservableValue<ClusterId | null>;
|
||||
readonly logger: Logger;
|
||||
readonly clusters: IComputedValue<Cluster[]>;
|
||||
updateEntityMetadata: UpdateEntityMetadata;
|
||||
updateEntitySpec: UpdateEntitySpec;
|
||||
getClusterConnection: (cluster: Cluster) => ClusterConnection;
|
||||
getClusterById: GetClusterById;
|
||||
addCluster: AddCluster;
|
||||
}
|
||||
|
||||
export class ClusterManager {
|
||||
@@ -42,15 +45,15 @@ export class ClusterManager {
|
||||
init = once(() => {
|
||||
// reacting to every cluster's state change and total amount of items
|
||||
reaction(
|
||||
() => this.dependencies.store.clustersList.map(c => c.getState()),
|
||||
() => this.updateCatalog(this.dependencies.store.clustersList),
|
||||
() => this.dependencies.clusters.get().map(c => c.getState()),
|
||||
() => this.updateCatalog(this.dependencies.clusters.get()),
|
||||
{ fireImmediately: false },
|
||||
);
|
||||
|
||||
// reacting to every cluster's preferences change and total amount of items
|
||||
reaction(
|
||||
() => this.dependencies.store.clustersList.map(c => toJS(c.preferences)),
|
||||
() => this.updateCatalog(this.dependencies.store.clustersList),
|
||||
() => this.dependencies.clusters.get().map(c => toJS(c.preferences)),
|
||||
() => this.updateCatalog(this.dependencies.clusters.get()),
|
||||
{ fireImmediately: false },
|
||||
);
|
||||
|
||||
@@ -152,7 +155,7 @@ export class ClusterManager {
|
||||
@action
|
||||
protected syncClustersFromCatalog(entities: KubernetesCluster[]) {
|
||||
for (const entity of entities) {
|
||||
const cluster = this.dependencies.store.getById(entity.getId());
|
||||
const cluster = this.dependencies.getClusterById(entity.getId());
|
||||
|
||||
if (!cluster) {
|
||||
const model = {
|
||||
@@ -167,7 +170,7 @@ export class ClusterManager {
|
||||
* Add the bare minimum of data to ClusterStore. And especially no
|
||||
* preferences, as those might be configured by the entity's source
|
||||
*/
|
||||
this.dependencies.store.addCluster(model);
|
||||
this.dependencies.addCluster(model);
|
||||
} catch (error) {
|
||||
if (isErrnoException(error) && error.code === "ENOENT" && error.path === entity.spec.kubeconfigPath) {
|
||||
this.dependencies.logger.warn(`${logPrefix} kubeconfig file disappeared`, model);
|
||||
@@ -208,7 +211,9 @@ export class ClusterManager {
|
||||
this.dependencies.logger.info(`${logPrefix} network is offline`);
|
||||
|
||||
await Promise.allSettled(
|
||||
this.dependencies.store.clustersList
|
||||
this.dependencies
|
||||
.clusters
|
||||
.get()
|
||||
.filter(cluster => !cluster.disconnected.get())
|
||||
.map(async (cluster) => {
|
||||
cluster.online.set(false);
|
||||
@@ -225,7 +230,9 @@ export class ClusterManager {
|
||||
this.dependencies.logger.info(`${logPrefix} network is online`);
|
||||
|
||||
await Promise.allSettled(
|
||||
this.dependencies.store.clustersList
|
||||
this.dependencies
|
||||
.clusters
|
||||
.get()
|
||||
.filter(cluster => !cluster.disconnected.get())
|
||||
.map((cluster) => (
|
||||
this.dependencies
|
||||
@@ -236,7 +243,7 @@ export class ClusterManager {
|
||||
};
|
||||
|
||||
stop() {
|
||||
for (const cluster of this.dependencies.store.clustersList) {
|
||||
for (const cluster of this.dependencies.clusters.get()) {
|
||||
this.dependencies
|
||||
.getClusterConnection(cluster)
|
||||
.disconnect();
|
||||
|
||||
@@ -18,7 +18,7 @@ interface Pre360ClusterModel extends ClusterModel {
|
||||
}
|
||||
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { clusterStoreMigrationInjectionToken } from "../../../common/cluster-store/migration-token";
|
||||
import { clusterStoreMigrationInjectionToken } from "../../../features/cluster/storage/common/migration-token";
|
||||
import readFileBufferSyncInjectable from "../../../common/fs/read-file-buffer-sync.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import writeFileSyncInjectable from "../../../common/fs/write-file-sync.injectable";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||
import { clusterStoreMigrationInjectionToken } from "../../../common/cluster-store/migration-token";
|
||||
import { clusterStoreMigrationInjectionToken } from "../../../features/cluster/storage/common/migration-token";
|
||||
import type { ClusterModel } from "../../../common/cluster-types";
|
||||
import readJsonSyncInjectable from "../../../common/fs/read-json-sync.injectable";
|
||||
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
||||
|
||||
@@ -10,7 +10,7 @@ import { isDefined } from "@k8slens/utilities";
|
||||
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import { clusterStoreMigrationInjectionToken } from "../../../common/cluster-store/migration-token";
|
||||
import { clusterStoreMigrationInjectionToken } from "../../../features/cluster/storage/common/migration-token";
|
||||
import { generateNewIdFor } from "../../../common/utils/generate-new-id-for";
|
||||
|
||||
interface Pre500ClusterModel extends ClusterModel {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Fix embedded kubeconfig paths under snap config
|
||||
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { clusterStoreMigrationInjectionToken } from "../../../common/cluster-store/migration-token";
|
||||
import { clusterStoreMigrationInjectionToken } from "../../../features/cluster/storage/common/migration-token";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import isSnapPackageInjectable from "../../../common/vars/is-snap-package.injectable";
|
||||
import type { ClusterModel } from "../../../common/cluster-types";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import { shouldShowResourceInjectionToken } from "../../common/cluster-store/allowed-resources-injection-token";
|
||||
import { shouldShowResourceInjectionToken } from "../../features/cluster/showing-kube-resources/common/allowed-resources-injection-token";
|
||||
import type { KubeApiResourceDescriptor } from "../../common/rbac";
|
||||
import { formatKubeApiResource } from "../../common/rbac";
|
||||
|
||||
|
||||
+3
-3
@@ -5,12 +5,12 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { setupIpcMainHandlers } from "./setup-ipc-main-handlers";
|
||||
import loggerInjectable from "../../../../common/logger.injectable";
|
||||
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
|
||||
import { onLoadOfApplicationInjectionToken } from "@k8slens/application";
|
||||
import applicationMenuItemCompositeInjectable from "../../../../features/application-menu/main/application-menu-item-composite.injectable";
|
||||
import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import pushCatalogToRendererInjectable from "../../../catalog-sync-to-renderer/push-catalog-to-renderer.injectable";
|
||||
import clusterFramesInjectable from "../../../../common/cluster-frames.injectable";
|
||||
import getClusterByIdInjectable from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import clustersInjectable from "../../../../features/cluster/storage/common/clusters.injectable";
|
||||
|
||||
const setupIpcMainHandlersInjectable = getInjectable({
|
||||
id: "setup-ipc-main-handlers",
|
||||
@@ -24,7 +24,7 @@ const setupIpcMainHandlersInjectable = getInjectable({
|
||||
setupIpcMainHandlers({
|
||||
applicationMenuItemComposite: di.inject(applicationMenuItemCompositeInjectable),
|
||||
pushCatalogToRenderer: di.inject(pushCatalogToRendererInjectable),
|
||||
clusterStore: di.inject(clusterStoreInjectable),
|
||||
clusters: di.inject(clustersInjectable),
|
||||
getClusterById: di.inject(getClusterByIdInjectable),
|
||||
clusterFrames: di.inject(clusterFramesInjectable),
|
||||
});
|
||||
|
||||
+6
-5
@@ -7,7 +7,6 @@ import { BrowserWindow, Menu } from "electron";
|
||||
import type { ClusterFrameInfo } from "../../../../common/cluster-frames.injectable";
|
||||
import { clusterSetFrameIdHandler, clusterStates } from "../../../../common/ipc/cluster";
|
||||
import type { ClusterId } from "../../../../common/cluster-types";
|
||||
import type { ClusterStore } from "../../../../common/cluster-store/cluster-store";
|
||||
import { broadcastMainChannel, broadcastMessage, ipcMainHandle, ipcMainOn } from "../../../../common/ipc";
|
||||
import type { IComputedValue, ObservableMap } from "mobx";
|
||||
import { windowActionHandleChannel, windowLocationChangedChannel, windowOpenAppMenuAsContextMenuChannel } from "../../../../common/ipc/window";
|
||||
@@ -16,21 +15,23 @@ import type { ApplicationMenuItemTypes } from "../../../../features/application-
|
||||
import type { Composite } from "../../../../common/utils/composite/get-composite/get-composite";
|
||||
import { getApplicationMenuTemplate } from "../../../../features/application-menu/main/populate-application-menu.injectable";
|
||||
import type { MenuItemRoot } from "../../../../features/application-menu/main/application-menu-item-composite.injectable";
|
||||
import type { GetClusterById } from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { GetClusterById } from "../../../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import type { Cluster } from "../../../../common/cluster/cluster";
|
||||
|
||||
interface Dependencies {
|
||||
applicationMenuItemComposite: IComputedValue<Composite<ApplicationMenuItemTypes | MenuItemRoot>>;
|
||||
clusterStore: ClusterStore;
|
||||
getClusterById: GetClusterById;
|
||||
pushCatalogToRenderer: () => void;
|
||||
clusterFrames: ObservableMap<string, ClusterFrameInfo>;
|
||||
clusters: IComputedValue<Cluster[]>;
|
||||
}
|
||||
|
||||
export const setupIpcMainHandlers = ({
|
||||
applicationMenuItemComposite,
|
||||
clusterStore,
|
||||
getClusterById,
|
||||
pushCatalogToRenderer,
|
||||
clusterFrames,
|
||||
clusters,
|
||||
}: Dependencies) => {
|
||||
ipcMainHandle(clusterSetFrameIdHandler, (event: IpcMainInvokeEvent, clusterId: ClusterId) => {
|
||||
const cluster = getClusterById(clusterId);
|
||||
@@ -60,7 +61,7 @@ export const setupIpcMainHandlers = ({
|
||||
});
|
||||
|
||||
ipcMainHandle(clusterStates, () => (
|
||||
clusterStore.clustersList.map(cluster => ({
|
||||
clusters.get().map(cluster => ({
|
||||
id: cluster.id,
|
||||
state: cluster.getState(),
|
||||
}))
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { Writable } from "type-fest";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import { createExtensionInstanceInjectionToken } from "../../extensions/extension-loader/create-extension-instance.token";
|
||||
import fileSystemProvisionerStoreInjectable from "../../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable";
|
||||
import ensureHashedDirectoryForExtensionInjectable from "../../extensions/extension-loader/file-system-provisioner-store/ensure-hashed-directory-for-extension.injectable";
|
||||
import { lensExtensionDependencies } from "../../extensions/lens-extension";
|
||||
import type { LensMainExtensionDependencies } from "../../extensions/lens-extension-set-dependencies";
|
||||
import type { LensMainExtension } from "../../extensions/lens-main-extension";
|
||||
@@ -17,7 +17,7 @@ const createExtensionInstanceInjectable = getInjectable({
|
||||
id: "create-extension-instance",
|
||||
instantiate: (di) => {
|
||||
const deps: LensMainExtensionDependencies = {
|
||||
fileSystemProvisionerStore: di.inject(fileSystemProvisionerStoreInjectable),
|
||||
ensureHashedDirectoryForExtension: di.inject(ensureHashedDirectoryForExtensionInjectable),
|
||||
entityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||
navigate: di.inject(navigateForExtensionInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
|
||||
@@ -10,7 +10,7 @@ import spawnInjectable from "./child-process/spawn.injectable";
|
||||
import initializeExtensionsInjectable from "./start-main-application/runnables/initialize-extensions.injectable";
|
||||
import setupIpcMainHandlersInjectable from "./electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable";
|
||||
import setupLensProxyInjectable from "./start-main-application/runnables/setup-lens-proxy.injectable";
|
||||
import setupSyncingOfWeblinksInjectable from "./start-main-application/runnables/setup-syncing-of-weblinks.injectable";
|
||||
import setupSyncingOfWeblinksInjectable from "../features/weblinks/main/setup-syncing-of-weblinks.injectable";
|
||||
import setupDeepLinkingInjectable from "./electron-app/runnables/setup-deep-linking.injectable";
|
||||
import setupMainWindowVisibilityAfterActivationInjectable from "./electron-app/runnables/setup-main-window-visibility-after-activation.injectable";
|
||||
import setupDeviceShutdownInjectable from "./electron-app/runnables/setup-device-shutdown.injectable";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import httpsProxyConfigurationInjectable from "../../../common/user-store/https-proxy.injectable";
|
||||
import httpsProxyConfigurationInjectable from "../../../features/user-preferences/common/https-proxy.injectable";
|
||||
|
||||
const execHelmEnvInjectable = getInjectable({
|
||||
id: "exec-helm-env",
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
// Cleans up a store that had the state related data stored
|
||||
import { getEmptyHotbar } from "../../../common/hotbars/types";
|
||||
import catalogCatalogEntityInjectable from "../../../common/catalog-entities/general-catalog-entities/implementations/catalog-catalog-entity.injectable";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { hotbarStoreMigrationInjectionToken } from "../../../common/hotbars/migrations-token";
|
||||
|
||||
const v500Alpha0HotbarStoreMigrationInjectable = getInjectable({
|
||||
id: "v5.0.0-alpha.0-hotbar-store-migration",
|
||||
instantiate: (di) => {
|
||||
const catalogCatalogEntity = di.inject(catalogCatalogEntityInjectable);
|
||||
|
||||
return {
|
||||
version: "5.0.0-alpha.0",
|
||||
run(store) {
|
||||
const hotbar = getEmptyHotbar("default");
|
||||
|
||||
const { metadata: { uid, name, source }} = catalogCatalogEntity;
|
||||
|
||||
hotbar.items[0] = { entity: { uid, name, source }};
|
||||
|
||||
store.set("hotbars", [hotbar]);
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: hotbarStoreMigrationInjectionToken,
|
||||
});
|
||||
|
||||
export default v500Alpha0HotbarStoreMigrationInjectable;
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
// Cleans up a store that had the state related data stored
|
||||
import type { Hotbar } from "../../../common/hotbars/types";
|
||||
import * as uuid from "uuid";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { hotbarStoreMigrationInjectionToken } from "../../../common/hotbars/migrations-token";
|
||||
|
||||
const v500Alpha2HotbarStoreMigrationInjectable = getInjectable({
|
||||
id: "v5.0.0-alpha.2-hotbar-store-migration",
|
||||
instantiate: () => ({
|
||||
version: "5.0.0-alpha.2",
|
||||
run(store) {
|
||||
const rawHotbars = store.get("hotbars");
|
||||
const hotbars: Hotbar[] = Array.isArray(rawHotbars) ? rawHotbars : [];
|
||||
|
||||
store.set("hotbars", hotbars.map(({ id, ...rest }) => ({
|
||||
id: id || uuid.v4(),
|
||||
...rest,
|
||||
})));
|
||||
},
|
||||
}),
|
||||
injectionToken: hotbarStoreMigrationInjectionToken,
|
||||
});
|
||||
|
||||
export default v500Alpha2HotbarStoreMigrationInjectable;
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import * as uuid from "uuid";
|
||||
import type { Hotbar, HotbarItem } from "../../../common/hotbars/types";
|
||||
import { defaultHotbarCells, getEmptyHotbar } from "../../../common/hotbars/types";
|
||||
import { getLegacyGlobalDiForExtensionApi } from "../../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||
import catalogCatalogEntityInjectable from "../../../common/catalog-entities/general-catalog-entities/implementations/catalog-catalog-entity.injectable";
|
||||
import { isDefined, isErrnoException } from "@k8slens/utilities";
|
||||
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { hotbarStoreMigrationInjectionToken } from "../../../common/hotbars/migrations-token";
|
||||
import readJsonSyncInjectable from "../../../common/fs/read-json-sync.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import { generateNewIdFor } from "../../../common/utils/generate-new-id-for";
|
||||
import type { ClusterModel } from "../../../common/cluster-types";
|
||||
|
||||
interface Pre500WorkspaceStoreModel {
|
||||
workspaces: {
|
||||
id: string;
|
||||
name: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
interface PartialHotbar {
|
||||
id: string;
|
||||
name: string;
|
||||
items: (null | HotbarItem)[];
|
||||
}
|
||||
|
||||
interface Pre500ClusterModel extends ClusterModel {
|
||||
workspace?: string;
|
||||
workspaces?: string[];
|
||||
}
|
||||
|
||||
interface Pre500ClusterStoreModel {
|
||||
clusters?: Pre500ClusterModel[];
|
||||
}
|
||||
|
||||
const v500Beta10HotbarStoreMigrationInjectable = getInjectable({
|
||||
id: "v5.0.0-beta.10-hotbar-store-migration",
|
||||
instantiate: (di) => {
|
||||
const userDataPath = di.inject(directoryForUserDataInjectable);
|
||||
const joinPaths = di.inject(joinPathsInjectable);
|
||||
const readJsonSync = di.inject(readJsonSyncInjectable);
|
||||
const catalogCatalogEntity = di.inject(catalogCatalogEntityInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
|
||||
return {
|
||||
version: "5.0.0-beta.10",
|
||||
run(store) {
|
||||
const rawHotbars = store.get("hotbars");
|
||||
const hotbars: Hotbar[] = Array.isArray(rawHotbars) ? rawHotbars.filter(h => h && typeof h === "object") : [];
|
||||
|
||||
|
||||
// Hotbars might be empty, if some of the previous migrations weren't run
|
||||
if (hotbars.length === 0) {
|
||||
const hotbar = getEmptyHotbar("default");
|
||||
const { metadata: { uid, name, source }} = catalogCatalogEntity;
|
||||
|
||||
hotbar.items[0] = { entity: { uid, name, source }};
|
||||
|
||||
hotbars.push(hotbar);
|
||||
}
|
||||
|
||||
try {
|
||||
const workspaceStoreData: Pre500WorkspaceStoreModel = readJsonSync(joinPaths(userDataPath, "lens-workspace-store.json"));
|
||||
const { clusters = [] }: Pre500ClusterStoreModel = readJsonSync(joinPaths(userDataPath, "lens-cluster-store.json"));
|
||||
const workspaceHotbars = new Map<string, PartialHotbar>(); // mapping from WorkspaceId to HotBar
|
||||
|
||||
for (const { id, name } of workspaceStoreData.workspaces) {
|
||||
logger.info(`Creating new hotbar for ${name}`);
|
||||
workspaceHotbars.set(id, {
|
||||
id: uuid.v4(), // don't use the old IDs as they aren't necessarily UUIDs
|
||||
items: [],
|
||||
name: `Workspace: ${name}`,
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
// grab the default named hotbar or the first.
|
||||
const defaultHotbarIndex = Math.max(0, hotbars.findIndex(hotbar => hotbar.name === "default"));
|
||||
const [{ name, id, items }] = hotbars.splice(defaultHotbarIndex, 1);
|
||||
|
||||
workspaceHotbars.set("default", {
|
||||
name,
|
||||
id,
|
||||
items: items.filter(isDefined),
|
||||
});
|
||||
}
|
||||
|
||||
for (const cluster of clusters) {
|
||||
const uid = generateNewIdFor(cluster);
|
||||
|
||||
for (const workspaceId of cluster.workspaces ?? [cluster.workspace].filter(isDefined)) {
|
||||
const workspaceHotbar = workspaceHotbars.get(workspaceId);
|
||||
|
||||
if (!workspaceHotbar) {
|
||||
logger.info(`Cluster ${uid} has unknown workspace ID, skipping`);
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.info(`Adding cluster ${uid} to ${workspaceHotbar.name}`);
|
||||
|
||||
if (workspaceHotbar?.items.length < defaultHotbarCells) {
|
||||
workspaceHotbar.items.push({
|
||||
entity: {
|
||||
uid: generateNewIdFor(cluster),
|
||||
name: cluster.preferences?.clusterName || cluster.contextName,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const hotbar of workspaceHotbars.values()) {
|
||||
if (hotbar.items.length === 0) {
|
||||
logger.info(`Skipping ${hotbar.name} due to it being empty`);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (hotbar.items.length < defaultHotbarCells) {
|
||||
hotbar.items.push(null);
|
||||
}
|
||||
|
||||
hotbars.push(hotbar as Hotbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finally, make sure that the catalog entity hotbar item is in place.
|
||||
* Just in case something else removed it.
|
||||
*
|
||||
* if every hotbar has elements that all not the `catalog-entity` item
|
||||
*/
|
||||
if (hotbars.every(hotbar => hotbar.items.every(item => item?.entity?.uid !== "catalog-entity"))) {
|
||||
// note, we will add a new whole hotbar here called "default" if that was previously removed
|
||||
const di = getLegacyGlobalDiForExtensionApi();
|
||||
const catalogCatalogEntity = di.inject(catalogCatalogEntityInjectable);
|
||||
|
||||
const defaultHotbar = hotbars.find(hotbar => hotbar.name === "default");
|
||||
const { metadata: { uid, name, source }} = catalogCatalogEntity;
|
||||
|
||||
if (defaultHotbar) {
|
||||
const freeIndex = defaultHotbar.items.findIndex(i => i === null);
|
||||
|
||||
if (freeIndex === -1) {
|
||||
// making a new hotbar is less destructive if the first hotbar
|
||||
// called "default" is full than overriding a hotbar item
|
||||
const hotbar = getEmptyHotbar("initial");
|
||||
|
||||
hotbar.items[0] = { entity: { uid, name, source }};
|
||||
hotbars.unshift(hotbar);
|
||||
} else {
|
||||
defaultHotbar.items[freeIndex] = { entity: { uid, name, source }};
|
||||
}
|
||||
} else {
|
||||
const hotbar = getEmptyHotbar("default");
|
||||
|
||||
hotbar.items[0] = { entity: { uid, name, source }};
|
||||
hotbars.unshift(hotbar);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
// ignore files being missing
|
||||
if (isErrnoException(error) && error.code !== "ENOENT") {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
store.set("hotbars", hotbars);
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: hotbarStoreMigrationInjectionToken,
|
||||
});
|
||||
|
||||
export default v500Beta10HotbarStoreMigrationInjectable;
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { Hotbar } from "../../../common/hotbars/types";
|
||||
import catalogEntityRegistryInjectable from "../../catalog/entity-registry.injectable";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { hotbarStoreMigrationInjectionToken } from "../../../common/hotbars/migrations-token";
|
||||
|
||||
const v500Beta5HotbarStoreMigrationInjectable = getInjectable({
|
||||
id: "v500-beta5-hotbar-store-migration",
|
||||
instantiate: (di) => {
|
||||
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
|
||||
|
||||
return {
|
||||
version: "5.0.0-beta.5",
|
||||
run(store) {
|
||||
const rawHotbars = store.get("hotbars");
|
||||
const hotbars: Hotbar[] = Array.isArray(rawHotbars) ? rawHotbars : [];
|
||||
|
||||
for (const hotbar of hotbars) {
|
||||
for (let i = 0; i < hotbar.items.length; i += 1) {
|
||||
const item = hotbar.items[i];
|
||||
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const entity = catalogEntityRegistry.findById(item.entity.uid);
|
||||
|
||||
if (!entity) {
|
||||
// Clear disabled item
|
||||
hotbar.items[i] = null;
|
||||
} else {
|
||||
// Save additional data
|
||||
item.entity = {
|
||||
...item.entity,
|
||||
name: entity.metadata.name,
|
||||
source: entity.metadata.source,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
store.set("hotbars", hotbars);
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: hotbarStoreMigrationInjectionToken,
|
||||
});
|
||||
|
||||
export default v500Beta5HotbarStoreMigrationInjectable;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* 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 getClusterByIdInjectable from "../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import resourceApplierInjectable from "../resource-applier/create-resource-applier.injectable";
|
||||
import { getRequestChannelListenerInjectable } from "@k8slens/messaging";
|
||||
|
||||
@@ -15,14 +15,16 @@ const kubectlApplyAllChannelHandlerInjectable = getRequestChannelListenerInjecta
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||
|
||||
return async ({
|
||||
clusterId,
|
||||
extraArgs,
|
||||
resources,
|
||||
}) => {
|
||||
emitAppEvent({ name: "cluster", action: "kubectl-apply-all" });
|
||||
return async (event) => {
|
||||
const {
|
||||
clusterId,
|
||||
extraArgs,
|
||||
resources,
|
||||
} = event;
|
||||
const cluster = getClusterById(clusterId);
|
||||
|
||||
emitAppEvent({ name: "cluster", action: "kubectl-apply-all" });
|
||||
|
||||
if (!cluster) {
|
||||
return {
|
||||
callWasSuccessful: false,
|
||||
|
||||
@@ -6,7 +6,6 @@ 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";
|
||||
@@ -20,6 +19,7 @@ import getBasenameOfPathInjectable from "../../common/path/get-basename.injectab
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import execFileInjectable from "../../common/fs/exec-file.injectable";
|
||||
import unlinkInjectable from "../../common/fs/unlink.injectable";
|
||||
import userPreferencesStateInjectable from "../../features/user-preferences/common/state.injectable";
|
||||
|
||||
export type CreateKubectl = (version: string) => Kubectl;
|
||||
|
||||
@@ -28,7 +28,7 @@ const createKubectlInjectable = getInjectable({
|
||||
|
||||
instantiate: (di): CreateKubectl => {
|
||||
const dependencies: KubectlDependencies = {
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
state: di.inject(userPreferencesStateInjectable),
|
||||
directoryForKubectlBinaries: di.inject(directoryForKubectlBinariesInjectable),
|
||||
normalizedDownloadArch: di.inject(kubectlDownloadingNormalizedArchInjectable),
|
||||
normalizedDownloadPlatform: di.inject(normalizedPlatformInjectable),
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* 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 getClusterByIdInjectable from "../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import resourceApplierInjectable from "../resource-applier/create-resource-applier.injectable";
|
||||
import { getRequestChannelListenerInjectable } from "@k8slens/messaging";
|
||||
|
||||
@@ -15,15 +15,16 @@ const kubectlDeleteAllChannelHandlerInjectable = getRequestChannelListenerInject
|
||||
const emitAppEvent = di.inject(emitAppEventInjectable);
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
|
||||
return async ({
|
||||
clusterId,
|
||||
extraArgs,
|
||||
resources,
|
||||
}) => {
|
||||
emitAppEvent({ name: "cluster", action: "kubectl-delete-all" });
|
||||
|
||||
return async (event) => {
|
||||
const {
|
||||
clusterId,
|
||||
extraArgs,
|
||||
resources,
|
||||
} = event;
|
||||
const cluster = getClusterById(clusterId);
|
||||
|
||||
emitAppEvent({ name: "cluster", action: "kubectl-delete-all" });
|
||||
|
||||
if (!cluster) {
|
||||
return {
|
||||
callWasSuccessful: false,
|
||||
|
||||
@@ -7,7 +7,6 @@ import fs from "fs";
|
||||
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";
|
||||
@@ -20,6 +19,7 @@ import type { Logger } from "../../common/logger";
|
||||
import type { ExecFile } from "../../common/fs/exec-file.injectable";
|
||||
import { hasTypedProperty, isObject, isString, json } from "@k8slens/utilities";
|
||||
import type { Unlink } from "../../common/fs/unlink.injectable";
|
||||
import { packageMirrors, defaultPackageMirror } from "../../features/user-preferences/common/preferences-helpers";
|
||||
|
||||
const initScriptVersionString = "# lens-initscript v3";
|
||||
|
||||
@@ -30,7 +30,7 @@ export interface KubectlDependencies {
|
||||
readonly kubectlBinaryName: string;
|
||||
readonly bundledKubectlBinaryPath: string;
|
||||
readonly baseBundeledBinariesDirectory: string;
|
||||
readonly userStore: {
|
||||
readonly state: {
|
||||
readonly kubectlBinariesPath?: string;
|
||||
readonly downloadBinariesPath?: string;
|
||||
readonly downloadKubectlBinaries: boolean;
|
||||
@@ -91,12 +91,12 @@ export class Kubectl {
|
||||
}
|
||||
|
||||
public getPathFromPreferences() {
|
||||
return this.dependencies.userStore.kubectlBinariesPath || this.getBundledPath();
|
||||
return this.dependencies.state.kubectlBinariesPath || this.getBundledPath();
|
||||
}
|
||||
|
||||
protected getDownloadDir() {
|
||||
if (this.dependencies.userStore.downloadBinariesPath) {
|
||||
return this.dependencies.joinPaths(this.dependencies.userStore.downloadBinariesPath, "kubectl");
|
||||
if (this.dependencies.state.downloadBinariesPath) {
|
||||
return this.dependencies.joinPaths(this.dependencies.state.downloadBinariesPath, "kubectl");
|
||||
}
|
||||
|
||||
return this.dependencies.directoryForKubectlBinaries;
|
||||
@@ -107,7 +107,7 @@ export class Kubectl {
|
||||
return this.getBundledPath();
|
||||
}
|
||||
|
||||
if (this.dependencies.userStore.downloadKubectlBinaries === false) {
|
||||
if (this.dependencies.state.downloadKubectlBinaries === false) {
|
||||
return this.getPathFromPreferences();
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ export class Kubectl {
|
||||
}
|
||||
|
||||
public async ensureKubectl(): Promise<boolean> {
|
||||
if (this.dependencies.userStore.downloadKubectlBinaries === false) {
|
||||
if (this.dependencies.state.downloadKubectlBinaries === false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ export class Kubectl {
|
||||
|
||||
protected async writeInitScripts() {
|
||||
const binariesDir = this.dependencies.baseBundeledBinariesDirectory;
|
||||
const kubectlPath = this.dependencies.userStore.downloadKubectlBinaries
|
||||
const kubectlPath = this.dependencies.state.downloadKubectlBinaries
|
||||
? this.dirname
|
||||
: this.dependencies.getDirnameOfPath(this.getPathFromPreferences());
|
||||
|
||||
@@ -370,7 +370,7 @@ export class Kubectl {
|
||||
protected getDownloadMirror(): string {
|
||||
// MacOS packages are only available from default
|
||||
|
||||
const { url } = packageMirrors.get(this.dependencies.userStore.downloadMirror)
|
||||
const { url } = packageMirrors.get(this.dependencies.state.downloadMirror)
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
?? packageMirrors.get(defaultPackageMirror)!;
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable";
|
||||
import { getClusterIdFromHost } from "../../common/utils";
|
||||
import { apiKubePrefix } from "../../common/vars";
|
||||
import getClusterByIdInjectable from "../../features/cluster/storage/common/get-by-id.injectable";
|
||||
import type { GetClusterForRequest } from "./lens-proxy";
|
||||
|
||||
const getClusterForRequestInjectable = getInjectable({
|
||||
|
||||
@@ -6,12 +6,10 @@
|
||||
import * as uuid from "uuid";
|
||||
|
||||
import { ProtocolHandlerExtension, ProtocolHandlerInternal, ProtocolHandlerInvalid } from "../../../common/protocol-handler";
|
||||
import { delay, noop } from "@k8slens/utilities";
|
||||
import type { ExtensionsStore, IsEnabledExtensionDescriptor } from "../../../extensions/extensions-store/extensions-store";
|
||||
import { noop } from "@k8slens/utilities";
|
||||
import type { LensProtocolRouterMain } from "../lens-protocol-router-main/lens-protocol-router-main";
|
||||
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
|
||||
import lensProtocolRouterMainInjectable from "../lens-protocol-router-main/lens-protocol-router-main.injectable";
|
||||
import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable";
|
||||
import getConfigurationFileModelInjectable from "../../../common/get-configuration-file-model/get-configuration-file-model.injectable";
|
||||
import { LensExtension } from "../../../extensions/lens-extension";
|
||||
import type { ObservableMap } from "mobx";
|
||||
@@ -23,6 +21,8 @@ import pathExistsInjectable from "../../../common/fs/path-exists.injectable";
|
||||
import readJsonSyncInjectable from "../../../common/fs/read-json-sync.injectable";
|
||||
import writeJsonSyncInjectable from "../../../common/fs/write-json-sync.injectable";
|
||||
import type { LensExtensionId } from "@k8slens/legacy-extensions";
|
||||
import type { LensExtensionState } from "../../../features/extensions/enabled/common/state.injectable";
|
||||
import enabledExtensionsStateInjectable from "../../../features/extensions/enabled/common/state.injectable";
|
||||
|
||||
function throwIfDefined(val: any): void {
|
||||
if (val != null) {
|
||||
@@ -33,7 +33,7 @@ function throwIfDefined(val: any): void {
|
||||
describe("protocol router tests", () => {
|
||||
let extensionInstances: ObservableMap<LensExtensionId, LensExtension>;
|
||||
let lpr: LensProtocolRouterMain;
|
||||
let enabledExtensions: Set<string>;
|
||||
let enabledExtensions: ObservableMap<LensExtensionId, LensExtensionState>;
|
||||
let broadcastMessageMock: jest.Mock;
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -44,11 +44,7 @@ describe("protocol router tests", () => {
|
||||
di.override(readJsonSyncInjectable, () => () => { throw new Error("tried call readJsonSync without override"); });
|
||||
di.override(writeJsonSyncInjectable, () => () => { throw new Error("tried call writeJsonSync without override"); });
|
||||
|
||||
enabledExtensions = new Set();
|
||||
|
||||
di.override(extensionsStoreInjectable, () => ({
|
||||
isEnabled: ({ id, isBundled }: IsEnabledExtensionDescriptor) => isBundled || enabledExtensions.has(id),
|
||||
} as unknown as ExtensionsStore));
|
||||
enabledExtensions = di.inject(enabledExtensionsStateInjectable);
|
||||
|
||||
di.permitSideEffects(getConfigurationFileModelInjectable);
|
||||
|
||||
@@ -95,7 +91,7 @@ describe("protocol router tests", () => {
|
||||
});
|
||||
|
||||
extensionInstances.set(extId, ext);
|
||||
enabledExtensions.add(extId);
|
||||
enabledExtensions.set(extId, { name: "@mirantis/minikube", enabled: true });
|
||||
|
||||
lpr.addInternalHandler("/", noop);
|
||||
|
||||
@@ -105,14 +101,14 @@ describe("protocol router tests", () => {
|
||||
expect(throwIfDefined(error)).not.toThrow();
|
||||
}
|
||||
|
||||
expect(broadcastMessageMock).toHaveBeenCalledWith(ProtocolHandlerInternal, "lens://app", "matched");
|
||||
|
||||
try {
|
||||
expect(await lpr.route("lens://extension/@mirantis/minikube")).toBeUndefined();
|
||||
} catch (error) {
|
||||
expect(throwIfDefined(error)).not.toThrow();
|
||||
}
|
||||
|
||||
await delay(50);
|
||||
expect(broadcastMessageMock).toHaveBeenCalledWith(ProtocolHandlerInternal, "lens://app", "matched");
|
||||
expect(broadcastMessageMock).toHaveBeenCalledWith(ProtocolHandlerExtension, "lens://extension/@mirantis/minikube", "matched");
|
||||
});
|
||||
|
||||
@@ -175,7 +171,7 @@ describe("protocol router tests", () => {
|
||||
});
|
||||
|
||||
extensionInstances.set(extId, ext);
|
||||
enabledExtensions.add(extId);
|
||||
enabledExtensions.set(extId, { name: "@foobar/icecream", enabled: true });
|
||||
|
||||
try {
|
||||
expect(await lpr.route("lens://extension/@foobar/icecream/page/foob")).toBeUndefined();
|
||||
@@ -183,7 +179,6 @@ describe("protocol router tests", () => {
|
||||
expect(throwIfDefined(error)).not.toThrow();
|
||||
}
|
||||
|
||||
await delay(50);
|
||||
expect(called).toBe("foob");
|
||||
expect(broadcastMessageMock).toBeCalledWith(ProtocolHandlerExtension, "lens://extension/@foobar/icecream/page/foob", "matched");
|
||||
});
|
||||
@@ -214,7 +209,7 @@ describe("protocol router tests", () => {
|
||||
});
|
||||
|
||||
extensionInstances.set(extId, ext);
|
||||
enabledExtensions.add(extId);
|
||||
enabledExtensions.set(extId, { name: "@foobar/icecream", enabled: true });
|
||||
}
|
||||
|
||||
{
|
||||
@@ -240,19 +235,15 @@ describe("protocol router tests", () => {
|
||||
});
|
||||
|
||||
extensionInstances.set(extId, ext);
|
||||
enabledExtensions.add(extId);
|
||||
enabledExtensions.set(extId, { name: "icecream", enabled: true });
|
||||
}
|
||||
|
||||
enabledExtensions.add("@foobar/icecream");
|
||||
enabledExtensions.add("icecream");
|
||||
|
||||
try {
|
||||
expect(await lpr.route("lens://extension/icecream/page")).toBeUndefined();
|
||||
} catch (error) {
|
||||
expect(throwIfDefined(error)).not.toThrow();
|
||||
}
|
||||
|
||||
await delay(50);
|
||||
|
||||
expect(called).toBe(1);
|
||||
expect(broadcastMessageMock).toBeCalledWith(ProtocolHandlerExtension, "lens://extension/icecream/page", "matched");
|
||||
|
||||
+8
-9
@@ -5,22 +5,21 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import extensionLoaderInjectable from "../../../extensions/extension-loader/extension-loader.injectable";
|
||||
import { LensProtocolRouterMain } from "./lens-protocol-router-main";
|
||||
import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable";
|
||||
import showApplicationWindowInjectable from "../../start-main-application/lens-window/show-application-window.injectable";
|
||||
import broadcastMessageInjectable from "../../../common/ipc/broadcast-message.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import isExtensionEnabledInjectable from "../../../features/extensions/enabled/common/is-enabled.injectable";
|
||||
|
||||
const lensProtocolRouterMainInjectable = getInjectable({
|
||||
id: "lens-protocol-router-main",
|
||||
|
||||
instantiate: (di) =>
|
||||
new LensProtocolRouterMain({
|
||||
extensionLoader: di.inject(extensionLoaderInjectable),
|
||||
extensionsStore: di.inject(extensionsStoreInjectable),
|
||||
showApplicationWindow: di.inject(showApplicationWindowInjectable),
|
||||
broadcastMessage: di.inject(broadcastMessageInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
}),
|
||||
instantiate: (di) => new LensProtocolRouterMain({
|
||||
extensionLoader: di.inject(extensionLoaderInjectable),
|
||||
isExtensionEnabled: di.inject(isExtensionEnabledInjectable),
|
||||
showApplicationWindow: di.inject(showApplicationWindowInjectable),
|
||||
broadcastMessage: di.inject(broadcastMessageInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
export default lensProtocolRouterMainInjectable;
|
||||
+14
-2
@@ -119,7 +119,13 @@ export class LensProtocolRouterMain extends proto.LensProtocolRouter {
|
||||
const rawUrl = url.toString(); // for sending to renderer
|
||||
const attempt = super._routeToInternal(url);
|
||||
|
||||
this.disposers.push(when(() => this.rendererLoaded, () => this.dependencies.broadcastMessage(proto.ProtocolHandlerInternal, rawUrl, attempt)));
|
||||
const sendRoutingToRenderer = () => this.dependencies.broadcastMessage(proto.ProtocolHandlerInternal, rawUrl, attempt);
|
||||
|
||||
if (this.rendererLoaded) {
|
||||
sendRoutingToRenderer();
|
||||
} else {
|
||||
this.disposers.push(when(() => this.rendererLoaded, sendRoutingToRenderer));
|
||||
}
|
||||
|
||||
return attempt;
|
||||
}
|
||||
@@ -136,7 +142,13 @@ export class LensProtocolRouterMain extends proto.LensProtocolRouter {
|
||||
*/
|
||||
const attempt = await super._routeToExtension(new URLParse(url.toString(), true));
|
||||
|
||||
this.disposers.push(when(() => this.rendererLoaded, () => this.dependencies.broadcastMessage(proto.ProtocolHandlerExtension, rawUrl, attempt)));
|
||||
const sendRoutingToRenderer = () => this.dependencies.broadcastMessage(proto.ProtocolHandlerExtension, rawUrl, attempt);
|
||||
|
||||
if (this.rendererLoaded) {
|
||||
sendRoutingToRenderer();
|
||||
} else {
|
||||
this.disposers.push(when(() => this.rendererLoaded, sendRoutingToRenderer));
|
||||
}
|
||||
|
||||
return attempt;
|
||||
}
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { UserStore } from "../../../common/user-store";
|
||||
import type { ShellSessionArgs, ShellSessionDependencies } from "../shell-session";
|
||||
import { ShellSession } from "../shell-session";
|
||||
import type { ModifyTerminalShellEnv } from "../shell-env-modifier/modify-terminal-shell-env.injectable";
|
||||
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 { UserPreferencesState } from "../../../features/user-preferences/common/state.injectable";
|
||||
|
||||
export interface LocalShellSessionDependencies extends ShellSessionDependencies {
|
||||
readonly directoryForBinaries: string;
|
||||
readonly userStore: UserStore;
|
||||
readonly state: UserPreferencesState;
|
||||
modifyTerminalShellEnv: ModifyTerminalShellEnv;
|
||||
joinPaths: JoinPaths;
|
||||
getDirnameOfPath: GetDirnameOfPath;
|
||||
@@ -50,8 +50,8 @@ export class LocalShellSession extends ShellSession {
|
||||
}
|
||||
|
||||
protected async getShellArgs(shell: string): Promise<string[]> {
|
||||
const pathFromPreferences = this.dependencies.userStore.kubectlBinariesPath || this.kubectl.getBundledPath();
|
||||
const kubectlPathDir = this.dependencies.userStore.downloadKubectlBinaries
|
||||
const pathFromPreferences = this.dependencies.state.kubectlBinariesPath || this.kubectl.getBundledPath();
|
||||
const kubectlPathDir = this.dependencies.state.downloadKubectlBinaries
|
||||
? this.dependencies.directoryContainingKubectl
|
||||
: this.dependencies.getDirnameOfPath(pathFromPreferences);
|
||||
|
||||
|
||||
@@ -12,19 +12,19 @@ import isMacInjectable from "../../../common/vars/is-mac.injectable";
|
||||
import type { Cluster } from "../../../common/cluster/cluster";
|
||||
import isWindowsInjectable from "../../../common/vars/is-windows.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import userStoreInjectable from "../../../common/user-store/user-store.injectable";
|
||||
import type WebSocket from "ws";
|
||||
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 computeShellEnvironmentInjectable from "../../../features/shell-sync/main/compute-shell-environment.injectable";
|
||||
import spawnPtyInjectable from "../spawn-pty.injectable";
|
||||
import userShellSettingInjectable from "../../../common/user-store/shell-setting.injectable";
|
||||
import appNameInjectable from "../../../common/vars/app-name.injectable";
|
||||
import buildVersionInjectable from "../../vars/build-version/build-version.injectable";
|
||||
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||
import statInjectable from "../../../common/fs/stat.injectable";
|
||||
import kubeconfigManagerInjectable from "../../kubeconfig-manager/kubeconfig-manager.injectable";
|
||||
import userPreferencesStateInjectable from "../../../features/user-preferences/common/state.injectable";
|
||||
import userShellSettingInjectable from "../../../features/user-preferences/common/shell-setting.injectable";
|
||||
|
||||
export interface OpenLocalShellSessionArgs {
|
||||
websocket: WebSocket;
|
||||
@@ -44,7 +44,7 @@ const openLocalShellSessionInjectable = getInjectable({
|
||||
isMac: di.inject(isMacInjectable),
|
||||
isWindows: di.inject(isWindowsInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
userStore: di.inject(userStoreInjectable),
|
||||
state: di.inject(userPreferencesStateInjectable),
|
||||
userShellSetting: di.inject(userShellSettingInjectable),
|
||||
appName: di.inject(appNameInjectable),
|
||||
buildVersion: di.inject(buildVersionInjectable),
|
||||
|
||||
@@ -14,7 +14,6 @@ import loggerInjectable from "../../../common/logger.injectable";
|
||||
import createKubeJsonApiForClusterInjectable from "../../../common/k8s-api/create-kube-json-api-for-cluster.injectable";
|
||||
import computeShellEnvironmentInjectable from "../../../features/shell-sync/main/compute-shell-environment.injectable";
|
||||
import spawnPtyInjectable from "../spawn-pty.injectable";
|
||||
import userShellSettingInjectable from "../../../common/user-store/shell-setting.injectable";
|
||||
import appNameInjectable from "../../../common/vars/app-name.injectable";
|
||||
import buildVersionInjectable from "../../vars/build-version/build-version.injectable";
|
||||
import emitAppEventInjectable from "../../../common/app-event-bus/emit-event.injectable";
|
||||
@@ -22,6 +21,7 @@ import statInjectable from "../../../common/fs/stat.injectable";
|
||||
import createKubeApiInjectable from "../../../common/k8s-api/create-kube-api.injectable";
|
||||
import loadProxyKubeconfigInjectable from "../../cluster/load-proxy-kubeconfig.injectable";
|
||||
import kubeconfigManagerInjectable from "../../kubeconfig-manager/kubeconfig-manager.injectable";
|
||||
import userShellSettingInjectable from "../../../features/user-preferences/common/shell-setting.injectable";
|
||||
|
||||
export interface NodeShellSessionArgs {
|
||||
websocket: WebSocket;
|
||||
|
||||
-23
@@ -1,23 +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 { onLoadOfApplicationInjectionToken } from "@k8slens/application";
|
||||
import syncWeblinksInjectable from "../../catalog-sources/sync-weblinks.injectable";
|
||||
|
||||
const setupSyncingOfWeblinksInjectable = getInjectable({
|
||||
id: "setup-syncing-of-weblinks",
|
||||
|
||||
instantiate: (di) => ({
|
||||
run: () => {
|
||||
const syncWeblinks = di.inject(syncWeblinksInjectable);
|
||||
|
||||
syncWeblinks();
|
||||
},
|
||||
}),
|
||||
|
||||
injectionToken: onLoadOfApplicationInjectionToken,
|
||||
});
|
||||
|
||||
export default setupSyncingOfWeblinksInjectable;
|
||||
@@ -1,26 +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 userStoreFileNameMigrationInjectable from "../../common/user-store/file-name-migration.injectable";
|
||||
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
||||
import { beforeApplicationIsLoadingInjectionToken } from "@k8slens/application";
|
||||
import initDefaultUpdateChannelInjectable from "../vars/default-update-channel/init.injectable";
|
||||
|
||||
const initUserStoreInjectable = getInjectable({
|
||||
id: "init-user-store",
|
||||
instantiate: (di) => ({
|
||||
run: async () => {
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
const userStoreFileNameMigration = di.inject(userStoreFileNameMigrationInjectable);
|
||||
|
||||
await userStoreFileNameMigration();
|
||||
userStore.load();
|
||||
},
|
||||
runAfter: initDefaultUpdateChannelInjectable,
|
||||
}),
|
||||
injectionToken: beforeApplicationIsLoadingInjectionToken,
|
||||
});
|
||||
|
||||
export default initUserStoreInjectable;
|
||||
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
// Switch representation of hiddenTableColumns in store
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { userStoreMigrationInjectionToken } from "../../../common/user-store/migrations-token";
|
||||
|
||||
interface PreV500Alpha3UserPreferencesModel {
|
||||
hiddenTableColumns?: Record<string, string[]>;
|
||||
}
|
||||
|
||||
const v500Alpha3UserStoreMigrationInjectable = getInjectable({
|
||||
id: "v5.0.0-alpha.3-user-store-migration",
|
||||
instantiate: () => ({
|
||||
version: "5.0.0-alpha.3",
|
||||
run(store) {
|
||||
const preferences = (store.get("preferences") ?? {}) as PreV500Alpha3UserPreferencesModel;
|
||||
const oldHiddenTableColumns = preferences.hiddenTableColumns;
|
||||
|
||||
if (!oldHiddenTableColumns) {
|
||||
return;
|
||||
}
|
||||
|
||||
store.set("preferences", {
|
||||
...preferences,
|
||||
hiddenTableColumns: Object.entries(oldHiddenTableColumns),
|
||||
});
|
||||
},
|
||||
}),
|
||||
injectionToken: userStoreMigrationInjectionToken,
|
||||
});
|
||||
|
||||
export default v500Alpha3UserStoreMigrationInjectable;
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { ClusterStoreModel } from "../../../common/cluster-store/cluster-store";
|
||||
import type { KubeconfigSyncEntry, UserPreferencesModel } from "../../../common/user-store";
|
||||
import { isErrnoException } from "@k8slens/utilities";
|
||||
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
|
||||
import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
||||
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
||||
import isLogicalChildPathInjectable from "../../../common/path/is-logical-child-path.injectable";
|
||||
import getDirnameOfPathInjectable from "../../../common/path/get-dirname.injectable";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { userStoreMigrationInjectionToken } from "../../../common/user-store/migrations-token";
|
||||
import readJsonSyncInjectable from "../../../common/fs/read-json-sync.injectable";
|
||||
import homeDirectoryPathInjectable from "../../../common/os/home-directory-path.injectable";
|
||||
import loggerInjectable from "../../../common/logger.injectable";
|
||||
import pathExistsSyncInjectable from "../../../common/fs/path-exists-sync.injectable";
|
||||
|
||||
const v503Beta1UserStoreMigrationInjectable = getInjectable({
|
||||
id: "v5.0.3-beta.1-user-store-migration",
|
||||
instantiate: (di) => {
|
||||
const userDataPath = di.inject(directoryForUserDataInjectable);
|
||||
const kubeConfigsPath = di.inject(directoryForKubeConfigsInjectable);
|
||||
const joinPaths = di.inject(joinPathsInjectable);
|
||||
const logger = di.inject(loggerInjectable);
|
||||
const isLogicalChildPath = di.inject(isLogicalChildPathInjectable);
|
||||
const getDirnameOfPath = di.inject(getDirnameOfPathInjectable);
|
||||
const readJsonSync = di.inject(readJsonSyncInjectable);
|
||||
const homeDirectoryPath = di.inject(homeDirectoryPathInjectable);
|
||||
const pathExistsSync = di.inject(pathExistsSyncInjectable);
|
||||
|
||||
return {
|
||||
version: "5.0.3-beta.1",
|
||||
run(store) {
|
||||
try {
|
||||
const { syncKubeconfigEntries = [], ...preferences } = (store.get("preferences") ?? {}) as UserPreferencesModel;
|
||||
const { clusters = [] }: ClusterStoreModel = readJsonSync(joinPaths(userDataPath, "lens-cluster-store.json"), "utf-8") ?? {};
|
||||
const extensionDataDir = joinPaths(userDataPath, "extension_data");
|
||||
const syncPaths = new Set(syncKubeconfigEntries.map(s => s.filePath));
|
||||
|
||||
syncPaths.add(joinPaths(homeDirectoryPath, ".kube"));
|
||||
|
||||
for (const cluster of clusters) {
|
||||
if (!cluster.kubeConfigPath) {
|
||||
continue;
|
||||
}
|
||||
const dirOfKubeconfig = getDirnameOfPath(cluster.kubeConfigPath);
|
||||
|
||||
if (dirOfKubeconfig === kubeConfigsPath) {
|
||||
logger.info(`Skipping ${cluster.id} because kubeConfigPath is under the stored KubeConfig folder`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (syncPaths.has(cluster.kubeConfigPath) || syncPaths.has(dirOfKubeconfig)) {
|
||||
logger.info(`Skipping ${cluster.id} because kubeConfigPath is already being synced`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isLogicalChildPath(extensionDataDir, cluster.kubeConfigPath)) {
|
||||
logger.info(`Skipping ${cluster.id} because kubeConfigPath is placed under an extension_data folder`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pathExistsSync(cluster.kubeConfigPath)) {
|
||||
logger.info(`Skipping ${cluster.id} because kubeConfigPath no longer exists`);
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.info(`Adding ${cluster.kubeConfigPath} from ${cluster.id} to sync paths`);
|
||||
syncPaths.add(cluster.kubeConfigPath);
|
||||
}
|
||||
|
||||
const updatedSyncEntries: KubeconfigSyncEntry[] = [...syncPaths].map(filePath => ({ filePath }));
|
||||
|
||||
logger.info("Final list of synced paths", updatedSyncEntries);
|
||||
store.set("preferences", { ...preferences, syncKubeconfigEntries: updatedSyncEntries });
|
||||
} catch (error) {
|
||||
if (isErrnoException(error) && error.code !== "ENOENT") {
|
||||
// ignore files being missing
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: userStoreMigrationInjectionToken,
|
||||
});
|
||||
|
||||
export default v503Beta1UserStoreMigrationInjectable;
|
||||
@@ -1,32 +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 { reaction } from "mobx";
|
||||
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
||||
import setLoginItemSettingsInjectable from "../electron-app/features/set-login-item-settings.injectable";
|
||||
import { onLoadOfApplicationInjectionToken } from "@k8slens/application";
|
||||
|
||||
const setupSyncOpenAtLoginWithOsInjectable = getInjectable({
|
||||
id: "setup-sync-open-at-login-with-os",
|
||||
instantiate: (di) => ({
|
||||
run: () => {
|
||||
const setLoginItemSettings = di.inject(setLoginItemSettingsInjectable);
|
||||
const userStore = di.inject(userStoreInjectable);
|
||||
|
||||
reaction(() => userStore.openAtLogin, openAtLogin => {
|
||||
setLoginItemSettings({
|
||||
openAtLogin,
|
||||
openAsHidden: true,
|
||||
args: ["--hidden"],
|
||||
});
|
||||
}, {
|
||||
fireImmediately: true,
|
||||
});
|
||||
},
|
||||
}),
|
||||
injectionToken: onLoadOfApplicationInjectionToken,
|
||||
});
|
||||
|
||||
export default setupSyncOpenAtLoginWithOsInjectable;
|
||||
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
|
||||
export const lensWebsiteWeblinkId = "lens-website-link";
|
||||
export const lensWebsiteLinkName = "Lens Website";
|
||||
|
||||
export const lensDocumentationWeblinkId = "lens-documentation-link";
|
||||
export const lensDocumentationWeblinkName = "Lens Documentation";
|
||||
|
||||
export const lensForumsWeblinkId = "lens-forums-link";
|
||||
export const lensForumsWeblinkName = "Lens Forums";
|
||||
|
||||
export const lensTwitterWeblinkId = "lens-twitter-link";
|
||||
export const lensTwitterWeblinkName = "Lens on Twitter";
|
||||
|
||||
export const lensBlogWeblinkId = "lens-blog-link";
|
||||
export const lensBlogWeblinkName = "Lens Official Blog";
|
||||
|
||||
export const kubernetesDocumentationWeblinkId = "kubernetes-documentation-link";
|
||||
export const kubernetesDocumentationWeblinkName = "Kubernetes Documentation";
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { docsUrl, forumsUrl } from "../../../common/vars";
|
||||
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
|
||||
import * as links from "../links";
|
||||
|
||||
const v514WeblinkStoreMigrationInjectable = getInjectable({
|
||||
id: "v5.1.4-weblink-store-migration",
|
||||
instantiate: () => ({
|
||||
version: "5.1.4",
|
||||
run(store) {
|
||||
const weblinksRaw = store.get("weblinks");
|
||||
const weblinks = (Array.isArray(weblinksRaw) ? weblinksRaw : []) as WeblinkData[];
|
||||
|
||||
weblinks.push(
|
||||
{ id: "https://k8slens.dev", name: links.lensWebsiteLinkName, url: "https://k8slens.dev" },
|
||||
{ id: docsUrl, name: links.lensDocumentationWeblinkName, url: docsUrl },
|
||||
{ id: forumsUrl, name: links.lensForumsWeblinkName, url: forumsUrl },
|
||||
{ id: "https://twitter.com/k8slens", name: links.lensTwitterWeblinkName, url: "https://twitter.com/k8slens" },
|
||||
{ id: "https://medium.com/k8slens", name: links.lensBlogWeblinkName, url: "https://medium.com/k8slens" },
|
||||
{ id: "https://kubernetes.io/docs/home/", name: links.kubernetesDocumentationWeblinkName, url: "https://kubernetes.io/docs/home/" },
|
||||
);
|
||||
|
||||
store.set("weblinks", weblinks);
|
||||
},
|
||||
}),
|
||||
injectionToken: weblinkStoreMigrationInjectionToken,
|
||||
});
|
||||
|
||||
export default v514WeblinkStoreMigrationInjectable;
|
||||
@@ -1,61 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
|
||||
import * as links from "../links";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
|
||||
|
||||
const v545Beta1WeblinkStoreMigrationInjectable = getInjectable({
|
||||
id: "v5.4.5-beta.1-weblink-store-migration",
|
||||
instantiate: () => ({
|
||||
version: "5.4.5-beta.1 || >=5.5.0-alpha.0",
|
||||
run(store) {
|
||||
const weblinksRaw = store.get("weblinks");
|
||||
const weblinks = (Array.isArray(weblinksRaw) ? weblinksRaw : []) as WeblinkData[];
|
||||
|
||||
const lensWebsite = weblinks.find(weblink => weblink.name === links.lensWebsiteLinkName);
|
||||
|
||||
if (lensWebsite) {
|
||||
lensWebsite.id = links.lensWebsiteWeblinkId;
|
||||
}
|
||||
|
||||
const lensDocumentationWeblink = weblinks.find(weblink => weblink.name === links.lensDocumentationWeblinkName);
|
||||
|
||||
if (lensDocumentationWeblink) {
|
||||
lensDocumentationWeblink.id = links.lensDocumentationWeblinkId;
|
||||
}
|
||||
|
||||
const lensForumsWeblink = weblinks.find(weblink => weblink.name === links.lensForumsWeblinkName);
|
||||
|
||||
if (lensForumsWeblink) {
|
||||
lensForumsWeblink.id = links.lensForumsWeblinkId;
|
||||
}
|
||||
|
||||
const lensTwitterWeblink = weblinks.find(weblink => weblink.name === links.lensTwitterWeblinkName);
|
||||
|
||||
if (lensTwitterWeblink) {
|
||||
lensTwitterWeblink.id = links.lensTwitterWeblinkId;
|
||||
}
|
||||
|
||||
const lensBlogWeblink = weblinks.find(weblink => weblink.name === links.lensBlogWeblinkName);
|
||||
|
||||
if (lensBlogWeblink) {
|
||||
lensBlogWeblink.id = links.lensBlogWeblinkId;
|
||||
}
|
||||
|
||||
const kubernetesDocumentationWeblink = weblinks.find(weblink => weblink.name === links.kubernetesDocumentationWeblinkName);
|
||||
|
||||
if (kubernetesDocumentationWeblink) {
|
||||
kubernetesDocumentationWeblink.id = links.kubernetesDocumentationWeblinkId;
|
||||
}
|
||||
|
||||
store.set("weblinks", weblinks);
|
||||
},
|
||||
}),
|
||||
injectionToken: weblinkStoreMigrationInjectionToken,
|
||||
});
|
||||
|
||||
export default v545Beta1WeblinkStoreMigrationInjectable;
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { docsUrl, forumsUrl } from "../../../common/vars";
|
||||
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
|
||||
import { lensDocumentationWeblinkId, lensForumsWeblinkId } from "../links";
|
||||
import { applicationInformationToken } from "@k8slens/application";
|
||||
|
||||
const currentVersionWeblinkStoreMigrationInjectable = getInjectable({
|
||||
id: "current-version-weblink-store-migration",
|
||||
instantiate: (di) => {
|
||||
const { version } = di.inject(applicationInformationToken);
|
||||
|
||||
return {
|
||||
version, // Run always after upgrade
|
||||
run(store) {
|
||||
const weblinksRaw = store.get("weblinks");
|
||||
const weblinks = (Array.isArray(weblinksRaw) ? weblinksRaw : []) as WeblinkData[];
|
||||
const forumsWeblink = weblinks.find(weblink => weblink.id === lensForumsWeblinkId);
|
||||
|
||||
if (forumsWeblink) {
|
||||
forumsWeblink.url = forumsUrl;
|
||||
}
|
||||
|
||||
const docsWeblink = weblinks.find(weblink => weblink.id === lensDocumentationWeblinkId);
|
||||
|
||||
if (docsWeblink) {
|
||||
docsWeblink.url = docsUrl;
|
||||
}
|
||||
|
||||
const removedSlackLink = weblinks.filter(weblink => weblink.id !== "lens-slack-link");
|
||||
|
||||
store.set("weblinks", removedSlackLink);
|
||||
},
|
||||
};
|
||||
},
|
||||
injectionToken: weblinkStoreMigrationInjectionToken,
|
||||
});
|
||||
|
||||
export default currentVersionWeblinkStoreMigrationInjectable;
|
||||
Reference in new issue
Block a user