]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
make provisioning/reliability work in the new location, fix tests
authorBrian Warner <warner@lothar.com>
Wed, 15 Feb 2012 18:24:42 +0000 (18:24 +0000)
committerBrian Warner <warner@lothar.com>
Thu, 16 Feb 2012 22:29:05 +0000 (22:29 +0000)
Makefile
misc/operations_helpers/provisioning/provisioning.py
misc/operations_helpers/provisioning/run.py [new file with mode: 0644]
misc/operations_helpers/provisioning/tahoe.css [new file with mode: 0644]
misc/operations_helpers/provisioning/test_provisioning.py
misc/operations_helpers/provisioning/util.py [new file with mode: 0644]
misc/operations_helpers/provisioning/web_reliability.py

index 38bb647994425717c8d83bbffb1211caf410abcd..4bf09d39ac9a189a17fd4b75259d01050fa1dea6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -199,6 +199,10 @@ check-grid: .built
 bench-dirnode: .built
        $(TAHOE) @src/allmydata/test/bench_dirnode.py
 
+# the provisioning tool runs as a stand-alone webapp server
+run-provisioning-tool: .built
+       $(TAHOE) @misc/operations_helpers/provisioning/run.py
+
 # 'make repl' is a simple-to-type command to get a Python interpreter loop
 # from which you can type 'import allmydata'
 repl:
index 9d9af0ea6e92a7998debe24e6c1d6c1414589050..37acd16d22f752bbb8aac358d993a0a280214025 100644 (file)
@@ -1,12 +1,17 @@
 
-from nevow import inevow, rend, tags as T
+from nevow import inevow, rend, loaders, tags as T
 import math
-from allmydata.util import mathutil
-from allmydata.web.common import getxmlfile
+import util
 
 # factorial and binomial copied from
 # http://mail.python.org/pipermail/python-list/2007-April/435718.html
 
+def div_ceil(n, d):
+    """
+    The smallest integer k such that k*d >= n.
+    """
+    return (n/d) + (n%d != 0)
+
 def factorial(n):
     """factorial(n): return the factorial of the integer n.
     factorial(0) = 1
@@ -35,7 +40,7 @@ def binomial(n, k):
 
 class ProvisioningTool(rend.Page):
     addSlash = True
-    docFactory = getxmlfile("provisioning.xhtml")
+    docFactory = loaders.xmlfile(util.sibling("provisioning.xhtml"))
 
     def render_forms(self, ctx, data):
         req = inevow.IRequest(ctx)
@@ -566,12 +571,12 @@ class ProvisioningTool(rend.Page):
                              number(total_file_check_rate,
                                     "Hz")])
 
-            total_drives = max(mathutil.div_ceil(int(total_share_space),
-                                                 int(drive_size)),
+            total_drives = max(div_ceil(int(total_share_space),
+                                        int(drive_size)),
                                num_servers)
             add_output("Drives",
                        T.div["Total drives: ", number(total_drives), " drives"])
-            drives_per_server = mathutil.div_ceil(total_drives, num_servers)
+            drives_per_server = div_ceil(total_drives, num_servers)
             add_output("Servers",
                        T.div["Drives per server: ", drives_per_server])
 
@@ -606,8 +611,7 @@ class ProvisioningTool(rend.Page):
             # $44/server/mo power+space
             server_bandwidth = max(server_inbound_byte_rate,
                                    server_outbound_byte_rate)
-            server_bandwidth_mbps = mathutil.div_ceil(int(server_bandwidth*8),
-                                                      int(1e6))
+            server_bandwidth_mbps = div_ceil(int(server_bandwidth*8), int(1e6))
             server_monthly_cost = 70*server_bandwidth_mbps + 44
             add_output("Servers", T.div["Monthly cost per server: $",
                                         server_monthly_cost])
diff --git a/misc/operations_helpers/provisioning/run.py b/misc/operations_helpers/provisioning/run.py
new file mode 100644 (file)
index 0000000..d81f771
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+# this depends upon Twisted and Nevow, but not upon Tahoe itself
+
+import webbrowser
+
+from twisted.application import strports
+from twisted.internet import reactor
+from nevow import appserver, rend, loaders
+from twisted.web import static
+import web_reliability, provisioning
+
+class Root(rend.Page):
+    docFactory = loaders.xmlstr('''\
+<html xmlns:n="http://nevow.com/ns/nevow/0.1">
+  <head>
+    <title>Tahoe-LAFS Provisioning/Reliability Calculator</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  </head>
+  <body>
+  <p><a href="reliability">Reliability Tool</a></p>
+  <p><a href="provisioning">Provisioning Tool</a></p>
+  </body>
+</html>
+''')
+
+    child_reliability = web_reliability.ReliabilityTool()
+    child_provisioning = provisioning.ProvisioningTool()
+
+
+def run(portnum):
+    root = Root()
+    root.putChild("tahoe.css", static.File("tahoe.css"))
+    site = appserver.NevowSite(root)
+    s = strports.service("tcp:%d" % portnum, site)
+    s.startService()
+    reactor.callLater(1.0, webbrowser.open, "http://localhost:%d/" % portnum)
+    reactor.run()
+
+if __name__ == '__main__':
+    import sys
+    portnum = 8070
+    if len(sys.argv) > 1:
+        portnum = int(sys.argv[1])
+    run(portnum)
diff --git a/misc/operations_helpers/provisioning/tahoe.css b/misc/operations_helpers/provisioning/tahoe.css
new file mode 100644 (file)
index 0000000..e834ecc
--- /dev/null
@@ -0,0 +1,163 @@
+
+pre.overflow {
+               background: #f7f7f7;
+               border: 1px solid #d7d7d7;
+               margin: 1em 1.75em;
+               padding: .25em;
+               overflow: auto;
+               }
+               
+/* ----------------------------------------------------------------------- */
+
+/* colors borrowed from the Allmydata logo */
+
+/* general style */
+h1 {
+  text-align: center;
+}
+table { 
+  margin: 1em auto;
+  border: .2em solid #3289b4; 
+  border-spacing: 1px;
+}
+th { 
+  color: white;
+  background-color: #58a1c3;
+}
+td {
+    padding: .3em .3em;
+}
+
+th {
+    padding: .3em .3em;
+}
+
+.table-headings-top th {
+    text-align: center;
+    
+}
+.table-headings-left th {
+    text-align: right;
+    vertical-align: top;
+}
+legend {
+  font-weight: bold;
+}
+
+.connected-yes, .connected-True {
+  border: 1px solid #75d24a;
+  background-color: #EFE;
+}
+.connected-no, .connected-False {
+  border: 1px solid #F00;
+  background-color: #FBB;
+}
+
+.encoded, .nodeid {
+  font-family: monospace;
+  font-size: 80%;
+}
+
+.empty-marker {
+  background-color: white;
+  color: gray;
+}
+table td.empty-marker {
+  padding: 6em 10em;
+  text-align: center;
+  vertical-align: center;
+}
+
+/* styles for server listings in tables (nickname above nodeid) */
+th.nickname-and-peerid {
+  text-align: left;
+}
+.nickname {
+  font: inherit;
+  font-family: sans-serif;
+  font-weight: bold;
+}
+
+
+/* just in case, make sure floats don't stomp on big tables etc. */
+#section { clear: both; }
+
+/* section-specific styles - turn this client info into a sidebar */
+#this-client {
+  font-size: 60%;
+  border: .2em solid #3289b4;
+  float: right;
+  width: 40%;
+  margin: 0 0 .5em .5em;
+  padding: 3px;
+}
+#this-client .nodeid { font-size: inherit; }
+#this-client h2 {
+  text-align: center;
+  background: #3289b4;
+  color: white;
+  margin: -2px -2px 0 -2px; /* matches padding */
+  padding: .3em;
+}
+#this-client table { 
+  font-size: inherit;
+  margin: 0 -3px -3px -3px; /* matches padding */
+}
+#this-client td > ul {
+  list-style-type: outside;
+  margin: 0 0 0 2.3em;
+  padding-left: 0;
+}
+
+
+/* services table */
+.services {
+}
+
+/* --- Directory page styles --- */
+
+body.tahoe-directory-page {
+  color: black;
+  background: #c0d9e6;
+  margin: 1em 0; /* zero margin so the table can be flush */
+}
+table.tahoe-directory {
+  color: black;
+  background: white;
+  width: 100%;
+  /*border-left-color: #D7E0E5;
+  border-right-color: #D7E0E5;*/
+  border-left: 0;
+  border-right: 0;
+}
+.tahoe-directory-footer {
+  color: black;
+  background: #c0d9e6;
+  margin: 0 1em; /* compensate for page 0 margin */
+}
+
+/* directory-screen toolbar */
+.toolbar {
+  display: table;
+  margin: .2em auto;
+  text-align: center;
+  /*width: 100%;*/
+}
+.toolbar .toolbar-item {
+  display: inline;
+  text-align: center;
+  padding: 0 1em;
+}
+
+/* recent upload/download status pages */
+
+table.status-download-events {
+  #border: 1px solid #aaa;
+  margin: 1em auto;
+  border: .2em solid #3289b4; 
+  border-spacing: 1px;
+}
+table.status-download-events td {
+  border: 1px solid #a00;
+  padding: 2px
+}
index 71bc657034046bf56aeb0ee61541f6b73ca56b5f..d2b9dbd1749757318d7d2d8b7c7870e6cc3c16df 100644 (file)
@@ -1,5 +1,5 @@
 
-from twisted.trial import unittest
+import unittest
 from allmydata import provisioning
 ReliabilityModel = None
 try:
@@ -111,3 +111,5 @@ class Reliability(unittest.TestCase):
         self.failUnlessAlmostEqual(P_dead_unmaintained, 0.033591004555395272)
         self.failUnlessAlmostEqual(P_dead_maintained, 3.2983995819177542e-08)
 
+if __name__=='__main__':
+    unittest.main()
diff --git a/misc/operations_helpers/provisioning/util.py b/misc/operations_helpers/provisioning/util.py
new file mode 100644 (file)
index 0000000..db28915
--- /dev/null
@@ -0,0 +1,5 @@
+
+import os.path
+
+def sibling(filename):
+    return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
index d5d340615a4c33ebf5f86a586cef220fc924c443..149079e94713680d1d4d7adeade851b32119f48b 100644 (file)
@@ -1,11 +1,27 @@
 
-from nevow import rend, tags as T
-reliability = None # might not be usable
-try:
-    from allmydata import reliability # requires NumPy
-except ImportError:
-    pass
-from allmydata.web.common import getxmlfile, get_arg
+from nevow import rend, loaders, tags as T
+from nevow.inevow import IRequest
+import reliability # requires NumPy
+import util
+
+def get_arg(ctx_or_req, argname, default=None, multiple=False):
+    """Extract an argument from either the query args (req.args) or the form
+    body fields (req.fields). If multiple=False, this returns a single value
+    (or the default, which defaults to None), and the query args take
+    precedence. If multiple=True, this returns a tuple of arguments (possibly
+    empty), starting with all those in the query args.
+    """
+    req = IRequest(ctx_or_req)
+    results = []
+    if argname in req.args:
+        results.extend(req.args[argname])
+    if req.fields and argname in req.fields:
+        results.append(req.fields[argname].value)
+    if multiple:
+        return tuple(results)
+    if results:
+        return results[0]
+    return default
 
 
 DAY=24*60*60
@@ -22,7 +38,7 @@ def yandm(seconds):
 
 class ReliabilityTool(rend.Page):
     addSlash = True
-    docFactory = getxmlfile("reliability.xhtml")
+    docFactory = loaders.xmlfile(util.sibling("reliability.xhtml"))
 
     DEFAULT_PARAMETERS = [
         ("drive_lifetime", "8Y", "time",