gnocchi: Create resource-types on upgrades

Change-Id: Ibc7ce7daf598a5d5702655d50e116cefcc8267bc
This commit is contained in:
Mehdi Abaakouk 2016-08-03 16:10:02 +02:00
parent a60b004fd6
commit 9709608bb1
4 changed files with 155 additions and 26 deletions

View File

@ -21,13 +21,14 @@ import six.moves.urllib.parse as urlparse
import sqlalchemy as sa
from ceilometer.i18n import _LE, _LI, _LW
from ceilometer import gnocchi_client
from ceilometer import service
from ceilometer import storage
LOG = log.getLogger(__name__)
def upgrade():
def upgrade(default_skip_gnocchi_resource_types=False):
cfg.CONF.register_cli_opts([
cfg.BoolOpt('skip-metering-database',
help='Skip metering database upgrade.',
@ -35,6 +36,9 @@ def upgrade():
cfg.BoolOpt('skip-event-database',
help='Skip event database upgrade.',
default=False),
cfg.BoolOpt('skip-gnocchi-resource-types',
help='Skip gnocchi resource-types upgrade.',
default=default_skip_gnocchi_resource_types),
])
service.prepare_service()
@ -50,11 +54,17 @@ def upgrade():
LOG.debug("Upgrading event database")
storage.get_connection_from_config(cfg.CONF, 'event').upgrade()
if cfg.CONF.skip_gnocchi_resource_types:
LOG.info("Skipping Gnocchi resource types upgrade")
else:
LOG.debug("Upgrading Gnocchi resource types")
gnocchi_client.upgrade_resource_types(cfg.CONF)
def dbsync():
LOG.warning(_LW('ceilometer-dbsync is deprecated in favor of '
'ceilometer-upgrade'))
upgrade()
upgrade(default_skip_gnocchi_resource_types=True)
def expirer():

View File

@ -20,16 +20,13 @@ import re
import threading
import uuid
from gnocchiclient import client
from gnocchiclient import exceptions as gnocchi_exc
from gnocchiclient import utils as gnocchi_utils
from keystoneauth1 import exceptions as ka_exceptions
from keystoneauth1 import session as ka_session
from oslo_config import cfg
from oslo_log import log
from oslo_utils import fnmatch
from oslo_utils import timeutils
import requests
import retrying
import six
from stevedore import extension
@ -37,6 +34,7 @@ from stevedore import extension
from ceilometer import declarative
from ceilometer import dispatcher
from ceilometer.i18n import _, _LE, _LW
from ceilometer import gnocchi_client
from ceilometer import keystone_client
NAME_ENCODED = __name__.encode('utf-8')
@ -52,9 +50,6 @@ dispatcher_opts = [
default='gnocchi',
help='Gnocchi project used to filter out samples '
'generated by Gnocchi service activity'),
cfg.StrOpt('url',
deprecated_for_removal=True,
help='URL to Gnocchi. default: autodetection'),
cfg.StrOpt('archive_policy',
help='The archive policy to use when the dispatcher '
'create a new metric.'),
@ -157,19 +152,6 @@ class ResourcesDefinition(object):
return attrs
def get_gnocchiclient(conf):
requests_session = requests.session()
for scheme in list(requests_session.adapters.keys()):
requests_session.mount(scheme, ka_session.TCPKeepAliveAdapter(
pool_block=True))
session = keystone_client.get_session(requests_session=requests_session)
return client.Client('1', session,
interface=conf.service_credentials.interface,
region_name=conf.service_credentials.region_name,
endpoint_override=conf.dispatcher_gnocchi.url)
class LockedDefaultDict(defaultdict):
"""defaultdict with lock to handle threading
@ -241,7 +223,8 @@ class GnocchiDispatcher(dispatcher.MeterDispatcherBase):
self._gnocchi_project_id_lock = threading.Lock()
self._gnocchi_resource_lock = LockedDefaultDict(threading.Lock)
self._gnocchi = get_gnocchiclient(conf)
self._gnocchi = gnocchi_client.get_gnocchiclient(conf)
# Convert retry_interval secs to msecs for retry decorator
retries = conf.storage.max_retries

View File

@ -0,0 +1,129 @@
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from gnocchiclient import client
from gnocchiclient import exceptions as gnocchi_exc
from keystoneauth1 import session as ka_session
from oslo_config import cfg
from oslo_log import log
import requests
from ceilometer import keystone_client
LOG = log.getLogger(__name__)
OPTS = [
cfg.StrOpt('url',
deprecated_for_removal=True,
help='URL to Gnocchi. default: autodetection'),
]
cfg.CONF.register_opts(OPTS, group="dispatcher_gnocchi")
def get_gnocchiclient(conf, endpoint_override=None):
requests_session = requests.session()
for scheme in list(requests_session.adapters.keys()):
requests_session.mount(scheme, ka_session.TCPKeepAliveAdapter(
pool_block=True))
session = keystone_client.get_session(requests_session=requests_session)
return client.Client('1', session,
interface=conf.service_credentials.interface,
region_name=conf.service_credentials.region_name,
endpoint_override=endpoint_override)
# NOTE(sileht): This is the initial resource types created in Gnocchi
# This list must never change to keep in sync with what Gnocchi early
# database contents was containing
resources_initial = {
"image": {
"name": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
"container_format": {"type": "string", "min_length": 0,
"max_length": 255, "required": True},
"disk_format": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
},
"instance": {
"flavor_id": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
"image_ref": {"type": "string", "min_length": 0, "max_length": 255,
"required": False},
"host": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
"display_name": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
"server_group": {"type": "string", "min_length": 0, "max_length": 255,
"required": False},
},
"instance_disk": {
"name": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
"instance_id": {"type": "uuid", "required": True},
},
"instance_network_interface": {
"name": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
"instance_id": {"type": "uuid", "required": True},
},
"volume": {
"display_name": {"type": "string", "min_length": 0, "max_length": 255,
"required": False},
},
"swift_account": {},
"ceph_account": {},
"network": {},
"identity": {},
"ipmi": {},
"stack": {},
"host": {
"host_name": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
},
"host_network_interface": {
"host_name": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
"device_name": {"type": "string", "min_length": 0, "max_length": 255,
"required": False},
},
"host_disk": {
"host_name": {"type": "string", "min_length": 0, "max_length": 255,
"required": True},
"device_name": {"type": "string", "min_length": 0, "max_length": 255,
"required": False},
},
}
def upgrade_resource_types(conf):
gnocchi = get_gnocchiclient(conf)
# TODO(sileht): Detect what is the version of the schema created
# in Gnocchi, we don't have local database to store this.
# For now we can upgrade the schema so we are safe :p
for name, attributes in resources_initial.items():
try:
gnocchi.resource_type.get(name=name)
except gnocchi_exc.NotFound:
# FIXME(sileht): It should be ResourceTypeNotFound but
# gnocchiclient doesn't raise that :(
rt = {'name': name, 'attributes': attributes}
try:
gnocchi.resource_type.create(resource_type=rt)
except Exception:
LOG.error("Gnocchi resource creation fail", exc_info=True)
else:
# NOTE(sileht): We have to handle this case when it will be
# possible to add/rm resource-types columns
pass

View File

@ -359,10 +359,17 @@ function init_ceilometer {
sudo install -d -o $STACK_USER $CEILOMETER_AUTH_CACHE_DIR
rm -f $CEILOMETER_AUTH_CACHE_DIR/*
if is_service_enabled ceilometer-collector ceilometer-api && is_service_enabled mysql postgresql ; then
if [ "$CEILOMETER_BACKEND" = 'mysql' ] || [ "$CEILOMETER_BACKEND" = 'postgresql' ] || [ "$CEILOMETER_BACKEND" = 'es' ] ; then
recreate_database ceilometer
$CEILOMETER_BIN_DIR/ceilometer-upgrade
if is_service_enabled ceilometer-collector ceilometer-api; then
if is_service_enabled mysql postgresql ; then
if [ "$CEILOMETER_BACKEND" = 'mysql' ] || [ "$CEILOMETER_BACKEND" = 'postgresql' ] || [ "$CEILOMETER_BACKEND" = 'es' ] ; then
recreate_database ceilometer
$CEILOMETER_BIN_DIR/ceilometer-upgrade --skip-gnocchi-resource-types
fi
fi
if is_service_enabled gnocchi ; then
if [ "$CEILOMETER_BACKEND" = 'gnocchi' ]; then
$CEILOMETER_BIN_DIR/ceilometer-upgrade --skip-metering-database --skip-event-database
fi
fi
fi
}