diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt index 93c375b016f..ca176b6e2d4 100644 --- a/.github/actions/spelling/excludes.txt +++ b/.github/actions/spelling/excludes.txt @@ -88,6 +88,7 @@ ^\Qpkg/rancher-desktop/utils/processOutputInterpreters/__tests__/assets/push.txt\E$ ^\QSECURITY.md\E$ ^pkg/rancher-desktop/assets/scripts/logrotate-k3s$ +^pkg/rancher-desktop/assets/scripts/logrotate-lima-guestagent$ ignore$ /translations/(?!en) ^\Qpkg/rancher-desktop/router.js\E$ diff --git a/background.ts b/background.ts index 4644116f9eb..07cd61ddfe9 100644 --- a/background.ts +++ b/background.ts @@ -23,7 +23,7 @@ import * as settings from '@pkg/config/settings'; import * as settingsImpl from '@pkg/config/settingsImpl'; import { TransientSettings } from '@pkg/config/transientSettings'; import { IntegrationManager, getIntegrationManager } from '@pkg/integrations/integrationManager'; -import { PathManager } from '@pkg/integrations/pathManager'; +import { PathManagementStrategy, PathManager } from '@pkg/integrations/pathManager'; import { getPathManagerFor } from '@pkg/integrations/pathManagerImpl'; import { BackendState, CommandWorkerInterface, HttpCommandServer } from '@pkg/main/commandServer/httpCommandServer'; import SettingsValidator from '@pkg/main/commandServer/settingsValidator'; @@ -141,9 +141,8 @@ mainEvents.on('settings-update', async(newSettings) => { } k8smanager.debug = runInDebugMode; - if (pathManager.strategy !== newSettings.application.pathManagementStrategy) { - await pathManager.remove(); - pathManager = getPathManagerFor(newSettings.application.pathManagementStrategy); + if (pathManager?.strategy !== newSettings.application.pathManagementStrategy) { + await setPathManager(newSettings.application.pathManagementStrategy); } await pathManager.enforce(); @@ -258,8 +257,7 @@ Electron.app.whenReady().then(async() => { await initUI(); await checkForBackendLock(); - - pathManager = getPathManagerFor(cfg.application.pathManagementStrategy); + await setPathManager(cfg.application.pathManagementStrategy); await integrationManager.enforce(); mainEvents.emit('settings-update', cfg); @@ -298,6 +296,13 @@ Electron.app.whenReady().then(async() => { } }); +async function setPathManager(newStrategy: PathManagementStrategy) { + if (pathManager) { + await pathManager.remove(); + } + pathManager = getPathManagerFor(newStrategy); +} + /** * Reads the 'backend.lock' file and returns its contents if it exists. * Returns null if the file doesn't exist. diff --git a/pkg/rancher-desktop/assets/dependencies.yaml b/pkg/rancher-desktop/assets/dependencies.yaml index dbe8819b414..9a7e075c641 100644 --- a/pkg/rancher-desktop/assets/dependencies.yaml +++ b/pkg/rancher-desktop/assets/dependencies.yaml @@ -1,11 +1,11 @@ -lima: 0.19.0.rd1 +lima: 0.19.0.rd2 limaAndQemu: 1.31.2 alpineLimaISO: isoVersion: 0.2.31.rd11 alpineVersion: 3.18.0 WSLDistro: "0.51" kuberlr: 0.4.4 -helm: 3.13.2 +helm: 3.13.3 dockerCLI: 24.0.7 dockerBuildx: 0.12.0 dockerCompose: 2.23.3 diff --git a/pkg/rancher-desktop/assets/scripts/logrotate-lima-guestagent b/pkg/rancher-desktop/assets/scripts/logrotate-lima-guestagent new file mode 100644 index 00000000000..88d2eb2e7e5 --- /dev/null +++ b/pkg/rancher-desktop/assets/scripts/logrotate-lima-guestagent @@ -0,0 +1,5 @@ +/var/log/lima-guestagent.log { + missingok + notifempty + copytruncate +} diff --git a/pkg/rancher-desktop/backend/lima.ts b/pkg/rancher-desktop/backend/lima.ts index 1b6f1c094e4..039907ddf24 100644 --- a/pkg/rancher-desktop/backend/lima.ts +++ b/pkg/rancher-desktop/backend/lima.ts @@ -35,6 +35,7 @@ import SERVICE_BUILDKITD_CONF from '@pkg/assets/scripts/buildkit.confd'; import SERVICE_BUILDKITD_INIT from '@pkg/assets/scripts/buildkit.initd'; import DOCKER_CREDENTIAL_SCRIPT from '@pkg/assets/scripts/docker-credential-rancher-desktop'; import CONTAINERD_CONFIG from '@pkg/assets/scripts/k3s-containerd-config.toml'; +import LOGROTATE_LIMA_GUESTAGENT_SCRIPT from '@pkg/assets/scripts/logrotate-lima-guestagent'; import LOGROTATE_OPENRESTY_SCRIPT from '@pkg/assets/scripts/logrotate-openresty'; import NERDCTL from '@pkg/assets/scripts/nerdctl'; import NGINX_CONF from '@pkg/assets/scripts/nginx.conf'; @@ -1578,6 +1579,10 @@ export default class LimaBackend extends events.EventEmitter implements VMBacken } } + protected async configureLogrotate(): Promise { + await this.writeFile('/etc/logrotate.d/lima-guestagent', LOGROTATE_LIMA_GUESTAGENT_SCRIPT, 0o644); + } + async readFile(filePath: string, options?: { encoding?: BufferEncoding }): Promise { const encoding = options?.encoding ?? 'utf-8'; const stdout: Buffer[] = []; @@ -1910,6 +1915,7 @@ export default class LimaBackend extends events.EventEmitter implements VMBacken this.progressTracker.action('Installing CA certificates', 50, this.installCACerts()), this.progressTracker.action('Configuring image proxy', 50, this.configureOpenResty(config)), this.progressTracker.action('Configuring containerd', 50, this.configureContainerd()), + this.progressTracker.action('Configuring logrotate', 50, this.configureLogrotate()), ]); if (config.containerEngine.allowedImages.enabled) { diff --git a/pkg/rancher-desktop/layouts/default.vue b/pkg/rancher-desktop/layouts/default.vue index 7c8f9844984..8e3697aac4d 100644 --- a/pkg/rancher-desktop/layouts/default.vue +++ b/pkg/rancher-desktop/layouts/default.vue @@ -11,8 +11,8 @@ :extensions="extensions" @open-preferences="openPreferences" /> - -
+ +
@@ -112,11 +112,15 @@ export default { }); ipcRenderer.on('extensions/getContentArea', () => { - const rect = this.$refs['rdx-title'].$el.getBoundingClientRect(); - + /** @type {DOMRect} */ + const titleRect = this.$refs.title.$el.getBoundingClientRect(); + /** @type {DOMRect} */ + const bodyRect = this.$refs.body.getBoundingClientRect(); const payload = { - x: rect.left, - y: rect.top, + top: titleRect.top, + right: titleRect.right, + bottom: bodyRect.bottom, + left: titleRect.left, }; ipcRenderer.send('ok:extensions/getContentArea', payload); diff --git a/pkg/rancher-desktop/main/mainmenu.ts b/pkg/rancher-desktop/main/mainmenu.ts index 8c06f253782..96df5b681db 100644 --- a/pkg/rancher-desktop/main/mainmenu.ts +++ b/pkg/rancher-desktop/main/mainmenu.ts @@ -246,7 +246,6 @@ function setZoomLevel(focusedWindow: Electron.BrowserWindow | undefined, zoomLev const desiredZoomLevel = zoomLevelAdjustment === 0 ? zoomLevelAdjustment : currentZoomLevel + zoomLevelAdjustment; webContents.setZoomLevel(desiredZoomLevel); - focusedWindow.getBrowserView()?.webContents.setZoomLevel(desiredZoomLevel); return; } diff --git a/pkg/rancher-desktop/main/networking/win-ca.ts b/pkg/rancher-desktop/main/networking/win-ca.ts index d21a9416ed3..52385d03711 100644 --- a/pkg/rancher-desktop/main/networking/win-ca.ts +++ b/pkg/rancher-desktop/main/networking/win-ca.ts @@ -47,7 +47,7 @@ export default async function* getWinCertificates(): AsyncIterable { buffer += chunk; } while (true) { - const [match] = /^.*?-----END CERTIFICATE-----\r?\n?/.exec(buffer) ?? []; + const [match] = /^.*?-----END CERTIFICATE-----\r?\n?/s.exec(buffer) ?? []; if (!match) { break; @@ -59,11 +59,16 @@ export default async function* getWinCertificates(): AsyncIterable { await iterator.error(ex); } }); - proc.on('exit', (code, signal) => { + proc.on('exit', async(code, signal) => { if (!(code === 0 || signal === 'SIGTERM')) { iterator.error(code || signal); } else { - iterator.end(); + try { + await iterator.emit(buffer); + iterator.end(); + } catch (ex) { + await iterator.error(ex); + } } }); diff --git a/pkg/rancher-desktop/typings/electron-ipc.d.ts b/pkg/rancher-desktop/typings/electron-ipc.d.ts index 27d900ba304..240ba6c6454 100644 --- a/pkg/rancher-desktop/typings/electron-ipc.d.ts +++ b/pkg/rancher-desktop/typings/electron-ipc.d.ts @@ -102,7 +102,7 @@ export interface IpcMainEvents { level: 'success' | 'warning' | 'error', message: string ) => void; - 'ok:extensions/getContentArea': (payload: { x: number; y: number }) => void; + 'ok:extensions/getContentArea': (payload: { top: number, right: number, bottom: number, left: number }) => void; // #endregion // #region Snapshots diff --git a/pkg/rancher-desktop/window/index.ts b/pkg/rancher-desktop/window/index.ts index a290324d9f1..51a31ca8a63 100644 --- a/pkg/rancher-desktop/window/index.ts +++ b/pkg/rancher-desktop/window/index.ts @@ -216,24 +216,18 @@ const createView = () => { * @param window The main window * @param payload Payload representing coordinates for view position */ -const updateView = (window: any, payload: any) => { +const updateView = (window: Electron.BrowserWindow, payload: { top: number, right: number, bottom: number, left: number }) => { if (!view) { return; } - const contentSize = window.getContentSize(); - const titleBarHeight = 0; - - const yZoomFactor = window.webContents.getZoomFactor(); - - const x = Math.round(payload.x * window.webContents.getZoomFactor()); - const y = Math.round((payload.y + titleBarHeight) * yZoomFactor); + const zoomFactor = window.webContents.getZoomFactor(); view.setBounds({ - x, - y, - width: contentSize[0] - x, - height: (contentSize[1] + titleBarHeight) - y, + x: Math.round(payload.left * zoomFactor), + y: Math.round(payload.top * zoomFactor), + width: Math.round((payload.right - payload.left) * zoomFactor), + height: Math.round((payload.bottom - payload.top) * zoomFactor), }); view.setAutoResize({ width: true, height: true }); @@ -259,14 +253,15 @@ function extensionNavigate() { }); } -const zoomInKey = os.platform().startsWith('darwin') ? '=' : '+'; +const zoomInKeys = new Set(`+${ process.platform === 'darwin' ? '=' : '' }`); +const zoomOutKeys = new Set('-'); +const zoomResetKeys = new Set('0'); +const zoomAllKeys = new Set([...zoomInKeys, ...zoomOutKeys, ...zoomResetKeys]); function isZoomKeyCombo(input: Electron.Input) { const modifier = input.control || input.meta; - return input.type === 'keyDown' && - modifier && - (input.key === '-' || input.key === zoomInKey || input.key === '0'); + return input.type === 'keyDown' && modifier && zoomAllKeys.has(input.key); } /** @@ -286,12 +281,13 @@ const extensionZoomListener = (event: Electron.Event, input: Electron.Input) => event.preventDefault(); const currentZoomLevel = window.webContents.getZoomLevel(); const newZoomLevel = (() => { - switch (input.key) { - case '-': - return currentZoomLevel - 0.5; - case zoomInKey: + if (zoomInKeys.has(input.key)) { return currentZoomLevel + 0.5; - case '0': + } + if (zoomOutKeys.has(input.key)) { + return currentZoomLevel - 0.5; + } + if (zoomResetKeys.has(input.key)) { return 0; } })(); @@ -304,7 +300,7 @@ const extensionZoomListener = (event: Electron.Event, input: Electron.Input) => window.webContents.setZoomLevel(newZoomLevel); view?.webContents.setZoomLevel(newZoomLevel); - window.webContents.send('extensions/getContentArea'); + setImmediate(() => window.webContents.send('extensions/getContentArea')); } }; @@ -314,7 +310,7 @@ const extensionZoomListener = (event: Electron.Event, input: Electron.Input) => * @param _event The Electron Ipc Main Event that triggered this listener * @param args Arguments associated with the event */ -function extensionGetContentAreaListener(_event: Electron.IpcMainEvent, args: any) { +function extensionGetContentAreaListener(_event: Electron.IpcMainEvent, payload: { top: number, right: number, bottom: number, left: number }) { const window = getWindow('main'); if (!window) { @@ -331,7 +327,7 @@ function extensionGetContentAreaListener(_event: Electron.IpcMainEvent, args: an } } - updateView(window, args); + updateView(window, payload); extensionNavigate(); }