#!/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 # Helper function to ping all the nodes. def ping_nodes (nodes): for node in nodes.values(): node.ping () # Helper function to get node objects from a list of node names. def get_nodes_by_name (all_nodes, names, all): if not all: return map (lambda name : get_node_by_name (all_nodes, name), names) else: return all_nodes.values() def get_node_by_name (nodes, name): if name in nodes: return nodes[name] else: sys.exit ("error: node does not exist: %s" % name) # Get separate list of running and inactive guests. def get_all_guests (c, nodes): running = {} inactive = {} # Find running guests. for node in nodes: # Get the flat list of guests from this node: doms = node.guests () # Store which node the guest is running on, and turn list into a map. for dom in doms: name = dom.name() if name in running: sys.exit ("error: virtual machine %s is running on two nodes!" % name) running[name] = { 'dom' : dom, 'node' : node } # Find inactive guests (XML configuration files). for name in get_guest_configs (c, nodes): 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, nodes): 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 # Convert virDomainState to string. # Copied from virt-manager. def pretty_run_status (status): if status == libvirt.VIR_DOMAIN_RUNNING: return "running" elif status == libvirt.VIR_DOMAIN_PAUSED: return "paused" elif status == libvirt.VIR_DOMAIN_SHUTDOWN: return "shutting down" elif status == libvirt.VIR_DOMAIN_SHUTOFF: return "shutoff" elif status == libvirt.VIR_DOMAIN_CRASHED: return "crashed" elif status == libvirt.VIR_DOMAIN_PMSUSPENDED: return "suspended" # Start a guest running on a given node. The node must not be # running anywhere already. def start_guest (c, node, guest_name): fp = open ("%s/%s.xml" % (c['xmls_dir'], guest_name), "r") xml = fp.read () fp.close () conn = node.get_connection() conn.createXML (xml) def pick_any_node_which_is_up (nodes): node = None for n in nodes.values(): if n.ping (): node = n break if not node: sys.exit ("error: no nodes are up, use mclu wake [node|--all]") return node