From 33ec0904362bc0011abab4e02944d504ff47b4f1 Mon Sep 17 00:00:00 2001
From: Dan Prince <dan.prince@rackspace.com>
Date: Wed, 17 Aug 2011 11:46:28 -0400
Subject: [PATCH 01/25] Split set state into vm, task, and power state
 functions.

---
 nova/db/sqlalchemy/api.py | 46 +++++++++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 9 deletions(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 57a4370d8..07207b8ee 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1439,15 +1439,43 @@ def instance_get_floating_address(context, instance_id):
 
 
 @require_admin_context
-def instance_set_state(context, instance_id, state, description=None):
-    # TODO(devcamcar): Move this out of models and into driver
-    from nova.compute import power_state
-    if not description:
-        description = power_state.name(state)
-    db.instance_update(context,
-                       instance_id,
-                       {'state': state,
-                        'state_description': description})
+def instance_set_power_state(context, instance_id, power_state):
+    session = get_session()
+    partial = session.query(models.Instance)
+  
+    if utils.is_uuid_like(instance_id):
+        result = partial.filter_by(uuid=instance_id)
+    else:
+        result = partial.filter_by(id=instance_id)
+
+    result.update({'power_state': power_state})
+
+
+@require_admin_context
+def instance_set_vm_state(context, instance_id, vm_state):
+    # vm_state = running, halted, suspended, paused
+    session = get_session()
+    partial = session.query(models.Instance)
+  
+    if utils.is_uuid_like(instance_id):
+        result = partial.filter_by(uuid=instance_id)
+    else:
+        result = partial.filter_by(id=instance_id)
+
+    result.update({'vm_state': vm_state})
+
+
+def instance_set_task_state(context, instance_id, task_state):
+    # task_state = running, halted, suspended, paused
+    session = get_session()
+    partial = session.query(models.Instance)
+  
+    if utils.is_uuid_like(instance_id):
+        result = partial.filter_by(uuid=instance_id)
+    else:
+        result = partial.filter_by(id=instance_id)
+
+    result.update({'task_state': task_state})
 
 
 @require_context

From 18b5c50a0c666f87c39d6e8badce7a60232fd293 Mon Sep 17 00:00:00 2001
From: Dan Prince <dan.prince@rackspace.com>
Date: Wed, 17 Aug 2011 11:51:39 -0400
Subject: [PATCH 02/25] Pep8 fixes.

---
 nova/db/sqlalchemy/api.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 07207b8ee..e7d02cb5d 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1442,7 +1442,7 @@ def instance_get_floating_address(context, instance_id):
 def instance_set_power_state(context, instance_id, power_state):
     session = get_session()
     partial = session.query(models.Instance)
-  
+
     if utils.is_uuid_like(instance_id):
         result = partial.filter_by(uuid=instance_id)
     else:
@@ -1456,7 +1456,7 @@ def instance_set_vm_state(context, instance_id, vm_state):
     # vm_state = running, halted, suspended, paused
     session = get_session()
     partial = session.query(models.Instance)
-  
+
     if utils.is_uuid_like(instance_id):
         result = partial.filter_by(uuid=instance_id)
     else:
@@ -1469,7 +1469,7 @@ def instance_set_task_state(context, instance_id, task_state):
     # task_state = running, halted, suspended, paused
     session = get_session()
     partial = session.query(models.Instance)
-  
+
     if utils.is_uuid_like(instance_id):
         result = partial.filter_by(uuid=instance_id)
     else:

From 20a4630b69d9ea47a3e44317d279881db4e7db24 Mon Sep 17 00:00:00 2001
From: Brian Lamar <brian.lamar@rackspace.com>
Date: Thu, 18 Aug 2011 12:34:01 -0400
Subject: [PATCH 03/25] Updated a number of items to pave the way for new
 states.

---
 nova/db/sqlalchemy/api.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index e7d02cb5d..67736dea2 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1079,8 +1079,8 @@ def instance_stop(context, instance_id):
         session.query(models.Instance).\
                 filter_by(id=instance_id).\
                 update({'host': None,
-                        'state': power_state.SHUTOFF,
-                        'state_description': 'stopped',
+                        'vm_state': vm_state.STOP,
+                        'task_state': None,
                         'updated_at': literal_column('updated_at')})
         session.query(models.SecurityGroupInstanceAssociation).\
                 filter_by(instance_id=instance_id).\

From fc7fc16cddf8e891aae15c66921db71f51ab95e1 Mon Sep 17 00:00:00 2001
From: Dan Prince <dan.prince@rackspace.com>
Date: Mon, 22 Aug 2011 13:04:05 -0400
Subject: [PATCH 04/25] Use 'vm_state' instead of 'state' in instance filters
 query.

---
 nova/db/sqlalchemy/api.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index a5ed2363f..3e690e094 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1239,7 +1239,7 @@ def instance_get_all_by_filters(context, filters):
     # Filters for exact matches that we can do along with the SQL query...
     # For other filters that don't match this, we will do regexp matching
     exact_match_filter_names = ['project_id', 'user_id', 'image_ref',
-            'state', 'instance_type_id', 'deleted']
+            'vm_state', 'instance_type_id', 'deleted']
 
     query_filters = [key for key in filters.iterkeys()
             if key in exact_match_filter_names]

From ed128cd50269578a3495bc680a4b4b2d61a92d24 Mon Sep 17 00:00:00 2001
From: Dan Wendlandt <dan@nicira.com>
Date: Mon, 22 Aug 2011 22:18:43 -0700
Subject: [PATCH 05/25] pulling all qmanager changes into a branch based on
 trunk, as they were previously stacked on top of melange

---
 nova/db/api.py            |  5 +++++
 nova/db/sqlalchemy/api.py | 20 +++++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/nova/db/api.py b/nova/db/api.py
index 2d854f24c..9ff3a1c74 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -419,6 +419,11 @@ def virtual_interface_get_by_address(context, address):
     return IMPL.virtual_interface_get_by_address(context, address)
 
 
+def virtual_interface_get_by_uuid(context, vif_uuid):
+    """Gets a virtual interface from the table filtering on vif uuid."""
+    return IMPL.virtual_interface_get_by_uuid(context, vif_uuid)
+
+
 def virtual_interface_get_by_fixed_ip(context, fixed_ip_id):
     """Gets the virtual interface fixed_ip is associated with."""
     return IMPL.virtual_interface_get_by_fixed_ip(context, fixed_ip_id)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 04b5405f6..d96b951a1 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -688,10 +688,8 @@ def fixed_ip_associate(context, address, instance_id, network_id=None):
 def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None):
     session = get_session()
     with session.begin():
-        network_or_none = or_(models.FixedIp.network_id == network_id,
-                              models.FixedIp.network_id == None)
         fixed_ip_ref = session.query(models.FixedIp).\
-                               filter(network_or_none).\
+                               filter_by(network_id=network_id).\
                                filter_by(reserved=False).\
                                filter_by(deleted=False).\
                                filter_by(instance=None).\
@@ -928,6 +926,22 @@ def virtual_interface_get_by_address(context, address):
     return vif_ref
 
 
+@require_context
+def virtual_interface_get_by_uuid(context, vif_uuid):
+    """Gets a virtual interface from the table.
+
+    :param vif_uuid: = the uuid of the interface you're looking to get
+    """
+    session = get_session()
+    vif_ref = session.query(models.VirtualInterface).\
+                      filter_by(uuid=vif_uuid).\
+                      options(joinedload('network')).\
+                      options(joinedload('instance')).\
+                      options(joinedload('fixed_ips')).\
+                      first()
+    return vif_ref
+
+
 @require_context
 def virtual_interface_get_by_fixed_ip(context, fixed_ip_id):
     """Gets the virtual interface fixed_ip is associated with.

From 8d9735d3c28942ff3ca8237ad93f47aae7301598 Mon Sep 17 00:00:00 2001
From: Brian Lamar <brian.lamar@rackspace.com>
Date: Thu, 25 Aug 2011 17:27:10 -0400
Subject: [PATCH 06/25] review feedback

---
 nova/db/sqlalchemy/api.py | 40 ---------------------------------------
 1 file changed, 40 deletions(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 08fc81759..7b78e286d 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1484,46 +1484,6 @@ def instance_get_floating_address(context, instance_id):
     return fixed_ip_refs[0].floating_ips[0]['address']
 
 
-@require_admin_context
-def instance_set_power_state(context, instance_id, power_state):
-    session = get_session()
-    partial = session.query(models.Instance)
-
-    if utils.is_uuid_like(instance_id):
-        result = partial.filter_by(uuid=instance_id)
-    else:
-        result = partial.filter_by(id=instance_id)
-
-    result.update({'power_state': power_state})
-
-
-@require_admin_context
-def instance_set_vm_state(context, instance_id, vm_state):
-    # vm_state = running, halted, suspended, paused
-    session = get_session()
-    partial = session.query(models.Instance)
-
-    if utils.is_uuid_like(instance_id):
-        result = partial.filter_by(uuid=instance_id)
-    else:
-        result = partial.filter_by(id=instance_id)
-
-    result.update({'vm_state': vm_state})
-
-
-def instance_set_task_state(context, instance_id, task_state):
-    # task_state = running, halted, suspended, paused
-    session = get_session()
-    partial = session.query(models.Instance)
-
-    if utils.is_uuid_like(instance_id):
-        result = partial.filter_by(uuid=instance_id)
-    else:
-        result = partial.filter_by(id=instance_id)
-
-    result.update({'task_state': task_state})
-
-
 @require_context
 def instance_update(context, instance_id, values):
     session = get_session()

From 655bd7a476596929d63b8841f3690221e70244e4 Mon Sep 17 00:00:00 2001
From: Vishvananda Ishaya <vishvananda@gmail.com>
Date: Fri, 26 Aug 2011 16:17:40 -0700
Subject: [PATCH 07/25] use db layer for aggregation

---
 nova/db/api.py            | 11 ++++++++---
 nova/db/sqlalchemy/api.py | 19 ++++++++++++-------
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/nova/db/api.py b/nova/db/api.py
index 3bb9b4970..f443239c1 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -495,9 +495,14 @@ def instance_get_all_by_filters(context, filters):
     return IMPL.instance_get_all_by_filters(context, filters)
 
 
-def instance_get_active_by_window(context, begin, end=None):
-    """Get instances active during a certain time window."""
-    return IMPL.instance_get_active_by_window(context, begin, end)
+def instance_get_active_by_window(context, begin, end=None,
+                                  project_id=None, fast=False):
+    """Get instances active during a certain time window.
+
+    Setting fast to true will stop all joinedloads.
+    Specifying a project_id will filter for a certain project."""
+    return IMPL.instance_get_active_by_window(context, begin, end,
+                                              project_id, fast)
 
 
 def instance_get_all_by_user(context, user_id):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index d1fbf8cab..2d50f458f 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1307,20 +1307,25 @@ def instance_get_all_by_filters(context, filters):
 
 
 @require_admin_context
-def instance_get_active_by_window(context, begin, end=None):
+def instance_get_active_by_window(context, begin, end=None,
+                                  project_id=None, fast=False):
     """Return instances that were continuously active over the given window"""
     session = get_session()
-    query = session.query(models.Instance).\
-                   options(joinedload_all('fixed_ips.floating_ips')).\
-                   options(joinedload('security_groups')).\
-                   options(joinedload_all('fixed_ips.network')).\
-                   options(joinedload('instance_type')).\
-                   filter(models.Instance.launched_at < begin)
+    query = session.query(models.Instance)
+    if not fast:
+        query = query.options(joinedload_all('fixed_ips.floating_ips')).\
+                      options(joinedload('security_groups')).\
+                      options(joinedload_all('fixed_ips.network')).\
+                      options(joinedload('instance_type'))
+
+    query = query.filter(models.Instance.launched_at < begin)
     if end:
         query = query.filter(or_(models.Instance.terminated_at == None,
                                  models.Instance.terminated_at > end))
     else:
         query = query.filter(models.Instance.terminated_at == None)
+    if project_id:
+        query = query.filter_by(project_id=project_id)
     return query.all()
 
 

From ef206acdc7c8d0a4c55711d1fe1f3b41114acd44 Mon Sep 17 00:00:00 2001
From: Dan Wendlandt <dan@nicira.com>
Date: Sun, 28 Aug 2011 11:37:19 -0700
Subject: [PATCH 08/25] use 'uuid' field in networks table rather than
 'bridge'.  Specify project_id when creating instance in unit test

---
 nova/db/api.py            |  5 +++++
 nova/db/sqlalchemy/api.py | 13 +++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/nova/db/api.py b/nova/db/api.py
index 9ff3a1c74..17ef0bd0b 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -708,6 +708,11 @@ def network_get_by_bridge(context, bridge):
     return IMPL.network_get_by_bridge(context, bridge)
 
 
+def network_get_by_uuid(context, uuid):
+    """Get a network by uuid or raise if it does not exist."""
+    return IMPL.network_get_by_uuid(context, uuid)
+
+
 def network_get_by_cidr(context, cidr):
     """Get a network by cidr or raise if it does not exist"""
     return IMPL.network_get_by_cidr(context, cidr)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index d96b951a1..80ce76e8f 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1846,6 +1846,19 @@ def network_get_by_bridge(context, bridge):
     return result
 
 
+@require_admin_context
+def network_get_by_uuid(context, uuid):
+    session = get_session()
+    result = session.query(models.Network).\
+                 filter_by(uuid=uuid).\
+                 filter_by(deleted=False).\
+                 first()
+
+    if not result:
+        raise exception.NetworkNotFoundForUUID(uuid=uuid)
+    return result
+
+
 @require_admin_context
 def network_get_by_cidr(context, cidr):
     session = get_session()

From 9fd5d5382aa0ac15d92d31084816e8ce135d622b Mon Sep 17 00:00:00 2001
From: "danwent@gmail.com" <>
Date: Sun, 28 Aug 2011 20:00:38 -0700
Subject: [PATCH 09/25] restore fixed_ip_associate_pool in
 nova/db/sqlalchemy.py to its original form before this branch.  Figured out
 how to make unit tests pass without requiring that this function changes

---
 nova/db/sqlalchemy/api.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 80ce76e8f..00af62682 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -688,8 +688,10 @@ def fixed_ip_associate(context, address, instance_id, network_id=None):
 def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None):
     session = get_session()
     with session.begin():
+        network_or_none = or_(models.FixedIp.network_id == network_id,
+                              models.FixedIp.network_id == None)
         fixed_ip_ref = session.query(models.FixedIp).\
-                               filter_by(network_id=network_id).\
+                               filter(network_or_none).\
                                filter_by(reserved=False).\
                                filter_by(deleted=False).\
                                filter_by(instance=None).\

From 3389c3fd6e42df3358df3caef5f6b18a6d344ff3 Mon Sep 17 00:00:00 2001
From: Brian Waldon <brian.waldon@rackspace.com>
Date: Tue, 30 Aug 2011 11:13:25 -0400
Subject: [PATCH 10/25] supporting changes-since

---
 nova/db/sqlalchemy/api.py | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 65b09a65d..1685e9928 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -35,6 +35,7 @@ from sqlalchemy.exc import IntegrityError
 from sqlalchemy.orm import joinedload
 from sqlalchemy.orm import joinedload_all
 from sqlalchemy.sql import func
+from sqlalchemy.sql.expression import desc
 from sqlalchemy.sql.expression import literal_column
 
 FLAGS = flags.FLAGS
@@ -1250,12 +1251,17 @@ def instance_get_all_by_filters(context, filters):
                    options(joinedload_all('fixed_ips.network')).\
                    options(joinedload('metadata')).\
                    options(joinedload('instance_type')).\
-                   filter_by(deleted=can_read_deleted(context))
+                   order_by(desc(models.Instance.updated_at))
 
     # Make a copy of the filters dictionary to use going forward, as we'll
     # be modifying it and we shouldn't affect the caller's use of it.
     filters = filters.copy()
 
+    if 'changes-since' in filters:
+        changes_since = filters['changes-since']
+        query_prefix = query_prefix.\
+                            filter(models.Instance.updated_at > changes_since)
+
     if not context.is_admin:
         # If we're not admin context, add appropriate filter..
         if context.project_id:
@@ -1277,9 +1283,7 @@ def instance_get_all_by_filters(context, filters):
         query_prefix = _exact_match_filter(query_prefix, filter_name,
                 filters.pop(filter_name))
 
-    instances = query_prefix.\
-                    filter_by(deleted=can_read_deleted(context)).\
-                    all()
+    instances = query_prefix.all()
 
     if not instances:
         return []

From a72cac7bb23bdb634aabad25d945a786ea69d435 Mon Sep 17 00:00:00 2001
From: Brian Waldon <brian.waldon@rackspace.com>
Date: Tue, 30 Aug 2011 12:51:02 -0400
Subject: [PATCH 11/25] changing default sort to created_at

---
 nova/db/sqlalchemy/api.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 1685e9928..1e55d08e7 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1251,7 +1251,7 @@ def instance_get_all_by_filters(context, filters):
                    options(joinedload_all('fixed_ips.network')).\
                    options(joinedload('metadata')).\
                    options(joinedload('instance_type')).\
-                   order_by(desc(models.Instance.updated_at))
+                   order_by(desc(models.Instance.created_at))
 
     # Make a copy of the filters dictionary to use going forward, as we'll
     # be modifying it and we shouldn't affect the caller's use of it.

From 1d15b2c33cebaa64adc714ac04f30baf78d1e32e Mon Sep 17 00:00:00 2001
From: Vishvananda Ishaya <vishvananda@gmail.com>
Date: Tue, 30 Aug 2011 12:01:18 -0700
Subject: [PATCH 12/25] make two functions instead of fast flag and add compute
 api commands instead of hitting db directly

---
 nova/db/api.py            | 16 +++++++++++-----
 nova/db/sqlalchemy/api.py | 36 +++++++++++++++++++++++++-----------
 2 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/nova/db/api.py b/nova/db/api.py
index 3233985b6..148887635 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -496,14 +496,20 @@ def instance_get_all_by_filters(context, filters):
     return IMPL.instance_get_all_by_filters(context, filters)
 
 
-def instance_get_active_by_window(context, begin, end=None,
-                                  project_id=None, fast=False):
+def instance_get_active_by_window(context, begin, end=None, project_id=None):
     """Get instances active during a certain time window.
 
-    Setting fast to true will stop all joinedloads.
     Specifying a project_id will filter for a certain project."""
-    return IMPL.instance_get_active_by_window(context, begin, end,
-                                              project_id, fast)
+    return IMPL.instance_get_active_by_window(context, begin, end, project_id)
+
+
+def instance_get_active_by_window_joined(context, begin, end=None,
+                                         project_id=None):
+    """Get instances and joins active during a certain time window.
+
+    Specifying a project_id will filter for a certain project."""
+    return IMPL.instance_get_active_by_window_joined(context, begin, end,
+                                              project_id)
 
 
 def instance_get_all_by_user(context, user_id):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index c4cc199eb..d76dc22ed 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1306,19 +1306,33 @@ def instance_get_all_by_filters(context, filters):
     return instances
 
 
-@require_admin_context
-def instance_get_active_by_window(context, begin, end=None,
-                                  project_id=None, fast=False):
-    """Return instances that were continuously active over the given window"""
+@require_context
+def instance_get_active_by_window(context, begin, end=None, project_id=None):
+    """Return instances that were continuously active over window."""
     session = get_session()
-    query = session.query(models.Instance)
-    if not fast:
-        query = query.options(joinedload_all('fixed_ips.floating_ips')).\
-                      options(joinedload('security_groups')).\
-                      options(joinedload_all('fixed_ips.network')).\
-                      options(joinedload('instance_type'))
+    query = session.query(models.Instance).\
+                    filter(models.Instance.launched_at < begin)
+    if end:
+        query = query.filter(or_(models.Instance.terminated_at == None,
+                                 models.Instance.terminated_at > end))
+    else:
+        query = query.filter(models.Instance.terminated_at == None)
+    if project_id:
+        query = query.filter_by(project_id=project_id)
+    return query.all()
 
-    query = query.filter(models.Instance.launched_at < begin)
+
+@require_admin_context
+def instance_get_active_by_window_joined(context, begin, end=None,
+                                         project_id=None):
+    """Return instances and joins that were continuously active over window."""
+    session = get_session()
+    query = session.query(models.Instance).\
+                    options(joinedload_all('fixed_ips.floating_ips')).\
+                    options(joinedload('security_groups')).\
+                    options(joinedload_all('fixed_ips.network')).\
+                    options(joinedload('instance_type')).\
+                    filter(models.Instance.launched_at < begin)
     if end:
         query = query.filter(or_(models.Instance.terminated_at == None,
                                  models.Instance.terminated_at > end))

From 56ceb6f9c5ebf78677a91a2da143704f8e9db324 Mon Sep 17 00:00:00 2001
From: Brian Lamar <brian.lamar@rackspace.com>
Date: Wed, 31 Aug 2011 10:14:07 -0400
Subject: [PATCH 13/25] Removed extraneous import and
 s/vm_state.STOP/vm_states.STOPPED/

---
 nova/db/sqlalchemy/api.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 24e1772f6..631e53ceb 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -28,6 +28,7 @@ from nova import flags
 from nova import ipv6
 from nova import utils
 from nova import log as logging
+from nova.compute import vm_states
 from nova.db.sqlalchemy import models
 from nova.db.sqlalchemy.session import get_session
 from sqlalchemy import or_
@@ -1102,11 +1103,10 @@ def instance_destroy(context, instance_id):
 def instance_stop(context, instance_id):
     session = get_session()
     with session.begin():
-        from nova.compute import power_state
         session.query(models.Instance).\
                 filter_by(id=instance_id).\
                 update({'host': None,
-                        'vm_state': vm_state.STOP,
+                        'vm_state': vm_states.STOPPED,
                         'task_state': None,
                         'updated_at': literal_column('updated_at')})
         session.query(models.SecurityGroupInstanceAssociation).\

From d976fdc30bfe06691feb3ad259cced958c1b0fa6 Mon Sep 17 00:00:00 2001
From: Tushar Patil <tushar.vitthal.patil@gmail.com>
Date: Wed, 31 Aug 2011 17:06:15 -0700
Subject: [PATCH 14/25] Fix for LP Bug #838251

---
 nova/utils.py | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/nova/utils.py b/nova/utils.py
index 21e6221b2..4855f6fd6 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -901,3 +901,12 @@ def monkey_patch():
                 func = import_class("%s.%s" % (module, key))
                 setattr(sys.modules[module], key,\
                     decorator("%s.%s" % (module, key), func))
+
+
+def convert_to_set(lst, label):
+    """Convert a value or list into a set"""
+    if lst is None or lst == []:
+        return None
+    if not isinstance(lst, list):
+        lst = [lst]
+    return [{label: x} for x in lst]

From e5e2d0be4e0f2abdfcfeb0fa2e51c44320395c73 Mon Sep 17 00:00:00 2001
From: Tushar Patil <tushar.vitthal.patil@gmail.com>
Date: Fri, 2 Sep 2011 12:34:14 -0700
Subject: [PATCH 15/25] Fix for LP Bug #839269

---
 nova/db/api.py            | 6 ++++--
 nova/db/sqlalchemy/api.py | 5 +++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/nova/db/api.py b/nova/db/api.py
index 148887635..efc088e35 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -324,13 +324,15 @@ def migration_get_by_instance_and_status(context, instance_uuid, status):
 ####################
 
 
-def fixed_ip_associate(context, address, instance_id, network_id=None):
+def fixed_ip_associate(context, address, instance_id, network_id=None,
+                       reserved=False):
     """Associate fixed ip to instance.
 
     Raises if fixed ip is not available.
 
     """
-    return IMPL.fixed_ip_associate(context, address, instance_id, network_id)
+    return IMPL.fixed_ip_associate(context, address, instance_id, network_id,
+                                   reserved)
 
 
 def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index b99667afc..e0be8454e 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -669,14 +669,15 @@ def floating_ip_update(context, address, values):
 
 
 @require_admin_context
-def fixed_ip_associate(context, address, instance_id, network_id=None):
+def fixed_ip_associate(context, address, instance_id, network_id=None,
+                       reserved=False):
     session = get_session()
     with session.begin():
         network_or_none = or_(models.FixedIp.network_id == network_id,
                               models.FixedIp.network_id == None)
         fixed_ip_ref = session.query(models.FixedIp).\
                                filter(network_or_none).\
-                               filter_by(reserved=False).\
+                               filter_by(reserved=reserved).\
                                filter_by(deleted=False).\
                                filter_by(address=address).\
                                with_lockmode('update').\

From a75101ee660047006875629b0b9316352057c108 Mon Sep 17 00:00:00 2001
From: Dan Wendlandt <dan@nicira.com>
Date: Fri, 2 Sep 2011 13:05:24 -0700
Subject: [PATCH 16/25] feedback from jk0's review, including removing a lot of
 spaces from docstrings

---
 nova/db/sqlalchemy/api.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 09356e966..e0da2269d 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -946,7 +946,7 @@ def virtual_interface_get_by_address(context, address):
 def virtual_interface_get_by_uuid(context, vif_uuid):
     """Gets a virtual interface from the table.
 
-    :param vif_uuid: = the uuid of the interface you're looking to get
+    :param vif_uuid: the uuid of the interface you're looking to get
     """
     session = get_session()
     vif_ref = session.query(models.VirtualInterface).\

From 97b2d1b83c4bc44b2ef03119e6f3b24350686e33 Mon Sep 17 00:00:00 2001
From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp>
Date: Mon, 5 Sep 2011 14:45:41 +0900
Subject: [PATCH 17/25] Fix bug #835919 that output a option file for dnsmasq
 not to offer a default gateway on second vif.

---
 nova/db/sqlalchemy/api.py | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 mode change 100644 => 100755 nova/db/sqlalchemy/api.py

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
old mode 100644
new mode 100755
index b99667afc..aee1c2a55
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1415,6 +1415,21 @@ def instance_get_all_by_reservation(context, reservation_id):
                 filter_by(project_id=context.project_id).\
                 filter_by(deleted=False).\
                 all()
+                
+@require_admin_context
+def instance_get_all_by_network(context, network_id):
+    session = get_session()
+    return session.query(models.Instance).\
+                   options(joinedload_all('fixed_ips.floating_ips')).\
+                   options(joinedload('virtual_interfaces')).\
+                   options(joinedload('security_groups')).\
+                   options(joinedload_all('fixed_ips.network')).\
+                   options(joinedload('metadata')).\
+                   options(joinedload('instance_type')).\
+                   filter_by(deleted=can_read_deleted(context)).\
+                   filter_by(network_id=network_id).\
+                   all()
+
 
 
 @require_context

From 272fcf91454afda37aa54898d9b9493327b530d6 Mon Sep 17 00:00:00 2001
From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp>
Date: Mon, 5 Sep 2011 20:23:28 +0900
Subject: [PATCH 18/25] implement unit test for linux_net

---
 nova/db/api.py | 5 +++++
 1 file changed, 5 insertions(+)
 mode change 100644 => 100755 nova/db/api.py

diff --git a/nova/db/api.py b/nova/db/api.py
old mode 100644
new mode 100755
index 148887635..85e9c7669
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -532,6 +532,11 @@ def instance_get_all_by_reservation(context, reservation_id):
     return IMPL.instance_get_all_by_reservation(context, reservation_id)
 
 
+def instance_get_all_by_network(context, network_id):
+    """Get all instances belonging to a network."""
+    return IMPL.instance_get_all_by_network(context, network_id)
+    
+    
 def instance_get_by_fixed_ip(context, address):
     """Get an instance for a fixed ip by address."""
     return IMPL.instance_get_by_fixed_ip(context, address)

From d193081258f2a3c0cedcc220c49355acc600c7a2 Mon Sep 17 00:00:00 2001
From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp>
Date: Mon, 5 Sep 2011 21:13:00 +0900
Subject: [PATCH 19/25] format for pep8

---
 nova/db/api.py            | 4 ++--
 nova/db/sqlalchemy/api.py | 5 ++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/nova/db/api.py b/nova/db/api.py
index 85e9c7669..faac13966 100755
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -535,8 +535,8 @@ def instance_get_all_by_reservation(context, reservation_id):
 def instance_get_all_by_network(context, network_id):
     """Get all instances belonging to a network."""
     return IMPL.instance_get_all_by_network(context, network_id)
-    
-    
+
+
 def instance_get_by_fixed_ip(context, address):
     """Get an instance for a fixed ip by address."""
     return IMPL.instance_get_by_fixed_ip(context, address)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index aee1c2a55..3194a5231 100755
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1415,8 +1415,8 @@ def instance_get_all_by_reservation(context, reservation_id):
                 filter_by(project_id=context.project_id).\
                 filter_by(deleted=False).\
                 all()
-                
-@require_admin_context
+
+
 def instance_get_all_by_network(context, network_id):
     session = get_session()
     return session.query(models.Instance).\
@@ -1431,7 +1431,6 @@ def instance_get_all_by_network(context, network_id):
                    all()
 
 
-
 @require_context
 def instance_get_by_fixed_ip(context, address):
     """Return instance ref by exact match of FixedIP"""

From e6ab1718de8eaba5ca6282ec291631765fe9c084 Mon Sep 17 00:00:00 2001
From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp>
Date: Tue, 6 Sep 2011 10:14:27 +0900
Subject: [PATCH 20/25] correct a method to collect instances from db add
 interface data to test

---
 nova/db/api.py            |  5 -----
 nova/db/sqlalchemy/api.py | 14 --------------
 2 files changed, 19 deletions(-)

diff --git a/nova/db/api.py b/nova/db/api.py
index faac13966..148887635 100755
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -532,11 +532,6 @@ def instance_get_all_by_reservation(context, reservation_id):
     return IMPL.instance_get_all_by_reservation(context, reservation_id)
 
 
-def instance_get_all_by_network(context, network_id):
-    """Get all instances belonging to a network."""
-    return IMPL.instance_get_all_by_network(context, network_id)
-
-
 def instance_get_by_fixed_ip(context, address):
     """Get an instance for a fixed ip by address."""
     return IMPL.instance_get_by_fixed_ip(context, address)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 3194a5231..b99667afc 100755
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1417,20 +1417,6 @@ def instance_get_all_by_reservation(context, reservation_id):
                 all()
 
 
-def instance_get_all_by_network(context, network_id):
-    session = get_session()
-    return session.query(models.Instance).\
-                   options(joinedload_all('fixed_ips.floating_ips')).\
-                   options(joinedload('virtual_interfaces')).\
-                   options(joinedload('security_groups')).\
-                   options(joinedload_all('fixed_ips.network')).\
-                   options(joinedload('metadata')).\
-                   options(joinedload('instance_type')).\
-                   filter_by(deleted=can_read_deleted(context)).\
-                   filter_by(network_id=network_id).\
-                   all()
-
-
 @require_context
 def instance_get_by_fixed_ip(context, address):
     """Return instance ref by exact match of FixedIP"""

From 23f90a9edd5033a187ca5a971d96d1fc03cd5e6e Mon Sep 17 00:00:00 2001
From: Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp>
Date: Tue, 6 Sep 2011 10:20:28 +0900
Subject: [PATCH 21/25] revert codes for db

---
 nova/db/api.py            | 0
 nova/db/sqlalchemy/api.py | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 nova/db/api.py
 mode change 100755 => 100644 nova/db/sqlalchemy/api.py

diff --git a/nova/db/api.py b/nova/db/api.py
old mode 100755
new mode 100644
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
old mode 100755
new mode 100644

From f9431a1f884bc6f93a1a0afee3eee4d7dc2d391b Mon Sep 17 00:00:00 2001
From: Brian Waldon <brian.waldon@rackspace.com>
Date: Thu, 8 Sep 2011 11:32:11 -0400
Subject: [PATCH 22/25] adding can_read_deleted back to db api

---
 nova/db/sqlalchemy/api.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 523258841..1730b4ddb 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1277,6 +1277,10 @@ def instance_get_all_by_filters(context, filters):
         changes_since = filters['changes-since']
         query_prefix = query_prefix.\
                             filter(models.Instance.updated_at > changes_since)
+    else:
+        # filter out deleted instances if no changes-since filter provided
+        query_prefix = query_prefix.\
+                            filter_by(deleted=can_read_deleted(context))
 
     if not context.is_admin:
         # If we're not admin context, add appropriate filter..

From 0873840079e6af51f8c6c43b8d4adea711667c5c Mon Sep 17 00:00:00 2001
From: Brian Waldon <brian.waldon@rackspace.com>
Date: Thu, 8 Sep 2011 15:26:44 -0400
Subject: [PATCH 23/25] converting fix to just address ec2; updating test

---
 nova/db/sqlalchemy/api.py | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 1730b4ddb..523258841 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1277,10 +1277,6 @@ def instance_get_all_by_filters(context, filters):
         changes_since = filters['changes-since']
         query_prefix = query_prefix.\
                             filter(models.Instance.updated_at > changes_since)
-    else:
-        # filter out deleted instances if no changes-since filter provided
-        query_prefix = query_prefix.\
-                            filter_by(deleted=can_read_deleted(context))
 
     if not context.is_admin:
         # If we're not admin context, add appropriate filter..

From 9403d4e0949fb7e41d4b865e3b4389dc1ab2a333 Mon Sep 17 00:00:00 2001
From: Antony Messerli <amesserl@rackspace.com>
Date: Mon, 12 Sep 2011 14:43:15 -0500
Subject: [PATCH 24/25] pep8 fixes

---
 nova/db/sqlalchemy/api.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 40e2ca167..e5a661c7f 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -672,7 +672,7 @@ def floating_ip_update(context, address, values):
 def fixed_ip_associate(context, address, instance_id, network_id=None,
                        reserved=False):
     """Keyword arguments:
-    reserved -- should be a boolean value(True or False), exact value will be 
+    reserved -- should be a boolean value(True or False), exact value will be
     used to filter on the fixed ip address
     """
     session = get_session()

From 34092169a293bd50dfd83a2d1a4bc14ce140d72c Mon Sep 17 00:00:00 2001
From: Vishvananda Ishaya <vishvananda@gmail.com>
Date: Tue, 13 Sep 2011 16:38:46 -0700
Subject: [PATCH 25/25] makes sure floating addresses are associated with host
 on associate so they come back

---
 nova/db/api.py            | 8 +++++---
 nova/db/sqlalchemy/api.py | 5 ++++-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/nova/db/api.py b/nova/db/api.py
index c03a86671..5b57b178e 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -261,11 +261,13 @@ def floating_ip_disassociate(context, address):
     return IMPL.floating_ip_disassociate(context, address)
 
 
-def floating_ip_fixed_ip_associate(context, floating_address, fixed_address):
+def floating_ip_fixed_ip_associate(context, floating_address,
+                                   fixed_address, host):
     """Associate an floating ip to a fixed_ip by address."""
     return IMPL.floating_ip_fixed_ip_associate(context,
                                                floating_address,
-                                               fixed_address)
+                                               fixed_address,
+                                               host)
 
 
 def floating_ip_get_all(context):
@@ -365,7 +367,7 @@ def fixed_ip_get_all(context):
 
 def fixed_ip_get_all_by_instance_host(context, host):
     """Get all allocated fixed ips filtered by instance host."""
-    return IMPL.fixed_ip_get_all_instance_by_host(context, host)
+    return IMPL.fixed_ip_get_all_by_instance_host(context, host)
 
 
 def fixed_ip_get_by_address(context, address):
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 523258841..9c3d8413e 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -529,7 +529,8 @@ def floating_ip_count_by_project(context, project_id):
 
 
 @require_context
-def floating_ip_fixed_ip_associate(context, floating_address, fixed_address):
+def floating_ip_fixed_ip_associate(context, floating_address,
+                                   fixed_address, host):
     session = get_session()
     with session.begin():
         # TODO(devcamcar): How to ensure floating_id belongs to user?
@@ -540,6 +541,7 @@ def floating_ip_fixed_ip_associate(context, floating_address, fixed_address):
                                                fixed_address,
                                                session=session)
         floating_ip_ref.fixed_ip = fixed_ip_ref
+        floating_ip_ref.host = host
         floating_ip_ref.save(session=session)
 
 
@@ -583,6 +585,7 @@ def floating_ip_disassociate(context, address):
         else:
             fixed_ip_address = None
         floating_ip_ref.fixed_ip = None
+        floating_ip_ref.host = None
         floating_ip_ref.save(session=session)
     return fixed_ip_address