diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-07-11 17:06:42 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-07-11 17:06:42 +0000 |
| commit | f220bf679086fdb3fbb01fd77fc2bb7234c121fe (patch) | |
| tree | 6a84c5d8fddf1e205aaf8eec3451a3bf62931245 /nova/db | |
| parent | 0c8d9c749a5d697c49ba45c08ba716c47809e2ab (diff) | |
| parent | 2fdd73816c56b578a65466db4e5a86b9b191e1c1 (diff) | |
| download | nova-f220bf679086fdb3fbb01fd77fc2bb7234c121fe.tar.gz nova-f220bf679086fdb3fbb01fd77fc2bb7234c121fe.tar.xz nova-f220bf679086fdb3fbb01fd77fc2bb7234c121fe.zip | |
Merge "Refactor instance_usage_audit. Add audit tasklog."
Diffstat (limited to 'nova/db')
| -rw-r--r-- | nova/db/api.py | 67 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 95 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/108_task_log.py | 62 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/models.py | 14 |
4 files changed, 230 insertions, 8 deletions
diff --git a/nova/db/api.py b/nova/db/api.py index 695c083c9..fd4babb55 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -585,20 +585,26 @@ def instance_get_all_by_filters(context, filters, sort_key='created_at', sort_dir) -def instance_get_active_by_window(context, begin, end=None, project_id=None): +def instance_get_active_by_window(context, begin, end=None, project_id=None, + host=None): """Get instances active during a certain time window. - Specifying a project_id will filter for a certain project.""" - return IMPL.instance_get_active_by_window(context, begin, end, project_id) + Specifying a project_id will filter for a certain project. + Specifying a host will filter for instances on a given compute host. + """ + return IMPL.instance_get_active_by_window(context, begin, end, + project_id, host) def instance_get_active_by_window_joined(context, begin, end=None, - project_id=None): + project_id=None, host=None): """Get instances and joins active during a certain time window. - Specifying a project_id will filter for a certain project.""" + Specifying a project_id will filter for a certain project. + Specifying a host will filter for instances on a given compute host. + """ return IMPL.instance_get_active_by_window_joined(context, begin, end, - project_id) + project_id, host) def instance_get_all_by_project(context, project_id): @@ -1948,3 +1954,52 @@ def get_instance_uuid_by_ec2_id(context, instance_id): def ec2_instance_create(context, instance_ec2_id): """Create the ec2 id to instance uuid mapping on demand""" return IMPL.ec2_instance_create(context, instance_ec2_id) + + +#################### + + +def task_log_end_task(context, task_name, + period_beginning, + period_ending, + host, + errors, + message=None, + session=None): + """Mark a task as complete for a given host/time period""" + return IMPL.task_log_end_task(context, task_name, + period_beginning, + period_ending, + host, + errors, + message, + session) + + +def task_log_begin_task(context, task_name, + period_beginning, + period_ending, + host, + task_items=None, + message=None, + session=None): + """Mark a task as started for a given host/time period""" + return IMPL.task_log_begin_task(context, task_name, + period_beginning, + period_ending, + host, + task_items, + message, + session) + + +def task_log_get_all(context, task_name, period_beginning, + period_ending, host=None, state=None, session=None): + return IMPL.task_log_get_all(context, task_name, period_beginning, + period_ending, host, state, session) + + +def task_log_get(context, task_name, period_beginning, + period_ending, host, state=None, session=None): + return IMPL.task_log_get(context, task_name, period_beginning, + period_ending, host, state, session) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 93bce01c5..54d70b14f 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1564,7 +1564,8 @@ def instance_get_all_by_filters(context, filters, sort_key, sort_dir): @require_context -def instance_get_active_by_window(context, begin, end=None, project_id=None): +def instance_get_active_by_window(context, begin, end=None, + project_id=None, host=None): """Return instances that were active during window.""" session = get_session() query = session.query(models.Instance) @@ -1575,13 +1576,15 @@ def instance_get_active_by_window(context, begin, end=None, project_id=None): query = query.filter(models.Instance.launched_at < end) if project_id: query = query.filter_by(project_id=project_id) + if host: + query = query.filter_by(host=host) return query.all() @require_admin_context def instance_get_active_by_window_joined(context, begin, end=None, - project_id=None): + project_id=None, host=None): """Return instances and joins that were active during window.""" session = get_session() query = session.query(models.Instance) @@ -1596,6 +1599,8 @@ def instance_get_active_by_window_joined(context, begin, end=None, query = query.filter(models.Instance.launched_at < end) if project_id: query = query.filter_by(project_id=project_id) + if host: + query = query.filter_by(host=host) return query.all() @@ -5189,3 +5194,89 @@ def get_instance_uuid_by_ec2_id(context, instance_id, session=None): @require_context def _ec2_instance_get_query(context, session=None): return model_query(context, models.InstanceIdMapping, session=session) + + +@require_admin_context +def task_log_get(context, task_name, period_beginning, + period_ending, host, state=None, session=None): + query = model_query(context, models.TaskLog, session=session).\ + filter_by(task_name=task_name).\ + filter_by(period_beginning=period_beginning).\ + filter_by(period_ending=period_ending).\ + filter_by(host=host) + if state is not None: + query = query.filter_by(state=state) + + return query.first() + + +@require_admin_context +def task_log_get_all(context, task_name, period_beginning, + period_ending, host=None, state=None, session=None): + query = model_query(context, models.TaskLog, session=session).\ + filter_by(task_name=task_name).\ + filter_by(period_beginning=period_beginning).\ + filter_by(period_ending=period_ending) + if host is not None: + query = query.filter_by(host=host) + if state is not None: + query = query.filter_by(state=state) + return query.all() + + +@require_admin_context +def task_log_begin_task(context, task_name, + period_beginning, + period_ending, + host, + task_items=None, + message=None, + session=None): + session = session or get_session() + with session.begin(): + task = task_log_get(context, task_name, + period_beginning, + period_ending, + host, + session=session) + if task: + #It's already run(ning)! + raise exception.TaskAlreadyRunning(task_name=task_name, host=host) + task = models.TaskLog() + task.task_name = task_name + task.period_beginning = period_beginning + task.period_ending = period_ending + task.host = host + task.state = "RUNNING" + if message: + task.message = message + if task_items: + task.task_items = task_items + task.save(session=session) + return task + + +@require_admin_context +def task_log_end_task(context, task_name, + period_beginning, + period_ending, + host, + errors, + message=None, + session=None): + session = session or get_session() + with session.begin(): + task = task_log_get(context, task_name, + period_beginning, + period_ending, + host, + session=session) + if not task: + #It's not running! + raise exception.TaskNotRunning(task_name=task_name, host=host) + task.state = "DONE" + if message: + task.message = message + task.errors = errors + task.save(session=session) + return task diff --git a/nova/db/sqlalchemy/migrate_repo/versions/108_task_log.py b/nova/db/sqlalchemy/migrate_repo/versions/108_task_log.py new file mode 100644 index 000000000..e6aedc1a6 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/108_task_log.py @@ -0,0 +1,62 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2012 SINA Corp. +# 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. + +from sqlalchemy import Boolean, Column, DateTime, Integer +from sqlalchemy import Index, MetaData, String, Table + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + # create new table + task_log = Table('task_log', meta, + Column('created_at', DateTime(timezone=False)), + Column('updated_at', DateTime(timezone=False)), + Column('deleted_at', DateTime(timezone=False)), + Column('deleted', + Boolean(create_constraint=True, name=None)), + Column('id', Integer(), + primary_key=True, + nullable=False, + autoincrement=True), + Column('task_name', String(255), nullable=False), + Column('state', String(255), nullable=False), + Column('host', String(255), index=True, nullable=False), + Column('period_beginning', String(255), + index=True, nullable=False), + Column('period_ending', String(255), index=True, nullable=False), + Column('message', String(255), nullable=False), + Column('task_items', Integer()), + Column('errors', Integer()), + ) + try: + task_log.create() + except Exception: + meta.drop_all(tables=[task_log]) + raise + + if migrate_engine.name == "mysql": + migrate_engine.execute("ALTER TABLE task_log " + "Engine=InnoDB") + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + task_log = Table('task_log', meta, autoload=True) + task_log.drop() diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 335989135..d117d9361 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -1043,3 +1043,17 @@ class InstanceIdMapping(BASE, NovaBase): __tablename__ = 'instance_id_mappings' id = Column(Integer, primary_key=True, nullable=False, autoincrement=True) uuid = Column(String(36), nullable=False) + + +class TaskLog(BASE, NovaBase): + """Audit log for background periodic tasks""" + __tablename__ = 'task_log' + id = Column(Integer, primary_key=True, nullable=False, autoincrement=True) + task_name = Column(String(255), nullable=False) + state = Column(String(255), nullable=False) + host = Column(String(255)) + period_beginning = Column(String(255), default=timeutils.utcnow) + period_ending = Column(String(255), default=timeutils.utcnow) + message = Column(String(255), nullable=False) + task_items = Column(Integer(), default=0) + errors = Column(Integer(), default=0) |
