Add Initial Seaweed File System UI

This commit is contained in:
chrislusf 2015-03-19 10:39:22 -07:00
parent 6fc72b19bb
commit b75ca9890d
7 changed files with 232 additions and 1 deletions

View file

@ -60,6 +60,7 @@ func NewMasterServer(r *mux.Router, port int, metaFolder string,
ms.guard = security.NewGuard(whiteList, secureKey) ms.guard = security.NewGuard(whiteList, secureKey)
r.HandleFunc("/ui/index.html", ms.uiStatusHandler)
r.HandleFunc("/dir/assign", ms.proxyToLeader(ms.guard.WhiteList(ms.dirAssignHandler))) r.HandleFunc("/dir/assign", ms.proxyToLeader(ms.guard.WhiteList(ms.dirAssignHandler)))
r.HandleFunc("/dir/lookup", ms.proxyToLeader(ms.guard.WhiteList(ms.dirLookupHandler))) r.HandleFunc("/dir/lookup", ms.proxyToLeader(ms.guard.WhiteList(ms.dirLookupHandler)))
r.HandleFunc("/dir/join", ms.proxyToLeader(ms.guard.WhiteList(ms.dirJoinHandler))) r.HandleFunc("/dir/join", ms.proxyToLeader(ms.guard.WhiteList(ms.dirJoinHandler)))

View file

@ -0,0 +1,26 @@
package weed_server
import (
"net/http"
"github.com/chrislusf/weed-fs/go/util"
ui "github.com/chrislusf/weed-fs/go/weed/weed_server/master_ui"
)
func (ms *MasterServer) uiStatusHandler(w http.ResponseWriter, r *http.Request) {
stats := make(map[string]interface{})
stats["Version"] = util.VERSION
args := struct {
Version string
Topology interface{}
Peers interface{}
Stats interface{}
}{
util.VERSION,
ms.Topo.ToMap(),
ms.Topo.RaftServer.Peers(),
stats,
//serverStats,
}
ui.StatusTpl.Execute(w, args)
}

View file

@ -0,0 +1,90 @@
package master_ui
import (
"html/template"
)
var StatusTpl = template.Must(template.New("status").Parse(`<!DOCTYPE html>
<html>
<head>
<title>Seaweed File System {{ .Version }}</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="page-header">
<h1>Seaweed File System <small>{{ .Version }}</small></h1>
</div>
<div class="row">
<div class="col-sm-6">
<h2>Cluster status</h2>
<table class="table">
<tbody>
<tr>
<th>Free</th>
<td>{{ .Topology.Free }}</td>
</tr>
<tr>
<th>Max</th>
<td>{{ .Topology.Max }}</td>
</tr>
<tr>
<td class="col-sm-2 field-label"><label>Peers:</label></td>
<td class="col-sm-10"><ul class="list-unstyled">
{{ range .Peers }}
<li><a href="https://{{ . }}">{{ . }}</a></li>
{{ end }}
</ul></td>
</tr>
</tbody>
</table>
</div>
<div class="col-sm-6">
<h2>System Stats</h2>
<table class="table table-condensed table-striped">
{{ range $key, $val := .Stats }}
<tr>
<th>{{ $key }}</th>
<td>{{ $val }}</td>
</tr>
{{ end }}
</table>
</div>
</div>
<div class="row">
<h2>Topology</h2>
<table class="table table-striped">
<thead>
<tr>
<th>Data Center</th>
<th>Rack</th>
<th>RemoteAddr</th>
<th>#Volumes</th>
<th>Max</th>
</tr>
</thead>
<tbody>
{{ range $dc_index, $dc := .Topology.DataCenters }}
{{ range $rack_index, $rack := $dc.Racks }}
{{ range $dn_index, $dn := $rack.DataNodes }}
<tr>
<td><code>{{ $dc.Id }}</code></td>
<td>{{ $rack.Id }}</td>
<td><a href="http://{{ $dn.Url }}/ui/index.html">{{ $dn.Url }}</a></td>
<td>{{ $dn.Volumes }}</td>
<td>{{ $dn.Max }}</td>
</tr>
{{ end }}
{{ end }}
{{ end }}
</tbody>
</table>
</div>
</div>
</body>
</html>
`))

View file

@ -41,6 +41,7 @@ func NewVolumeServer(adminMux, publicMux *http.ServeMux, ip string,
vs.guard = security.NewGuard(whiteList, "") vs.guard = security.NewGuard(whiteList, "")
adminMux.HandleFunc("/ui/index.html", vs.uiStatusHandler)
adminMux.HandleFunc("/status", vs.guard.WhiteList(vs.statusHandler)) adminMux.HandleFunc("/status", vs.guard.WhiteList(vs.statusHandler))
adminMux.HandleFunc("/admin/assign_volume", vs.guard.WhiteList(vs.assignVolumeHandler)) adminMux.HandleFunc("/admin/assign_volume", vs.guard.WhiteList(vs.assignVolumeHandler))
adminMux.HandleFunc("/admin/vacuum_volume_check", vs.guard.WhiteList(vs.vacuumVolumeCheckHandler)) adminMux.HandleFunc("/admin/vacuum_volume_check", vs.guard.WhiteList(vs.vacuumVolumeCheckHandler))

View file

@ -60,6 +60,6 @@ func (vs *VolumeServer) statsDiskHandler(w http.ResponseWriter, r *http.Request)
ds = append(ds, stats.NewDiskStatus(dir)) ds = append(ds, stats.NewDiskStatus(dir))
} }
} }
m["DiskStatues"] = ds m["DiskStatuses"] = ds
writeJsonQuiet(w, r, http.StatusOK, m) writeJsonQuiet(w, r, http.StatusOK, m)
} }

View file

@ -0,0 +1,35 @@
package weed_server
import (
"net/http"
"path/filepath"
"github.com/chrislusf/weed-fs/go/stats"
"github.com/chrislusf/weed-fs/go/util"
ui "github.com/chrislusf/weed-fs/go/weed/weed_server/volume_server_ui"
)
func (vs *VolumeServer) uiStatusHandler(w http.ResponseWriter, r *http.Request) {
infos := make(map[string]interface{})
infos["Version"] = util.VERSION
var ds []*stats.DiskStatus
for _, loc := range vs.store.Locations {
if dir, e := filepath.Abs(loc.Directory); e == nil {
ds = append(ds, stats.NewDiskStatus(dir))
}
}
args := struct {
Version string
Master string
Volumes interface{}
DiskStatuses interface{}
Stats interface{}
}{
util.VERSION,
vs.masterNode,
vs.store.Status(),
ds,
infos,
}
ui.StatusTpl.Execute(w, args)
}

View file

@ -0,0 +1,78 @@
package master_ui
import (
"html/template"
)
var StatusTpl = template.Must(template.New("status").Parse(`<!DOCTYPE html>
<html>
<head>
<title>Seaweed File System {{ .Version }}</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="page-header">
<h1>Seaweed File System <small>{{ .Version }}</small></h1>
</div>
<div class="row">
<div class="col-sm-6">
<h2>Disk Stats</h2>
<table class="table table-condensed table-striped">
{{ range .DiskStatuses }}
<tr>
<th>{{ .Dir }}</th>
<td>{{ .Free }}</td>
</tr>
{{ end }}
</table>
</div>
<div class="col-sm-6">
<h2>System Stats</h2>
<table class="table table-condensed table-striped">
<tr>
<th>Master</th>
<td><a href="http://{{.Master}}/ui/index.html">{{.Master}}</a></td>
</tr>
{{ range $key, $val := .Stats }}
<tr>
<th>{{ $key }}</th>
<td>{{ $val }}</td>
</tr>
{{ end }}
</table>
</div>
</div>
<div class="row">
<h2>Volumes</h2>
<table class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Size</th>
<th>Files</th>
<th>Trash</th>
<th>TTL</th>
</tr>
</thead>
<tbody>
{{ range .Volumes }}
<tr>
<td><code>{{ .Id }}</code></td>
<td>{{ .Size }}</td>
<td>{{ .FileCount }}</td>
<td>{{ .DeleteCount }} / {{.DeletedByteCount}} Bytes</td>
<td>{{ .Ttl }}</td>
</tr>
{{ end }}
</tbody>
</table>
</div>
</div>
</body>
</html>
`))