Reorganize to allow file systems next to VMs, storage drives, and UPS cards

This commit is contained in:
Josh Holtrop 2026-04-19 22:56:45 -04:00
parent b78fb9469e
commit f037a97792

View File

@ -113,12 +113,13 @@ if cgi.params.key?("content")
filesystems = info.select { |e| e["type"] == "filesystem" } filesystems = info.select { |e| e["type"] == "filesystem" }
vms = info.select { |e| e["type"] == "vm" } vms = info.select { |e| e["type"] == "vm" }
html << %(<div class="span-3">)
if vms.any? if vms.any?
running = vms.count { |v| v["state"].to_s == "running" } running = vms.count { |v| v["state"].to_s == "running" }
total = vms.size total = vms.size
hdr_cls = running == total ? "ok" : running == 0 ? "bad" : "warn" hdr_cls = running == total ? "ok" : running == 0 ? "bad" : "warn"
html << %(<div class="span-3">)
html << %(<div class="section-label">Virtual Machines</div>) html << %(<div class="section-label">Virtual Machines</div>)
html << <<~HTML html << <<~HTML
<div class="card #{hdr_cls}"> <div class="card #{hdr_cls}">
@ -202,7 +203,6 @@ if cgi.params.key?("content")
end end
html << %(</div></div>) html << %(</div></div>)
html << %(</div>)
end end
thousands = ->(n) { n.to_s.gsub(/(\d)(?=(\d{3})+$)/, '\1,') } thousands = ->(n) { n.to_s.gsub(/(\d)(?=(\d{3})+$)/, '\1,') }
@ -253,8 +253,13 @@ if cgi.params.key?("content")
stats stats
end end
upses = info.select { |e| e["type"] == "ups" }
if drives.any? || upses.any?
html << %(<div style="display:grid;grid-template-columns:2fr 1fr;gap:1rem;align-items:start;margin-top:1rem;">)
end
if drives.any? if drives.any?
html << %(<div class="span-2">) html << %(<div>)
html << %(<div class="section-label">Storage Drives</div>) html << %(<div class="section-label">Storage Drives</div>)
html << %(<div class="stack">) html << %(<div class="stack">)
drives.each do |entry| drives.each do |entry|
@ -291,6 +296,61 @@ if cgi.params.key?("content")
html << %(</div>) html << %(</div>)
end end
upses.each do |ups|
status = ups["status"].to_s
online = status.include?("ONLINE")
card_cls = online ? "ok" : "bad"
model = ups["model"] ? "APC " + CGI.escapeHTML(ups["model"]) : "UPS"
stats = []
stats << [online ? "ok" : "bad", CGI.escapeHTML(status)] unless status.empty?
if (charge = ups["charge"])
cls = charge >= 80 ? "ok" : charge >= 50 ? "warn" : "bad"
stats << [cls, "Charge #{charge.round}%"]
end
if (timeleft = ups["timeleft"])
cls = timeleft >= 10 ? "ok" : timeleft >= 5 ? "warn" : "bad"
stats << [cls, "#{timeleft.round(1)} min left"]
end
if (load = ups["load"])
cls = load >= 90 ? "bad" : load >= 70 ? "warn" : "ok"
stats << [cls, "Load #{load.round}%"]
end
if (lv = ups["line_voltage"])
stats << ["ok", "Line #{lv.round} V"]
end
if (bv = ups["battery_voltage"])
stats << ["ok", "Batt #{bv.round(1)} V"]
end
stats_html = stats.map { |c, txt|
%(<span class="stat #{c}">#{txt}</span>)
}.join
stats_block = stats.empty? ? "" :
%(<div class="drive-stats" style="margin-top:0.6rem;">#{stats_html}</div>)
html << %(<div>)
html << %(<div class="section-label">UPS</div>)
html << <<~HTML
<div class="card #{card_cls}">
<div class="card-header">
<span class="card-title">#{model}</span>
<span class="badge #{card_cls}">#{online ? "Online" : CGI.escapeHTML(status)}</span>
</div>
#{stats_block}
</div>
HTML
html << %(</div>)
end
if drives.any? || upses.any?
html << %(</div>)
end
html << %(</div>)
if filesystems.any? if filesystems.any?
html << %(<div>) html << %(<div>)
html << %(<div class="section-label">File Systems</div>) html << %(<div class="section-label">File Systems</div>)
@ -346,56 +406,6 @@ if cgi.params.key?("content")
html << %(</div>) html << %(</div>)
end end
upses = info.select { |e| e["type"] == "ups" }
upses.each do |ups|
status = ups["status"].to_s
online = status.include?("ONLINE")
card_cls = online ? "ok" : "bad"
model = ups["model"] ? "APC " + CGI.escapeHTML(ups["model"]) : "UPS"
stats = []
stats << [online ? "ok" : "bad", CGI.escapeHTML(status)] unless status.empty?
if (charge = ups["charge"])
cls = charge >= 80 ? "ok" : charge >= 50 ? "warn" : "bad"
stats << [cls, "Charge #{charge.round}%"]
end
if (timeleft = ups["timeleft"])
cls = timeleft >= 10 ? "ok" : timeleft >= 5 ? "warn" : "bad"
stats << [cls, "#{timeleft.round(1)} min left"]
end
if (load = ups["load"])
cls = load >= 90 ? "bad" : load >= 70 ? "warn" : "ok"
stats << [cls, "Load #{load.round}%"]
end
if (lv = ups["line_voltage"])
stats << ["ok", "Line #{lv.round} V"]
end
if (bv = ups["battery_voltage"])
stats << ["ok", "Batt #{bv.round(1)} V"]
end
stats_html = stats.map { |c, txt|
%(<span class="stat #{c}">#{txt}</span>)
}.join
stats_block = stats.empty? ? "" :
%(<div class="drive-stats" style="margin-top:0.6rem;">#{stats_html}</div>)
html << %(<div>)
html << %(<div class="section-label">UPS</div>)
html << <<~HTML
<div class="card #{card_cls}">
<div class="card-header">
<span class="card-title">#{model}</span>
<span class="badge #{card_cls}">#{online ? "Online" : CGI.escapeHTML(status)}</span>
</div>
#{stats_block}
</div>
HTML
html << %(</div>)
end
cgi.out("type" => "text/html", "charset" => "UTF-8") do cgi.out("type" => "text/html", "charset" => "UTF-8") do
html html
end end