#!/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 os import subprocess import libvirt import config class Node: def __init__ (self, name, host, mac, uri): self.name = name self.host = host self.mac = mac self.uri = uri def ping (self, force = False): """Test if node is up.""" if not force: if hasattr (self, 'up'): return self.up devnull = open (os.devnull, "w") r = subprocess.call (["ping", "-c", "1", self.host], stdout = devnull, stderr = devnull) self.up = r == 0 return self.up def ssh_ping (self): """Test if we can open an SSH connection""" if self.ping (): devnull = open (os.devnull, "w") r = subprocess.call ([config.SSH, "-l", "root", self.host, ":"], stdout = devnull, stderr = devnull) return r == 0 else: return False def libvirt_ping (self): """Test if we can open a libvirt connection""" if self.ping(): conn = libvirt.openReadOnly (self.uri) return conn != None else: return False def wake (self): if not self.ping (): devnull = open (os.devnull, "w") subprocess.check_call ([config.WOL, self.mac], stdout = devnull, stderr = devnull) def shutdown (self): if self.ping (): devnull = open (os.devnull, "w") r = subprocess.call ([config.SSH, "-l", "root", self.host, "/sbin/poweroff"], stdout = devnull, stderr = devnull) # returns a non-zero exit status, for unknown reasons def guests (self): """Return the list of VMs running on this node""" guests = [] if self.ping (): conn = self.get_connection () for id in conn.listDomainsID(): try: dom = conn.lookupByID (id) except: continue guests.append (dom) return guests def get_connection (self): """Return cached libvirt connection, fail if not possible.""" if not self.ping (): sys.exit ("error: node %s is not awake" % self.name) if hasattr (self, 'conn'): return self.conn conn = libvirt.open (self.uri) if conn == None: sys.exit ("error: could not open a libvirt connection to %s (URI: %s)" % (self.host, self.uri)) self.conn = conn return self.conn