+ remctl('web', 'vmboot', machine.name)
+
+def registerMachine(machine):
+ """Register a machine to be controlled by the web interface"""
+ remctl('web', 'register', 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 == ')':
+ stack[-2].append(stack[-1])
+ stack.pop()
+ else:
+ if not v:
+ continue
+ stack[-1].extend(v.split())
+ return stack[-1]
+
+def statusInfo(machine):
+ value_string, err_string = remctl('list-long', machine.name, err=True)
+ if 'Unknown command' in err_string:
+ raise MyException("ERROR in remctl list-long %s is not registered" % (machine.name,))
+ elif 'does not exist' in err_string:
+ return None
+ elif err_string:
+ raise MyException("ERROR in remctl list-long %s: %s" % (machine.name, err_string))
+ status = parseStatus(value_string)
+ return status
+
+def hasVnc(status):
+ if status is None:
+ return False
+ for l in status:
+ if l[0] == 'device' and l[1][0] == 'vfb':
+ d = dict(l[1][1:])
+ return 'location' in d
+ return False