Disable image cloning when ice3 is booted - this should work as a locking
[invirt/packages/invirt-web.git] / code / main.py
index 3b43859..60c2818 100755 (executable)
@@ -105,8 +105,9 @@ class Defaults:
     cdrom = ''
     autoinstall = ''
     name = ''
     cdrom = ''
     autoinstall = ''
     name = ''
+    type = 'linux-hvm'
+
     def __init__(self, max_memory=None, max_disk=None, **kws):
     def __init__(self, max_memory=None, max_disk=None, **kws):
-        self.type = Type.get('linux-hvm')
         if max_memory is not None:
             self.memory = min(self.memory, max_memory)
         if max_disk is not None:
         if max_memory is not None:
             self.memory = min(self.memory, max_memory)
         if max_disk is not None:
@@ -195,20 +196,26 @@ def create(user, fields):
 
 def getListDict(user):
     """Gets the list of local variables used by list.tmpl."""
 
 def getListDict(user):
     """Gets the list of local variables used by list.tmpl."""
+    checkpoint.checkpoint('Starting')
     machines = g.machines
     checkpoint.checkpoint('Got my machines')
     on = {}
     has_vnc = {}
     machines = g.machines
     checkpoint.checkpoint('Got my machines')
     on = {}
     has_vnc = {}
-    on = g.uptimes
+    xmlist = g.xmlist
     checkpoint.checkpoint('Got uptimes')
     checkpoint.checkpoint('Got uptimes')
+    can_clone = (controls.getList([Machine.get_by(name='ice3')])) == {}
     for m in machines:
     for m in machines:
-        m.uptime = g.uptimes.get(m)
-        if not on[m]:
+        if m not in xmlist:
             has_vnc[m] = 'Off'
             has_vnc[m] = 'Off'
-        elif m.type.hvm:
-            has_vnc[m] = True
+            m.uptime = None
         else:
         else:
-            has_vnc[m] = "ParaVM"+helppopup("paravm_console")
+            m.uptime = xmlist[m]['uptime']
+            if xmlist[m]['console']:
+                has_vnc[m] = True
+            elif m.type.hvm:
+                has_vnc[m] = "WTF?"
+            else:
+                has_vnc[m] = "ParaVM"+helppopup("ParaVM Console")
     max_memory = validation.maxMemory(user)
     max_disk = validation.maxDisk(user)
     checkpoint.checkpoint('Got max mem/disk')
     max_memory = validation.maxMemory(user)
     max_disk = validation.maxDisk(user)
     checkpoint.checkpoint('Got max mem/disk')
@@ -227,7 +234,7 @@ def getListDict(user):
              defaults=defaults,
              machines=machines,
              has_vnc=has_vnc,
              defaults=defaults,
              machines=machines,
              has_vnc=has_vnc,
-             uptimes=g.uptimes)
+             can_clone=can_clone)
     return d
 
 def listVms(user, fields):
     return d
 
 def listVms(user, fields):
@@ -291,7 +298,7 @@ def getHostname(nic):
     if nic.hostname and '.' in nic.hostname:
         return nic.hostname
     elif nic.machine:
     if nic.hostname and '.' in nic.hostname:
         return nic.hostname
     elif nic.machine:
-        return nic.machine.name + '.servers.csail.mit.edu'
+        return nic.machine.name + '.xvm.mit.edu'
     else:
         return None
 
     else:
         return None
 
@@ -451,40 +458,40 @@ def helpHandler(user, fields):
     simple = fields.getfirst('simple')
     subjects = fields.getlist('subject')
 
     simple = fields.getfirst('simple')
     subjects = fields.getlist('subject')
 
-    help_mapping = dict(paravm_console="""
+    help_mapping = {'ParaVM Console': """
 ParaVM machines do not support local console access over VNC.  To
 access the serial console of these machines, you can SSH with Kerberos
 ParaVM machines do not support local console access over VNC.  To
 access the serial console of these machines, you can SSH with Kerberos
-to sipb-xen-console.mit.edu, using the name of the machine as your
+to console.xvm.mit.edu, using the name of the machine as your
 username.""",
 username.""",
-                        hvm_paravm="""
+                    'HVM/ParaVM': """
 HVM machines use the virtualization features of the processor, while
 ParaVM machines use Xen's emulation of virtualization features.  You
 want an HVM virtualized machine.""",
 HVM machines use the virtualization features of the processor, while
 ParaVM machines use Xen's emulation of virtualization features.  You
 want an HVM virtualized machine.""",
-                        cpu_weight="""
+                    'CPU Weight': """
 Don't ask us!  We're as mystified as you are.""",
 Don't ask us!  We're as mystified as you are.""",
-                        owner="""
+                    'Owner': """
 The owner field is used to determine <a
 The owner field is used to determine <a
-href="help?subject=quotas">quotas</a>.  It must be the name of a
+href="help?subject=Quotas">quotas</a>.  It must be the name of a
 locker that you are an AFS administrator of.  In particular, you or an
 AFS group you are a member of must have AFS rlidwka bits on the
 locker.  You can check who administers the LOCKER locker using the
 commands 'attach LOCKER; fs la /mit/LOCKER' on Athena.)  See also <a
 locker that you are an AFS administrator of.  In particular, you or an
 AFS group you are a member of must have AFS rlidwka bits on the
 locker.  You can check who administers the LOCKER locker using the
 commands 'attach LOCKER; fs la /mit/LOCKER' on Athena.)  See also <a
-href="help?subject=administrator">administrator</a>.""",
-                        administrator="""
+href="help?subject=Administrator">administrator</a>.""",
+                    'Administrator': """
 The administrator field determines who can access the console and
 power on and off the machine.  This can be either a user or a moira
 group.""",
 The administrator field determines who can access the console and
 power on and off the machine.  This can be either a user or a moira
 group.""",
-                        quotas="""
+                    'Quotas': """
 Quotas are determined on a per-locker basis.  Each locker may have a
 maximum of 512 megabytes of active ram, 50 gigabytes of disk, and 4
 active machines.""",
 Quotas are determined on a per-locker basis.  Each locker may have a
 maximum of 512 megabytes of active ram, 50 gigabytes of disk, and 4
 active machines.""",
-                        console="""
+                    'Console': """
 <strong>Framebuffer:</strong> At a Linux boot prompt in your VM, try
 setting <tt>fb=false</tt> to disable the framebuffer.  If you don't,
 your machine will run just fine, but the applet's display of the
 console will suffer artifacts.
 """
 <strong>Framebuffer:</strong> At a Linux boot prompt in your VM, try
 setting <tt>fb=false</tt> to disable the framebuffer.  If you don't,
 your machine will run just fine, but the applet's display of the
 console will suffer artifacts.
 """
-                   )
+                    }
 
     if not subjects:
         subjects = sorted(help_mapping.keys())
 
     if not subjects:
         subjects = sorted(help_mapping.keys())
@@ -531,7 +538,7 @@ def infoDict(user, machine):
                       ('memory', 'RAM'),
                       'DISK_INFO',
                       ('state', 'state (xen format)'),
                       ('memory', 'RAM'),
                       'DISK_INFO',
                       ('state', 'state (xen format)'),
-                      ('cpu_weight', 'CPU weight'+helppopup('cpu_weight')),
+                      ('cpu_weight', 'CPU weight'+helppopup('CPU Weight')),
                       ('on_reboot', 'Action on VM reboot'),
                       ('on_poweroff', 'Action on VM poweroff'),
                       ('on_crash', 'Action on VM crash'),
                       ('on_reboot', 'Action on VM reboot'),
                       ('on_poweroff', 'Action on VM poweroff'),
                       ('on_crash', 'Action on VM crash'),
@@ -576,8 +583,9 @@ def infoDict(user, machine):
     checkpoint.checkpoint('Got mem')
     max_disk = validation.maxDisk(user, machine)
     defaults = Defaults()
     checkpoint.checkpoint('Got mem')
     max_disk = validation.maxDisk(user, machine)
     defaults = Defaults()
-    for name in 'machine_id name administrator owner memory contact type'.split():
+    for name in 'machine_id name administrator owner memory contact'.split():
         setattr(defaults, name, getattr(machine, name))
         setattr(defaults, name, getattr(machine, name))
+    defaults.type = machine.type.type_id
     defaults.disk = "%0.2f" % (machine.disks[0].size/1024.)
     checkpoint.checkpoint('Got defaults')
     d = dict(user=user,
     defaults.disk = "%0.2f" % (machine.disks[0].size/1024.)
     checkpoint.checkpoint('Got defaults')
     d = dict(user=user,
@@ -589,7 +597,7 @@ def infoDict(user, machine):
              ram=machine.memory,
              max_mem=max_mem,
              max_disk=max_disk,
              ram=machine.memory,
              max_mem=max_mem,
              max_disk=max_disk,
-             owner_help=helppopup("owner"),
+             owner_help=helppopup("Owner"),
              fields = fields)
     return d
 
              fields = fields)
     return d
 
@@ -600,13 +608,18 @@ def info(user, fields):
     checkpoint.checkpoint('Got infodict')
     return templates.info(searchList=[d])
 
     checkpoint.checkpoint('Got infodict')
     return templates.info(searchList=[d])
 
+def unauthFront(_, fields):
+    """Information for unauth'd users."""
+    return templates.unauth(searchList=[{'simple' : True}])
+
 mapping = dict(list=listVms,
                vnc=vnc,
                command=command,
                modify=modify,
                info=info,
                create=create,
 mapping = dict(list=listVms,
                vnc=vnc,
                command=command,
                modify=modify,
                info=info,
                create=create,
-               help=helpHandler)
+               help=helpHandler,
+               unauth=unauthFront)
 
 def printHeaders(headers):
     """Print a dictionary as HTTP headers."""
 
 def printHeaders(headers):
     """Print a dictionary as HTTP headers."""
@@ -617,8 +630,10 @@ def printHeaders(headers):
 
 def getUser():
     """Return the current user based on the SSL environment variables"""
 
 def getUser():
     """Return the current user based on the SSL environment variables"""
-    username = os.environ['SSL_CLIENT_S_DN_Email'].split("@")[0]
-    return username
+    email = os.environ.get('SSL_CLIENT_S_DN_Email', None)
+    if email is None:
+        return None
+    return email.split("@")[0]
 
 def main(operation, user, fields):
     start_time = time.time()
 
 def main(operation, user, fields):
     start_time = time.time()
@@ -642,7 +657,8 @@ def main(operation, user, fields):
         output_string =  str(output)
         checkpoint.checkpoint('output as a string')
         print output_string
         output_string =  str(output)
         checkpoint.checkpoint('output as a string')
         print output_string
-        print '<!-- <pre>%s</pre> -->' % checkpoint
+        if fields.has_key('timedebug'):
+            print '<pre>%s</pre>' % checkpoint
     except Exception, err:
         if not fields.has_key('js'):
             if isinstance(err, CodeError):
     except Exception, err:
         if not fields.has_key('js'):
             if isinstance(err, CodeError):
@@ -657,7 +673,7 @@ def main(operation, user, fields):
                 sys.exit(1)
         print 'Content-Type: text/plain\n'
         print 'Uh-oh!  We experienced an error.'
                 sys.exit(1)
         print 'Content-Type: text/plain\n'
         print 'Uh-oh!  We experienced an error.'
-        print 'Please email sipb-xen@mit.edu with the contents of this page.'
+        print 'Please email xvm-dev@mit.edu with the contents of this page.'
         print '----'
         e = revertStandardError()
         print e
         print '----'
         e = revertStandardError()
         print e
@@ -666,6 +682,13 @@ def main(operation, user, fields):
 
 if __name__ == '__main__':
     fields = cgi.FieldStorage()
 
 if __name__ == '__main__':
     fields = cgi.FieldStorage()
+
+    if fields.has_key('sqldebug'):
+        import logging
+        logging.basicConfig()
+        logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
+        logging.getLogger('sqlalchemy.orm.unitofwork').setLevel(logging.INFO)
+
     u = getUser()
     g.user = u
     operation = os.environ.get('PATH_INFO', '')
     u = getUser()
     g.user = u
     operation = os.environ.get('PATH_INFO', '')
@@ -674,6 +697,9 @@ if __name__ == '__main__':
         print 'Location: ' + os.environ['SCRIPT_NAME']+'/\n'
         sys.exit(0)
 
         print 'Location: ' + os.environ['SCRIPT_NAME']+'/\n'
         sys.exit(0)
 
+    if u is None:
+        operation = 'unauth'
+
     if operation.startswith('/'):
         operation = operation[1:]
     if not operation:
     if operation.startswith('/'):
         operation = operation[1:]
     if not operation: