Skip to content

Commit

Permalink
Merge pull request rancher-sandbox#7142 from rancher-sandbox/diagnost…
Browse files Browse the repository at this point in the history
…ics-wsl-kubeconfig-wsl-helper

Add diagnostic to verify kubeConfig
  • Loading branch information
Nino-K authored Jul 12, 2024
2 parents 49a5af4 + b2f339b commit 2db7343
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pkg/rancher-desktop/integrations/integrationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function getIntegrationManager(): IntegrationManager {
case 'darwin':
return new UnixIntegrationManager(resourcesBinDir, paths.integration, dockerCliPluginDir);
case 'win32':
return new WindowsIntegrationManager();
return WindowsIntegrationManager.getInstance();
default:
throw new Error(`OS ${ platform } is not supported`);
}
Expand Down
46 changes: 46 additions & 0 deletions pkg/rancher-desktop/integrations/windowsIntegrationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ export default class WindowsIntegrationManager implements IntegrationManager {
/** Extra debugging arguments for wsl-helper. */
protected wslHelperDebugArgs: string[] = [];

/** Singleton instance. */
private static instance: WindowsIntegrationManager;

constructor() {
mainEvents.on('settings-update', (settings) => {
this.wslHelperDebugArgs = runInDebugMode(settings.application.debug) ? ['--verbose'] : [];
Expand Down Expand Up @@ -130,6 +133,13 @@ export default class WindowsIntegrationManager implements IntegrationManager {
mainEvents.emit('settings-write', {});
}

/** Static method to access the singleton instance. */
public static getInstance(): WindowsIntegrationManager {
WindowsIntegrationManager.instance ||= new WindowsIntegrationManager();

return WindowsIntegrationManager.instance;
}

async enforce(): Promise<void> {
this.enforcing = true;
await this.sync();
Expand Down Expand Up @@ -460,6 +470,42 @@ export default class WindowsIntegrationManager implements IntegrationManager {
}
}

/**
* verifyAllDistrosKubeConfig loops through all the available distros
* and checks if the kubeconfig can be managed; if any distro fails
* the check, an exception is thrown.
*/
async verifyAllDistrosKubeConfig() {
const distros = await this.supportedDistros;

await Promise.all(distros.map(async(distro) => {
await this.verifyDistroKubeConfig(distro.name);
}));
}

/**
* verifyDistroKubeConfig calls the wsl-helper kubeconfig --verify per distro.
* It determines the condition of the kubeConfig from the returned error code.
*/
protected async verifyDistroKubeConfig(distro: string) {
try {
const wslHelper = await this.getLinuxToolPath(distro, executable('wsl-helper-linux'));

await this.execCommand({ distro }, wslHelper, 'kubeconfig', '--verify');
} catch (err: any) {
// Only throw for a specific error code 1, since we control that from the
// kubeconfig --verify command. The logic here is to bubble up this error
// so that the diagnostic is very specific to this issue. Any other errors
// are captured as log messages.
if (err && 'code' in err && err.code === 1) {
throw new Error(`The kubeConfig contains non-Rancher Desktop configuration in distro ${ distro }`);
} else {
console.error(`Verifying kubeconfig in distro ${ distro } failed: ${ err }`);
}
}
console.debug(`Verified kubeconfig in the following distro: ${ distro }`);
}

protected async syncDistroKubeconfig(distro: string, kubeconfigPath: string, state: boolean) {
try {
console.debug(`Syncing ${ distro } kubeconfig`);
Expand Down
9 changes: 5 additions & 4 deletions pkg/rancher-desktop/main/diagnostics/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ export class DiagnosticsManager {
constructor(diagnostics?: DiagnosticsChecker[]) {
this.checkers = diagnostics ? Promise.resolve(diagnostics) : (async() => {
const imports = (await Promise.all([
import('./testCheckers'),
import('./connectedToInternet'),
import('./dockerCliSymlinks'),
import('./rdBinInShell'),
import('./kubeConfigSymlink'),
import('./kubeContext'),
import('./wslFromStore'),
import('./mockForScreenshots'),
import('./limaDarwin'),
import('./mockForScreenshots'),
import('./rdBinInShell'),
import('./testCheckers'),
import('./wslFromStore'),
])).map(obj => obj.default);

return (await Promise.all(imports)).flat();
Expand Down
44 changes: 44 additions & 0 deletions pkg/rancher-desktop/main/diagnostics/kubeConfigSymlink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { DiagnosticsCategory, DiagnosticsChecker } from './types';

import WindowsIntegrationManager from '@pkg/integrations/windowsIntegrationManager';
import Logging from '@pkg/utils/logging';

const console = Logging.diagnostics;

async function verifyKubeConfigSymlink(): Promise<boolean> {
const integrationManager = WindowsIntegrationManager.getInstance();

try {
await integrationManager.verifyAllDistrosKubeConfig();

return true;
} catch (error: any) {
console.error(`Error verifying kubeconfig symlinks: ${ error.message }`);

return false;
}
}

/**
* CheckKubeConfigSymlink checks the symlinked kubeConfig in WSL integration
* enabled distro for non-rancher desktop configuration.
*/
const CheckKubeConfigSymlink: DiagnosticsChecker = {
id: 'VERIFY_WSL_INTEGRATION_KUBECONFIG',
category: DiagnosticsCategory.Kubernetes,
applicable() {
return Promise.resolve(true);
},
async check() {
return Promise.resolve({
description: 'Rancher Desktop cannot automatically convert the provided kubeconfig file to a symlink' +
' due to existing configurations within that file. To resolve this issue, you will need to ' +
'manually create the symlink to ensure existing configurations are preserved and to prevent ' +
'any loss of configuration.',
passed: await verifyKubeConfigSymlink(),
fixes: [],
});
},
};

export default CheckKubeConfigSymlink;

0 comments on commit 2db7343

Please sign in to comment.