Add vm-info script to gather VM info

This commit is contained in:
Josh Holtrop 2026-04-17 20:13:14 -04:00
parent 5773347bda
commit 34e984d563
2 changed files with 116 additions and 0 deletions

View File

@ -105,3 +105,34 @@ cp /var/www/malp/systemd/* /usr/lib/systemd/system
systemctl enable --now malpd.socket systemctl enable --now malpd.socket
systemctl enable --now malpd.service systemctl enable --now malpd.service
``` ```
### Virtual Machine Info
#### Generate SSH Key
On server host OS, generate an SSH key that will be used to gather information
from each running VM.
Leave the passphrase empty so it can be used non-interactively.
```
ssh-keygen -f /root/.ssh/malp-vm-key
```
#### malp user
On each VM to gather status information, add a `malp` user with:
```
useradd -m malp
```
Add a /home/malp/.ssh/authorized_keys file with content such as (replacing the
SSH key beginning with `ssh-ed25519`...):
```
command="/path/to/malp/bin/vm-info",no-port-forwarding,no-x11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3Nza...user@example.com
```
#### vm-info script
Make the `bin/vm-info` script available on each VM (via scp/rsync, NFS, etc...)

85
bin/vm-info Executable file
View File

@ -0,0 +1,85 @@
#!/usr/bin/env ruby
require "json"
def read_os_id
return nil unless File.exist?("/etc/os-release")
File.readlines("/etc/os-release").each do |line|
if line =~ /^ID=(.+)$/
return $1.strip.delete('"').downcase
end
end
nil
end
def read_os_name
return nil unless File.exist?("/etc/os-release")
File.readlines("/etc/os-release").each do |line|
if line =~ /^PRETTY_NAME="(.+)"$/
return $1.strip.delete('"').downcase
end
end
nil
end
def ubuntu_updates
out = `apt-get -s -o Debug::NoLocking=true upgrade 2>/dev/null`
count = 0
out.each_line do |line|
count += 1 if line.start_with?("Inst ")
end
count
end
def ubuntu_reboot_pending
File.exist?("/var/run/reboot-required")
end
def alma_updates
out = `dnf -q check-update 2>/dev/null`
status = $?.exitstatus
return 0 if status == 0
return nil unless status == 100
count = 0
out.each_line do |line|
line = line.strip
next if line.empty?
next if line.start_with?("Obsoleting", "Last metadata")
count += 1 if line.split(/\s+/).size >= 3
end
count
end
def alma_reboot_pending
`dnf needs-restarting -r >/dev/null 2>&1`
$?.exitstatus == 1
end
def df
df_out = `df -k /`
if df_out =~ /^\S+\s+(\d+)\s+(\d+)/
total, used = $1.to_i, $2.to_i
[total, used]
end
end
result = {}
if os = read_os_id
result["os"] = os
end
if os_name = read_os_name
result["os_name"] = os_name
end
case os
when "ubuntu", "debian"
result["updates"] = ubuntu_updates
result["reboot_pending"] = ubuntu_reboot_pending
when "almalinux", "rocky", "rhel", "centos", "fedora"
result["updates"] = alma_updates
result["reboot_pending"] = alma_reboot_pending
end
if df_info = df
result["df"] = df_info
end
puts JSON.generate(result)