Store a little global state to avoid an extra remctls.
[invirt/packages/invirt-web.git] / templates / main.py
index 984f3b8..8de8a37 100755 (executable)
@@ -37,7 +37,17 @@ class CodeError(MyException):
     """Exception for internal errors or bad faith input."""
     pass
 
+class Global(object):
+    def __init__(self, user):
+        self.user = user
 
+    def __get_uptimes(self):
+        if not hasattr(self, '_uptimes'):
+            self._uptimes = getUptimes(self.machines)
+        return self._uptimes
+    uptimes = property(__get_uptimes)
+
+g = None
 
 def helppopup(subj):
     """Return HTML code for a (?) link to a specified help topic"""
@@ -72,7 +82,7 @@ def getMachinesByOwner(owner):
     """Return the machines owned by a given owner."""
     return Machine.select_by(owner=owner)
 
-def maxMemory(user, machine=None, on=None):
+def maxMemory(user, machine=None):
     """Return the maximum memory for a machine or a user.
 
     If machine is None, return the memory available for a new 
@@ -83,9 +93,7 @@ def maxMemory(user, machine=None, on=None):
     """
 
     machines = getMachinesByOwner(user.username)
-    if on is None:
-        on = getUptimes(machines)
-    active_machines = [x for x in machines if on[x]]
+    active_machines = [x for x in machines if g.uptimes[x]]
     mem_usage = sum([x.memory for x in active_machines if x != machine])
     return min(MAX_MEMORY_SINGLE, MAX_MEMORY_TOTAL-mem_usage)
 
@@ -95,11 +103,9 @@ def maxDisk(user, machine=None):
                       for x in machines if x != machine])
     return min(MAX_DISK_SINGLE, MAX_DISK_TOTAL-disk_usage/1024.)
 
-def canAddVm(user, on=None):
+def canAddVm(user):
     machines = getMachinesByOwner(user.username)
-    if on is None:
-        on = getUptimes(machines)
-    active_machines = [x for x in machines if on[x]]
+    active_machines = [x for x in machines if g.uptimes[x]]
     return (len(machines) < MAX_VMS_TOTAL and
             len(active_machines) < MAX_VMS_ACTIVE)
 
@@ -159,9 +165,15 @@ def remctl(*args, **kws):
                           (args, p.stderr.read()))
     return p.stdout.read()
 
-def makeDisks():
-    """Update the lvm partitions to include all disks in the database."""
-    remctl('web', 'lvcreate')
+def lvcreate(machine, disk):
+    """Create a single disk for a machine"""
+    remctl('web', 'lvcreate', machine.name,
+           disk.guest_device_name, str(disk.size))
+    
+def makeDisks(machine):
+    """Update the lvm partitions to add a disk."""
+    for disk in machine.disks:
+        lvcreate(machine, disk)
 
 def bootMachine(machine, cdtype):
     """Boot a machine with a given boot CD.
@@ -286,7 +298,7 @@ def createVm(user, name, memory, disk, is_hvm, cdrom):
         transaction.rollback()
         raise
     registerMachine(machine)
-    makeDisks()
+    makeDisks(machine)
     # tell it to boot with cdrom
     bootMachine(machine, cdrom)
 
@@ -355,8 +367,7 @@ def listVms(user, fields):
     machines = [m for m in Machine.select() if haveAccess(user, m)]    
     on = {}
     has_vnc = {}
-    uptimes = getUptimes(machines)
-    on = uptimes
+    on = g.uptimes
     for m in machines:
         if not on[m]:
             has_vnc[m] = 'Off'
@@ -368,10 +379,10 @@ def listVms(user, fields):
     #         status = statusInfo(m)
     #         on[m.name] = status is not None
     #         has_vnc[m.name] = hasVnc(status)
-    max_mem=maxMemory(user, on=on)
+    max_mem=maxMemory(user)
     max_disk=maxDisk(user)
     d = dict(user=user,
-             can_add_vm=canAddVm(user, on=on),
+             can_add_vm=canAddVm(user),
              max_mem=max_mem,
              max_disk=max_disk,
              default_mem=max_mem,
@@ -432,7 +443,12 @@ def vnc(user, fields):
     token = cPickle.dumps(token)
     token = base64.urlsafe_b64encode(token)
     
+    status = statusInfo(machine)
+    has_vnc = hasVnc(status)
+    
     d = dict(user=user,
+             on=status,
+             has_vnc=has_vnc,
              machine=machine,
              hostname=os.environ.get('SERVER_NAME', 'localhost'),
              authtoken=token)
@@ -646,6 +662,7 @@ if __name__ == '__main__':
         username = "moo"
         email = 'moo@cow.com'
     u = User()
+    g = Global(u)
     if 'SSL_CLIENT_S_DN_Email' in os.environ:
         username = os.environ[ 'SSL_CLIENT_S_DN_Email'].split("@")[0]
         u.username = username