add PublicInterfaceAddrs and display them on the status page

This commit is contained in:
Michael Stapelberg 2018-03-20 19:34:00 +01:00
parent ffa8ce0e42
commit b5d7cb2fcf
4 changed files with 41 additions and 12 deletions

View File

@ -71,11 +71,19 @@ No permanent storage mounted. To create a filesystem for permanent storage, plug
<h2>private network addresses</h2>
<ul>
{{ range $idx, $host := .Hosts }}
<li>{{ $host }}</li>
{{ range $idx, $addr := .PrivateAddrs }}
<li>{{ $addr }}</li>
{{ end }}
</ul>
<h2>public network addresses</h2>
<ul>
{{ range $idx, $addr := .PublicAddrs }}
<li>{{ $addr }}</li>
{{ end }}
</ul>
</div>
</div>

View File

@ -9,5 +9,5 @@ var assets = map[string][]byte{
}
var assets_0 = []byte("<!DOCTYPE html>\n<html lang=\"en\">\n<title>gokrazy</title>\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css\" integrity=\"sha256-916EbMg70RQy9LHiGkXzG8hSg9EdNy97GazNG/aiY1w=\" crossorigin=\"anonymous\" />\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.0/bootstrap-table.min.css\" integrity=\"sha256-eU4xmpfQx1HSi5q1q2rHNcMEzTNJov7r2Wr/6zF3ANc=\" crossorigin=\"anonymous\" />\n<style type=\"text/css\">\n.progress-bar:nth-child(5n) {\n background-color: #337ab7;\n}\n.progress-bar:nth-child(5n+1) {\n background-color: #5cb85c;\n}\n.progress-bar:nth-child(5n+2) {\n background-color: #5bc0de;\n}\n.progress-bar:nth-child(5n+3) {\n background-color: #f0ad4e;\n}\n.progress-bar:nth-child(5n+4) {\n background-color: #d9534f;\n}\n.lastlog {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n}\ntable {\n table-layout: fixed;\n}\n</style>\n\n <nav class=\"navbar navbar-default\">\n <div class=\"container-fluid\">\n <!-- Brand and toggle get grouped for better mobile display -->\n <div class=\"navbar-header\">\n <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar-collapse-1\" aria-expanded=\"false\">\n <span class=\"sr-only\">Toggle navigation</span>\n <span class=\"icon-bar\"></span>\n <span class=\"icon-bar\"></span>\n <span class=\"icon-bar\"></span>\n </button>\n <p style=\"width: 50ex; margin-top: 0.25em; font-size: 18px\"><a href=\"/\">gokrazy</a><br>\n <small style=\"font-size: 11px\" class=\"text-muted\">version {{ .BuildTimestamp }}</small></p>\n </div>\n\n <div class=\"collapse navbar-collapse\" id=\"navbar-collapse-1\">\n <ul class=\"nav navbar-nav\">\n </ul>\n\n <p class=\"navbar-text navbar-right\">\n host “{{ .Hostname }}”\n </p>\n </div><!-- /.navbar-collapse -->\n </div><!-- /.container-fluid -->\n </nav>\n\n <div class=\"container\">\n")
var assets_1 = []byte("\n</div>\n\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js\" integrity=\"sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=\" crossorigin=\"anonymous\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.0/bootstrap-table.min.js\" integrity=\"sha256-eXHLyyVI+v6X1wbfg9NB05IWqOqY4E9185nHZgeDIhg=\" crossorigin=\"anonymous\"></script>\n\n</html>")
var assets_2 = []byte("{{ template \"header\" . }}\n\n<div class=\"row\">\n<div class=\"col-md-12\">\n\n<h1>services</h1>\n\n<table class=\"table\">\n<tbody><tr>\n<th width=\"20%\">path</th>\n<th width=\"80%\">last log line</th>\n</tr>\n\n{{ range $idx, $svc := .Services }}\n<tr>\n<td>\n<a href=\"/status?path={{ $svc.Name }}\">{{ $svc.Name }}</a>\n{{ if restarting $svc.Started }}\n<span class=\"label label-danger\">restarting</span>\n{{ end }}\n{{ if $svc.Stopped }}\n<span class=\"label label-warning\">stopped</span>\n{{ end }}\n</td>\n<td class=\"lastlog\">\n{{ last $svc.Stdout.Lines $svc.Stderr.Lines }}\n</td>\n</tr>\n{{ end }}\n\n</table>\n</div> \n<div class=\"col-md-12\">\n<h2>memory</h2>\n{{ megabytes (index .Meminfo \"MemTotal\") }} total, {{ megabytes (index .Meminfo \"MemAvailable\") }} available<br>\n<strong>resident set size (RSS) by service</strong>:\n<div class=\"progress\">\n\n{{ with $rss := initRss }}\n<div class=\"progress-bar\" style=\"width: {{ rssPercentage $.Meminfo $rss }}%\" title=\"init uses {{ megabytes $rss }} RSS\">\n<span class=\"sr-only\"></span>\ninit\n</div>\n{{ end }}\n\n{{ range $idx, $svc := .Services }}\n{{ with $rss := $svc.RSS }}\n<div class=\"progress-bar\" style=\"width: {{ rssPercentage $.Meminfo $rss }}%\" title=\"{{ $svc.Name }} uses {{ megabytes $rss }} RSS\">\n<span class=\"sr-only\"></span>\n{{ baseName $svc.Name }}\n</div>\n{{ end }}\n{{ end }}\n<div class=\"progress-bar\" style=\"width: 100%; overflow:initial; float: none\" title=\"memory usage outside of gokrazy services\">\n<span class=\"sr-only\"></span>\nunaccounted\n</div>\n</div>\n</div>\n\n<div class=\"col-md-12\">\n\n\n<h2>storage</h2>\n\n{{ if eq .PermAvail 0 }}\nNo permanent storage mounted. To create a filesystem for permanent storage, plug the SD card into a Linux computer and, if your SD card is <code>/dev/sdb</code>, use <code>mkfs.ext4 /dev/sdb4</code>.\n{{ else }}\n<strong>/dev/mmcblk0p4</strong>: {{ gigabytes .PermTotal }} total, {{ gigabytes .PermUsed }} used, {{ gigabytes .PermAvail }} avail<br>\n{{ end }}\n\n<h2>private network addresses</h2>\n<ul>\n{{ range $idx, $host := .Hosts }} \n<li>{{ $host }}</li>\n{{ end }}\n</ul>\n\n</div>\n</div>\n\n{{ template \"footer\" . }}")
var assets_2 = []byte("{{ template \"header\" . }}\n\n<div class=\"row\">\n<div class=\"col-md-12\">\n\n<h1>services</h1>\n\n<table class=\"table\">\n<tbody><tr>\n<th width=\"20%\">path</th>\n<th width=\"80%\">last log line</th>\n</tr>\n\n{{ range $idx, $svc := .Services }}\n<tr>\n<td>\n<a href=\"/status?path={{ $svc.Name }}\">{{ $svc.Name }}</a>\n{{ if restarting $svc.Started }}\n<span class=\"label label-danger\">restarting</span>\n{{ end }}\n{{ if $svc.Stopped }}\n<span class=\"label label-warning\">stopped</span>\n{{ end }}\n</td>\n<td class=\"lastlog\">\n{{ last $svc.Stdout.Lines $svc.Stderr.Lines }}\n</td>\n</tr>\n{{ end }}\n\n</table>\n</div> \n<div class=\"col-md-12\">\n<h2>memory</h2>\n{{ megabytes (index .Meminfo \"MemTotal\") }} total, {{ megabytes (index .Meminfo \"MemAvailable\") }} available<br>\n<strong>resident set size (RSS) by service</strong>:\n<div class=\"progress\">\n\n{{ with $rss := initRss }}\n<div class=\"progress-bar\" style=\"width: {{ rssPercentage $.Meminfo $rss }}%\" title=\"init uses {{ megabytes $rss }} RSS\">\n<span class=\"sr-only\"></span>\ninit\n</div>\n{{ end }}\n\n{{ range $idx, $svc := .Services }}\n{{ with $rss := $svc.RSS }}\n<div class=\"progress-bar\" style=\"width: {{ rssPercentage $.Meminfo $rss }}%\" title=\"{{ $svc.Name }} uses {{ megabytes $rss }} RSS\">\n<span class=\"sr-only\"></span>\n{{ baseName $svc.Name }}\n</div>\n{{ end }}\n{{ end }}\n<div class=\"progress-bar\" style=\"width: 100%; overflow:initial; float: none\" title=\"memory usage outside of gokrazy services\">\n<span class=\"sr-only\"></span>\nunaccounted\n</div>\n</div>\n</div>\n\n<div class=\"col-md-12\">\n\n\n<h2>storage</h2>\n\n{{ if eq .PermAvail 0 }}\nNo permanent storage mounted. To create a filesystem for permanent storage, plug the SD card into a Linux computer and, if your SD card is <code>/dev/sdb</code>, use <code>mkfs.ext4 /dev/sdb4</code>.\n{{ else }}\n<strong>/dev/mmcblk0p4</strong>: {{ gigabytes .PermTotal }} total, {{ gigabytes .PermUsed }} used, {{ gigabytes .PermAvail }} avail<br>\n{{ end }}\n\n<h2>private network addresses</h2>\n<ul>\n{{ range $idx, $addr := .PrivateAddrs }}\n<li>{{ $addr }}</li>\n{{ end }}\n</ul>\n\n<h2>public network addresses</h2>\n<ul>\n{{ range $idx, $addr := .PublicAddrs }}\n<li>{{ $addr }}</li>\n{{ end }}\n</ul>\n\n\n</div>\n</div>\n\n{{ template \"footer\" . }}")
var assets_3 = []byte("{{ template \"header\" . }}\n\n<div class=\"row\">\n<div class=\"col-md-12\">\n<table>\n<tr>\n<th>Name</th>\n<th>Started</th>\n<th>Actions</th>\n</tr>\n<tr>\n<td><a href=\"#{{ .Service.Name }}\">{{ .Service.Name }}</a></td>\n<td>{{ .Service.Started }}</td>\n<td><form method=\"POST\" action=\"/restart\"><input type=\"hidden\" name=\"path\" value=\"{{ .Service.Name }}\"><input type=\"submit\" value=\"restart\"></form><form method=\"POST\" action=\"/stop\"><input type=\"hidden\" name=\"path\" value=\"{{ .Service.Name }}\"><input type=\"submit\" value=\"stop\"></form></td>\n</tr>\n</table>\n\n <h3>stdout</h3>\n <pre>\n {{ range $idx, $line := .Service.Stdout.Lines -}}\n {{ $line }}\n {{ end }}\n </pre>\n\n <h3>stderr</h3>\n <pre>\n {{ range $idx, $line := .Service.Stderr.Lines -}}\n {{ $line }}\n {{ end }}\n </pre>\n</div>\n</div>\n\n{{ template \"footer\" . }}")

View File

@ -51,10 +51,7 @@ func isPrivate(ipaddr net.IP) bool {
return false
}
// PrivateInterfaceAddrs returns all private (as per RFC1918, RFC4193,
// RFC3330, RFC3513, RFC3927, RFC4291) host addresses of all active
// interfaces, suitable to be passed to net.Listen.
func PrivateInterfaceAddrs() ([]string, error) {
func interfaceAddrs(keep func(net.IP) bool) ([]string, error) {
ifaces, err := net.Interfaces()
if err != nil {
return nil, err
@ -76,7 +73,7 @@ func PrivateInterfaceAddrs() ([]string, error) {
return nil, err
}
if !isPrivate(ipaddr) {
if !keep(ipaddr) {
continue
}
@ -90,6 +87,24 @@ func PrivateInterfaceAddrs() ([]string, error) {
return hosts, nil
}
// PrivateInterfaceAddrs returns all private (as per RFC1918, RFC4193,
// RFC3330, RFC3513, RFC3927, RFC4291) host addresses of all active
// interfaces, suitable to be passed to net.JoinHostPort.
func PrivateInterfaceAddrs() ([]string, error) {
return interfaceAddrs(func(addr net.IP) bool {
return isPrivate(addr)
})
}
// PublicInterfaceAddrs returns all public (excluding RFC1918, RFC4193,
// RFC3330, RFC3513, RFC3927, RFC4291) host addresses of all active
// interfaces, suitable to be passed to net.JoinHostPort.
func PublicInterfaceAddrs() ([]string, error) {
return interfaceAddrs(func(addr net.IP) bool {
return !isPrivate(addr)
})
}
var (
listeners = make(map[string]*http.Server)
listenersMu sync.Mutex

View File

@ -124,9 +124,13 @@ func initStatus(services []*service) {
if err := unix.Statfs("/perm", &st); err != nil {
log.Printf("could not stat /perm: %v", err)
}
hosts, err := PrivateInterfaceAddrs()
privateAddrs, err := PrivateInterfaceAddrs()
if err != nil {
log.Printf("could not get addrs: %v", err)
log.Printf("could not get private addrs: %v", err)
}
publicAddrs, err := PublicInterfaceAddrs()
if err != nil {
log.Printf("could not get public addrs: %v", err)
}
var buf bytes.Buffer
if err := overviewTmpl.Execute(&buf, struct {
@ -134,7 +138,8 @@ func initStatus(services []*service) {
PermUsed int64
PermAvail int64
PermTotal int64
Hosts []string
PrivateAddrs []string
PublicAddrs []string
BuildTimestamp string
Meminfo map[string]int64
Hostname string
@ -143,7 +148,8 @@ func initStatus(services []*service) {
PermUsed: int64(st.Bsize) * int64(st.Blocks-st.Bfree),
PermAvail: int64(st.Bsize) * int64(st.Bavail),
PermTotal: int64(st.Bsize) * int64(st.Blocks),
Hosts: hosts,
PrivateAddrs: privateAddrs,
PublicAddrs: publicAddrs,
BuildTimestamp: buildTimestamp,
Meminfo: parseMeminfo(),
Hostname: hostname,