Commit 4e33955e authored by Anael Beutot's avatar Anael Beutot
Browse files

Cleaning/Refactoring/Docstrings.

parent 8ba167df
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
import logging
from ConfigParser import SafeConfigParser

from ccnode import __version__


logger = logging.getLogger(__name__)

+9 −53
Original line number Diff line number Diff line
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.tags import Tag, DynamicTags, tag_inspector
from ccnode.host import tags


@@ -17,55 +16,8 @@ class Handler(DefaultHandler):
    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():
        for t in tag_inspector(tags, 'ccnode.host.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):
@@ -79,7 +31,11 @@ class Handler(DefaultHandler):

    @pure
    def node_shutdown(self, reboot=True, gracefull=True):
        """Halt/Reboot the node."""
        """Halt/Reboot the node.

        :param bool reboot: halt/reboot the system
        :param bool gracefull: force the operation (gracefull == not force)
        """
        args = ['/sbin/shutdown']
        if reboot:
            args.append('-r')

ccnode/hypervisor/handler.py

deleted100644 → 0
+0 −0

Empty file deleted.

+23 −7
Original line number Diff line number Diff line
@@ -16,6 +16,12 @@ DEFAULT_TAGS = (Tag(u'version', __version__, -1),)


class DefaultHandler(RpcHandler):
    """Base handler for :class:`Node` objects. Containing only a ``version``
    tag that returns current ``cc-node`` version.

    See `sjRpc documentation <http://google.fr>`_ for more information.

    """
    def __init__(self, *args, **kwargs):
        RpcHandler.__init__(self, *args, **kwargs)

@@ -23,7 +29,8 @@ class DefaultHandler(RpcHandler):

    @pure
    def get_tags(self, tags=None, noresolve_tags=None):
        """
        """Method used from the ``cc-server`` to get tags.

        :param iterable tags: list of tags to return
        :param iterable noresolve_tags: list of tags to not return
        """
@@ -75,16 +82,21 @@ class Node(Thread):

        self.daemon = True

        #: proxy
        #: ``sjRpc`` proxy
        self.proxy = None
        #: rpc connection manager
        #: ``sjRpc`` connection manager
        self.manager = None
        #: role returned by cc-server
        #: role returned by cc-server (set to None unless the authentication
        #: has succeed)
        self.role = None

        self._manager_lock = Lock()

    def init_rpc(self):
        """Init a new connection to ``cc-server``, create a ``sjRpc`` manager
        and proxy.

        """
        self.manager = SimpleRpcClient.from_addr(
            addr=self.server_host,
            port=self.server_port,
@@ -94,9 +106,11 @@ class Node(Thread):
        self.proxy = ConnectionProxy(self.manager)

    def authentify(self):
        """Try to authenticate to the server while the server returns a bad
        role.
        """Try to authenticate to the server. If successfull, import and then
        set :class:`Handler` corresponding to the role returned by the
        ``cc-server``.

        :raise: exception raised by :func:`proxy.authentify`
        """
        try:
            role = self.proxy.authentify(self.user_name, self.user_passwd)
@@ -122,7 +136,8 @@ class Node(Thread):
        self.role = role

    def rpc(self):
        """Runs rpc main loop."""
        """Runs ``sjRpc`` main loop. Catches exceptions. :func:`shutdown` the
        manager before returning."""
        try:
            self.manager.run()
        except Exception:
@@ -160,6 +175,7 @@ class Node(Thread):
            self.role = None

    def shutdown(self):
        """Shutdown the ``sjRpc`` manager and reset object state."""
        with self._manager_lock:
            if self.manager is not None:
                self.manager.shutdown()
+89 −6
Original line number Diff line number Diff line
import inspect
import logging
from inspect import isfunction


logger = logging.getLogger(__name__)


class Tag(object):
    """Class that abstract tags."""
    """``class`` that abstract tags and act as a simple container."""
    def __init__(self, name, valuable, ttl):
        """
        :param string name: tag name
@@ -19,8 +19,11 @@ class Tag(object):

    @property
    def value(self):
        """Returns tag value."""
        if isfunction(self._value):
        """Property that return tag value. Just return the provided value or
        call the function.

        """
        if inspect.isfunction(self._value):
            try:
                return self._value()
            except Exception:
@@ -31,11 +34,91 @@ class Tag(object):


class DynamicTags(object):
    """Set tags dynamicaly."""
    """Set tags dynamicaly.

    Tags must be defined in the constructor.

    Example use:

        * first subclass :class:`DynamicTags`:
            .. code-block:: python

                class Disks(DynamicTags):
                    def __init__(self):
        """Here define the tags."""
                        # find disk by calling an arbitrary function
                        disks = find_disks()

                        # for each disk associate a function that calculate
                        # the size
                        for d in disks:
                            # arbitrary example: for each disk set a tag
                            # with the disk name and the size as value with
                            # a ttl of one hour
                            self.tags.append(
                                Tag(d, find_disk_size(d), 3600),
                            )

                        # we're done :)
        * we now just need to instanciate our new ``class``:
            .. code-block:: python

                disks_size = Disks()

        * the tags are automaticaly found using :func:`tag_inspector`
    """
    def __init__(self):
        #: iterable containing :class:`Tag` objects (``list`` by default)
        self.tags = []

    def iter_tags(self):
        for t in self.tags:
            yield t


def tag_inspector(mod, match):
    """Inspect module to find tags.

    :param module mod: module to inspect
    :param string match: module name to match for tags

    Currently there are three ways to define a tag inside a module:

        * affect a string to a variable, the variable name will be the tag
          name
        * define a function that returns a value as a string or None (meaning
          the tag doesn't exist on the host), as you guessed the function name
          will define the tag name
        * subclass :class:`DynamicTags` and create an instance. The instance
          must have an attribute ``tags`` which must be an **iterable** of
          :class:`Tag` objects (by default it is a ``list``). The name of the
          instance isn't meaningfull.
    """
    tags = []
    for n, m in inspect.getmembers(mod):  # (name, member)
        # only keep strings or functions as tags
        if getattr(m, '__module__', None) != match 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():
                tags.append(t)
                logger.debug('Introspected %s with ttl %s.' % (t.name,
                                                               t.ttl))
            continue
        else:
            # whatever it is we don't care...
            continue

        logger.debug('Introspected %s with ttl %s.' % (n, ttl))

        # finally add the tag
        tags.append(Tag(n, m, ttl))

    return tags