summaryrefslogtreecommitdiffstats
path: root/nova/db
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-07-11 17:06:42 +0000
committerGerrit Code Review <review@openstack.org>2012-07-11 17:06:42 +0000
commitf220bf679086fdb3fbb01fd77fc2bb7234c121fe (patch)
tree6a84c5d8fddf1e205aaf8eec3451a3bf62931245 /nova/db
parent0c8d9c749a5d697c49ba45c08ba716c47809e2ab (diff)
parent2fdd73816c56b578a65466db4e5a86b9b191e1c1 (diff)
downloadnova-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.py67
-rw-r--r--nova/db/sqlalchemy/api.py95
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/108_task_log.py62
-rw-r--r--nova/db/sqlalchemy/models.py14
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)