import sys
import time
import urllib
+import socket
+import cherrypy
from StringIO import StringIO
+from view import View
+
+class InvirtWeb(View):
+ @cherrypy.expose
+ def helloworld(self):
+ return "Hello world!"
def revertStandardError():
"""Move stderr to stdout, and return the contents of the old stderr."""
from invirt.database import Machine, CDROM, session, connect, MachineAccess, Type, Autoinstall
from invirt.config import structs as config
from invirt.common import InvalidInput, CodeError
-from invirt.remctl import remctl
def pathSplit(path):
if path.startswith('/'):
if max_memory is not None:
self.memory = min(self.memory, max_memory)
if max_disk is not None:
- self.max_disk = min(self.disk, max_disk)
+ self.disk = min(self.disk, max_disk)
for key in kws:
setattr(self, key, kws[key])
kws = dict([(kw, fields.getfirst(kw)) for kw in 'name description owner memory disksize vmtype cdrom autoinstall'.split()])
validate = validation.Validate(username, state, strict=True, **kws)
return dict(contact=username, name=validate.name, description=validate.description, memory=validate.memory,
- disksize=validate.disksize, owner=validate.owner, machine_type=validate.vmtype,
+ disksize=validate.disksize, owner=validate.owner, machine_type=getattr(validate, 'vmtype', Defaults.type),
cdrom=getattr(validate, 'cdrom', None),
autoinstall=getattr(validate, 'autoinstall', None))
checkpoint.checkpoint('Got max mem/disk')
defaults = Defaults(max_memory=max_memory,
max_disk=max_disk,
- owner=username,
- cdrom='gutsy-i386')
+ owner=username)
checkpoint.checkpoint('Got defaults')
def sortkey(machine):
return (machine.owner != username, machine.owner, machine.name)
"""
machine = validation.Validate(username, state, machine_id=fields.getfirst('machine_id')).machine
- token = controls.remctl('control', machine.name, 'vnctoken').strip()
+ token = controls.vnctoken(machine)
host = controls.listHost(machine)
if host:
port = 10003 + [h.hostname for h in config.hosts].index(host)
XXX this should be merged with the similar logic in DNS and DHCP.
"""
- if nic.hostname and '.' in nic.hostname:
- return nic.hostname
+ if nic.hostname:
+ hostname = nic.hostname
elif nic.machine:
- return nic.machine.name + '.' + config.dns.domains[0]
+ hostname = nic.machine.name
else:
return None
-
+ if '.' in hostname:
+ return hostname
+ else:
+ return hostname + '.' + config.dns.domains[0]
def getNicInfo(data_dict, machine):
"""Helper function for info, get data on nics for a machine.
nic_fields = []
for i in range(len(machine.nics)):
nic_fields.extend([(x % i, y % i) for x, y in nic_fields_template])
- if not i:
- data_dict['nic%s_hostname' % i] = getHostname(machine.nics[i])
+ data_dict['nic%s_hostname' % i] = getHostname(machine.nics[i])
data_dict['nic%s_mac' % i] = machine.nics[i].mac_addr
data_dict['nic%s_ip' % i] = machine.nics[i].ip
if len(machine.nics) == 1:
update_acl = True
if hasattr(validate, 'name'):
machine.name = validate.name
+ for n in machine.nics:
+ if n.hostname == oldname:
+ n.hostname = validate.name
if hasattr(validate, 'description'):
machine.description = validate.description
if hasattr(validate, 'admin') and validate.admin != machine.administrator:
session.save_or_update(machine)
if update_acl:
- print >> sys.stderr, machine, machine.administrator
cache_acls.refreshMachine(machine)
session.commit()
except:
simple = fields.getfirst('simple')
subjects = fields.getlist('subject')
- help_mapping = {'ParaVM Console': """
+ help_mapping = {
+ 'Autoinstalls': """
+The autoinstaller builds a minimal Debian or Ubuntu system to run as a
+ParaVM. You can access the resulting system by logging into the <a
+href="help?simple=true&subject=ParaVM+Console">serial console server</a>
+with your Kerberos tickets; there is no root password so sshd will
+refuse login.</p>
+
+<p>Under the covers, the autoinstaller uses our own patched version of
+xen-create-image, which is a tool based on debootstrap. If you log
+into the serial console while the install is running, you can watch
+it.
+""",
+ '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 console.%s, using the name of the machine as your
-username.""" % config.dns.domains[0],
+to %s, using the name of the machine as your
+username.""" % config.console.hostname,
'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.""",
+ParaVM machines rely on a modified kernel to communicate directly with
+the hypervisor. HVMs support boot CDs of any operating system, and
+the VNC console applet. The three-minute autoinstaller produces
+ParaVMs. ParaVMs typically are more efficient, and always support the
+<a href="help?subject=ParaVM+Console">console server</a>.</p>
+
+<p>More details are <a
+href="https://xvm.scripts.mit.edu/wiki/Paravirtualization">on the
+wiki</a>, including steps to prepare an HVM guest to boot as a ParaVM
+(which you can skip by using the autoinstaller to begin with.)</p>
+
+<p>We recommend using a ParaVM when possible and an HVM when necessary.
+""",
'CPU Weight': """
Don't ask us! We're as mystified as you are.""",
'Owner': """
group.""",
'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
+maximum of 512 mebibytes of active ram, 50 gibibytes of disk, and 4
active machines.""",
'Console': """
<strong>Framebuffer:</strong> At a Linux boot prompt in your VM, try
console will suffer artifacts.
""",
'Windows': """
-<strong>Windows Vista:</strong> The Vista image is licensed for all MIT students and will automatically activate off the network; see <a href="/static/msca-email.txt">the licensing confirmation e-mail</a> for details. The installer req uires 512 MB RAM and at least 7.5 GB disk space (15 GB or more recommended).<br>
+<strong>Windows Vista:</strong> The Vista image is licensed for all MIT students and will automatically activate off the network; see <a href="/static/msca-email.txt">the licensing confirmation e-mail</a> for details. The installer requires 512 MiB RAM and at least 7.5 GiB disk space (15 GiB or more recommended).<br>
<strong>Windows XP:</strong> This is the volume license CD image. You will need your own volume license key to complete the install. We do not have these available for the general MIT community; ask your department if they have one.
"""
}
cpu_time_float = float(main_status.get('cpu_time', 0))
cputime = datetime.timedelta(seconds=int(cpu_time_float))
checkpoint.checkpoint('Status')
- display_fields = """name uptime memory state cpu_weight on_reboot
- on_poweroff on_crash on_xend_start on_xend_stop bootloader""".split()
display_fields = [('name', 'Name'),
('description', 'Description'),
('owner', 'Owner'),
'DISK_INFO',
('state', 'state (xen format)'),
('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'),
- ('on_xend_start', 'Action on Xen start'),
- ('on_xend_stop', 'Action on Xen stop'),
- ('bootloader', 'Bootloader options'),
]
fields = []
machine_info = {}
def unauthFront(_, _2, _3, fields):
"""Information for unauth'd users."""
- return templates.unauth(searchList=[{'simple' : True}])
+ return templates.unauth(searchList=[{'simple' : True,
+ 'hostname' : socket.getfqdn()}])
def admin(username, state, path, fields):
if path == '':
return ({'Status': '303 See Other',
'Location': 'admin/'},
"You shouldn't see this message.")
- if not username in getAfsGroupMembers(config.web.adminacl, 'athena.mit.edu'):
+ if not username in getAfsGroupMembers(config.adminacl, 'athena.mit.edu'):
raise InvalidInput('username', username,
- 'Not in admin group %s.' % config.web.adminacl)
+ 'Not in admin group %s.' % config.adminacl)
newstate = State(username, isadmin=True)
newstate.environ = state.environ
return handler(username, newstate, path, fields)
%s
""" % (to, config.web.hostname, subject, body)
- p = subprocess.Popen(['/usr/sbin/sendmail', to], stdin=subprocess.PIPE)
+ p = subprocess.Popen(['/usr/sbin/sendmail', '-f', to, to],
+ stdin=subprocess.PIPE)
p.stdin.write(mail)
p.stdin.close()
p.wait()
def getUser(environ):
"""Return the current user based on the SSL environment variables"""
- return environ.get('REMOTE_USER', None)
+ user = environ.get('REMOTE_USER')
+ if user is None:
+ return
+
+ if environ.get('AUTH_TYPE') == 'Negotiate':
+ # Convert the krb5 principal into a krb4 username
+ if not user.endswith('@%s' % config.kerberos.realm):
+ return
+ else:
+ return user.split('@')[0].replace('/', '.')
+ else:
+ return user
def handler(username, state, path, fields):
operation, path = pathSplit(path)