1#!/usr/bin/python
2
3# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7# A local web server that sets up SSH port-forwarding to display the
8# front-panel display of an 8960
9
10import BaseHTTPServer
11import subprocess
12import sys
13
14import labconfig
15
16DOCUMENTATION="""
17This will start up an SSH to port-forward connections to the 8960.
18and then a web server to offer a simple UI to fetch images of the
198960 front panel display. It will print a localhost URL to visit.
20When you visit that URL, you'll see the front-panel display from
21the instrument. If the image is stale, the display greys out.
22"""
23
24PAGE="""
25<html>
26  <head>
27  </head>
28  <script type="text/javascript">
29    var port = %(ssh_tunnel_port)s;
30    var lastTimestamp = 0;
31    function onTimer() {
32      var imageSpan = document.getElementById('image_span');
33      var newImage = document.createElement('image');
34      var tag = new Date().getTime();
35
36      if (tag - lastTimestamp > 3000) {
37        imageSpan.style.opacity=0.3;
38      }
39
40      newImage.src = 'http://localhost:' + port + '/screen.gif?' + tag;
41      newImage.onload = function () {
42        imageSpan.replaceChild(newImage, imageSpan.children[0]);
43        lastTimestamp = tag;
44        imageSpan.style.opacity=1;
45      }
46      t = setTimeout("onTimer()", 1000);
47    }
48
49    setTimeout("onTimer()", 0);
50  </script>
51
52  <body>
53    <div>8960 in test cell <strong>%(cell)s</strong></div>
54    <span id="image_span">
55      <span>
56        <!-- Placeholder -->
57        8960 screen should go here. <br>
58      </span>
59    </span>
60  </body>
61</html>
62"""
63
64
65try:
66    [cell] = sys.argv[1:]
67except ValueError:
68    print 'Usage: %s [cell-name]' % sys.argv[0]
69    print DOCUMENTATION
70    exit(1)
71
72ssh_tunnel_port = 1839
73http_server_port = 8192
74
75c = labconfig.Configuration(['--cell=%s' % (cell)])
76
77basestation_ip = c.cell['basestations'][0]['bs_addresses'][0]
78bastion_ip = c.cell['perfserver']['address']
79
80ssh_forwarding_configuration = 'localhost:%s:%s:80' % (
81    ssh_tunnel_port, basestation_ip)
82
83
84class PopenContext(object):
85    def __init__(self, *args, **kwargs):
86        self.args = args
87        self.kwargs = kwargs
88
89    def __enter__(self):
90        self.process = subprocess.Popen(*self.args, **self.kwargs)
91        return self.process
92
93    def __exit__(self, exception, value, traceback):
94        self.process.kill()
95
96
97class PageHandler(BaseHTTPServer.BaseHTTPRequestHandler):
98    def do_GET(self):
99        self.send_response(200)
100        self.end_headers()
101        self.wfile.write(PAGE % {'ssh_tunnel_port': ssh_tunnel_port,
102                                 'cell': cell})
103
104with PopenContext(
105    ['/usr/bin/ssh',
106     '-N',                  # Forward ports only
107     '-l','root',
108     '-L', ssh_forwarding_configuration,
109     bastion_ip,]) as ssh:
110
111    httpd = BaseHTTPServer.HTTPServer(('', http_server_port), PageHandler)
112    print DOCUMENTATION
113    print 'http://localhost:%s/8960.html' % http_server_port
114    httpd.serve_forever()
115