mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Create c&p folder before starting kube sync (#3428)
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
a6bb296f76
commit
9a8616f05e
@ -22,10 +22,9 @@
|
|||||||
import { action, observable, IComputedValue, computed, ObservableMap, runInAction, makeObservable, observe } from "mobx";
|
import { action, observable, IComputedValue, computed, ObservableMap, runInAction, makeObservable, observe } from "mobx";
|
||||||
import type { CatalogEntity } from "../../common/catalog";
|
import type { CatalogEntity } from "../../common/catalog";
|
||||||
import { catalogEntityRegistry } from "../../main/catalog";
|
import { catalogEntityRegistry } from "../../main/catalog";
|
||||||
import { watch } from "chokidar";
|
import { FSWatcher, watch } from "chokidar";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fse from "fs-extra";
|
|
||||||
import type stream from "stream";
|
import type stream from "stream";
|
||||||
import { Disposer, ExtendedObservableMap, iter, Singleton, storedKubeConfigFolder } from "../../common/utils";
|
import { Disposer, ExtendedObservableMap, iter, Singleton, storedKubeConfigFolder } from "../../common/utils";
|
||||||
import logger from "../logger";
|
import logger from "../logger";
|
||||||
@ -117,20 +116,15 @@ export class KubeconfigSyncManager extends Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
protected async startNewSync(filePath: string): Promise<void> {
|
protected startNewSync(filePath: string): void {
|
||||||
if (this.sources.has(filePath)) {
|
if (this.sources.has(filePath)) {
|
||||||
// don't start a new sync if we already have one
|
// don't start a new sync if we already have one
|
||||||
return void logger.debug(`${logPrefix} already syncing file/folder`, { filePath });
|
return void logger.debug(`${logPrefix} already syncing file/folder`, { filePath });
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
this.sources.set(filePath, watchFileChanges(filePath));
|
||||||
this.sources.set(filePath, await watchFileChanges(filePath));
|
logger.info(`${logPrefix} starting sync of file/folder`, { filePath });
|
||||||
|
logger.debug(`${logPrefix} ${this.sources.size} files/folders watched`, { files: Array.from(this.sources.keys()) });
|
||||||
logger.info(`${logPrefix} starting sync of file/folder`, { filePath });
|
|
||||||
logger.debug(`${logPrefix} ${this.sources.size} files/folders watched`, { files: Array.from(this.sources.keys()) });
|
|
||||||
} catch (error) {
|
|
||||||
logger.warn(`${logPrefix} failed to start watching changes: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -274,55 +268,69 @@ function diffChangedConfig(filePath: string, source: RootSource): Disposer {
|
|||||||
return cleanup;
|
return cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function watchFileChanges(filePath: string): Promise<[IComputedValue<CatalogEntity[]>, Disposer]> {
|
function watchFileChanges(filePath: string): [IComputedValue<CatalogEntity[]>, Disposer] {
|
||||||
const stat = await fse.stat(filePath); // traverses symlinks, is a race condition
|
|
||||||
const isFolderSync = stat.isDirectory();
|
|
||||||
const watcher = watch(filePath, {
|
|
||||||
followSymlinks: true,
|
|
||||||
depth: isFolderSync ? 0 : 1, // DIRs works with 0 but files need 1 (bug: https://github.com/paulmillr/chokidar/issues/1095)
|
|
||||||
disableGlobbing: true,
|
|
||||||
ignorePermissionErrors: true,
|
|
||||||
usePolling: false,
|
|
||||||
awaitWriteFinish: {
|
|
||||||
pollInterval: 100,
|
|
||||||
stabilityThreshold: 1000,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const rootSource = new ExtendedObservableMap<string, ObservableMap<string, RootSourceValue>>();
|
const rootSource = new ExtendedObservableMap<string, ObservableMap<string, RootSourceValue>>();
|
||||||
const derivedSource = computed(() => Array.from(iter.flatMap(rootSource.values(), from => iter.map(from.values(), child => child[1]))));
|
const derivedSource = computed(() => Array.from(iter.flatMap(rootSource.values(), from => iter.map(from.values(), child => child[1]))));
|
||||||
const cleanupFns = new Map<string, Disposer>();
|
|
||||||
|
|
||||||
watcher
|
let watcher: FSWatcher;
|
||||||
.on("change", (childFilePath) => {
|
|
||||||
const cleanup = cleanupFns.get(childFilePath);
|
|
||||||
|
|
||||||
if (!cleanup) {
|
(async () => {
|
||||||
// file was previously ignored, do nothing
|
try {
|
||||||
return void logger.debug(`${logPrefix} ${inspect(childFilePath)} that should have been previously ignored has changed. Doing nothing`);
|
const stat = await fs.promises.stat(filePath);
|
||||||
}
|
const isFolderSync = stat.isDirectory();
|
||||||
|
const cleanupFns = new Map<string, Disposer>();
|
||||||
|
|
||||||
cleanup();
|
watcher = watch(filePath, {
|
||||||
cleanupFns.set(childFilePath, diffChangedConfig(childFilePath, rootSource.getOrInsert(childFilePath, observable.map)));
|
followSymlinks: true,
|
||||||
})
|
depth: isFolderSync ? 0 : 1, // DIRs works with 0 but files need 1 (bug: https://github.com/paulmillr/chokidar/issues/1095)
|
||||||
.on("add", (childFilePath) => {
|
disableGlobbing: true,
|
||||||
if (isFolderSync) {
|
ignorePermissionErrors: true,
|
||||||
const fileName = path.basename(childFilePath);
|
usePolling: false,
|
||||||
|
awaitWriteFinish: {
|
||||||
|
pollInterval: 100,
|
||||||
|
stabilityThreshold: 1000,
|
||||||
|
},
|
||||||
|
atomic: 150, // for "atomic writes"
|
||||||
|
});
|
||||||
|
|
||||||
for (const ignoreGlob of ignoreGlobs) {
|
watcher
|
||||||
if (ignoreGlob.matcher.test(fileName)) {
|
.on("change", (childFilePath) => {
|
||||||
return void logger.info(`${logPrefix} ignoring ${inspect(childFilePath)} due to ignore glob: ${ignoreGlob.rawGlob}`);
|
const cleanup = cleanupFns.get(childFilePath);
|
||||||
|
|
||||||
|
if (!cleanup) {
|
||||||
|
// file was previously ignored, do nothing
|
||||||
|
return void logger.debug(`${logPrefix} ${inspect(childFilePath)} that should have been previously ignored has changed. Doing nothing`);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanupFns.set(childFilePath, diffChangedConfig(childFilePath, rootSource.getOrInsert(childFilePath, observable.map)));
|
cleanup();
|
||||||
})
|
cleanupFns.set(childFilePath, diffChangedConfig(childFilePath, rootSource.getOrInsert(childFilePath, observable.map)));
|
||||||
.on("unlink", (childFilePath) => {
|
})
|
||||||
cleanupFns.get(childFilePath)?.();
|
.on("add", (childFilePath) => {
|
||||||
cleanupFns.delete(childFilePath);
|
if (isFolderSync) {
|
||||||
rootSource.delete(childFilePath);
|
const fileName = path.basename(childFilePath);
|
||||||
})
|
|
||||||
.on("error", error => logger.error(`${logPrefix} watching file/folder failed: ${error}`, { filePath }));
|
|
||||||
|
|
||||||
return [derivedSource, () => watcher.close()];
|
for (const ignoreGlob of ignoreGlobs) {
|
||||||
|
if (ignoreGlob.matcher.test(fileName)) {
|
||||||
|
return void logger.info(`${logPrefix} ignoring ${inspect(childFilePath)} due to ignore glob: ${ignoreGlob.rawGlob}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanupFns.set(childFilePath, diffChangedConfig(childFilePath, rootSource.getOrInsert(childFilePath, observable.map)));
|
||||||
|
})
|
||||||
|
.on("unlink", (childFilePath) => {
|
||||||
|
cleanupFns.get(childFilePath)?.();
|
||||||
|
cleanupFns.delete(childFilePath);
|
||||||
|
rootSource.delete(childFilePath);
|
||||||
|
})
|
||||||
|
.on("error", error => logger.error(`${logPrefix} watching file/folder failed: ${error}`, { filePath }));
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error.stack);
|
||||||
|
logger.warn(`${logPrefix} failed to start watching changes: ${error}`);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
return [derivedSource, () => {
|
||||||
|
watcher?.close();
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,7 @@ import { WeblinkStore } from "../common/weblink-store";
|
|||||||
import { ExtensionsStore } from "../extensions/extensions-store";
|
import { ExtensionsStore } from "../extensions/extensions-store";
|
||||||
import { FilesystemProvisionerStore } from "./extension-filesystem";
|
import { FilesystemProvisionerStore } from "./extension-filesystem";
|
||||||
import { SentryInit } from "../common/sentry";
|
import { SentryInit } from "../common/sentry";
|
||||||
|
import { ensureDir } from "fs-extra";
|
||||||
|
|
||||||
// This has to be called before start using winton-based logger
|
// This has to be called before start using winton-based logger
|
||||||
// For example, before any logger.log
|
// For example, before any logger.log
|
||||||
@ -210,8 +211,9 @@ app.on("ready", async () => {
|
|||||||
windowManager.ensureMainWindow();
|
windowManager.ensureMainWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcMainOn(IpcRendererNavigationEvents.LOADED, () => {
|
ipcMainOn(IpcRendererNavigationEvents.LOADED, async () => {
|
||||||
cleanup.push(pushCatalogToRenderer(catalogEntityRegistry));
|
cleanup.push(pushCatalogToRenderer(catalogEntityRegistry));
|
||||||
|
await ensureDir(ClusterStore.storedKubeConfigFolder);
|
||||||
KubeconfigSyncManager.getInstance().startSync();
|
KubeconfigSyncManager.getInstance().startSync();
|
||||||
startUpdateChecking();
|
startUpdateChecking();
|
||||||
LensProtocolRouterMain.getInstance().rendererLoaded = true;
|
LensProtocolRouterMain.getInstance().rendererLoaded = true;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user