From a71d83bd8e113be0fe302c29909c82b73a108b1e Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@lothar.com>
Date: Wed, 7 Mar 2007 19:16:06 -0700
Subject: [PATCH] add a local foolscap control interface, to upload/download
 files and check memory usage

---
 src/allmydata/client.py     | 11 +++++++++++
 src/allmydata/control.py    | 31 +++++++++++++++++++++++++++++++
 src/allmydata/interfaces.py | 25 ++++++++++++++++++++++++-
 3 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 src/allmydata/control.py

diff --git a/src/allmydata/client.py b/src/allmydata/client.py
index 41801695..53956915 100644
--- a/src/allmydata/client.py
+++ b/src/allmydata/client.py
@@ -15,6 +15,7 @@ from allmydata.upload import Uploader
 from allmydata.download import Downloader
 from allmydata.vdrive import VDrive
 from allmydata.webish import WebishServer
+from allmydata.control import ControlServer
 
 class Client(node.Node, Referenceable):
     implements(RIClient)
@@ -51,6 +52,7 @@ class Client(node.Node, Referenceable):
 
     def tub_ready(self):
         self.my_pburl = self.tub.registerReference(self)
+        self.register_control()
         self.maybe_connect_to_queen()
 
     def set_queen_pburl(self, queen_pburl):
@@ -70,6 +72,15 @@ class Client(node.Node, Referenceable):
         self.queen_connector = self.tub.connectTo(self.queen_pburl,
                                                   self._got_queen)
 
+    def register_control(self):
+        c = ControlServer()
+        c.setServiceParent(self)
+        control_url = self.tub.registerReference(c)
+        f = open("control.pburl", "w")
+        f.write(control_url + "\n")
+        f.close()
+        os.chmod("control.pburl", 0600)
+
     def stopService(self):
         if self.queen_connector:
             self.queen_connector.stopConnecting()
diff --git a/src/allmydata/control.py b/src/allmydata/control.py
new file mode 100644
index 00000000..3f77e6b2
--- /dev/null
+++ b/src/allmydata/control.py
@@ -0,0 +1,31 @@
+
+from zope.interface import implements
+from twisted.application import service
+from foolscap import Referenceable
+from allmydata.interfaces import RIControlClient
+
+
+class ControlServer(Referenceable, service.Service):
+
+    def remote_upload_from_file_to_uri(self, filename):
+        uploader = self.parent.getServiceNamed("uploader")
+        d = uploader.upload_filename(filename)
+        return d
+
+    def remote_download_from_uri_to_file(self, uri, filename):
+        downloader = self.parent.getServiceNamed("downloader")
+        d = downloader.download_to_filename(uri, filename)
+        d.addCallback(lambda res: filename)
+        return d
+
+    def remote_get_memory_usage(self):
+        # this is obviously linux-specific
+        stat_names = ("VmPeak",
+                      "VmSize",
+                      #"VmHWM",
+                      "VmData")
+        for line in open("/proc/self/status", "r").readlines():
+            name, right = line.split(":",2)
+            if name in stat_names:
+                stats[name] = int(right.strip()) * 1024
+        return stats
diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py
index 4aa10643..c1c5a372 100644
--- a/src/allmydata/interfaces.py
+++ b/src/allmydata/interfaces.py
@@ -1,6 +1,6 @@
 
 from zope.interface import Interface
-from foolscap.schema import StringConstraint, ListOf, TupleOf, Any
+from foolscap.schema import StringConstraint, ListOf, TupleOf, Any, DictOf
 from foolscap import RemoteInterface
 
 Nodeid = StringConstraint(20) # binary format 20-byte SHA1 hash
@@ -407,3 +407,26 @@ class IWorkQueue(Interface):
 
 class NotCapableError(Exception):
     """You have tried to write to a read-only node."""
+
+class RIControlClient(RemoteInterface):
+    def upload_from_file_to_uri(filename=str):
+        """Upload a file to the mesh. This accepts a filename (which must be
+        absolute) that points to a file on the node's local disk. The node
+        will read the contents of this file, upload it to the mesh, then
+        return the URI at which it was uploaded.
+        """
+        return URI
+
+    def download_from_uri_to_file(uri=URI, filename=str):
+        """Download a file from the mesh, placing it on the node's local disk
+        at the given filename (which must be absolute[?]). Returns the
+        absolute filename where the file was written."""
+        return str
+
+    # debug stuff
+
+    def get_memory_usage():
+        """Return a dict describes the amount of memory currently in use. The
+        keys are 'VmPeak', 'VmSize', and 'VmData'. The values are integers,
+        measuring memory consupmtion in bytes."""
+        return DictOf(str, int)
-- 
2.45.2