Skip to content
tags.py 5.61 KiB
Newer Older
# This file is part of CloudControl.
#
# CloudControl is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# CloudControl is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with CloudControl.  If not, see <http://www.gnu.org/licenses/>.


"""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 time
import datetime
import os as os_
import platform as platform_
from multiprocessing import cpu_count
Anael Beutot's avatar
Anael Beutot committed
from socket import getfqdn
from cloudcontrol.common.client.tags import ttl, refresh, background

@ttl(3600 * 24)  # one day
def h():
    """Hostname tag."""
Anael Beutot's avatar
Anael Beutot committed
    return getfqdn()


# 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',
    }.get(platform_.machine(), u'unknown')


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


@ttl(10)
@refresh(2)
def cpuuse():
    """CPU usage in percentage."""
    return u'%.1f' % psutil.cpu_percent()


# memory related tags
def mem():
    """Total physical memory available on system."""
    if hasattr(psutil, 'avail_phymem') and hasattr(psutil, 'used_phymem'):
        return unicode(psutil.avail_phymem() + psutil.used_phymem())
    else:
        memory = psutil.virtual_memory()
        return unicode(memory.available + memory.used)
@ttl(5)
@refresh(10)
def memfree():
    """Available physical memory on system."""
    if hasattr(psutil, 'avail_phymem'):
        return unicode(psutil.avail_phymem())
    else:
        return unicode(psutil.virtual_memory().available)
@ttl(5)
@refresh(10)
def memused():
    """Used physical memory on system."""
    if hasattr(psutil, 'used_phymem'):
        return unicode(psutil.used_phymem())
    else:
        return unicode(psutil.virtual_memory().used)
Anael Beutot's avatar
Anael Beutot committed
@ttl(5)
@refresh(10)
def membuffers():
    """Buffers memory use."""
    if hasattr(psutil, 'phymem_buffers'):
        return unicode(psutil.phymem_buffers())
    else:
        return unicode(psutil.virtual_memory().buffers)
Anael Beutot's avatar
Anael Beutot committed
@ttl(5)
@refresh(10)
def memcache():
    """Caches memory use."""
    if hasattr(psutil, 'cached_phymem'):
        return unicode(psutil.cached_phymem())
    else:
        return unicode(psutil.virtual_memory().cached)
# 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))


# 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


Antoine Millet's avatar
Antoine Millet committed
def chaslot():
    """Position in blade chassis."""
    chassis_version = open('/sys/class/dmi/id/chassis_version').read().strip()
    if chassis_version == 'PowerEdge M1000e':
        version = open('/sys/class/dmi/id/board_serial').read().strip()
        return version.split('.')[3]


def uuid():
    """System UUID."""
    return open('/sys/class/dmi/id/product_uuid').read().strip().lower() 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


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


@ttl(5)
@refresh(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_
Antoine Millet's avatar
Antoine Millet committed

Anael Beutot's avatar
Anael Beutot committed
def plugins(handler):
    return ' '.join(handler.plugins) or None


# HKVM related tags
def hkvmver():
    """HKVM version and patch level."""
    return open('/etc/hkvm_version').read().strip()


def hkvmsetup():
    """HKVM setup date."""
    fields = dict(x.split(': ', 1) for x in open('/etc/isimage').read().split('\n') if x.strip())
    setup_date = datetime.datetime.strptime(fields['setup date'], '%a, %d %b %Y %H:%M:%S +0000')
    return int(time.mktime(setup_date.timetuple()))