source: trunk/packages/sipb-xen-remote-server/files/usr/sbin/sipb-xen-remote-create @ 662

Last change on this file since 662 was 658, checked in by price, 16 years ago

code to load-balance boots among hosts

  • Property svn:executable set to *
File size: 2.1 KB
Line 
1#!/usr/bin/python
2"""
3Picks a host to "create" (boot) a VM on, and does so.
4
5For now, a very dumb algorithm for which host to boot on:
6the one with fewer machines running.
7
8TODO: load-balance based on something like actual free RAM
9
10TODO: use a lock to avoid creating the same VM twice in a race
11"""
12
13
14from subprocess import PIPE, Popen, call
15import sys
16import yaml
17
18
19def choose_host():
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']
24    pipes = [(server,
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]
28    for (s, p) in pipes:
29        if p.returncode != 0:
30            raise RuntimeError("remctl to host %s returned non-zero exit status %d"
31                               % (s, p.returncode)) 
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?
34
35    return max( (int(o['free_memory']), s) for (s, o) in results )[1]
36
37
38def main(argv):
39    if len(argv) < 2:
40        print >>sys.stderr, "usage: sipb-xen-remote-create <machine> [<other args...>]"
41        return 2
42    machine_name = argv[1]
43    args = argv[2:]
44
45
46    p = Popen(['/usr/sbin/sipb-xen-remote-proxy-web', 'listvms'], stdout=PIPE)
47    output = p.communicate()[0]
48    if p.returncode != 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)
52
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))
57        return 1
58
59
60    host = choose_host()
61    print 'Creating on host %s...' % host
62    return call(['remctl', host, 'remote', 'control',
63                 machine_name, 'create'] + args)
64
65if __name__ == '__main__':
66    sys.exit(main(sys.argv))
67
68# vim:et:sw=4:ts=4
Note: See TracBrowser for help on using the repository browser.