import hmac
import datetime
-print 'Content-Type: text/html\n'
sys.stderr = sys.stdout
sys.path.append('/home/ecprice/.local/lib/python2.5/site-packages')
class MyException(Exception):
pass
+def helppopup(subj):
+ return '<span class="helplink"><a href="help?subject='+subj+'&simple=true" target="_blank" onclick="return helppopup(\''+subj+'\')">(?)</a></span>'
+
+
+global_dict = {}
+global_dict['helppopup'] = helppopup
+
+
# ... and stolen from xend/uuid.py
def randomUUID():
"""Generate a random UUID."""
return 10.0
def haveAccess(user, machine):
- return True
+ if user.username == 'moo':
+ return True
+ return machine.owner == user.username
def error(op, user, fields, err):
d = dict(op=op, user=user, errorMessage=str(err))
- print Template(file='error.tmpl', searchList=d);
+ print Template(file='error.tmpl', searchList=[d, global_dict]);
def validMachineName(name):
"""Check that name is valid for a machine name"""
charset = string.ascii_letters + string.digits + '-_'
if name[0] in '-_' or len(name) > 22:
return False
- return all(x in charset for x in name)
+ for x in name:
+ if x not in charset:
+ return False
+ return True
def kinit(username = 'tabbott/extra', keytab = '/etc/tabbott.keytab'):
"""Kinit with a given username and keytab"""
return machine
-def create(user, fields):
- name = fields.getfirst('name')
- if not validMachineName(name):
- raise MyException("Invalid name '%s'" % name)
- name = user.username + '_' + name.lower()
-
- if Machine.get_by(name=name):
- raise MyException("A machine named '%s' already exists" % name)
-
- memory = fields.getfirst('memory')
+def validMemory(user, memory, machine=None):
try:
memory = int(memory)
if memory <= 0:
raise ValueError
except ValueError:
raise MyException("Invalid memory amount")
- if memory > maxMemory(user):
+ if memory > maxMemory(user, machine):
raise MyException("Too much memory requested")
-
- disk = fields.getfirst('disk')
+ return memory
+
+def validDisk(user, disk, machine=None):
try:
disk = float(disk)
- if disk > maxDisk(user):
+ if disk > maxDisk(user, machine):
raise MyException("Too much disk requested")
disk = int(disk * 1024)
if disk <= 0:
raise ValueError
except ValueError:
raise MyException("Invalid disk amount")
+ return disk
+
+def create(user, fields):
+ name = fields.getfirst('name')
+ if not validMachineName(name):
+ raise MyException("Invalid name '%s'" % name)
+ name = user.username + '_' + name.lower()
+
+ if Machine.get_by(name=name):
+ raise MyException("A machine named '%s' already exists" % name)
+
+ memory = fields.getfirst('memory')
+ memory = validMemory(user, memory)
+ disk = fields.getfirst('disk')
+ disk = validDisk(user, disk)
+
vm_type = fields.getfirst('vmtype')
if vm_type not in ('hvm', 'paravm'):
raise MyException("Invalid vm type '%s'" % vm_type)
d = dict(user=user,
machine=machine)
print Template(file='create.tmpl',
- searchList=d);
+ searchList=[d, global_dict]);
def listVms(user, fields):
- machines = Machine.select()
+ machines = [m for m in Machine.select() if haveAccess(user, m)]
on = {}
has_vnc = {}
uptimes = getUptimes(machines)
- on = has_vnc = uptimes
+ on = uptimes
+ for m in machines:
+ if not on.get(m.name):
+ has_vnc[m.name] = 'Off'
+ elif m.type.hvm:
+ has_vnc[m.name] = True
+ else:
+ has_vnc[m.name] = "ParaVM"+helppopup("paravm_console")
# for m in machines:
# status = statusInfo(m)
# on[m.name] = status is not None
has_vnc=has_vnc,
uptimes=uptimes,
cdroms=CDROM.select())
- print Template(file='list.tmpl', searchList=d)
+ print Template(file='list.tmpl', searchList=[d, global_dict])
def testMachineId(user, machineId, exists=True):
if machineId is None:
hostname=os.environ.get('SERVER_NAME', 'localhost'),
authtoken=token)
print Template(file='vnc.tmpl',
- searchList=d)
+ searchList=[d, global_dict])
def getNicInfo(data_dict, machine):
data_dict['num_nics'] = len(machine.nics)
d = dict(user=user,
command=action,
machine=machine)
- print Template(file="command.tmpl", searchList=d)
+ print Template(file="command.tmpl", searchList=[d, global_dict])
def modify(user, fields):
machine = testMachineId(user, fields.getfirst('machine_id'))
+def help(user, fields):
+ simple = fields.getfirst('simple')
+ subjects = fields.getlist('subject')
+
+ mapping = dict(paravm_console="""
+ParaVM machines do not support console access over VNC. To access
+these machines, you either need to boot with a liveCD and ssh in or
+hope that the sipb-xen maintainers add support for serial consoles.""",
+ 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.""",
+ cpu_weight="""Don't ask us! We're as mystified as you are.""")
+
+ d = dict(user=user,
+ simple=simple,
+ subjects=subjects,
+ mapping=mapping)
+
+ print Template(file="help.tmpl", searchList=[d, global_dict])
+
def info(user, fields):
machine = testMachineId(user, fields.getfirst('machine_id'))
display_fields = [('name', 'Name'),
('owner', 'Owner'),
('contact', 'Contact'),
+ ('type', 'Type'),
'NIC_INFO',
('uptime', 'uptime'),
('cputime', 'CPU usage'),
('memory', 'RAM'),
'DISK_INFO',
('state', 'state (xen format)'),
- ('cpu_weight', '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'),
]
fields = []
machine_info = {}
+ machine_info['type'] = machine.type.hvm and 'HVM' or 'ParaVM'
machine_info['owner'] = machine.owner
machine_info['contact'] = machine.contact
maxdisk=maxDisk(user, machine),
fields = fields)
print Template(file='info.tmpl',
- searchList=d)
+ searchList=[d, global_dict])
mapping = dict(list=listVms,
vnc=vnc,
command=command,
modify=modify,
info=info,
- create=create)
+ create=create,
+ help=help)
if __name__ == '__main__':
start_time = time.time()
username = "moo"
email = 'moo@cow.com'
u = User()
+ if 'SSL_CLIENT_S_DN_Email' in os.environ:
+ username = os.environ[ 'SSL_CLIENT_S_DN_Email'].split("@")[0]
+ u.username = username
+ u.email = os.environ[ 'SSL_CLIENT_S_DN_Email']
+ else:
+ u.username = 'nobody'
+ u.email = None
connect('postgres://sipb-xen@sipb-xen-dev/sipb_xen')
operation = os.environ.get('PATH_INFO', '')
+ #print 'Content-Type: text/plain\n'
+ #print operation
if not operation:
- pass
- #XXX do redirect
+ print "Status: 301 Moved Permanently"
+ print 'Location: ' + os.environ['SCRIPT_NAME']+'/\n'
+ sys.exit(0)
+ print 'Content-Type: text/html\n'
if operation.startswith('/'):
operation = operation[1:]
lambda u, e:
error(operation, u, e,
"Invalid operation '%s'" % operation))
+ if fun not in (help, ):
+ connect('postgres://sipb-xen@sipb-xen-dev/sipb_xen')
try:
fun(u, fields)
except MyException, err: