Skip to content
tags.py 3.78 KiB
Newer Older
"""This module acts as a little framework for defining tags in a simple way.
Just define a string or a function and it will be introspected and used as a
tag value.
"""
import re
import os as os_
import platform as platform_
from multiprocessing import cpu_count
from socket import gethostname, gethostbyaddr

import psutil

from ccnode.tags import Tag, DynamicTags


def h():
    """Hostname tag."""
    hn = gethostname()

    return gethostbyaddr(hn)[0] or hn
h.ttl = 3600 * 24  # one day


# CPU related tags
def arch():
    """Hardware CPU architecture."""
    return {
        u'i386': u'x86',
        u'i486': u'x86',
        u'i586': u'x86',
        u'i686': u'x86',
        u'x86_64': u'x64',
        u'': None,
    }[platform_.machine()]


def cpu():
    """Number of CPU (core) on the host."""
    try:
        return unicode(cpu_count())
    except NotImplementedError:
        return None


def cpuuse():
    """CPU usage in percentage."""
    return u'%.1f' % psutil.cpu_percent()
cpuuse.ttl = 5


# memory related tags
def mem():
    """Total physical memory available on system."""
    return unicode(psutil.avail_phymem() + psutil.used_phymem())
mem.ttl = -1  # FIXME validate ttl


def memfree():
    """Available physical memory on system."""
    return unicode(psutil.avail_phymem())
memfree.ttl = 60


def memused():
    """Used physical memory on system."""
    return unicode(psutil.used_phymem())
memused.ttl = 60


# disks related tags
def disk():
    """List of disk devices on the host."""
    disk_pattern = re.compile(r'[sh]d[a-z]+')

    return u' '.join(d for d in os_.listdir(
        '/sys/block/') if disk_pattern.match(d))


def _disk_tag_value(disk_name):
    def size():
        s = open(os_.path.join('/sys/block', disk_name, 'size')).read().strip()
        try:
            s = int(s)
            if s > 0:
                return s * 512
            else:
                return None
        except ValueError:
            return None

    return size


class DynamicDisks(DynamicTags):
    def __init__(self):
        DynamicTags.__init__(self)

        for d in disk().split():
            self.tags.append(Tag(u'disk%s_size' % d, _disk_tag_value(d), 3600))


disks_size = DynamicDisks()


# other hardware related tags
def chaserial():
    """Blade chassis serial number."""
    return open('/sys/class/dmi/id/chassis_serial').read().strip() or None


def chaasset():
    """Blade chassis asset tag."""
    return open('/sys/class/dmi/id/chassis_asset_tag').read().strip() or None


def hmodel():
    """Host hardware model."""
    return open('/sys/class/dmi/id/product_name').read().strip() or None


def hserial():
    """Host hardware serial number."""
    return open('/sys/class/dmi/id/product_serial').read().strip() or None


def hvendor():
    """Host hardware vendor."""
    return open('/sys/class/dmi/id/sys_vendor').read().strip() or None


def hbios():
    """Host BIOS version."""
    return u'%s (%s)' % (
        open('/sys/class/dmi/id/bios_version').read().strip() or None,
        open('/sys/class/dmi/id/bios_date').read().strip() or None,
    )


# Operating system related tags
def os():
    """Operating system (linux/windows)."""
    return unicode(platform_.system().lower())


def platform():
    """Python platform.platform() info."""
    return unicode(platform_.platform())


def uname():
    """As uname command (see python os.uname)."""
    return u' '.join(os_.uname()) or None


def uptime():
    """Uptime of the system in seconds."""
    return open('/proc/uptime').read().split()[0].split(u'.')[0] or None
uptime.ttl = 5


def load():
    """Average of the number of processes in the run queue over the last 1, 5
    and 15 minutes."""
    load_ = None
    try:
        load_ = u' '.join(unicode(l) for l in os_.getloadavg())
    except OSError:
        pass
    return load_
load.ttl = 5