961b5b0fd2255c0e021b431fa0618e9f8c1061bd
[mclu.git] / lib.py
1 #!/usr/bin/python
2 # mclu (mini cluster)
3 # Copyright (C) 2014 Red Hat Inc.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
19 import sys
20 import os
21 import re
22 import libvirt
23
24 # Helper function to ping all the nodes.
25 def ping_nodes (nodes):
26     for node in nodes.values():
27         node.ping ()
28
29 # Helper function to get node objects from a list of node names.
30 def get_nodes_by_name (all_nodes, names, all):
31     if not all:
32         return map (lambda name : get_node_by_name (all_nodes, name), names)
33     else:
34         return all_nodes.values()
35
36 def get_node_by_name (nodes, name):
37     if name in nodes:
38         return nodes[name]
39     else:
40         sys.exit ("error: node does not exist: %s" % name)
41
42 # Get separate list of running and inactive guests.
43 def get_all_guests (c, nodes):
44     running = {}
45     inactive = {}
46
47     # Find running guests.
48     for node in nodes:
49         # Get the flat list of guests from this node:
50         doms = node.guests ()
51         # Store which node the guest is running on, and turn list into a map.
52         for dom in doms:
53             name = dom.name()
54             if name in running:
55                 sys.exit ("error: virtual machine %s is running on two nodes!" % name)
56             running[name] = { 'dom' : dom, 'node' : node }
57
58     # Find inactive guests (XML configuration files).
59     for name in get_guest_configs (c, nodes):
60         if name not in running:
61             inactive[name] = name
62
63     return running, inactive
64
65 # Get the names of guests from the XML configuration files in xmls_dir.
66 def get_guest_configs (c, nodes):
67     names = []
68     for filename in sorted (os.listdir (c['xmls_dir'])):
69         m = re.search (r'^(.*)\.xml$', filename)
70         if m:
71             names.append (m.group (1))
72     return names
73
74 # Convert virDomainState to string.
75 # Copied from virt-manager.
76 def pretty_run_status (status):
77     if status == libvirt.VIR_DOMAIN_RUNNING:
78         return "running"
79     elif status == libvirt.VIR_DOMAIN_PAUSED:
80         return "paused"
81     elif status == libvirt.VIR_DOMAIN_SHUTDOWN:
82         return "shutting down"
83     elif status == libvirt.VIR_DOMAIN_SHUTOFF:
84         return "shutoff"
85     elif status == libvirt.VIR_DOMAIN_CRASHED:
86         return "crashed"
87     elif status == libvirt.VIR_DOMAIN_PMSUSPENDED:
88         return "suspended"
89
90 # Start a guest running on a given node.  The node must not be
91 # running anywhere already.
92 def start_guest (c, node, guest_name):
93     fp = open ("%s/%s.xml" % (c['xmls_dir'], guest_name), "r")
94     xml = fp.read ()
95     fp.close ()
96
97     conn = node.get_connection()
98     conn.createXML (xml)
99
100 def pick_any_node_which_is_up (nodes):
101     node = None
102     for n in nodes.values():
103         if n.ping ():
104             node = n
105             break
106     if not node:
107         sys.exit ("error: no nodes are up, use mclu on [node|--all]")
108     return node