From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 337691FF1F0 for ; Wed, 24 Jul 2024 17:04:48 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id B8CD91E646; Wed, 24 Jul 2024 17:05:20 +0200 (CEST) From: Max Carrara To: pve-devel@lists.proxmox.com Date: Wed, 24 Jul 2024 17:05:07 +0200 Message-Id: <20240724150511.474844-2-m.carrara@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240724150511.474844-1-m.carrara@proxmox.com> References: <20240724150511.474844-1-m.carrara@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.029 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH v3 pve-manager 1/5] fix #5366: ui: ceph: services: parse and display build commit X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" The build commit is displayed and taken into account when comparing monitor and manager versions in the client. Specifically, the shortened build commit is now displayed in parentheses next to the version for both monitors and managers like so: 18.2.2 (build: abcd1234) Should the build commit of the running service differ from the one that's installed on the host, the newer build commit will also be shown in parentheses: 18.2.2 (build: abcd1234 -> 5678fedc) The icon displayed for running a service with an outdated build is the same as for running an outdated version. The conditional display of icons related to cluster health remains the same otherwise. The Ceph summary view also displays the hash and will show a warning if a service is running with a build commit that doesn't match the one that's advertised by the host. This requires the introduction of two helper functions: 1. `PVE.Utils.parseCephBuildCommit`, which can be used to get the full hash "eccf199d..." in parentheses from a string like the following: ceph version 17.2.7 (eccf199d63457659c09677399928203b7903c888) quincy (stable) 2. `PVE.Utils.renderCephBuildCommit`, which is used to determine how to render a service's current build commit and which accompanying icon to choose. Signed-off-by: Max Carrara Fixes: https://bugzilla.proxmox.com/show_bug.cgi?id=5366 --- Changes v2 --> v3: * add new `renderCephBuildCommit` helper function (thanks Thomas!) * add docstrings for helpers * use less ambiguous variable names (thanks Thomas!) * put 'build: ' in front of build commit when rendering (thanks Thomas!) * handle no rendered build commit being available in MGR / MON lists, returning the icon + version without the commit instead * make the modified logic in Services.js more readable * reword message about differing builds in the overview * reword commit title & message * add 'Fixes' trailer * remove outdated R-b and T-b trailers Changes v1 --> v2: * use camelCase instead of snake_case (thanks Lukas!) * use more descriptive variable names (thanks Lukas!) * use `let` instead of `const` for variables where applicable (thanks Lukas!) www/manager6/Utils.js | 107 +++++++++++++++++++++++++++++++ www/manager6/ceph/ServiceList.js | 33 +++++++--- www/manager6/ceph/Services.js | 19 +++++- 3 files changed, 148 insertions(+), 11 deletions(-) diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js index db86fa9a..1d42be34 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -128,6 +128,113 @@ Ext.define('PVE.Utils', { return undefined; }, + /** + * Parses a Ceph build commit from its version string. + * + * @param {object} service + * @param {string} service.ceph_version - The long form of a Ceph version string + * @returns {(undefined|string)} The matched build commit or `undefined` + */ + parseCephBuildCommit: function(service) { + if (service.ceph_version) { + // See PVE/Ceph/Tools.pm - get_local_version + const match = service.ceph_version.match( + /^ceph.*\sv?(?:\d+(?:\.\d+)+)\s+(?:\(([a-zA-Z0-9]+)\))/, + ); + if (match) { + return match[1]; + } + } + + return undefined; + }, + + /** + * Determines how Ceph build commits should be rendered and which icon + * should be chosen depending on the Ceph versions and build commits given. + * + * Should the two build commits be identical, the commit is shortened. + * Should they differ, they're rendered as e.g.: + * + * 0558a7146 -> b72f4fd04 + * + * Note that the arrow `->` is rendered as a Font Awesome icon. + * + * @param {Object} versionInfo + * @param {string} versionInfo.runningVersion - The version of the currently + * running Ceph service + * @param {string} versionInfo.installedVersion - The version of the Ceph + * service (or its executable) as reported by the node + * @param {string} versionInfo.runningBuildCommit - The build commit of the + * currently running Ceph service + * @param {string} versionInfo.installedBuildCommit - The build commit of the + * Ceph service (or its executable) as reported by the node + * @param {string} versionInfo.maxVersion - The highest version of the + * Ceph service in the cluster + * @param {boolean} versionInfo.hasMixedVersions - Whether different + * versions of the service are currently running in the cluster + * @param {number} [buildCommitLength] - (Optional) The length to which to + * shorten the rendered build commit(s), `9` by default + * @returns {Object} - An object containing the selected `icon`, whether the + * current build commit has `changed` and the build commit (or build + * commit changes) as `renderedBuildCommit` + */ + renderCephBuildCommit: function(versionInfo, buildCommitLength) { + buildCommitLength ??= 9; + + versionInfo = versionInfo ?? {}; + + let runningVersion = versionInfo.runningVersion ?? ''; + let installedVersion = versionInfo.installedVersion ?? ''; + + let runningBuildCommit = versionInfo.runningBuildCommit ?? ''; + let installedBuildCommit = versionInfo.installedBuildCommit ?? ''; + + let maxVersion = versionInfo.maxVersion ?? ''; + let hasMixedVersions = versionInfo.hasMixedVersions ?? false; + + let hasBuildCommits = runningBuildCommit !== '' && installedBuildCommit !== ''; + let hasRunningBuildCommitChanged = hasBuildCommits && + runningBuildCommit !== installedBuildCommit; + + let icon = ''; + + if (PVE.Utils.compare_ceph_versions(maxVersion, installedVersion) > 0) { + icon = PVE.Utils.get_ceph_icon_html('HEALTH_UPGRADE'); + } else if (PVE.Utils.compare_ceph_versions(installedVersion, runningVersion) > 0) { + icon = PVE.Utils.get_ceph_icon_html('HEALTH_OLD'); + } else if (hasMixedVersions && !hasRunningBuildCommitChanged) { + icon = PVE.Utils.get_ceph_icon_html('HEALTH_OK'); + } + + if (!hasBuildCommits) { + return { + icon: icon, + changed: hasRunningBuildCommitChanged, + renderedBuildCommit: (runningBuildCommit || installedBuildCommit) + .substring(0, buildCommitLength), + }; + } + + let renderedBuildCommit = runningBuildCommit.substring(0, buildCommitLength); + + if (hasRunningBuildCommitChanged) { + const arrow = ''; + icon ||= PVE.Utils.get_ceph_icon_html('HEALTH_OLD'); + + let buildCommitFrom = runningBuildCommit.substring(0, buildCommitLength); + let buildCommitTo = installedBuildCommit.substring(0, buildCommitLength); + + renderedBuildCommit = `${buildCommitFrom}${arrow}${buildCommitTo}`; + } + + return { + icon: icon, + changed: hasRunningBuildCommitChanged, + renderedBuildCommit: renderedBuildCommit, + }; + }, + compare_ceph_versions: function(a, b) { let avers = []; let bvers = []; diff --git a/www/manager6/ceph/ServiceList.js b/www/manager6/ceph/ServiceList.js index 2dd80c14..20dfb5d0 100644 --- a/www/manager6/ceph/ServiceList.js +++ b/www/manager6/ceph/ServiceList.js @@ -103,21 +103,34 @@ Ext.define('PVE.node.CephServiceController', { if (value === undefined) { return ''; } + let view = this.getView(); - let host = rec.data.host, nodev = [0]; + let host = rec.data.host; + + let nodeVersion = [0]; + let nodeBuildCommit = ''; + if (view.nodeversions[host] !== undefined) { - nodev = view.nodeversions[host].version.parts; + nodeVersion = view.nodeversions[host].version.parts; + nodeBuildCommit = view.nodeversions[host].buildcommit; } - let icon = ''; - if (PVE.Utils.compare_ceph_versions(view.maxversion, nodev) > 0) { - icon = PVE.Utils.get_ceph_icon_html('HEALTH_UPGRADE'); - } else if (PVE.Utils.compare_ceph_versions(nodev, value) > 0) { - icon = PVE.Utils.get_ceph_icon_html('HEALTH_OLD'); - } else if (view.mixedversions) { - icon = PVE.Utils.get_ceph_icon_html('HEALTH_OK'); + let versionInfo = { + runningVersion: value, + installedVersion: nodeVersion, + runningBuildCommit: PVE.Utils.parseCephBuildCommit(rec.data) ?? '', + installedBuildCommit: nodeBuildCommit, + maxVersion: view.maxversion, + hasMixedVersions: view.mixedversions, + }; + + let { icon, renderedBuildCommit } = PVE.Utils.renderCephBuildCommit(versionInfo, 9); + + if (renderedBuildCommit) { + return `${icon}${value} (build: ${renderedBuildCommit})`; } - return icon + value; + + return `${icon}${value}`; }, getMaxVersions: function(store, records, success) { diff --git a/www/manager6/ceph/Services.js b/www/manager6/ceph/Services.js index dfafee43..ff6f80e9 100644 --- a/www/manager6/ceph/Services.js +++ b/www/manager6/ceph/Services.js @@ -155,6 +155,7 @@ Ext.define('PVE.ceph.Services', { title: metadata[type][id].name || name, host: host, version: PVE.Utils.parse_ceph_version(metadata[type][id]), + buildcommit: PVE.Utils.parseCephBuildCommit(metadata[type][id]), service: metadata[type][id].service, addr: metadata[type][id].addr || metadata[type][id].addrs || Proxmox.Utils.unknownText, }; @@ -181,7 +182,15 @@ Ext.define('PVE.ceph.Services', { } if (result.version) { - result.statuses.push(gettext('Version') + ": " + result.version); + let installedBuildCommit = metadata.node[host]?.buildcommit ?? ''; + let runningBuildCommit = result.buildcommit ?? ''; + + let statusLine = gettext('Version') + `: ${result.version}`; + if (runningBuildCommit) { + statusLine += ` (build: ${runningBuildCommit.substring(0, 9)})`; + } + + result.statuses.push(statusLine); if (PVE.Utils.compare_ceph_versions(result.version, maxversion) !== 0) { let host_version = metadata.node[host]?.version?.parts || metadata.version?.[host] || ""; @@ -202,6 +211,14 @@ Ext.define('PVE.ceph.Services', { gettext('Other cluster members use a newer version of this service, please upgrade and restart'), ); } + } else if (installedBuildCommit !== "" && runningBuildCommit !== installedBuildCommit) { + if (result.health > healthstates.HEALTH_OLD) { + result.health = healthstates.HEALTH_OLD; + } + result.messages.push( + PVE.Utils.get_ceph_icon_html('HEALTH_OLD', true) + + gettext('A newer build of this release was installed but old build still running, please restart'), + ); } } -- 2.39.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel