3 Picks a host to "create" (boot) a VM on, and does so.
5 Current load-balancing algorithm: wherever there's more free RAM.
7 TODO: use a lock to avoid creating the same VM twice in a race
11 from subprocess import PIPE, Popen, call
17 # Query each of the hosts.
18 # TODO get `servers` from a real list of all the VM hosts (instead of
19 # hardcoding the list here)
20 servers = ['black-mesa.mit.edu', 'sx-blade-2.mit.edu']
22 Popen(['remctl', server, 'remote', 'web', 'info'], stdout=PIPE))
23 for server in servers]
24 outputs = [(s, p.communicate()[0]) for (s, p) in pipes]
27 raise RuntimeError("remctl to host %s returned non-zero exit status %d"
29 results = [(s, yaml.load(o, yaml.CSafeLoader)) for (s, o) in outputs]
30 # XXX will the output of 'xm info' always be parseable YAML?
32 return max( (int(o['free_memory']), s) for (s, o) in results )[1]
37 print >>sys.stderr, "usage: sipb-xen-remote-create <machine> [<other args...>]"
39 machine_name = argv[1]
43 p = Popen(['/usr/sbin/sipb-xen-remote-proxy-web', 'listvms'], stdout=PIPE)
44 output = p.communicate()[0]
46 raise RuntimeError("Command '%s' returned non-zero exit status %d"
47 % ('sipb-xen-remote-proxy-web', p.returncode))
48 vms = yaml.load(output, yaml.CSafeLoader)
50 if machine_name in vms:
51 host = vms[machine_name]['host']
52 print >>sys.stderr, ("machine '%s' is already running on host %s"
53 % (machine_name, host))
58 print 'Creating on host %s...' % host
60 return call(['remctl', host, 'remote', 'control',
61 machine_name, 'create'] + args)
63 if __name__ == '__main__':
64 sys.exit(main(sys.argv))