X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/invirt-remote.git/blobdiff_plain/15813cdf61c889aae4cc9b1d2eecbdf71869fb8a..c7a4b1ed77b6091d7a9bf27c59e098bdff84474e:/files/usr/sbin/sipb-xen-remote-create diff --git a/files/usr/sbin/sipb-xen-remote-create b/files/usr/sbin/sipb-xen-remote-create index c4a62cc..f957a59 100755 --- a/files/usr/sbin/sipb-xen-remote-create +++ b/files/usr/sbin/sipb-xen-remote-create @@ -1,47 +1,41 @@ #!/usr/bin/python + """ Picks a host to "create" (boot) a VM on, and does so. -For now, a very dumb algorithm for which host to boot on: -the one with fewer machines running. - -TODO: load-balance based on something like actual free RAM +Current load-balancing algorithm: wherever there's more free RAM. TODO: use a lock to avoid creating the same VM twice in a race """ - +from invirt.remote import bcast from subprocess import PIPE, Popen, call import sys import yaml - def choose_host(): # Query each of the hosts. - # TODO get `servers` from a real list of all the VM hosts (instead of - # hardcoding the list here) - servers = ['black-mesa.mit.edu', 'sx-blade-2.mit.edu'] - pipes = [(server, - Popen(['remctl', server, 'remote', 'web', 'info'], stdout=PIPE)) - for server in servers] - outputs = [(s, p.communicate()[0]) for (s, p) in pipes] - for (s, p) in pipes: - if p.returncode != 0: - raise RuntimeError("remctl to host %s returned non-zero exit status %d" - % (s, p.returncode)) - results = [(s, yaml.load(o, yaml.CSafeLoader)) for (s, o) in outputs] # XXX will the output of 'xm info' always be parseable YAML? - - return max( (int(o['free_memory']), s) for (s, o) in results )[1] - + results = bcast('info') + return max((int(o['free_memory']), s) for (s, o) in results)[1] def main(argv): - if len(argv) < 2: - print >>sys.stderr, "usage: sipb-xen-remote-create []" + if len(argv) < 3: + print >> sys.stderr, "usage: sipb-xen-remote-create []" return 2 - machine_name = argv[1] - args = argv[2:] - + operation = argv[1] + machine_name = argv[2] + args = argv[3:] + + if operation == 'install': + options = dict(arg.split('=', 1) for arg in args) + valid_keys = set(('mirror', 'dist', 'arch', 'imagesize', 'noinstall')) + if not set(options.keys()).issubset(valid_keys): + print >> sys.stderr, "Invalid argument. Use the help command to see valid arguments to install" + return 1 + if any(' ' in val for val in options.values()): + print >> sys.stderr, "Arguments to the autoinstaller cannot contain spaces" + return 1 p = Popen(['/usr/sbin/sipb-xen-remote-proxy-web', 'listvms'], stdout=PIPE) output = p.communicate()[0] @@ -52,15 +46,15 @@ def main(argv): if machine_name in vms: host = vms[machine_name]['host'] - print >>sys.stderr, ("machine '%s' is already running on host %s" - % (machine_name, host)) + print >> sys.stderr, ("machine '%s' is already running on host %s" + % (machine_name, host)) return 1 - host = choose_host() print 'Creating on host %s...' % host + sys.stdout.flush() return call(['remctl', host, 'remote', 'control', - machine_name, 'create'] + args) + machine_name, operation] + args) if __name__ == '__main__': sys.exit(main(sys.argv))