Made some changes requested by Broder.
[invirt/packages/invirt-remote.git] / server / usr / sbin / invirt-remote-create
index 0a95d35..add3113 100755 (executable)
@@ -12,12 +12,23 @@ from invirt.remote import bcast
 from subprocess import PIPE, Popen, call
 import sys
 import yaml
+import invirt.database
+
+def maxMemory(owner, xmlist):
+    """
+    Return the memory available for a new machine.
+    """
+    machines = invirt.database.Machine.query().filter_by(owner=owner)
+    (quota_total, quota_single) = invirt.database.Owner.getMemoryQuotas(owner)
+
+    active_machines = [m for m in machines if m.name in xmlist]
+    mem_usage = sum([x.memory for x in active_machines])
+    return min(quota_single, quota_total - mem_usage)
 
 def choose_host():
     # Query each of the hosts.
-    # XXX will the output of 'xm info' always be parseable YAML?
-    results = bcast('info')
-    return max((int(o['max_free_memory']), s) for (s, o) in results)[1]
+    results = bcast('availability')
+    return max((int(o), s) for (s, o) in results)[1]
 
 def main(argv):
     if len(argv) < 3:
@@ -26,7 +37,9 @@ def main(argv):
     operation = argv[1]
     machine_name = argv[2]
     args = argv[3:]
-    
+
+    invirt.database.connect()
+
     if operation == 'install':
         options = dict(arg.split('=', 1) for arg in args)
         valid_keys = set(('mirror', 'dist', 'arch', 'imagesize', 'noinstall'))
@@ -50,6 +63,17 @@ def main(argv):
                               % (machine_name, host))
         return 1
 
+    if operation == "create":
+        machine = invirt.database.Machine.query().filter_by(name=machine_name).first()
+
+        owner = machine.owner
+        vm_memory = machine.memory
+
+        max_memory = maxMemory(owner, vms.keys())
+        if vm_memory > max_memory:
+            print >>sys.stderr, "owner %s requested %d MB of memory for vm %s; %d MB allowed" % (owner, vm_memory, machine_name, max_memory)
+            return 1
+
     host = choose_host()
     print 'Creating on host %s...' % host
     sys.stdout.flush()