diff --git a/src/go/util/mm/minimega.go b/src/go/util/mm/minimega.go index 955e161f..d99cfce7 100644 --- a/src/go/util/mm/minimega.go +++ b/src/go/util/mm/minimega.go @@ -698,7 +698,7 @@ func (this Minimega) GetVMCaptures(opts ...Option) []Capture { return keep } -func (Minimega) GetClusterHosts(schedOnly bool) (Hosts, error) { +func (this Minimega) GetClusterHosts(schedOnly bool) (Hosts, error) { // Get headnode details hosts, err := processNamespaceHosts("minimega") if err != nil { @@ -729,6 +729,10 @@ func (Minimega) GetClusterHosts(schedOnly bool) (Hosts, error) { // This will happen if the headnode is included as a compute node // (ie. when there's only one node in the cluster). if host.Name == head.Name { + // Add disk info + head.DiskUsage.Phenix = this.getDiskUsage(head.Name, common.PhenixBase) + head.DiskUsage.Minimega = this.getDiskUsage(head.Name, common.MinimegaBase) + head.Schedulable = true continue } @@ -736,6 +740,10 @@ func (Minimega) GetClusterHosts(schedOnly bool) (Hosts, error) { host.Name = common.TrimHostnameSuffixes(host.Name) host.Schedulable = true + // Add disk info + host.DiskUsage.Phenix = this.getDiskUsage(host.Name, common.PhenixBase) + host.DiskUsage.Minimega = this.getDiskUsage(host.Name, common.MinimegaBase) + cluster = append(cluster, host) } @@ -745,6 +753,10 @@ func (Minimega) GetClusterHosts(schedOnly bool) (Hosts, error) { head.Name = common.TrimHostnameSuffixes(head.Name) + // Add disk info + head.DiskUsage.Phenix = this.getDiskUsage(head.Name, common.PhenixBase) + head.DiskUsage.Minimega = this.getDiskUsage(head.Name, common.MinimegaBase) + cluster = append(cluster, head) return cluster, nil @@ -1147,6 +1159,33 @@ func (Minimega) MeshShell(host, command string) error { return nil } +func (Minimega) MeshShellResponse(host, command string) (string, error) { + cmd := mmcli.NewCommand() + + if host == "" { + host = Headnode() + } + + if IsHeadnode(host) { + cmd.Command = fmt.Sprintf("shell %s", command) + } else { + cmd.Command = fmt.Sprintf("mesh send %s shell %s", host, command) + } + + for resps := range mmcli.Run(cmd) { + for _, resp := range resps.Resp { + if resp.Error != "" { + plog.Warn("error running shell command: ", "cmd", cmd) + continue + } + + return strings.TrimSpace(resp.Response), nil + } + } + + return "", fmt.Errorf("error running MeshShellResponse()") +} + func (Minimega) MeshSend(ns, host, command string) error { var cmd *mmcli.Command @@ -1320,3 +1359,19 @@ func processNamespaceHosts(namespace string) (Hosts, error) { return hosts, nil } + +// Run shell command to get disk usage for `path` on `host` +func (this Minimega) getDiskUsage(host string, path string) float64 { + diskUsage := 0.0 + + cmd := fmt.Sprintf(`bash -c "echo $(df %s | awk '{print $(NF-1)}' | tail -1)"`, path) + resp, err := this.MeshShellResponse(host, cmd) + + if (resp == "") || (err != nil) { + return diskUsage + } + + diskUsage, _ = strconv.ParseFloat(strings.TrimSuffix(resp, "%"), 64) + + return diskUsage +} diff --git a/src/go/util/mm/types.go b/src/go/util/mm/types.go index ffb98aad..dff10cc9 100644 --- a/src/go/util/mm/types.go +++ b/src/go/util/mm/types.go @@ -122,21 +122,27 @@ type Cluster struct { } type Host struct { - Name string `json:"name"` - CPUs int `json:"cpus"` - CPUCommit int `json:"cpucommit"` - Load []string `json:"load"` - MemUsed int `json:"memused"` - MemTotal int `json:"memtotal"` - MemCommit int `json:"memcommit"` - Tx float64 `json:"tx"` - Rx float64 `json:"rx"` - Bandwidth string `json:"bandwidth"` - NetCommit int `json:"netcommit"` - VMs int `json:"vms"` - Uptime float64 `json:"uptime"` - Schedulable bool `json:"schedulable"` - Headnode bool `json:"headnode"` + Name string `json:"name"` + CPUs int `json:"cpus"` + CPUCommit int `json:"cpucommit"` + Load []string `json:"load"` + MemUsed int `json:"memused"` + MemTotal int `json:"memtotal"` + MemCommit int `json:"memcommit"` + Tx float64 `json:"tx"` + Rx float64 `json:"rx"` + Bandwidth string `json:"bandwidth"` + DiskUsage DiskUsage `json:"diskusage"` + NetCommit int `json:"netcommit"` + VMs int `json:"vms"` + Uptime float64 `json:"uptime"` + Schedulable bool `json:"schedulable"` + Headnode bool `json:"headnode"` +} + +type DiskUsage struct { + Phenix float64 `json:"diskphenix"` + Minimega float64 `json:"diskminimega"` } type VMs []VM diff --git a/src/js/src/components/Hosts.vue b/src/js/src/components/Hosts.vue index 125edf96..a861aed9 100644 --- a/src/js/src/components/Hosts.vue +++ b/src/js/src/components/Hosts.vue @@ -44,6 +44,15 @@ available for experiments, the number of VMs, and host uptime. {{ props.row.memtotal | ram }} + + + {{ props.row.diskusage.diskphenix }} + + / + + {{ props.row.diskusage.diskminimega }} + + {{ props.row.bandwidth }}