import simplejson
import sys
import time
+import urllib
from StringIO import StringIO
def revertStandardError():
import templates
from Cheetah.Template import Template
import sipb_xen_database
-from sipb_xen_database import Machine, CDROM, ctx, connect, MachineAccess, Type
+from sipb_xen_database import Machine, CDROM, ctx, connect, MachineAccess, Type, Autoinstall
import validation
+import cache_acls
from webcommon import InvalidInput, CodeError, g
import controls
checkpoint = Checkpoint()
+def jquote(string):
+ return "'" + string.replace('\\', '\\\\').replace("'", "\\'").replace('\n', '\\n') + "'"
def helppopup(subj):
"""Return HTML code for a (?) link to a specified help topic"""
- return ('<span class="helplink"><a href="help?subject=' + subj +
- '&simple=true" target="_blank" ' +
- 'onclick="return helppopup(\'' + subj + '\')">(?)</a></span>')
+ return ('<span class="helplink"><a href="help?' +
+ cgi.escape(urllib.urlencode(dict(subject=subj, simple='true')))
+ +'" target="_blank" ' +
+ 'onclick="return helppopup(' + cgi.escape(jquote(subj)) + ')">(?)</a></span>')
def makeErrorPre(old, addition):
if addition is None:
memory = 256
disk = 4.0
cdrom = ''
+ autoinstall = ''
name = ''
+ type = 'linux-hvm'
+
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:
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 = {}
- on = g.uptimes
+ xmlist = g.xmlist
checkpoint.checkpoint('Got uptimes')
for m in machines:
- m.uptime = g.uptimes.get(m)
- if not on[m]:
+ if m not in xmlist:
has_vnc[m] = 'Off'
- elif m.type.hvm:
- has_vnc[m] = True
+ m.uptime = None
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_disk=max_disk,
defaults=defaults,
machines=machines,
- has_vnc=has_vnc,
- uptimes=g.uptimes,
- cdroms=CDROM.select())
+ has_vnc=has_vnc)
return d
def listVms(user, fields):
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
disk.size = disksize
ctx.current.save(disk)
- if owner is not None:
+ update_acl = False
+ if owner is not None and owner != machine.owner:
machine.owner = owner
+ update_acl = True
if name is not None:
machine.name = name
- if admin is not None:
+ if admin is not None and admin != machine.administrator:
machine.administrator = admin
+ update_acl = True
if contact is not None:
machine.contact = contact
ctx.current.save(machine)
+ if update_acl:
+ cache_acls.refreshMachine(machine)
transaction.commit()
except:
transaction.rollback()
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
-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.""",
- 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.""",
- cpu_weight="""
+ 'CPU Weight': """
Don't ask us! We're as mystified as you are.""",
- owner="""
+ 'Owner': """
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
-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.""",
- 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.""",
- 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.
"""
- )
+ }
if not subjects:
subjects = sorted(help_mapping.keys())
('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'),
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))
+ defaults.type = machine.type.type_id
defaults.disk = "%0.2f" % (machine.disks[0].size/1024.)
checkpoint.checkpoint('Got defaults')
d = dict(user=user,
- cdroms=CDROM.select(),
on=status is not None,
machine=machine,
defaults=defaults,
ram=machine.memory,
max_mem=max_mem,
max_disk=max_disk,
- owner_help=helppopup("owner"),
+ owner_help=helppopup("Owner"),
fields = fields)
return 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,
- help=helpHandler)
+ help=helpHandler,
+ unauth=unauthFront)
def printHeaders(headers):
"""Print a dictionary as HTTP headers."""
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()
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):
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
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', '')
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: