Skip to content
__init__.py 3.13 KiB
Newer Older
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))