nova list trace - dianaclarke/openstack-notes GitHub Wiki
- Setup a simple DevStack standbox
- Create an instance called
instance-1
using the Dashboard - Configure the credentials you're going to use for the nova command line client
$ . openrc admin demo
- List the instance using
nova list
$ nova list
+--------------------------------------+------------+--------+------------+-------------+------------------+
| ID | Name | Status | Task State | Power State | Networks |
+--------------------------------------+------------+--------+------------+-------------+------------------+
| 114ee114-cb45-4871-bab5-c877b301e4f5 | instance-1 | ACTIVE | - | Running | private=10.0.0.2 |
+--------------------------------------+------------+--------+------------+-------------+------------------+
- Attach the debugger to the nova command line client by adding a
import pdb; pdb.set_trace()
right before line 830 in/usr/lib/python2.7/site-packages/novaclient/shell.py
.
...
import pdb; pdb.set_trace()
args.func(self.cs, args)
...
- Call
nova list
again, and this time step into the call. Note that you now know thatnova list
will calldo_list()
.
$ nova list
> /usr/lib/python2.7/site-packages/novaclient/shell.py(832)main()
-> args.func(self.cs, args)
(Pdb) s
--Call--
> /usr/lib/python2.7/site-packages/novaclient/v2/shell.py(1227)do_list()
-> @cliutils.arg(
-
do_list()
callsservers.ServerManager.list()
def do_list(cs, args):
"""List active servers."""
...
servers = cs.servers.list(detailed=detailed,
search_opts=search_opts,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
marker=args.marker,
limit=args.limit)
...
-
servers.ServerManager.list()
callsbase.Manager._list()
def list(self, detailed=True, search_opts=None, marker=None, limit=None,
sort_keys=None, sort_dirs=None):
...
servers = self._list("/servers%s%s" % (detail, query_string),
"servers")
...
-
base.Manager._list()
is going to do aHTTP GET
to/servers/detail
, resulting in a status200 OK
and a json response body. API docs: http://developer.openstack.org/api-ref-compute-v2.1.html
def _list(self, url, response_key, obj_class=None, body=None):
...
_resp, body = self.api.client.get(url)
...
{
"servers": [
{
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "localhost.localdomain",
"OS-EXT-SRV-ATTR:hostname": "instance-1",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "localhost.localdomain",
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
"OS-EXT-SRV-ATTR:kernel_id": "b9a04ceb-36e0-4056-8b17-d293562311c7",
"OS-EXT-SRV-ATTR:launch_index": 0,
"OS-EXT-SRV-ATTR:ramdisk_id": "d970dcc9-47e3-4955-b05b-e57fa7945cae",
"OS-EXT-SRV-ATTR:reservation_id": "r-joc3mzr4",
"OS-EXT-SRV-ATTR:root_device_name": "/dev/vda",
"OS-EXT-SRV-ATTR:user_data": null,
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"OS-SRV-USG:launched_at": "2015-09-28T17:45:34.000000",
"OS-SRV-USG:terminated_at": null,
"accessIPv4": "",
"accessIPv6": "",
"addresses": {
"private": [
{
"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:07:de:2d",
"OS-EXT-IPS:type": "fixed",
"addr": "10.0.0.2",
"version": 4
}
]
},
"config_drive": "True",
"created": "2015-09-28T17:45:06Z",
"flavor": {
"id": "42",
"links": [
{
"href": "http://192.168.122.55:8774/76ec4597d1df4910bdd98f185e925065/flavors/42",
"rel": "bookmark"
}
]
},
"hostId": "68810647eeee49257031df253fd2a8da0258a9e906293bfd5b5768df",
"id": "114ee114-cb45-4871-bab5-c877b301e4f5",
"image": {
"id": "95cfe253-bb56-4776-8908-cd204ea64c9d",
"links": [
{
"href": "http://192.168.122.55:8774/76ec4597d1df4910bdd98f185e925065/images/95cfe253-bb56-4776-8908-cd204ea64c9d",
"rel": "bookmark"
}
]
},
"key_name": null,
"links": [
{
"href": "http://192.168.122.55:8774/v2.1/76ec4597d1df4910bdd98f185e925065/servers/114ee114-cb45-4871-bab5-c877b301e4f5",
"rel": "self"
},
{
"href": "http://192.168.122.55:8774/76ec4597d1df4910bdd98f185e925065/servers/114ee114-cb45-4871-bab5-c877b301e4f5",
"rel": "bookmark"
}
],
"locked": false,
"metadata": {},
"name": "instance-1",
"os-extended-volumes:volumes_attached": [],
"progress": 0,
"security_groups": [
{
"name": "default"
}
],
"status": "ACTIVE",
"tenant_id": "76ec4597d1df4910bdd98f185e925065",
"updated": "2015-09-28T17:45:34Z",
"user_id": "0761a535feca411184d6cd0af20a99f8"
}
]
}
- That was all in the nova client, now let's look what happened in nova during the
/servers/detail
HTTP call. The/servers/detail
URL dispatches to theServersController
in nova. In particular, it callsservers.ServersController.details()
.
@extensions.expected_errors((400, 403))
def detail(self, req):
"""Returns a list of server details for a given user."""
context = req.environ['nova.context']
authorize(context, action="detail")
try:
servers = self._get_servers(req, is_detail=True)
except exception.Invalid as err:
raise exc.HTTPBadRequest(explanation=err.format_message())
return servers
-
detail()
eventually callsapi.API.get_all()
instance_list = self.compute_api.get_all(elevated or context,
search_opts=search_opts, limit=limit, marker=marker,
want_objects=True, expected_attrs=expected_attrs,
sort_keys=sort_keys, sort_dirs=sort_dirs)
-
get_all()
callsapi.API._get_instances_by_filters()
def get_all(self, context, search_opts=None, limit=None, marker=None,
want_objects=False, expected_attrs=None, sort_keys=None,
sort_dirs=None):
...
inst_models = self._get_instances_by_filters(context, filters,
limit=limit, marker=marker, expected_attrs=expected_attrs,
sort_keys=sort_keys, sort_dirs=sort_dirs)
...
-
_get_instances_by_filters()
callsobjects.InstanceList.get_by_filters
def _get_instances_by_filters(self, context, filters,
limit=None, marker=None, expected_attrs=None,
sort_keys=None, sort_dirs=None):
fields = ['metadata', 'system_metadata', 'info_cache',
'security_groups']
if expected_attrs:
fields.extend(expected_attrs)
return objects.InstanceList.get_by_filters(
context, filters=filters, limit=limit, marker=marker,
expected_attrs=fields, sort_keys=sort_keys, sort_dirs=sort_dirs)
-
get_by_filters
eventually callsdb.api.instance_get_all_by_filters_sort()
def instance_get_all_by_filters_sort(context, filters, limit=None,
marker=None, columns_to_join=None,
use_slave=False, sort_keys=None,
sort_dirs=None):
"""Get all instances that match all filters sorted by multiple keys.
sort_keys and sort_dirs must be a list of strings.
"""
return IMPL.instance_get_all_by_filters_sort(
context, filters, limit=limit, marker=marker,
columns_to_join=columns_to_join, use_slave=use_slave,
sort_keys=sort_keys, sort_dirs=sort_dirs)
- Finally! It's database query time in
db.sqlalchemy.api.instance_get_all_by_filters_sort()
(my goal of this exercise).
@require_context
def instance_get_all_by_filters_sort(context, filters, limit=None, marker=None,
columns_to_join=None, use_slave=False,
sort_keys=None, sort_dirs=None):
"""Return instances that match all filters sorted the the given keys.
Deleted instances will be returned by default, unless there's a filter that
says otherwise.
Depending on the name of a filter, matching for that filter is
performed using either exact matching or as regular expression
matching. Exact matching is applied for the following filters::
| ['project_id', 'user_id', 'image_ref',
| 'vm_state', 'instance_type_id', 'uuid',
| 'metadata', 'host', 'system_metadata']
A third type of filter (also using exact matching), filters
based on instance metadata tags when supplied under a special
key named 'filter'::
| filters = {
| 'filter': [
| {'name': 'tag-key', 'value': '<metakey>'},
| {'name': 'tag-value', 'value': '<metaval>'},
| {'name': 'tag:<metakey>', 'value': '<metaval>'}
| ]
| }
Special keys are used to tweek the query further::
| 'changes-since' - only return instances updated after
| 'deleted' - only return (or exclude) deleted instances
| 'soft_deleted' - modify behavior of 'deleted' to either
| include or exclude instances whose
| vm_state is SOFT_DELETED.
A fourth type of filter (also using exact matching), filters
based on instance tags (not metadata tags). There are two types
of these tags:
`tag` -- One or more strings that will be used to filter results
in an AND expression.
`tag-any` -- One or more strings that will be used to filter results in
an OR expression.
Tags should be represented as list::
| filters = {
| 'tag': [some-tag, some-another-tag],
| 'tag-any: [some-any-tag, some-another-any-tag]
| }
"""
# NOTE(mriedem): If the limit is 0 there is no point in even going
# to the database since nothing is going to be returned anyway.
if limit == 0:
return []
sort_keys, sort_dirs = process_sort_params(sort_keys,
sort_dirs,
default_dir='desc')
if CONF.database.slave_connection == '':
use_slave = False
session = get_session(use_slave=use_slave)
if columns_to_join is None:
columns_to_join_new = ['info_cache', 'security_groups']
manual_joins = ['metadata', 'system_metadata']
else:
manual_joins, columns_to_join_new = (
_manual_join_columns(columns_to_join))
query_prefix = session.query(models.Instance)
for column in columns_to_join_new:
if 'extra.' in column:
query_prefix = query_prefix.options(undefer(column))
else:
query_prefix = query_prefix.options(joinedload(column))
# Note: order_by is done in the sqlalchemy.utils.py paginate_query(),
# no need to do it here as well
# 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 = timeutils.normalize_time(filters['changes-since'])
query_prefix = query_prefix.\
filter(models.Instance.updated_at >= changes_since)
deleted = False
if 'deleted' in filters:
# Instances can be soft or hard deleted and the query needs to
# include or exclude both
deleted = filters.pop('deleted')
if deleted:
if filters.pop('soft_deleted', True):
delete = or_(
models.Instance.deleted == models.Instance.id,
models.Instance.vm_state == vm_states.SOFT_DELETED
)
query_prefix = query_prefix.\
filter(delete)
else:
query_prefix = query_prefix.\
filter(models.Instance.deleted == models.Instance.id)
else:
query_prefix = query_prefix.\
filter_by(deleted=0)
if not filters.pop('soft_deleted', False):
# It would be better to have vm_state not be nullable
# but until then we test it explicitly as a workaround.
not_soft_deleted = or_(
models.Instance.vm_state != vm_states.SOFT_DELETED,
models.Instance.vm_state == null()
)
query_prefix = query_prefix.filter(not_soft_deleted)
if 'cleaned' in filters:
if filters.pop('cleaned'):
query_prefix = query_prefix.filter(models.Instance.cleaned == 1)
else:
query_prefix = query_prefix.filter(models.Instance.cleaned == 0)
if 'tag' in filters:
tags = filters.pop('tag')
# We build a JOIN ladder expression for each tag, JOIN'ing
# the first tag to the instances table, and each subsequent
# tag to the last JOIN'd tags table
first_tag = tags.pop(0)
query_prefix = query_prefix.join(models.Instance.tags)
query_prefix = query_prefix.filter(models.Tag.tag == first_tag)
for tag in tags:
tag_alias = aliased(models.Tag)
query_prefix = query_prefix.join(tag_alias,
models.Instance.tags)
query_prefix = query_prefix.filter(tag_alias.tag == tag)
if 'tag-any' in filters:
tags = filters.pop('tag-any')
tag_alias = aliased(models.Tag)
query_prefix = query_prefix.join(tag_alias, models.Instance.tags)
query_prefix = query_prefix.filter(tag_alias.tag.in_(tags))
if not context.is_admin:
# If we're not admin context, add appropriate filter..
if context.project_id:
filters['project_id'] = context.project_id
else:
filters['user_id'] = context.user_id
# 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',
'vm_state', 'instance_type_id', 'uuid',
'metadata', 'host', 'task_state',
'system_metadata']
# Filter the query
query_prefix = _exact_instance_filter(query_prefix,
filters, exact_match_filter_names)
query_prefix = _regex_instance_filter(query_prefix, filters)
query_prefix = _tag_instance_filter(context, query_prefix, filters)
# paginate query
if marker is not None:
try:
marker = _instance_get_by_uuid(
context.elevated(read_deleted='yes'), marker,
session=session)
except exception.InstanceNotFound:
raise exception.MarkerNotFound(marker)
try:
query_prefix = sqlalchemyutils.paginate_query(query_prefix,
models.Instance, limit,
sort_keys,
marker=marker,
sort_dirs=sort_dirs)
except db_exc.InvalidSortKey:
raise exception.InvalidSortKey()
return _instances_fill_metadata(context, query_prefix.all(), manual_joins)
-
So where are the N
block_device_mapping
queries coming from? Where N = number of instances. As seen here: https://github.com/dianaclarke/openstack-notes/wiki/nova-list-queries -
The
block_device_mapping
queries from the logs, including the query from immediately before them:
SELECT instance_faults.created_at AS instance_faults_created_at, instance_faults.updated_at AS instance_faults_updated_at, instance_faults.deleted_at AS instance_faults_deleted_at, instance_faults.deleted AS instance_faults_deleted, instance_faults.id AS instance_faults_id, instance_faults.instance_uuid AS instance_faults_instance_uuid, instance_faults.code AS instance_faults_code, instance_faults.message AS instance_faults_message, instance_faults.details AS instance_faults_details, instance_faults.host AS instance_faults_host
FROM instance_faults
WHERE instance_faults.deleted = 0 AND instance_faults.instance_uuid IN ('e0f41dae-9579-47b5-94a1-d6b5f15cc263', '44f3f532-e773-4add-8f45-980988899471', '53ce3de4-bd65-4e04-a7d7-f220c895ed92', '6aec54ab-f069-4159-ba67-fc8376c164c7', 'e9512e80-e25b-4ff1-9e29-a2cc617ee71b') ORDER BY instance_faults.created_at DESC, instance_faults.id DESC;
SELECT block_device_mapping.created_at AS block_device_mapping_created_at, block_device_mapping.updated_at AS block_device_mapping_updated_at, block_device_mapping.deleted_at AS block_device_mapping_deleted_at, block_device_mapping.deleted AS block_device_mapping_deleted, block_device_mapping.id AS block_device_mapping_id, block_device_mapping.instance_uuid AS block_device_mapping_instance_uuid, block_device_mapping.source_type AS block_device_mapping_source_type, block_device_mapping.destination_type AS block_device_mapping_destination_type, block_device_mapping.guest_format AS block_device_mapping_guest_format, block_device_mapping.device_type AS block_device_mapping_device_type, block_device_mapping.disk_bus AS block_device_mapping_disk_bus, block_device_mapping.boot_index AS block_device_mapping_boot_index, block_device_mapping.device_name AS block_device_mapping_device_name, block_device_mapping.delete_on_termination AS block_device_mapping_delete_on_termination, block_device_mapping.snapshot_id AS block_device_mapping_snapshot_id, block_device_mapping.volume_id AS block_device_mapping_volume_id, block_device_mapping.volume_size AS block_device_mapping_volume_size, block_device_mapping.image_id AS block_device_mapping_image_id, block_device_mapping.no_device AS block_device_mapping_no_device, block_device_mapping.connection_info AS block_device_mapping_connection_info
FROM block_device_mapping
WHERE block_device_mapping.deleted = 0 AND block_device_mapping.instance_uuid = 'e0f41dae-9579-47b5-94a1-d6b5f15cc263';
SELECT block_device_mapping.created_at AS block_device_mapping_created_at, block_device_mapping.updated_at AS block_device_mapping_updated_at, block_device_mapping.deleted_at AS block_device_mapping_deleted_at, block_device_mapping.deleted AS block_device_mapping_deleted, block_device_mapping.id AS block_device_mapping_id, block_device_mapping.instance_uuid AS block_device_mapping_instance_uuid, block_device_mapping.source_type AS block_device_mapping_source_type, block_device_mapping.destination_type AS block_device_mapping_destination_type, block_device_mapping.guest_format AS block_device_mapping_guest_format, block_device_mapping.device_type AS block_device_mapping_device_type, block_device_mapping.disk_bus AS block_device_mapping_disk_bus, block_device_mapping.boot_index AS block_device_mapping_boot_index, block_device_mapping.device_name AS block_device_mapping_device_name, block_device_mapping.delete_on_termination AS block_device_mapping_delete_on_termination, block_device_mapping.snapshot_id AS block_device_mapping_snapshot_id, block_device_mapping.volume_id AS block_device_mapping_volume_id, block_device_mapping.volume_size AS block_device_mapping_volume_size, block_device_mapping.image_id AS block_device_mapping_image_id, block_device_mapping.no_device AS block_device_mapping_no_device, block_device_mapping.connection_info AS block_device_mapping_connection_info
FROM block_device_mapping
WHERE block_device_mapping.deleted = 0 AND block_device_mapping.instance_uuid = '44f3f532-e773-4add-8f45-980988899471';
SELECT block_device_mapping.created_at AS block_device_mapping_created_at, block_device_mapping.updated_at AS block_device_mapping_updated_at, block_device_mapping.deleted_at AS block_device_mapping_deleted_at, block_device_mapping.deleted AS block_device_mapping_deleted, block_device_mapping.id AS block_device_mapping_id, block_device_mapping.instance_uuid AS block_device_mapping_instance_uuid, block_device_mapping.source_type AS block_device_mapping_source_type, block_device_mapping.destination_type AS block_device_mapping_destination_type, block_device_mapping.guest_format AS block_device_mapping_guest_format, block_device_mapping.device_type AS block_device_mapping_device_type, block_device_mapping.disk_bus AS block_device_mapping_disk_bus, block_device_mapping.boot_index AS block_device_mapping_boot_index, block_device_mapping.device_name AS block_device_mapping_device_name, block_device_mapping.delete_on_termination AS block_device_mapping_delete_on_termination, block_device_mapping.snapshot_id AS block_device_mapping_snapshot_id, block_device_mapping.volume_id AS block_device_mapping_volume_id, block_device_mapping.volume_size AS block_device_mapping_volume_size, block_device_mapping.image_id AS block_device_mapping_image_id, block_device_mapping.no_device AS block_device_mapping_no_device, block_device_mapping.connection_info AS block_device_mapping_connection_info
FROM block_device_mapping
WHERE block_device_mapping.deleted = 0 AND block_device_mapping.instance_uuid = '53ce3de4-bd65-4e04-a7d7-f220c895ed92';
SELECT block_device_mapping.created_at AS block_device_mapping_created_at, block_device_mapping.updated_at AS block_device_mapping_updated_at, block_device_mapping.deleted_at AS block_device_mapping_deleted_at, block_device_mapping.deleted AS block_device_mapping_deleted, block_device_mapping.id AS block_device_mapping_id, block_device_mapping.instance_uuid AS block_device_mapping_instance_uuid, block_device_mapping.source_type AS block_device_mapping_source_type, block_device_mapping.destination_type AS block_device_mapping_destination_type, block_device_mapping.guest_format AS block_device_mapping_guest_format, block_device_mapping.device_type AS block_device_mapping_device_type, block_device_mapping.disk_bus AS block_device_mapping_disk_bus, block_device_mapping.boot_index AS block_device_mapping_boot_index, block_device_mapping.device_name AS block_device_mapping_device_name, block_device_mapping.delete_on_termination AS block_device_mapping_delete_on_termination, block_device_mapping.snapshot_id AS block_device_mapping_snapshot_id, block_device_mapping.volume_id AS block_device_mapping_volume_id, block_device_mapping.volume_size AS block_device_mapping_volume_size, block_device_mapping.image_id AS block_device_mapping_image_id, block_device_mapping.no_device AS block_device_mapping_no_device, block_device_mapping.connection_info AS block_device_mapping_connection_info
FROM block_device_mapping
WHERE block_device_mapping.deleted = 0 AND block_device_mapping.instance_uuid = '6aec54ab-f069-4159-ba67-fc8376c164c7';
SELECT block_device_mapping.created_at AS block_device_mapping_created_at, block_device_mapping.updated_at AS block_device_mapping_updated_at, block_device_mapping.deleted_at AS block_device_mapping_deleted_at, block_device_mapping.deleted AS block_device_mapping_deleted, block_device_mapping.id AS block_device_mapping_id, block_device_mapping.instance_uuid AS block_device_mapping_instance_uuid, block_device_mapping.source_type AS block_device_mapping_source_type, block_device_mapping.destination_type AS block_device_mapping_destination_type, block_device_mapping.guest_format AS block_device_mapping_guest_format, block_device_mapping.device_type AS block_device_mapping_device_type, block_device_mapping.disk_bus AS block_device_mapping_disk_bus, block_device_mapping.boot_index AS block_device_mapping_boot_index, block_device_mapping.device_name AS block_device_mapping_device_name, block_device_mapping.delete_on_termination AS block_device_mapping_delete_on_termination, block_device_mapping.snapshot_id AS block_device_mapping_snapshot_id, block_device_mapping.volume_id AS block_device_mapping_volume_id, block_device_mapping.volume_size AS block_device_mapping_volume_size, block_device_mapping.image_id AS block_device_mapping_image_id, block_device_mapping.no_device AS block_device_mapping_no_device, block_device_mapping.connection_info AS block_device_mapping_connection_info
FROM block_device_mapping
WHERE block_device_mapping.deleted = 0 AND block_device_mapping.instance_uuid = 'e9512e80-e25b-4ff1-9e29-a2cc617ee71b';
- Perhaps it's from the relationship declared in the following mapping, but I doubt it given the clause order differs (and I think SQLAlchemy preserves the order):
class BlockDeviceMapping(BASE, NovaBase):
"""Represents block device mapping that is defined by EC2."""
__tablename__ = "block_device_mapping"
__table_args__ = (
Index('snapshot_id', 'snapshot_id'),
Index('volume_id', 'volume_id'),
Index('block_device_mapping_instance_uuid_device_name_idx',
'instance_uuid', 'device_name'),
Index('block_device_mapping_instance_uuid_volume_id_idx',
'instance_uuid', 'volume_id'),
Index('block_device_mapping_instance_uuid_idx', 'instance_uuid'),
)
id = Column(Integer, primary_key=True, autoincrement=True)
instance_uuid = Column(String(36), ForeignKey('instances.uuid'))
instance = orm.relationship(Instance,
backref=orm.backref('block_device_mapping'),
foreign_keys=instance_uuid,
primaryjoin='and_(BlockDeviceMapping.'
'instance_uuid=='
'Instance.uuid,'
'BlockDeviceMapping.deleted=='
'0)')
...
- All the queries executed during a
nova list
with 2 instances.
-----> Grab the instances
SELECT anon_1.instances_created_at AS anon_1_instances_created_at, anon_1.instances_updated_at AS anon_1_instances_updated_at, anon_1.instances_deleted_at AS anon_1_instances_deleted_at, anon_1.instances_deleted AS anon_1_instances_deleted, anon_1.instances_id AS anon_1_instances_id, anon_1.instances_user_id AS anon_1_instances_user_id, anon_1.instances_project_id AS anon_1_instances_project_id, anon_1.instances_image_ref AS anon_1_instances_image_ref, anon_1.instances_kernel_id AS anon_1_instances_kernel_id, anon_1.instances_ramdisk_id AS anon_1_instances_ramdisk_id, anon_1.instances_hostname AS anon_1_instances_hostname, anon_1.instances_launch_index AS anon_1_instances_launch_index, anon_1.instances_key_name AS anon_1_instances_key_name, anon_1.instances_key_data AS anon_1_instances_key_data, anon_1.instances_power_state AS anon_1_instances_power_state, anon_1.instances_vm_state AS anon_1_instances_vm_state, anon_1.instances_task_state AS anon_1_instances_task_state, anon_1.instances_memory_mb AS anon_1_instances_memory_mb, anon_1.instances_vcpus AS anon_1_instances_vcpus, anon_1.instances_root_gb AS anon_1_instances_root_gb, anon_1.instances_ephemeral_gb AS anon_1_instances_ephemeral_gb, anon_1.instances_ephemeral_key_uuid AS anon_1_instances_ephemeral_key_uuid, anon_1.instances_host AS anon_1_instances_host, anon_1.instances_node AS anon_1_instances_node, anon_1.instances_instance_type_id AS anon_1_instances_instance_type_id, anon_1.instances_user_data AS anon_1_instances_user_data, anon_1.instances_reservation_id AS anon_1_instances_reservation_id, anon_1.instances_launched_at AS anon_1_instances_launched_at, anon_1.instances_terminated_at AS anon_1_instances_terminated_at, anon_1.instances_availability_zone AS anon_1_instances_availability_zone, anon_1.instances_display_name AS anon_1_instances_display_name, anon_1.instances_display_description AS anon_1_instances_display_description, anon_1.instances_launched_on AS anon_1_instances_launched_on, anon_1.instances_locked AS anon_1_instances_locked, anon_1.instances_locked_by AS anon_1_instances_locked_by, anon_1.instances_os_type AS anon_1_instances_os_type, anon_1.instances_architecture AS anon_1_instances_architecture, anon_1.instances_vm_mode AS anon_1_instances_vm_mode, anon_1.instances_uuid AS anon_1_instances_uuid, anon_1.instances_root_device_name AS anon_1_instances_root_device_name, anon_1.instances_default_ephemeral_device AS anon_1_instances_default_ephemeral_device, anon_1.instances_default_swap_device AS anon_1_instances_default_swap_device, anon_1.instances_config_drive AS anon_1_instances_config_drive, anon_1.instances_access_ip_v4 AS anon_1_instances_access_ip_v4, anon_1.instances_access_ip_v6 AS anon_1_instances_access_ip_v6, anon_1.instances_auto_disk_config AS anon_1_instances_auto_disk_config, anon_1.instances_progress AS anon_1_instances_progress, anon_1.instances_shutdown_terminate AS anon_1_instances_shutdown_terminate, anon_1.instances_disable_terminate AS anon_1_instances_disable_terminate, anon_1.instances_cell_name AS anon_1_instances_cell_name, anon_1.instances_internal_id AS anon_1_instances_internal_id, anon_1.instances_cleaned AS anon_1_instances_cleaned, security_groups_1.created_at AS security_groups_1_created_at, security_groups_1.updated_at AS security_groups_1_updated_at, security_groups_1.deleted_at AS security_groups_1_deleted_at, security_groups_1.deleted AS security_groups_1_deleted, security_groups_1.id AS security_groups_1_id, security_groups_1.name AS security_groups_1_name, security_groups_1.description AS security_groups_1_description, security_groups_1.user_id AS security_groups_1_user_id, security_groups_1.project_id AS security_groups_1_project_id, instance_metadata_1.created_at AS instance_metadata_1_created_at, instance_metadata_1.updated_at AS instance_metadata_1_updated_at, instance_metadata_1.deleted_at AS instance_metadata_1_deleted_at, instance_metadata_1.deleted AS instance_metadata_1_deleted, instance_metadata_1.id AS instance_metadata_1_id, instance_metadata_1.`key` AS instance_metadata_1_key, instance_metadata_1.value AS instance_metadata_1_value, instance_metadata_1.instance_uuid AS instance_metadata_1_instance_uuid, instance_info_caches_1.created_at AS instance_info_caches_1_created_at, instance_info_caches_1.updated_at AS instance_info_caches_1_updated_at, instance_info_caches_1.deleted_at AS instance_info_caches_1_deleted_at, instance_info_caches_1.deleted AS instance_info_caches_1_deleted, instance_info_caches_1.id AS instance_info_caches_1_id, instance_info_caches_1.network_info AS instance_info_caches_1_network_info, instance_info_caches_1.instance_uuid AS instance_info_caches_1_instance_uuid, instance_extra_1.flavor AS instance_extra_1_flavor, instance_extra_1.created_at AS instance_extra_1_created_at, instance_extra_1.updated_at AS instance_extra_1_updated_at, instance_extra_1.deleted_at AS instance_extra_1_deleted_at, instance_extra_1.deleted AS instance_extra_1_deleted, instance_extra_1.id AS instance_extra_1_id, instance_extra_1.instance_uuid AS instance_extra_1_instance_uuid
FROM (SELECT instances.created_at AS instances_created_at, instances.updated_at AS instances_updated_at, instances.deleted_at AS instances_deleted_at, instances.deleted AS instances_deleted, instances.id AS instances_id, instances.user_id AS instances_user_id, instances.project_id AS instances_project_id, instances.image_ref AS instances_image_ref, instances.kernel_id AS instances_kernel_id, instances.ramdisk_id AS instances_ramdisk_id, instances.hostname AS instances_hostname, instances.launch_index AS instances_launch_index, instances.key_name AS instances_key_name, instances.key_data AS instances_key_data, instances.power_state AS instances_power_state, instances.vm_state AS instances_vm_state, instances.task_state AS instances_task_state, instances.memory_mb AS instances_memory_mb, instances.vcpus AS instances_vcpus, instances.root_gb AS instances_root_gb, instances.ephemeral_gb AS instances_ephemeral_gb, instances.ephemeral_key_uuid AS instances_ephemeral_key_uuid, instances.host AS instances_host, instances.node AS instances_node, instances.instance_type_id AS instances_instance_type_id, instances.user_data AS instances_user_data, instances.reservation_id AS instances_reservation_id, instances.launched_at AS instances_launched_at, instances.terminated_at AS instances_terminated_at, instances.availability_zone AS instances_availability_zone, instances.display_name AS instances_display_name, instances.display_description AS instances_display_description, instances.launched_on AS instances_launched_on, instances.locked AS instances_locked, instances.locked_by AS instances_locked_by, instances.os_type AS instances_os_type, instances.architecture AS instances_architecture, instances.vm_mode AS instances_vm_mode, instances.uuid AS instances_uuid, instances.root_device_name AS instances_root_device_name, instances.default_ephemeral_device AS instances_default_ephemeral_device, instances.default_swap_device AS instances_default_swap_device, instances.config_drive AS instances_config_drive, instances.access_ip_v4 AS instances_access_ip_v4, instances.access_ip_v6 AS instances_access_ip_v6, instances.auto_disk_config AS instances_auto_disk_config, instances.progress AS instances_progress, instances.shutdown_terminate AS instances_shutdown_terminate, instances.disable_terminate AS instances_disable_terminate, instances.cell_name AS instances_cell_name, instances.internal_id AS instances_internal_id, instances.cleaned AS instances_cleaned
FROM instances
WHERE instances.deleted = %s AND (instances.vm_state != %s OR instances.vm_state IS NULL) AND instances.project_id = %s ORDER BY instances.created_at DESC, instances.id DESC
LIMIT %s) AS anon_1 LEFT OUTER JOIN (security_group_instance_association AS security_group_instance_association_1 INNER JOIN security_groups AS security_groups_1 ON security_groups_1.id = security_group_instance_association_1.security_group_id AND security_group_instance_association_1.deleted = %s AND security_groups_1.deleted = %s) ON security_group_instance_association_1.instance_uuid = anon_1.instances_uuid AND anon_1.instances_deleted = %s LEFT OUTER JOIN instance_metadata AS instance_metadata_1 ON instance_metadata_1.instance_uuid = anon_1.instances_uuid AND instance_metadata_1.deleted = %s LEFT OUTER JOIN instance_info_caches AS instance_info_caches_1 ON instance_info_caches_1.instance_uuid = anon_1.instances_uuid LEFT OUTER JOIN instance_extra AS instance_extra_1 ON instance_extra_1.instance_uuid = anon_1.instances_uuid ORDER BY anon_1.instances_created_at DESC, anon_1.instances_id DESC
(0, 'soft-delete', u'56c6ffd000e1439ca019bd00fc1aa41a', 1000, 0, 0, 0, 0)
-----> The following 3 queries are coming from the _instances_fill_metadata call.
SELECT instance_metadata.created_at AS instance_metadata_created_at, instance_metadata.updated_at AS instance_metadata_updated_at, instance_metadata.deleted_at AS instance_metadata_deleted_at, instance_metadata.deleted AS instance_metadata_deleted, instance_metadata.id AS instance_metadata_id, instance_metadata.`key` AS instance_metadata_key, instance_metadata.value AS instance_metadata_value, instance_metadata.instance_uuid AS instance_metadata_instance_uuid
FROM instance_metadata
WHERE instance_metadata.deleted = %s AND instance_metadata.instance_uuid IN (%s, %s)
(0, u'02c5093d-a7f5-4b8c-91a6-26bb2ca285e8', u'e70c5625-3d8a-461b-b586-f0bdfbbcb33d')
SELECT instance_system_metadata.created_at AS instance_system_metadata_created_at, instance_system_metadata.updated_at AS instance_system_metadata_updated_at, instance_system_metadata.deleted_at AS instance_system_metadata_deleted_at, instance_system_metadata.deleted AS instance_system_metadata_deleted, instance_system_metadata.id AS instance_system_metadata_id, instance_system_metadata.`key` AS instance_system_metadata_key, instance_system_metadata.value AS instance_system_metadata_value, instance_system_metadata.instance_uuid AS instance_system_metadata_instance_uuid
FROM instance_system_metadata
WHERE instance_system_metadata.instance_uuid IN (%s, %s)
(u'02c5093d-a7f5-4b8c-91a6-26bb2ca285e8', u'e70c5625-3d8a-461b-b586-f0bdfbbcb33d')
SELECT pci_devices.created_at AS pci_devices_created_at, pci_devices.updated_at AS pci_devices_updated_at, pci_devices.deleted_at AS pci_devices_deleted_at, pci_devices.deleted AS pci_devices_deleted, pci_devices.id AS pci_devices_id, pci_devices.compute_node_id AS pci_devices_compute_node_id, pci_devices.address AS pci_devices_address, pci_devices.vendor_id AS pci_devices_vendor_id, pci_devices.product_id AS pci_devices_product_id, pci_devices.dev_type AS pci_devices_dev_type, pci_devices.dev_id AS pci_devices_dev_id, pci_devices.label AS pci_devices_label, pci_devices.status AS pci_devices_status, pci_devices.request_id AS pci_devices_request_id, pci_devices.extra_info AS pci_devices_extra_info, pci_devices.instance_uuid AS pci_devices_instance_uuid, pci_devices.numa_node AS pci_devices_numa_node
FROM pci_devices
WHERE pci_devices.deleted = %s AND pci_devices.status = %s AND pci_devices.instance_uuid IN (%s, %s)
(0, 'allocated', u'02c5093d-a7f5-4b8c-91a6-26bb2ca285e8', u'e70c5625-3d8a-461b-b586-f0bdfbbcb33d')
-----> This is from instance_list.fill_faults() in servers.py, line 405
SELECT instance_faults.created_at AS instance_faults_created_at, instance_faults.updated_at AS instance_faults_updated_at, instance_faults.deleted_at AS instance_faults_deleted_at, instance_faults.deleted AS instance_faults_deleted, instance_faults.id AS instance_faults_id, instance_faults.instance_uuid AS instance_faults_instance_uuid, instance_faults.code AS instance_faults_code, instance_faults.message AS instance_faults_message, instance_faults.details AS instance_faults_details, instance_faults.host AS instance_faults_host
FROM instance_faults
WHERE instance_faults.deleted = %s AND instance_faults.instance_uuid IN (%s, %s) ORDER BY instance_faults.created_at DESC, instance_faults.id DESC
(0, '02c5093d-a7f5-4b8c-91a6-26bb2ca285e8', 'e70c5625-3d8a-461b-b586-f0bdfbbcb33d')
-----> Where are these coming from?
-----> Answer: block_device_mapping_get_all_by_instance()
-----> But who's calling it?
SELECT block_device_mapping.created_at AS block_device_mapping_created_at, block_device_mapping.updated_at AS block_device_mapping_updated_at, block_device_mapping.deleted_at AS block_device_mapping_deleted_at, block_device_mapping.deleted AS block_device_mapping_deleted, block_device_mapping.id AS block_device_mapping_id, block_device_mapping.instance_uuid AS block_device_mapping_instance_uuid, block_device_mapping.source_type AS block_device_mapping_source_type, block_device_mapping.destination_type AS block_device_mapping_destination_type, block_device_mapping.guest_format AS block_device_mapping_guest_format, block_device_mapping.device_type AS block_device_mapping_device_type, block_device_mapping.disk_bus AS block_device_mapping_disk_bus, block_device_mapping.boot_index AS block_device_mapping_boot_index, block_device_mapping.device_name AS block_device_mapping_device_name, block_device_mapping.delete_on_termination AS block_device_mapping_delete_on_termination, block_device_mapping.snapshot_id AS block_device_mapping_snapshot_id, block_device_mapping.volume_id AS block_device_mapping_volume_id, block_device_mapping.volume_size AS block_device_mapping_volume_size, block_device_mapping.image_id AS block_device_mapping_image_id, block_device_mapping.no_device AS block_device_mapping_no_device, block_device_mapping.connection_info AS block_device_mapping_connection_info
FROM block_device_mapping
WHERE block_device_mapping.deleted = %s AND block_device_mapping.instance_uuid = %s
(0, '02c5093d-a7f5-4b8c-91a6-26bb2ca285e8')
SELECT block_device_mapping.created_at AS block_device_mapping_created_at, block_device_mapping.updated_at AS block_device_mapping_updated_at, block_device_mapping.deleted_at AS block_device_mapping_deleted_at, block_device_mapping.deleted AS block_device_mapping_deleted, block_device_mapping.id AS block_device_mapping_id, block_device_mapping.instance_uuid AS block_device_mapping_instance_uuid, block_device_mapping.source_type AS block_device_mapping_source_type, block_device_mapping.destination_type AS block_device_mapping_destination_type, block_device_mapping.guest_format AS block_device_mapping_guest_format, block_device_mapping.device_type AS block_device_mapping_device_type, block_device_mapping.disk_bus AS block_device_mapping_disk_bus, block_device_mapping.boot_index AS block_device_mapping_boot_index, block_device_mapping.device_name AS block_device_mapping_device_name, block_device_mapping.delete_on_termination AS block_device_mapping_delete_on_termination, block_device_mapping.snapshot_id AS block_device_mapping_snapshot_id, block_device_mapping.volume_id AS block_device_mapping_volume_id, block_device_mapping.volume_size AS block_device_mapping_volume_size, block_device_mapping.image_id AS block_device_mapping_image_id, block_device_mapping.no_device AS block_device_mapping_no_device, block_device_mapping.connection_info AS block_device_mapping_connection_info
FROM block_device_mapping
WHERE block_device_mapping.deleted = %s AND block_device_mapping.instance_uuid = %s
(0, 'e70c5625-3d8a-461b-b586-f0bdfbbcb33d')
-
Those queries are coming from
BlockDeviceMappingList.get_by_instance_uuid()
, but I'm still not sure how that's being invoked N times. -
Toss an exception in there to see the caller. Ah! Apparently there is some kind of post-processing you can hook into:
2015-09-29 21:18:36.532 ERROR nova.api.openstack [req-1b5a7a93-78af-4c6a-b7e3-a44a6aaab4f5 admin admin] Caught error: HELLO!
2015-09-29 21:18:36.532 TRACE nova.api.openstack Traceback (most recent call last):
File "/opt/stack/nova/nova/api/openstack/__init__.py", line 134, in __call__
return req.get_response(self.application)
File "/usr/lib/python2.7/site-packages/webob/request.py", line 1317, in send
application, catch_exc_info=False)
File "/usr/lib/python2.7/site-packages/webob/request.py", line 1281, in call_application
app_iter = application(self.environ, start_response)
File "/usr/lib/python2.7/site-packages/webob/dec.py", line 144, in __call__
return resp(environ, start_response)
File "/usr/lib/python2.7/site-packages/webob/dec.py", line 130, in __call__
resp = self.call_func(req, *args, **self.kwargs)
File "/usr/lib/python2.7/site-packages/webob/dec.py", line 195, in call_func
return self.func(req, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/keystonemiddleware/auth_token/__init__.py", line 454, in __call__
response = req.get_response(self._app)
File "/usr/lib/python2.7/site-packages/webob/request.py", line 1317, in send
application, catch_exc_info=False)
File "/usr/lib/python2.7/site-packages/webob/request.py", line 1281, in call_application
app_iter = application(self.environ, start_response)
File "/usr/lib/python2.7/site-packages/webob/dec.py", line 144, in __call__
return resp(environ, start_response)
File "/usr/lib/python2.7/site-packages/webob/dec.py", line 144, in __call__
return resp(environ, start_response)
File "/usr/lib/python2.7/site-packages/routes/middleware.py", line 136, in __call__
response = self.app(environ, start_response)
File "/usr/lib/python2.7/site-packages/webob/dec.py", line 144, in __call__
return resp(environ, start_response)
File "/usr/lib/python2.7/site-packages/webob/dec.py", line 130, in __call__
resp = self.call_func(req, *args, **self.kwargs)
File "/usr/lib/python2.7/site-packages/webob/dec.py", line 195, in call_func
return self.func(req, *args, **kwargs)
File "/opt/stack/nova/nova/api/openstack/wsgi.py", line 765, in __call__
content_type, body, accept)
File "/opt/stack/nova/nova/api/openstack/wsgi.py", line 856, in _process_stack
request, action_args)
File "/opt/stack/nova/nova/api/openstack/wsgi.py", line 719, in post_process_extensions
**action_args)
File "/opt/stack/nova/nova/api/openstack/compute/extended_volumes.py", line 65, in detail
req.api_version_request)
File "/opt/stack/nova/nova/api/openstack/compute/extended_volumes.py", line 32, in _extend_server
context, instance.uuid)
File "/usr/lib/python2.7/site-packages/oslo_versionedobjects/base.py", line 171, in wrapper
result = fn(cls, context, *args, **kwargs)
File "/opt/stack/nova/nova/objects/block_device.py", line 294, in get_by_instance_uuid
raise Exception('HELLO!')
2015-09-29 21:18:36.532 TRACE nova.api.openstack Exception: HELLO!
- Post-processing extensions:
<bound method ConfigDriveController.detail of <nova.api.openstack.compute.config_drive.ConfigDriveController object at 0x7f1c45fa6790>>
<bound method ServerUsageController.detail of <nova.api.openstack.compute.server_usage.ServerUsageController object at 0x7f1c45f9c8d0>>
<bound method ExtendedStatusController.detail of <nova.api.openstack.compute.extended_status.ExtendedStatusController object at 0x7f1c45f9c7d0>>
<bound method ExtendedAZController.detail of <nova.api.openstack.compute.extended_availability_zone.ExtendedAZController object at 0x7f1c45f97c10>>
<bound method Controller.detail of <nova.api.openstack.compute.hide_server_addresses.Controller object at 0x7f1c4600dd10>>
-------------> This one:
<bound method ExtendedVolumesController.detail of <nova.api.openstack.compute.extended_volumes.ExtendedVolumesController object at 0x7f1c460043d0>>
<--------------
<bound method ServerDiskConfigController.detail of <nova.api.openstack.compute.disk_config.ServerDiskConfigController object at 0x7f1c45ff9ad0>>
<bound method AccessIPsController.detail of <nova.api.openstack.compute.access_ips.AccessIPsController object at 0x7f1c45ff9a90>>
<bound method SecurityGroupsOutputController.detail of <nova.api.openstack.compute.security_groups.SecurityGroupsOutputController object at 0x7f1c45feea50>>
<bound method ExtendedServerAttributesController.detail of <nova.api.openstack.compute.extended_server_attributes.ExtendedServerAttributesController object at 0x7f1c45fee9d0>>
<bound method Controller.detail of <nova.api.openstack.compute.keypairs.Controller object at 0x7f1c46a70890>>
Here's the class that's doing N queries in the detail()
case:
class ExtendedVolumesController(wsgi.Controller):
def __init__(self, *args, **kwargs):
super(ExtendedVolumesController, self).__init__(*args, **kwargs)
self.api_version_2_3 = api_version_request.APIVersionRequest('2.3')
def _extend_server(self, context, server, instance, requested_version):
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
context, instance.uuid)
volumes_attached = []
for bdm in bdms:
if bdm.get('volume_id'):
volume_attached = {'id': bdm['volume_id']}
if requested_version >= self.api_version_2_3:
volume_attached['delete_on_termination'] = (
bdm['delete_on_termination'])
volumes_attached.append(volume_attached)
key = "%s:volumes_attached" % ExtendedVolumes.alias
server[key] = volumes_attached
@wsgi.extends
def show(self, req, resp_obj, id):
context = req.environ['nova.context']
if soft_authorize(context):
server = resp_obj.obj['server']
db_instance = req.get_db_instance(server['id'])
# server['id'] is guaranteed to be in the cache due to
# the core API adding it in its 'show' method.
self._extend_server(context, server, db_instance,
req.api_version_request)
@wsgi.extends
def detail(self, req, resp_obj):
context = req.environ['nova.context']
if soft_authorize(context):
servers = list(resp_obj.obj['servers'])
for server in servers:
db_instance = req.get_db_instance(server['id'])
# server['id'] is guaranteed to be in the cache due to
# the core API adding it in its 'detail' method.
self._extend_server(context, server, db_instance,
req.api_version_request)
- What do we know about this table & data?
MariaDB [nova]> select * from block_device_mapping\G
*************************** 1. row ***************************
created_at: 2015-09-29 20:21:36
updated_at: 2015-09-29 20:21:37
deleted_at: NULL
id: 1
device_name: /dev/vda
delete_on_termination: 1
snapshot_id: NULL
volume_id: NULL
volume_size: NULL
no_device: 0
connection_info: NULL
instance_uuid: e70c5625-3d8a-461b-b586-f0bdfbbcb33d
deleted: 0
source_type: image
destination_type: local
guest_format: NULL
device_type: disk
disk_bus: NULL
boot_index: 0
image_id: 76742559-84d6-4804-8a82-7f707c1ca9da
*************************** 2. row ***************************
created_at: 2015-09-29 21:26:33
updated_at: 2015-09-29 21:26:35
deleted_at: NULL
id: 2
device_name: /dev/vda
delete_on_termination: 1
snapshot_id: NULL
volume_id: NULL
volume_size: NULL
no_device: 0
connection_info: NULL
instance_uuid: 02c5093d-a7f5-4b8c-91a6-26bb2ca285e8
deleted: 0
source_type: image
destination_type: local
guest_format: NULL
device_type: disk
disk_bus: NULL
boot_index: 0
image_id: 76742559-84d6-4804-8a82-7f707c1ca9da
2 rows in set (0.00 sec)
MariaDB [nova]> describe block_device_mapping;
+-----------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+----------------+
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
| deleted_at | datetime | YES | | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
| device_name | varchar(255) | YES | | NULL | |
| delete_on_termination | tinyint(1) | YES | | NULL | |
| snapshot_id | varchar(36) | YES | MUL | NULL | |
| volume_id | varchar(36) | YES | MUL | NULL | |
| volume_size | int(11) | YES | | NULL | |
| no_device | tinyint(1) | YES | | NULL | |
| connection_info | mediumtext | YES | | NULL | |
| instance_uuid | varchar(36) | YES | MUL | NULL | |
| deleted | int(11) | YES | | NULL | |
| source_type | varchar(255) | YES | | NULL | |
| destination_type | varchar(255) | YES | | NULL | |
| guest_format | varchar(255) | YES | | NULL | |
| device_type | varchar(255) | YES | | NULL | |
| disk_bus | varchar(255) | YES | | NULL | |
| boot_index | int(11) | YES | | NULL | |
| image_id | varchar(36) | YES | | NULL | |
+-----------------------+--------------+------+-----+---------+----------------+
20 rows in set (0.00 sec)
- This bug is already reported: https://bugs.launchpad.net/nova/+bug/1359808
- Update the
volumne_id
(s) in the database to be not NULL so that we get block device info in the json response.
MariaDB [nova]> update block_device_mapping set volume_id=concat('some_volumne_id_', id);
MariaDB [nova]> select * from block_device_mapping\G
*************************** 1. row ***************************
created_at: 2015-09-29 20:21:36
updated_at: 2015-09-29 20:21:37
deleted_at: NULL
id: 1
device_name: /dev/vda
delete_on_termination: 1
snapshot_id: NULL
volume_id: some_volumne_id_1
volume_size: NULL
no_device: 0
connection_info: NULL
instance_uuid: e70c5625-3d8a-461b-b586-f0bdfbbcb33d
deleted: 0
source_type: image
destination_type: local
guest_format: NULL
device_type: disk
disk_bus: NULL
boot_index: 0
image_id: 76742559-84d6-4804-8a82-7f707c1ca9da
*************************** 2. row ***************************
created_at: 2015-09-29 21:26:33
updated_at: 2015-09-29 21:26:35
deleted_at: NULL
id: 2
device_name: /dev/vda
delete_on_termination: 1
snapshot_id: NULL
volume_id: some_volumne_id_2
volume_size: NULL
no_device: 0
connection_info: NULL
instance_uuid: 02c5093d-a7f5-4b8c-91a6-26bb2ca285e8
deleted: 0
source_type: image
destination_type: local
guest_format: NULL
device_type: disk
disk_bus: NULL
boot_index: 0
image_id: 7
- Note the volume id in the results now:
[
{
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "reserved",
"OS-EXT-SRV-ATTR:hostname": "instance-2",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "reserved",
"OS-EXT-SRV-ATTR:instance_name": "instance-00000002",
"OS-EXT-SRV-ATTR:kernel_id": "37060936-0e85-44da-b792-ec5b27f959c6",
"OS-EXT-SRV-ATTR:launch_index": 0,
"OS-EXT-SRV-ATTR:ramdisk_id": "3196473f-b7f6-43f6-bcb4-ca81607b8188",
"OS-EXT-SRV-ATTR:reservation_id": "r-ikjkrugu",
"OS-EXT-SRV-ATTR:root_device_name": "/dev/vda",
"OS-EXT-SRV-ATTR:user_data": null,
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"OS-SRV-USG:launched_at": "2015-09-30T13:57:19.000000",
"OS-SRV-USG:terminated_at": null,
"accessIPv4": "",
"accessIPv6": "",
"addresses": {
"private": [
{
"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:b3:c4:68",
"OS-EXT-IPS:type": "fixed",
"addr": "10.0.0.3",
"version": 4
}
]
},
"config_drive": "True",
"created": "2015-09-29T21:26:33Z",
"flavor": {
"id": "42",
"links": [
{
"href": "http://192.168.122.15:8774/56c6ffd000e1439ca019bd00fc1aa41a/flavors/42",
"rel": "bookmark"
}
]
},
"hostId": "28a24236a69fe969a3121c663df3326d18b49588964b6b0a2ad842ef",
"id": "02c5093d-a7f5-4b8c-91a6-26bb2ca285e8",
"image": {
"id": "76742559-84d6-4804-8a82-7f707c1ca9da",
"links": [
{
"href": "http://192.168.122.15:8774/56c6ffd000e1439ca019bd00fc1aa41a/images/76742559-84d6-4804-8a82-7f707c1ca9da",
"rel": "bookmark"
}
]
},
"key_name": null,
"links": [
{
"href": "http://192.168.122.15:8774/v2.1/56c6ffd000e1439ca019bd00fc1aa41a/servers/02c5093d-a7f5-4b8c-91a6-26bb2ca285e8",
"rel": "self"
},
{
"href": "http://192.168.122.15:8774/56c6ffd000e1439ca019bd00fc1aa41a/servers/02c5093d-a7f5-4b8c-91a6-26bb2ca285e8",
"rel": "bookmark"
}
],
"locked": false,
"metadata": {},
"name": "instance-2",
"os-extended-volumes:volumes_attached": [
{
"delete_on_termination": true,
"id": "some_volumne_id_2" <-------- see!
}
],
"progress": 0,
"security_groups": [
{
"name": "default"
}
],
"status": "ACTIVE",
"tenant_id": "56c6ffd000e1439ca019bd00fc1aa41a",
"updated": "2015-09-30T13:57:19Z",
"user_id": "469cb305d1f94c15b97985dde3eba3b3"
},
{
"OS-DCF:diskConfig": "AUTO",
"OS-EXT-AZ:availability_zone": "nova",
"OS-EXT-SRV-ATTR:host": "reserved",
"OS-EXT-SRV-ATTR:hostname": "instance-1",
"OS-EXT-SRV-ATTR:hypervisor_hostname": "reserved",
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
"OS-EXT-SRV-ATTR:kernel_id": "37060936-0e85-44da-b792-ec5b27f959c6",
"OS-EXT-SRV-ATTR:launch_index": 0,
"OS-EXT-SRV-ATTR:ramdisk_id": "3196473f-b7f6-43f6-bcb4-ca81607b8188",
"OS-EXT-SRV-ATTR:reservation_id": "r-mlgvzrde",
"OS-EXT-SRV-ATTR:root_device_name": "/dev/vda",
"OS-EXT-SRV-ATTR:user_data": null,
"OS-EXT-STS:power_state": 1,
"OS-EXT-STS:task_state": null,
"OS-EXT-STS:vm_state": "active",
"OS-SRV-USG:launched_at": "2015-09-29T20:22:03.000000",
"OS-SRV-USG:terminated_at": null,
"accessIPv4": "",
"accessIPv6": "",
"addresses": {
"private": [
{
"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:14:4b:b5",
"OS-EXT-IPS:type": "fixed",
"addr": "10.0.0.2",
"version": 4
}
]
},
"config_drive": "True",
"created": "2015-09-29T20:21:35Z",
"flavor": {
"id": "42",
"links": [
{
"href": "http://192.168.122.15:8774/56c6ffd000e1439ca019bd00fc1aa41a/flavors/42",
"rel": "bookmark"
}
]
},
"hostId": "28a24236a69fe969a3121c663df3326d18b49588964b6b0a2ad842ef",
"id": "e70c5625-3d8a-461b-b586-f0bdfbbcb33d",
"image": {
"id": "76742559-84d6-4804-8a82-7f707c1ca9da",
"links": [
{
"href": "http://192.168.122.15:8774/56c6ffd000e1439ca019bd00fc1aa41a/images/76742559-84d6-4804-8a82-7f707c1ca9da",
"rel": "bookmark"
}
]
},
"key_name": null,
"links": [
{
"href": "http://192.168.122.15:8774/v2.1/56c6ffd000e1439ca019bd00fc1aa41a/servers/e70c5625-3d8a-461b-b586-f0bdfbbcb33d",
"rel": "self"
},
{
"href": "http://192.168.122.15:8774/56c6ffd000e1439ca019bd00fc1aa41a/servers/e70c5625-3d8a-461b-b586-f0bdfbbcb33d",
"rel": "bookmark"
}
],
"locked": false,
"metadata": {},
"name": "instance-1",
"os-extended-volumes:volumes_attached": [
{
"delete_on_termination": true,
"id": "some_volumne_id_1" <-------- see!
}
],
"progress": 0,
"security_groups": [
{
"name": "default"
}
],
"status": "ACTIVE",
"tenant_id": "56c6ffd000e1439ca019bd00fc1aa41a",
"updated": "2015-09-29T20:22:03Z",
"user_id": "469cb305d1f94c15b97985dde3eba3b3"
}
]