3 Picks a host to "create" (boot) a VM on, and does so.
5 For now, a very dumb algorithm for which host to boot on:
6 the one with fewer machines running.
8 TODO: load-balance based on something like actual free RAM
10 TODO: use a lock to avoid creating the same VM twice in a race
14 from subprocess import PIPE, Popen, call
20 # Query each of the hosts.
21 # TODO get `servers` from a real list of all the VM hosts (instead of
22 # hardcoding the list here)
23 servers = ['black-mesa.mit.edu', 'sx-blade-2.mit.edu']
25 Popen(['remctl', server, 'remote', 'web', 'info'], stdout=PIPE))
26 for server in servers]
27 outputs = [(s, p.communicate()[0]) for (s, p) in pipes]
30 raise RuntimeError("remctl to host %s returned non-zero exit status %d"
32 results = [(s, yaml.load(o, yaml.CSafeLoader)) for (s, o) in outputs]
33 # XXX will the output of 'xm info' always be parseable YAML?
35 return max( (int(o['free_memory']), s) for (s, o) in results )[1]
40 print >>sys.stderr, "usage: sipb-xen-remote-create <machine> [<other args...>]"
42 machine_name = argv[1]
46 p = Popen(['/usr/sbin/sipb-xen-remote-proxy-web', 'listvms'], stdout=PIPE)
47 output = p.communicate()[0]
49 raise RuntimeError("Command '%s' returned non-zero exit status %d"
50 % ('sipb-xen-remote-proxy-web', p.returncode))
51 vms = yaml.load(output, yaml.CSafeLoader)
53 if machine_name in vms:
54 host = vms[machine_name]['host']
55 print >>sys.stderr, ("machine '%s' is already running on host %s"
56 % (machine_name, host))
61 print 'Creating on host %s...' % host
62 return call(['remctl', host, 'remote', 'control',
63 machine_name, 'create'] + args)
65 if __name__ == '__main__':
66 sys.exit(main(sys.argv))