Allow reconnecting to the same terminal session
[invirt/packages/invirt-web.git] / code / main.py
index dd2b591..77646c9 100755 (executable)
@@ -37,6 +37,7 @@ from invirt.config import structs as config
 from invirt.common import InvalidInput, CodeError
 
 from view import View, revertStandardError
+import ajaxterm
 
 
 static_dir = os.path.join(os.path.dirname(__file__), 'static')
@@ -388,6 +389,45 @@ console will suffer artifacts.
             else:
                 raise InvalidInput('back', back, 'Not a known back page.')
 
+        atmulti = ajaxterm.Multiplex()
+        atsessions = {}
+
+        @cherrypy.expose
+        @cherrypy.tools.mako(filename="/terminal.mako")
+        def terminal(self, machine_id):
+            machine = validation.Validate(cherrypy.request.login, cherrypy.request.state, machine_id=machine_id).machine
+
+            status = controls.statusInfo(machine)
+            has_vnc = hasVnc(status)
+
+            d = dict(on=status,
+                     has_vnc=has_vnc,
+                     machine=machine,
+                     hostname=cherrypy.request.local.name)
+            return d
+
+        @cherrypy.expose
+        def at(self, machine_id, k=None, c=0, force=0):
+            machine = validation.Validate(cherrypy.request.login, cherrypy.request.state, machine_id=machine_id).machine
+            if machine_id in self.atsessions:
+                term = self.atsessions[machine_id]
+            else:
+                print >>sys.stderr, "spawning new session for terminal to ",machine_id
+                term = self.atsessions[machine_id] = self.atmulti.create(
+                    ["ssh", "-e","none", "-l", machine.name, config.console.hostname]
+                    )
+            if k:
+                self.atmulti.proc_write(term,k)
+            time.sleep(0.002)
+            dump=self.atmulti.dump(term,c,int(force))
+            cherrypy.response.headers['Content-Type']='text/xml'
+            if isinstance(dump,str):
+                return dump
+            else:
+                print "Removing session for", machine_id
+                del self.atsessions[machine_id]
+                return '<?xml version="1.0"?><idem></idem>'
+
     machine = MachineView()