Master-Branch-Fix freebsd dashboard items (#7967)
* Fix freebsd dashboard items * Fix service total count
This commit is contained in:
@@ -31,6 +31,99 @@
|
||||
*/
|
||||
class bsd_system_information extends system_information {
|
||||
|
||||
/**
|
||||
* Selects the preferred service definition file for BSD.
|
||||
*
|
||||
* @param array $module_files Service definition files for a module.
|
||||
*
|
||||
* @return string|null Preferred file path.
|
||||
*/
|
||||
protected function select_preferred_service_file(array $module_files): ?string {
|
||||
$selected_file = $module_files[0] ?? null;
|
||||
if ($selected_file === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($module_files as $candidate) {
|
||||
if (basename($candidate) === 'freebsd.service') {
|
||||
$selected_file = $candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $selected_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a BSD service identifier from an rc.d-style service definition.
|
||||
*
|
||||
* @param string $file Path to the service file.
|
||||
*
|
||||
* @return string Service identifier, or empty string if not found.
|
||||
*/
|
||||
protected function get_service_identifier(string $file): string {
|
||||
if (!file_exists($file)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$content = file_get_contents($file);
|
||||
if ($content === false) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('/^#\s*PROVIDE:\s*(\S+)/mi', $content, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
|
||||
if (preg_match('/^name\s*=\s*["\']([^"\']+)["\']/mi', $content, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a process with the given name is currently running on BSD.
|
||||
*
|
||||
* @param string $name The name of the process to check for.
|
||||
*
|
||||
* @return array Process status including running flag, PID, and elapsed time.
|
||||
*/
|
||||
public function is_running(string $name): array {
|
||||
$name = trim($name);
|
||||
$safe_name = escapeshellarg($name);
|
||||
$running = false;
|
||||
$pid = null;
|
||||
$etime = null;
|
||||
|
||||
$rc = 1;
|
||||
exec("service $safe_name onestatus >/dev/null 2>&1", $out, $rc);
|
||||
if ($rc === 0) {
|
||||
$running = true;
|
||||
$status_line = shell_exec("service $safe_name status 2>/dev/null");
|
||||
if (preg_match('/pid\s+([0-9]+)/i', (string)$status_line, $m)) {
|
||||
$pid = $m[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback for services with non-standard status output or process names.
|
||||
if (!$running) {
|
||||
$proc_name = ($name === 'postgresql') ? 'postgres' : $name;
|
||||
$safe_proc = escapeshellarg($proc_name);
|
||||
$pid_guess = trim((string)shell_exec("pgrep -f $safe_proc | head -n 1"));
|
||||
if ($pid_guess !== '' && preg_match('/^\d+$/', $pid_guess)) {
|
||||
$running = true;
|
||||
$pid = $pid_guess;
|
||||
}
|
||||
}
|
||||
|
||||
if ($running && !empty($pid)) {
|
||||
$etime = trim((string)shell_exec("ps -p " . escapeshellarg($pid) . " -o etime= | tr -d '\n'"));
|
||||
}
|
||||
|
||||
return ['running' => $running, 'pid' => $pid, 'etime' => $etime];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the network card information.
|
||||
*
|
||||
@@ -39,9 +132,17 @@ class bsd_system_information extends system_information {
|
||||
* @return string|null The network card information or the default value.
|
||||
*/
|
||||
public function get_network_card(?string $default_value = null): ?string {
|
||||
// Implementation for BSD systems
|
||||
$result = shell_exec("ifconfig -a | head -n1 | awk '{print $1}'");
|
||||
$network_card = trim($result, " :");
|
||||
// Implementation for BSD systems - get first non-loopback interface
|
||||
$result = shell_exec("ifconfig -l 2>/dev/null | awk '{print $1}' | head -n1");
|
||||
$network_card = trim($result);
|
||||
if (!$network_card) {
|
||||
// Fallback: try em0 first (common on VMs), then other common BSD interfaces
|
||||
foreach (['em0', 'igb0', 'ixl0', 're0', 'bge0'] as $iface) {
|
||||
if (@file_exists("/sys/class/net/$iface") || shell_exec("ifconfig $iface 2>/dev/null") !== null) {
|
||||
return $iface;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $network_card ?: $default_value;
|
||||
}
|
||||
|
||||
@@ -51,9 +152,15 @@ class bsd_system_information extends system_information {
|
||||
* @return int The number of CPU cores.
|
||||
*/
|
||||
public function get_cpu_cores(): int {
|
||||
$result = shell_exec("dmesg | grep -i --max-count 1 CPUs | sed 's/[^0-9]*//g'");
|
||||
$cpu_cores = trim($result);
|
||||
return $cpu_cores;
|
||||
// Try sysctl first (more reliable on FreeBSD)
|
||||
$result = @shell_exec("sysctl -n hw.ncpu 2>/dev/null");
|
||||
if ($result && is_numeric(trim($result))) {
|
||||
return intval(trim($result));
|
||||
}
|
||||
// Fallback to dmesg parsing
|
||||
$result = @shell_exec("dmesg | grep -i --max-count 1 CPUs | sed 's/[^0-9]*//g' 2>/dev/null");
|
||||
$cpu_cores = intval(trim($result));
|
||||
return $cpu_cores > 0 ? $cpu_cores : 1;
|
||||
}
|
||||
|
||||
//get the CPU details
|
||||
@@ -64,14 +171,59 @@ class bsd_system_information extends system_information {
|
||||
* @return float The current CPU usage percentage.
|
||||
*/
|
||||
public function get_cpu_percent(): float {
|
||||
$result = shell_exec('ps -A -o pcpu');
|
||||
$percent_cpu = 0;
|
||||
foreach (explode("\n", $result) as $value) {
|
||||
if (is_numeric($value)) {
|
||||
$percent_cpu = $percent_cpu + $value;
|
||||
static $last = null;
|
||||
|
||||
$read_cp_time = static function (): ?array {
|
||||
$raw = @trim((string) shell_exec('sysctl -n kern.cp_time 2>/dev/null'));
|
||||
if ($raw === '') {
|
||||
return null;
|
||||
}
|
||||
$parts = array_map('intval', preg_split('/\s+/', $raw));
|
||||
if (count($parts) < 5) {
|
||||
return null;
|
||||
}
|
||||
return [
|
||||
'user' => $parts[0],
|
||||
'nice' => $parts[1],
|
||||
'sys' => $parts[2],
|
||||
'intr' => $parts[3],
|
||||
'idle' => $parts[4],
|
||||
'total' => array_sum(array_slice($parts, 0, 5)),
|
||||
];
|
||||
};
|
||||
|
||||
$current = $read_cp_time();
|
||||
if ($current === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Prime baseline on first call so we can calculate a meaningful delta.
|
||||
if ($last === null) {
|
||||
$last = $current;
|
||||
usleep(200000);
|
||||
$current = $read_cp_time();
|
||||
if ($current === null) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return $percent_cpu;
|
||||
|
||||
$delta_total = $current['total'] - $last['total'];
|
||||
$delta_idle = $current['idle'] - $last['idle'];
|
||||
$last = $current;
|
||||
|
||||
if ($delta_total <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$usage = (1 - ($delta_idle / $delta_total)) * 100;
|
||||
if ($usage < 0) {
|
||||
$usage = 0;
|
||||
}
|
||||
if ($usage > 100) {
|
||||
$usage = 100;
|
||||
}
|
||||
|
||||
return round($usage, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +232,8 @@ class bsd_system_information extends system_information {
|
||||
* @return string The system uptime in seconds.
|
||||
*/
|
||||
public function get_uptime() {
|
||||
return shell_exec('uptime');
|
||||
$result = @shell_exec('uptime 2>/dev/null');
|
||||
return $result ?: 'unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,18 +291,41 @@ class bsd_system_information extends system_information {
|
||||
public function get_network_speed(string $interface = 'em0'): array {
|
||||
static $last = [];
|
||||
|
||||
// Run netstat for the interface
|
||||
// Validate interface exists by running netstat
|
||||
$output = shell_exec("netstat -bI {$interface} 2>/dev/null");
|
||||
if (!$output)
|
||||
if (!$output) {
|
||||
// Interface doesn't exist or error - return zeros and try to detect correct interface
|
||||
if (!isset($last[$interface])) {
|
||||
// Try to auto-detect valid interface
|
||||
$fallback = $this->get_network_card();
|
||||
if ($fallback && $fallback !== $interface) {
|
||||
$output = shell_exec("netstat -bI {$fallback} 2>/dev/null");
|
||||
if ($output) {
|
||||
// Use fallback interface for future calls
|
||||
$interface = $fallback;
|
||||
} else {
|
||||
return ['rx_bps' => 0, 'tx_bps' => 0];
|
||||
}
|
||||
} else {
|
||||
return ['rx_bps' => 0, 'tx_bps' => 0];
|
||||
}
|
||||
} else {
|
||||
return ['rx_bps' => 0, 'tx_bps' => 0];
|
||||
}
|
||||
}
|
||||
|
||||
$lines = explode("\n", trim($output));
|
||||
if (count($lines) < 2)
|
||||
return ['rx_bps' => 0, 'tx_bps' => 0];
|
||||
|
||||
$cols = preg_split('/\s+/', $lines[1]);
|
||||
$rx_bytes = (int) $cols[6]; // Ibytes
|
||||
$tx_bytes = (int) $cols[9]; // Obytes
|
||||
$cols = preg_split('/\s+/', trim($lines[1]));
|
||||
if (count($cols) < 11)
|
||||
return ['rx_bps' => 0, 'tx_bps' => 0];
|
||||
|
||||
// FreeBSD netstat -bI layout:
|
||||
// 0 Name 1 Mtu 2 Network 3 Address 4 Ipkts 5 Ierrs 6 Idrop 7 Ibytes 8 Opkts 9 Oerrs 10 Obytes 11 Coll
|
||||
$rx_bytes = (int) $cols[7]; // Ibytes
|
||||
$tx_bytes = (int) $cols[10]; // Obytes
|
||||
$now = microtime(true);
|
||||
|
||||
if (!isset($last[$interface])) {
|
||||
|
||||
@@ -31,6 +31,72 @@
|
||||
*/
|
||||
class linux_system_information extends system_information {
|
||||
|
||||
/**
|
||||
* Selects the preferred service definition file for Linux.
|
||||
*
|
||||
* @param array $module_files Service definition files for a module.
|
||||
*
|
||||
* @return string|null Preferred file path.
|
||||
*/
|
||||
protected function select_preferred_service_file(array $module_files): ?string {
|
||||
$selected_file = $module_files[0] ?? null;
|
||||
if ($selected_file === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($module_files as $candidate) {
|
||||
if (strpos(basename($candidate), 'debian') !== false) {
|
||||
$selected_file = $candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $selected_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a Linux service identifier from a systemd service definition.
|
||||
*
|
||||
* @param string $file Path to the service file.
|
||||
*
|
||||
* @return string Service identifier, or empty string if not found.
|
||||
*/
|
||||
protected function get_service_identifier(string $file): string {
|
||||
if (!file_exists($file)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$content = file_get_contents($file);
|
||||
if ($content === false) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('/^ExecStart\s*=\s*.*?\s+([^\s]+\.php)\s*$/mi', $content, $matches)) {
|
||||
return basename($matches[1], '.php');
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a process with the given name is currently running on Linux.
|
||||
*
|
||||
* @param string $name The name of the process to check for.
|
||||
*
|
||||
* @return array Process status including running flag, PID, and elapsed time.
|
||||
*/
|
||||
public function is_running(string $name): array {
|
||||
$name = trim($name);
|
||||
$safe_name = escapeshellarg($name);
|
||||
$pid = trim((string)shell_exec("ps -aux | grep $safe_name | grep -v grep | awk '{print \$2}' | head -n 1"));
|
||||
if ($pid !== '' && preg_match('/^\d+$/', $pid)) {
|
||||
$etime = trim((string)shell_exec("ps -p $pid -o etime= | tr -d '\n'"));
|
||||
return ['running' => true, 'pid' => $pid, 'etime' => $etime];
|
||||
}
|
||||
|
||||
return ['running' => false, 'pid' => null, 'etime' => null];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of CPU cores available on the system.
|
||||
*
|
||||
|
||||
@@ -64,8 +64,14 @@ class system_dashboard_service extends base_websocket_system_service {
|
||||
// get the network interval
|
||||
$this->network_status_refresh_interval = intval($this->settings->get('system', 'network_status_refresh_interval', 3));
|
||||
|
||||
// get the network card to watch
|
||||
$this->network_interface = $this->settings->get('system', 'network_interface', 'eth0');
|
||||
// get the network card to watch - auto-detect if not configured
|
||||
$configured_interface = $this->settings->get('system', 'network_interface', '');
|
||||
if (!empty($configured_interface)) {
|
||||
$this->network_interface = $configured_interface;
|
||||
} else {
|
||||
// Auto-detect network interface from system information
|
||||
$this->network_interface = self::$system_information->get_network_card('em0');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,8 +128,8 @@ class system_dashboard_service extends base_websocket_system_service {
|
||||
->topic(self::NETWORK_STATUS_TOPIC)
|
||||
;
|
||||
if ($message !== null && $message instanceof websocket_message) {
|
||||
$this->debug("Responding to message request id: ".$message->id());
|
||||
$response->id($message->id());
|
||||
$this->debug("Responding to message request id: ".$message->request_id());
|
||||
$response->request_id($message->request_id());
|
||||
}
|
||||
|
||||
// Log for debugging
|
||||
@@ -167,7 +173,7 @@ class system_dashboard_service extends base_websocket_system_service {
|
||||
if ($message !== null && $message instanceof websocket_message) {
|
||||
$payload = $message->payload();
|
||||
if (!empty($payload['network_interface'])) {
|
||||
$this->network_interface = ['network_interface'];
|
||||
$this->network_interface = $payload['network_interface'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,7 +208,7 @@ class system_dashboard_service extends base_websocket_system_service {
|
||||
|
||||
// Include message ID if responding to a request
|
||||
if ($message !== null && $message instanceof websocket_message) {
|
||||
$response->id($message->id());
|
||||
$response->request_id($message->request_id());
|
||||
}
|
||||
|
||||
// Log for debugging
|
||||
|
||||
@@ -37,6 +37,9 @@ abstract class system_information {
|
||||
abstract public function get_cpu_percent_per_core(): array;
|
||||
abstract public function get_network_speed(string $interface = 'eth0'): array;
|
||||
abstract public function get_network_card(?string $default_value = null): ?string;
|
||||
abstract public function is_running(string $name): array;
|
||||
abstract protected function get_service_identifier(string $file): string;
|
||||
abstract protected function select_preferred_service_file(array $module_files): ?string;
|
||||
|
||||
/**
|
||||
* Returns the system load average.
|
||||
@@ -47,18 +50,71 @@ abstract class system_information {
|
||||
return sys_getloadavg();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds installed service status entries from grouped service definition files.
|
||||
*
|
||||
* @param array $grouped_service_files Grouped service files keyed by module directory.
|
||||
* @param array $service_labels Optional map of service key to display label.
|
||||
*
|
||||
* @return array Installed services keyed by service name.
|
||||
*/
|
||||
public function get_installed_services(array $grouped_service_files, array $service_labels = []): array {
|
||||
$services = [];
|
||||
|
||||
foreach ($grouped_service_files as $module_files) {
|
||||
if (!is_array($module_files) || empty($module_files)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$selected_file = $this->select_preferred_service_file($module_files);
|
||||
if (empty($selected_file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$service = $this->get_service_identifier($selected_file);
|
||||
if (!empty($service)) {
|
||||
$basename = basename($service, '.php');
|
||||
$info = $this->is_running($basename);
|
||||
$info['label'] = $service_labels[$basename] ?? ucwords(str_replace('_', ' ', $basename));
|
||||
$services[$basename] = $info;
|
||||
}
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a system information object based on the underlying operating system.
|
||||
*
|
||||
* @return ?system_information The system information object for the current OS, or null if not supported.
|
||||
*/
|
||||
public static function new(): ?system_information {
|
||||
if (stristr(PHP_OS, 'BSD')) {
|
||||
return new bsd_system_information();
|
||||
// Compatibility with PHP 7.1 and below
|
||||
if (!defined('PHP_OS_FAMILY')) {
|
||||
if (stripos(PHP_OS, 'linux') === 0) {
|
||||
define('PHP_OS_FAMILY', 'Linux');
|
||||
} elseif (stripos(PHP_OS, 'bsd') !== false) {
|
||||
define('PHP_OS_FAMILY', 'BSD');
|
||||
} elseif (stripos(PHP_OS, 'dar') === 0) {
|
||||
define('PHP_OS_FAMILY', 'Darwin');
|
||||
} elseif (stripos(PHP_OS, 'sunos') === 0) {
|
||||
define('PHP_OS_FAMILY', 'Solaris');
|
||||
} elseif (stripos(PHP_OS, 'win') === 0) {
|
||||
define('PHP_OS_FAMILY', 'Windows');
|
||||
} else {
|
||||
define('PHP_OS_FAMILY', 'Unknown');
|
||||
}
|
||||
if (stristr(PHP_OS, 'Linux')) {
|
||||
return new linux_system_information();
|
||||
}
|
||||
|
||||
// Determine the class name based on the OS family
|
||||
$class = strtolower(PHP_OS_FAMILY) . '_system_information';
|
||||
|
||||
if (class_exists($class)) {
|
||||
// linux_system_information or bsd_system_information object
|
||||
return new $class();
|
||||
}
|
||||
|
||||
// Unsupported OS
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,28 +32,18 @@
|
||||
$row_style["1"] = "row_style1";
|
||||
|
||||
//get the CPU details
|
||||
if (stristr(PHP_OS, 'BSD') || stristr(PHP_OS, 'Linux')) {
|
||||
$system_information = system_information::new();
|
||||
if ($system_information !== null) {
|
||||
|
||||
$result = shell_exec('ps -A -o pcpu');
|
||||
$percent_cpu = 0;
|
||||
foreach (explode("\n", $result) as $value) {
|
||||
if (is_numeric($value)) { $percent_cpu = $percent_cpu + $value; }
|
||||
$percent_cpu = $system_information->get_cpu_percent();
|
||||
$cpu_cores = $system_information->get_cpu_cores();
|
||||
if ($cpu_cores < 1) {
|
||||
$cpu_cores = 1;
|
||||
}
|
||||
if (stristr(PHP_OS, 'BSD')) {
|
||||
$result = shell_exec("dmesg | grep -i --max-count 1 CPUs | sed 's/[^0-9]*//g'");
|
||||
$cpu_cores = trim($result);
|
||||
}
|
||||
if (stristr(PHP_OS, 'Linux')) {
|
||||
$result = @trim(shell_exec("grep -P '^processor' /proc/cpuinfo"));
|
||||
$cpu_cores = count(explode("\n", $result));
|
||||
}
|
||||
if ($cpu_cores > 1) { $percent_cpu = $percent_cpu / $cpu_cores; }
|
||||
$percent_cpu = round($percent_cpu, 2);
|
||||
|
||||
//uptime
|
||||
$result = shell_exec('uptime');
|
||||
$load_average = sys_getloadavg();
|
||||
|
||||
}
|
||||
|
||||
//show the content
|
||||
|
||||
@@ -36,51 +36,6 @@
|
||||
exit;
|
||||
}
|
||||
|
||||
//function to parse a FusionPBX service from a .service file
|
||||
if (!function_exists('get_classname')) {
|
||||
/**
|
||||
* Retrieves the name of a PHP class from an ExecStart directive in a service file.
|
||||
*
|
||||
* @param string $file Path to the service file.
|
||||
*
|
||||
* @return string The name of the PHP class, or empty string if not found.
|
||||
*/
|
||||
function get_classname(string $file) {
|
||||
if (!file_exists($file)) {
|
||||
return '';
|
||||
}
|
||||
$parsed = parse_ini_file($file);
|
||||
$exec_cmd = $parsed['ExecStart'] ?? '';
|
||||
$parts = explode(' ', $exec_cmd ?? '');
|
||||
$php_file = $parts[1] ?? '';
|
||||
if (!empty($php_file)) {
|
||||
return $php_file;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
//function to check for running process: returns [running, pid, etime]
|
||||
if (!function_exists('is_running')) {
|
||||
/**
|
||||
* Checks if a process with the given name is currently running.
|
||||
*
|
||||
* @param string $name The name of the process to check for.
|
||||
*
|
||||
* @return array An array containing information about the process's status,
|
||||
* including whether it's running, its PID, and how long it's been running.
|
||||
*/
|
||||
function is_running(string $name) {
|
||||
$name = escapeshellarg($name);
|
||||
$pid = trim(shell_exec("ps -aux | grep $name | grep -v grep | awk '{print \$2}' | head -n 1") ?? '');
|
||||
if ($pid && is_numeric($pid)) {
|
||||
$etime = trim(shell_exec("ps -p $pid -o etime= | tr -d '\n'") ?? '');
|
||||
return ['running' => true, 'pid' => $pid, 'etime' => $etime];
|
||||
}
|
||||
return ['running' => false, 'pid' => null, 'etime' => null];
|
||||
}
|
||||
}
|
||||
|
||||
//function to format etime into friendly display
|
||||
if (!function_exists('format_etime')) {
|
||||
/**
|
||||
@@ -145,19 +100,17 @@
|
||||
|
||||
$files = glob(PROJECT_ROOT . '/*/*/resources/service/*.service');
|
||||
$services = [];
|
||||
$total_running = 0;
|
||||
|
||||
// load FusionPBX installed services
|
||||
// Group files by module directory so debian/freebsd variants are counted once.
|
||||
$grouped_service_files = [];
|
||||
foreach ($files as $file) {
|
||||
$service = get_classname($file);
|
||||
//check if the service name was found
|
||||
if (!empty($service)) {
|
||||
$basename = basename($service, '.php');
|
||||
$info = is_running($service);
|
||||
$info['label'] = $service_labels[$basename] ?? ucwords(str_replace('_', ' ', $basename));
|
||||
$services[$basename] = $info;
|
||||
if ($info['running']) $total_running++;
|
||||
$grouped_service_files[dirname($file)][] = $file;
|
||||
}
|
||||
|
||||
// load FusionPBX installed services using OS-specific class handling
|
||||
$system = system_information::new();
|
||||
if ($system !== null) {
|
||||
$services = $system->get_installed_services($grouped_service_files, $service_labels);
|
||||
}
|
||||
|
||||
// Get extra system services from default settings
|
||||
@@ -171,11 +124,10 @@
|
||||
// Loop through extra services if array is not empty
|
||||
if (!empty($extra_services)) {
|
||||
foreach ($extra_services as $extra) {
|
||||
if (!isset($services[$extra])) {
|
||||
$info = is_running($extra);
|
||||
if (!isset($services[$extra]) && $system !== null) {
|
||||
$info = $system->is_running($extra);
|
||||
$info['label'] = $service_labels[$extra] ?? ucwords($extra);
|
||||
$services[$extra] = $info;
|
||||
if ($info['running']) $total_running++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,6 +135,9 @@
|
||||
|
||||
//track total installed services for charts
|
||||
$total_services = count($services);
|
||||
$total_running = count(array_filter($services, function($service) {
|
||||
return !empty($service['running']);
|
||||
}));
|
||||
|
||||
//convert to a key
|
||||
$widget_key = str_replace(' ', '_', strtolower($widget_name));
|
||||
|
||||
Reference in New Issue
Block a user