import inspect import logging from subprocess import Popen, PIPE, STDOUT from sjrpc.utils import pure from ccnode.node import DefaultHandler from ccnode.tags import Tag, DynamicTags from ccnode.host import tags logger = logging.getLogger(__name__) class Handler(DefaultHandler): """Handler for host role.""" def __init__(self, *args, **kwargs): DefaultHandler.__init__(self, *args, **kwargs) # add host tags to self.tags dict [ 'cpu', 'cpuuse', 'arch', 'chaserial', 'cpufreq', 'disk', 'hmodel', 'hserial', 'hvendor', 'hbios', 'load', 'mem', 'memfree', 'memused', 'os', 'platform', 'sto', 'uname', 'uptime', ] logger.debug(u'Begin introspection') for n, m in inspect.getmembers(tags): # (name, member) # only keep strings or functions as tags if getattr(m, '__module__', None) != 'ccnode.host.tags' or ( n.startswith('_')): continue elif isinstance(m, (str, unicode)): # if string, it means it is constant, then ttl = -1 ttl = -1 elif inspect.isfunction(m): # if function take function ttl argument or set -1 by default ttl = getattr(m, 'ttl', -1) elif isinstance(m, DynamicTags): logger.debug('plop') for t in m.iter_tags(): self.tags[t.name] = t logger.debug('Introspected %s with ttl %s.' % (t.name, t.ttl)) continue else: continue logger.debug('Introspected %s with ttl %s.' % (n, ttl)) # finally add the tag self.tags[n] = Tag(n, m, ttl) logger.debug(u'End introspection') @pure def execute_command(self, command): """Execute an arbitrary shell command on the host. :param string command: shell command to run """ # return stdout and stderr mixed in return Popen(command, shell=True, bufsize=-1, stdin=PIPE, stdout=PIPE, stderr=STDOUT).communicate()[0] or None @pure def node_shutdown(self, reboot=True, gracefull=True): """Halt/Reboot the node.""" args = ['/sbin/shutdown'] if reboot: args.append('-r') if gracefull: logger.info(u'Going to reboot the host...') args.append('-f') else: logger.info(u'Going to force the reboot of the host...') args.append('-n') else: # halt args.append('-h -P') if not gracefull: logger.info(u'Going to halt the host...') args.append('-n') else: logger.info(u'Going to force the halt of the host...') args.append('0') return self.execute_command(' '.join(args))