Skip to content

Commit 245632a

Browse files
committed
Diagnostics: Add moby image store check
This builds upon 16ccfb0 by exposing the moby image store decisions as a diagnostics event, and having a diagnostic to tell the user about the decision of that. Signed-off-by: Mark Yen <mark.yen@suse.com>
1 parent ac11cf7 commit 245632a

File tree

5 files changed

+110
-11
lines changed

5 files changed

+110
-11
lines changed

pkg/rancher-desktop/backend/backendHelper.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { LockedFieldError } from '@pkg/config/commandLineOptions';
1414
import { ContainerEngine, Settings } from '@pkg/config/settings';
1515
import * as settingsImpl from '@pkg/config/settingsImpl';
1616
import SettingsValidator from '@pkg/main/commandServer/settingsValidator';
17+
import mainEvents from '@pkg/main/mainEvents';
1718
import { minimumUpgradeVersion, SemanticVersionEntry } from '@pkg/utils/kubeVersions';
1819
import Logging from '@pkg/utils/logging';
1920
import paths from '@pkg/utils/paths';
@@ -400,22 +401,28 @@ export default class BackendHelper {
400401
}
401402
}
402403

404+
const hasSnapshotterData = await dirHasChildren(snapshotterDir);
405+
const hasClassicData = await dirHasChildren(classicDir);
406+
403407
// If `storageDriver` is explicitly set, use that setting.
404408
if (storageDriver !== 'auto') {
405409
useSnapshotter = (storageDriver === 'snapshotter');
406410
} else if (configureWASM) {
407411
// WASM requires the containerd snapshotter.
408412
useSnapshotter = true;
409-
} else {
413+
} else if (hasSnapshotterData) {
410414
// If there is data in the containerd snapshotter store, use it.
411-
if (await dirHasChildren(snapshotterDir)) {
412-
useSnapshotter = true;
413-
}
414-
}
415-
if (useSnapshotter === undefined) {
415+
useSnapshotter = true;
416+
} else {
416417
// If there is no data in the classic storage, use containerd snapshotter.
417-
useSnapshotter = !(await dirHasChildren(classicDir));
418+
useSnapshotter = !hasClassicData;
418419
}
420+
mainEvents.emit('diagnostics-event', {
421+
id: 'moby-storage',
422+
hasClassicData,
423+
hasSnapshotterData,
424+
useSnapshotter,
425+
});
419426

420427
let config: Record<string, any>;
421428

pkg/rancher-desktop/main/commandServer/settingsValidator.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -413,9 +413,9 @@ export default class SettingsValidator {
413413
mergedSettings.containerEngine.mobyStorageDriver === 'classic'
414414
) {
415415
const message: string = {
416-
'containerEngine.name': 'Cannot switch to moby container engine with classic storage when WASM is enabled.',
417-
'experimental.containerEngine.webAssembly.enabled': 'Cannot enable WASM with classic storage for moby.',
418-
'containerEngine.mobyStorageDriver': 'Cannot switch to classic storage for moby when WASM is enabled.',
416+
'containerEngine.name': 'Cannot switch to moby container engine with classic storage when WebAssembly is enabled.',
417+
'experimental.containerEngine.webAssembly.enabled': 'Cannot enable WebAssembly with classic storage for moby.',
418+
'containerEngine.mobyStorageDriver': 'Cannot switch to classic storage for moby when WebAssembly is enabled.',
419419
}[fqname];
420420

421421
if (currentValue !== desiredValue) {

pkg/rancher-desktop/main/diagnostics/diagnostics.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ export class DiagnosticsManager {
3838
/** Time stamp of when the last check occurred. */
3939
lastUpdate = new Date(0);
4040

41+
/** Last known applicable state, for message limiting. */
42+
applicable: Record<DiagnosticsChecker['id'], boolean> = {};
43+
4144
/** Last known check results, indexed by the checker id. */
4245
results: Record<DiagnosticsChecker['id'], DiagnosticsCheckerResult | DiagnosticsCheckerSingleResult[]> = {};
4346

@@ -60,6 +63,7 @@ export class DiagnosticsManager {
6063
import('./kubeVersionsAvailable'),
6164
import('./limaDarwin'),
6265
import('./limaOverrides'),
66+
import('./mobyImageStore'),
6367
import('./mockForScreenshots'),
6468
import('./pathManagement'),
6569
import('./rdBinInShell'),
@@ -118,7 +122,11 @@ export class DiagnosticsManager {
118122
}
119123
})))
120124
.map(([checker, applicable]) => {
121-
console.debug(`${ checker.id } is ${ applicable ? '' : 'not ' }applicable`);
125+
if (applicable !== this.applicable[checker.id]) {
126+
const verb = this.applicable[checker.id] === undefined ? 'is' : 'turned';
127+
console.debug(`${ checker.id } ${ verb } ${ applicable ? '' : 'not ' }applicable`);
128+
this.applicable[checker.id] = applicable;
129+
}
122130

123131
return [checker, applicable] as const;
124132
})
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { DiagnosticsCategory, DiagnosticsChecker } from './types';
2+
3+
import { ContainerEngine } from '@pkg/config/settings';
4+
import mainEvents from '@pkg/main/mainEvents';
5+
6+
const id = 'MOBY_IMAGE_STORE';
7+
const documentation = 'https://docs.rancherdesktop.io/troubleshooting/migrating-images/';
8+
9+
let containerEngine: ContainerEngine = ContainerEngine.NONE;
10+
let state = {
11+
hasClassicData: false,
12+
hasSnapshotterData: false,
13+
useSnapshotter: false,
14+
};
15+
16+
mainEvents.on('settings-update', (settings) => {
17+
containerEngine = settings.containerEngine.name;
18+
});
19+
20+
mainEvents.on('diagnostics-event', (payload) => {
21+
if (payload.id === 'moby-storage') {
22+
state = payload;
23+
mainEvents.invoke('diagnostics-trigger', id);
24+
}
25+
});
26+
27+
/**
28+
* We use moby's containerd image store for new VMs, as well as when WASM is
29+
* enabled; however, the migration in Rancher Desktop 1.21 had a bug that caused
30+
* some users to end up using the containerd snapshotter when they still had
31+
* data in the old moby image store. Detect when we have data in both and warn
32+
* the user.
33+
*/
34+
class CheckMobyImageStore implements DiagnosticsChecker {
35+
readonly id = id;
36+
37+
category = DiagnosticsCategory.ContainerEngine;
38+
applicable(): Promise<boolean> {
39+
return Promise.resolve(containerEngine === ContainerEngine.MOBY);
40+
}
41+
42+
async check() {
43+
if (!await this.applicable()) {
44+
return {
45+
passed: true,
46+
description: 'Moby container engine is not in use',
47+
fixes: [],
48+
};
49+
}
50+
51+
if (state.hasClassicData && state.useSnapshotter) {
52+
if (state.hasSnapshotterData) {
53+
return {
54+
passed: false,
55+
description: `There are images in both the moby classic storage driver and the containerd image store. Currently using the containerd snapshotter.`,
56+
fixes: [],
57+
documentation,
58+
};
59+
}
60+
return {
61+
passed: false,
62+
description: `There are images in the moby classic storage driver, but the containerd snapshotter is being used.`,
63+
fixes: [],
64+
documentation,
65+
};
66+
} else if (state.hasSnapshotterData && !state.useSnapshotter) {
67+
return {
68+
passed: false,
69+
description: `There are images in the containerd image store, but the moby classic storage driver is being used.`,
70+
fixes: [],
71+
documentation,
72+
};
73+
}
74+
75+
return {
76+
passed: true,
77+
description: `There are no issues with the moby image store: classic:${ state.hasClassicData } snapshotter:${ state.hasSnapshotterData } using snapshotter:${ state.useSnapshotter }`,
78+
fixes: [],
79+
};
80+
}
81+
}
82+
83+
export default new CheckMobyImageStore();

pkg/rancher-desktop/main/mainEvents.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ interface MainEventNames {
174174
type DiagnosticsEventPayload =
175175
{ id: 'integrations-windows', distro?: string, key: string, error?: Error } |
176176
{ id: 'kube-versions-available', available: boolean } |
177+
{ id: 'moby-storage', hasClassicData: boolean, hasSnapshotterData: boolean, useSnapshotter: boolean } |
177178
{ id: 'network-connectivity', connected: boolean } |
178179
{ id: 'path-management', fileName: string; error: Error | undefined };
179180

0 commit comments

Comments
 (0)