#!/usr/bin/env python # # Plugin to monitor used size of a tenant in glance # # To monitor the used size of a tenant in glance do: # E.g. # ln -s /usr/share/munin/plugins/glance_size_ /etc/munin/plugins/glance_size_ # # Needs following minimal configuration in plugin-conf.d/glance: # [glance_*] # user glance # # To show tenant name plugin must run as root # # Magic markers #%# capabilities=autoconf suggest #%# family=auto import sys import os try: from sqlalchemy.orm import joinedload import sqlalchemy.exc from glance.common.cfg import CommonConfigOpts from glance.registry.db import models from glance.registry.db.api import get_session, configure_db from keystone.common import utils from keystone import config from keystone import exception from keystone import identity except ImportError: successful_import = False else: successful_import = True def get_name_from_tenant(tenant): try: KEYSTONE_CONF = config.CONF(config_files=[utils.find_config('keystone.conf')]) except: # keystone configuration can not be loaded, use id as name" return tenant identity_api = identity.Manager() try: tenant_info = identity_api.get_tenant(None, tenant) except sqlalchemy.exc.OperationalError: # keystone database can not be connected, use id as name" return tenant if not tenant_info: return tenant else: return tenant_info["name"] def load_conf(): CONF = CommonConfigOpts(project="glance", prog="glance-registry") CONF() # Hide missing logger warning message sys.stderr = open(os.devnull, 'w') configure_db(CONF) sys.stderr = sys.__stderr__ def print_config(tenant): if tenant == "Global": print 'graph_title Glance used size for all tenants' print 'graph_info This graph shows the used size in glance for all tenants' else: print 'graph_title Glance used size for tenant %s' % get_name_from_tenant(tenant) print 'graph_info This graph shows the used size in glance for tenant %s' % tenant print 'graph_vlabel Bytes' print 'graph_args --base 1024 --lower-limit 0' print 'graph_category glance' print '%s.label %s' % (tenant, get_name_from_tenant(tenant)) print '%s.draw LINE2' % tenant print '%s.info %s MBytes' % (tenant, tenant) def request(**kwargs): session = get_session() try: query = session.query(models.Image).\ options(joinedload(models.Image.properties)).\ options(joinedload(models.Image.members)) if kwargs: query = query.filter_by(**kwargs) images = query.all() except exc.NoResultFound: return [] return images def print_suggest(): print "Global" print "\n".join(set( image["owner"] for image in request(deleted=False) )) def print_values(tenant): if tenant != "Global" : images = request(deleted=False, owner=tenant) else: images = request(deleted=False) total_size = sum([ image["size"] for image in images ]) print '%s.value %s' % (tenant, total_size) if __name__ == '__main__': argv = sys.argv[:] tenant = argv[0].split('glance_size_').pop() or 'Global' if len(argv) > 1: if argv[1] == 'config': print_config(tenant) elif argv[1] == 'suggest' and successful_import: load_conf() print_suggest() elif argv[1] == 'autoconf': if not successful_import: print 'no (failed import glance and/or sqlachemy module)' sys.exit(0) try: load_conf() get_session() except: print 'no (failed to connect glance backend, check user)' sys.exit(0) print 'yes' elif successful_import: load_conf() print_values(tenant)