Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fc971e0a6 | ||
|
|
2ae9708c4e | ||
|
|
8a9b7568a7 | ||
|
|
f754331c3a | ||
|
|
e46734cd37 | ||
|
|
bc87579d77 | ||
|
|
e59d09a788 | ||
|
|
cee8d04e36 | ||
|
|
8ebc2b4753 | ||
|
|
795b0ebf39 | ||
|
|
43514fc949 | ||
|
|
c1c26aff56 |
No files matched your search
@@ -58,7 +58,6 @@ jobs:
|
||||
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||
# Always recreate from main — avoids rebase conflicts after PR merge
|
||||
git checkout -b chore/version-bump origin/main
|
||||
git push --force origin chore/version-bump
|
||||
else
|
||||
# Label change: check out the existing branch
|
||||
git fetch origin chore/version-bump
|
||||
@@ -133,8 +132,8 @@ jobs:
|
||||
echo "$MAIN_CHANGELOG"
|
||||
} > debian/changelog
|
||||
git add debian/changelog
|
||||
git diff --cached --quiet || git commit -m "chore: update changelog to v${NEW_VERSION}"
|
||||
git push --force-with-lease origin chore/version-bump
|
||||
git commit -m "chore: update changelog to v${NEW_VERSION}"
|
||||
git push --force origin chore/version-bump
|
||||
|
||||
- name: Build PR body
|
||||
env:
|
||||
|
||||
@@ -36,11 +36,20 @@ jobs:
|
||||
test:
|
||||
needs: discover
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: debian:trixie
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
mod: ${{ fromJSON(needs.discover.outputs.mods) }}
|
||||
steps:
|
||||
# ── Base tools (mirrors validate-mods.yml) ──────────────────────────────
|
||||
- name: Install base tools
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates git sudo wget xz-utils dpkg nodejs perl
|
||||
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
@@ -48,22 +57,32 @@ jobs:
|
||||
# ── Build (mirrors test-release.yml) ───────────────────────────────────
|
||||
- name: Install build deps
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y devscripts debhelper build-essential
|
||||
apt-get update -qq
|
||||
apt-get install -y devscripts debhelper build-essential
|
||||
|
||||
- name: Compute build version
|
||||
id: version
|
||||
run: |
|
||||
BASE_VERSION=$(grep -m1 '(' debian/changelog | sed 's/.*(\(.*\)).*/\1/')
|
||||
SHORT_SHA=$(git rev-parse --short HEAD)
|
||||
BUILD_VERSION="${BASE_VERSION}+weekly.${SHORT_SHA}"
|
||||
echo "build_version=$BUILD_VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "Building version: $BUILD_VERSION"
|
||||
|
||||
- name: Inject version into Config.pm
|
||||
run: |
|
||||
VERSION=$(grep -m1 '(' debian/changelog | sed 's/.*(\(.*\)).*/\1/')
|
||||
SHORT_SHA=$(git rev-parse --short HEAD)
|
||||
export BUILD_VERSION="${VERSION}-test-${SHORT_SHA}"
|
||||
perl -i -pe 'BEGIN { $v = $ENV{BUILD_VERSION} }
|
||||
s/(our \$VERSION\s*=\s*'"'"')[^'"'"']*'"'"';/$1'"'"'$v'"'"';/
|
||||
' src/modules/node_info/files/Config.pm
|
||||
BUILD_VERSION="${{ steps.version.outputs.build_version }}"
|
||||
sed -i -E "s/^our \\\$VERSION\s*=.*/our \\\$VERSION = '${BUILD_VERSION}';/" \
|
||||
src/modules/node_info/files/Config.pm
|
||||
|
||||
- name: Set package version in changelog
|
||||
run: |
|
||||
BUILD_VERSION="${{ steps.version.outputs.build_version }}"
|
||||
sed -i -E "0,/\(([^)]*)\)/s//(${BUILD_VERSION})/" debian/changelog
|
||||
|
||||
- name: Generate dynamic debian rules
|
||||
run: |
|
||||
bash build/gen-rules.sh >> debian/rules
|
||||
bash build/gen-rules.sh conffiles >> debian/pve-mod.conffiles
|
||||
|
||||
- name: Build package
|
||||
run: dpkg-buildpackage -us -uc -b
|
||||
@@ -72,13 +91,26 @@ jobs:
|
||||
- name: Fetch upstream Proxmox files
|
||||
run: bash build/test/fetch-proxmox-files.sh
|
||||
|
||||
- name: Capture upstream package versions
|
||||
id: pve_versions
|
||||
run: |
|
||||
PVE_MANAGER_VERSION=$(dpkg-query -W -f='${Version}' pve-manager 2>/dev/null || echo "unknown")
|
||||
PWT_VERSION=$(dpkg-query -W -f='${Version}' proxmox-widget-toolkit 2>/dev/null || echo "unknown")
|
||||
echo "pve_manager=${PVE_MANAGER_VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "proxmox_widget_toolkit=${PWT_VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "pve-manager: ${PVE_MANAGER_VERSION}"
|
||||
echo "proxmox-widget-toolkit: ${PWT_VERSION}"
|
||||
|
||||
- name: Install built package
|
||||
run: sudo apt-get install -y ../pve-mod_*.deb
|
||||
run: apt-get install -y ../pve-mod_*.deb
|
||||
|
||||
- name: Test mod
|
||||
run: |
|
||||
set -o pipefail
|
||||
sudo bash build/test/test-patches.sh "${{ matrix.mod }}" 2>&1 | tee test-output.log
|
||||
bash build/test/test-patches.sh "${{ matrix.mod }}" 2>&1 | tee test-output.log
|
||||
|
||||
- name: Validate source syntax
|
||||
run: bash build/test/test-syntax.sh "${{ matrix.mod }}"
|
||||
|
||||
- name: Report failure as issue
|
||||
if: failure()
|
||||
@@ -90,6 +122,10 @@ jobs:
|
||||
{
|
||||
echo "The weekly patch test failed for mod \`${MOD}\` against the latest Proxmox VE files."
|
||||
echo ""
|
||||
echo "**Proxmox versions tested:**"
|
||||
echo "- pve-manager: \`${{ steps.pve_versions.outputs.pve_manager }}\`"
|
||||
echo "- proxmox-widget-toolkit: \`${{ steps.pve_versions.outputs.proxmox_widget_toolkit }}\`"
|
||||
echo ""
|
||||
echo "Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||
echo ""
|
||||
echo "<details><summary>Test log</summary>"
|
||||
@@ -109,9 +145,10 @@ jobs:
|
||||
--jq ".[] | select(.title==\"$TITLE\") | .number" | head -n1)
|
||||
|
||||
if [[ -n "$EXISTING" ]]; then
|
||||
gh issue edit "$EXISTING" --body-file issue-body.md
|
||||
gh issue comment "$EXISTING" --body-file issue-body.md
|
||||
echo "Commented on existing issue #$EXISTING"
|
||||
echo "Updated and commented on existing issue #$EXISTING"
|
||||
else
|
||||
gh issue create --title "$TITLE" --label patch-break --body-file issue-body.md
|
||||
echo "Opened new issue for mod $MOD"
|
||||
fi
|
||||
fi
|
||||
@@ -121,7 +121,7 @@ test_one_mod() {
|
||||
if [[ $ok -eq 0 ]]; then
|
||||
info "Reverting patches for '$mod'..."
|
||||
local revert_log
|
||||
revert_log="$("$REVERT" 2>&1)"
|
||||
revert_log="$("$REVERT" "$mod" 2>&1)"
|
||||
echo "$revert_log"
|
||||
if echo "$revert_log" | grep -qE "could not be reverted cleanly|reported an error"; then
|
||||
warn "revert-patches.sh reported an unclean revert for mod '$mod'"
|
||||
|
||||
@@ -3,11 +3,80 @@ A small collection of scripts and mods for Proxmox Virtual Environment (PVE)
|
||||
|
||||
If you find this helpful, a small donation is appreciated, [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K8XPMSEBERH3W).
|
||||
|
||||
## Node sensor readings view
|
||||
| Version | Description | Status |
|
||||
|---------|-------------|--------|
|
||||
| **v2** (current) | Debian package (`pve-mod`) with interactive `pve-mod-configure` wizard | Recommended |
|
||||
| v1 (legacy) | Standalone bash scripts, manual install | Archived — see [Legacy section](#legacy-v1-shell-scripts) |
|
||||
|
||||
---
|
||||
|
||||
## Version 2 (beta) — Debian package
|
||||
|
||||
Compatibility: PVE 9.0+
|
||||
|
||||
TBD PICTURE
|
||||
|
||||
`pve-mod` is a Debian package that installs UI patches and an interactive configuration wizard.
|
||||
|
||||
### Mods
|
||||
|
||||
| Mod | Description | Dependencies |
|
||||
|--------|-------------|--------------|
|
||||
| [`node_info`](src/modules/node_info/readme.md) | Displays sensor readings in the node summary panel: CPU, NVMe/HDD/SSD temperatures (°C/°F), fan speeds, RAM temperatures, GPU stats (Intel/NVIDIA), UPS status, and system/motherboard info. <br> Can optionally run as background sensor daemon | - General sensors: `lm-sensors`<br>- HDD/SSD: Kernal module `drivetemp`<br>- UPS: `upsc`<br>- GPU: INTEL `intel-gpu-tools` and/or NVIDIA `nvidia-driver-* `
|
||||
| [`nag_screen`](src/modules/nag_screen/readme.md) | Removes the subscription nag screen from the PVE web UI. | - |
|
||||
|
||||
### How it works
|
||||
|
||||
1. The `pve-mod` package installs the mods installation, patch files under `/usr/lib/pve-mod/`.
|
||||
2. The mods main configuration file and mods can be found under `/etc/pve-mod/`.
|
||||
2. Running `pve-mod-configure` prompts for which modules to enable and configuration of mods.
|
||||
3. The wizard applies the selected patches to the PVE system files and restarts `pveproxy`.
|
||||
|
||||
### Install
|
||||
|
||||
Commands and mod configuration must be run as `root`.
|
||||
|
||||
```bash
|
||||
curl -sL https://raw.githubusercontent.com/Meliox/PVE-mods/refs/heads/main/install.sh | bash
|
||||
```
|
||||
|
||||
Install respective mod dependencies - see Mod table.
|
||||
|
||||
Run `pve-mod-configure` to install/uninstall and configure mods.
|
||||
|
||||
#### Manual configuration changes
|
||||
Configuration files are located in `/etc/pve-mod/`. After any manual edits, restart `pveproxy` to apply the changes:
|
||||
|
||||
```bash
|
||||
systemctl restart pveproxy
|
||||
```
|
||||
|
||||
### Uninstall
|
||||
|
||||
Commands and mod configuration must be run as `root`.
|
||||
|
||||
```bash
|
||||
apt-get remove pve-mod
|
||||
```
|
||||
And remove dependencies needed by respective mods.
|
||||
|
||||
### Notes
|
||||
|
||||
Multiple node support requires application to be installed on all nodes with identical configuration. (untested)
|
||||
|
||||
---
|
||||
|
||||
## Legacy / v1 (shell scripts)
|
||||
|
||||
> **These scripts are archived.** For new installations, use the [v2 Debian package](#version-2--debian-package) above.
|
||||
|
||||
### Node sensor readings view
|
||||
|
||||

|
||||
|
||||
Compatibility:
|
||||
- 9.0-9.2. Newer versions may often work
|
||||
- Older version (7.x-8.x), use git version from Apr 6th 2025
|
||||

|
||||
|
||||
This bash script installs a modification to the Proxmox Virtual Environment (PVE) web user interface (UI) to display sensor readings in a flexible and readable manner.
|
||||
The following readings are possible:
|
||||
@@ -15,7 +84,7 @@ The following readings are possible:
|
||||
- UPS information via Network Monitoring Tool
|
||||
- Motherboard information or system information via dmidecode
|
||||
|
||||
### How it works
|
||||
#### How it works
|
||||
The modification involves the following steps:
|
||||
1. Backup original files in the home directory/backup
|
||||
- `/usr/share/pve-manager/js/pvemanagerlib.js`
|
||||
@@ -38,7 +107,7 @@ Notes:
|
||||
- UPS support in multi-node setups require identical login credentials across nodes. This has not been fully tested.
|
||||
- Proxmox upgrades may overwrite modified files; reinstallation of this mod could be required.
|
||||
|
||||
### Install
|
||||
#### Install
|
||||
Instructions be performed as 'root', as normal users do not have access to the files.
|
||||
|
||||
```
|
||||
@@ -51,7 +120,7 @@ bash pve-mod-gui-sensors.sh install
|
||||
```
|
||||
Additionally, adjustments are available in the first part of the script, where paths can be edited, cpucore offset and display information.
|
||||
|
||||
## Nag screen deactivation
|
||||
### Nag screen deactivation
|
||||
(Tested compatibility: 7.x - 8.3.5)
|
||||
This bash script installs a modification to the Proxmox Virtual Environment (PVE) web user interface (UI) which deactivates the subscription nag screen.
|
||||
|
||||
@@ -65,21 +134,21 @@ The script provides three options:
|
||||
| `install` | Installs the modification by applying the necessary changes. |
|
||||
| `uninstall` | Removes the modification by restoring the original files from backups. |
|
||||
|
||||
### Install
|
||||
#### Install
|
||||
Instructions be performed as 'root', as normal users do not have access to the files.
|
||||
```
|
||||
wget https://raw.githubusercontent.com/Meliox/PVE-mods/refs/heads/main/legacy-scripts/pve-mod-nag-screen.sh
|
||||
bash pve-mod-nag-screen.sh install
|
||||
```
|
||||
|
||||
## Script to update all containers
|
||||
### Script to update all containers
|
||||
(Tested compatibility: 7.x - 8.3.5)
|
||||
|
||||
This script updates all running Proxmox containers, skipping specified excluded containers, and generates a separate log file for each container.
|
||||
The script first updates the Proxmox host system, then iterates through each container, updates the container, and reboots it if necessary.
|
||||
Each container's log file is stored in $log_path and the main script log file is named container-upgrade-main.log.
|
||||
|
||||
### Install
|
||||
#### Install
|
||||
```
|
||||
wget https://raw.githubusercontent.com/Meliox/PVE-mods/refs/heads/main/legacy-scripts/updateallcontainers.sh
|
||||
```
|
||||
|
||||
@@ -98,6 +98,7 @@ sub _get_temperature_sensors {
|
||||
hdd => $config{lm_sensors}{enable_hdd_temp} ? \1 : \0,
|
||||
other => $config{lm_sensors}{enable_other_temp} ? \1 : \0,
|
||||
temp_unit => $config{lm_sensors}{temp_unit},
|
||||
cpu_temp_target => $config{lm_sensors}{cpu_temp_target},
|
||||
data => { 'PVE MOD lm-sensors Enhanced' => $sensors_json },
|
||||
});
|
||||
|
||||
|
||||
@@ -112,7 +112,14 @@ sub notify_pve_mod_worker {
|
||||
# ============================================================================
|
||||
|
||||
sub _worker_lock_file_exists {
|
||||
return -f $pve_mod_worker_lock;
|
||||
return 0 unless -f $pve_mod_worker_lock;
|
||||
my $pid = read_lock_pid($pve_mod_worker_lock);
|
||||
if (defined $pid && $pid =~ /^(\d+)$/ && is_process_alive($1)) {
|
||||
return 1;
|
||||
}
|
||||
debug(__LINE__, "Stale or zombie worker lock found, removing it");
|
||||
unlink($pve_mod_worker_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Forks the worker process and records its PID in the lock file.
|
||||
|
||||
@@ -68,9 +68,10 @@ sub _merge_graphics_files {
|
||||
|
||||
my $merged = {
|
||||
Graphics => {
|
||||
Intel => {},
|
||||
NVIDIA => {},
|
||||
AMD => {},
|
||||
Intel => {},
|
||||
NVIDIA => {},
|
||||
AMD => {},
|
||||
temp_unit => $config{lm_sensors}{temp_unit},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -134,7 +135,7 @@ sub _load_graphics_data {
|
||||
\@filepaths,
|
||||
$graphics_cache,
|
||||
\&_merge_graphics_files,
|
||||
{ Graphics => { Intel => {}, NVIDIA => {}, AMD => {} } }
|
||||
{ Graphics => { Intel => {}, NVIDIA => {}, AMD => {}, temp_unit => $config{lm_sensors}{temp_unit} } }
|
||||
);
|
||||
|
||||
my $intel_count = scalar(keys %{$data->{Graphics}{Intel} // {}});
|
||||
|
||||
@@ -224,14 +224,13 @@ Ext.define('PVE.node.StatusView', {
|
||||
objValue = {};
|
||||
}
|
||||
// sensors configuration
|
||||
const cpuTempHelper = Ext.create('PVE.mod.TempHelper', {srcUnit: PVE.mod.TempHelper.CELSIUS, dstUnit: objValue.temp_unit === 'F' ? PVE.mod.TempHelper.FAHRENHEIT : PVE.mod.TempHelper.CELSIUS});
|
||||
|
||||
const cpuTempHelper = Ext.create('PVE.mod.TempHelper', {srcUnit: PVE.mod.TempHelper.CELSIUS, dstUnit: value.temp_unit === 'F' ? PVE.mod.TempHelper.FAHRENHEIT : PVE.mod.TempHelper.CELSIUS});
|
||||
const cpuKeysI = Object.keys(objValue).filter(item => String(item).startsWith('coretemp-isa-')).sort();
|
||||
const cpuKeysA = Object.keys(objValue).filter(item => String(item).startsWith('k10temp-pci-')).sort();
|
||||
const cpuKeysRpi = Object.keys(objValue).filter(item => String(item).startsWith('cpu_thermal-virtual-')).sort();
|
||||
const bINTEL = cpuKeysI.length > 0 ? true : false;
|
||||
const INTELPackagePrefix = 'Core' == 'Core' ? 'Core ' : 'Package id';
|
||||
const INTELPackageCaption = 'Core' == 'Core' ? 'Core' : 'Package';
|
||||
const INTELPackagePrefix = value.cpu_temp_target == 'Core' ? 'Core ' : 'Package id';
|
||||
const INTELPackageCaption = value.cpu_temp_target == 'Core' ? 'Core' : 'Package';
|
||||
let AMDPackagePrefix = 'Tccd';
|
||||
let AMDPackageCaption = 'CCD';
|
||||
|
||||
@@ -392,9 +391,16 @@ Ext.define('PVE.node.StatusView', {
|
||||
this.hide();
|
||||
return '';
|
||||
} else if (!gpuStats || !gpuStats.Graphics) {
|
||||
this.hide();
|
||||
return '';
|
||||
}
|
||||
|
||||
// Create temperature helper for GPU temperature conversion
|
||||
const gpuTempHelper = Ext.create('PVE.mod.TempHelper', {
|
||||
srcUnit: PVE.mod.TempHelper.CELSIUS,
|
||||
dstUnit: gpuStats.temp_unit === 'F' ? PVE.mod.TempHelper.FAHRENHEIT : PVE.mod.TempHelper.CELSIUS
|
||||
});
|
||||
|
||||
let html = '<table style="width: 100%; border-collapse: collapse; table-layout: fixed;">';
|
||||
|
||||
// Intel GPUs - Secondary details
|
||||
@@ -444,7 +450,16 @@ Ext.define('PVE.node.StatusView', {
|
||||
const stats = gpuData.stats;
|
||||
|
||||
let details = [];
|
||||
|
||||
|
||||
// GPU Utilization
|
||||
if (stats.utilization && stats.utilization.gpu) {
|
||||
const gpuUsage = parseInt(stats.utilization.gpu);
|
||||
let gpuStyle = '';
|
||||
if (gpuUsage >= 90) gpuStyle = 'color: #d9534f; font-weight: bold;';
|
||||
else if (gpuUsage >= 70) gpuStyle = 'color: #f0ad4e; font-weight: bold;';
|
||||
details.push(`<span style="${gpuStyle}">GPU: ${stats.utilization.gpu}%</span>`);
|
||||
}
|
||||
|
||||
// Memory Utilization
|
||||
if (stats.utilization && stats.utilization.memory) {
|
||||
const memUsage = parseInt(stats.utilization.memory);
|
||||
@@ -467,13 +482,18 @@ Ext.define('PVE.node.StatusView', {
|
||||
|
||||
// Temperature
|
||||
if (stats.temperature) {
|
||||
const gpuTemp = gpuTempHelper.getTemp(parseFloat(stats.temperature.gpu));
|
||||
const tempUnit = gpuTempHelper.getUnit();
|
||||
// Convert thresholds to target unit for comparison
|
||||
const tempHigh = gpuTempHelper.getTemp(80);
|
||||
const tempWarn = gpuTempHelper.getTemp(70);
|
||||
let tempStyle = '';
|
||||
if (stats.temperature.gpu >= 80) {
|
||||
if (gpuTemp >= tempHigh) {
|
||||
tempStyle = 'color: red; font-weight: bold;';
|
||||
} else if (stats.temperature.gpu >= 70) {
|
||||
} else if (gpuTemp >= tempWarn) {
|
||||
tempStyle = 'color: #FFC300; font-weight: bold;';
|
||||
}
|
||||
details.push(`Temp: <span style="${tempStyle}">${stats.temperature.gpu}${stats.temperature.unit}</span>`);
|
||||
details.push(`Temp: <span style="${tempStyle}">${Ext.util.Format.number(gpuTemp, '0')}${tempUnit}</span>`);
|
||||
}
|
||||
|
||||
// Power
|
||||
@@ -489,9 +509,12 @@ Ext.define('PVE.node.StatusView', {
|
||||
}
|
||||
|
||||
html += '</table>';
|
||||
return html.indexOf('<tr>') > 0
|
||||
? '<div style="padding-left: 20px; box-sizing: border-box;">' + html + '</div>'
|
||||
: '';
|
||||
if (html.indexOf('<tr>') <= 0) {
|
||||
this.hide();
|
||||
return '';
|
||||
}
|
||||
this.show();
|
||||
return '<div style="padding-left: 20px; box-sizing: border-box;">' + html + '</div>';
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -520,7 +543,7 @@ Ext.define('PVE.node.StatusView', {
|
||||
} catch(e) {
|
||||
objValue = {};
|
||||
}
|
||||
const tempHelper = Ext.create('PVE.mod.TempHelper', {srcUnit: PVE.mod.TempHelper.CELSIUS, dstUnit: objValue.temp_unit === 'F' ? PVE.mod.TempHelper.FAHRENHEIT : PVE.mod.TempHelper.CELSIUS});
|
||||
const tempHelper = Ext.create('PVE.mod.TempHelper', {srcUnit: PVE.mod.TempHelper.CELSIUS, dstUnit: value.temp_unit === 'F' ? PVE.mod.TempHelper.FAHRENHEIT : PVE.mod.TempHelper.CELSIUS});
|
||||
const drvKeys = Object.keys(objValue).filter(item => String(item).startsWith(addressPrefix)).sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }));
|
||||
let drvData = [];
|
||||
drvKeys.forEach((drvKey) => {
|
||||
@@ -600,7 +623,7 @@ Ext.define('PVE.node.StatusView', {
|
||||
} catch(e) {
|
||||
objValue = {};
|
||||
}
|
||||
const tempHelper = Ext.create('PVE.mod.TempHelper', {srcUnit: PVE.mod.TempHelper.CELSIUS, dstUnit: objValue.temp_unit === 'F' ? PVE.mod.TempHelper.FAHRENHEIT : PVE.mod.TempHelper.CELSIUS});
|
||||
const tempHelper = Ext.create('PVE.mod.TempHelper', {srcUnit: PVE.mod.TempHelper.CELSIUS, dstUnit: value.temp_unit === 'F' ? PVE.mod.TempHelper.FAHRENHEIT : PVE.mod.TempHelper.CELSIUS});
|
||||
const nvmeKeys = Object.keys(objValue).filter(item => String(item).startsWith(addressPrefix)).sort();
|
||||
let nvmeData = [];
|
||||
nvmeKeys.forEach((nvmeKey, index) => {
|
||||
@@ -688,7 +711,7 @@ Ext.define('PVE.node.StatusView', {
|
||||
} catch(e) {
|
||||
objValue = {};
|
||||
}
|
||||
const tempHelper = Ext.create('PVE.mod.TempHelper', {srcUnit: PVE.mod.TempHelper.CELSIUS, dstUnit: objValue.temp_unit === 'F' ? PVE.mod.TempHelper.FAHRENHEIT : PVE.mod.TempHelper.CELSIUS});
|
||||
const tempHelper = Ext.create('PVE.mod.TempHelper', {srcUnit: PVE.mod.TempHelper.CELSIUS, dstUnit: value.temp_unit === 'F' ? PVE.mod.TempHelper.FAHRENHEIT : PVE.mod.TempHelper.CELSIUS});
|
||||
|
||||
// Keep only keys that do not belong to known categories
|
||||
const otherKeys = Object.keys(objValue).filter(key =>
|
||||
@@ -846,6 +869,7 @@ Ext.define('PVE.node.StatusView', {
|
||||
this.hide();
|
||||
return '';
|
||||
} else if (!gpuStats || !gpuStats.Graphics || !gpuStats.Graphics.NVIDIA) {
|
||||
this.hide();
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -873,8 +897,10 @@ Ext.define('PVE.node.StatusView', {
|
||||
});
|
||||
|
||||
if (rows.length === 0) {
|
||||
this.hide();
|
||||
return '';
|
||||
}
|
||||
this.show();
|
||||
|
||||
return '<div style="padding-left: 20px; box-sizing: border-box;"><table style="width: 100%; border-collapse: collapse; table-layout: fixed;">' + rows.join('') + '</table></div>';
|
||||
},
|
||||
|
||||
@@ -91,7 +91,15 @@ sub read_sysfs {
|
||||
|
||||
sub is_process_alive {
|
||||
my ($pid) = @_;
|
||||
return -d "/proc/$pid";
|
||||
return 0 unless -d "/proc/$pid";
|
||||
# A zombie still has /proc/<pid> but is dead - otherwise a stale
|
||||
# worker lock is never cleaned up.
|
||||
if (open my $fh, '<', "/proc/$pid/stat") {
|
||||
my $line = <$fh>;
|
||||
close $fh;
|
||||
return 0 if defined $line && $line =~ /\)\s+Z\s/;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub read_lock_pid {
|
||||
|
||||
Reference in new issue
Block a user