Work around for monasca libvirt metrics
Issue: CIRRUS-1327 Change-Id: Iabcbf9f8dbcf8d54164dbd729ec2c3f6f3df3e68
This commit is contained in:
parent
2f225a53e6
commit
6fd256081f
|
@ -0,0 +1,161 @@
|
|||
#!/usr/bin/env python
|
||||
""" Detect running daemons then configure and start the agent.
|
||||
"""
|
||||
|
||||
import agent_config
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import pwd
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import yaml
|
||||
from detection.plugins import ceilometer
|
||||
from detection.plugins import cinder
|
||||
from detection.plugins import glance
|
||||
from detection.plugins import kafka_consumer
|
||||
from detection.plugins import keystone
|
||||
from detection.plugins import libvirt
|
||||
from detection.plugins import mon
|
||||
from detection.plugins import mysql
|
||||
from detection.plugins import network
|
||||
from detection.plugins import neutron
|
||||
from detection.plugins import nova
|
||||
from detection.plugins import rabbitmq
|
||||
from detection.plugins import swift
|
||||
from detection.plugins import zookeeper
|
||||
from service import sysv
|
||||
|
||||
# List of all detection plugins to run
|
||||
DETECTION_PLUGINS = [ceilometer.Ceilometer, cinder.Cinder, glance.Glance,
|
||||
kafka_consumer.Kafka, keystone.Keystone,
|
||||
mon.MonAPI, mon.MonPersister, mon.MonThresh, mysql.MySQL,
|
||||
network.Network, neutron.Neutron, nova.Nova,
|
||||
rabbitmq.RabbitMQ, swift.Swift, zookeeper.Zookeeper]
|
||||
# Map OS to service type
|
||||
OS_SERVICE_MAP = {'Linux': sysv.SysV}
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(description='Detect running daemons then configure and start the agent.',
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument(
|
||||
'-u', '--username', help="Username used for keystone authentication", required=True)
|
||||
parser.add_argument(
|
||||
'-p', '--password', help="Password used for keystone authentication", required=True)
|
||||
parser.add_argument('--keystone_url', help="Keystone url", required=True)
|
||||
parser.add_argument('--monasca_url', help="Monasca API url", required=True)
|
||||
parser.add_argument('--insecure', help="Set whether certificates are used for Keystone authentication", required=False, default=False)
|
||||
parser.add_argument('--project_name', help="Project name for keystone authentication", required=False, default='')
|
||||
parser.add_argument('--project_domain_id', help="Project domain id for keystone authentication", required=False, default='')
|
||||
parser.add_argument('--project_domain_name', help="Project domain name for keystone authentication", required=False, default='')
|
||||
parser.add_argument('--project_id', help="Keystone project id for keystone authentication", required=False, default='')
|
||||
parser.add_argument('--ca_file', help="Sets the path to the ca certs file if using certificates" +
|
||||
"Required only if insecure is set to False", required=False, default='')
|
||||
parser.add_argument('--config_dir', help="Configuration directory", default='/etc/monasca/agent')
|
||||
parser.add_argument('--dimensions', help="Additional dimensions to set for all metrics. A comma seperated list " +
|
||||
"of name/value pairs, 'name:value,name2:value2'")
|
||||
parser.add_argument('--log_dir', help="monasca-agent log directory", default='/var/log/monasca/agent')
|
||||
parser.add_argument(
|
||||
'--template_dir', help="Alternative template directory", default='/usr/local/share/monasca/agent')
|
||||
parser.add_argument('--headless', help="Run in a non-interactive mode", action="store_true")
|
||||
parser.add_argument('--overwrite',
|
||||
help="Overwrite existing plugin configuration." +
|
||||
"The default is to merge. Agent.conf is always overwritten.",
|
||||
action="store_true")
|
||||
parser.add_argument('--skip_enable', help="By default the service is enabled," +
|
||||
" which requires the script run as root. Set this to skip that step.",
|
||||
action="store_true")
|
||||
parser.add_argument('--user', help="User name to run monasca-agent as", default='monasca-agent')
|
||||
parser.add_argument('-s', '--service', help="Service this node is associated with, added as a dimension.")
|
||||
parser.add_argument('-v', '--verbose', help="Verbose Output", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.verbose:
|
||||
logging.basicConfig(level=logging.DEBUG, format="%(levelname)s: %(message)s")
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
|
||||
|
||||
# Detect os
|
||||
detected_os = platform.system()
|
||||
if detected_os == 'Linux':
|
||||
pass
|
||||
elif detected_os == 'Darwin':
|
||||
print("Mac OS is not currently supported by the Monasca Agent")
|
||||
sys.exit()
|
||||
elif detected_os == 'Windows':
|
||||
print("Windows is not currently supported by the Monasca Agent")
|
||||
sys.exit()
|
||||
else:
|
||||
print("{0} is not currently supported by the Monasca Agent".format(detected_os))
|
||||
|
||||
# Service enable, includes setup of users/config directories so must be
|
||||
# done before configuration
|
||||
agent_service = OS_SERVICE_MAP[detected_os](os.path.join(args.template_dir, 'monasca-agent.init'),
|
||||
args.config_dir,
|
||||
args.log_dir, username=args.user)
|
||||
if not args.skip_enable:
|
||||
agent_service.enable()
|
||||
|
||||
gid = pwd.getpwnam(args.user).pw_gid
|
||||
# Write the main agent.conf - Note this is always overwritten
|
||||
log.info('Configuring base Agent settings.')
|
||||
agent_conf_path = os.path.join(args.config_dir, 'agent.conf')
|
||||
with open(os.path.join(args.template_dir, 'agent.conf.template'), 'r') as agent_template:
|
||||
with open(agent_conf_path, 'w') as agent_conf:
|
||||
# Join service in with the dimensions
|
||||
if args.service is not None:
|
||||
if args.dimensions is None:
|
||||
args.dimensions = 'service:' + args.service
|
||||
else:
|
||||
args.dimensions = ','.join([args.dimensions, 'service:' + args.service])
|
||||
agent_conf.write(agent_template.read().format(args=args, hostname=socket.getfqdn()))
|
||||
os.chown(agent_conf_path, 0, gid)
|
||||
os.chmod(agent_conf_path, 0o640)
|
||||
# Link the supervisor.conf
|
||||
supervisor_path = os.path.join(args.config_dir, 'supervisor.conf')
|
||||
if os.path.exists(supervisor_path):
|
||||
os.remove(supervisor_path)
|
||||
os.symlink(os.path.join(args.template_dir, 'supervisor.conf'), supervisor_path)
|
||||
|
||||
# Run through detection and config building for the plugins
|
||||
plugin_config = agent_config.Plugins()
|
||||
for detect_class in DETECTION_PLUGINS:
|
||||
detect = detect_class(args.template_dir, args.overwrite)
|
||||
if detect.available:
|
||||
log.info('Configuring {0}'.format(detect.name))
|
||||
new_config = detect.build_config()
|
||||
plugin_config.merge(new_config)
|
||||
|
||||
# todo add option to install dependencies
|
||||
|
||||
# Write out the plugin config
|
||||
for key, value in plugin_config.iteritems():
|
||||
# todo if overwrite is set I should either warn or just delete any config files not in the new config
|
||||
# todo add the ability to show a diff before overwriting or merging config
|
||||
config_path = os.path.join(args.config_dir, 'conf.d', key + '.yaml')
|
||||
# merge old and new config, new has precedence
|
||||
if (not args.overwrite) and os.path.exists(config_path):
|
||||
with open(config_path, 'r') as config_file:
|
||||
old_config = yaml.load(config_file.read())
|
||||
if old_config is not None:
|
||||
agent_config.deep_merge(old_config, value)
|
||||
value = old_config
|
||||
with open(config_path, 'w') as config_file:
|
||||
os.chmod(config_path, 0o640)
|
||||
os.chown(config_path, 0, gid)
|
||||
config_file.write(yaml.safe_dump(value, encoding='utf-8', allow_unicode=True))
|
||||
|
||||
# Now that the config is build start the service
|
||||
try:
|
||||
agent_service.start(restart=True)
|
||||
except subprocess.CalledProcessError:
|
||||
log.error('The service did not startup correctly see %s' % args.log_dir)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
|
@ -14,7 +14,7 @@ class monasca::agent(
|
|||
$password,
|
||||
$keystone_url,
|
||||
$service,
|
||||
$project_name = 'monasca',
|
||||
$project_name = 'services',
|
||||
$hostname = undef,
|
||||
$dimensions = undef,
|
||||
$recent_point_threshold = '30',
|
||||
|
@ -44,11 +44,13 @@ class monasca::agent(
|
|||
Agent_config<||> ~> Service['monasca-agent']
|
||||
|
||||
if $::monasca::params::agent_package {
|
||||
ensure_packages('python-pip')
|
||||
Package['python-dev'] -> Package['monasca-agent']
|
||||
Package['monasca-agent'] -> Exec['monasca-setup']
|
||||
package { 'monasca-agent':
|
||||
ensure => true,
|
||||
name => $::monasca::params::agent_package,
|
||||
require => Package['python-pip'],
|
||||
provider => pip,
|
||||
}
|
||||
package { 'python-dev':
|
||||
|
@ -57,6 +59,15 @@ class monasca::agent(
|
|||
}
|
||||
}
|
||||
|
||||
# Work around for https://bugs.launchpad.net/monasca/+bug/1391961
|
||||
# Remove this statement and files/main.py when this bug is resolved
|
||||
file { '/usr/local/lib/python2.7/dist-packages/monsetup/main.py':
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/monasca/main.py',
|
||||
before => Exec['monasca-setup'],
|
||||
require => Package['monasca-agent'],
|
||||
}
|
||||
|
||||
exec { 'monasca-setup':
|
||||
path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
|
||||
command => "monasca-setup --username ${username} --password ${password} --project_name ${project_name} --service ${service} --keystone_url ${keystone_url} --monasca_url ${url} --overwrite; rm ${agent_conf}; touch ${agent_conf}",
|
||||
|
|
Loading…
Reference in New Issue