graphvizify
diff --git a/service.go b/service.go
index 991797d..afdd04b 100644
--- a/service.go
+++ b/service.go
@@ -1,11 +1,14 @@
 package main
 
 import (
+	"context"
+	"fmt"
 	"net/http"
 
 	"code.hackerspace.pl/q3k/topo/graph"
+	"github.com/gobuffalo/packr"
 	"github.com/golang/glog"
-	_ "github.com/q3k/statusz"
+	"github.com/q3k/statusz"
 )
 
 type ServiceConfig struct {
@@ -24,10 +27,74 @@
 	}
 }
 
+type TopologyStatus struct {
+}
+
+const topologyFragment = `
+  <script src="/assets/viz.js"></script>
+  <script>
+
+    var viz = new Viz({ workerURL: '/assets/full.render.js' });
+	var xmlhttp = new XMLHttpRequest();
+	xmlhttp.onreadystatechange = function() {
+      if (this.readyState == 4 && this.status == 200) {
+        var dot = this.responseText;
+        viz.renderSVGElement(dot)
+        .then(function(element) {
+          document.body.appendChild(element);
+        });
+      }
+    };
+    xmlhttp.open('GET', '/debug/graphviz');
+    xmlhttp.send();
+
+  </script>
+`
+
 func (s *Service) Run() {
+	assets := packr.NewBox("./assets")
+	http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(assets)))
+
 	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 		http.Redirect(w, r, "/debug/status", http.StatusSeeOther)
 	})
+
+	http.HandleFunc("/debug/graphviz", func(w http.ResponseWriter, r *http.Request) {
+		fmt.Fprintf(w, "graph G {\n")
+		for _, machine := range s.gr.Machines {
+			fmt.Fprintf(w, "  subgraph cluster%s {\n", machine.Name)
+			fmt.Fprintf(w, "    label = %s\n", machine.Name)
+			for _, port := range machine.Ports {
+				a := machine.Name + "|" + port.Name
+				fmt.Fprintf(w, "    %q [label = %q]\n", a, port.Name)
+			}
+			fmt.Fprintf(w, "  }\n")
+		}
+		for _, sw := range s.gr.Switches {
+			fmt.Fprintf(w, "  subgraph cluster%s {\n", sw.Name)
+			fmt.Fprintf(w, "    label = %s\n", sw.Name)
+			for _, port := range sw.Ports {
+				a := sw.Name + "|" + port.Name
+				fmt.Fprintf(w, "    %q [label = %q]\n", a, port.Name)
+			}
+			fmt.Fprintf(w, "  }\n")
+		}
+		for _, machine := range s.gr.Machines {
+			for _, port := range machine.Ports {
+				if port.OtherEnd == nil {
+					continue
+				}
+				a := machine.Name + "|" + port.Name
+				b := port.OtherEnd.Switch.Name + "|" + port.OtherEnd.Name
+				fmt.Fprintf(w, "  %q -- %q\n", a, b)
+			}
+		}
+		fmt.Fprintf(w, "}\n")
+	})
+
+	statusz.AddStatusPart("Topology", topologyFragment, func(ctx context.Context) interface{} {
+		return &TopologyStatus{}
+	})
 	glog.Infof("Debug listening on %s....", s.config.DebugListen)
 	http.ListenAndServe(s.config.DebugListen, nil)
 }