What a sexy pre-commit config file !

This commit is contained in:
nicolargo 2025-11-22 18:48:13 +01:00
parent 868aa0f4b1
commit 50818213b1
58 changed files with 8489 additions and 7673 deletions

View File

@ -1,36 +1,105 @@
repos: repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.24.2
hooks:
- id: gitleaks
name: "🔒 security · Detect hardcoded secrets"
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.1 rev: v0.14.1
hooks: hooks:
# Run the linter.
- id: ruff-check - id: ruff-check
name: "🐍 python · Linter with Ruff"
types_or: [ python, pyi ] types_or: [ python, pyi ]
args: [ --fix, --exit-non-zero-on-fix ] args: [ --fix, --exit-non-zero-on-fix ]
# Run the formatter.
- id: ruff-format - id: ruff-format
name: "🐍 python · Format with Ruff"
types_or: [ python, pyi ] types_or: [ python, pyi ]
# - repo: https://github.com/RobertCraigie/pyright-python
# rev: v1.1.391
# hooks:
# - id: pyright
# name: "🐍 python · Check types"
# - repo: https://github.com/biomejs/pre-commit
# rev: "v2.3.7"
# hooks:
# - id: biome-check
# name: "🟨 javascript · Lint, format, and safe fixes with Biome"
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.35.0
hooks:
- id: check-github-workflows
name: "🐙 github-actions · Validate gh workflow files"
args: ["--verbose"]
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.11.0.1
hooks:
- id: shellcheck
name: "🐚 shell · Lint shell scripts"
- repo: https://github.com/openstack/bashate
rev: 2.1.1
hooks:
- id: bashate
name: "🐚 shell · Check shell script code style"
entry: bashate --error . --ignore=E006
- repo: https://github.com/mrtazz/checkmake.git
rev: 0.2.2
hooks:
- id: checkmake
name: "🐮 Makefile · Lint Makefile"
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0 rev: v6.0.0
hooks: hooks:
- id: check-ast - id: check-executables-have-shebangs
- id: check-docstring-first name: "📁 filesystem/⚙️ exec · Verify shebang presence"
- id: check-json
- id: check-merge-conflict
- id: check-shebang-scripts-are-executable - id: check-shebang-scripts-are-executable
name: "📁 filesystem/⚙️ exec · Verify script permissions"
- id: check-case-conflict
name: "📁 filesystem/📝 names · Check case sensitivity"
- id: destroyed-symlinks
name: "📁 filesystem/🔗 symlink · Detect broken symlinks"
- id: check-merge-conflict
name: "🌳 git · Detect conflict markers"
- id: forbid-new-submodules
name: "🌳 git · Prevent submodule creation"
- id: no-commit-to-branch
name: "🌳 git · Protect main branches"
args: ["--branch", "main", "--branch", "master"]
- id: check-added-large-files
name: "🌳 git · Block large file commits"
args: ['--maxkb=5000']
- id: check-ast
name: "🐍 python/🔍 quality · Validate Python AST"
- id: check-docstring-first
name: "🐍 python/📝 style · Enforce docstring at top"
- id: check-json
name: "📄 formats/json · Validate JSON files"
- id: check-shebang-scripts-are-executable
name: "📁 filesystem/⚙️ exec · Ensure scripts are executable"
- id: check-toml - id: check-toml
name: "📄 formats/toml · Validate TOML files"
- id: check-yaml - id: check-yaml
name: "📄 formats/yaml · Validate YAML syntax"
- id: debug-statements - id: debug-statements
name: "🐍 python/🪲 debug · Detect debug statements"
- id: detect-private-key - id: detect-private-key
name: "🔐 security · Detect private keys"
- id: mixed-line-ending - id: mixed-line-ending
name: "📄 text/↩️ newline · Normalize line endings"
- id: requirements-txt-fixer - id: requirements-txt-fixer
name: "🐍 python/📦 deps · Sort requirements.txt"
- repo: local - repo: local
hooks: hooks:
# test duplicate line at the end of file with a custom script
# /bin/bash tests-data/tools/find-duplicate-lines.sh
- id: find-duplicate-lines - id: find-duplicate-lines
name: find duplicate lines at the end of file name: "❗local script · Find duplicate lines at the end of file"
entry: bash tests-data/tools/find-duplicate-lines.sh entry: bash tests-data/tools/find-duplicate-lines.sh
language: system language: system
types: [python] types: [python]

View File

@ -20,14 +20,12 @@ UV_RUN := .venv-uv/bin/uv
# if the command is only `make`, the default tasks will be the printing of the help. # if the command is only `make`, the default tasks will be the printing of the help.
.DEFAULT_GOAL := help .DEFAULT_GOAL := help
.PHONY: help test docs docs-server venv .PHONY: help test docs docs-server venv requirements profiling docker all clean
help: ## List all make commands available help: ## List all make commands available
@grep -E '^[\.a-zA-Z_%-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ @grep -E '^[\.a-zA-Z_%-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk -F ":" '{print $1}' | \ awk -F ":" '{print $1}' | \
grep -v % | \ grep -v % | sed 's/\\//g' | sort | \
sed 's/\\//g' | \
sort | \
awk 'BEGIN {FS = ":[^:]*?##"}; {printf "\033[1;34mmake %-50s\033[0m %s\n", $$1, $$2}' awk 'BEGIN {FS = ":[^:]*?##"}; {printf "\033[1;34mmake %-50s\033[0m %s\n", $$1, $$2}'
# =================================================================== # ===================================================================
@ -142,7 +140,10 @@ test-exports: test-export-csv test-export-json test-export-influxdb-v1 test-expo
# Linters, profilers and cyber security # Linters, profilers and cyber security
# =================================================================== # ===================================================================
find-duplicate-lines: pre-commit: ## Run pre-commit hooks
$(UV_RUN) run pre-commit run --all-files
find-duplicate-lines: ## Search for duplicate lines in files
/bin/bash tests-data/tools/find-duplicate-lines.sh /bin/bash tests-data/tools/find-duplicate-lines.sh
format: ## Format the code format: ## Format the code

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,24 @@
{ {
"version": 1, "version": 1,
"disable_existing_loggers": "False", "disable_existing_loggers": "False",
"root": {"level": "INFO", "handlers": ["console"]}, "root": { "level": "INFO", "handlers": ["console"] },
"formatters": { "formatters": {
"standard": {"format": "%(asctime)s -- %(levelname)s -- %(message)s"}, "standard": { "format": "%(asctime)s -- %(levelname)s -- %(message)s" },
"short": {"format": "%(levelname)s -- %(message)s"}, "short": { "format": "%(levelname)s -- %(message)s" },
"long": {"format": "%(asctime)s -- %(levelname)s -- %(message)s (%(funcName)s in %(filename)s)"}, "long": {
"free": {"format": "%(message)s"} "format": "%(asctime)s -- %(levelname)s -- %(message)s (%(funcName)s in %(filename)s)"
}, },
"handlers": { "free": { "format": "%(message)s" }
"console": {"class": "logging.StreamHandler", "formatter": "standard"} },
}, "handlers": {
"loggers": { "console": { "class": "logging.StreamHandler", "formatter": "standard" }
"debug": {"handlers": ["console"], "level": "DEBUG"}, },
"verbose": {"handlers": ["console"], "level": "INFO"}, "loggers": {
"standard": {"handlers": ["console"], "level": "INFO"}, "debug": { "handlers": ["console"], "level": "DEBUG" },
"requests": {"handlers": ["console"], "level": "ERROR"}, "verbose": { "handlers": ["console"], "level": "INFO" },
"elasticsearch": {"handlers": ["console"], "level": "ERROR"}, "standard": { "handlers": ["console"], "level": "INFO" },
"elasticsearch.trace": {"handlers": ["console"], "level": "ERROR"} "requests": { "handlers": ["console"], "level": "ERROR" },
} "elasticsearch": { "handlers": ["console"], "level": "ERROR" },
} "elasticsearch.trace": { "handlers": ["console"], "level": "ERROR" }
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,5 @@
#!/bin/sh
make clean
make html make html
LC_ALL=C make man LC_ALL=C make man

View File

@ -1,10 +1,10 @@
module.exports = { module.exports = {
printWidth: 100, printWidth: 100,
arrowParens: 'always', arrowParens: "always",
bracketSpacing: true, bracketSpacing: true,
semi: true, semi: true,
singleQuote: true, singleQuote: true,
tabWidth: 4, tabWidth: 4,
trailingComma: 'none', trailingComma: "none",
useTabs: false useTabs: false,
}; };

View File

@ -1,29 +1,29 @@
import eslint from '@eslint/js'; import eslint from "@eslint/js";
import eslintConfigPrettier from 'eslint-config-prettier'; import eslintConfigPrettier from "eslint-config-prettier";
import eslintPluginVue from 'eslint-plugin-vue'; import eslintPluginVue from "eslint-plugin-vue";
import globals from 'globals'; import globals from "globals";
import typescriptEslint from 'typescript-eslint'; import typescriptEslint from "typescript-eslint";
export default typescriptEslint.config( export default typescriptEslint.config(
{ ignores: ['*.d.ts', '**/coverage', '**/dist'] }, { ignores: ["*.d.ts", "**/coverage", "**/dist"] },
{ {
extends: [ extends: [
eslint.configs.recommended, eslint.configs.recommended,
...typescriptEslint.configs.recommended, ...typescriptEslint.configs.recommended,
...eslintPluginVue.configs['flat/recommended'], ...eslintPluginVue.configs["flat/recommended"],
], ],
files: ['**/*.{ts,vue}'], files: ["**/*.{ts,vue}"],
languageOptions: { languageOptions: {
ecmaVersion: 'latest', ecmaVersion: "latest",
sourceType: 'module', sourceType: "module",
globals: globals.browser, globals: globals.browser,
parserOptions: { parserOptions: {
parser: typescriptEslint.parser, parser: typescriptEslint.parser,
}, },
}, },
rules: { rules: {
// your rules // your rules
}, },
}, },
eslintConfigPrettier eslintConfigPrettier,
); );

View File

@ -90,329 +90,335 @@
</template> </template>
<script> <script>
import hotkeys from 'hotkeys-js'; import hotkeys from "hotkeys-js";
import { GlancesStats } from './services.js'; import GlancesHelp from "./components/help.vue";
import { store } from './store.js'; import GlancesPluginAlert from "./components/plugin-alert.vue";
import GlancesPluginCloud from "./components/plugin-cloud.vue";
import GlancesPluginConnections from "./components/plugin-connections.vue";
import GlancesPluginContainers from "./components/plugin-containers.vue";
import GlancesPluginCpu from "./components/plugin-cpu.vue";
import GlancesPluginDiskio from "./components/plugin-diskio.vue";
import GlancesPluginFolders from "./components/plugin-folders.vue";
import GlancesPluginFs from "./components/plugin-fs.vue";
import GlancesPluginGpu from "./components/plugin-gpu.vue";
import GlancesPluginHostname from "./components/plugin-hostname.vue";
import GlancesPluginIp from "./components/plugin-ip.vue";
import GlancesPluginIrq from "./components/plugin-irq.vue";
import GlancesPluginLoad from "./components/plugin-load.vue";
import GlancesPluginMem from "./components/plugin-mem.vue";
import GlancesPluginMemswap from "./components/plugin-memswap.vue";
import GlancesPluginNetwork from "./components/plugin-network.vue";
import GlancesPluginNow from "./components/plugin-now.vue";
import GlancesPluginPercpu from "./components/plugin-percpu.vue";
import GlancesPluginPorts from "./components/plugin-ports.vue";
import GlancesPluginProcess from "./components/plugin-process.vue";
import GlancesPluginQuicklook from "./components/plugin-quicklook.vue";
import GlancesPluginRaid from "./components/plugin-raid.vue";
import GlancesPluginSensors from "./components/plugin-sensors.vue";
import GlancesPluginSmart from "./components/plugin-smart.vue";
import GlancesPluginSystem from "./components/plugin-system.vue";
import GlancesPluginUptime from "./components/plugin-uptime.vue";
import GlancesPluginVms from "./components/plugin-vms.vue";
import GlancesPluginWifi from "./components/plugin-wifi.vue";
import { GlancesStats } from "./services.js";
import { store } from "./store.js";
import GlancesHelp from './components/help.vue'; import uiconfig from "./uiconfig.json";
import GlancesPluginAlert from './components/plugin-alert.vue';
import GlancesPluginCloud from './components/plugin-cloud.vue';
import GlancesPluginConnections from './components/plugin-connections.vue';
import GlancesPluginCpu from './components/plugin-cpu.vue';
import GlancesPluginDiskio from './components/plugin-diskio.vue';
import GlancesPluginContainers from './components/plugin-containers.vue';
import GlancesPluginFolders from './components/plugin-folders.vue';
import GlancesPluginFs from './components/plugin-fs.vue';
import GlancesPluginGpu from './components/plugin-gpu.vue';
import GlancesPluginHostname from './components/plugin-hostname.vue';
import GlancesPluginIp from './components/plugin-ip.vue';
import GlancesPluginIrq from './components/plugin-irq.vue';
import GlancesPluginLoad from './components/plugin-load.vue';
import GlancesPluginMem from './components/plugin-mem.vue';
import GlancesPluginMemswap from './components/plugin-memswap.vue';
import GlancesPluginNetwork from './components/plugin-network.vue';
import GlancesPluginNow from './components/plugin-now.vue';
import GlancesPluginPercpu from './components/plugin-percpu.vue';
import GlancesPluginPorts from './components/plugin-ports.vue';
import GlancesPluginProcess from './components/plugin-process.vue';
import GlancesPluginQuicklook from './components/plugin-quicklook.vue';
import GlancesPluginRaid from './components/plugin-raid.vue';
import GlancesPluginSmart from './components/plugin-smart.vue';
import GlancesPluginSensors from './components/plugin-sensors.vue';
import GlancesPluginSystem from './components/plugin-system.vue';
import GlancesPluginUptime from './components/plugin-uptime.vue';
import GlancesPluginVms from './components/plugin-vms.vue';
import GlancesPluginWifi from './components/plugin-wifi.vue';
import uiconfig from './uiconfig.json';
export default { export default {
components: { components: {
GlancesHelp, GlancesHelp,
GlancesPluginAlert, GlancesPluginAlert,
GlancesPluginCloud, GlancesPluginCloud,
GlancesPluginConnections, GlancesPluginConnections,
GlancesPluginCpu, GlancesPluginCpu,
GlancesPluginDiskio, GlancesPluginDiskio,
GlancesPluginContainers, GlancesPluginContainers,
GlancesPluginFolders, GlancesPluginFolders,
GlancesPluginFs, GlancesPluginFs,
GlancesPluginGpu, GlancesPluginGpu,
GlancesPluginHostname, GlancesPluginHostname,
GlancesPluginIp, GlancesPluginIp,
GlancesPluginIrq, GlancesPluginIrq,
GlancesPluginLoad, GlancesPluginLoad,
GlancesPluginMem, GlancesPluginMem,
GlancesPluginMemswap, GlancesPluginMemswap,
GlancesPluginNetwork, GlancesPluginNetwork,
GlancesPluginNow, GlancesPluginNow,
GlancesPluginPercpu, GlancesPluginPercpu,
GlancesPluginPorts, GlancesPluginPorts,
GlancesPluginProcess, GlancesPluginProcess,
GlancesPluginQuicklook, GlancesPluginQuicklook,
GlancesPluginRaid, GlancesPluginRaid,
GlancesPluginSensors, GlancesPluginSensors,
GlancesPluginSmart, GlancesPluginSmart,
GlancesPluginSystem, GlancesPluginSystem,
GlancesPluginUptime, GlancesPluginUptime,
GlancesPluginVms, GlancesPluginVms,
GlancesPluginWifi GlancesPluginWifi,
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
config() { config() {
return this.store.config || {}; return this.store.config || {};
}, },
data() { data() {
return this.store.data || {}; return this.store.data || {};
}, },
dataLoaded() { dataLoaded() {
return this.store.data !== undefined; return this.store.data !== undefined;
}, },
hasGpu() { hasGpu() {
return this.store.data.stats.gpu.length > 0; return this.store.data.stats.gpu.length > 0;
}, },
isLinux() { isLinux() {
return this.store.data.isLinux; return this.store.data.isLinux;
}, },
title() { title() {
const { data } = this; const { data } = this;
const title = (data.stats && data.stats.system && data.stats.system.hostname) || ''; const title =
return title ? `${title} - Glances` : 'Glances'; (data.stats && data.stats.system && data.stats.system.hostname) || "";
}, return title ? `${title} - Glances` : "Glances";
topMenu() { },
return this.config.outputs !== undefined && this.config.outputs.top_menu !== undefined topMenu() {
? this.config.outputs.top_menu.split(',') return this.config.outputs !== undefined &&
: uiconfig.topMenu; this.config.outputs.top_menu !== undefined
}, ? this.config.outputs.top_menu.split(",")
leftMenu() { : uiconfig.topMenu;
return this.config.outputs !== undefined && this.config.outputs.left_menu !== undefined },
? this.config.outputs.left_menu.split(',') leftMenu() {
: uiconfig.leftMenu; return this.config.outputs !== undefined &&
} this.config.outputs.left_menu !== undefined
}, ? this.config.outputs.left_menu.split(",")
watch: { : uiconfig.leftMenu;
title() { },
if (document) { },
document.title = this.title; watch: {
} title() {
} if (document) {
}, document.title = this.title;
mounted() { }
const GLANCES = window.__GLANCES__ || {}; },
const refreshTime = isFinite(GLANCES['refresh-time']) },
? parseInt(GLANCES['refresh-time'], 10) mounted() {
: undefined; const GLANCES = window.__GLANCES__ || {};
GlancesStats.init(refreshTime); const refreshTime = isFinite(GLANCES["refresh-time"])
this.setupHotKeys(); ? parseInt(GLANCES["refresh-time"], 10)
}, : undefined;
beforeUnmount() { GlancesStats.init(refreshTime);
hotkeys.unbind(); this.setupHotKeys();
}, },
methods: { beforeUnmount() {
setupHotKeys() { hotkeys.unbind();
// a => Sort processes/containers automatically },
hotkeys('a', () => { methods: {
this.store.args.sort_processes_key = null; setupHotKeys() {
}); // a => Sort processes/containers automatically
hotkeys("a", () => {
this.store.args.sort_processes_key = null;
});
// c => Sort processes/containers by CPU% // c => Sort processes/containers by CPU%
hotkeys('c', () => { hotkeys("c", () => {
this.store.args.sort_processes_key = 'cpu_percent'; this.store.args.sort_processes_key = "cpu_percent";
}); });
// m => Sort processes/containers by MEM% // m => Sort processes/containers by MEM%
hotkeys('m', () => { hotkeys("m", () => {
this.store.args.sort_processes_key = 'memory_percent'; this.store.args.sort_processes_key = "memory_percent";
}); });
// u => Sort processes/containers by user // u => Sort processes/containers by user
hotkeys('u', () => { hotkeys("u", () => {
this.store.args.sort_processes_key = 'username'; this.store.args.sort_processes_key = "username";
}); });
// p => Sort processes/containers by name // p => Sort processes/containers by name
hotkeys('p', () => { hotkeys("p", () => {
this.store.args.sort_processes_key = 'name'; this.store.args.sort_processes_key = "name";
}); });
// i => Sort processes/containers by I/O rate // i => Sort processes/containers by I/O rate
hotkeys('i', () => { hotkeys("i", () => {
this.store.args.sort_processes_key = 'io_counters'; this.store.args.sort_processes_key = "io_counters";
}); });
// t => Sort processes/containers by time // t => Sort processes/containers by time
hotkeys('t', () => { hotkeys("t", () => {
this.store.args.sort_processes_key = 'timemillis'; this.store.args.sort_processes_key = "timemillis";
}); });
// A => Enable/disable AMPs // A => Enable/disable AMPs
hotkeys('shift+A', () => { hotkeys("shift+A", () => {
this.store.args.disable_amps = !this.store.args.disable_amps; this.store.args.disable_amps = !this.store.args.disable_amps;
}); });
// d => Show/hide disk I/O stats // d => Show/hide disk I/O stats
hotkeys('d', () => { hotkeys("d", () => {
this.store.args.disable_diskio = !this.store.args.disable_diskio; this.store.args.disable_diskio = !this.store.args.disable_diskio;
}); });
// Q => Show/hide IRQ // Q => Show/hide IRQ
hotkeys('shift+Q', () => { hotkeys("shift+Q", () => {
this.store.args.enable_irq = !this.store.args.enable_irq; this.store.args.enable_irq = !this.store.args.enable_irq;
}); });
// f => Show/hide filesystem stats // f => Show/hide filesystem stats
hotkeys('f', () => { hotkeys("f", () => {
this.store.args.disable_fs = !this.store.args.disable_fs; this.store.args.disable_fs = !this.store.args.disable_fs;
}); });
// j => Accumulate processes by program // j => Accumulate processes by program
hotkeys('j', () => { hotkeys("j", () => {
this.store.args.programs = !this.store.args.programs; this.store.args.programs = !this.store.args.programs;
}); });
// k => Show/hide connections stats // k => Show/hide connections stats
hotkeys('k', () => { hotkeys("k", () => {
this.store.args.disable_connections = !this.store.args.disable_connections; this.store.args.disable_connections =
}); !this.store.args.disable_connections;
});
// n => Show/hide network stats // n => Show/hide network stats
hotkeys('n', () => { hotkeys("n", () => {
this.store.args.disable_network = !this.store.args.disable_network; this.store.args.disable_network = !this.store.args.disable_network;
}); });
// s => Show/hide sensors stats // s => Show/hide sensors stats
hotkeys('s', () => { hotkeys("s", () => {
this.store.args.disable_sensors = !this.store.args.disable_sensors; this.store.args.disable_sensors = !this.store.args.disable_sensors;
}); });
// 2 => Show/hide left sidebar // 2 => Show/hide left sidebar
hotkeys('2', () => { hotkeys("2", () => {
this.store.args.disable_left_sidebar = !this.store.args.disable_left_sidebar; this.store.args.disable_left_sidebar =
}); !this.store.args.disable_left_sidebar;
});
// z => Enable/disable processes stats // z => Enable/disable processes stats
hotkeys('z', () => { hotkeys("z", () => {
this.store.args.disable_process = !this.store.args.disable_process; this.store.args.disable_process = !this.store.args.disable_process;
}); });
// S => Enable/disable short processes name // S => Enable/disable short processes name
hotkeys('shift+S', () => { hotkeys("shift+S", () => {
this.store.args.process_short_name = !this.store.args.process_short_name; this.store.args.process_short_name =
}); !this.store.args.process_short_name;
});
// D => Enable/disable containers stats // D => Enable/disable containers stats
hotkeys('shift+D', () => { hotkeys("shift+D", () => {
this.store.args.disable_containers = !this.store.args.disable_containers; this.store.args.disable_containers =
}); !this.store.args.disable_containers;
});
// b => Bytes or bits for network I/O // b => Bytes or bits for network I/O
hotkeys('b', () => { hotkeys("b", () => {
this.store.args.byte = !this.store.args.byte; this.store.args.byte = !this.store.args.byte;
}); });
// 'B' => Switch between bit/s and IO/s for Disk IO // 'B' => Switch between bit/s and IO/s for Disk IO
hotkeys('shift+B', () => { hotkeys("shift+B", () => {
this.store.args.diskio_iops = !this.store.args.diskio_iops; this.store.args.diskio_iops = !this.store.args.diskio_iops;
if (this.store.args.diskio_iops) { if (this.store.args.diskio_iops) {
this.store.args.diskio_latency = false; this.store.args.diskio_latency = false;
} }
}); });
// 'L' => Switch to latency for Disk IO // 'L' => Switch to latency for Disk IO
hotkeys('shift+L', () => { hotkeys("shift+L", () => {
this.store.args.diskio_latency = !this.store.args.diskio_latency; this.store.args.diskio_latency = !this.store.args.diskio_latency;
if (this.store.args.diskio_latency) { if (this.store.args.diskio_latency) {
this.store.args.diskio_iops = false; this.store.args.diskio_iops = false;
} }
}); });
// l => Show/hide alert logs // l => Show/hide alert logs
hotkeys('l', () => { hotkeys("l", () => {
this.store.args.disable_alert = !this.store.args.disable_alert; this.store.args.disable_alert = !this.store.args.disable_alert;
}); });
// 1 => Global CPU or per-CPU stats // 1 => Global CPU or per-CPU stats
hotkeys('1', () => { hotkeys("1", () => {
this.store.args.percpu = !this.store.args.percpu; this.store.args.percpu = !this.store.args.percpu;
}); });
// h => Show/hide this help screen // h => Show/hide this help screen
hotkeys('h', () => { hotkeys("h", () => {
this.store.args.help_tag = !this.store.args.help_tag; this.store.args.help_tag = !this.store.args.help_tag;
}); });
// T => View network I/O as combination // T => View network I/O as combination
hotkeys('shift+T', () => { hotkeys("shift+T", () => {
this.store.args.network_sum = !this.store.args.network_sum; this.store.args.network_sum = !this.store.args.network_sum;
}); });
// U => View cumulative network I/O // U => View cumulative network I/O
hotkeys('shift+U', () => { hotkeys("shift+U", () => {
this.store.args.network_cumul = !this.store.args.network_cumul; this.store.args.network_cumul = !this.store.args.network_cumul;
}); });
// F => Show filesystem free space // F => Show filesystem free space
hotkeys('shift+F', () => { hotkeys("shift+F", () => {
this.store.args.fs_free_space = !this.store.args.fs_free_space; this.store.args.fs_free_space = !this.store.args.fs_free_space;
}); });
// 3 => Enable/disable quick look plugin // 3 => Enable/disable quick look plugin
hotkeys('3', () => { hotkeys("3", () => {
this.store.args.disable_quicklook = !this.store.args.disable_quicklook; this.store.args.disable_quicklook = !this.store.args.disable_quicklook;
}); });
// 6 => Enable/disable mean gpu // 6 => Enable/disable mean gpu
hotkeys('6', () => { hotkeys("6", () => {
this.store.args.meangpu = !this.store.args.meangpu; this.store.args.meangpu = !this.store.args.meangpu;
}); });
// G => Enable/disable gpu // G => Enable/disable gpu
hotkeys('shift+G', () => { hotkeys("shift+G", () => {
this.store.args.disable_gpu = !this.store.args.disable_gpu; this.store.args.disable_gpu = !this.store.args.disable_gpu;
}); });
hotkeys('5', () => { hotkeys("5", () => {
this.store.args.disable_quicklook = !this.store.args.disable_quicklook; this.store.args.disable_quicklook = !this.store.args.disable_quicklook;
this.store.args.disable_cpu = !this.store.args.disable_cpu; this.store.args.disable_cpu = !this.store.args.disable_cpu;
this.store.args.disable_mem = !this.store.args.disable_mem; this.store.args.disable_mem = !this.store.args.disable_mem;
this.store.args.disable_memswap = !this.store.args.disable_memswap; this.store.args.disable_memswap = !this.store.args.disable_memswap;
this.store.args.disable_load = !this.store.args.disable_load; this.store.args.disable_load = !this.store.args.disable_load;
this.store.args.disable_gpu = !this.store.args.disable_gpu; this.store.args.disable_gpu = !this.store.args.disable_gpu;
}); });
// I => Show/hide IP module // I => Show/hide IP module
hotkeys('shift+I', () => { hotkeys("shift+I", () => {
this.store.args.disable_ip = !this.store.args.disable_ip; this.store.args.disable_ip = !this.store.args.disable_ip;
}); });
// P => Enable/disable ports module // P => Enable/disable ports module
hotkeys('shift+P', () => { hotkeys("shift+P", () => {
this.store.args.disable_ports = !this.store.args.disable_ports; this.store.args.disable_ports = !this.store.args.disable_ports;
}); });
// V => Enable/disable VMs stats // V => Enable/disable VMs stats
hotkeys('shift+V', () => { hotkeys("shift+V", () => {
this.store.args.disable_vms = !this.store.args.disable_vms; this.store.args.disable_vms = !this.store.args.disable_vms;
}); });
// 'W' > Enable/Disable Wifi plugin // 'W' > Enable/Disable Wifi plugin
hotkeys('shift+W', () => { hotkeys("shift+W", () => {
this.store.args.disable_wifi = !this.store.args.disable_wifi; this.store.args.disable_wifi = !this.store.args.disable_wifi;
}); });
// 0 => Enable/disable IRIX mode (see issue #3158) // 0 => Enable/disable IRIX mode (see issue #3158)
hotkeys('0', () => { hotkeys("0", () => {
this.store.args.disable_irix = !this.store.args.disable_irix; this.store.args.disable_irix = !this.store.args.disable_irix;
}); });
} },
} },
}; };
</script> </script>

View File

@ -56,54 +56,59 @@
// import { store } from './store.js'; // import { store } from './store.js';
export default { export default {
data() { data() {
return { return {
servers: undefined, servers: undefined,
}; };
}, },
computed: { computed: {
serversListLoaded() { serversListLoaded() {
return this.servers !== undefined; return this.servers !== undefined;
}, },
}, },
created() { created() {
this.updateServersList(); this.updateServersList();
}, },
mounted() { mounted() {
const GLANCES = window.__GLANCES__ || {}; const GLANCES = window.__GLANCES__ || {};
const refreshTime = isFinite(GLANCES['refresh-time']) const refreshTime = isFinite(GLANCES["refresh-time"])
? parseInt(GLANCES['refresh-time'], 10) ? parseInt(GLANCES["refresh-time"], 10)
: undefined; : undefined;
this.interval = setInterval(this.updateServersList, refreshTime * 1000) this.interval = setInterval(this.updateServersList, refreshTime * 1000);
}, },
unmounted() { unmounted() {
clearInterval(this.interval) clearInterval(this.interval);
}, },
methods: { methods: {
updateServersList() { updateServersList() {
fetch('api/4/serverslist', { method: 'GET' }) fetch("api/4/serverslist", { method: "GET" })
.then((response) => response.json()) .then((response) => response.json())
.then((response) => (this.servers = response)); .then((response) => (this.servers = response));
}, },
formatNumber(value) { formatNumber(value) {
if (typeof value === "number" && !isNaN(value)) { if (typeof value === "number" && !isNaN(value)) {
return value.toFixed(1); return value.toFixed(1);
} }
return value; return value;
}, },
goToGlances(server) { goToGlances(server) {
if (server.protocol === 'rpc') { if (server.protocol === "rpc") {
alert("You just click on a Glances RPC server.\nPlease open a terminal and enter the following command line:\n\nglances -c " + String(server.ip) + " -p " + String(server.port)) alert(
} else { "You just click on a Glances RPC server.\nPlease open a terminal and enter the following command line:\n\nglances -c " +
window.location.href = server.uri; String(server.ip) +
} " -p " +
}, String(server.port),
getDecoration(server, column) { );
if (server[column + '_decoration'] === undefined) { } else {
return; window.location.href = server.uri;
} }
return server[column + '_decoration'].replace('_LOG', '').toLowerCase(); },
} getDecoration(server, column) {
} if (server[column + "_decoration"] === undefined) {
return;
}
return server[column + "_decoration"].replace("_LOG", "").toLowerCase();
},
},
}; };
</script> </script>

View File

@ -1,17 +1,17 @@
/* global module */ /* global module */
if (module.hot) { if (module.hot) {
module.hot.accept(); module.hot.accept();
} }
import '../css/custom.scss'; import "../css/custom.scss";
import '../css/style.scss'; import "../css/style.scss";
import * as bootstrap from 'bootstrap'; import * as bootstrap from "bootstrap";
import { createApp } from 'vue'; import { createApp } from "vue";
import App from './App.vue'; import App from "./App.vue";
import * as filters from "./filters.js"; import * as filters from "./filters.js";
const app = createApp(App); const app = createApp(App);
app.config.globalProperties.$filters = filters; app.config.globalProperties.$filters = filters;
app.mount('#app'); app.mount("#app");

View File

@ -1,17 +1,17 @@
/* global module */ /* global module */
if (module.hot) { if (module.hot) {
module.hot.accept(); module.hot.accept();
} }
import '../css/custom.scss'; import "../css/custom.scss";
import '../css/style.scss'; import "../css/style.scss";
import * as bootstrap from 'bootstrap'; import * as bootstrap from "bootstrap";
import { createApp } from 'vue'; import { createApp } from "vue";
import App from './Browser.vue'; import App from "./Browser.vue";
import * as filters from "./filters.js"; import * as filters from "./filters.js";
const app = createApp(App); const app = createApp(App);
app.config.globalProperties.$filters = filters; app.config.globalProperties.$filters = filters;
app.mount('#browser'); app.mount("#browser");

View File

@ -163,15 +163,15 @@
<script> <script>
export default { export default {
data() { data() {
return { return {
help: undefined help: undefined,
}; };
}, },
mounted() { mounted() {
fetch('api/4/help', { method: 'GET' }) fetch("api/4/help", { method: "GET" })
.then((response) => response.json()) .then((response) => response.json())
.then((response) => (this.help = response)); .then((response) => (this.help = response));
} },
}; };
</script> </script>

View File

@ -29,97 +29,110 @@
</template> </template>
<script> <script>
import { padStart } from 'lodash'; import { padStart } from "lodash";
import { GlancesFavico } from '../services.js'; import { GlancesFavico } from "../services.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['alert']; return this.data.stats["alert"];
}, },
alerts() { alerts() {
return (this.stats || []).map((alertStats) => { return (this.stats || []).map((alertStats) => {
const alert = {}; const alert = {};
alert.state = alertStats.state; alert.state = alertStats.state;
alert.type = alertStats.type; alert.type = alertStats.type;
alert.begin = alertStats.begin * 1000; alert.begin = alertStats.begin * 1000;
alert.end = alertStats.end * 1000; alert.end = alertStats.end * 1000;
alert.ongoing = alertStats.end == -1; alert.ongoing = alertStats.end == -1;
alert.min = alertStats.min; alert.min = alertStats.min;
alert.avg = alertStats.avg; alert.avg = alertStats.avg;
alert.max = alertStats.max; alert.max = alertStats.max;
if (alertStats.top.length > 0) { if (alertStats.top.length > 0) {
alert.top = ': ' + alertStats.top.join(', '); alert.top = ": " + alertStats.top.join(", ");
} }
if (!alert.ongoing) { if (!alert.ongoing) {
const duration = alert.end - alert.begin; const duration = alert.end - alert.begin;
const seconds = parseInt((duration / 1000) % 60), const seconds = parseInt((duration / 1000) % 60),
minutes = parseInt((duration / (1000 * 60)) % 60), minutes = parseInt((duration / (1000 * 60)) % 60),
hours = parseInt((duration / (1000 * 60 * 60)) % 24); hours = parseInt((duration / (1000 * 60 * 60)) % 24);
alert.duration = padStart(hours, 2, '0') + alert.duration =
':' + padStart(minutes, 2, '0') + padStart(hours, 2, "0") +
':' + padStart(seconds, 2, '0'); ":" +
} padStart(minutes, 2, "0") +
":" +
padStart(seconds, 2, "0");
}
return alert; return alert;
}); });
}, },
hasAlerts() { hasAlerts() {
return this.countAlerts > 0; return this.countAlerts > 0;
}, },
countAlerts() { countAlerts() {
return this.alerts.length; return this.alerts.length;
}, },
hasOngoingAlerts() { hasOngoingAlerts() {
return this.countOngoingAlerts > 0; return this.countOngoingAlerts > 0;
}, },
countOngoingAlerts() { countOngoingAlerts() {
return this.alerts.filter(({ ongoing }) => ongoing).length; return this.alerts.filter(({ ongoing }) => ongoing).length;
} },
}, },
watch: { watch: {
countOngoingAlerts() { countOngoingAlerts() {
if (this.countOngoingAlerts) { if (this.countOngoingAlerts) {
GlancesFavico.badge(this.countOngoingAlerts); GlancesFavico.badge(this.countOngoingAlerts);
} else { } else {
GlancesFavico.reset(); GlancesFavico.reset();
} }
} },
}, },
methods: { methods: {
formatDate(timestamp) { formatDate(timestamp) {
const tzOffset = new Date().getTimezoneOffset(); const tzOffset = new Date().getTimezoneOffset();
const hours = Math.trunc(Math.abs(tzOffset) / 60); const hours = Math.trunc(Math.abs(tzOffset) / 60);
const minutes = Math.abs(tzOffset % 60); const minutes = Math.abs(tzOffset % 60);
let tzString = tzOffset <= 0 ? '+' : '-'; let tzString = tzOffset <= 0 ? "+" : "-";
tzString += String(hours).padStart(2, '0') + String(minutes).padStart(2, '0'); tzString +=
String(hours).padStart(2, "0") + String(minutes).padStart(2, "0");
const date = new Date(timestamp); const date = new Date(timestamp);
return String(date.getFullYear()) + return (
'-' + String(date.getMonth() + 1).padStart(2, '0') + String(date.getFullYear()) +
'-' + String(date.getDate()).padStart(2, '0') + "-" +
' ' + String(date.getHours()).padStart(2, '0') + String(date.getMonth() + 1).padStart(2, "0") +
':' + String(date.getMinutes()).padStart(2, '0') + "-" +
':' + String(date.getSeconds()).padStart(2, '0') + String(date.getDate()).padStart(2, "0") +
'(' + tzString + ')'; " " +
}, String(date.getHours()).padStart(2, "0") +
clear() { ":" +
const requestOptions = { String(date.getMinutes()).padStart(2, "0") +
method: 'POST', ":" +
headers: { 'Content-Type': 'application/json' } String(date.getSeconds()).padStart(2, "0") +
}; "(" +
fetch('api/4/events/clear/all', requestOptions) tzString +
.then(response => response.json()) ")"
.then(data => product.value = data); );
} },
} clear() {
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
};
fetch("api/4/events/clear/all", requestOptions)
.then((response) => response.json())
.then((data) => (product.value = data));
},
},
}; };
</script> </script>

View File

@ -28,42 +28,42 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['amps']; return this.data.stats["amps"];
}, },
processes() { processes() {
return this.stats.filter((process) => process.result !== null); return this.stats.filter((process) => process.result !== null);
}, },
hasAmps() { hasAmps() {
return this.processes.length > 0; return this.processes.length > 0;
} },
}, },
methods: { methods: {
getNameDecoration(process) { getNameDecoration(process) {
const count = process.count; const count = process.count;
const countMin = process.countmin; const countMin = process.countmin;
const countMax = process.countmax; const countMax = process.countmax;
let decoration = 'ok'; let decoration = "ok";
if (count > 0) { if (count > 0) {
if ( if (
(countMin === null || count >= countMin) && (countMin === null || count >= countMin) &&
(countMax === null || count <= countMax) (countMax === null || count <= countMax)
) { ) {
decoration = 'ok'; decoration = "ok";
} else { } else {
decoration = 'careful'; decoration = "careful";
} }
} else { } else {
decoration = countMin === null ? 'ok' : 'critical'; decoration = countMin === null ? "ok" : "critical";
} }
return decoration; return decoration;
} },
} },
}; };
</script> </script>

View File

@ -6,24 +6,24 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['cloud']; return this.data.stats["cloud"];
}, },
provider() { provider() {
return this.stats['id'] !== undefined ? `${stats['platform']}` : null; return this.stats["id"] !== undefined ? `${stats["platform"]}` : null;
}, },
instance() { instance() {
const { stats } = this; const { stats } = this;
return this.stats['id'] !== undefined return this.stats["id"] !== undefined
? `${stats['type']} instance ${stats['name']} (${stats['region']})` ? `${stats["type"]} instance ${stats["name"]} (${stats["region"]})`
: null; : null;
} },
} },
}; };
</script> </script>

View File

@ -37,44 +37,44 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['connections']; return this.data.stats["connections"];
}, },
view() { view() {
return this.data.views['connections']; return this.data.views["connections"];
}, },
listen() { listen() {
return this.stats['LISTEN']; return this.stats["LISTEN"];
}, },
initiated() { initiated() {
return this.stats['initiated']; return this.stats["initiated"];
}, },
established() { established() {
return this.stats['ESTABLISHED']; return this.stats["ESTABLISHED"];
}, },
terminated() { terminated() {
return this.stats['terminated']; return this.stats["terminated"];
}, },
tracked() { tracked() {
return { return {
count: this.stats['nf_conntrack_count'], count: this.stats["nf_conntrack_count"],
max: this.stats['nf_conntrack_max'] max: this.stats["nf_conntrack_max"],
}; };
} },
}, },
methods: { methods: {
getDecoration(value) { getDecoration(value) {
if (this.view[value] === undefined) { if (this.view[value] === undefined) {
return; return;
} }
return this.view[value].decoration.toLowerCase(); return this.view[value].decoration.toLowerCase();
} },
} },
}; };
</script> </script>

View File

@ -177,122 +177,124 @@
</template> </template>
<script> <script>
import { orderBy } from 'lodash'; import { orderBy } from "lodash";
import { GlancesHelper } from '../services.js'; import { GlancesHelper } from "../services.js";
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store, store,
sorter: undefined sorter: undefined,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
sortProcessesKey() { sortProcessesKey() {
return this.args.sort_processes_key; return this.args.sort_processes_key;
}, },
stats() { stats() {
return this.data.stats['containers']; return this.data.stats["containers"];
}, },
views() { views() {
return this.data.views['containers']; return this.data.views["containers"];
}, },
containers() { containers() {
const { sorter } = this; const { sorter } = this;
const containers = (this.stats || []) // const containers = (this.stats || []) //
.map((containerData) => { .map((containerData) => {
// Memory usage no cache is reflected the algorithm used in Docker top // Memory usage no cache is reflected the algorithm used in Docker top
let memory_usage_no_cache; let memory_usage_no_cache;
if (containerData.memory_usage != undefined) { if (containerData.memory_usage != undefined) {
memory_usage_no_cache = containerData.memory_usage; memory_usage_no_cache = containerData.memory_usage;
if (containerData.memory_inactive_file != undefined) { if (containerData.memory_inactive_file != undefined) {
memory_usage_no_cache = memory_usage_no_cache =
memory_usage_no_cache - containerData.memory_inactive_file; memory_usage_no_cache - containerData.memory_inactive_file;
} }
} else { } else {
memory_usage_no_cache = undefined; memory_usage_no_cache = undefined;
} }
return { return {
id: containerData.id, id: containerData.id,
name: containerData.name, name: containerData.name,
status: containerData.status, status: containerData.status,
uptime: containerData.uptime, uptime: containerData.uptime,
cpu_percent: containerData.cpu.total, cpu_percent: containerData.cpu.total,
memory_usage: memory_usage_no_cache, memory_usage: memory_usage_no_cache,
limit: containerData.memory.limit, limit: containerData.memory.limit,
io_rx: containerData.io_rx, io_rx: containerData.io_rx,
io_wx: containerData.io_wx, io_wx: containerData.io_wx,
network_rx: containerData.network_rx, network_rx: containerData.network_rx,
network_tx: containerData.network_tx, network_tx: containerData.network_tx,
ports: containerData.ports, ports: containerData.ports,
command: containerData.command, command: containerData.command,
image: containerData.image, image: containerData.image,
engine: containerData.engine, engine: containerData.engine,
pod_id: containerData.pod_id pod_id: containerData.pod_id,
}; };
}); });
return orderBy( return orderBy(
containers, containers,
[sorter.column].map((col) => { [sorter.column].map((col) => {
const sorter = (item) => const sorter = (item) =>
item[col === 'memory_percent' ? 'memory_usage' : col] ?? -Infinity; item[col === "memory_percent" ? "memory_usage" : col] ?? -Infinity;
return sorter; return sorter;
}, []), }, []),
[sorter.isReverseColumn(sorter.column) ? 'desc' : 'asc'] [sorter.isReverseColumn(sorter.column) ? "desc" : "asc"],
); );
}, },
showEngine() { showEngine() {
return this.views.show_engine_name; return this.views.show_engine_name;
}, },
showPod() { showPod() {
return this.views.show_pod_name; return this.views.show_pod_name;
} },
}, },
watch: { watch: {
sortProcessesKey: { sortProcessesKey: {
immediate: true, immediate: true,
handler(sortProcessesKey) { handler(sortProcessesKey) {
const sortable = ['cpu_percent', 'memory_percent', 'name']; const sortable = ["cpu_percent", "memory_percent", "name"];
function isReverseColumn(column) { function isReverseColumn(column) {
return !['name'].includes(column); return !["name"].includes(column);
} }
function getColumnLabel(value) { function getColumnLabel(value) {
const labels = { const labels = {
io_counters: 'disk IO', io_counters: "disk IO",
cpu_percent: 'CPU consumption', cpu_percent: "CPU consumption",
memory_usage: 'memory consumption', memory_usage: "memory consumption",
cpu_times: 'uptime', cpu_times: "uptime",
name: 'container name', name: "container name",
None: 'None' None: "None",
}; };
return labels[value] || value; return labels[value] || value;
} }
if (!sortProcessesKey || sortable.includes(sortProcessesKey)) { if (!sortProcessesKey || sortable.includes(sortProcessesKey)) {
this.sorter = { this.sorter = {
column: this.args.sort_processes_key || 'cpu_percent', column: this.args.sort_processes_key || "cpu_percent",
auto: !this.args.sort_processes_key, auto: !this.args.sort_processes_key,
isReverseColumn, isReverseColumn,
getColumnLabel getColumnLabel,
}; };
} }
} },
} },
}, },
methods: { methods: {
getDisableStats() { getDisableStats() {
return GlancesHelper.getLimit('containers', 'containers_disable_stats') || []; return (
} GlancesHelper.getLimit("containers", "containers_disable_stats") || []
} );
},
},
}; };
</script> </script>

View File

@ -122,85 +122,89 @@ v-if="!isWindows && !isSunOS && soft_interrupts != undefined" scope="col"
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['cpu']; return this.data.stats["cpu"];
}, },
view() { view() {
return this.data.views['cpu']; return this.data.views["cpu"];
}, },
isLinux() { isLinux() {
return this.data.isLinux; return this.data.isLinux;
}, },
isSunOS() { isSunOS() {
return this.data.isSunOS; return this.data.isSunOS;
}, },
isWindows() { isWindows() {
return this.data.isWindows; return this.data.isWindows;
}, },
total() { total() {
return this.stats.total; return this.stats.total;
}, },
user() { user() {
return this.stats.user; return this.stats.user;
}, },
system() { system() {
return this.stats.system; return this.stats.system;
}, },
idle() { idle() {
return this.stats.idle; return this.stats.idle;
}, },
nice() { nice() {
return this.stats.nice; return this.stats.nice;
}, },
irq() { irq() {
return this.stats.irq; return this.stats.irq;
}, },
iowait() { iowait() {
return this.stats.iowait; return this.stats.iowait;
}, },
dpc() { dpc() {
return this.stats.dpc; return this.stats.dpc;
}, },
steal() { steal() {
return this.stats.steal; return this.stats.steal;
}, },
guest() { guest() {
return this.stats.guest; return this.stats.guest;
}, },
ctx_switches() { ctx_switches() {
const { stats } = this; const { stats } = this;
return stats.ctx_switches return stats.ctx_switches
? Math.floor(stats.ctx_switches / stats.time_since_update) ? Math.floor(stats.ctx_switches / stats.time_since_update)
: null; : null;
}, },
interrupts() { interrupts() {
const { stats } = this; const { stats } = this;
return stats.interrupts ? Math.floor(stats.interrupts / stats.time_since_update) : null; return stats.interrupts
}, ? Math.floor(stats.interrupts / stats.time_since_update)
soft_interrupts() { : null;
const { stats } = this; },
return stats.soft_interrupts soft_interrupts() {
? Math.floor(stats.soft_interrupts / stats.time_since_update) const { stats } = this;
: null; return stats.soft_interrupts
}, ? Math.floor(stats.soft_interrupts / stats.time_since_update)
syscalls() { : null;
const { stats } = this; },
return stats.syscalls ? Math.floor(stats.syscalls / stats.time_since_update) : null; syscalls() {
} const { stats } = this;
}, return stats.syscalls
methods: { ? Math.floor(stats.syscalls / stats.time_since_update)
getDecoration(value) { : null;
if (this.view[value] === undefined) { },
return; },
} methods: {
return this.view[value].decoration.toLowerCase(); getDecoration(value) {
} if (this.view[value] === undefined) {
} return;
}
return this.view[value].decoration.toLowerCase();
},
},
}; };
</script> </script>

View File

@ -46,71 +46,78 @@
</template> </template>
<script> <script>
import { orderBy } from 'lodash'; import { orderBy } from "lodash";
import { store } from '../store.js'; import { bytes } from "../filters.js";
import { bytes } from '../filters.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
stats() { stats() {
return this.data.stats['diskio']; return this.data.stats["diskio"];
}, },
view() { view() {
return this.data.views['diskio']; return this.data.views["diskio"];
}, },
disks() { disks() {
const disks = this.stats.map((diskioData) => { const disks = this.stats
return { .map((diskioData) => {
name: diskioData['disk_name'], return {
alias: diskioData['alias'] !== undefined ? diskioData['alias'] : null, name: diskioData["disk_name"],
bitrate: { alias:
txps: bytes(diskioData['read_bytes_rate_per_sec']), diskioData["alias"] !== undefined ? diskioData["alias"] : null,
rxps: bytes(diskioData['write_bytes_rate_per_sec']) bitrate: {
}, txps: bytes(diskioData["read_bytes_rate_per_sec"]),
count: { rxps: bytes(diskioData["write_bytes_rate_per_sec"]),
txps: bytes(diskioData['read_count_rate_per_sec']), },
rxps: bytes(diskioData['write_count_rate_per_sec']) count: {
}, txps: bytes(diskioData["read_count_rate_per_sec"]),
latency: { rxps: bytes(diskioData["write_count_rate_per_sec"]),
txps: bytes(diskioData['read_latency']), },
rxps: bytes(diskioData['write_latency']) latency: {
} txps: bytes(diskioData["read_latency"]),
}; rxps: bytes(diskioData["write_latency"]),
}).filter(disk => { },
const readBytesRate = this.view[disk.name]['read_bytes_rate_per_sec']; };
const writeBytesRate = this.view[disk.name]['write_bytes_rate_per_sec']; })
return (!readBytesRate || readBytesRate.hidden === false) && (!writeBytesRate || writeBytesRate.hidden === false); .filter((disk) => {
}); const readBytesRate = this.view[disk.name]["read_bytes_rate_per_sec"];
return orderBy(disks, ['name']); const writeBytesRate =
}, this.view[disk.name]["write_bytes_rate_per_sec"];
hasDisks() { return (
return this.disks.length > 0; (!readBytesRate || readBytesRate.hidden === false) &&
} (!writeBytesRate || writeBytesRate.hidden === false)
}, );
methods: { });
getDecoration(diskName, field) { return orderBy(disks, ["name"]);
if (this.view[diskName][field] == undefined) { },
if (this.view[field] == undefined) { hasDisks() {
return; return this.disks.length > 0;
} else { },
return this.view[field].decoration.toLowerCase(); },
} methods: {
} getDecoration(diskName, field) {
return this.view[diskName][field].decoration.toLowerCase(); if (this.view[diskName][field] == undefined) {
} if (this.view[field] == undefined) {
} return;
} else {
return this.view[field].decoration.toLowerCase();
}
}
return this.view[diskName][field].decoration.toLowerCase();
},
},
}; };
</script> </script>

View File

@ -24,45 +24,51 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['folders']; return this.data.stats["folders"];
}, },
folders() { folders() {
return this.stats.map((folderData) => { return this.stats.map((folderData) => {
return { return {
path: folderData['path'], path: folderData["path"],
size: folderData['size'], size: folderData["size"],
errno: folderData['errno'], errno: folderData["errno"],
careful: folderData['careful'], careful: folderData["careful"],
warning: folderData['warning'], warning: folderData["warning"],
critical: folderData['critical'] critical: folderData["critical"],
}; };
}); });
}, },
hasFolders() { hasFolders() {
return this.folders.length > 0; return this.folders.length > 0;
} },
}, },
methods: { methods: {
getDecoration(folder) { getDecoration(folder) {
if (folder.errno > 0) { if (folder.errno > 0) {
return 'error'; return "error";
} }
if (folder.critical !== null && folder.size > folder.critical * 1000000) { if (folder.critical !== null && folder.size > folder.critical * 1000000) {
return 'critical'; return "critical";
} else if (folder.warning !== null && folder.size > folder.warning * 1000000) { } else if (
return 'warning'; folder.warning !== null &&
} else if (folder.careful !== null && folder.size > folder.careful * 1000000) { folder.size > folder.warning * 1000000
return 'careful'; ) {
} return "warning";
return 'ok'; } else if (
} folder.careful !== null &&
} folder.size > folder.careful * 1000000
) {
return "careful";
}
return "ok";
},
},
}; };
</script> </script>

View File

@ -43,55 +43,55 @@ v-if="(fs.alias ? fs.alias : fs.mountPoint).length + fs.name.length <= 15"
</template> </template>
<script> <script>
import { orderBy } from 'lodash'; import { orderBy } from "lodash";
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
stats() { stats() {
return this.data.stats['fs']; return this.data.stats["fs"];
}, },
view() { view() {
return this.data.views['fs']; return this.data.views["fs"];
}, },
fileSystems() { fileSystems() {
const fileSystems = this.stats.map((fsData) => { const fileSystems = this.stats.map((fsData) => {
return { return {
name: fsData['device_name'], name: fsData["device_name"],
mountPoint: fsData['mnt_point'], mountPoint: fsData["mnt_point"],
percent: fsData['percent'], percent: fsData["percent"],
size: fsData['size'], size: fsData["size"],
used: fsData['used'], used: fsData["used"],
free: fsData['free'], free: fsData["free"],
alias: fsData['alias'] !== undefined ? fsData['alias'] : null alias: fsData["alias"] !== undefined ? fsData["alias"] : null,
}; };
}); });
return orderBy(fileSystems, ['mnt_point']); return orderBy(fileSystems, ["mnt_point"]);
}, },
hasFs() { hasFs() {
return this.fileSystems.length > 0; return this.fileSystems.length > 0;
} },
}, },
methods: { methods: {
getDecoration(mountPoint, field) { getDecoration(mountPoint, field) {
if (this.view[mountPoint][field] == undefined) { if (this.view[mountPoint][field] == undefined) {
return; return;
} }
return this.view[mountPoint][field].decoration.toLowerCase(); return this.view[mountPoint][field].decoration.toLowerCase();
} },
} },
}; };
</script> </script>

View File

@ -91,74 +91,74 @@ v-if="gpu.temperature != null" class="col text-end"
</template> </template>
<script> <script>
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
stats() { stats() {
return this.data.stats['gpu']; return this.data.stats["gpu"];
}, },
view() { view() {
return this.data.views['gpu']; return this.data.views["gpu"];
}, },
gpus() { gpus() {
return this.stats; return this.stats;
}, },
name() { name() {
let name = 'GPU'; let name = "GPU";
const sameName = true; const sameName = true;
const { stats } = this; const { stats } = this;
if (stats.length === 1) { if (stats.length === 1) {
name = stats[0].name; name = stats[0].name;
} else if (stats.length && sameName) { } else if (stats.length && sameName) {
name = `${stats.length} GPU ${stats[0].name}`; name = `${stats.length} GPU ${stats[0].name}`;
} }
return name; return name;
}, },
mean() { mean() {
const mean = { const mean = {
proc: null, proc: null,
mem: null, mem: null,
temperature: null temperature: null,
}; };
const { stats } = this; const { stats } = this;
if (!stats.length) { if (!stats.length) {
return mean; return mean;
} }
for (const gpu of stats) { for (const gpu of stats) {
mean.proc += gpu.proc; mean.proc += gpu.proc;
mean.mem += gpu.mem; mean.mem += gpu.mem;
mean.temperature += gpu.temperature; mean.temperature += gpu.temperature;
} }
mean.proc = mean.proc / stats.length; mean.proc = mean.proc / stats.length;
mean.mem = mean.mem / stats.length; mean.mem = mean.mem / stats.length;
mean.temperature = mean.temperature / stats.length; mean.temperature = mean.temperature / stats.length;
return mean; return mean;
} },
}, },
methods: { methods: {
getDecoration(gpuId, value) { getDecoration(gpuId, value) {
if (this.view[gpuId][value] === undefined) { if (this.view[gpuId][value] === undefined) {
return; return;
} }
return this.view[gpuId][value].decoration.toLowerCase(); return this.view[gpuId][value].decoration.toLowerCase();
}, },
getMeanDecoration(value) { getMeanDecoration(value) {
return 'DEFAULT'; return "DEFAULT";
} },
} },
}; };
</script> </script>

View File

@ -6,29 +6,29 @@
</template> </template>
<script> <script>
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['system']; return this.data.stats["system"];
}, },
hostname() { hostname() {
return this.stats['hostname']; return this.stats["hostname"];
}, },
isDisconnected() { isDisconnected() {
return this.store.status === 'FAILURE'; return this.store.status === "FAILURE";
} },
} },
}; };
</script> </script>

View File

@ -10,30 +10,30 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
ipStats() { ipStats() {
return this.data.stats['ip']; return this.data.stats["ip"];
}, },
address() { address() {
return this.ipStats.address; return this.ipStats.address;
}, },
gateway() { gateway() {
return this.ipStats.gateway; return this.ipStats.gateway;
}, },
maskCdir() { maskCdir() {
return this.ipStats.mask_cidr; return this.ipStats.mask_cidr;
}, },
publicAddress() { publicAddress() {
return this.ipStats.public_address; return this.ipStats.public_address;
}, },
publicInfo() { publicInfo() {
return this.ipStats.public_info_human; return this.ipStats.public_info_human;
} },
} },
}; };
</script> </script>

View File

@ -19,23 +19,23 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['irq']; return this.data.stats["irq"];
}, },
irqs() { irqs() {
return this.stats.map((IrqData) => { return this.stats.map((IrqData) => {
return { return {
irq_line: IrqData['irq_line'], irq_line: IrqData["irq_line"],
irq_rate: IrqData['irq_rate'] irq_rate: IrqData["irq_rate"],
}; };
}); });
} },
} },
}; };
</script> </script>

View File

@ -31,38 +31,38 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['load']; return this.data.stats["load"];
}, },
view() { view() {
return this.data.views['load']; return this.data.views["load"];
}, },
cpucore() { cpucore() {
return this.stats['cpucore']; return this.stats["cpucore"];
}, },
min1() { min1() {
return this.stats['min1']; return this.stats["min1"];
}, },
min5() { min5() {
return this.stats['min5']; return this.stats["min5"];
}, },
min15() { min15() {
return this.stats['min15']; return this.stats["min15"];
} },
}, },
methods: { methods: {
getDecoration(value) { getDecoration(value) {
if (this.view[value] === undefined) { if (this.view[value] === undefined) {
return; return;
} }
return this.view[value].decoration.toLowerCase(); return this.view[value].decoration.toLowerCase();
} },
} },
}; };
</script> </script>

View File

@ -83,69 +83,71 @@
</template> </template>
<script> <script>
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
config() { config() {
return this.store.config || {}; return this.store.config || {};
}, },
available_args() { available_args() {
return this.config !== undefined && this.config.mem !== undefined && this.config.available !== undefined return this.config !== undefined &&
? this.config.mem.available || false this.config.mem !== undefined &&
: false this.config.available !== undefined
}, ? this.config.mem.available || false
stats() { : false;
return this.data.stats['mem']; },
}, stats() {
view() { return this.data.stats["mem"];
return this.data.views['mem']; },
}, view() {
percent() { return this.data.views["mem"];
return this.stats['percent'].toFixed(1); },
}, percent() {
total() { return this.stats["percent"].toFixed(1);
return this.stats['total']; },
}, total() {
used() { return this.stats["total"];
return this.stats['used']; },
}, used() {
available() { return this.stats["used"];
return this.stats['available']; },
}, available() {
free() { return this.stats["available"];
return this.stats['free']; },
}, free() {
active() { return this.stats["free"];
return this.stats['active']; },
}, active() {
inactive() { return this.stats["active"];
return this.stats['inactive']; },
}, inactive() {
buffers() { return this.stats["inactive"];
return this.stats['buffers']; },
}, buffers() {
cached() { return this.stats["buffers"];
return this.stats['cached']; },
} cached() {
}, return this.stats["cached"];
methods: { },
getDecoration(value) { },
if (this.view[value] === undefined) { methods: {
return; getDecoration(value) {
} if (this.view[value] === undefined) {
return this.view[value].decoration.toLowerCase(); return;
} }
} return this.view[value].decoration.toLowerCase();
},
},
}; };
</script> </script>

View File

@ -31,38 +31,38 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['memswap']; return this.data.stats["memswap"];
}, },
view() { view() {
return this.data.views['memswap']; return this.data.views["memswap"];
}, },
percent() { percent() {
return this.stats['percent']; return this.stats["percent"];
}, },
total() { total() {
return this.stats['total']; return this.stats["total"];
}, },
used() { used() {
return this.stats['used']; return this.stats["used"];
}, },
free() { free() {
return this.stats['free']; return this.stats["free"];
} },
}, },
methods: { methods: {
getDecoration(value) { getDecoration(value) {
if (this.view[value] === undefined) { if (this.view[value] === undefined) {
return; return;
} }
return this.view[value].decoration.toLowerCase(); return this.view[value].decoration.toLowerCase();
} },
} },
}; };
</script> </script>

View File

@ -53,65 +53,73 @@ v-show="!args.network_cumul && !args.network_sum" class="text-end"
</template> </template>
<script> <script>
import { orderBy } from 'lodash'; import { orderBy } from "lodash";
import { store } from '../store.js'; import { bytes } from "../filters.js";
import { bytes } from '../filters.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
stats() { stats() {
return this.data.stats['network']; return this.data.stats["network"];
}, },
view() { view() {
return this.data.views['network']; return this.data.views["network"];
}, },
networks() { networks() {
const networks = this.stats.map((networkData) => { const networks = this.stats
const alias = networkData['alias'] !== undefined ? networkData['alias'] : null; .map((networkData) => {
const alias =
networkData["alias"] !== undefined ? networkData["alias"] : null;
const network = { const network = {
interfaceName: networkData['interface_name'], interfaceName: networkData["interface_name"],
ifname: alias ? alias : networkData['interface_name'], ifname: alias ? alias : networkData["interface_name"],
bytes_recv_rate_per_sec: networkData['bytes_recv_rate_per_sec'], bytes_recv_rate_per_sec: networkData["bytes_recv_rate_per_sec"],
bytes_sent_rate_per_sec: networkData['bytes_sent_rate_per_sec'], bytes_sent_rate_per_sec: networkData["bytes_sent_rate_per_sec"],
bytes_all_rate_per_sec: networkData['bytes_all_rate_per_sec'], bytes_all_rate_per_sec: networkData["bytes_all_rate_per_sec"],
bytes_recv: networkData['bytes_recv'], bytes_recv: networkData["bytes_recv"],
bytes_sent: networkData['bytes_sent'], bytes_sent: networkData["bytes_sent"],
bytes_all: networkData['bytes_all'] bytes_all: networkData["bytes_all"],
}; };
return network; return network;
}).filter(network => { })
const bytesRecvRate = this.view[network.interfaceName]['bytes_recv_rate_per_sec']; .filter((network) => {
const bytesSentRate = this.view[network.interfaceName]['bytes_sent_rate_per_sec']; const bytesRecvRate =
return (!bytesRecvRate || bytesRecvRate.hidden === false) && (!bytesSentRate || bytesSentRate.hidden === false); this.view[network.interfaceName]["bytes_recv_rate_per_sec"];
}); const bytesSentRate =
return orderBy(networks, ['interfaceName']); this.view[network.interfaceName]["bytes_sent_rate_per_sec"];
}, return (
hasNetworks() { (!bytesRecvRate || bytesRecvRate.hidden === false) &&
return this.networks.length > 0; (!bytesSentRate || bytesSentRate.hidden === false)
} );
}, });
methods: { return orderBy(networks, ["interfaceName"]);
getDecoration(interfaceName, field) { },
if (this.view[interfaceName][field] == undefined) { hasNetworks() {
return; return this.networks.length > 0;
} },
return this.view[interfaceName][field].decoration.toLowerCase(); },
} methods: {
} getDecoration(interfaceName, field) {
if (this.view[interfaceName][field] == undefined) {
return;
}
return this.view[interfaceName][field].decoration.toLowerCase();
},
},
}; };
</script> </script>

View File

@ -6,15 +6,15 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
date_custom() { date_custom() {
return this.data.stats['now']['custom']; return this.data.stats["now"]["custom"];
} },
} },
}; };
</script> </script>

View File

@ -32,42 +32,42 @@
</template> </template>
<script> <script>
import { store } from '../store.js'; import { chunk } from "lodash";
import { GlancesHelper } from '../services.js'; import { GlancesHelper } from "../services.js";
import { chunk } from 'lodash'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
config() { config() {
return this.store.config || {}; return this.store.config || {};
}, },
percpuStats() { percpuStats() {
return this.data.stats['percpu']; return this.data.stats["percpu"];
} },
}, },
methods: { methods: {
getUserAlert(cpu) { getUserAlert(cpu) {
return GlancesHelper.getAlert('percpu', 'percpu_user_', cpu.user); return GlancesHelper.getAlert("percpu", "percpu_user_", cpu.user);
}, },
getSystemAlert(cpu) { getSystemAlert(cpu) {
return GlancesHelper.getAlert('percpu', 'percpu_system_', cpu.system); return GlancesHelper.getAlert("percpu", "percpu_system_", cpu.system);
}, },
getIOWaitAlert(cpu) { getIOWaitAlert(cpu) {
return GlancesHelper.getAlert('percpu', 'percpu_iowait_', cpu.system); return GlancesHelper.getAlert("percpu", "percpu_iowait_", cpu.system);
} },
} },
}; };
</script> </script>

View File

@ -30,46 +30,46 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['ports']; return this.data.stats["ports"];
}, },
ports() { ports() {
return this.stats; return this.stats;
}, },
hasPorts() { hasPorts() {
return this.ports.length > 0; return this.ports.length > 0;
} },
}, },
methods: { methods: {
getPortDecoration(port) { getPortDecoration(port) {
if (port.status === null) { if (port.status === null) {
return 'careful'; return "careful";
} else if (port.status === false) { } else if (port.status === false) {
return 'critical'; return "critical";
} else if (port.rtt_warning !== null && port.status > port.rtt_warning) { } else if (port.rtt_warning !== null && port.status > port.rtt_warning) {
return 'warning'; return "warning";
} }
return 'ok'; return "ok";
}, },
getWebDecoration(web) { getWebDecoration(web) {
const okCodes = [200, 301, 302]; const okCodes = [200, 301, 302];
if (web.status === null) { if (web.status === null) {
return 'careful'; return "careful";
} else if (okCodes.indexOf(web.status) === -1) { } else if (okCodes.indexOf(web.status) === -1) {
return 'critical'; return "critical";
} else if (web.rtt_warning !== null && web.elapsed > web.rtt_warning) { } else if (web.rtt_warning !== null && web.elapsed > web.rtt_warning) {
return 'warning'; return "warning";
} }
return 'ok'; return "ok";
} },
} },
}; };
</script> </script>

View File

@ -16,75 +16,75 @@
</template> </template>
<script> <script>
import { store } from '../store.js'; import { store } from "../store.js";
import GlancesPluginAmps from './plugin-amps.vue'; import GlancesPluginAmps from "./plugin-amps.vue";
import GlancesPluginProcesscount from './plugin-processcount.vue'; import GlancesPluginProcesscount from "./plugin-processcount.vue";
import GlancesPluginProcesslist from './plugin-processlist.vue'; import GlancesPluginProcesslist from "./plugin-processlist.vue";
export default { export default {
components: { components: {
GlancesPluginAmps, GlancesPluginAmps,
GlancesPluginProcesscount, GlancesPluginProcesscount,
GlancesPluginProcesslist GlancesPluginProcesslist,
}, },
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store, store,
sorter: undefined sorter: undefined,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
sortProcessesKey() { sortProcessesKey() {
return this.args.sort_processes_key; return this.args.sort_processes_key;
} },
}, },
watch: { watch: {
sortProcessesKey: { sortProcessesKey: {
immediate: true, immediate: true,
handler(sortProcessesKey) { handler(sortProcessesKey) {
const sortable = [ const sortable = [
'cpu_percent', "cpu_percent",
'memory_percent', "memory_percent",
'username', "username",
'timemillis', "timemillis",
'num_threads', "num_threads",
'io_counters', "io_counters",
'name' "name",
]; ];
function isReverseColumn(column) { function isReverseColumn(column) {
return !['username', 'name'].includes(column); return !["username", "name"].includes(column);
} }
function getColumnLabel(value) { function getColumnLabel(value) {
const labels = { const labels = {
cpu_percent: 'CPU consumption', cpu_percent: "CPU consumption",
memory_percent: 'memory consumption', memory_percent: "memory consumption",
username: 'user name', username: "user name",
timemillis: 'process time', timemillis: "process time",
cpu_times: 'process time', cpu_times: "process time",
io_counters: 'disk IO', io_counters: "disk IO",
name: 'process name', name: "process name",
None: 'None' None: "None",
}; };
return labels[value] || value; return labels[value] || value;
} }
if (!sortProcessesKey || sortable.includes(sortProcessesKey)) { if (!sortProcessesKey || sortable.includes(sortProcessesKey)) {
this.sorter = { this.sorter = {
column: this.args.sort_processes_key || 'cpu_percent', column: this.args.sort_processes_key || "cpu_percent",
auto: !this.args.sort_processes_key, auto: !this.args.sort_processes_key,
isReverseColumn, isReverseColumn,
getColumnLabel getColumnLabel,
}; };
} }
} },
} },
} },
}; };
</script> </script>

View File

@ -12,44 +12,44 @@
</template> </template>
<script> <script>
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
}, },
sorter: { sorter: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
stats() { stats() {
return this.data.stats['processcount']; return this.data.stats["processcount"];
}, },
total() { total() {
return this.stats['total'] || 0; return this.stats["total"] || 0;
}, },
running() { running() {
return this.stats['running'] || 0; return this.stats["running"] || 0;
}, },
sleeping() { sleeping() {
return this.stats['sleeping'] || 0; return this.stats["sleeping"] || 0;
}, },
stopped() { stopped() {
return this.stats['stopped'] || 0; return this.stats["stopped"] || 0;
}, },
thread() { thread() {
return this.stats['thread'] || 0; return this.stats["thread"] || 0;
} },
} },
}; };
</script> </script>

View File

@ -380,246 +380,304 @@
</template> </template>
<script> <script>
import { orderBy, last } from 'lodash'; import { last, orderBy } from "lodash";
import { timemillis, timedelta, limitTo, number, dictToString } from '../filters.js'; import {
import { GlancesHelper } from '../services.js'; dictToString,
import { store } from '../store.js'; limitTo,
number,
timedelta,
timemillis,
} from "../filters.js";
import { GlancesHelper } from "../services.js";
import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
}, },
sorter: { sorter: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
config() { config() {
return this.store.config || {}; return this.store.config || {};
}, },
stats_processlist() { stats_processlist() {
return this.data.stats['processlist']; return this.data.stats["processlist"];
}, },
stats_core() { stats_core() {
return this.data.stats['core']; return this.data.stats["core"];
}, },
cpucore() { cpucore() {
return (this.stats_core['log'] !== 0) ? this.stats_core['log'] : 1; return this.stats_core["log"] !== 0 ? this.stats_core["log"] : 1;
}, },
extended_stats() { extended_stats() {
return this.stats_processlist.find(item => item['extended_stats'] === true) || null; return (
}, this.stats_processlist.find(
processes() { (item) => item["extended_stats"] === true,
const { sorter } = this; ) || null
const processes = (this.stats_processlist || []).map((process) => { );
return this.updateProcess(process, this.data.stats['isWindows'], this.args, this.cpucore); },
}); processes() {
const { sorter } = this;
const processes = (this.stats_processlist || []).map((process) => {
return this.updateProcess(
process,
this.data.stats["isWindows"],
this.args,
this.cpucore,
);
});
return orderBy( return orderBy(
processes, processes,
[sorter.column].reduce((retval, col) => { [sorter.column].reduce((retval, col) => {
if (col === 'io_counters') { if (col === "io_counters") {
col = ['io_read', 'io_write'] col = ["io_read", "io_write"];
} }
return retval.concat(col); return retval.concat(col);
}, []), }, []),
[sorter.isReverseColumn(sorter.column) ? 'desc' : 'asc'] [sorter.isReverseColumn(sorter.column) ? "desc" : "asc"],
).slice(0, this.limit); ).slice(0, this.limit);
}, },
ioReadWritePresentProcesses() { ioReadWritePresentProcesses() {
return (this.stats_processlist || []).some(({ io_counters }) => io_counters); return (this.stats_processlist || []).some(
}, ({ io_counters }) => io_counters,
stats_programlist() { );
return this.data.stats['programlist']; },
}, stats_programlist() {
programs() { return this.data.stats["programlist"];
const { sorter } = this; },
const isWindows = this.data.stats['isWindows']; programs() {
const programs = (this.stats_programlist || []).map((process) => { const { sorter } = this;
process.memvirt = '?'; const isWindows = this.data.stats["isWindows"];
process.memres = '?'; const programs = (this.stats_programlist || []).map((process) => {
if (process.memory_info) { process.memvirt = "?";
process.memvirt = process.memory_info.vms; process.memres = "?";
process.memres = process.memory_info.rss; if (process.memory_info) {
} process.memvirt = process.memory_info.vms;
process.memres = process.memory_info.rss;
}
if (isWindows && process.username !== null) { if (isWindows && process.username !== null) {
process.username = last(process.username.split('\\')); process.username = last(process.username.split("\\"));
} }
process.timeforhuman = '?'; process.timeforhuman = "?";
if (process.cpu_times) { if (process.cpu_times) {
process.timeplus = timedelta([process.cpu_times['user'], process.cpu_times['system']]); process.timeplus = timedelta([
process.timeforhuman = process.timeplus.hours.toString().padStart(2, '0') + ':' + process.cpu_times["user"],
process.timeplus.minutes.toString().padStart(2, '0') + ':' + process.cpu_times["system"],
process.timeplus.seconds.toString().padStart(2, '0') ]);
} process.timeforhuman =
process.timeplus.hours.toString().padStart(2, "0") +
":" +
process.timeplus.minutes.toString().padStart(2, "0") +
":" +
process.timeplus.seconds.toString().padStart(2, "0");
}
if (process.num_threads === null) { if (process.num_threads === null) {
process.num_threads = -1; process.num_threads = -1;
} }
if (process.cpu_percent === null) { if (process.cpu_percent === null) {
process.cpu_percent = -1; process.cpu_percent = -1;
} }
if (process.memory_percent === null) { if (process.memory_percent === null) {
process.memory_percent = -1; process.memory_percent = -1;
} }
process.io_read = null; process.io_read = null;
process.io_write = null; process.io_write = null;
if (process.io_counters) { if (process.io_counters) {
process.io_read = process.io_read =
(process.io_counters[0] - process.io_counters[2]) / (process.io_counters[0] - process.io_counters[2]) /
process.time_since_update; process.time_since_update;
process.io_write = process.io_write =
(process.io_counters[1] - process.io_counters[3]) / (process.io_counters[1] - process.io_counters[3]) /
process.time_since_update; process.time_since_update;
} }
process.isNice = process.isNice =
process.nice !== undefined && process.nice !== undefined &&
((isWindows && process.nice != 32) || (!isWindows && process.nice != 0)); ((isWindows && process.nice != 32) ||
(!isWindows && process.nice != 0));
if (Array.isArray(process.cmdline)) { if (Array.isArray(process.cmdline)) {
process.cmdline = process.cmdline.join(' ').replace(/\n/g, ' '); process.cmdline = process.cmdline.join(" ").replace(/\n/g, " ");
} }
if (typeof process.cmdline !== "string" || process.cmdline.length === 0) { if (
process.cmdline = process.name; typeof process.cmdline !== "string" ||
} process.cmdline.length === 0
) {
process.cmdline = process.name;
}
return process; return process;
}); });
return orderBy( return orderBy(
programs, programs,
[sorter.column].reduce((retval, col) => { [sorter.column].reduce((retval, col) => {
if (col === 'io_counters') { if (col === "io_counters") {
col = ['io_read', 'io_write'] col = ["io_read", "io_write"];
} }
return retval.concat(col); return retval.concat(col);
}, []), }, []),
[sorter.isReverseColumn(sorter.column) ? 'desc' : 'asc'] [sorter.isReverseColumn(sorter.column) ? "desc" : "asc"],
).slice(0, this.limit); ).slice(0, this.limit);
}, },
ioReadWritePresentPrograms() { ioReadWritePresentPrograms() {
return (this.stats_programlist || []).some(({ io_counters }) => io_counters); return (this.stats_programlist || []).some(
}, ({ io_counters }) => io_counters,
limit() { );
return this.config.outputs !== undefined },
? this.config.outputs.max_processes_display limit() {
: undefined; return this.config.outputs !== undefined
}, ? this.config.outputs.max_processes_display
focus() { : undefined;
return this.args !== undefined && this.args.process_focus !== undefined && this.args.process_focus !== null },
? this.args.process_focus.split(',') focus() {
: this.config.processlist !== undefined && this.config.processlist.focus !== undefined && this.config.processlist.focus !== null return this.args !== undefined &&
? this.config.processlist.focus.split(',') this.args.process_focus !== undefined &&
: []; this.args.process_focus !== null
}, ? this.args.process_focus.split(",")
is_focus() { : this.config.processlist !== undefined &&
return this.focus.length > 0; this.config.processlist.focus !== undefined &&
} this.config.processlist.focus !== null
}, ? this.config.processlist.focus.split(",")
methods: { : [];
updateProcess(process, isWindows, args, cpucore) { },
process.memvirt = '?'; is_focus() {
process.memres = '?'; return this.focus.length > 0;
if (process.memory_info) { },
process.memvirt = process.memory_info.vms; },
process.memres = process.memory_info.rss; methods: {
} updateProcess(process, isWindows, args, cpucore) {
process.memvirt = "?";
process.memres = "?";
if (process.memory_info) {
process.memvirt = process.memory_info.vms;
process.memres = process.memory_info.rss;
}
if (isWindows && process.username !== null) { if (isWindows && process.username !== null) {
process.username = last(process.username.split('\\')); process.username = last(process.username.split("\\"));
} }
process.timeforhuman = '?'; process.timeforhuman = "?";
if (process.cpu_times) { if (process.cpu_times) {
process.timeplus = timedelta([process.cpu_times['user'], process.cpu_times['system']]); process.timeplus = timedelta([
process.timeforhuman = process.timeplus.hours.toString().padStart(2, '0') + ':' + process.cpu_times["user"],
process.timeplus.minutes.toString().padStart(2, '0') + ':' + process.cpu_times["system"],
process.timeplus.seconds.toString().padStart(2, '0') ]);
} process.timeforhuman =
process.timeplus.hours.toString().padStart(2, "0") +
":" +
process.timeplus.minutes.toString().padStart(2, "0") +
":" +
process.timeplus.seconds.toString().padStart(2, "0");
}
if (process.num_threads === null) { if (process.num_threads === null) {
process.num_threads = -1; process.num_threads = -1;
} }
process.irix = 1; process.irix = 1;
if (process.cpu_percent === null) { if (process.cpu_percent === null) {
process.cpu_percent = -1; process.cpu_percent = -1;
} else { } else {
if (args.disable_irix) { if (args.disable_irix) {
process.irix = cpucore process.irix = cpucore;
} }
} }
if (process.memory_percent === null) { if (process.memory_percent === null) {
process.memory_percent = -1; process.memory_percent = -1;
} }
process.io_read = null; process.io_read = null;
process.io_write = null; process.io_write = null;
if (process.io_counters) { if (process.io_counters) {
process.io_read = process.io_read =
(process.io_counters[0] - process.io_counters[2]) / (process.io_counters[0] - process.io_counters[2]) /
process.time_since_update; process.time_since_update;
process.io_write = process.io_write =
(process.io_counters[1] - process.io_counters[3]) / (process.io_counters[1] - process.io_counters[3]) /
process.time_since_update; process.time_since_update;
} }
process.isNice = process.isNice =
process.nice !== undefined && process.nice !== undefined &&
((isWindows && process.nice != 32) || (!isWindows && process.nice != 0)); ((isWindows && process.nice != 32) ||
(!isWindows && process.nice != 0));
if (Array.isArray(process.cmdline)) { if (Array.isArray(process.cmdline)) {
process.name = process.name + ' ' + process.cmdline.slice(1).join(' ').replace(/\n/g, ' '); process.name =
process.cmdline = process.cmdline.join(' ').replace(/\n/g, ' '); process.name +
} " " +
process.cmdline.slice(1).join(" ").replace(/\n/g, " ");
process.cmdline = process.cmdline.join(" ").replace(/\n/g, " ");
}
if (typeof process.cmdline !== "string" || process.cmdline.length === 0) { if (typeof process.cmdline !== "string" || process.cmdline.length === 0) {
process.cmdline = process.name; process.cmdline = process.name;
} }
return process return process;
}, },
getCpuPercentAlert(process) { getCpuPercentAlert(process) {
return GlancesHelper.getAlert('processlist', 'processlist_cpu_', process.cpu_percent); return GlancesHelper.getAlert(
}, "processlist",
getMemoryPercentAlert(process) { "processlist_cpu_",
return GlancesHelper.getAlert('processlist', 'processlist_mem_', process.cpu_percent); process.cpu_percent,
}, );
getDisableStats() { },
return GlancesHelper.getLimit('processlist', 'processlist_disable_stats') || []; getMemoryPercentAlert(process) {
}, return GlancesHelper.getAlert(
getDisableVms() { "processlist",
const ret = GlancesHelper.getLimit('processlist', 'processlist_disable_virtual_memory') || ['False']; "processlist_mem_",
return (ret[0].toLowerCase() === 'true') ? true : false; process.cpu_percent,
}, );
setExtendedStats(pid) { },
fetch('api/4/processes/extended/' + pid.toString(), { method: 'POST' }) getDisableStats() {
.then((response) => response.json()); return (
this.$forceUpdate() GlancesHelper.getLimit("processlist", "processlist_disable_stats") || []
}, );
disableExtendedStats() { },
fetch('api/4/processes/extended/disable', { method: 'POST' }) getDisableVms() {
.then((response) => response.json()); const ret = GlancesHelper.getLimit(
this.$forceUpdate() "processlist",
} "processlist_disable_virtual_memory",
} ) || ["False"];
return ret[0].toLowerCase() === "true" ? true : false;
},
setExtendedStats(pid) {
fetch("api/4/processes/extended/" + pid.toString(), {
method: "POST",
}).then((response) => response.json());
this.$forceUpdate();
},
disableExtendedStats() {
fetch("api/4/processes/extended/disable", { method: "POST" }).then(
(response) => response.json(),
);
this.$forceUpdate();
},
},
}; };
</script> </script>

View File

@ -51,73 +51,82 @@
</template> </template>
<script> <script>
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
config() { config() {
return this.store.config || {}; return this.store.config || {};
}, },
stats() { stats() {
return this.data.stats['quicklook']; return this.data.stats["quicklook"];
}, },
view() { view() {
return this.data.views['quicklook']; return this.data.views["quicklook"];
}, },
cpu() { cpu() {
return this.stats.cpu; return this.stats.cpu;
}, },
cpu_name() { cpu_name() {
return this.stats.cpu_name; return this.stats.cpu_name;
}, },
cpu_hz_current() { cpu_hz_current() {
return (this.stats.cpu_hz_current / 1000000).toFixed(0); return (this.stats.cpu_hz_current / 1000000).toFixed(0);
}, },
cpu_hz() { cpu_hz() {
return (this.stats.cpu_hz / 1000000).toFixed(0); return (this.stats.cpu_hz / 1000000).toFixed(0);
}, },
percpus() { percpus() {
const cpu_list = this.stats.percpu.map(({ cpu_number: number, total }) => ({ number, total })) const cpu_list = this.stats.percpu.map(
const max_cpu_display = parseInt(this.config.percpu.max_cpu_display) ({ cpu_number: number, total }) => ({ number, total }),
if (this.stats.percpu.length > max_cpu_display) { );
var cpu_list_sorted = cpu_list.sort(function (a, b) { return b.total - a.total; }) const max_cpu_display = parseInt(this.config.percpu.max_cpu_display);
const other_cpu = { if (this.stats.percpu.length > max_cpu_display) {
number: "x", var cpu_list_sorted = cpu_list.sort((a, b) => b.total - a.total);
total: Number((cpu_list_sorted.slice(max_cpu_display).reduce((n, { total }) => n + total, 0) / (this.stats.percpu.length - max_cpu_display)).toFixed(1)) const other_cpu = {
} number: "x",
// Add the top n this total: Number(
// and the mean of others CPU (
cpu_list_sorted = cpu_list_sorted.slice(0, max_cpu_display) cpu_list_sorted
cpu_list_sorted.push(other_cpu) .slice(max_cpu_display)
} .reduce((n, { total }) => n + total, 0) /
return this.stats.percpu.length <= max_cpu_display (this.stats.percpu.length - max_cpu_display)
? cpu_list ).toFixed(1),
: cpu_list_sorted ),
}, };
stats_list_after_cpu() { // Add the top n this
return this.view.list.filter((key) => !key.includes('cpu')); // and the mean of others CPU
}, cpu_list_sorted = cpu_list_sorted.slice(0, max_cpu_display);
}, cpu_list_sorted.push(other_cpu);
methods: { }
getDecoration(value) { return this.stats.percpu.length <= max_cpu_display
if (this.view[value] === undefined) { ? cpu_list
return; : cpu_list_sorted;
} },
return this.view[value].decoration.toLowerCase(); stats_list_after_cpu() {
} return this.view.list.filter((key) => !key.includes("cpu"));
} },
},
methods: {
getDecoration(value) {
if (this.view[value] === undefined) {
return;
}
return this.view[value].decoration.toLowerCase();
},
},
}; };
</script> </script>

View File

@ -37,54 +37,57 @@
</template> </template>
<script> <script>
import { orderBy } from 'lodash'; import { orderBy } from "lodash";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['raid']; return this.data.stats["raid"];
}, },
disks() { disks() {
const disks = Object.entries(this.stats).map(([diskKey, diskData]) => { const disks = Object.entries(this.stats).map(([diskKey, diskData]) => {
const components = Object.entries(diskData.components).map(([name, number]) => { const components = Object.entries(diskData.components).map(
return { ([name, number]) => {
number: number, return {
name: name number: number,
}; name: name,
}); };
return { },
name: diskKey, );
type: diskData.type == null ? 'UNKNOWN' : diskData.type, return {
used: diskData.used, name: diskKey,
available: diskData.available, type: diskData.type == null ? "UNKNOWN" : diskData.type,
status: diskData.status, used: diskData.used,
degraded: diskData.used < diskData.available, available: diskData.available,
config: diskData.config == null ? '' : diskData.config.replace('_', 'A'), status: diskData.status,
inactive: diskData.status == 'inactive', degraded: diskData.used < diskData.available,
components: orderBy(components, ['number']) config:
}; diskData.config == null ? "" : diskData.config.replace("_", "A"),
}); inactive: diskData.status == "inactive",
return orderBy(disks, ['name']); components: orderBy(components, ["number"]),
}, };
hasDisks() { });
return this.disks.length > 0; return orderBy(disks, ["name"]);
} },
}, hasDisks() {
methods: { return this.disks.length > 0;
getAlert(disk) { },
if (disk.inactive) { },
return 'critical'; methods: {
} getAlert(disk) {
if (disk.degraded) { if (disk.inactive) {
return 'warning'; return "critical";
} }
return 'ok'; if (disk.degraded) {
} return "warning";
} }
return "ok";
},
},
}; };
</script> </script>

View File

@ -22,61 +22,63 @@
</template> </template>
<script> <script>
import { GlancesHelper } from '../services.js'; import { GlancesHelper } from "../services.js";
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
stats() { stats() {
return this.data.stats['sensors']; return this.data.stats["sensors"];
}, },
view() { view() {
return this.data.views['sensors']; return this.data.views["sensors"];
}, },
sensors() { sensors() {
return this.stats return (
// .filter((sensor) => { this.stats
// // prettier-ignore // .filter((sensor) => {
// const isEmpty = (Array.isArray(sensor.value) && sensor.value.length === 0) || sensor.value === 0; // // prettier-ignore
// return !isEmpty; // const isEmpty = (Array.isArray(sensor.value) && sensor.value.length === 0) || sensor.value === 0;
// }) // return !isEmpty;
.map((sensor) => { // })
if ( .map((sensor) => {
this.args.fahrenheit && if (
sensor.type != 'battery' && this.args.fahrenheit &&
sensor.type != 'fan_speed' sensor.type != "battery" &&
) { sensor.type != "fan_speed"
// prettier-ignore ) {
sensor.value = parseFloat(sensor.value * 1.8 + 32).toFixed(1); // prettier-ignore
sensor.unit = 'F'; sensor.value = parseFloat(sensor.value * 1.8 + 32).toFixed(1);
} sensor.unit = "F";
return sensor; }
}); return sensor;
}, })
hasSensors() { );
return this.sensors.length > 0; },
} hasSensors() {
}, return this.sensors.length > 0;
methods: { },
getDecoration(key) { },
if (this.view[key].value.decoration === undefined) { methods: {
return; getDecoration(key) {
} if (this.view[key].value.decoration === undefined) {
return this.view[key].value.decoration.toLowerCase(); return;
} }
} return this.view[key].value.decoration.toLowerCase();
},
},
}; };
</script> </script>

View File

@ -25,28 +25,30 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['smart']; return this.data.stats["smart"];
}, },
drives() { drives() {
return (Array.isArray(this.stats) ? this.stats : []).map((data) => { return (Array.isArray(this.stats) ? this.stats : []).map((data) => {
const name = data.DeviceName; const name = data.DeviceName;
const details = Object.entries(data) const details = Object.entries(data)
.filter(([key]) => key !== 'DeviceName') .filter(([key]) => key !== "DeviceName")
.sort(([, a], [, b]) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) .sort(([, a], [, b]) =>
.map(([prop, value]) => value); a.name < b.name ? -1 : a.name > b.name ? 1 : 0,
return { name, details }; )
}); .map(([prop, value]) => value);
}, return { name, details };
hasDrives() { });
return this.drives.length > 0; },
} hasDrives() {
} return this.drives.length > 0;
},
},
}; };
</script> </script>

View File

@ -7,32 +7,32 @@
</template> </template>
<script> <script>
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store store,
}; };
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['system']; return this.data.stats["system"];
}, },
hostname() { hostname() {
return this.stats['hostname']; return this.stats["hostname"];
}, },
humanReadableName() { humanReadableName() {
return this.stats['hr_name']; return this.stats["hr_name"];
}, },
isDisconnected() { isDisconnected() {
return this.store.status === 'FAILURE'; return this.store.status === "FAILURE";
} },
} },
}; };
</script> </script>

View File

@ -6,15 +6,15 @@
<script> <script>
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
value() { value() {
return this.data.stats['uptime']; return this.data.stats["uptime"];
} },
} },
}; };
</script> </script>

View File

@ -61,100 +61,103 @@
</template> </template>
<script> <script>
import { orderBy } from 'lodash'; import { orderBy } from "lodash";
import { store } from '../store.js'; import { store } from "../store.js";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
data() { data() {
return { return {
store, store,
sorter: undefined sorter: undefined,
}; };
}, },
computed: { computed: {
args() { args() {
return this.store.args || {}; return this.store.args || {};
}, },
sortProcessesKey() { sortProcessesKey() {
return this.args.sort_processes_key; return this.args.sort_processes_key;
}, },
stats() { stats() {
return this.data.stats['vms']; return this.data.stats["vms"];
}, },
views() { views() {
return this.data.views['vms']; return this.data.views["vms"];
}, },
vms() { vms() {
const { sorter } = this; const { sorter } = this;
const vms = (this.stats || []).map( const vms = (this.stats || []).map((vmData) => {
(vmData) => { return {
return { id: vmData.id,
'id': vmData.id, name: vmData.name,
'name': vmData.name, status: vmData.status != undefined ? vmData.status : "-",
'status': vmData.status != undefined ? vmData.status : '-', cpu_count: vmData.cpu_count != undefined ? vmData.cpu_count : "-",
'cpu_count': vmData.cpu_count != undefined ? vmData.cpu_count : '-', cpu_time: vmData.cpu_time != undefined ? vmData.cpu_time : "-",
'cpu_time': vmData.cpu_time != undefined ? vmData.cpu_time : '-', cpu_time_rate_per_sec:
'cpu_time_rate_per_sec': vmData.cpu_time_rate_per_sec != undefined ? vmData.cpu_time_rate_per_sec : '?', vmData.cpu_time_rate_per_sec != undefined
'memory_usage': vmData.memory_usage != undefined ? vmData.memory_usage : '-', ? vmData.cpu_time_rate_per_sec
'memory_total': vmData.memory_total != undefined ? vmData.memory_total : '-', : "?",
'load_1min': vmData.load_1min != undefined ? vmData.load_1min : '-', memory_usage:
'load_5min': vmData.load_5min != undefined ? vmData.load_5min : '-', vmData.memory_usage != undefined ? vmData.memory_usage : "-",
'load_15min': vmData.load_15min != undefined ? vmData.load_15min : '-', memory_total:
'release': vmData.release, vmData.memory_total != undefined ? vmData.memory_total : "-",
'image': vmData.image, load_1min: vmData.load_1min != undefined ? vmData.load_1min : "-",
'engine': vmData.engine, load_5min: vmData.load_5min != undefined ? vmData.load_5min : "-",
'engine_version': vmData.engine_version, load_15min: vmData.load_15min != undefined ? vmData.load_15min : "-",
}; release: vmData.release,
} image: vmData.image,
); engine: vmData.engine,
return orderBy( engine_version: vmData.engine_version,
vms, };
[sorter.column].reduce((retval, col) => { });
if (col === 'memory_usage') { return orderBy(
col = ['memory_usage']; vms,
} [sorter.column].reduce((retval, col) => {
return retval.concat(col); if (col === "memory_usage") {
}, []), col = ["memory_usage"];
[sorter.isReverseColumn(sorter.column) ? 'desc' : 'asc'] }
); return retval.concat(col);
}, }, []),
showEngine() { [sorter.isReverseColumn(sorter.column) ? "desc" : "asc"],
return this.views.show_engine_name; );
}, },
}, showEngine() {
watch: { return this.views.show_engine_name;
sortProcessesKey: { },
immediate: true, },
handler(sortProcessesKey) { watch: {
const sortable = ['load_1min', 'cpu_time', 'memory_usage', 'name']; sortProcessesKey: {
function isReverseColumn(column) { immediate: true,
return !['name'].includes(column); handler(sortProcessesKey) {
} const sortable = ["load_1min", "cpu_time", "memory_usage", "name"];
function getColumnLabel(value) { function isReverseColumn(column) {
const labels = { return !["name"].includes(column);
load_1min: 'load', }
cpu_time: 'CPU time', function getColumnLabel(value) {
memory_usage: 'memory consumption', const labels = {
name: 'VM name', load_1min: "load",
None: 'None' cpu_time: "CPU time",
}; memory_usage: "memory consumption",
return labels[value] || value; name: "VM name",
} None: "None",
if (!sortProcessesKey || sortable.includes(sortProcessesKey)) { };
this.sorter = { return labels[value] || value;
column: this.args.sort_processes_key || 'cpu_time', }
auto: !this.args.sort_processes_key, if (!sortProcessesKey || sortable.includes(sortProcessesKey)) {
isReverseColumn, this.sorter = {
getColumnLabel column: this.args.sort_processes_key || "cpu_time",
}; auto: !this.args.sort_processes_key,
} isReverseColumn,
} getColumnLabel,
} };
} }
},
},
},
}; };
</script> </script>

View File

@ -20,46 +20,46 @@
</template> </template>
<script> <script>
import { orderBy } from 'lodash'; import { orderBy } from "lodash";
export default { export default {
props: { props: {
data: { data: {
type: Object type: Object,
} },
}, },
computed: { computed: {
stats() { stats() {
return this.data.stats['wifi']; return this.data.stats["wifi"];
}, },
view() { view() {
return this.data.views['wifi']; return this.data.views["wifi"];
}, },
hotspots() { hotspots() {
const hotspots = this.stats const hotspots = this.stats
.map((hotspotData) => { .map((hotspotData) => {
if (hotspotData['ssid'] === '') { if (hotspotData["ssid"] === "") {
return; return;
} }
return { return {
ssid: hotspotData['ssid'], ssid: hotspotData["ssid"],
quality_level: hotspotData['quality_level'] quality_level: hotspotData["quality_level"],
}; };
}) })
.filter(Boolean); .filter(Boolean);
return orderBy(hotspots, ['ssid']); return orderBy(hotspots, ["ssid"]);
}, },
hasHotpots() { hasHotpots() {
return this.hotspots.length > 0; return this.hotspots.length > 0;
} },
}, },
methods: { methods: {
getDecoration(hotpost, field) { getDecoration(hotpost, field) {
if (this.view[hotpost.ssid][field] === undefined) { if (this.view[hotpost.ssid][field] === undefined) {
return; return;
} }
return this.view[hotpost.ssid][field].decoration.toLowerCase(); return this.view[hotpost.ssid][field].decoration.toLowerCase();
} },
} },
}; };
</script> </script>

View File

@ -1,141 +1,144 @@
import { min } from 'lodash'; import { min } from "lodash";
import sanitizeHtml from 'sanitize-html'; import sanitizeHtml from "sanitize-html";
export function bits(bits, low_precision) { export function bits(bits, low_precision) {
bits = Math.round(bits) * 8; bits = Math.round(bits) * 8;
return bytes(bits, low_precision) + 'b'; return bytes(bits, low_precision) + "b";
} }
export function bytes(bytes, low_precision) { export function bytes(bytes, low_precision) {
low_precision = low_precision || false; low_precision = low_precision || false;
if (isNaN(parseFloat(bytes)) || !isFinite(bytes) || bytes == 0) { if (isNaN(parseFloat(bytes)) || !isFinite(bytes) || bytes == 0) {
return bytes; return bytes;
} }
const symbols = ['Y', 'Z', 'E', 'P', 'T', 'G', 'M', 'K']; const symbols = ["Y", "Z", "E", "P", "T", "G", "M", "K"];
const prefix = { const prefix = {
Y: 1208925819614629174706176, Y: 1208925819614629174706176,
Z: 1180591620717411303424, Z: 1180591620717411303424,
E: 1152921504606846976, E: 1152921504606846976,
P: 1125899906842624, P: 1125899906842624,
T: 1099511627776, T: 1099511627776,
G: 1073741824, G: 1073741824,
M: 1048576, M: 1048576,
K: 1024 K: 1024,
}; };
for (var i = 0; i < symbols.length; i++) { for (var i = 0; i < symbols.length; i++) {
var symbol = symbols[i]; var symbol = symbols[i];
var value = bytes / prefix[symbol]; var value = bytes / prefix[symbol];
if (value > 1) { if (value > 1) {
var decimal_precision = 0; var decimal_precision = 0;
if (value < 10) { if (value < 10) {
decimal_precision = 2; decimal_precision = 2;
} else if (value < 100) { } else if (value < 100) {
decimal_precision = 1; decimal_precision = 1;
} }
if (low_precision) { if (low_precision) {
if (symbol == 'MK') { if (symbol == "MK") {
decimal_precision = 0; decimal_precision = 0;
} else { } else {
decimal_precision = min([1, decimal_precision]); decimal_precision = min([1, decimal_precision]);
} }
} else if (symbol == 'K') { } else if (symbol == "K") {
decimal_precision = 0; decimal_precision = 0;
} }
return parseFloat(value).toFixed(decimal_precision) + symbol; return parseFloat(value).toFixed(decimal_precision) + symbol;
} }
} }
return bytes.toFixed(0); return bytes.toFixed(0);
} }
export function exclamation(input) { export function exclamation(input) {
if (input === undefined || input === '') { if (input === undefined || input === "") {
return '?'; return "?";
} }
return input; return input;
} }
export function leftPad(value, length, chars) { export function leftPad(value, length, chars) {
length = length || 0; length = length || 0;
chars = chars || ' '; chars = chars || " ";
return String(value).padStart(length, chars); return String(value).padStart(length, chars);
} }
export function limitTo(value, limit) { export function limitTo(value, limit) {
if (typeof value.slice !== 'function') { if (typeof value.slice !== "function") {
value = String(value); value = String(value);
} }
return value.slice(0, limit); return value.slice(0, limit);
} }
export function minSize(input, max, begin = true) { export function minSize(input, max, begin = true) {
max = max || 8; max = max || 8;
if (input.length > max) { if (input.length > max) {
if (begin) { if (begin) {
return input.substring(0, max - 1) + '_'; return input.substring(0, max - 1) + "_";
} else { } else {
return '_' + input.substring(input.length - max + 1); return "_" + input.substring(input.length - max + 1);
} }
} }
return input; return input;
} }
export function nl2br(input) { export function nl2br(input) {
function escapeHTML(html) { function escapeHTML(html) {
var div = document.createElement('div'); var div = document.createElement("div");
div.innerText = html; div.innerText = html;
return div.innerHTML; return div.innerHTML;
} }
if (typeof input === 'undefined') { if (typeof input === "undefined") {
return input; return input;
} }
var sanitizedInput = escapeHTML(input); var sanitizedInput = escapeHTML(input);
var html = sanitizedInput.replace(/\n/g, '<br>'); var html = sanitizedInput.replace(/\n/g, "<br>");
return sanitizeHtml(html); return sanitizeHtml(html);
} }
export function number(value, options) { export function number(value, options) {
// If value is undefined or not a number then return '-' // If value is undefined or not a number then return '-'
if ((typeof value === 'undefined') || isNaN(value)) { if (typeof value === "undefined" || isNaN(value)) {
return '-'; return "-";
} }
// Else // Else
return new Intl.NumberFormat( return new Intl.NumberFormat(
"en-US", "en-US",
typeof options === 'number' ? { maximumFractionDigits: options } : options typeof options === "number" ? { maximumFractionDigits: options } : options,
).format(value); ).format(value);
} }
export function timemillis(array) { export function timemillis(array) {
var sum = 0.0; var sum = 0.0;
for (var i = 0; i < array.length; i++) { for (var i = 0; i < array.length; i++) {
sum += array[i] * 1000.0; sum += array[i] * 1000.0;
} }
return sum; return sum;
} }
export function timedelta(value) { export function timedelta(value) {
var sum = timemillis(value); var sum = timemillis(value);
var d = new Date(sum); var d = new Date(sum);
var doy = Math.floor((d - new Date(d.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24); var doy = Math.floor(
return { (d - new Date(d.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24,
hours: d.getUTCHours() + (doy - 1) * 24, );
minutes: d.getUTCMinutes(), return {
seconds: d.getUTCSeconds(), hours: d.getUTCHours() + (doy - 1) * 24,
milliseconds: parseInt('' + d.getUTCMilliseconds() / 10) minutes: d.getUTCMinutes(),
}; seconds: d.getUTCSeconds(),
milliseconds: parseInt("" + d.getUTCMilliseconds() / 10),
};
} }
export function dictToString(dict) { export function dictToString(dict) {
return Object.entries(dict).map(([key, value]) => `${key}: ${value}`).join(' / '); return Object.entries(dict)
.map(([key, value]) => `${key}: ${value}`)
.join(" / ");
} }

View File

@ -1,132 +1,140 @@
import { store } from './store.js'; import Favico from "favico.js";
import Favico from 'favico.js'; import { store } from "./store.js";
// prettier-ignore // prettier-ignore
const fetchAll = () => fetch('api/4/all', { method: 'GET' }).then((response) => response.json()); const fetchAll = () =>
fetch("api/4/all", { method: "GET" }).then((response) => response.json());
// prettier-ignore // prettier-ignore
const fetchAllViews = () => fetch('api/4/all/views', { method: 'GET' }).then((response) => response.json()); const fetchAllViews = () =>
fetch("api/4/all/views", { method: "GET" }).then((response) =>
response.json(),
);
// prettier-ignore // prettier-ignore
const fetchAllLimits = () => fetch('api/4/all/limits', { method: 'GET' }).then((response) => response.json()); const fetchAllLimits = () =>
fetch("api/4/all/limits", { method: "GET" }).then((response) =>
response.json(),
);
// prettier-ignore // prettier-ignore
const fetchArgs = () => fetch('api/4/args', { method: 'GET' }).then((response) => response.json()); const fetchArgs = () =>
fetch("api/4/args", { method: "GET" }).then((response) => response.json());
// prettier-ignore // prettier-ignore
const fetchConfig = () => fetch('api/4/config', { method: 'GET' }).then((response) => response.json()); const fetchConfig = () =>
fetch("api/4/config", { method: "GET" }).then((response) => response.json());
class GlancesHelperService { class GlancesHelperService {
limits = {}; limits = {};
limitSuffix = ['critical', 'careful', 'warning']; limitSuffix = ["critical", "careful", "warning"];
setLimits(limits) { setLimits(limits) {
this.limits = limits; this.limits = limits;
} }
getLimit(pluginName, limitName) { getLimit(pluginName, limitName) {
if (this.limits[pluginName] != undefined) { if (this.limits[pluginName] != undefined) {
if (this.limits[pluginName][limitName] != undefined) { if (this.limits[pluginName][limitName] != undefined) {
return this.limits[pluginName][limitName] return this.limits[pluginName][limitName];
} }
} }
return null return null;
} }
getAlert(pluginName, limitNamePrefix, current, maximum, log) { getAlert(pluginName, limitNamePrefix, current, maximum, log) {
current = current || 0; current = current || 0;
maximum = maximum || 100; maximum = maximum || 100;
log = log || false; log = log || false;
var log_str = log ? '_log' : ''; var log_str = log ? "_log" : "";
var value = (current * 100) / maximum; var value = (current * 100) / maximum;
if (this.limits[pluginName] != undefined) { if (this.limits[pluginName] != undefined) {
for (var i = 0; i < this.limitSuffix.length; i++) { for (var i = 0; i < this.limitSuffix.length; i++) {
var limitName = limitNamePrefix + this.limitSuffix[i]; var limitName = limitNamePrefix + this.limitSuffix[i];
var limit = this.limits[pluginName][limitName]; var limit = this.limits[pluginName][limitName];
if (value >= limit) { if (value >= limit) {
var pos = limitName.lastIndexOf('_'); var pos = limitName.lastIndexOf("_");
var className = limitName.substring(pos + 1); var className = limitName.substring(pos + 1);
return className + log_str; return className + log_str;
} }
} }
} }
return 'ok' + log_str; return "ok" + log_str;
} }
getAlertLog(pluginName, limitNamePrefix, current, maximum) { getAlertLog(pluginName, limitNamePrefix, current, maximum) {
return this.getAlert(pluginName, limitNamePrefix, current, maximum, true); return this.getAlert(pluginName, limitNamePrefix, current, maximum, true);
} }
} }
export const GlancesHelper = new GlancesHelperService(); export const GlancesHelper = new GlancesHelperService();
class GlancesStatsService { class GlancesStatsService {
data = undefined; data = undefined;
init(REFRESH_TIME = 60) { init(REFRESH_TIME = 60) {
let timeout = undefined; let timeout;
const fetchData = () => { const fetchData = () => {
store.status = 'PENDING'; store.status = "PENDING";
return Promise.all([fetchAll(), fetchAllViews()]) return Promise.all([fetchAll(), fetchAllViews()])
.then((response) => { .then((response) => {
const data = { const data = {
stats: response[0], stats: response[0],
views: response[1], views: response[1],
isBsd: response[0].system?.os_name === 'FreeBSD', isBsd: response[0].system?.os_name === "FreeBSD",
isLinux: response[0].system?.os_name === 'Linux', isLinux: response[0].system?.os_name === "Linux",
isSunOS: response[0].system?.os_name === 'SunOS', isSunOS: response[0].system?.os_name === "SunOS",
isMac: response[0].system?.os_name === 'Darwin', isMac: response[0].system?.os_name === "Darwin",
isWindows: response[0].system?.os_name === 'Windows' isWindows: response[0].system?.os_name === "Windows",
}; };
this.data = data; this.data = data;
store.data = data; store.data = data;
store.status = 'SUCCESS'; store.status = "SUCCESS";
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
store.status = 'FAILURE'; store.status = "FAILURE";
}) })
.then(() => { .then(() => {
if (timeout) { if (timeout) {
clearTimeout(timeout); clearTimeout(timeout);
} }
timeout = setTimeout(fetchData, REFRESH_TIME * 1000); // in milliseconds timeout = setTimeout(fetchData, REFRESH_TIME * 1000); // in milliseconds
}); });
}; };
fetchData(); fetchData();
fetchAllLimits().then((response) => { fetchAllLimits().then((response) => {
GlancesHelper.setLimits(response); GlancesHelper.setLimits(response);
}); });
fetchArgs().then((response = {}) => { fetchArgs().then((response = {}) => {
store.args = { ...store.args, ...response }; store.args = { ...store.args, ...response };
}); });
fetchConfig().then((response = {}) => { fetchConfig().then((response = {}) => {
store.config = { ...store.config, ...response }; store.config = { ...store.config, ...response };
}); });
} }
getData() { getData() {
return this.data; return this.data;
} }
} }
export const GlancesStats = new GlancesStatsService(); export const GlancesStats = new GlancesStatsService();
class GlancesFavicoService { class GlancesFavicoService {
constructor() { constructor() {
this.favico = new Favico({ this.favico = new Favico({
animation: 'none' animation: "none",
}); });
} }
badge(nb) { badge(nb) {
this.favico.badge(nb); this.favico.badge(nb);
} }
reset() { reset() {
this.favico.reset(); this.favico.reset();
} }
} }
export const GlancesFavico = new GlancesFavicoService(); export const GlancesFavico = new GlancesFavicoService();

View File

@ -1,8 +1,8 @@
import { reactive } from 'vue'; import { reactive } from "vue";
export const store = reactive({ export const store = reactive({
args: undefined, args: undefined,
config: undefined, config: undefined,
data: undefined, data: undefined,
status: 'IDLE' status: "IDLE",
}); });

View File

@ -1,24 +1,16 @@
{ {
"topMenu": [ "topMenu": ["quicklook", "cpu", "percpu", "gpu", "mem", "memswap", "load"],
"quicklook", "leftMenu": [
"cpu", "network",
"percpu", "ports",
"gpu", "wifi",
"mem", "connections",
"memswap", "diskio",
"load" "fs",
], "irq",
"leftMenu": [ "folders",
"network", "raid",
"ports", "smart",
"wifi", "sensors"
"connections", ]
"diskio",
"fs",
"irq",
"folders",
"raid",
"smart",
"sensors"
]
} }

View File

@ -1,41 +1,41 @@
{ {
"private": true, "private": true,
"dependencies": { "dependencies": {
"bootstrap": "^5.3.5", "bootstrap": "^5.3.5",
"favico.js": "^0.3.10", "favico.js": "^0.3.10",
"hotkeys-js": "^3.13.9", "hotkeys-js": "^3.13.9",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"sanitize-html": "^2.16.0", "sanitize-html": "^2.16.0",
"vue": "^3.5.13" "vue": "^3.5.13"
}, },
"devDependencies": { "devDependencies": {
"@vue/compiler-sfc": "^3.5.13", "@vue/compiler-sfc": "^3.5.13",
"copy-webpack-plugin": "^13.0.0", "copy-webpack-plugin": "^13.0.0",
"css-loader": "^7.1.2", "css-loader": "^7.1.2",
"del": "^8.0.0", "del": "^8.0.0",
"eslint": "^9.25.0", "eslint": "^9.25.0",
"eslint-config-prettier": "^10.1.2", "eslint-config-prettier": "^10.1.2",
"eslint-plugin-vue": "^10.0.0", "eslint-plugin-vue": "^10.0.0",
"globals": "^16.0.0", "globals": "^16.0.0",
"html-webpack-plugin": "^5.6.3", "html-webpack-plugin": "^5.6.3",
"less": "^4.3.0", "less": "^4.3.0",
"less-loader": "^12.2.0", "less-loader": "^12.2.0",
"sass": "^1.86.3", "sass": "^1.86.3",
"sass-loader": "^16.0.5", "sass-loader": "^16.0.5",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"typescript-eslint": "^8.30.1", "typescript-eslint": "^8.30.1",
"url-loader": "^4.1.1", "url-loader": "^4.1.1",
"vue-loader": "^17.4.2", "vue-loader": "^17.4.2",
"webpack": "^5.99.6", "webpack": "^5.99.6",
"webpack-cli": "^6.0.1", "webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.1" "webpack-dev-server": "^5.2.1"
}, },
"scripts": { "scripts": {
"build": "webpack --progress --mode=production", "build": "webpack --progress --mode=production",
"start": "webpack serve --mode=development", "start": "webpack serve --mode=development",
"watch": "webpack --progress --watch", "watch": "webpack --progress --watch",
"lint": "eslint ./ --ext .js,.vue", "lint": "eslint ./ --ext .js,.vue",
"lint-fix": "eslint ./ --ext .js,.vue --fix", "lint-fix": "eslint ./ --ext .js,.vue --fix",
"clean": "rm -rf node_modules" "clean": "rm -rf node_modules"
} }
} }

View File

@ -1,86 +1,90 @@
const webpack = require("webpack");
const webpack = require('webpack');
const path = require("path"); const path = require("path");
const CopyWebpackPlugin = require("copy-webpack-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin'); const HtmlWebpackPlugin = require("html-webpack-plugin");
const TerserWebpackPlugin = require('terser-webpack-plugin'); const TerserWebpackPlugin = require("terser-webpack-plugin");
const { VueLoaderPlugin } = require('vue-loader'); const { VueLoaderPlugin } = require("vue-loader");
const PORT = process.env.PORT || 61209; const PORT = process.env.PORT || 61209;
module.exports = (_, env) => { module.exports = (_, env) => {
const isProd = env.mode === 'production'; const isProd = env.mode === "production";
return { return {
mode: isProd ? 'production' : 'development', mode: isProd ? "production" : "development",
entry: { entry: {
glances: "./js/app.js", glances: "./js/app.js",
browser: "./js/browser.js" browser: "./js/browser.js",
}, },
output: { output: {
path: path.join(__dirname, "public"), path: path.join(__dirname, "public"),
filename: "[name].js", filename: "[name].js",
publicPath: '/', publicPath: "/",
clean: true clean: true,
}, },
devtool: isProd ? false : 'eval-source-map', devtool: isProd ? false : "eval-source-map",
module: { module: {
rules: [ rules: [
{ {
test: /\.vue$/i, test: /\.vue$/i,
loader: 'vue-loader' loader: "vue-loader",
}, },
{ {
test: /\.scss$/i, test: /\.scss$/i,
use: [{ use: [
loader: "style-loader", {
}, { loader: "style-loader",
loader: "css-loader", },
}, { {
loader: "sass-loader", loader: "css-loader",
}] },
}, {
{ loader: "sass-loader",
test: /\.css$/i, },
use: [{ ],
loader: "style-loader", },
}, { {
loader: "css-loader", test: /\.css$/i,
}] use: [
} {
], loader: "style-loader",
}, },
plugins: [ {
new webpack.DefinePlugin({ loader: "css-loader",
__VUE_OPTIONS_API__: true, },
__VUE_PROD_DEVTOOLS__: false, ],
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false },
}), ],
new CopyWebpackPlugin({ },
patterns: [ plugins: [
{ from: "./images/favicon.ico" } new webpack.DefinePlugin({
] __VUE_OPTIONS_API__: true,
}), __VUE_PROD_DEVTOOLS__: false,
!isProd && new HtmlWebpackPlugin({ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false,
template: './templates/index.html', }),
inject: false new CopyWebpackPlugin({
}), patterns: [{ from: "./images/favicon.ico" }],
isProd && new TerserWebpackPlugin({ extractComments: false }), }),
new VueLoaderPlugin() !isProd &&
].filter(Boolean), new HtmlWebpackPlugin({
devServer: { template: "./templates/index.html",
client: { inject: false,
overlay: false }),
}, isProd && new TerserWebpackPlugin({ extractComments: false }),
host: '0.0.0.0', new VueLoaderPlugin(),
port: PORT, ].filter(Boolean),
hot: true, devServer: {
proxy: [ client: {
{ overlay: false,
context: ['/api'], },
target: 'http://0.0.0.0:61208' host: "0.0.0.0",
} port: PORT,
] hot: true,
} proxy: [
{
}; context: ["/api"],
target: "http://0.0.0.0:61208",
},
],
},
};
}; };

View File

@ -1,8 +1,6 @@
{ {
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [ "extends": ["config:recommended"],
"config:recommended" "prHourlyLimit": 3,
], "updateLockFiles": false
"prHourlyLimit": 3,
"updateLockFiles": false
} }

14
tests-data/issues/issue3322-homepage/run-homepage.sh Normal file → Executable file
View File

@ -1,7 +1,9 @@
#!/bin/sh
docker run --rm \ docker run --rm \
--name homepage \ --name homepage \
-p 3000:3000 \ -p 3000:3000 \
-e HOMEPAGE_ALLOWED_HOSTS=localhost:3000,0.0.0.0:3000 \ -e HOMEPAGE_ALLOWED_HOSTS=localhost:3000,0.0.0.0:3000 \
-v ./config:/app/config \ -v ./config:/app/config \
-v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/gethomepage/homepage:latest ghcr.io/gethomepage/homepage:latest

View File

@ -1,9 +1,11 @@
#!/bin/sh
docker run -d \ docker run -d \
--name homeassistant \ --name homeassistant \
--privileged \ --privileged \
--restart=unless-stopped \ --restart=unless-stopped \
-e TZ=Europe/Paris \ -e TZ=Europe/Paris \
-v ./config:/config \ -v ./config:/config \
-v /run/dbus:/run/dbus:ro \ -v /run/dbus:/run/dbus:ro \
--network=host \ --network=host \
ghcr.io/home-assistant/home-assistant:stable ghcr.io/home-assistant/home-assistant:stable

2
tests-data/tools/find-duplicate-lines.sh Normal file → Executable file
View File

@ -1,3 +1,5 @@
#!/bin/sh
find ./glances/ -type f -name "*.py" -exec sh -c ' find ./glances/ -type f -name "*.py" -exec sh -c '
duplicate_found=0 duplicate_found=0
for file; do for file; do

View File

@ -19,7 +19,7 @@ for i in {1..30}; do
break break
fi fi
if [ $i -eq 30 ]; then if [ "$i" -eq 30 ]; then
echo "Error: Timed out waiting for InfluxDB to start" echo "Error: Timed out waiting for InfluxDB to start"
docker stop influxdb-v1-for-glances docker stop influxdb-v1-for-glances
docker rm influxdb-v1-for-glances docker rm influxdb-v1-for-glances
@ -68,4 +68,4 @@ echo "Stopping and removing InfluxDB container..."
docker stop influxdb-v1-for-glances docker stop influxdb-v1-for-glances
docker rm influxdb-v1-for-glances docker rm influxdb-v1-for-glances
echo "Script completed successfully!" echo "Script completed successfully!"

View File

@ -18,7 +18,7 @@ sleep 5
# Create the token # Create the token
echo "Creating InfluxDB token..." echo "Creating InfluxDB token..."
TOKEN_RETURN=$(docker exec influxdb-v3-for-glances influxdb3 create token --admin) TOKEN_RETURN=$(docker exec influxdb-v3-for-glances influxdb3 create token --admin)
TOKEN=$(echo -n $TOKEN_RETURN | awk '{ print $6 }') TOKEN=$(echo -n "$TOKEN_RETURN" | awk '{ print $6 }')
echo "Token: $TOKEN" echo "Token: $TOKEN"
# Create a new configuration for the test # Create a new configuration for the test

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/bash
if [ $(id -u) -ne 0 ]; then if [ "$(id -u)" != "0" ]; then
echo -e "* ERROR: User $(whoami) is not root, and does not have sudo privileges" echo "* ERROR: User $(whoami) is not root, and does not have sudo privileges"
exit 1 exit 1
fi fi
@ -14,9 +14,9 @@ fi
python setup.py install --record install.record python setup.py install --record install.record
for i in $(cat install.record); do while IFS= read -r i; do
rm $i rm "$i"
done done < install.record
echo -e "\n\n* SUCCESS: Uninstall complete." echo -e "\n\n* SUCCESS: Uninstall complete."
rm install.record rm install.record