From e827587c1b9eabbcb0170eaf38f46f43b9b842d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucian=20V=C4=83c=C4=83roiu?= Date: Mon, 10 Nov 2025 19:36:06 +0200 Subject: [PATCH 1/6] feat: add hardware server info --- app/Traits/ServersTrait.php | 32 +++++++++++++++++++ playbooks/server-info.sh | 64 +++++++++++++++++++++++++++++++++---- 2 files changed, 90 insertions(+), 6 deletions(-) diff --git a/app/Traits/ServersTrait.php b/app/Traits/ServersTrait.php index 8ebc55fe..3e77346c 100644 --- a/app/Traits/ServersTrait.php +++ b/app/Traits/ServersTrait.php @@ -144,6 +144,38 @@ protected function displayServerInfo(array $info): void $this->io->displayDeets($deets); $this->io->writeln(''); + // Display hardware information if available + if (isset($info['hardware']) && is_array($info['hardware'])) { + $hardwareItems = []; + + if (isset($info['hardware']['cpu_cores'])) { + /** @var int|string $cpuCores */ + $cpuCores = $info['hardware']['cpu_cores']; + $coresText = $cpuCores === '1' || $cpuCores === 1 ? '1 core' : "{$cpuCores} cores"; + $hardwareItems[] = "CPU: {$coresText}"; + } + + if (isset($info['hardware']['ram_mb'])) { + /** @var int|string $ramMb */ + $ramMb = $info['hardware']['ram_mb']; + $ramGb = round((int) $ramMb / 1024, 1); + $ramText = $ramGb >= 1 ? "{$ramGb} GB" : "{$ramMb} MB"; + $hardwareItems[] = "RAM: {$ramText}"; + } + + if (isset($info['hardware']['disk_type'])) { + /** @var string $diskType */ + $diskType = $info['hardware']['disk_type']; + $diskText = strtoupper($diskType); + $hardwareItems[] = "Disk: {$diskText}"; + } + + if (count($hardwareItems) > 0) { + $this->io->displayDeets(['Hardware' => $hardwareItems]); + $this->io->writeln(''); + } + } + $services = []; // Add listening ports if any diff --git a/playbooks/server-info.sh b/playbooks/server-info.sh index fde041fa..14151ccb 100755 --- a/playbooks/server-info.sh +++ b/playbooks/server-info.sh @@ -143,22 +143,64 @@ ensure_tools() { local family=$1 perms=$2 export DEPLOYER_PERMS=$perms - # If the command is already installed, return - command -v ss > /dev/null 2>&1 && return 0 - command -v netstat > /dev/null 2>&1 && return 0 + # Check if required tools exist + command -v ss > /dev/null 2>&1 && command -v lsblk > /dev/null 2>&1 && return 0 case $family in debian) run_cmd apt-get update -q 2> /dev/null - run_cmd apt-get install -y -q iproute2 2> /dev/null + run_cmd apt-get install -y -q iproute2 util-linux 2> /dev/null ;; fedora | redhat | amazon) - run_cmd yum install -y -q iproute 2> /dev/null \ - || run_cmd dnf install -y -q iproute 2> /dev/null + run_cmd yum install -y -q iproute util-linux 2> /dev/null \ + || run_cmd dnf install -y -q iproute util-linux 2> /dev/null ;; esac } +# +# Hardware Detection +# ---- + +# +# Detect CPU core count + +detect_cpu_cores() { + nproc 2> /dev/null || echo "1" +} + +# +# Detect total system RAM in MB + +detect_ram_mb() { + free -m 2> /dev/null | awk 'NR==2 {print $2}' || echo "512" +} + +# +# Detect disk type (ssd or hdd) + +detect_disk_type() { + local disc_gran rotation + + # Primary detection: Check discard granularity (TRIM support = SSD) + # Works reliably in virtualized environments (cloud VMs) + disc_gran=$(lsblk -d -o name,disc-gran 2> /dev/null | grep -E "^[sv]da" | head -n1 | awk '{print $2}') + + # If disc-gran is non-zero (e.g., "512B"), it's an SSD + if [[ -n $disc_gran && $disc_gran != "0B" ]]; then + echo "ssd" + return + fi + + # Fallback: Check rotation flag (works for physical disks) + rotation=$(lsblk -d -o name,rota 2> /dev/null | grep -E "^[sv]da" | head -n1 | awk '{print $2}') + if [[ $rotation == "0" ]]; then + echo "ssd" + else + echo "hdd" + fi +} + # ---- # Service Metrics # ---- @@ -332,6 +374,7 @@ get_php_fpm_metrics() { main() { local distro family permissions + local cpu_cores ram_mb disk_type # # Gather basic info @@ -343,6 +386,11 @@ main() { echo "✓ Checking permissions..." permissions=$(check_permissions) + echo "✓ Detecting hardware..." + cpu_cores=$(detect_cpu_cores) + ram_mb=$(detect_ram_mb) + disk_type=$(detect_disk_type) + echo "✓ Cataloging services..." ensure_tools "$family" "$permissions" @@ -374,6 +422,10 @@ main() { distro: $distro family: $family permissions: $permissions + hardware: + cpu_cores: $cpu_cores + ram_mb: $ram_mb + disk_type: $disk_type caddy: available: $caddy_available version: ${caddy_version:-unknown} From d7cc47621214cdc0f4ea6240b271cd72c9d89acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucian=20V=C4=83c=C4=83roiu?= Date: Mon, 10 Nov 2025 19:44:59 +0200 Subject: [PATCH 2/6] refactor(server-info): add nvme support --- playbooks/server-info.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/playbooks/server-info.sh b/playbooks/server-info.sh index 14151ccb..bc3f5cc7 100755 --- a/playbooks/server-info.sh +++ b/playbooks/server-info.sh @@ -184,7 +184,7 @@ detect_disk_type() { # Primary detection: Check discard granularity (TRIM support = SSD) # Works reliably in virtualized environments (cloud VMs) - disc_gran=$(lsblk -d -o name,disc-gran 2> /dev/null | grep -E "^[sv]da" | head -n1 | awk '{print $2}') + disc_gran=$(lsblk -d -o name,disc-gran 2> /dev/null | grep -E "^([sv]da|nvme)" | head -n1 | awk '{print $2}') # If disc-gran is non-zero (e.g., "512B"), it's an SSD if [[ -n $disc_gran && $disc_gran != "0B" ]]; then @@ -193,7 +193,7 @@ detect_disk_type() { fi # Fallback: Check rotation flag (works for physical disks) - rotation=$(lsblk -d -o name,rota 2> /dev/null | grep -E "^[sv]da" | head -n1 | awk '{print $2}') + rotation=$(lsblk -d -o name,rota 2> /dev/null | grep -E "^([sv]da|nvme)" | head -n1 | awk '{print $2}') if [[ $rotation == "0" ]]; then echo "ssd" else From 537f00ec5e2ec9ef2299077054b22021f1c0d8d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucian=20V=C4=83c=C4=83roiu?= Date: Mon, 10 Nov 2025 19:57:01 +0200 Subject: [PATCH 3/6] fix(server-info): ensure tools are installed before hardware detection Reorder ensure_tools() execution before detect_disk_type() to prevent silent fallback to incorrect 'hdd' default when lsblk is not available. --- playbooks/server-info.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/playbooks/server-info.sh b/playbooks/server-info.sh index bc3f5cc7..54c0d1ab 100755 --- a/playbooks/server-info.sh +++ b/playbooks/server-info.sh @@ -386,14 +386,14 @@ main() { echo "✓ Checking permissions..." permissions=$(check_permissions) + echo "✓ Cataloging services..." + ensure_tools "$family" "$permissions" + echo "✓ Detecting hardware..." cpu_cores=$(detect_cpu_cores) ram_mb=$(detect_ram_mb) disk_type=$(detect_disk_type) - echo "✓ Cataloging services..." - ensure_tools "$family" "$permissions" - echo "✓ Checking Caddy status..." local caddy_metrics caddy_available="false" local caddy_version caddy_sites caddy_domains caddy_uptime caddy_active_req caddy_total_req caddy_memory From b84d8eb64858858c1394dbe25032f515b600eaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucian=20V=C4=83c=C4=83roiu?= Date: Mon, 10 Nov 2025 20:05:33 +0200 Subject: [PATCH 4/6] docs(playbook): update server-info header to include hardware Add hardware detection to script description and YAML output documentation. The playbook now detects cpu_cores, ram_mb, and disk_type. --- playbooks/server-info.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/playbooks/server-info.sh b/playbooks/server-info.sh index 54c0d1ab..be281a46 100755 --- a/playbooks/server-info.sh +++ b/playbooks/server-info.sh @@ -2,7 +2,7 @@ # # Gather Server Information # ---- -# This playbook detects distribution, family, permissions, listening services, Caddy metrics, and PHP-FPM metrics. +# This playbook detects distribution, family, permissions, hardware info, listening services, Caddy metrics, and PHP-FPM metrics. # # Required Environment Variables: # DEPLOYER_OUTPUT_FILE - Output file path (provided automatically) @@ -11,6 +11,7 @@ # - distro: ubuntu|debian|fedora|centos|rocky|alma|rhel|amazon|unknown # - family: debian|fedora|redhat|amazon|unknown # - permissions: root|sudo|none +# - hardware: cpu_cores, ram_mb, disk_type # - caddy: Caddy metrics (available, version, sites_count, domains, uptime_seconds, active_requests, total_requests, memory_mb) # - php_fpm: PHP-FPM metrics (available, pool, process_manager, uptime_seconds, accepted_conn, listen_queue, idle_processes, active_processes, total_processes, max_children_reached, slow_requests) # - ports: map of port numbers to process names From 5252802a3d07bc799df3531659ae617d3c9fb0af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucian=20V=C4=83c=C4=83roiu?= Date: Mon, 10 Nov 2025 20:05:45 +0200 Subject: [PATCH 5/6] fix(playbook): expand disk detection regex to match all disk types Change pattern from ^([sv]da|nvme) to ^([sv]d|nvme) to detect all SATA and virtio disks (sdb, sdc, vdb, vdc, etc.), not just the first disk. --- playbooks/server-info.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/playbooks/server-info.sh b/playbooks/server-info.sh index be281a46..fc903902 100755 --- a/playbooks/server-info.sh +++ b/playbooks/server-info.sh @@ -185,7 +185,7 @@ detect_disk_type() { # Primary detection: Check discard granularity (TRIM support = SSD) # Works reliably in virtualized environments (cloud VMs) - disc_gran=$(lsblk -d -o name,disc-gran 2> /dev/null | grep -E "^([sv]da|nvme)" | head -n1 | awk '{print $2}') + disc_gran=$(lsblk -d -o name,disc-gran 2> /dev/null | grep -E "^([sv]d|nvme)" | head -n1 | awk '{print $2}') # If disc-gran is non-zero (e.g., "512B"), it's an SSD if [[ -n $disc_gran && $disc_gran != "0B" ]]; then @@ -194,7 +194,7 @@ detect_disk_type() { fi # Fallback: Check rotation flag (works for physical disks) - rotation=$(lsblk -d -o name,rota 2> /dev/null | grep -E "^([sv]da|nvme)" | head -n1 | awk '{print $2}') + rotation=$(lsblk -d -o name,rota 2> /dev/null | grep -E "^([sv]d|nvme)" | head -n1 | awk '{print $2}') if [[ $rotation == "0" ]]; then echo "ssd" else From 14ef900a234b73e4135c61f6a17f536a620e5ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucian=20V=C4=83c=C4=83roiu?= Date: Mon, 10 Nov 2025 20:13:30 +0200 Subject: [PATCH 6/6] fixup: typo --- playbooks/server-info.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/playbooks/server-info.sh b/playbooks/server-info.sh index fc903902..d7ee95a4 100755 --- a/playbooks/server-info.sh +++ b/playbooks/server-info.sh @@ -181,14 +181,14 @@ detect_ram_mb() { # Detect disk type (ssd or hdd) detect_disk_type() { - local disc_gran rotation + local disk_gran rotation # Primary detection: Check discard granularity (TRIM support = SSD) # Works reliably in virtualized environments (cloud VMs) - disc_gran=$(lsblk -d -o name,disc-gran 2> /dev/null | grep -E "^([sv]d|nvme)" | head -n1 | awk '{print $2}') + disk_gran=$(lsblk -d -o name,disc-gran 2> /dev/null | grep -E "^([sv]d|nvme)" | head -n1 | awk '{print $2}') # If disc-gran is non-zero (e.g., "512B"), it's an SSD - if [[ -n $disc_gran && $disc_gran != "0B" ]]; then + if [[ -n $disk_gran && $disk_gran != "0B" ]]; then echo "ssd" return fi