summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Erdfelt <johannes.erdfelt@rackspace.com>2012-01-06 12:57:37 -0800
committerJohannes Erdfelt <johannes.erdfelt@rackspace.com>2012-01-24 16:54:23 +0000
commita4223f1d89ea7033cbae35790a0411ec439cdb6d (patch)
treebf3768b78a9ab8633b525b17579bc8326bbcab63
parent91bc67d81a9711fbf5a0f0c46bbf1d87232391f8 (diff)
downloadnova-a4223f1d89ea7033cbae35790a0411ec439cdb6d.tar.gz
nova-a4223f1d89ea7033cbae35790a0411ec439cdb6d.tar.xz
nova-a4223f1d89ea7033cbae35790a0411ec439cdb6d.zip
KVM and XEN Disk Management Parity
Implements blueprint disk-configuration-parity This change splits local_gb into root_gb and ephemeral_gb. libvirt interpreted local_gb as what ephemeral_gb is now, whereas XenAPI interpreted local_gb as what root_gb is now. Change-Id: I496600991bac1e990326d4ded1607fee08209d68
-rw-r--r--nova/api/ec2/admin.py2
-rw-r--r--nova/api/metadata/handler.py7
-rw-r--r--nova/api/openstack/compute/contrib/simple_tenant_usage.py2
-rw-r--r--nova/api/openstack/compute/flavors.py2
-rw-r--r--nova/api/openstack/compute/views/flavors.py2
-rw-r--r--nova/compute/api.py11
-rw-r--r--nova/compute/instance_types.py5
-rw-r--r--nova/compute/manager.py16
-rw-r--r--nova/db/sqlalchemy/api.py4
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/074_change_flavor_local_gb.py130
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/074_sqlite_upgrade.sql313
-rw-r--r--nova/db/sqlalchemy/models.py8
-rw-r--r--nova/flags.py6
-rw-r--r--nova/scheduler/host_manager.py2
-rw-r--r--nova/scheduler/manager.py22
-rw-r--r--nova/tests/api/ec2/test_admin.py2
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py8
-rw-r--r--nova/tests/api/openstack/compute/test_consoles.py2
-rw-r--r--nova/tests/api/openstack/compute/test_flavors.py6
-rw-r--r--nova/tests/api/openstack/compute/test_server_actions.py2
-rw-r--r--nova/tests/api/openstack/fakes.py3
-rw-r--r--nova/tests/db/fakes.py17
-rw-r--r--nova/tests/fake_network.py2
-rw-r--r--nova/tests/scheduler/fakes.py18
-rw-r--r--nova/tests/scheduler/test_distributed_scheduler.py12
-rw-r--r--nova/tests/scheduler/test_host_filters.py15
-rw-r--r--nova/tests/scheduler/test_scheduler.py24
-rw-r--r--nova/tests/test_compute.py23
-rw-r--r--nova/tests/test_compute_utils.py2
-rw-r--r--nova/tests/test_instance_types.py46
-rw-r--r--nova/tests/test_instance_types_extra_specs.py3
-rw-r--r--nova/tests/test_libvirt.py6
-rw-r--r--nova/tests/test_quota.py10
-rw-r--r--nova/tests/test_xenapi.py103
-rw-r--r--nova/tests/utils.py4
-rw-r--r--nova/tests/vmwareapi/db_fakes.py12
-rw-r--r--nova/tests/xenapi/stubs.py10
-rw-r--r--nova/utils.py2
-rw-r--r--nova/virt/disk/api.py2
-rw-r--r--nova/virt/libvirt.xml.template4
-rw-r--r--nova/virt/libvirt/connection.py45
-rw-r--r--nova/virt/xenapi/vm_utils.py65
-rw-r--r--nova/virt/xenapi/vmops.py19
43 files changed, 807 insertions, 192 deletions
diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py
index de2348c91..80a30659d 100644
--- a/nova/api/ec2/admin.py
+++ b/nova/api/ec2/admin.py
@@ -89,7 +89,7 @@ def instance_dict(inst):
return {'name': inst['name'],
'memory_mb': inst['memory_mb'],
'vcpus': inst['vcpus'],
- 'disk_gb': inst['local_gb'],
+ 'disk_gb': inst['root_gb'],
'flavor_id': inst['flavorid']}
diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py
index 04e64bd57..7cf5514a3 100644
--- a/nova/api/metadata/handler.py
+++ b/nova/api/metadata/handler.py
@@ -100,9 +100,10 @@ class MetadataRequestHandler(wsgi.Application):
mappings = {}
mappings['ami'] = block_device.strip_dev(root_device_name)
mappings['root'] = root_device_name
- default_local_device = instance_ref.get('default_local_device')
- if default_local_device:
- mappings['ephemeral0'] = default_local_device
+ default_ephemeral_device = \
+ instance_ref.get('default_ephemeral_device')
+ if default_ephemeral_device:
+ mappings['ephemeral0'] = default_ephemeral_device
default_swap_device = instance_ref.get('default_swap_device')
if default_swap_device:
mappings['swap'] = default_swap_device
diff --git a/nova/api/openstack/compute/contrib/simple_tenant_usage.py b/nova/api/openstack/compute/contrib/simple_tenant_usage.py
index f34581f6c..85ea9a859 100644
--- a/nova/api/openstack/compute/contrib/simple_tenant_usage.py
+++ b/nova/api/openstack/compute/contrib/simple_tenant_usage.py
@@ -135,7 +135,7 @@ class SimpleTenantUsageController(object):
info['name'] = instance['display_name']
info['memory_mb'] = flavor['memory_mb']
- info['local_gb'] = flavor['local_gb']
+ info['local_gb'] = flavor['root_gb'] + flavor['ephemeral_gb']
info['vcpus'] = flavor['vcpus']
info['tenant_id'] = instance['project_id']
diff --git a/nova/api/openstack/compute/flavors.py b/nova/api/openstack/compute/flavors.py
index c7ceecbec..99f6f44d8 100644
--- a/nova/api/openstack/compute/flavors.py
+++ b/nova/api/openstack/compute/flavors.py
@@ -104,7 +104,7 @@ class Controller(wsgi.Controller):
if 'minDisk' in req.params:
try:
- filters['min_local_gb'] = int(req.params['minDisk'])
+ filters['min_root_gb'] = int(req.params['minDisk'])
except ValueError:
pass # ignore bogus values per spec
diff --git a/nova/api/openstack/compute/views/flavors.py b/nova/api/openstack/compute/views/flavors.py
index 050ea20d3..729c4df24 100644
--- a/nova/api/openstack/compute/views/flavors.py
+++ b/nova/api/openstack/compute/views/flavors.py
@@ -37,7 +37,7 @@ class ViewBuilder(common.ViewBuilder):
"id": flavor["flavorid"],
"name": flavor["name"],
"ram": flavor["memory_mb"],
- "disk": flavor["local_gb"],
+ "disk": flavor["root_gb"],
"vcpus": flavor.get("vcpus") or "",
"swap": flavor.get("swap") or "",
"rxtx_factor": flavor.get("rxtx_factor") or "",
diff --git a/nova/compute/api.py b/nova/compute/api.py
index ca28f3871..a4c228e26 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -226,7 +226,7 @@ class API(base.Base):
if instance_type['memory_mb'] < int(image.get('min_ram') or 0):
raise exception.InstanceTypeMemoryTooSmall()
- if instance_type['local_gb'] < int(image.get('min_disk') or 0):
+ if instance_type['root_gb'] < int(image.get('min_disk') or 0):
raise exception.InstanceTypeDiskTooSmall()
config_drive_id = None
@@ -315,7 +315,8 @@ class API(base.Base):
'instance_type_id': instance_type['id'],
'memory_mb': instance_type['memory_mb'],
'vcpus': instance_type['vcpus'],
- 'local_gb': instance_type['local_gb'],
+ 'root_gb': instance_type['root_gb'],
+ 'ephemeral_gb': instance_type['ephemeral_gb'],
'display_name': display_name,
'display_description': display_description,
'user_data': user_data or '',
@@ -376,13 +377,13 @@ class API(base.Base):
# TODO(yamahata): ephemeralN where N > 0
# Only ephemeral0 is allowed for now because InstanceTypes
- # table only allows single local disk, local_gb.
+ # table only allows single local disk, ephemeral_gb.
# In order to enhance it, we need to add a new columns to
# instance_types table.
if num > 0:
return 0
- size = instance_type.get('local_gb')
+ size = instance_type.get('ephemeral_gb')
return size
@@ -1240,7 +1241,7 @@ class API(base.Base):
#disk format of vhd is non-shrinkable
if orig_image.get('disk_format') == 'vhd':
min_ram = instance['instance_type']['memory_mb']
- min_disk = instance['instance_type']['local_gb']
+ min_disk = instance['instance_type']['root_gb']
else:
#set new image values to the original image values
min_ram = orig_image.get('min_ram')
diff --git a/nova/compute/instance_types.py b/nova/compute/instance_types.py
index 58f479a07..191f9ca0e 100644
--- a/nova/compute/instance_types.py
+++ b/nova/compute/instance_types.py
@@ -30,13 +30,14 @@ FLAGS = flags.FLAGS
LOG = logging.getLogger('nova.instance_types')
-def create(name, memory, vcpus, local_gb, flavorid, swap=0,
+def create(name, memory, vcpus, root_gb, ephemeral_gb, flavorid, swap=0,
rxtx_factor=1):
"""Creates instance types."""
kwargs = {
'memory_mb': memory,
'vcpus': vcpus,
- 'local_gb': local_gb,
+ 'root_gb': root_gb,
+ 'ephemeral_gb': ephemeral_gb,
'swap': swap,
'rxtx_factor': rxtx_factor,
}
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 65985ca02..f43c7a1a0 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -432,12 +432,12 @@ class ComputeManager(manager.SchedulerDependentManager):
instance_type_id = instance['instance_type_id']
instance_type = instance_types.get_instance_type(instance_type_id)
- allowed_size_gb = instance_type['local_gb']
+ allowed_size_gb = instance_type['root_gb']
- # NOTE(jk0): Since libvirt uses local_gb as a secondary drive, we
- # need to handle potential situations where local_gb is 0. This is
- # the default for m1.tiny.
- if allowed_size_gb == 0:
+ # NOTE(johannes): root_gb is allowed to be 0 for legacy reasons
+ # since libvirt interpreted the value differently than other
+ # drivers. A value of 0 means don't check size.
+ if not allowed_size_gb:
return image_meta
allowed_size_bytes = allowed_size_gb * 1024 * 1024 * 1024
@@ -1111,7 +1111,8 @@ class ComputeManager(manager.SchedulerDependentManager):
memory_mb=instance_type['memory_mb'],
host=migration_ref['source_compute'],
vcpus=instance_type['vcpus'],
- local_gb=instance_type['local_gb'],
+ root_gb=instance_type['root_gb'],
+ ephemeral_gb=instance_type['ephemeral_gb'],
instance_type_id=instance_type['id'])
self.driver.finish_revert_migration(instance_ref)
@@ -1238,7 +1239,8 @@ class ComputeManager(manager.SchedulerDependentManager):
dict(instance_type_id=instance_type['id'],
memory_mb=instance_type['memory_mb'],
vcpus=instance_type['vcpus'],
- local_gb=instance_type['local_gb']))
+ root_gb=instance_type['root_gb'],
+ ephemeral_gb=instance_type['ephemeral_gb']))
resize_instance = True
instance_ref = self.db.instance_get_by_uuid(context,
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index b59e50544..794861b11 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -3380,9 +3380,9 @@ def instance_type_get_all(context, inactive=False, filters=None):
if 'min_memory_mb' in filters:
query = query.filter(
models.InstanceTypes.memory_mb >= filters['min_memory_mb'])
- if 'min_local_gb' in filters:
+ if 'min_root_gb' in filters:
query = query.filter(
- models.InstanceTypes.local_gb >= filters['min_local_gb'])
+ models.InstanceTypes.root_gb >= filters['min_root_gb'])
inst_types = query.order_by("name").all()
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/074_change_flavor_local_gb.py b/nova/db/sqlalchemy/migrate_repo/versions/074_change_flavor_local_gb.py
new file mode 100644
index 000000000..ef7e3293a
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/074_change_flavor_local_gb.py
@@ -0,0 +1,130 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import sqlalchemy
+from sqlalchemy import select, Column, Integer
+
+from nova import exception
+from nova import flags
+from nova import log as logging
+
+
+LOG = logging.getLogger('nova.db.sqlalchemy.migrate_repo.versions')
+
+FLAGS = flags.FLAGS
+
+meta = sqlalchemy.MetaData()
+
+
+def _get_table(name):
+ return sqlalchemy.Table(name, meta, autoload=True)
+
+
+def upgrade_libvirt(instances, instance_types):
+ # Update instance_types first
+ tiny = None
+ for inst_type in instance_types.select().execute():
+ if inst_type['name'] == 'm1.tiny':
+ tiny = inst_type['id']
+ root_gb = 0
+ else:
+ root_gb = 10
+
+ instance_types.update()\
+ .values(root_gb=root_gb,
+ ephemeral_gb=inst_type['local_gb'])\
+ .where(instance_types.c.id == inst_type['id'])\
+ .execute()
+
+ # then update instances following same pattern
+ instances.update()\
+ .values(root_gb=10,
+ ephemeral_gb=instances.c.local_gb)\
+ .execute()
+
+ if tiny is not None:
+ instances.update()\
+ .values(root_gb=0,
+ ephemeral_gb=instances.c.local_gb)\
+ .where(instances.c.instance_type_id == tiny)\
+ .execute()
+
+
+def upgrade_other(instances, instance_types):
+ for table in (instances, instance_types):
+ table.update().values(root_gb=table.c.local_gb,
+ ephemeral_gb=0).execute()
+
+
+def upgrade(migrate_engine):
+ if not FLAGS.connection_type:
+ raise exception.Error("Need connection_type specified to run "
+ "migration")
+
+ meta.bind = migrate_engine
+ instances = _get_table('instances')
+ instance_types = _get_table('instance_types')
+
+ for table in (instances, instance_types):
+ root_gb = Column('root_gb', Integer)
+ root_gb.create(table)
+ ephemeral_gb = Column('ephemeral_gb', Integer)
+ ephemeral_gb.create(table)
+
+ # Since this migration is part of the work to get all drivers
+ # working the same way, we need to treat the new root_gb and
+ # ephemeral_gb columns differently depending on what the
+ # driver implementation used to behave like.
+ if FLAGS.connection_type == 'libvirt':
+ upgrade_libvirt(instances, instance_types)
+ else:
+ upgrade_other(instances, instance_types)
+
+ default_local_device = instances.c.default_local_device
+ default_local_device.alter(name='default_ephemeral_device')
+
+ for table in (instances, instance_types):
+ table.drop_column('local_gb')
+
+
+def downgrade(migrate_engine):
+ meta.bind = migrate_engine
+ instances = _get_table('instances')
+ instance_types = _get_table('instance_types')
+
+ for table in (instances, instance_types):
+ local_gb = Column('root_gb', Integer)
+ local_gb.create(table)
+
+ try:
+ for table in (instances, instance_types):
+ if FLAGS.connection_type == 'libvirt':
+ column = table.c.ephemeral_gb
+ else:
+ column = table.c.root_gb
+ table.update().values(local_gb=column).execute()
+ except Exception:
+ for table in (instances, instance_types):
+ table.drop_column('local_gb')
+ raise
+
+ default_ephemeral_device = instances.c.default_ephemeral_device
+ default_ephemeral_device.alter(name='default_local_device')
+
+ for table in (instances, instance_types):
+ table.drop_column('root_gb')
+ table.drop_column('ephemeral_gb')
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/074_sqlite_upgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/074_sqlite_upgrade.sql
new file mode 100644
index 000000000..e2708111b
--- /dev/null
+++ b/nova/db/sqlalchemy/migrate_repo/versions/074_sqlite_upgrade.sql
@@ -0,0 +1,313 @@
+-- sqlalchemy-migrate is surprisingly broken when it comes to migrations
+-- for sqlite. As a result, we have to do much of the work manually here
+
+BEGIN TRANSACTION;
+ -- make backup of instance_types
+ CREATE TEMPORARY TABLE instance_types_backup (
+ created_at DATETIME,
+ updated_at DATETIME,
+ deleted_at DATETIME,
+ deleted BOOLEAN,
+ name VARCHAR(255),
+ id INTEGER NOT NULL,
+ memory_mb INTEGER NOT NULL,
+ vcpus INTEGER NOT NULL,
+ local_gb INTEGER NOT NULL,
+ swap INTEGER NOT NULL,
+ rxtx_factor FLOAT,
+ vcpu_weight INTEGER,
+ flavorid VARCHAR(255),
+ PRIMARY KEY (id),
+ UNIQUE (flavorid),
+ CHECK (deleted IN (0, 1)),
+ UNIQUE (name)
+ );
+
+ INSERT INTO instance_types_backup
+ SELECT created_at,
+ updated_at,
+ deleted_at,
+ deleted,
+ name,
+ id,
+ memory_mb,
+ vcpus,
+ local_gb,
+ swap,
+ rxtx_factor,
+ vcpu_weight,
+ flavorid
+ FROM instance_types;
+
+ DROP TABLE instance_types;
+
+ CREATE TABLE instance_types (
+ created_at DATETIME,
+ updated_at DATETIME,
+ deleted_at DATETIME,
+ deleted BOOLEAN,
+ name VARCHAR(255),
+ id INTEGER NOT NULL,
+ memory_mb INTEGER NOT NULL,
+ vcpus INTEGER NOT NULL,
+ root_gb INTEGER NOT NULL,
+ ephemeral_gb INTEGER NOT NULL,
+ swap INTEGER NOT NULL,
+ rxtx_factor FLOAT,
+ vcpu_weight INTEGER,
+ flavorid VARCHAR(255),
+ PRIMARY KEY (id),
+ UNIQUE (flavorid),
+ CHECK (deleted IN (0, 1)),
+ UNIQUE (name)
+ );
+
+ -- copy from backup to new table with root_gb set to local_gb and
+ -- ephmeral_gb set to 0
+ INSERT INTO instance_types
+ SELECT created_at,
+ updated_at,
+ deleted_at,
+ deleted,
+ name,
+ id,
+ memory_mb,
+ vcpus,
+ local_gb,
+ 0,
+ swap,
+ rxtx_factor,
+ vcpu_weight,
+ flavorid
+ FROM instance_types_backup;
+
+ DROP TABLE instance_types_backup;
+
+ -- make backup of instances
+ CREATE TEMPORARY TABLE instances_backup (
+ created_at DATETIME,
+ updated_at DATETIME,
+ deleted_at DATETIME,
+ deleted BOOLEAN,
+ id INTEGER NOT NULL,
+ internal_id INTEGER,
+ user_id VARCHAR(255),
+ project_id VARCHAR(255),
+ image_ref VARCHAR(255),
+ kernel_id VARCHAR(255),
+ ramdisk_id VARCHAR(255),
+ server_name VARCHAR(255),
+ launch_index INTEGER,
+ key_name VARCHAR(255),
+ key_data TEXT,
+ power_state INTEGER,
+ vm_state VARCHAR(255),
+ memory_mb INTEGER,
+ vcpus INTEGER,
+ local_gb INTEGER,
+ hostname VARCHAR(255),
+ host VARCHAR(255),
+ user_data TEXT,
+ reservation_id VARCHAR(255),
+ scheduled_at DATETIME,
+ launched_at DATETIME,
+ terminated_at DATETIME,
+ display_name VARCHAR(255),
+ display_description VARCHAR(255),
+ availability_zone VARCHAR(255),
+ locked BOOLEAN,
+ os_type VARCHAR(255),
+ launched_on TEXT,
+ instance_type_id INTEGER,
+ vm_mode VARCHAR(255),
+ uuid VARCHAR(36),
+ architecture VARCHAR(255),
+ root_device_name VARCHAR(255),
+ access_ip_v4 VARCHAR(255),
+ access_ip_v6 VARCHAR(255),
+ config_drive VARCHAR(255),
+ task_state VARCHAR(255),
+ default_local_device VARCHAR(255),
+ default_swap_device VARCHAR(255),
+ progress INTEGER,
+ auto_disk_config BOOLEAN,
+ shutdown_terminate BOOLEAN,
+ disable_terminate BOOLEAN,
+ PRIMARY KEY (id),
+ CHECK (deleted IN (0, 1)),
+ CHECK (locked IN (0, 1)),
+ CHECK (auto_disk_config IN (0, 1)),
+ CHECK (shutdown_terminate IN (0, 1)),
+ CHECK (disable_terminate IN (0, 1))
+ );
+
+ INSERT INTO instances_backup
+ SELECT created_at,
+ updated_at,
+ deleted_at,
+ deleted,
+ id,
+ internal_id,
+ user_id,
+ project_id,
+ image_ref,
+ kernel_id,
+ ramdisk_id,
+ server_name,
+ launch_index,
+ key_name,
+ key_data,
+ power_state,
+ vm_state,
+ memory_mb,
+ vcpus,
+ local_gb,
+ hostname,
+ host,
+ user_data,
+ reservation_id,
+ scheduled_at,
+ launched_at,
+ terminated_at,
+ display_name,
+ display_description,
+ availability_zone,
+ locked,
+ os_type,
+ launched_on,
+ instance_type_id,
+ vm_mode,
+ uuid,
+ architecture,
+ root_device_name,
+ access_ip_v4,
+ access_ip_v6,
+ config_drive,
+ task_state,
+ default_local_device,
+ default_swap_device,
+ progress,
+ auto_disk_config,
+ shutdown_terminate,
+ disable_terminate
+ FROM instances;
+
+ DROP TABLE instances;
+
+ CREATE TABLE instances (
+ created_at DATETIME,
+ updated_at DATETIME,
+ deleted_at DATETIME,
+ deleted BOOLEAN,
+ id INTEGER NOT NULL,
+ internal_id INTEGER,
+ user_id VARCHAR(255),
+ project_id VARCHAR(255),
+ image_ref VARCHAR(255),
+ kernel_id VARCHAR(255),
+ ramdisk_id VARCHAR(255),
+ server_name VARCHAR(255),
+ launch_index INTEGER,
+ key_name VARCHAR(255),
+ key_data TEXT,
+ power_state INTEGER,
+ vm_state VARCHAR(255),
+ memory_mb INTEGER,
+ vcpus INTEGER,
+ root_gb INTEGER,
+ ephemeral_gb INTEGER,
+ hostname VARCHAR(255),
+ host VARCHAR(255),
+ user_data TEXT,
+ reservation_id VARCHAR(255),
+ scheduled_at DATETIME,
+ launched_at DATETIME,
+ terminated_at DATETIME,
+ display_name VARCHAR(255),
+ display_description VARCHAR(255),
+ availability_zone VARCHAR(255),
+ locked BOOLEAN,
+ os_type VARCHAR(255),
+ launched_on TEXT,
+ instance_type_id INTEGER,
+ vm_mode VARCHAR(255),
+ uuid VARCHAR(36),
+ architecture VARCHAR(255),
+ root_device_name VARCHAR(255),
+ access_ip_v4 VARCHAR(255),
+ access_ip_v6 VARCHAR(255),
+ config_drive VARCHAR(255),
+ task_state VARCHAR(255),
+ default_ephemeral_device VARCHAR(255),
+ default_swap_device VARCHAR(255),
+ progress INTEGER,
+ auto_disk_config BOOLEAN,
+ shutdown_terminate BOOLEAN,
+ disable_terminate BOOLEAN,
+ PRIMARY KEY (id),
+ CHECK (deleted IN (0, 1)),
+ CHECK (locked IN (0, 1)),
+ CHECK (auto_disk_config IN (0, 1)),
+ CHECK (shutdown_terminate IN (0, 1)),
+ CHECK (disable_terminate IN (0, 1))
+ );
+
+ CREATE INDEX project_id ON instances (project_id);
+ CREATE UNIQUE INDEX uuid ON instances (uuid);
+
+ -- copy from backup to new table with root_gb set to local_gb and
+ -- ephmeral_gb set to 0
+ INSERT INTO instances
+ SELECT created_at,
+ updated_at,
+ deleted_at,
+ deleted,
+ id,
+ internal_id,
+ user_id,
+ project_id,
+ image_ref,
+ kernel_id,
+ ramdisk_id,
+ server_name,
+ launch_index,
+ key_name,
+ key_data,
+ power_state,
+ vm_state,
+ memory_mb,
+ vcpus,
+ local_gb,
+ 0,
+ hostname,
+ host,
+ user_data,
+ reservation_id,
+ scheduled_at,
+ launched_at,
+ terminated_at,
+ display_name,
+ display_description,
+ availability_zone,
+ locked,
+ os_type,
+ launched_on,
+ instance_type_id,
+ vm_mode,
+ uuid,
+ architecture,
+ root_device_name,
+ access_ip_v4,
+ access_ip_v6,
+ config_drive,
+ task_state,
+ default_local_device,
+ default_swap_device,
+ progress,
+ auto_disk_config,
+ shutdown_terminate,
+ disable_terminate
+ FROM instances_backup;
+
+ DROP TABLE instances_backup;
+COMMIT;
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index 2dfc798b6..f7b9a555c 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -223,7 +223,8 @@ class Instance(BASE, NovaBase):
memory_mb = Column(Integer)
vcpus = Column(Integer)
- local_gb = Column(Integer)
+ root_gb = Column(Integer)
+ ephemeral_gb = Column(Integer)
hostname = Column(String(255))
host = Column(String(255)) # , ForeignKey('hosts.id'))
@@ -256,7 +257,7 @@ class Instance(BASE, NovaBase):
uuid = Column(String(36))
root_device_name = Column(String(255))
- default_local_device = Column(String(255), nullable=True)
+ default_ephemeral_device = Column(String(255), nullable=True)
default_swap_device = Column(String(255), nullable=True)
config_drive = Column(String(255))
@@ -339,7 +340,8 @@ class InstanceTypes(BASE, NovaBase):
name = Column(String(255), unique=True)
memory_mb = Column(Integer)
vcpus = Column(Integer)
- local_gb = Column(Integer)
+ root_gb = Column(Integer)
+ ephemeral_gb = Column(Integer)
flavorid = Column(String(255), unique=True)
swap = Column(Integer, nullable=False, default=0)
rxtx_factor = Column(Float, nullable=False, default=1)
diff --git a/nova/flags.py b/nova/flags.py
index 4345b4777..855ef8ed0 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -261,7 +261,7 @@ DEFINE_string('my_ip', _get_my_ip(), 'host ip address')
DEFINE_list('region_list',
[],
'list of region=fqdn pairs separated by commas')
-DEFINE_string('connection_type', 'libvirt', 'libvirt, xenapi or fake')
+DEFINE_string('connection_type', None, 'libvirt, xenapi or fake')
DEFINE_string('aws_access_key_id', 'admin', 'AWS Access ID')
DEFINE_string('aws_secret_access_key', 'admin', 'AWS Access Key')
# NOTE(sirp): my_ip interpolation doesn't work within nested structures
@@ -428,6 +428,10 @@ DEFINE_bool('start_guests_on_host_boot', False,
'Whether to restart guests when the host reboots')
DEFINE_bool('resume_guests_state_on_host_boot', False,
'Whether to start guests, that was running before the host reboot')
+DEFINE_string('default_ephemeral_format',
+ None,
+ 'The default format a ephemeral_volume will be formatted '
+ 'with on creation.')
DEFINE_string('root_helper', 'sudo',
'Command prefix to use for running commands as root')
diff --git a/nova/scheduler/host_manager.py b/nova/scheduler/host_manager.py
index 6daeaf977..88ca3da61 100644
--- a/nova/scheduler/host_manager.py
+++ b/nova/scheduler/host_manager.py
@@ -115,7 +115,7 @@ class HostState(object):
def consume_from_instance(self, instance):
"""Update information about a host from instance info."""
- disk_mb = instance['local_gb'] * 1024
+ disk_mb = (instance['root_gb'] + instance['ephemeral_gb']) * 1024
ram_mb = instance['memory_mb']
vcpus = instance['vcpus']
self.free_ram_mb -= ram_mb
diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py
index 498759530..99f51fab2 100644
--- a/nova/scheduler/manager.py
+++ b/nova/scheduler/manager.py
@@ -169,17 +169,21 @@ class SchedulerManager(manager.Manager):
project_ids = [i['project_id'] for i in instance_refs]
project_ids = list(set(project_ids))
for project_id in project_ids:
- vcpus = [i['vcpus'] for i in instance_refs \
- if i['project_id'] == project_id]
+ vcpus = [i['vcpus'] for i in instance_refs
+ if i['project_id'] == project_id]
- mem = [i['memory_mb'] for i in instance_refs \
- if i['project_id'] == project_id]
+ mem = [i['memory_mb'] for i in instance_refs
+ if i['project_id'] == project_id]
- disk = [i['local_gb'] for i in instance_refs \
- if i['project_id'] == project_id]
+ root = [i['root_gb'] for i in instance_refs
+ if i['project_id'] == project_id]
- usage[project_id] = {'vcpus': reduce(lambda x, y: x + y, vcpus),
- 'memory_mb': reduce(lambda x, y: x + y, mem),
- 'local_gb': reduce(lambda x, y: x + y, disk)}
+ ephemeral = [i['ephemeral_gb'] for i in instance_refs
+ if i['project_id'] == project_id]
+
+ usage[project_id] = {'vcpus': sum(vcpus),
+ 'memory_mb': sum(mem),
+ 'root_gb': sum(root),
+ 'ephemeral_gb': sum(ephemeral)}
return {'resource': resource, 'usage': usage}
diff --git a/nova/tests/api/ec2/test_admin.py b/nova/tests/api/ec2/test_admin.py
index 0277e8278..2b4e463ee 100644
--- a/nova/tests/api/ec2/test_admin.py
+++ b/nova/tests/api/ec2/test_admin.py
@@ -123,7 +123,7 @@ class AdminTestCase(test.TestCase):
inst = {'name': 'this_inst',
'memory_mb': 1024,
'vcpus': 2,
- 'local_gb': 500,
+ 'root_gb': 500,
'flavorid': 1}
expected_inst_dict = {'name': 'this_inst',
diff --git a/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py b/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py
index 3ff12bf3a..b41773824 100644
--- a/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py
+++ b/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py
@@ -34,7 +34,8 @@ FLAGS = flags.FLAGS
SERVERS = 5
TENANTS = 2
HOURS = 24
-LOCAL_GB = 10
+ROOT_GB = 10
+EPHEMERAL_GB = 20
MEMORY_MB = 1024
VCPUS = 2
STOP = datetime.datetime.utcnow()
@@ -44,7 +45,8 @@ START = STOP - datetime.timedelta(hours=HOURS)
def fake_instance_type_get(self, context, instance_type_id):
return {'id': 1,
'vcpus': VCPUS,
- 'local_gb': LOCAL_GB,
+ 'root_gb': ROOT_GB,
+ 'ephemeral_gb': EPHEMERAL_GB,
'memory_mb': MEMORY_MB,
'name':
'fakeflavor'}
@@ -107,7 +109,7 @@ class SimpleTenantUsageTest(test.TestCase):
self.assertEqual(int(usages[i]['total_hours']),
SERVERS * HOURS)
self.assertEqual(int(usages[i]['total_local_gb_usage']),
- SERVERS * LOCAL_GB * HOURS)
+ SERVERS * (ROOT_GB + EPHEMERAL_GB) * HOURS)
self.assertEqual(int(usages[i]['total_memory_mb_usage']),
SERVERS * MEMORY_MB * HOURS)
self.assertEqual(int(usages[i]['total_vcpus_usage']),
diff --git a/nova/tests/api/openstack/compute/test_consoles.py b/nova/tests/api/openstack/compute/test_consoles.py
index 00239d99c..ac0499e84 100644
--- a/nova/tests/api/openstack/compute/test_consoles.py
+++ b/nova/tests/api/openstack/compute/test_consoles.py
@@ -101,7 +101,7 @@ def stub_instance(id, user_id='fake', project_id='fake', host=None,
"task_state": task_state,
"memory_mb": 0,
"vcpus": 0,
- "local_gb": 0,
+ "root_gb": 0,
"hostname": "",
"host": host,
"instance_type": {},
diff --git a/nova/tests/api/openstack/compute/test_flavors.py b/nova/tests/api/openstack/compute/test_flavors.py
index 672f5b8eb..8ad5eea0c 100644
--- a/nova/tests/api/openstack/compute/test_flavors.py
+++ b/nova/tests/api/openstack/compute/test_flavors.py
@@ -38,13 +38,13 @@ FAKE_FLAVORS = {
"flavorid": '1',
"name": 'flavor 1',
"memory_mb": '256',
- "local_gb": '10'
+ "root_gb": '10'
},
'flavor 2': {
"flavorid": '2',
"name": 'flavor 2',
"memory_mb": '512',
- "local_gb": '20'
+ "root_gb": '20'
},
}
@@ -63,7 +63,7 @@ def fake_instance_type_get_all(inactive=False, filters=None):
for (flavor_name, flavor) in FAKE_FLAVORS.items():
if reject_min('memory_mb', 'min_memory_mb'):
continue
- elif reject_min('local_gb', 'min_local_gb'):
+ elif reject_min('root_gb', 'min_root_gb'):
continue
output[flavor_name] = flavor
diff --git a/nova/tests/api/openstack/compute/test_server_actions.py b/nova/tests/api/openstack/compute/test_server_actions.py
index 08612adb1..6c38c3fad 100644
--- a/nova/tests/api/openstack/compute/test_server_actions.py
+++ b/nova/tests/api/openstack/compute/test_server_actions.py
@@ -100,7 +100,7 @@ def stub_instance(id, metadata=None, image_ref="10", flavor_id="1",
"task_state": task_state,
"memory_mb": 0,
"vcpus": 0,
- "local_gb": 0,
+ "root_gb": 0,
"hostname": "",
"host": "fake_host",
"instance_type": dict(inst_type),
diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py
index 103f3678c..b5966b460 100644
--- a/nova/tests/api/openstack/fakes.py
+++ b/nova/tests/api/openstack/fakes.py
@@ -514,7 +514,8 @@ def stub_instance(id, user_id='fake', project_id='fake', host=None,
"power_state": power_state,
"memory_mb": 0,
"vcpus": 0,
- "local_gb": 0,
+ "root_gb": 0,
+ "ephemeral_gb": 0,
"hostname": "",
"host": host,
"instance_type": dict(inst_type),
diff --git a/nova/tests/db/fakes.py b/nova/tests/db/fakes.py
index f24f020a6..9f89aaba8 100644
--- a/nova/tests/db/fakes.py
+++ b/nova/tests/db/fakes.py
@@ -349,29 +349,33 @@ def stub_out_db_instance_api(stubs, injected=True):
'm1.tiny': dict(id=2,
memory_mb=512,
vcpus=1,
- local_gb=0,
+ root_gb=0,
+ ephemeral_gb=10,
flavorid=1,
rxtx_cap=1,
swap=0),
'm1.small': dict(id=5,
memory_mb=2048,
vcpus=1,
- local_gb=20,
+ root_gb=20,
+ ephemeral_gb=0,
flavorid=2,
rxtx_cap=2,
- swap=0),
+ swap=1024),
'm1.medium':
dict(id=1,
memory_mb=4096,
vcpus=2,
- local_gb=40,
+ root_gb=40,
+ ephemeral_gb=40,
flavorid=3,
rxtx_cap=3,
swap=0),
'm1.large': dict(id=3,
memory_mb=8192,
vcpus=4,
- local_gb=80,
+ root_gb=80,
+ ephemeral_gb=80,
flavorid=4,
rxtx_cap=4,
swap=0),
@@ -379,7 +383,8 @@ def stub_out_db_instance_api(stubs, injected=True):
dict(id=4,
memory_mb=16384,
vcpus=8,
- local_gb=160,
+ root_gb=160,
+ ephemeral_gb=160,
flavorid=5,
rxtx_cap=5,
swap=0)}
diff --git a/nova/tests/fake_network.py b/nova/tests/fake_network.py
index 29bb793ce..2c950c143 100644
--- a/nova/tests/fake_network.py
+++ b/nova/tests/fake_network.py
@@ -155,7 +155,7 @@ flavor = {'id': 0,
'name': 'fake_flavor',
'memory_mb': 2048,
'vcpus': 2,
- 'local_gb': 10,
+ 'root_gb': 10,
'flavor_id': 0,
'swap': 0,
'rxtx_factor': 3}
diff --git a/nova/tests/scheduler/fakes.py b/nova/tests/scheduler/fakes.py
index 94287bac3..d2de4ba40 100644
--- a/nova/tests/scheduler/fakes.py
+++ b/nova/tests/scheduler/fakes.py
@@ -40,14 +40,20 @@ COMPUTE_NODES = [
]
INSTANCES = [
- dict(local_gb=512, memory_mb=512, vcpus=1, host='host1'),
- dict(local_gb=512, memory_mb=512, vcpus=1, host='host2'),
- dict(local_gb=512, memory_mb=512, vcpus=1, host='host2'),
- dict(local_gb=1024, memory_mb=1024, vcpus=1, host='host3'),
+ dict(root_gb=512, ephemeral_gb=0, memory_mb=512, vcpus=1,
+ host='host1'),
+ dict(root_gb=512, ephemeral_gb=0, memory_mb=512, vcpus=1,
+ host='host2'),
+ dict(root_gb=512, ephemeral_gb=0, memory_mb=512, vcpus=1,
+ host='host2'),
+ dict(root_gb=1024, ephemeral_gb=0, memory_mb=1024, vcpus=1,
+ host='host3'),
# Broken host
- dict(local_gb=1024, memory_mb=1024, vcpus=1, host=None),
+ dict(root_gb=1024, ephemeral_gb=0, memory_mb=1024, vcpus=1,
+ host=None),
# No matching host
- dict(local_gb=1024, memory_mb=1024, vcpus=1, host='host5'),
+ dict(root_gb=1024, ephemeral_gb=0, memory_mb=1024, vcpus=1,
+ host='host5'),
]
diff --git a/nova/tests/scheduler/test_distributed_scheduler.py b/nova/tests/scheduler/test_distributed_scheduler.py
index 8e586ac8b..426da044f 100644
--- a/nova/tests/scheduler/test_distributed_scheduler.py
+++ b/nova/tests/scheduler/test_distributed_scheduler.py
@@ -104,7 +104,8 @@ class DistributedSchedulerTestCase(test.TestCase):
self.stubs.Set(db, 'zone_get_all', fake_zone_get_all)
fake_context = context.RequestContext('user', 'project')
- request_spec = {'instance_type': {'memory_mb': 1, 'local_gb': 1},
+ request_spec = {'instance_type': {'memory_mb': 1, 'root_gb': 1,
+ 'ephemeral_gb': 0},
'instance_properties': {'project_id': 1}}
self.assertRaises(exception.NoValidHost, sched.schedule_run_instance,
fake_context, request_spec)
@@ -219,7 +220,8 @@ class DistributedSchedulerTestCase(test.TestCase):
self.stubs.Set(sched, '_call_zone_method', fake_call_zone_method)
request_spec = {'num_instances': 10,
- 'instance_type': {'memory_mb': 512, 'local_gb': 512},
+ 'instance_type': {'memory_mb': 512, 'root_gb': 512,
+ 'ephemeral_gb': 0},
'instance_properties': {'project_id': 1}}
self.mox.ReplayAll()
weighted_hosts = sched._schedule(fake_context, 'compute',
@@ -260,10 +262,12 @@ class DistributedSchedulerTestCase(test.TestCase):
self.stubs.Set(sched, '_call_zone_method', fake_call_zone_method)
request_spec = {'num_instances': 10,
- 'instance_type': {'memory_mb': 512, 'local_gb': 512},
+ 'instance_type': {'memory_mb': 512, 'root_gb': 512,
+ 'ephemeral_gb': 256},
'instance_properties': {'project_id': 1,
'memory_mb': 512,
- 'local_gb': 512,
+ 'root_gb': 512,
+ 'ephemeral_gb': 0,
'vcpus': 1}}
filter_properties = {'local_zone_only': True}
self.mox.ReplayAll()
diff --git a/nova/tests/scheduler/test_host_filters.py b/nova/tests/scheduler/test_host_filters.py
index 5e3ff2601..d03d224d1 100644
--- a/nova/tests/scheduler/test_host_filters.py
+++ b/nova/tests/scheduler/test_host_filters.py
@@ -267,7 +267,8 @@ class HostFiltersTestCase(test.TestCase):
def test_json_filter_passes(self):
filt_cls = filters.JsonFilter()
filter_properties = {'instance_type': {'memory_mb': 1024,
- 'local_gb': 200},
+ 'root_gb': 200,
+ 'ephemeral_gb': 0},
'query': self.json_query}
capabilities = {'enabled': True}
host = fakes.FakeHostState('host1', 'compute',
@@ -279,7 +280,8 @@ class HostFiltersTestCase(test.TestCase):
def test_json_filter_passes_with_no_query(self):
filt_cls = filters.JsonFilter()
filter_properties = {'instance_type': {'memory_mb': 1024,
- 'local_gb': 200}}
+ 'root_gb': 200,
+ 'ephemeral_gb': 0}}
capabilities = {'enabled': True}
host = fakes.FakeHostState('host1', 'compute',
{'free_ram_mb': 0,
@@ -290,7 +292,8 @@ class HostFiltersTestCase(test.TestCase):
def test_json_filter_fails_on_memory(self):
filt_cls = filters.JsonFilter()
filter_properties = {'instance_type': {'memory_mb': 1024,
- 'local_gb': 200},
+ 'root_gb': 200,
+ 'ephemeral_gb': 0},
'query': self.json_query}
capabilities = {'enabled': True}
host = fakes.FakeHostState('host1', 'compute',
@@ -302,7 +305,8 @@ class HostFiltersTestCase(test.TestCase):
def test_json_filter_fails_on_disk(self):
filt_cls = filters.JsonFilter()
filter_properties = {'instance_type': {'memory_mb': 1024,
- 'local_gb': 200},
+ 'root_gb': 200,
+ 'ephemeral_gb': 0},
'query': self.json_query}
capabilities = {'enabled': True}
host = fakes.FakeHostState('host1', 'compute',
@@ -318,7 +322,8 @@ class HostFiltersTestCase(test.TestCase):
['>=', '$free_disk_mb', 200 * 1024],
'$capabilities.enabled'])
filter_properties = {'instance_type': {'memory_mb': 1024,
- 'local_gb': 200},
+ 'root_gb': 200,
+ 'ephemeral_gb': 0},
'query': json_query}
capabilities = {'enabled': False}
host = fakes.FakeHostState('host1', 'compute',
diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py
index 73b538768..26e1aaaba 100644
--- a/nova/tests/scheduler/test_scheduler.py
+++ b/nova/tests/scheduler/test_scheduler.py
@@ -167,15 +167,18 @@ class SchedulerManagerTestCase(test.TestCase):
instances = [{'project_id': 'project1',
'vcpus': 1,
'memory_mb': 128,
- 'local_gb': 128},
+ 'root_gb': 128,
+ 'ephemeral_gb': 0},
{'project_id': 'project1',
'vcpus': 2,
'memory_mb': 256,
- 'local_gb': 384},
+ 'root_gb': 384,
+ 'ephemeral_gb': 0},
{'project_id': 'project2',
'vcpus': 2,
'memory_mb': 256,
- 'local_gb': 256}]
+ 'root_gb': 256,
+ 'ephemeral_gb': 0}]
self.mox.StubOutWithMock(db, 'service_get_all_compute_by_host')
self.mox.StubOutWithMock(db, 'instance_get_all_by_host')
@@ -188,15 +191,17 @@ class SchedulerManagerTestCase(test.TestCase):
result = self.manager.show_host_resources(self.context, host)
expected = {'usage': {'project1': {'memory_mb': 384,
'vcpus': 3,
- 'local_gb': 512},
+ 'root_gb': 512,
+ 'ephemeral_gb': 0},
'project2': {'memory_mb': 256,
'vcpus': 2,
- 'local_gb': 256}},
- 'resource': {'vcpus_used': 2,
+ 'root_gb': 256,
+ 'ephemeral_gb': 0}},
+ 'resource': {'vcpus': 4,
+ 'vcpus_used': 2,
+ 'local_gb': 1024,
'local_gb_used': 512,
'memory_mb': 1024,
- 'vcpus': 4,
- 'local_gb': 1024,
'memory_mb_used': 512}}
self.assertDictMatch(result, expected)
@@ -358,7 +363,8 @@ class SchedulerTestCase(test.TestCase):
'volumes': [volume1, volume2],
'power_state': power_state.RUNNING,
'memory_mb': 1024,
- 'local_gb': 1024}
+ 'root_gb': 1024,
+ 'ephemeral_gb': 0}
def test_live_migration_basic(self):
"""Test basic schedule_live_migration functionality"""
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index 83a41250c..f416e4a51 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -151,6 +151,8 @@ class BaseTestCase(test.TestCase):
type_id = instance_types.get_instance_type_by_name(type_name)['id']
inst['instance_type_id'] = type_id
inst['ami_launch_index'] = 0
+ inst['root_gb'] = 0
+ inst['ephemeral_gb'] = 0
inst.update(params)
return db.instance_create(self.context, inst)
@@ -168,7 +170,8 @@ class BaseTestCase(test.TestCase):
inst['name'] = 'm1.small'
inst['memory_mb'] = '1024'
inst['vcpus'] = '1'
- inst['local_gb'] = '20'
+ inst['root_gb'] = '20'
+ inst['ephemeral_gb'] = '10'
inst['flavorid'] = '1'
inst['swap'] = '2048'
inst['rxtx_factor'] = 1
@@ -1458,7 +1461,7 @@ class ComputeAPITestCase(BaseTestCase):
"""Test an instance type with too little disk space"""
inst_type = instance_types.get_default_instance_type()
- inst_type['local_gb'] = 1
+ inst_type['root_gb'] = 1
def fake_show(*args):
img = copy(self.fake_image)
@@ -1470,7 +1473,7 @@ class ComputeAPITestCase(BaseTestCase):
self.compute_api.create, self.context, inst_type, None)
# Now increase the inst_type disk space and make sure all is fine.
- inst_type['local_gb'] = 2
+ inst_type['root_gb'] = 2
(refs, resv_id) = self.compute_api.create(self.context,
inst_type, None)
db.instance_destroy(self.context, refs[0]['id'])
@@ -1479,7 +1482,7 @@ class ComputeAPITestCase(BaseTestCase):
"""Test an instance type with just enough ram and disk space"""
inst_type = instance_types.get_default_instance_type()
- inst_type['local_gb'] = 2
+ inst_type['root_gb'] = 2
inst_type['memory_mb'] = 2
def fake_show(*args):
@@ -1497,7 +1500,7 @@ class ComputeAPITestCase(BaseTestCase):
"""Test an instance type with no min_ram or min_disk"""
inst_type = instance_types.get_default_instance_type()
- inst_type['local_gb'] = 1
+ inst_type['root_gb'] = 1
inst_type['memory_mb'] = 1
def fake_show(*args):
@@ -1951,7 +1954,7 @@ class ComputeAPITestCase(BaseTestCase):
self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
instance = self._create_fake_instance()
- inst_params = {'local_gb': 2, 'memory_mb': 256}
+ inst_params = {'root_gb': 2, 'memory_mb': 256}
instance['instance_type'].update(inst_params)
image = self.compute_api.snapshot(self.context, instance, 'snap1',
@@ -2777,12 +2780,12 @@ class ComputeAPITestCase(BaseTestCase):
self.compute.terminate_instance(self.context, instance['uuid'])
def test_volume_size(self):
- local_size = 2
+ ephemeral_size = 2
swap_size = 3
- inst_type = {'local_gb': local_size, 'swap': swap_size}
+ inst_type = {'ephemeral_gb': ephemeral_size, 'swap': swap_size}
self.assertEqual(self.compute_api._volume_size(inst_type,
- 'ephemeral0'),
- local_size)
+ 'ephemeral0'),
+ ephemeral_size)
self.assertEqual(self.compute_api._volume_size(inst_type,
'ephemeral1'),
0)
diff --git a/nova/tests/test_compute_utils.py b/nova/tests/test_compute_utils.py
index 7ba03063f..71463fbc0 100644
--- a/nova/tests/test_compute_utils.py
+++ b/nova/tests/test_compute_utils.py
@@ -66,6 +66,8 @@ class UsageInfoTestCase(test.TestCase):
type_id = instance_types.get_instance_type_by_name('m1.tiny')['id']
inst['instance_type_id'] = type_id
inst['ami_launch_index'] = 0
+ inst['root_gb'] = 0
+ inst['ephemeral_gb'] = 0
inst.update(params)
return db.instance_create(self.context, inst)['id']
diff --git a/nova/tests/test_instance_types.py b/nova/tests/test_instance_types.py
index 2def43731..b0613c757 100644
--- a/nova/tests/test_instance_types.py
+++ b/nova/tests/test_instance_types.py
@@ -68,13 +68,14 @@ class InstanceTypeTestCase(test.TestCase):
original_list = instance_types.get_all_types()
# create new type and make sure values stick
- inst_type = instance_types.create(name, 256, 1, 120, flavorid)
+ inst_type = instance_types.create(name, 256, 1, 120, 100, flavorid)
inst_type_id = inst_type['id']
self.assertEqual(inst_type['flavorid'], flavorid)
self.assertEqual(inst_type['name'], name)
self.assertEqual(inst_type['memory_mb'], 256)
self.assertEqual(inst_type['vcpus'], 1)
- self.assertEqual(inst_type['local_gb'], 120)
+ self.assertEqual(inst_type['root_gb'], 120)
+ self.assertEqual(inst_type['ephemeral_gb'], 100)
self.assertEqual(inst_type['swap'], 0)
self.assertEqual(inst_type['rxtx_factor'], 1)
@@ -108,22 +109,23 @@ class InstanceTypeTestCase(test.TestCase):
def test_invalid_create_args_should_fail(self):
"""Ensures that instance type creation fails with invalid args"""
invalid_sigs = [
- (('Zero memory', 0, 1, 10, 'flavor1'), {}),
- (('Negative memory', -256, 1, 10, 'flavor1'), {}),
- (('Non-integer memory', 'asdf', 1, 10, 'flavor1'), {}),
+ (('Zero memory', 0, 1, 10, 20, 'flavor1'), {}),
+ (('Negative memory', -256, 1, 10, 20, 'flavor1'), {}),
+ (('Non-integer memory', 'asdf', 1, 10, 20, 'flavor1'), {}),
- (('Zero vcpus', 256, 0, 10, 'flavor1'), {}),
- (('Negative vcpus', 256, -1, 10, 'flavor1'), {}),
- (('Non-integer vcpus', 256, 'a', 10, 'flavor1'), {}),
+ (('Zero vcpus', 256, 0, 10, 20, 'flavor1'), {}),
+ (('Negative vcpus', 256, -1, 10, 20, 'flavor1'), {}),
+ (('Non-integer vcpus', 256, 'a', 10, 20, 'flavor1'), {}),
- (('Negative storage', 256, 1, -1, 'flavor1'), {}),
- (('Non-integer storage', 256, 1, 'a', 'flavor1'), {}),
+ (('Negative storage', 256, 1, -1, 20, 'flavor1'), {}),
+ (('Non-integer storage', 256, 1, 'a', 20, 'flavor1'), {}),
- (('Negative swap', 256, 1, 10, 'flavor1'), {'swap': -1}),
- (('Non-integer swap', 256, 1, 10, 'flavor1'), {'swap': -1}),
+ (('Negative swap', 256, 1, 10, 20, 'flavor1'), {'swap': -1}),
+ (('Non-integer swap', 256, 1, 10, 20, 'flavor1'), {'swap': -1}),
- (('Negative rxtx_factor', 256, 1, 10, 'f1'), {'rxtx_factor': -1}),
- (('Non-integer rxtx_factor', 256, 1, 10, 'f1'),
+ (('Negative rxtx_factor', 256, 1, 10, 20, 'f1'),
+ {'rxtx_factor': -1}),
+ (('Non-integer rxtx_factor', 256, 1, 10, 20, 'f1'),
{'rxtx_factor': "d"}),
]
@@ -140,18 +142,18 @@ class InstanceTypeTestCase(test.TestCase):
def test_duplicate_names_fail(self):
"""Ensures that name duplicates raise ApiError"""
name = 'some_name'
- instance_types.create(name, 256, 1, 120, 'flavor1')
+ instance_types.create(name, 256, 1, 120, 200, 'flavor1')
self.assertRaises(exception.ApiError,
instance_types.create,
- name, "256", 1, 120, 'flavor2')
+ name, "256", 1, 120, 200, 'flavor2')
def test_duplicate_flavorids_fail(self):
"""Ensures that flavorid duplicates raise ApiError"""
flavorid = 'flavor1'
- instance_types.create('name one', 256, 1, 120, flavorid)
+ instance_types.create('name one', 256, 1, 120, 200, flavorid)
self.assertRaises(exception.ApiError,
instance_types.create,
- 'name two', 256, 1, 120, flavorid)
+ 'name two', 256, 1, 120, 200, flavorid)
def test_will_not_destroy_with_no_name(self):
"""Ensure destroy sad path of no name raises error"""
@@ -239,14 +241,14 @@ class InstanceTypeFilteringTest(test.TestCase):
expected = ['m1.large', 'm1.medium', 'm1.small', 'm1.xlarge']
self.assertFilterResults(filters, expected)
- def test_min_local_gb_filter(self):
+ def test_min_root_gb_filter(self):
"""Exclude everything but large and xlarge which have >= 80 GB"""
- filters = dict(min_local_gb=80)
+ filters = dict(min_root_gb=80)
expected = ['m1.large', 'm1.xlarge']
self.assertFilterResults(filters, expected)
- def test_min_memory_mb_AND_local_gb_filter(self):
+ def test_min_memory_mb_AND_root_gb_filter(self):
"""Exclude everything but large and xlarge which have >= 80 GB"""
- filters = dict(min_memory_mb=16384, min_local_gb=80)
+ filters = dict(min_memory_mb=16384, min_root_gb=80)
expected = ['m1.xlarge']
self.assertFilterResults(filters, expected)
diff --git a/nova/tests/test_instance_types_extra_specs.py b/nova/tests/test_instance_types_extra_specs.py
index 999e5a126..8f4ea89d3 100644
--- a/nova/tests/test_instance_types_extra_specs.py
+++ b/nova/tests/test_instance_types_extra_specs.py
@@ -29,7 +29,8 @@ class InstanceTypeExtraSpecsTestCase(test.TestCase):
values = dict(name="cg1.4xlarge",
memory_mb=22000,
vcpus=8,
- local_gb=1690,
+ root_gb=1690,
+ ephemeral_gb=2000,
flavorid=105)
specs = dict(cpu_arch="x86_64",
cpu_model="Nehalem",
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
index 894ac583e..2dfa277c5 100644
--- a/nova/tests/test_libvirt.py
+++ b/nova/tests/test_libvirt.py
@@ -303,7 +303,8 @@ class LibvirtConnTestCase(test.TestCase):
'project_id': 'fake',
'bridge': 'br101',
'image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
- 'local_gb': 20,
+ 'root_gb': 10,
+ 'ephemeral_gb': 20,
'instance_type_id': '5'} # m1.small
def create_fake_libvirt_mock(self, **kwargs):
@@ -1625,7 +1626,8 @@ class NWFilterTestCase(test.TestCase):
inst['name'] = 'm1.small'
inst['memory_mb'] = '1024'
inst['vcpus'] = '1'
- inst['local_gb'] = '20'
+ inst['root_gb'] = '10'
+ inst['ephemeral_gb'] = '20'
inst['flavorid'] = '1'
inst['swap'] = '2048'
inst['rxtx_factor'] = 1
diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py
index 6f2f1161b..3c267b8b0 100644
--- a/nova/tests/test_quota.py
+++ b/nova/tests/test_quota.py
@@ -91,13 +91,13 @@ class QuotaTestCase(test.TestCase):
def _get_instance_type(self, name):
instance_types = {
- 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1),
- 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2),
+ 'm1.tiny': dict(memory_mb=512, vcpus=1, root_gb=0, flavorid=1),
+ 'm1.small': dict(memory_mb=2048, vcpus=1, root_gb=20, flavorid=2),
'm1.medium':
- dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3),
- 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4),
+ dict(memory_mb=4096, vcpus=2, root_gb=40, flavorid=3),
+ 'm1.large': dict(memory_mb=8192, vcpus=4, root_gb=80, flavorid=4),
'm1.xlarge':
- dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)}
+ dict(memory_mb=16384, vcpus=8, root_gb=160, flavorid=5)}
return instance_types[name]
def test_quota_overrides(self):
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 180400af4..c3730b3ca 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -107,7 +107,7 @@ class XenAPIVolumeTestCase(test.TestCase):
'image_ref': 1,
'kernel_id': 2,
'ramdisk_id': 3,
- 'local_gb': 20,
+ 'root_gb': 20,
'instance_type_id': '3', # m1.large
'os_type': 'linux',
'architecture': 'x86-64'}
@@ -414,7 +414,7 @@ class XenAPIVMTestCase(test.TestCase):
'image_ref': image_ref,
'kernel_id': kernel_id,
'ramdisk_id': ramdisk_id,
- 'local_gb': 20,
+ 'root_gb': 20,
'instance_type_id': instance_type_id,
'os_type': os_type,
'hostname': hostname,
@@ -700,7 +700,7 @@ class XenAPIVMTestCase(test.TestCase):
'image_ref': 1,
'kernel_id': 2,
'ramdisk_id': 3,
- 'local_gb': 20,
+ 'root_gb': 20,
'instance_type_id': '3', # m1.large
'os_type': 'linux',
'architecture': 'x86-64'}
@@ -797,7 +797,7 @@ class XenAPIMigrateInstance(test.TestCase):
'image_ref': 1,
'kernel_id': None,
'ramdisk_id': None,
- 'local_gb': 5,
+ 'root_gb': 5,
'instance_type_id': '3', # m1.large
'os_type': 'linux',
'architecture': 'x86-64'}
@@ -874,7 +874,7 @@ class XenAPIMigrateInstance(test.TestCase):
self.fake_finish_revert_migration_called = True
self.stubs.Set(stubs.FakeSessionForMigrationTests,
- "VDI_resize_online", fake_vdi_resize)
+ "VDI_resize_online", fake_vdi_resize)
self.stubs.Set(vmops.VMOps, '_start', fake_vm_start)
self.stubs.Set(vmops.VMOps, 'finish_revert_migration',
fake_finish_revert_migration)
@@ -889,7 +889,7 @@ class XenAPIMigrateInstance(test.TestCase):
'gateway_v6': 'dead:beef::1',
'ip6s': [{'enabled': '1',
'ip': 'dead:beef::dcad:beff:feef:0',
- 'netmask': '64'}],
+ 'netmask': '64'}],
'ips': [{'enabled': '1',
'ip': '192.168.0.100',
'netmask': '255.255.255.0'}],
@@ -917,9 +917,9 @@ class XenAPIMigrateInstance(test.TestCase):
def fake_vdi_resize(*args, **kwargs):
self.called = True
- self.stubs.Set(stubs.FakeSessionForMigrationTests,
- "VDI_resize_online", fake_vdi_resize)
self.stubs.Set(vmops.VMOps, '_start', fake_vm_start)
+ self.stubs.Set(stubs.FakeSessionForMigrationTests,
+ "VDI_resize_online", fake_vdi_resize)
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
stubs.stubout_loopingcall_start(self.stubs)
@@ -949,14 +949,14 @@ class XenAPIMigrateInstance(test.TestCase):
tiny_type_id = \
instance_types.get_instance_type_by_name('m1.tiny')['id']
self.instance_values.update({'instance_type_id': tiny_type_id,
- 'local_gb': 0})
+ 'root_gb': 0})
instance = db.instance_create(self.context, self.instance_values)
def fake_vdi_resize(*args, **kwargs):
raise Exception("This shouldn't be called")
self.stubs.Set(stubs.FakeSessionForMigrationTests,
- "VDI_resize_online", fake_vdi_resize)
+ "VDI_resize_online", fake_vdi_resize)
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
stubs.stubout_loopingcall_start(self.stubs)
conn = xenapi_conn.get_connection(False)
@@ -1157,7 +1157,7 @@ class XenAPIAutoDiskConfigTestCase(test.TestCase):
'image_ref': 1,
'kernel_id': 2,
'ramdisk_id': 3,
- 'local_gb': 20,
+ 'root_gb': 20,
'instance_type_id': '3', # m1.large
'os_type': 'linux',
'architecture': 'x86-64'}
@@ -1226,6 +1226,87 @@ class XenAPIAutoDiskConfigTestCase(test.TestCase):
self.assertIsPartitionCalled(True)
+class XenAPIGenerateLocal(test.TestCase):
+ """Test generating of local disks, like swap and ephemeral"""
+ def setUp(self):
+ super(XenAPIGenerateLocal, self).setUp()
+ self.stubs = stubout.StubOutForTesting()
+ self.flags(target_host='127.0.0.1',
+ xenapi_connection_url='test_url',
+ xenapi_connection_password='test_pass',
+ xenapi_generate_swap=True,
+ firewall_driver='nova.virt.xenapi.firewall.'
+ 'Dom0IptablesFirewallDriver')
+ stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
+ db_fakes.stub_out_db_instance_api(self.stubs)
+ xenapi_fake.reset()
+ self.conn = xenapi_conn.get_connection(False)
+
+ self.user_id = 'fake'
+ self.project_id = 'fake'
+
+ self.instance_values = {'id': 1,
+ 'project_id': self.project_id,
+ 'user_id': self.user_id,
+ 'image_ref': 1,
+ 'kernel_id': 2,
+ 'ramdisk_id': 3,
+ 'root_gb': 20,
+ 'instance_type_id': '3', # m1.large
+ 'os_type': 'linux',
+ 'architecture': 'x86-64'}
+
+ self.context = context.RequestContext(self.user_id, self.project_id)
+
+ @classmethod
+ def fake_create_vbd(cls, session, vm_ref, vdi_ref, userdevice,
+ bootable=True):
+ pass
+
+ self.stubs.Set(volume_utils.VolumeHelper,
+ "create_vbd",
+ fake_create_vbd)
+
+ def assertCalled(self, instance):
+ disk_image_type = vm_utils.ImageType.DISK_VHD
+ vm_ref = "blah"
+ first_vdi_ref = "blah"
+ vdis = ["blah"]
+
+ self.called = False
+ self.conn._vmops._attach_disks(instance, disk_image_type,
+ vm_ref, first_vdi_ref, vdis)
+ self.assertTrue(self.called)
+
+ def test_generate_swap(self):
+ """Test swap disk generation."""
+ instance = db.instance_create(self.context, self.instance_values)
+ instance = db.instance_update(self.context, instance['id'],
+ {'instance_type_id': 5})
+
+ @classmethod
+ def fake_generate_swap(cls, *args, **kwargs):
+ self.called = True
+ self.stubs.Set(vm_utils.VMHelper, 'generate_swap',
+ fake_generate_swap)
+
+ self.assertCalled(instance)
+
+ def test_generate_ephemeral(self):
+ """Test ephemeral disk generation."""
+ instance = db.instance_create(self.context, self.instance_values)
+ instance = db.instance_update(self.context, instance['id'],
+ {'instance_type_id': 4})
+
+ @classmethod
+ def fake_generate_ephemeral(cls, *args):
+ self.called = True
+ self.stubs.Set(vm_utils.VMHelper, 'generate_ephemeral',
+ fake_generate_ephemeral)
+
+ self.assertCalled(instance)
+
+
class XenAPIBWUsageTestCase(test.TestCase):
def setUp(self):
super(XenAPIBWUsageTestCase, self).setUp()
diff --git a/nova/tests/utils.py b/nova/tests/utils.py
index f78ba3f2e..898eed76a 100644
--- a/nova/tests/utils.py
+++ b/nova/tests/utils.py
@@ -41,7 +41,8 @@ def get_test_instance_type(context=None):
test_instance_type = {'name': 'kinda.big',
'memory_mb': 2048,
'vcpus': 4,
- 'local_gb': 40,
+ 'root_gb': 40,
+ 'ephemeral_gb': 80,
'swap': 1024}
instance_type_ref = nova.db.instance_type_create(context,
@@ -57,6 +58,7 @@ def get_test_instance(context=None):
'basepath': '/some/path',
'bridge_name': 'br100',
'vcpus': 2,
+ 'root_gb': 10,
'project_id': 'fake',
'bridge': 'br101',
'image_ref': 'cedef40a-ed67-4d10-800e-17455edce175',
diff --git a/nova/tests/vmwareapi/db_fakes.py b/nova/tests/vmwareapi/db_fakes.py
index 599ba271c..1425a8751 100644
--- a/nova/tests/vmwareapi/db_fakes.py
+++ b/nova/tests/vmwareapi/db_fakes.py
@@ -31,13 +31,13 @@ def stub_out_db_instance_api(stubs):
"""Stubs out the db API for creating Instances."""
INSTANCE_TYPES = {
- 'm1.tiny': dict(memory_mb=512, vcpus=1, local_gb=0, flavorid=1),
- 'm1.small': dict(memory_mb=2048, vcpus=1, local_gb=20, flavorid=2),
+ 'm1.tiny': dict(memory_mb=512, vcpus=1, root_gb=0, flavorid=1),
+ 'm1.small': dict(memory_mb=2048, vcpus=1, root_gb=20, flavorid=2),
'm1.medium':
- dict(memory_mb=4096, vcpus=2, local_gb=40, flavorid=3),
- 'm1.large': dict(memory_mb=8192, vcpus=4, local_gb=80, flavorid=4),
+ dict(memory_mb=4096, vcpus=2, root_gb=40, flavorid=3),
+ 'm1.large': dict(memory_mb=8192, vcpus=4, root_gb=80, flavorid=4),
'm1.xlarge':
- dict(memory_mb=16384, vcpus=8, local_gb=160, flavorid=5)}
+ dict(memory_mb=16384, vcpus=8, root_gb=160, flavorid=5)}
class FakeModel(object):
"""Stubs out for model."""
@@ -76,7 +76,7 @@ def stub_out_db_instance_api(stubs):
'memory_mb': type_data['memory_mb'],
'vcpus': type_data['vcpus'],
'mac_addresses': [{'address': values['mac_address']}],
- 'local_gb': type_data['local_gb'],
+ 'root_gb': type_data['root_gb'],
}
return FakeModel(base_options)
diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py
index c0de0dd37..0c707e14e 100644
--- a/nova/tests/xenapi/stubs.py
+++ b/nova/tests/xenapi/stubs.py
@@ -289,10 +289,15 @@ def stub_out_vm_methods(stubs):
def fake_spawn_rescue(self, context, inst, network_info, image_meta):
inst._rescue = False
+ @classmethod
+ def fake_generate_ephemeral(cls, *args):
+ pass
+
stubs.Set(vmops.VMOps, "_shutdown", fake_shutdown)
stubs.Set(vmops.VMOps, "_acquire_bootlock", fake_acquire_bootlock)
stubs.Set(vmops.VMOps, "_release_bootlock", fake_release_bootlock)
stubs.Set(vmops.VMOps, "spawn_rescue", fake_spawn_rescue)
+ stubs.Set(vm_utils.VMHelper, 'generate_ephemeral', fake_generate_ephemeral)
class FakeSessionForVolumeTests(fake.SessionBase):
@@ -383,6 +388,10 @@ def stub_out_migration_methods(stubs):
def fake_reset_network(*args, **kwargs):
pass
+ @classmethod
+ def fake_generate_ephemeral(cls, *args):
+ pass
+
stubs.Set(vmops.VMOps, '_destroy', fake_destroy)
stubs.Set(vm_utils.VMHelper, 'scan_default_sr', fake_sr)
stubs.Set(vm_utils.VMHelper, 'scan_sr', fake_sr)
@@ -392,3 +401,4 @@ def stub_out_migration_methods(stubs):
stubs.Set(vm_utils.VMHelper, 'get_sr_path', fake_get_sr_path)
stubs.Set(vmops.VMOps, 'reset_network', fake_reset_network)
stubs.Set(vmops.VMOps, '_shutdown', fake_shutdown)
+ stubs.Set(vm_utils.VMHelper, 'generate_ephemeral', fake_generate_ephemeral)
diff --git a/nova/utils.py b/nova/utils.py
index 90e06bcb5..bd68c6966 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -409,7 +409,7 @@ def usage_from_instance(instance_ref, network_info=None, **kw):
instance_type=instance_ref['instance_type']['name'],
instance_type_id=instance_ref['instance_type_id'],
memory_mb=instance_ref['memory_mb'],
- disk_gb=instance_ref['local_gb'],
+ disk_gb=instance_ref['root_gb'] + instance_ref['ephemeral_gb'],
display_name=instance_ref['display_name'],
created_at=str(instance_ref['created_at']),
launched_at=str(instance_ref['launched_at']) \
diff --git a/nova/virt/disk/api.py b/nova/virt/disk/api.py
index 9a457a318..1cd697347 100644
--- a/nova/virt/disk/api.py
+++ b/nova/virt/disk/api.py
@@ -39,8 +39,6 @@ from nova.virt.disk import nbd
LOG = logging.getLogger('nova.compute.disk')
FLAGS = flags.FLAGS
-flags.DEFINE_integer('minimum_root_size', 1024 * 1024 * 1024 * 10,
- 'minimum size in bytes of root partition')
flags.DEFINE_string('injected_network_template',
utils.abspath('virt/interfaces.template'),
'Template file for injected network')
diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template
index 2dda60edb..5b464a2d8 100644
--- a/nova/virt/libvirt.xml.template
+++ b/nova/virt/libvirt.xml.template
@@ -79,11 +79,11 @@
<target dev='${root_device}' bus='${root_disk_bus}'/>
</disk>
#end if
- #if $getVar('local_device', False)
+ #if $getVar('ephemeral_device', False)
<disk type='file'>
<driver type='${driver_type}'/>
<source file='${basepath}/disk.local'/>
- <target dev='${local_device}' bus='${ephemeral_disk_bus}'/>
+ <target dev='${ephemeral_device}' bus='${ephemeral_disk_bus}'/>
</disk>
#end if
#for $eph in $ephemerals
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index bf46c7728..8ebaa276f 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -131,10 +131,6 @@ flags.DEFINE_list('libvirt_volume_drivers',
'rbd=nova.virt.libvirt.volume.LibvirtNetVolumeDriver',
'sheepdog=nova.virt.libvirt.volume.LibvirtNetVolumeDriver'],
'Libvirt handlers for remote volumes.')
-flags.DEFINE_string('default_local_format',
- None,
- 'The default format a local_volume will be formatted with '
- 'on creation.')
flags.DEFINE_bool('libvirt_use_virtio_for_bridges',
False,
'Use virtio for bridge interfaces')
@@ -195,7 +191,7 @@ class LibvirtConnection(driver.ComputeDriver):
else:
self._disk_prefix = disk_prefix_map.get(FLAGS.libvirt_type, 'vd')
self.default_root_device = self._disk_prefix + 'a'
- self.default_local_device = self._disk_prefix + 'b'
+ self.default_ephemeral_device = self._disk_prefix + 'b'
self.default_swap_device = self._disk_prefix + 'c'
@property
@@ -834,15 +830,15 @@ class LibvirtConnection(driver.ComputeDriver):
"""Create a blank image of specified size"""
if not fs_format:
- fs_format = FLAGS.default_local_format
+ fs_format = FLAGS.default_ephemeral_format
libvirt_utils.create_image('raw', target,
'%d%c' % (local_size, unit))
if fs_format:
libvirt_utils.mkfs(fs_format, target)
- def _create_ephemeral(self, target, local_size, fs_label, os_type):
- self._create_local(target, local_size)
+ def _create_ephemeral(self, target, ephemeral_size, fs_label, os_type):
+ self._create_local(target, ephemeral_size)
disk.mkfs(os_type, fs_label, target)
@staticmethod
@@ -901,13 +897,15 @@ class LibvirtConnection(driver.ComputeDriver):
project_id=inst['project_id'])
root_fname = hashlib.sha1(str(disk_images['image_id'])).hexdigest()
- size = FLAGS.minimum_root_size
+ size = inst['root_gb'] * 1024 * 1024 * 1024
inst_type_id = inst['instance_type_id']
inst_type = instance_types.get_instance_type(inst_type_id)
if inst_type['name'] == 'm1.tiny' or suffix == '.rescue':
size = None
root_fname += "_sm"
+ else:
+ root_fname += "_%d" % inst['root_gb']
if not self._volume_in_mapping(self.default_root_device,
block_device_info):
@@ -921,18 +919,18 @@ class LibvirtConnection(driver.ComputeDriver):
project_id=inst['project_id'],
size=size)
- local_gb = inst['local_gb']
- if local_gb and not self._volume_in_mapping(
- self.default_local_device, block_device_info):
+ ephemeral_gb = inst['ephemeral_gb']
+ if ephemeral_gb and not self._volume_in_mapping(
+ self.default_ephemeral_device, block_device_info):
fn = functools.partial(self._create_ephemeral,
fs_label='ephemeral0',
os_type=inst.os_type)
self._cache_image(fn=fn,
target=basepath('disk.local'),
fname="ephemeral_%s_%s_%s" %
- ("0", local_gb, inst.os_type),
+ ("0", ephemeral_gb, inst.os_type),
cow=FLAGS.use_cow_images,
- local_size=local_gb)
+ ephemeral_size=ephemeral_gb)
for eph in driver.block_device_info_get_ephemerals(block_device_info):
fn = functools.partial(self._create_ephemeral,
@@ -943,7 +941,7 @@ class LibvirtConnection(driver.ComputeDriver):
fname="ephemeral_%s_%s_%s" %
(eph['num'], eph['size'], inst.os_type),
cow=FLAGS.use_cow_images,
- local_size=eph['size'])
+ ephemeral_size=eph['size'])
swap_mb = 0
@@ -1119,14 +1117,14 @@ class LibvirtConnection(driver.ComputeDriver):
ebs_root = self._volume_in_mapping(self.default_root_device,
block_device_info)
- local_device = False
- if not (self._volume_in_mapping(self.default_local_device,
+ ephemeral_device = False
+ if not (self._volume_in_mapping(self.default_ephemeral_device,
block_device_info) or
0 in [eph['num'] for eph in
driver.block_device_info_get_ephemerals(
block_device_info)]):
- if instance['local_gb'] > 0:
- local_device = self.default_local_device
+ if instance['ephemeral_gb'] > 0:
+ ephemeral_device = self.default_ephemeral_device
ephemerals = []
for eph in driver.block_device_info_get_ephemerals(block_device_info):
@@ -1147,7 +1145,7 @@ class LibvirtConnection(driver.ComputeDriver):
'vif_type': FLAGS.libvirt_vif_type,
'nics': nics,
'ebs_root': ebs_root,
- 'local_device': local_device,
+ 'ephemeral_device': ephemeral_device,
'volumes': volumes,
'use_virtio_for_bridges':
FLAGS.libvirt_use_virtio_for_bridges,
@@ -1165,10 +1163,11 @@ class LibvirtConnection(driver.ComputeDriver):
nova_context.get_admin_context(), instance['id'],
{'root_device_name': '/dev/' + self.default_root_device})
- if local_device:
+ if ephemeral_device:
db.instance_update(
nova_context.get_admin_context(), instance['id'],
- {'default_local_device': '/dev/' + self.default_local_device})
+ {'default_ephemeral_device':
+ '/dev/' + self.default_ephemeral_device})
swap = driver.block_device_info_get_swap(block_device_info)
if driver.swap_is_usable(swap):
@@ -1790,7 +1789,7 @@ class LibvirtConnection(driver.ComputeDriver):
image_id=instance_ref['image_ref'],
user_id=instance_ref['user_id'],
project_id=instance_ref['project_id'],
- size=instance_ref['local_gb'])
+ size=instance_ref['ephemeral_gb'])
libvirt_utils.create_cow_image(backing_file, instance_disk)
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index 3c03d2a59..75ff011b3 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -393,7 +393,7 @@ class VMHelper(HelperBase):
# Resize partition and filesystem down
cls.auto_configure_disk(session=session,
vdi_ref=copy_ref,
- new_gb=instance_type['local_gb'])
+ new_gb=instance_type['root_gb'])
# Create new VDI
new_ref = cls.fetch_blank_disk(session,
@@ -401,7 +401,7 @@ class VMHelper(HelperBase):
new_uuid = session.call_xenapi('VDI.get_uuid', new_ref)
# Manually copy contents over
- virtual_size = instance_type['local_gb'] * 1024 * 1024 * 1024
+ virtual_size = instance_type['root_gb'] * 1024 * 1024 * 1024
_copy_partition(session, copy_ref, new_ref, 1, virtual_size)
return new_ref, new_uuid
@@ -411,7 +411,7 @@ class VMHelper(HelperBase):
@classmethod
def auto_configure_disk(cls, session, vdi_ref, new_gb):
"""Partition and resize FS to match the size specified by
- instance_types.local_gb.
+ instance_types.root_gb.
This is a fail-safe to prevent accidentally destroying data on a disk
erroneously marked as auto_disk_config=True.
@@ -437,48 +437,52 @@ class VMHelper(HelperBase):
_resize_part_and_fs(dev, start, old_sectors, new_sectors)
@classmethod
- def generate_swap(cls, session, instance, vm_ref, userdevice, swap_mb):
+ def _generate_disk(cls, session, instance, vm_ref, userdevice, name,
+ size_mb, fs_type):
"""
- Steps to programmatically generate swap:
+ Steps to programmatically generate a disk:
- 1. Create VDI of desired swap size
+ 1. Create VDI of desired size
2. Attach VDI to compute worker
- 3. Create swap partition
+ 3. Create partition
- 4. Create VBD between instance VM and swap VDI
+ 4. Create VBD between instance VM and VDI
"""
# 1. Create VDI
sr_ref = cls.safe_find_sr(session)
- name_label = instance.name + "-swap"
+ name_label = '%s-%s' % (instance.name, name)
ONE_MEG = 1024 * 1024
- virtual_size = swap_mb * ONE_MEG
+ virtual_size = size_mb * ONE_MEG
vdi_ref = cls.create_vdi(
session, sr_ref, name_label, virtual_size, read_only=False)
try:
# 2. Attach VDI to compute worker (VBD hotplug)
with vdi_attached_here(session, vdi_ref, read_only=False) as dev:
- # 3. Create swap partition
-
- # NOTE(jk0): We use a FAT32 filesystem for the Windows swap
- # partition because that is what parted supports.
- is_windows = instance.os_type == "windows"
- fs_type = "fat32" if is_windows else "linux-swap"
-
+ # 3. Create partition
dev_path = utils.make_dev_path(dev)
utils.execute('parted', '--script', dev_path,
'mklabel', 'msdos', run_as_root=True)
partition_start = 0
- partition_end = swap_mb
- utils.execute('parted', '--script', dev_path, 'mkpartfs',
- 'primary', fs_type,
+ partition_end = size_mb
+ utils.execute('parted', '--script', dev_path,
+ 'mkpart', 'primary',
str(partition_start),
str(partition_end),
run_as_root=True)
+ partition_path = utils.make_dev_path(dev, partition=1)
+
+ if fs_type == 'linux-swap':
+ utils.execute('mkswap', partition_path,
+ run_as_root=True)
+ elif fs_type is not None:
+ utils.execute('mkfs', '-t', fs_type, partition_path,
+ run_as_root=True)
+
# 4. Create VBD between instance VM and swap VDI
volume_utils.VolumeHelper.create_vbd(
session, vm_ref, vdi_ref, userdevice, bootable=False)
@@ -487,11 +491,28 @@ class VMHelper(HelperBase):
cls.destroy_vdi(session, vdi_ref)
@classmethod
+ def generate_swap(cls, session, instance, vm_ref, userdevice, swap_mb):
+ # NOTE(jk0): We use a FAT32 filesystem for the Windows swap
+ # partition because that is what parted supports.
+ is_windows = instance.os_type == "windows"
+ fs_type = "fat32" if is_windows else "linux-swap"
+
+ cls._generate_disk(session, instance, vm_ref, userdevice,
+ 'swap', swap_mb, fs_type)
+
+ @classmethod
+ def generate_ephemeral(cls, session, instance, vm_ref, userdevice,
+ size_gb):
+ cls._generate_disk(session, instance, vm_ref, userdevice,
+ 'ephemeral', size_gb * 1024,
+ FLAGS.default_ephemeral_format)
+
+ @classmethod
def fetch_blank_disk(cls, session, instance_type_id):
# Size the blank harddrive to suit the machine type:
one_gig = 1024 * 1024 * 1024
req_type = instance_types.get_instance_type(instance_type_id)
- req_size = req_type['local_gb']
+ req_size = req_type['root_gb']
LOG.debug("Creating blank HD of size %(req_size)d gigs"
% locals())
@@ -595,7 +616,7 @@ class VMHelper(HelperBase):
# refactor this to a common area
instance_type_id = instance['instance_type_id']
instance_type = instance_types.get_instance_type(instance_type_id)
- allowed_size_gb = instance_type['local_gb']
+ allowed_size_gb = instance_type['root_gb']
allowed_size_bytes = allowed_size_gb * 1024 * 1024 * 1024
LOG.debug(_("image_size_bytes=%(size_bytes)d, allowed_size_bytes="
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 606da3bcc..1309879b5 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -371,7 +371,7 @@ class VMOps(object):
instance.instance_type_id)
VMHelper.auto_configure_disk(session=self._session,
vdi_ref=first_vdi_ref,
- new_gb=instance_type['local_gb'])
+ new_gb=instance_type['root_gb'])
VolumeHelper.create_vbd(session=self._session, vm_ref=vm_ref,
vdi_ref=first_vdi_ref,
@@ -390,6 +390,13 @@ class VMOps(object):
swap_mb=swap_mb)
userdevice += 1
+ ephemeral_gb = instance_type['ephemeral_gb']
+ if ephemeral_gb:
+ VMHelper.generate_ephemeral(self._session, instance,
+ vm_ref, userdevice,
+ ephemeral_gb)
+ userdevice += 1
+
# Attach any other disks
for vdi in vdis[1:]:
if generate_swap and vdi['vdi_type'] == 'swap':
@@ -703,10 +710,10 @@ class VMOps(object):
sr_path = VMHelper.get_sr_path(self._session)
if instance['auto_disk_config'] and \
- instance['local_gb'] > instance_type['local_gb']:
+ instance['root_gb'] > instance_type['root_gb']:
# Resizing disk storage down
- old_gb = instance['local_gb']
- new_gb = instance_type['local_gb']
+ old_gb = instance['root_gb']
+ new_gb = instance_type['root_gb']
LOG.debug(_("Resizing down VDI %(cow_uuid)s from "
"%(old_gb)dGB to %(new_gb)dGB") % locals())
@@ -816,7 +823,7 @@ class VMOps(object):
"""Resize a running instance by changing its disk size."""
#TODO(mdietz): this will need to be adjusted for swap later
- new_disk_size = instance.local_gb * 1024 * 1024 * 1024
+ new_disk_size = instance.root_gb * 1024 * 1024 * 1024
if not new_disk_size:
return
@@ -828,7 +835,7 @@ class VMOps(object):
instance_name = instance.name
old_gb = virtual_size / (1024 * 1024 * 1024)
- new_gb = instance.local_gb
+ new_gb = instance.root_gb
if virtual_size < new_disk_size:
# Resize up. Simple VDI resize will do the trick