#!/usr/bin/python # mclu (mini cluster) # Copyright (C) 2014 Red Hat Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import sys import os import re import libvirt import ansible.runner import ansible.inventory # Get separate list of running and inactive guests. def get_all_guests (c): running = {} inactive = {} # Find running guests. runner = ansible.runner.Runner ( remote_user = 'root', module_name = 'virt', module_args = 'command=list_vms', # XXX ignore state=shutdown pattern = c['nodes_group'], ) data = runner.run () for node in data['contacted'].keys(): # Get the flat list of guests from this node: vms = data['contacted'][node]['list_vms'] # Store which node the guest is running on, and turn list into a map. for vm in vms: if node in running: sys.exit ("error: virtual machine %s is running on two nodes!" % node) running[vm] = { 'vm' : vm, 'node' : node } # Find inactive guests (XML configuration files). for name in get_guest_configs (c): if name not in running: inactive[name] = name return running, inactive # Get the names of guests from the XML configuration files in xmls_dir. def get_guest_configs (c): names = [] for filename in sorted (os.listdir (c['xmls_dir'])): m = re.search (r'^(.*)\.xml$', filename) if m: names.append (m.group (1)) return names # Start a guest running on a given node. The node must not be # running anywhere already. def start_guest (c, node_name, guest_name): fp = open ("%s/%s.xml" % (c['xmls_dir'], guest_name), "r") xml = fp.read () fp.close () conn = libvirt.open (uri_of_node (node_name)) if conn == None: sys.exit ("error: could not open a libvirt connection to %s" % node_name) conn.createXML (xml) def pick_any_node_which_is_up (c): inventory = ansible.inventory.Inventory () runner = ansible.runner.Runner ( remote_user = 'root', module_name = 'ping', inventory = inventory, pattern = c['nodes_group'], ) data = runner.run () if len (data['contacted']) == 0: sys.exit ("error: no nodes are up, use mclu on") return data['contacted'].keys()[0] # XXX Make this configurable. def uri_of_node (node_name): return "qemu+ssh://root@%s/system" % node_name