- return Template(file='invalid.tmpl', searchList=[d, global_dict]);
-
-def validMachineName(name):
- """Check that name is valid for a machine name"""
- if not name:
- return False
- charset = string.ascii_letters + string.digits + '-_'
- if name[0] in '-_' or len(name) > 22:
- return False
- 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"""
-
- p = subprocess.Popen(['kinit', "-k", "-t", keytab, username],
- stderr=subprocess.PIPE)
- e = p.wait()
- if e:
- raise CodeError("Error %s in kinit: %s" % (e, p.stderr.read()))
-
-def checkKinit():
- """If we lack tickets, kinit."""
- p = subprocess.Popen(['klist', '-s'])
- if p.wait():
- kinit()
-
-def remctl(*args, **kws):
- """Perform a remctl and return the output.
-
- kinits if necessary, and outputs errors to stderr.
- """
- checkKinit()
- p = subprocess.Popen(['remctl', 'black-mesa.mit.edu']
- + list(args),
- 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 %s:' % args
- print >> sys.stderr, p.stderr.read()
- raise CodeError('ERROR on remctl')
- return p.stdout.read()
-
-def lvcreate(machine, disk):
- """Create a single disk for a machine"""
- remctl('web', 'lvcreate', machine.name,
- disk.guest_device_name, str(disk.size))
-
-def makeDisks(machine):
- """Update the lvm partitions to add a disk."""
- for disk in machine.disks:
- lvcreate(machine, disk)
-
-def bootMachine(machine, cdtype):
- """Boot a machine with a given boot CD.
-
- If cdtype is None, give no boot cd. Otherwise, it is the string
- id of the CD (e.g. 'gutsy_i386')
- """
- if cdtype is not None:
- remctl('web', 'vmboot', machine.name,
- cdtype)
- else:
- remctl('web', 'vmboot', machine.name)
-
-def registerMachine(machine):
- """Register a machine to be controlled by the web interface"""
- remctl('web', 'register', machine.name)
-
-def unregisterMachine(machine):
- """Unregister a machine to not be controlled by the web interface"""
- remctl('web', 'unregister', machine.name)
-
-def parseStatus(s):
- """Parse a status string into nested tuples of strings.
-
- s = output of xm list --long <machine_name>
- """
- values = re.split('([()])', s)
- stack = [[]]
- for v in values[2:-2]: #remove initial and final '()'
- if not v:
- continue
- v = v.strip()
- if v == '(':
- stack.append([])
- elif v == ')':
- if len(stack[-1]) == 1:
- stack[-1].append('')
- stack[-2].append(stack[-1])
- stack.pop()
- else:
- if not v:
- continue
- stack[-1].extend(v.split())
- return stack[-1]
-
-def getUptimes(machines=None):
- """Return a dictionary mapping machine names to uptime strings"""
- value_string = remctl('web', 'listvms')
- lines = value_string.splitlines()
- d = {}
- for line in lines:
- lst = line.split()
- name, id = lst[:2]
- uptime = ' '.join(lst[2:])
- d[name] = uptime
- ans = {}
- for m in machines:
- ans[m] = d.get(m.name)
- return ans
-
-def statusInfo(machine):
- """Return the status list for a given machine.
-
- Gets and parses xm list --long
- """
- value_string, err_string = remctl('list-long', machine.name, err=True)
- if 'Unknown command' in err_string:
- raise CodeError("ERROR in remctl list-long %s is not registered" % (machine.name,))
- elif 'does not exist' in err_string:
- return None
- elif err_string:
- raise CodeError("ERROR in remctl list-long %s: %s" % (machine.name, err_string))
- status = parseStatus(value_string)
- return status