<td>Hostname</td>
<td>Uptime</td>
<td>VNC</td>
- <td>Restart?</td>
+ <td></td>
#for $machine in $machines:
<tr>
<td><a href="info?machine_id=$machine.machine_id">$machine.name</a></td>
<td></td>
#end if
<td>#slurp
-#if $uptimes.get($machine.name)
-$uptimes[$machine.name]#slurp
+#if $uptimes[$machine]
+$uptimes[$machine]#slurp
#else
Off#slurp
#end if
</td>
<td>#slurp
-#if $has_vnc.get($machine.name) == True
+#if $has_vnc[$machine] == True
<a href="vnc?machine_id=$machine.machine_id">Console</a>#slurp
#else
-$has_vnc.get($machine.name)
+$has_vnc[$machine]
#end if
</td>
<td>
<form action="command">
<input type="hidden" name="machine_id"
value="$machine.machine_id"/>
- <input type="submit" class="button"
- value="Reboot"/>
+#if $uptimes[$machine]
+ <input type="submit" class="button" name="action" value="Shutdown"/>
+#else
+ <input type="submit" class="button" name="action" value="Power on"/>
+#end if
</form>
</td>
</tr>
#end for
</table>
#end if
-
+#if $can_add_vm
<p>Create a new VM:</p>
<form action="create" method="POST">
<table>
</tr>
<tr>
<td>Memory</td>
- <td><input type="text" name="memory" value="$maxmem" size=3/> megabytes ($maxmem max)</td>
+ <td><input type="text" name="memory" value="$default_mem" size=3/> megabytes ($max_mem max)</td>
</tr>
<tr>
<td>Disk</td>
- <td><input type="text" name="disk" value="$maxdisk" size=3/> gigabytes ($maxdisk max)</td>
+ <td><input type="text" name="disk" value="$default_disk" size=3/> gigabytes (${"%0.1f" % ($max_disk-0.05)} max)</td>
</tr>
<tr>
<td>HVM/ParaVM$helppopup('hvm_paravm')</td>
</table>
<input type="submit" class="button" value="Create it!"/>
</form>
-
+#else
+<p>You are at the maximum number of VMs.</p>
+#end if
#end def
return "-".join(["%02x" * 4, "%02x" * 2, "%02x" * 2, "%02x" * 2,
"%02x" * 6]) % tuple(u)
-def maxMemory(user, machine=None):
- return 256
+MAX_MEMORY_TOTAL = 512
+MAX_MEMORY_SINGLE = 256
+MIN_MEMORY_SINGLE = 16
+MAX_DISK_TOTAL = 50
+MAX_DISK_SINGLE = 50
+MIN_DISK_SINGLE = 0.1
+MAX_VMS_TOTAL = 10
+MAX_VMS_ACTIVE = 4
+
+def getMachinesOwner(owner):
+ return Machine.select_by(owner=owner)
+
+def maxMemory(user, machine=None, on=None):
+ machines = getMachinesOwner(user.username)
+ if on is None:
+ on = getUptimes(machines)
+ active_machines = [x for x in machines if on[x]]
+ mem_usage = sum([x.memory for x in active_machines if x != machine])
+ return min(MAX_MEMORY_SINGLE, MAX_MEMORY_TOTAL-mem_usage)
def maxDisk(user, machine=None):
- return 10.0
+ machines = getMachinesOwner(user.username)
+ disk_usage = sum([sum([y.size for y in x.disks])
+ for x in machines if x != machine])
+ return min(MAX_DISK_SINGLE, MAX_DISK_TOTAL-disk_usage/1024.)
+
+def canAddVm(user, on=None):
+ machines = getMachinesOwner(user.username)
+ if on is None:
+ on = getUptimes(machines)
+ active_machines = [x for x in machines if on[x]]
+ return (len(machines) < MAX_VMS_TOTAL and
+ len(active_machines) < MAX_VMS_ACTIVE)
def haveAccess(user, machine):
if user.username == 'moo':
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if kws.get('err'):
+ p.wait()
return p.stdout.read(), p.stderr.read()
if p.wait():
- print >> sys.stderr, 'ERROR on remctl ', args
- print >> sys.stderr, p.stderr.read()
+ raise MyException('ERROR on remctl %s: %s' %
+ (args, p.stderr.read()))
return p.stdout.read()
def makeDisks():
name, id = lst[:2]
uptime = ' '.join(lst[2:])
d[name] = uptime
- return d
+ ans = {}
+ for m in machines:
+ ans[m] = d.get(m.name)
+ return ans
def statusInfo(machine):
"""Return the status list for a given machine.
# put stuff in the table
transaction = ctx.current.create_transaction()
try:
+ if memory > maxMemory(user):
+ raise MyException("Too much memory requested")
+ if disk > maxDisk(user) * 1024:
+ raise MyException("Too much disk requested")
+ if not canAddVm(user):
+ raise MyException("Too many VMs requested")
res = meta.engine.execute('select nextval(\'"machines_machine_id_seq"\')')
id = res.fetchone()[0]
machine = Machine()
except:
transaction.rollback()
raise
- makeDisks()
registerMachine(machine)
+ makeDisks()
# tell it to boot with cdrom
bootMachine(machine, cdrom)
def validMemory(user, memory, machine=None):
try:
memory = int(memory)
- if memory <= 0:
+ if memory < MIN_MEMORY_SINGLE:
raise ValueError
except ValueError:
- raise MyException("Invalid memory amount")
+ raise MyException("Invalid memory amount; must be at least %s MB" %
+ MIN_MEMORY_SINGLE)
if memory > maxMemory(user, machine):
raise MyException("Too much memory requested")
return memory
if disk > maxDisk(user, machine):
raise MyException("Too much disk requested")
disk = int(disk * 1024)
- if disk <= 0:
+ if disk < MIN_DISK_SINGLE * 1024:
raise ValueError
except ValueError:
- raise MyException("Invalid disk amount")
+ raise MyException("Invalid disk amount; minimum is %s GB" %
+ MIN_DISK_SINGLE)
return disk
def create(user, fields):
uptimes = getUptimes(machines)
on = uptimes
for m in machines:
- if not on.get(m.name):
- has_vnc[m.name] = 'Off'
+ if not on[m]:
+ has_vnc[m] = 'Off'
elif m.type.hvm:
- has_vnc[m.name] = True
+ has_vnc[m] = True
else:
- has_vnc[m.name] = "ParaVM"+helppopup("paravm_console")
+ has_vnc[m] = "ParaVM"+helppopup("paravm_console")
# for m in machines:
# status = statusInfo(m)
# on[m.name] = status is not None
# has_vnc[m.name] = hasVnc(status)
+ max_mem=maxMemory(user, on=on)
+ max_disk=maxDisk(user)
d = dict(user=user,
- maxmem=maxMemory(user),
- maxdisk=maxDisk(user),
+ can_add_vm=canAddVm(user, on=on),
+ max_mem=max_mem,
+ max_disk=max_disk,
+ default_mem=max_mem,
+ default_disk=min(4.0, max_disk),
machines=machines,
has_vnc=has_vnc,
uptimes=uptimes,
else:
remctl('reboot', machine.name)
elif action == 'Power on':
+ if maxMemory(user) < machine.memory:
+ raise MyException("You don't have enough free RAM quota")
bootMachine(machine, cdrom)
elif action == 'Power off':
remctl('destroy', machine.name)
else:
pass
#fields.append((disp, None))
-
+ max_mem = maxMemory(user, machine)
+ max_disk = maxDisk(user, machine)
d = dict(user=user,
cdroms=CDROM.select(),
on=status is not None,
has_vnc=has_vnc,
uptime=str(uptime),
ram=machine.memory,
- maxmem=maxMemory(user, machine),
- maxdisk=maxDisk(user, machine),
+ max_mem=max_mem,
+ max_disk=max_disk,
fields = fields)
print Template(file='info.tmpl',
searchList=[d, global_dict])
u.username = username
u.email = os.environ[ 'SSL_CLIENT_S_DN_Email']
else:
- u.username = 'nobody'
- u.email = None
+ u.username = 'moo'
+ u.email = 'nobody'
connect('postgres://sipb-xen@sipb-xen-dev/sipb_xen')
operation = os.environ.get('PATH_INFO', '')
#print 'Content-Type: text/plain\n'