#!/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, exception, identity except ImportError: successful_import = False else: successful_import = True def get_name_from_tenant(tenant): try: 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(): loaded_config = CommonConfigOpts(project="glance", prog="glance-registry") loaded_config() # Hide missing logger warning message sys.stderr = open(os.devnull, 'w') configure_db(loaded_config) 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 cloud') 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 exception.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)