Skip to content

Commit

Permalink
WSL: Provide better error message when WSL is not installed.
Browse files Browse the repository at this point in the history
Signed-off-by: Mark Yen <[email protected]>
  • Loading branch information
mook-as committed May 13, 2021
1 parent a35a714 commit b9691f7
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 6 deletions.
31 changes: 25 additions & 6 deletions background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ Electron.app.whenReady().then(async() => {
console.log(cfg);
tray.emit('settings-update', cfg);
k8smanager = newK8sManager(cfg.kubernetes);

// Check if there are any reasons that would mean it makes no sense to
// continue starting the app.
const invalidReason = await k8smanager.getBackendInvalidReason();

if (invalidReason) {
handleFailure(invalidReason);
gone = true;
Electron.app.quit();

return;
}

imageManager = new Kim();
interface KimImage {
imageName: string,
Expand Down Expand Up @@ -486,14 +499,20 @@ async function linkResource(name: string, state: boolean): Promise<Error | null>
}

function handleFailure(payload: any) {
let { errorCode, message, context: titlePart } = payload;

if (typeof (payload) === 'number') {
errorCode = payload;
let titlePart = 'Starting Kubernetes';
let message = 'There was an unknown error starting Kubernetes';

if (payload instanceof K8s.KubernetesError) {
({ name: titlePart, message } = payload);
} else if (payload instanceof Error) {
message += `: ${ payload }`;
} else if (typeof payload === 'number') {
message = `Kubernetes was unable to start with the following exit code: ${ payload }`;
} else if ('errorCode' in payload) {
message = payload.message || message;
titlePart = payload.context || titlePart;
}
console.log(`Kubernetes was unable to start with exit code: ${ errorCode }`);
titlePart = titlePart || 'Starting Kubernetes';
console.log(`Kubernetes was unable to start:`, payload);
Electron.dialog.showErrorBox(`Error ${ titlePart }`, message);
}

Expand Down
4 changes: 4 additions & 0 deletions src/k8s-engine/hyperkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,10 @@ export default class HyperkitBackend extends events.EventEmitter implements K8s.
})();
}

getBackendInvalidReason(): Promise<K8s.KubernetesError | null> {
return Promise.resolve(null);
}

async start(): Promise<void> {
const desiredVersion = await this.desiredVersion;

Expand Down
14 changes: 14 additions & 0 deletions src/k8s-engine/k8s.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ export interface VersionLister {
on(event: 'versions-updated', callback: ()=>void): void;
}

export class KubernetesError extends Error {
constructor(name: string, message: string) {
super(message);
this.name = name;
}
}

export interface KubernetesBackend extends events.EventEmitter {
state: State;

Expand All @@ -57,6 +64,13 @@ export interface KubernetesBackend extends events.EventEmitter {
/** The amount of memory in the VM, in MiB, or 0 if the VM is not running. */
memory: Promise<number>;

/**
* Check if the current backend is valid.
* @returns Null if the backend is valid, otherwise an error describing why
* the backend is invalid that can be shown to the user.
*/
getBackendInvalidReason(): Promise<KubernetesError | null>;

/** Start the Kubernetes cluster. */
start(): Promise<void>;

Expand Down
4 changes: 4 additions & 0 deletions src/k8s-engine/notimplemented.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class OSNotImplemented extends events.EventEmitter {
return Promise.reject(new Error('not implemented'));
}

getBackendInvalidReason() {
return Promise.resolve(null);
}

start() {
this.#notified = displayError(this.#notified);

Expand Down
23 changes: 23 additions & 0 deletions src/k8s-engine/wsl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,29 @@ export default class WSLBackend extends events.EventEmitter implements K8s.Kuber
}
}

async getBackendInvalidReason(): Promise<K8s.KubernetesError | null> {
// Check if wsl.exe is available
try {
await this.isDistroRegistered();
} catch (ex) {
if ((ex as NodeJS.ErrnoException).code === 'ENOENT') {
console.log('Error launching WSL: it does not appear to be installed.');
const message = `
Windows Subsystem for Linux does not appear to be installed.
Please install it manually:
https://docs.microsoft.com/en-us/windows/wsl/install-win10
`.replace(/[ \t]{2,}/g, '');

return new K8s.KubernetesError('WSL Not Installed', message);
}
throw ex;
}

return null;
}

async start(): Promise<void> {
try {
if (this.process) {
Expand Down

0 comments on commit b9691f7

Please sign in to comment.