1
0
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:
Sebastian Malton 2021-08-04 08:02:21 -04:00 committed by GitHub
parent a6bb296f76
commit 9a8616f05e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 54 deletions

View File

@ -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.info(`${logPrefix} starting sync of file/folder`, { filePath });
logger.debug(`${logPrefix} ${this.sources.size} files/folders watched`, { files: Array.from(this.sources.keys()) }); 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,10 +268,19 @@ 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 rootSource = new ExtendedObservableMap<string, ObservableMap<string, RootSourceValue>>();
const derivedSource = computed(() => Array.from(iter.flatMap(rootSource.values(), from => iter.map(from.values(), child => child[1]))));
let watcher: FSWatcher;
(async () => {
try {
const stat = await fs.promises.stat(filePath);
const isFolderSync = stat.isDirectory(); const isFolderSync = stat.isDirectory();
const watcher = watch(filePath, { const cleanupFns = new Map<string, Disposer>();
watcher = watch(filePath, {
followSymlinks: true, followSymlinks: true,
depth: isFolderSync ? 0 : 1, // DIRs works with 0 but files need 1 (bug: https://github.com/paulmillr/chokidar/issues/1095) depth: isFolderSync ? 0 : 1, // DIRs works with 0 but files need 1 (bug: https://github.com/paulmillr/chokidar/issues/1095)
disableGlobbing: true, disableGlobbing: true,
@ -287,10 +290,8 @@ async function watchFileChanges(filePath: string): Promise<[IComputedValue<Catal
pollInterval: 100, pollInterval: 100,
stabilityThreshold: 1000, stabilityThreshold: 1000,
}, },
atomic: 150, // for "atomic writes"
}); });
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 cleanupFns = new Map<string, Disposer>();
watcher watcher
.on("change", (childFilePath) => { .on("change", (childFilePath) => {
@ -323,6 +324,13 @@ async function watchFileChanges(filePath: string): Promise<[IComputedValue<Catal
rootSource.delete(childFilePath); rootSource.delete(childFilePath);
}) })
.on("error", error => logger.error(`${logPrefix} watching file/folder failed: ${error}`, { filePath })); .on("error", error => logger.error(`${logPrefix} watching file/folder failed: ${error}`, { filePath }));
} catch (error) {
return [derivedSource, () => watcher.close()]; console.log(error.stack);
logger.warn(`${logPrefix} failed to start watching changes: ${error}`);
}
})();
return [derivedSource, () => {
watcher?.close();
}];
} }

View File

@ -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;