mirror of
https://github.com/uprightbass360/AzerothCore-RealmMaster.git
synced 2026-01-13 00:58:34 +00:00
status info
This commit is contained in:
@@ -9,6 +9,10 @@ from pathlib import Path
|
|||||||
|
|
||||||
PROJECT_DIR = Path(__file__).resolve().parents[2]
|
PROJECT_DIR = Path(__file__).resolve().parents[2]
|
||||||
ENV_FILE = PROJECT_DIR / ".env"
|
ENV_FILE = PROJECT_DIR / ".env"
|
||||||
|
DEFAULT_ACORE_STANDARD_REPO = "https://github.com/azerothcore/azerothcore-wotlk.git"
|
||||||
|
DEFAULT_ACORE_PLAYERBOTS_REPO = "https://github.com/mod-playerbots/azerothcore-wotlk.git"
|
||||||
|
DEFAULT_ACORE_STANDARD_BRANCH = "master"
|
||||||
|
DEFAULT_ACORE_PLAYERBOTS_BRANCH = "Playerbot"
|
||||||
|
|
||||||
def load_env():
|
def load_env():
|
||||||
env = {}
|
env = {}
|
||||||
@@ -150,6 +154,195 @@ def volume_info(name, fallback=None):
|
|||||||
pass
|
pass
|
||||||
return {"name": name, "exists": False, "mountpoint": "-"}
|
return {"name": name, "exists": False, "mountpoint": "-"}
|
||||||
|
|
||||||
|
def detect_source_variant(env):
|
||||||
|
variant = read_env(env, "STACK_SOURCE_VARIANT", "").strip().lower()
|
||||||
|
if variant in ("playerbots", "playerbot"):
|
||||||
|
return "playerbots"
|
||||||
|
if variant == "core":
|
||||||
|
return "core"
|
||||||
|
if read_env(env, "STACK_IMAGE_MODE", "").strip().lower() == "playerbots":
|
||||||
|
return "playerbots"
|
||||||
|
if read_env(env, "MODULE_PLAYERBOTS", "0") == "1" or read_env(env, "PLAYERBOT_ENABLED", "0") == "1":
|
||||||
|
return "playerbots"
|
||||||
|
return "core"
|
||||||
|
|
||||||
|
def repo_config_for_variant(env, variant):
|
||||||
|
if variant == "playerbots":
|
||||||
|
repo = read_env(env, "ACORE_REPO_PLAYERBOTS", DEFAULT_ACORE_PLAYERBOTS_REPO)
|
||||||
|
branch = read_env(env, "ACORE_BRANCH_PLAYERBOTS", DEFAULT_ACORE_PLAYERBOTS_BRANCH)
|
||||||
|
else:
|
||||||
|
repo = read_env(env, "ACORE_REPO_STANDARD", DEFAULT_ACORE_STANDARD_REPO)
|
||||||
|
branch = read_env(env, "ACORE_BRANCH_STANDARD", DEFAULT_ACORE_STANDARD_BRANCH)
|
||||||
|
return repo, branch
|
||||||
|
|
||||||
|
def image_labels(image):
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
["docker", "image", "inspect", "--format", "{{json .Config.Labels}}", image],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True,
|
||||||
|
timeout=3,
|
||||||
|
)
|
||||||
|
labels = json.loads(result.stdout or "{}")
|
||||||
|
if isinstance(labels, dict):
|
||||||
|
return {k: (v or "").strip() for k, v in labels.items()}
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def first_label(labels, keys):
|
||||||
|
for key in keys:
|
||||||
|
value = labels.get(key, "")
|
||||||
|
if value:
|
||||||
|
return value
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def short_commit(commit):
|
||||||
|
commit = commit.strip()
|
||||||
|
if re.fullmatch(r"[0-9a-fA-F]{12,}", commit):
|
||||||
|
return commit[:12]
|
||||||
|
return commit
|
||||||
|
|
||||||
|
def git_info_from_path(path):
|
||||||
|
repo_path = Path(path)
|
||||||
|
if not (repo_path / ".git").exists():
|
||||||
|
return None
|
||||||
|
|
||||||
|
def run_git(args):
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
["git"] + args,
|
||||||
|
cwd=repo_path,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
return result.stdout.strip()
|
||||||
|
except Exception:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
commit = run_git(["rev-parse", "HEAD"])
|
||||||
|
if not commit:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return {
|
||||||
|
"commit": commit,
|
||||||
|
"commit_short": run_git(["rev-parse", "--short", "HEAD"]) or short_commit(commit),
|
||||||
|
"date": run_git(["log", "-1", "--format=%cd", "--date=iso-strict"]),
|
||||||
|
"repo": run_git(["remote", "get-url", "origin"]),
|
||||||
|
"branch": run_git(["rev-parse", "--abbrev-ref", "HEAD"]),
|
||||||
|
"path": str(repo_path),
|
||||||
|
}
|
||||||
|
|
||||||
|
def candidate_source_paths(env, variant):
|
||||||
|
paths = []
|
||||||
|
for key in ("MODULES_REBUILD_SOURCE_PATH", "SOURCE_DIR"):
|
||||||
|
value = read_env(env, key, "")
|
||||||
|
if value:
|
||||||
|
paths.append(value)
|
||||||
|
|
||||||
|
local_root = read_env(env, "STORAGE_PATH_LOCAL", "./local-storage")
|
||||||
|
primary_dir = "azerothcore-playerbots" if variant == "playerbots" else "azerothcore"
|
||||||
|
fallback_dir = "azerothcore" if variant == "playerbots" else "azerothcore-playerbots"
|
||||||
|
paths.append(os.path.join(local_root, "source", primary_dir))
|
||||||
|
paths.append(os.path.join(local_root, "source", fallback_dir))
|
||||||
|
|
||||||
|
normalized = []
|
||||||
|
for p in paths:
|
||||||
|
expanded = expand_path(p, env)
|
||||||
|
try:
|
||||||
|
normalized.append(str(Path(expanded).expanduser().resolve()))
|
||||||
|
except Exception:
|
||||||
|
normalized.append(str(Path(expanded).expanduser()))
|
||||||
|
# Deduplicate while preserving order
|
||||||
|
seen = set()
|
||||||
|
unique_paths = []
|
||||||
|
for p in normalized:
|
||||||
|
if p not in seen:
|
||||||
|
seen.add(p)
|
||||||
|
unique_paths.append(p)
|
||||||
|
return unique_paths
|
||||||
|
|
||||||
|
def build_info(service_data, env):
|
||||||
|
variant = detect_source_variant(env)
|
||||||
|
repo, branch = repo_config_for_variant(env, variant)
|
||||||
|
info = {
|
||||||
|
"variant": variant,
|
||||||
|
"repo": repo,
|
||||||
|
"branch": branch,
|
||||||
|
"image": "",
|
||||||
|
"commit": "",
|
||||||
|
"commit_date": "",
|
||||||
|
"commit_source": "",
|
||||||
|
"source_path": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
image_candidates = []
|
||||||
|
for svc in service_data:
|
||||||
|
if svc.get("name") in ("ac-worldserver", "ac-authserver", "ac-db-import"):
|
||||||
|
image = svc.get("image") or ""
|
||||||
|
if image:
|
||||||
|
image_candidates.append(image)
|
||||||
|
|
||||||
|
for env_key in (
|
||||||
|
"AC_WORLDSERVER_IMAGE_PLAYERBOTS",
|
||||||
|
"AC_WORLDSERVER_IMAGE_MODULES",
|
||||||
|
"AC_WORLDSERVER_IMAGE",
|
||||||
|
"AC_AUTHSERVER_IMAGE_PLAYERBOTS",
|
||||||
|
"AC_AUTHSERVER_IMAGE_MODULES",
|
||||||
|
"AC_AUTHSERVER_IMAGE",
|
||||||
|
):
|
||||||
|
value = read_env(env, env_key, "")
|
||||||
|
if value:
|
||||||
|
image_candidates.append(value)
|
||||||
|
|
||||||
|
seen = set()
|
||||||
|
deduped_images = []
|
||||||
|
for img in image_candidates:
|
||||||
|
if img not in seen:
|
||||||
|
seen.add(img)
|
||||||
|
deduped_images.append(img)
|
||||||
|
|
||||||
|
commit_label_keys = [
|
||||||
|
"build.source_commit",
|
||||||
|
"org.opencontainers.image.revision",
|
||||||
|
"org.opencontainers.image.version",
|
||||||
|
]
|
||||||
|
date_label_keys = [
|
||||||
|
"build.source_date",
|
||||||
|
"org.opencontainers.image.created",
|
||||||
|
"build.timestamp",
|
||||||
|
]
|
||||||
|
|
||||||
|
for image in deduped_images:
|
||||||
|
labels = image_labels(image)
|
||||||
|
if not info["image"]:
|
||||||
|
info["image"] = image
|
||||||
|
if not labels:
|
||||||
|
continue
|
||||||
|
commit = short_commit(first_label(labels, commit_label_keys))
|
||||||
|
date = first_label(labels, date_label_keys)
|
||||||
|
if commit or date:
|
||||||
|
info["commit"] = commit
|
||||||
|
info["commit_date"] = date
|
||||||
|
info["commit_source"] = "image-label"
|
||||||
|
info["image"] = image
|
||||||
|
return info
|
||||||
|
|
||||||
|
for path in candidate_source_paths(env, variant):
|
||||||
|
git_meta = git_info_from_path(path)
|
||||||
|
if git_meta:
|
||||||
|
info["commit"] = git_meta.get("commit_short") or short_commit(git_meta.get("commit", ""))
|
||||||
|
info["commit_date"] = git_meta.get("date", "")
|
||||||
|
info["commit_source"] = "source-tree"
|
||||||
|
info["source_path"] = git_meta.get("path", "")
|
||||||
|
info["repo"] = git_meta.get("repo") or info["repo"]
|
||||||
|
info["branch"] = git_meta.get("branch") or info["branch"]
|
||||||
|
return info
|
||||||
|
|
||||||
|
return info
|
||||||
|
|
||||||
def expand_path(value, env):
|
def expand_path(value, env):
|
||||||
storage = read_env(env, "STORAGE_PATH", "./storage")
|
storage = read_env(env, "STORAGE_PATH", "./storage")
|
||||||
local_storage = read_env(env, "STORAGE_PATH_LOCAL", "./local-storage")
|
local_storage = read_env(env, "STORAGE_PATH_LOCAL", "./local-storage")
|
||||||
@@ -274,6 +467,8 @@ def main():
|
|||||||
"mysql_data": volume_info(f"{project}_mysql-data", "mysql-data"),
|
"mysql_data": volume_info(f"{project}_mysql-data", "mysql-data"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build = build_info(service_data, env)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
||||||
"project": project,
|
"project": project,
|
||||||
@@ -285,6 +480,7 @@ def main():
|
|||||||
"volumes": volumes,
|
"volumes": volumes,
|
||||||
"users": user_stats(env),
|
"users": user_stats(env),
|
||||||
"stats": docker_stats(),
|
"stats": docker_stats(),
|
||||||
|
"build": build,
|
||||||
}
|
}
|
||||||
|
|
||||||
print(json.dumps(data))
|
print(json.dumps(data))
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -61,6 +63,17 @@ type Module struct {
|
|||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BuildInfo struct {
|
||||||
|
Variant string `json:"variant"`
|
||||||
|
Repo string `json:"repo"`
|
||||||
|
Branch string `json:"branch"`
|
||||||
|
Image string `json:"image"`
|
||||||
|
Commit string `json:"commit"`
|
||||||
|
CommitDate string `json:"commit_date"`
|
||||||
|
CommitSource string `json:"commit_source"`
|
||||||
|
SourcePath string `json:"source_path"`
|
||||||
|
}
|
||||||
|
|
||||||
type Snapshot struct {
|
type Snapshot struct {
|
||||||
Timestamp string `json:"timestamp"`
|
Timestamp string `json:"timestamp"`
|
||||||
Project string `json:"project"`
|
Project string `json:"project"`
|
||||||
@@ -72,6 +85,7 @@ type Snapshot struct {
|
|||||||
Volumes map[string]VolumeInfo `json:"volumes"`
|
Volumes map[string]VolumeInfo `json:"volumes"`
|
||||||
Users UserStats `json:"users"`
|
Users UserStats `json:"users"`
|
||||||
Stats map[string]ContainerStats `json:"stats"`
|
Stats map[string]ContainerStats `json:"stats"`
|
||||||
|
Build BuildInfo `json:"build"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var persistentServiceOrder = []string{
|
var persistentServiceOrder = []string{
|
||||||
@@ -84,6 +98,81 @@ var persistentServiceOrder = []string{
|
|||||||
"ac-backup",
|
"ac-backup",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func humanDuration(d time.Duration) string {
|
||||||
|
if d < time.Minute {
|
||||||
|
return "<1m"
|
||||||
|
}
|
||||||
|
days := d / (24 * time.Hour)
|
||||||
|
d -= days * 24 * time.Hour
|
||||||
|
hours := d / time.Hour
|
||||||
|
d -= hours * time.Hour
|
||||||
|
mins := d / time.Minute
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case days > 0:
|
||||||
|
return fmt.Sprintf("%dd %dh", days, hours)
|
||||||
|
case hours > 0:
|
||||||
|
return fmt.Sprintf("%dh %dm", hours, mins)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("%dm", mins)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatUptime(startedAt string) string {
|
||||||
|
if startedAt == "" {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
parsed, err := time.Parse(time.RFC3339Nano, startedAt)
|
||||||
|
if err != nil {
|
||||||
|
parsed, err = time.Parse(time.RFC3339, startedAt)
|
||||||
|
if err != nil {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if parsed.IsZero() {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
uptime := time.Since(parsed)
|
||||||
|
if uptime < 0 {
|
||||||
|
uptime = 0
|
||||||
|
}
|
||||||
|
return humanDuration(uptime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func primaryIPv4() string {
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
for _, iface := range ifaces {
|
||||||
|
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addrs, err := iface.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var ip net.IP
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
ip = v.IP
|
||||||
|
case *net.IPAddr:
|
||||||
|
ip = v.IP
|
||||||
|
}
|
||||||
|
if ip == nil || ip.IsLoopback() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ip = ip.To4()
|
||||||
|
if ip == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return ip.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func runSnapshot() (*Snapshot, error) {
|
func runSnapshot() (*Snapshot, error) {
|
||||||
cmd := exec.Command("./scripts/bash/statusjson.sh")
|
cmd := exec.Command("./scripts/bash/statusjson.sh")
|
||||||
output, err := cmd.Output()
|
output, err := cmd.Output()
|
||||||
@@ -126,8 +215,8 @@ func buildServicesTable(s *Snapshot) *TableNoCol {
|
|||||||
runningServices, setupServices := partitionServices(s.Services)
|
runningServices, setupServices := partitionServices(s.Services)
|
||||||
|
|
||||||
table := NewTableNoCol()
|
table := NewTableNoCol()
|
||||||
rows := [][]string{{"Group", "Service", "Status", "Health", "CPU%", "Memory"}}
|
rows := [][]string{{"Service", "Status", "Health", "Uptime", "CPU%", "Memory"}}
|
||||||
appendRows := func(groupLabel string, services []Service) {
|
appendRows := func(services []Service) {
|
||||||
for _, svc := range services {
|
for _, svc := range services {
|
||||||
cpu := "-"
|
cpu := "-"
|
||||||
mem := "-"
|
mem := "-"
|
||||||
@@ -139,12 +228,12 @@ func buildServicesTable(s *Snapshot) *TableNoCol {
|
|||||||
if svc.Status != "running" && svc.ExitCode != "0" && svc.ExitCode != "" {
|
if svc.Status != "running" && svc.ExitCode != "0" && svc.ExitCode != "" {
|
||||||
health = fmt.Sprintf("%s (%s)", svc.Health, svc.ExitCode)
|
health = fmt.Sprintf("%s (%s)", svc.Health, svc.ExitCode)
|
||||||
}
|
}
|
||||||
rows = append(rows, []string{groupLabel, svc.Label, svc.Status, health, cpu, mem})
|
rows = append(rows, []string{svc.Label, svc.Status, health, formatUptime(svc.StartedAt), cpu, mem})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
appendRows("Persistent", runningServices)
|
appendRows(runningServices)
|
||||||
appendRows("Setup", setupServices)
|
appendRows(setupServices)
|
||||||
|
|
||||||
table.Rows = rows
|
table.Rows = rows
|
||||||
table.RowSeparator = false
|
table.RowSeparator = false
|
||||||
@@ -223,9 +312,11 @@ func buildStorageParagraph(s *Snapshot) *widgets.Paragraph {
|
|||||||
}
|
}
|
||||||
par := widgets.NewParagraph()
|
par := widgets.NewParagraph()
|
||||||
par.Title = "Storage"
|
par.Title = "Storage"
|
||||||
par.Text = b.String()
|
par.Text = strings.TrimRight(b.String(), "\n")
|
||||||
par.Border = true
|
par.Border = true
|
||||||
par.BorderStyle = ui.NewStyle(ui.ColorYellow)
|
par.BorderStyle = ui.NewStyle(ui.ColorYellow)
|
||||||
|
par.PaddingLeft = 0
|
||||||
|
par.PaddingRight = 0
|
||||||
return par
|
return par
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,13 +338,75 @@ func buildVolumesParagraph(s *Snapshot) *widgets.Paragraph {
|
|||||||
}
|
}
|
||||||
par := widgets.NewParagraph()
|
par := widgets.NewParagraph()
|
||||||
par.Title = "Volumes"
|
par.Title = "Volumes"
|
||||||
par.Text = b.String()
|
par.Text = strings.TrimRight(b.String(), "\n")
|
||||||
|
par.Border = true
|
||||||
|
par.BorderStyle = ui.NewStyle(ui.ColorYellow)
|
||||||
|
par.PaddingLeft = 0
|
||||||
|
par.PaddingRight = 0
|
||||||
|
return par
|
||||||
|
}
|
||||||
|
|
||||||
|
func simplifyRepo(repo string) string {
|
||||||
|
repo = strings.TrimSpace(repo)
|
||||||
|
repo = strings.TrimSuffix(repo, ".git")
|
||||||
|
repo = strings.TrimPrefix(repo, "https://")
|
||||||
|
repo = strings.TrimPrefix(repo, "http://")
|
||||||
|
repo = strings.TrimPrefix(repo, "git@")
|
||||||
|
repo = strings.TrimPrefix(repo, "github.com:")
|
||||||
|
repo = strings.TrimPrefix(repo, "gitlab.com:")
|
||||||
|
repo = strings.TrimPrefix(repo, "github.com/")
|
||||||
|
repo = strings.TrimPrefix(repo, "gitlab.com/")
|
||||||
|
return repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildInfoParagraph(s *Snapshot) *widgets.Paragraph {
|
||||||
|
build := s.Build
|
||||||
|
var lines []string
|
||||||
|
|
||||||
|
if build.Branch != "" {
|
||||||
|
lines = append(lines, fmt.Sprintf("Branch: %s", build.Branch))
|
||||||
|
}
|
||||||
|
|
||||||
|
if repo := simplifyRepo(build.Repo); repo != "" {
|
||||||
|
lines = append(lines, fmt.Sprintf("Repo: %s", repo))
|
||||||
|
}
|
||||||
|
|
||||||
|
commitLine := "Git: unknown"
|
||||||
|
if build.Commit != "" {
|
||||||
|
commitLine = fmt.Sprintf("Git: %s", build.Commit)
|
||||||
|
switch build.CommitSource {
|
||||||
|
case "image-label":
|
||||||
|
commitLine += " [image]"
|
||||||
|
case "source-tree":
|
||||||
|
commitLine += " [source]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lines = append(lines, commitLine)
|
||||||
|
|
||||||
|
if build.Image != "" {
|
||||||
|
// Skip image line to keep header compact
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = append(lines, fmt.Sprintf("Updated: %s", s.Timestamp))
|
||||||
|
|
||||||
|
par := widgets.NewParagraph()
|
||||||
|
par.Title = "Build"
|
||||||
|
par.Text = strings.Join(lines, "\n")
|
||||||
par.Border = true
|
par.Border = true
|
||||||
par.BorderStyle = ui.NewStyle(ui.ColorYellow)
|
par.BorderStyle = ui.NewStyle(ui.ColorYellow)
|
||||||
return par
|
return par
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderSnapshot(s *Snapshot, selectedModule int) (*widgets.List, *ui.Grid) {
|
func renderSnapshot(s *Snapshot, selectedModule int) (*widgets.List, *ui.Grid) {
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil || hostname == "" {
|
||||||
|
hostname = "unknown"
|
||||||
|
}
|
||||||
|
ip := primaryIPv4()
|
||||||
|
if ip == "" {
|
||||||
|
ip = "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
servicesTable := buildServicesTable(s)
|
servicesTable := buildServicesTable(s)
|
||||||
portsTable := buildPortsTable(s)
|
portsTable := buildPortsTable(s)
|
||||||
for i := 1; i < len(portsTable.Rows); i++ {
|
for i := 1; i < len(portsTable.Rows); i++ {
|
||||||
@@ -287,43 +440,43 @@ func renderSnapshot(s *Snapshot, selectedModule int) (*widgets.List, *ui.Grid) {
|
|||||||
moduleInfoPar.Border = true
|
moduleInfoPar.Border = true
|
||||||
moduleInfoPar.BorderStyle = ui.NewStyle(ui.ColorMagenta)
|
moduleInfoPar.BorderStyle = ui.NewStyle(ui.ColorMagenta)
|
||||||
storagePar := buildStorageParagraph(s)
|
storagePar := buildStorageParagraph(s)
|
||||||
storagePar.Border = true
|
|
||||||
storagePar.BorderStyle = ui.NewStyle(ui.ColorYellow)
|
|
||||||
storagePar.PaddingLeft = 1
|
|
||||||
storagePar.PaddingRight = 1
|
|
||||||
volumesPar := buildVolumesParagraph(s)
|
volumesPar := buildVolumesParagraph(s)
|
||||||
|
|
||||||
header := widgets.NewParagraph()
|
header := widgets.NewParagraph()
|
||||||
header.Text = fmt.Sprintf("Project: %s\nNetwork: %s\nUpdated: %s", s.Project, s.Network, s.Timestamp)
|
header.Text = fmt.Sprintf("Host: %s\nIP: %s\nProject: %s\nNetwork: %s", hostname, ip, s.Project, s.Network)
|
||||||
header.Border = true
|
header.Border = true
|
||||||
|
|
||||||
|
buildPar := buildInfoParagraph(s)
|
||||||
|
|
||||||
usersPar := widgets.NewParagraph()
|
usersPar := widgets.NewParagraph()
|
||||||
usersPar.Text = fmt.Sprintf("USERS:\n Accounts: %d\n Online: %d\n Characters: %d\n Active 7d: %d", s.Users.Accounts, s.Users.Online, s.Users.Characters, s.Users.Active7d)
|
usersPar.Title = "Users"
|
||||||
|
usersPar.Text = fmt.Sprintf(" Accounts: %d\n Online: %d\n Characters: %d\n Active 7d: %d", s.Users.Accounts, s.Users.Online, s.Users.Characters, s.Users.Active7d)
|
||||||
usersPar.Border = true
|
usersPar.Border = true
|
||||||
|
|
||||||
grid := ui.NewGrid()
|
grid := ui.NewGrid()
|
||||||
termWidth, termHeight := ui.TerminalDimensions()
|
termWidth, termHeight := ui.TerminalDimensions()
|
||||||
grid.SetRect(0, 0, termWidth, termHeight)
|
grid.SetRect(0, 0, termWidth, termHeight)
|
||||||
grid.Set(
|
grid.Set(
|
||||||
ui.NewRow(0.15,
|
ui.NewRow(0.18,
|
||||||
ui.NewCol(0.6, header),
|
ui.NewCol(0.34, header),
|
||||||
ui.NewCol(0.4, usersPar),
|
ui.NewCol(0.33, buildPar),
|
||||||
|
ui.NewCol(0.33, usersPar),
|
||||||
),
|
),
|
||||||
ui.NewRow(0.46,
|
ui.NewRow(0.43,
|
||||||
ui.NewCol(0.6, servicesTable),
|
ui.NewCol(0.6, servicesTable),
|
||||||
ui.NewCol(0.4, portsTable),
|
ui.NewCol(0.4, portsTable),
|
||||||
),
|
),
|
||||||
ui.NewRow(0.39,
|
ui.NewRow(0.39,
|
||||||
ui.NewCol(0.25, modulesList),
|
ui.NewCol(0.25, modulesList),
|
||||||
ui.NewCol(0.15,
|
ui.NewCol(0.15,
|
||||||
ui.NewRow(0.30, helpPar),
|
ui.NewRow(0.32, helpPar),
|
||||||
ui.NewRow(0.70, moduleInfoPar),
|
ui.NewRow(0.68, moduleInfoPar),
|
||||||
),
|
),
|
||||||
ui.NewCol(0.6,
|
ui.NewCol(0.6,
|
||||||
ui.NewRow(0.55,
|
ui.NewRow(0.513,
|
||||||
ui.NewCol(1.0, storagePar),
|
ui.NewCol(1.0, storagePar),
|
||||||
),
|
),
|
||||||
ui.NewRow(0.45,
|
ui.NewRow(0.487,
|
||||||
ui.NewCol(1.0, volumesPar),
|
ui.NewCol(1.0, volumesPar),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user