Hello community,
here is the log from the commit of package openstack-ceilometer for
openSUSE:Factory checked in at 2014-01-30 17:41:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openstack-ceilometer (Old)
and /work/SRC/openSUSE:Factory/.openstack-ceilometer.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openstack-ceilometer"
Changes:
--------
---
/work/SRC/openSUSE:Factory/openstack-ceilometer/openstack-ceilometer.changes
2014-01-23 15:50:27.000000000 +0100
+++
/work/SRC/openSUSE:Factory/.openstack-ceilometer.new/openstack-ceilometer.changes
2014-01-30 17:41:20.000000000 +0100
@@ -1,0 +2,43 @@
+Thu Jan 30 01:18:33 UTC 2014 - [email protected]
+
+- Rebased patches:
+ + 0001-Skip-tests-against-real-DB.patch (only offset)
+
+-------------------------------------------------------------------
+Wed Jan 29 09:12:30 UTC 2014 - [email protected]
+
+- Add refresh_patches source service
+
+-------------------------------------------------------------------
+Wed Jan 29 08:13:29 UTC 2014 - [email protected]
+
+- Use correct group name for directory ownerships.
+
+-------------------------------------------------------------------
+Tue Jan 28 19:39:35 UTC 2014 - [email protected]
+
+- configure signing_dir / lock_path
+
+-------------------------------------------------------------------
+Tue Jan 28 15:13:19 UTC 2014 - [email protected]
+
+- add 0001-enable-sql-metadata-query.patch
+
+-------------------------------------------------------------------
+Mon Jan 27 17:08:06 UTC 2014 - [email protected]
+
+- Fix ownership of /var/log/ceilometer/ceilometer-dbsync.log
+ (bnc#860598).
+
+-------------------------------------------------------------------
+Mon Jan 27 10:26:51 UTC 2014 - [email protected]
+
+- fix typo in logrotate script
+
+-------------------------------------------------------------------
+Sun Jan 19 01:28:56 UTC 2014 - [email protected]
+
+- Update to version 2013.2.2.dev6.g16eb199:
+ + Update ceilometer.conf.sample
+
+-------------------------------------------------------------------
New:
----
0001-enable-sql-metadata-query.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ openstack-ceilometer-doc.spec ++++++
--- /var/tmp/diff_new_pack.RwyFt0/_old 2014-01-30 17:41:20.000000000 +0100
+++ /var/tmp/diff_new_pack.RwyFt0/_new 2014-01-30 17:41:20.000000000 +0100
@@ -19,7 +19,7 @@
%define component ceilometer
Name: openstack-%{component}-doc
-Version: 2013.2.2.dev5.gef71dc6
+Version: 2013.2.2.dev6.g16eb199
Release: 0
Summary: OpenStack Metering (Ceilometer) - Documentation
License: Apache-2.0
@@ -70,7 +70,7 @@
This package contains documentation files for openstack-ceilometer.
%prep
-%setup -q -n ceilometer-2013.2.2.dev5.gef71dc6
+%setup -q -n ceilometer-2013.2.2.dev6.g16eb199
%openstack_cleanup_prep
sed -i "s|'sphinxcontrib.autohttp.flask',||" doc/source/conf.py
++++++ openstack-ceilometer.spec ++++++
--- /var/tmp/diff_new_pack.RwyFt0/_old 2014-01-30 17:41:20.000000000 +0100
+++ /var/tmp/diff_new_pack.RwyFt0/_new 2014-01-30 17:41:20.000000000 +0100
@@ -22,7 +22,7 @@
%define username openstack-%{component}
Name: openstack-%{component}
-Version: 2013.2.2.dev5.gef71dc6
+Version: 2013.2.2.dev6.g16eb199
Release: 0
Summary: OpenStack Metering (Ceilometer)
License: Apache-2.0
@@ -35,6 +35,7 @@
Source13: openstack-ceilometer-polkit.rules
# PATCH-FIX-SUSE: Skip testing against DB2 and Mongodb
Patch0: 0001-Skip-tests-against-real-DB.patch
+Patch1: 0001-enable-sql-metadata-query.patch
BuildRequires: crudini
BuildRequires: fdupes
BuildRequires: openstack-suse-macros
@@ -188,8 +189,9 @@
This package contains testsuite files for %{name}.
%prep
-%setup -q -n ceilometer-2013.2.2.dev5.gef71dc6
+%setup -q -n ceilometer-2013.2.2.dev6.g16eb199
%patch0 -p1
+%patch1 -p1
%openstack_cleanup_prep
%build
@@ -203,9 +205,8 @@
### directories
#TODO: Check what we need:
-install -d -m 755 %{buildroot}%{_localstatedir}/lib/%{component}
-install -d -m 755 %{buildroot}%{_localstatedir}/log/%{component}
-install -d -m 755 %{buildroot}%{_localstatedir}/run/%{component}
+install -d -m 755 %{buildroot}%{_localstatedir}/{lib,log}/%{component}
+install -d -m 750 %{buildroot}%{_localstatedir}/{lock,cache,run}/%{component}
### configuration files
install -d -m 0755 %{buildroot}%{_sysconfdir}/%{component}
@@ -249,6 +250,8 @@
crudini --set %{ceilometer_conf} DEFAULT verbose True
#NOTE(saschpe): Don't set 'log_file', each ceilometer deamon will create it's
own if only 'log_dir' is set:
crudini --set %{ceilometer_conf} DEFAULT log_dir
%{_localstatedir}/log/%{component}
+crudini --set %{ceilometer_conf} DEFAULT lock_path
%{_localstatedir}/lock/%{component}
+crudini --set %{ceilometer_conf} keystone_authtoken signing_dir
/var/cache/%component/keystone-signing
crudini --set %{ceilometer_conf} DEFAULT policy_file
%{_sysconfdir}/%{component}/policy.json
### authentication cache dir
@@ -330,10 +333,11 @@
%config %{_sysconfdir}/%{component}/sources.json
%config %{_sysconfdir}/%{component}/policy.json
%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
-%dir %attr(0755, %{username}, %{username}) %{_localstatedir}/lib/%{component}
-%dir %attr(0750, %{username}, %{username}) %{_localstatedir}/log/%{component}
-%dir %attr(0700, %{username}, %{username}) %{_localstatedir}/cache/ceilometer
-%ghost %dir %attr(0755, %{username}, root) %{_localstatedir}/run/%{component}
+%dir %attr(0755, %{username}, %{groupname}) %{_localstatedir}/lib/%{component}
+%dir %attr(0750, %{username}, %{groupname})
%{_localstatedir}/cache/%{component}
+%dir %attr(0750, %{username}, %{groupname}) %{_localstatedir}/lock/%{component}
+%dir %attr(0750, %{username}, %{groupname}) %{_localstatedir}/log/%{component}
+%ghost %dir %attr(0750, %{username}, %{groupname})
%{_localstatedir}/run/%{component}
%files -n python-ceilometer
%defattr(-,root,root,-)
++++++ 0001-Skip-tests-against-real-DB.patch ++++++
--- /var/tmp/diff_new_pack.RwyFt0/_old 2014-01-30 17:41:20.000000000 +0100
+++ /var/tmp/diff_new_pack.RwyFt0/_new 2014-01-30 17:41:20.000000000 +0100
@@ -10,11 +10,11 @@
tests/api/v2/test_statistics_scenarios.py | 5 +----
3 files changed, 2 insertions(+), 17 deletions(-)
-Index: ceilometer-2014.1.a67.g125411e/ceilometer/tests/db.py
+Index: ceilometer-2013.2.2.dev6.g16eb199/ceilometer/tests/db.py
===================================================================
---- ceilometer-2014.1.a67.g125411e.orig/ceilometer/tests/db.py
-+++ ceilometer-2014.1.a67.g125411e/ceilometer/tests/db.py
-@@ -84,7 +84,4 @@ class MixinTestsWithBackendScenarios(obj
+--- ceilometer-2013.2.2.dev6.g16eb199.orig/ceilometer/tests/db.py
++++ ceilometer-2013.2.2.dev6.g16eb199/ceilometer/tests/db.py
+@@ -83,7 +83,4 @@ class MixinTestsWithBackendScenarios(obj
scenarios = [
('sqlalchemy', dict(database_connection='sqlite://')),
@@ -22,10 +22,10 @@
- ('hbase', dict(database_connection='hbase://__test__')),
- ('db2', dict(database_connection=DB2FakeConnectionUrl())),
]
-Index: ceilometer-2014.1.a67.g125411e/tests/api/v2/test_app.py
+Index: ceilometer-2013.2.2.dev6.g16eb199/tests/api/v2/test_app.py
===================================================================
---- ceilometer-2014.1.a67.g125411e.orig/tests/api/v2/test_app.py
-+++ ceilometer-2014.1.a67.g125411e/tests/api/v2/test_app.py
+--- ceilometer-2013.2.2.dev6.g16eb199.orig/tests/api/v2/test_app.py
++++ ceilometer-2013.2.2.dev6.g16eb199/tests/api/v2/test_app.py
@@ -66,19 +66,10 @@ class TestApp(base.TestCase):
os.unlink(tmpfile)
@@ -47,10 +47,10 @@
no_lang_translated_error = 'No lang translated error'
en_US_translated_error = 'en-US translated error'
-Index: ceilometer-2014.1.a67.g125411e/tests/api/v2/test_statistics_scenarios.py
+Index:
ceilometer-2013.2.2.dev6.g16eb199/tests/api/v2/test_statistics_scenarios.py
===================================================================
----
ceilometer-2014.1.a67.g125411e.orig/tests/api/v2/test_statistics_scenarios.py
-+++ ceilometer-2014.1.a67.g125411e/tests/api/v2/test_statistics_scenarios.py
+---
ceilometer-2013.2.2.dev6.g16eb199.orig/tests/api/v2/test_statistics_scenarios.py
++++ ceilometer-2013.2.2.dev6.g16eb199/tests/api/v2/test_statistics_scenarios.py
@@ -1234,10 +1234,7 @@ class TestGroupBySource(base.FunctionalT
# tests.
++++++ 0001-enable-sql-metadata-query.patch ++++++
>From 02d93a52fa68d2ed75f0fbb1cb00f9aebaa5069c Mon Sep 17 00:00:00 2001
From: Gordon Chung <[email protected]>
Date: Wed, 2 Oct 2013 15:45:26 -0400
Subject: [PATCH] enable sql metadata query
explode metadata key/values to their own tables/rows (based on type).
build a key string using dot notation similar to other nosql db
and filter based on that.
Blueprint: sqlalchemy-metadata-query
Related-Bug: #1093625
Change-Id: I2076e67b79448f98124a57b62b5bfed7aa8ae2ad
(cherry picked from commit 1570462507eae1478123de25dbadc64b09c82af3)
---
ceilometer/storage/impl_sqlalchemy.py | 79 +++++++++++++++++++---
.../versions/020_add_metadata_tables.py | 78 +++++++++++++++++++++
ceilometer/storage/sqlalchemy/models.py | 48 +++++++++++++
ceilometer/utils.py | 24 +++++++
doc/source/install/dbreco.rst | 4 +-
tests/api/v2/test_list_meters_scenarios.py | 1 +
tests/test_utils.py | 16 +++++
7 files changed, 239 insertions(+), 11 deletions(-)
create mode 100644
ceilometer/storage/sqlalchemy/migrate_repo/versions/020_add_metadata_tables.py
diff --git a/ceilometer/storage/impl_sqlalchemy.py
b/ceilometer/storage/impl_sqlalchemy.py
index 08ffb47..9ede0f3 100644
--- a/ceilometer/storage/impl_sqlalchemy.py
+++ b/ceilometer/storage/impl_sqlalchemy.py
@@ -18,10 +18,12 @@
"""SQLAlchemy storage backend."""
from __future__ import absolute_import
-
import datetime
import operator
import os
+import types
+
+from sqlalchemy import and_
from sqlalchemy import func
from sqlalchemy import desc
from sqlalchemy.orm import aliased
@@ -39,6 +41,10 @@ from ceilometer.storage.sqlalchemy.models import AlarmChange
from ceilometer.storage.sqlalchemy.models import Base
from ceilometer.storage.sqlalchemy.models import Event
from ceilometer.storage.sqlalchemy.models import Meter
+from ceilometer.storage.sqlalchemy.models import MetaBool
+from ceilometer.storage.sqlalchemy.models import MetaFloat
+from ceilometer.storage.sqlalchemy.models import MetaInt
+from ceilometer.storage.sqlalchemy.models import MetaText
from ceilometer.storage.sqlalchemy.models import Project
from ceilometer.storage.sqlalchemy.models import Resource
from ceilometer.storage.sqlalchemy.models import Source
@@ -100,7 +106,40 @@ class SQLAlchemyStorage(base.StorageEngine):
return Connection(conf)
-def make_query_from_filter(query, sample_filter, require_meter=True):
+META_TYPE_MAP = {bool: MetaBool,
+ str: MetaText,
+ unicode: MetaText,
+ types.NoneType: MetaText,
+ int: MetaInt,
+ long: MetaInt,
+ float: MetaFloat}
+
+
+def apply_metaquery_filter(session, query, metaquery):
+ """Apply provided metaquery filter to existing query.
+
+ :param session: session used for original query
+ :param query: Query instance
+ :param metaquery: dict with metadata to match on.
+ """
+
+ for k, v in metaquery.iteritems():
+ key = k[9:] # strip out 'metadata.' prefix
+ try:
+ _model = META_TYPE_MAP[type(v)]
+ except KeyError:
+ raise NotImplementedError(_('Query on %(key)s is of %(value)s '
+ 'type and is not supported') %
+ {"key": k, "value": type(v)})
+ else:
+ meta_q = session.query(_model).\
+ filter(and_(_model.meta_key == key,
+ _model.value == v)).subquery()
+ query = query.filter_by(id=meta_q.c.id)
+ return query
+
+
+def make_query_from_filter(session, query, sample_filter, require_meter=True):
"""Return a query dictionary based on the settings in the filter.
:param filter: SampleFilter instance
@@ -134,7 +173,8 @@ def make_query_from_filter(query, sample_filter,
require_meter=True):
query = query.filter_by(resource_id=sample_filter.resource)
if sample_filter.metaquery:
- raise NotImplementedError(_('metaquery not implemented'))
+ query = apply_metaquery_filter(session, query,
+ sample_filter.metaquery)
return query
@@ -229,6 +269,21 @@ class Connection(base.Connection):
meter.message_signature = data['message_signature']
meter.message_id = data['message_id']
+ if rmetadata:
+ if isinstance(rmetadata, dict):
+ for key, v in utils.dict_to_keyval(rmetadata):
+ try:
+ _model = META_TYPE_MAP[type(v)]
+ except KeyError:
+ LOG.warn(_("Unknown metadata type. Key (%s) will "
+ "not be queryable."), key)
+ else:
+ session.add(_model(id=meter.id,
+ meta_key=key,
+ value=v))
+
+ session.flush()
+
@staticmethod
def clear_expired_metering_data(ttl):
"""Clear expired data from the backend storage system according to the
@@ -306,8 +361,6 @@ class Connection(base.Connection):
# just fail.
if pagination:
raise NotImplementedError(_('Pagination not implemented'))
- if metaquery:
- raise NotImplementedError(_('metaquery not implemented'))
# (thomasm) We need to get the max timestamp first, since that's the
# most accurate. We also need to filter down in the subquery to
@@ -331,6 +384,11 @@ class Connection(base.Connection):
ts_subquery = ts_subquery.filter(
Meter.sources.any(id=source))
+ if metaquery:
+ ts_subquery = apply_metaquery_filter(session,
+ ts_subquery,
+ metaquery)
+
# Here we limit the samples being used to a specific time period,
# if requested.
if start_timestamp:
@@ -397,8 +455,6 @@ class Connection(base.Connection):
if pagination:
raise NotImplementedError(_('Pagination not implemented'))
- if metaquery:
- raise NotImplementedError(_('metaquery not implemented'))
session = sqlalchemy_session.get_session()
@@ -422,6 +478,11 @@ class Connection(base.Connection):
query_meter = session.query(Meter).\
join(subquery_meter, Meter.id == subquery_meter.c.id)
+ if metaquery:
+ query_meter = apply_metaquery_filter(session,
+ query_meter,
+ metaquery)
+
alias_meter = aliased(Meter, query_meter.subquery())
query = session.query(Resource, alias_meter).join(
alias_meter, Resource.id == alias_meter.resource_id)
@@ -457,7 +518,7 @@ class Connection(base.Connection):
session = sqlalchemy_session.get_session()
query = session.query(Meter)
- query = make_query_from_filter(query, sample_filter,
+ query = make_query_from_filter(session, query, sample_filter,
require_meter=False)
if limit:
query = query.limit(limit)
@@ -509,7 +570,7 @@ class Connection(base.Connection):
if groupby:
query = query.group_by(*group_attributes)
- return make_query_from_filter(query, sample_filter)
+ return make_query_from_filter(session, query, sample_filter)
@staticmethod
def _stats_result_to_model(result, period, period_start,
diff --git
a/ceilometer/storage/sqlalchemy/migrate_repo/versions/020_add_metadata_tables.py
b/ceilometer/storage/sqlalchemy/migrate_repo/versions/020_add_metadata_tables.py
new file mode 100644
index 0000000..085cd6b
--- /dev/null
+++
b/ceilometer/storage/sqlalchemy/migrate_repo/versions/020_add_metadata_tables.py
@@ -0,0 +1,78 @@
+#
+# Copyright 2013 OpenStack Foundation
+# All Rights Reserved.
+#
+# 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.
+import json
+
+from sqlalchemy import Boolean
+from sqlalchemy import Column
+from sqlalchemy import Float
+from sqlalchemy import ForeignKey
+from sqlalchemy import Integer
+from sqlalchemy import MetaData
+from sqlalchemy import String
+from sqlalchemy import Table
+from sqlalchemy import Text
+from sqlalchemy.sql import select
+
+from ceilometer import utils
+
+tables = [('metadata_text', Text, True),
+ ('metadata_bool', Boolean, False),
+ ('metadata_int', Integer, False),
+ ('metadata_float', Float, False)]
+
+
+def upgrade(migrate_engine):
+ meta = MetaData(bind=migrate_engine)
+ meter = Table('meter', meta, autoload=True)
+ meta_tables = {}
+ for t_name, t_type, t_nullable in tables:
+ meta_tables[t_name] = Table(
+ t_name, meta,
+ Column('id', Integer, ForeignKey('meter.id'), primary_key=True),
+ Column('meta_key', String(255), index=True, primary_key=True),
+ Column('value', t_type, nullable=t_nullable),
+ mysql_engine='InnoDB',
+ mysql_charset='utf8',
+ )
+ meta_tables[t_name].create()
+
+ for row in select([meter]).execute():
+ meter_id = row['id']
+ rmeta = json.loads(row['resource_metadata'])
+ for key, v in utils.dict_to_keyval(rmeta):
+ if isinstance(v, basestring) or v is None:
+ meta_tables['metadata_text'].insert().values(id=meter_id,
+ meta_key=key,
+ value=v)
+ elif isinstance(v, bool):
+ meta_tables['metadata_bool'].insert().values(id=meter_id,
+ meta_key=key,
+ value=v)
+ elif isinstance(v, (int, long)):
+ meta_tables['metadata_int'].insert().values(id=meter_id,
+ meta_key=key,
+ value=v)
+ elif isinstance(v, float):
+ meta_tables['metadata_float'].insert().values(id=meter_id,
+ meta_key=key,
+ value=v)
+
+
+def downgrade(migrate_engine):
+ meta = MetaData(bind=migrate_engine)
+ for t in tables:
+ table = Table(t[0], meta, autoload=True)
+ table.drop()
diff --git a/ceilometer/storage/sqlalchemy/models.py
b/ceilometer/storage/sqlalchemy/models.py
index 45f98cb..8f890b3 100644
--- a/ceilometer/storage/sqlalchemy/models.py
+++ b/ceilometer/storage/sqlalchemy/models.py
@@ -141,6 +141,54 @@ class Source(Base):
id = Column(String(255), primary_key=True)
+class MetaText(Base):
+ """Metering text metadata."""
+
+ __tablename__ = 'metadata_text'
+ __table_args__ = (
+ Index('ix_meta_text_key', 'meta_key'),
+ )
+ id = Column(Integer, ForeignKey('meter.id'), primary_key=True)
+ meta_key = Column(String(255), primary_key=True)
+ value = Column(Text)
+
+
+class MetaBool(Base):
+ """Metering boolean metadata."""
+
+ __tablename__ = 'metadata_bool'
+ __table_args__ = (
+ Index('ix_meta_bool_key', 'meta_key'),
+ )
+ id = Column(Integer, ForeignKey('meter.id'), primary_key=True)
+ meta_key = Column(String(255), primary_key=True)
+ value = Column(Boolean)
+
+
+class MetaInt(Base):
+ """Metering integer metadata."""
+
+ __tablename__ = 'metadata_int'
+ __table_args__ = (
+ Index('ix_meta_int_key', 'meta_key'),
+ )
+ id = Column(Integer, ForeignKey('meter.id'), primary_key=True)
+ meta_key = Column(String(255), primary_key=True)
+ value = Column(Integer, default=False)
+
+
+class MetaFloat(Base):
+ """Metering float metadata."""
+
+ __tablename__ = 'metadata_float'
+ __table_args__ = (
+ Index('ix_meta_float_key', 'meta_key'),
+ )
+ id = Column(Integer, ForeignKey('meter.id'), primary_key=True)
+ meta_key = Column(String(255), primary_key=True)
+ value = Column(Float, default=False)
+
+
class Meter(Base):
"""Metering data."""
diff --git a/ceilometer/utils.py b/ceilometer/utils.py
index 07faf29..0bc7dfc 100644
--- a/ceilometer/utils.py
+++ b/ceilometer/utils.py
@@ -90,3 +90,27 @@ def stringify_timestamps(data):
isa_timestamp = lambda v: isinstance(v, datetime.datetime)
return dict((k, v.isoformat() if isa_timestamp(v) else v)
for (k, v) in data.iteritems())
+
+
+def dict_to_keyval(value, key_base=None):
+ """Expand a given dict to its corresponding key-value pairs.
+
+ Generated keys are fully qualified, delimited using dot notation.
+ ie. key = 'key.child_key.grandchild_key[0]'
+ """
+ val_iter, key_func = None, None
+ if isinstance(value, dict):
+ val_iter = value.iteritems()
+ key_func = lambda k: key_base + '.' + k if key_base else k
+ elif isinstance(value, (tuple, list)):
+ val_iter = enumerate(value)
+ key_func = lambda k: key_base + '[%d]' % k
+
+ if val_iter:
+ for k, v in val_iter:
+ key_gen = key_func(k)
+ if isinstance(v, dict) or isinstance(v, (tuple, list)):
+ for key_gen, v in dict_to_keyval(v, key_gen):
+ yield key_gen, v
+ else:
+ yield key_gen, v
diff --git a/doc/source/install/dbreco.rst b/doc/source/install/dbreco.rst
index fe60329..249cdc7 100644
--- a/doc/source/install/dbreco.rst
+++ b/doc/source/install/dbreco.rst
@@ -43,8 +43,8 @@ The following is a table indicating the status of each
database drivers:
Driver API querying API statistics Alarms
================== ============================= =================== ======
MongoDB Yes Yes Yes
-MySQL Yes, except metadata querying Yes Yes
-PostgreSQL Yes, except metadata querying Yes Yes
+MySQL Yes Yes Yes
+PostgreSQL Yes Yes Yes
HBase Yes Yes, except groupby No
DB2 Yes Yes No
================== ============================= =================== ======
diff --git a/tests/api/v2/test_list_meters_scenarios.py
b/tests/api/v2/test_list_meters_scenarios.py
index fe2c5b7..3381e15 100644
--- a/tests/api/v2/test_list_meters_scenarios.py
+++ b/tests/api/v2/test_list_meters_scenarios.py
@@ -252,6 +252,7 @@ class TestListMeters(FunctionalTest,
set(['meter.mine']))
self.assertEqual(set(r['resource_metadata']['is_public'] for r
in data), set(['False']))
+ # FIXME(gordc): verify no false positive (Bug#1236496)
def test_list_meters_query_string_metadata(self):
data = self.get_json('/meters/meter.test',
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 90e06d6..ec60542 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -84,3 +84,19 @@ class TestUtils(tests_base.TestCase):
def test_decimal_to_dt_with_none_parameter(self):
self.assertEqual(utils.decimal_to_dt(None), None)
+
+ def test_dict_to_kv(self):
+ data = {'a': 'A',
+ 'b': 'B',
+ 'nested': {'a': 'A',
+ 'b': 'B',
+ },
+ 'nested2': [{'c': 'A'}, {'c': 'B'}]
+ }
+ pairs = list(utils.dict_to_keyval(data))
+ self.assertEqual(pairs, [('a', 'A'),
+ ('b', 'B'),
+ ('nested2[0].c', 'A'),
+ ('nested2[1].c', 'B'),
+ ('nested.a', 'A'),
+ ('nested.b', 'B')])
--
1.8.4.1
++++++ _service ++++++
--- /var/tmp/diff_new_pack.RwyFt0/_old 2014-01-30 17:41:21.000000000 +0100
+++ /var/tmp/diff_new_pack.RwyFt0/_new 2014-01-30 17:41:21.000000000 +0100
@@ -4,4 +4,8 @@
<param name="email">[email protected]</param>
<param name="plain-version">True</param>
</service>
+
+ <service name="refresh_patches" mode="disabled">
+ <param name="changesgenerate">enable</param>
+ </service>
</services>
++++++ ceilometer-stable-havana.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ceilometer-2013.2.2.dev5.gef71dc6/AUTHORS
new/ceilometer-2013.2.2.dev6.g16eb199/AUTHORS
--- old/ceilometer-2013.2.2.dev5.gef71dc6/AUTHORS 2014-01-11
15:17:37.000000000 +0100
+++ new/ceilometer-2013.2.2.dev6.g16eb199/AUTHORS 2014-01-18
11:10:06.000000000 +0100
@@ -35,6 +35,7 @@
Guangyu Suo <[email protected]>
Haomeng, Wang <[email protected]>
Harri Hämäläinen <[email protected]>
+Ildiko Vancsa <[email protected]>
Ionuț Arțăriși <[email protected]>
Jake Liu <[email protected]>
Jason Zhang <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ceilometer-2013.2.2.dev5.gef71dc6/ChangeLog
new/ceilometer-2013.2.2.dev6.g16eb199/ChangeLog
--- old/ceilometer-2013.2.2.dev5.gef71dc6/ChangeLog 2014-01-11
15:17:37.000000000 +0100
+++ new/ceilometer-2013.2.2.dev6.g16eb199/ChangeLog 2014-01-18
11:10:05.000000000 +0100
@@ -1,3 +1,15 @@
+commit 16eb199124e73df48a15193ad31b681e382becc8
+Author: Ildiko Vancsa <[email protected]>
+Date: Mon Jan 13 20:26:07 2014 +0100
+
+ Update ceilometer.conf.sample
+
+ Due to python-keystoneclient update.
+
+ Change-Id: Ie683d3fbf8086d2be6a2fbe19374b8d31abaf976
+ Closes-bug: #1268614
+ (cherry picked from commit 76c06e03eaef0c66689c62aece24baee0b372644)
+
commit ef71dc6a11ab624e756bfb61ec974e9f6096bc30
Author: Eoghan Glynn <[email protected]>
Date: Thu Jan 9 11:11:43 2014 +0000
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ceilometer-2013.2.2.dev5.gef71dc6/PKG-INFO
new/ceilometer-2013.2.2.dev6.g16eb199/PKG-INFO
--- old/ceilometer-2013.2.2.dev5.gef71dc6/PKG-INFO 2014-01-11
15:17:37.000000000 +0100
+++ new/ceilometer-2013.2.2.dev6.g16eb199/PKG-INFO 2014-01-18
11:10:07.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: ceilometer
-Version: 2013.2.2.dev5.gef71dc6
+Version: 2013.2.2.dev6.g16eb199
Summary: OpenStack Metering
Home-page: http://www.openstack.org/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ceilometer-2013.2.2.dev5.gef71dc6/ceilometer.egg-info/PKG-INFO
new/ceilometer-2013.2.2.dev6.g16eb199/ceilometer.egg-info/PKG-INFO
--- old/ceilometer-2013.2.2.dev5.gef71dc6/ceilometer.egg-info/PKG-INFO
2014-01-11 15:17:37.000000000 +0100
+++ new/ceilometer-2013.2.2.dev6.g16eb199/ceilometer.egg-info/PKG-INFO
2014-01-18 11:10:06.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: ceilometer
-Version: 2013.2.2.dev5.gef71dc6
+Version: 2013.2.2.dev6.g16eb199
Summary: OpenStack Metering
Home-page: http://www.openstack.org/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ceilometer-2013.2.2.dev5.gef71dc6/etc/ceilometer/ceilometer.conf.sample
new/ceilometer-2013.2.2.dev6.g16eb199/etc/ceilometer/ceilometer.conf.sample
--- old/ceilometer-2013.2.2.dev5.gef71dc6/etc/ceilometer/ceilometer.conf.sample
2014-01-11 15:15:01.000000000 +0100
+++ new/ceilometer-2013.2.2.dev6.g16eb199/etc/ceilometer/ceilometer.conf.sample
2014-01-18 11:04:22.000000000 +0100
@@ -817,6 +817,12 @@
# value)
#memcache_secret_key=<None>
+# (optional) indicate whether to set the X-Service-Catalog
+# header. If False, middleware will not ask for service
+# catalog on token validation and will not set the X-Service-
+# Catalog header. (boolean value)
+#include_service_catalog=true
+
[collector]
++++++ openstack-ceilometer.init ++++++
--- /var/tmp/diff_new_pack.RwyFt0/_old 2014-01-30 17:41:21.000000000 +0100
+++ /var/tmp/diff_new_pack.RwyFt0/_new 2014-01-30 17:41:21.000000000 +0100
@@ -28,6 +28,7 @@
start)
if [ "$DAEMON" == "api" ]; then
echo -n "Checking DB Migrations for ceilometer"
+ test -f /var/log/ceilometer/ceilometer-dbsync.log && chown $USER.
/var/log/ceilometer/ceilometer-dbsync.log
su $USER -s /bin/sh -c "ceilometer-dbsync --config-file=$CONFFILE"
> /dev/null
rc_status -v
fi
++++++ openstack-ceilometer.logrotate ++++++
--- /var/tmp/diff_new_pack.RwyFt0/_old 2014-01-30 17:41:21.000000000 +0100
+++ /var/tmp/diff_new_pack.RwyFt0/_new 2014-01-30 17:41:21.000000000 +0100
@@ -6,7 +6,7 @@
weekly
dateext
missingok
- notifyempty
+ notifempty
su openstack-ceilometer openstack-ceilometer
copytruncate
sharedscripts
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]