Loading ccnode/config.py +0 −2 Original line number Diff line number Diff line import logging from ConfigParser import SafeConfigParser from ccnode import __version__ logger = logging.getLogger(__name__) Loading ccnode/host/__init__.py +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 Loading @@ -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): Loading @@ -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') Loading ccnode/hypervisor/handler.pydeleted 100644 → 0 +0 −0 Empty file deleted. ccnode/node.py +23 −7 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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 """ Loading Loading @@ -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, Loading @@ -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) Loading @@ -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: Loading Loading @@ -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() Loading ccnode/tags.py +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 Loading @@ -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: Loading @@ -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 Loading
ccnode/config.py +0 −2 Original line number Diff line number Diff line import logging from ConfigParser import SafeConfigParser from ccnode import __version__ logger = logging.getLogger(__name__) Loading
ccnode/host/__init__.py +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 Loading @@ -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): Loading @@ -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') Loading
ccnode/node.py +23 −7 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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 """ Loading Loading @@ -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, Loading @@ -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) Loading @@ -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: Loading Loading @@ -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() Loading
ccnode/tags.py +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 Loading @@ -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: Loading @@ -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