Add host and hypervisor_hostname to create servers
Adds the --host and --hypervisor-hostname options to the nova boot command and related python API bindings. Depends-On: https://review.opendev.org/#/c/645520/ Change-Id: If16d00b75f4d5f2b96aa6e3f32a973108049d928 Blueprint: add-host-and-hypervisor-hostname-flag-to-create-server
This commit is contained in:
parent
4bfcc1a9fa
commit
41c25881e6
@ -952,6 +952,8 @@ nova boot
|
||||
[--description <description>] [--tags <tags>]
|
||||
[--return-reservation-id]
|
||||
[--trusted-image-certificate-id <trusted-image-certificate-id>]
|
||||
[--host <host>]
|
||||
[--hypervisor-hostname <hypervisor-hostname>]
|
||||
<name>
|
||||
|
||||
Boot a new server.
|
||||
@ -1117,6 +1119,14 @@ quality of service support, microversion ``2.72`` is required.
|
||||
May be specified multiple times to pass multiple trusted image
|
||||
certificate IDs. (Supported by API versions '2.63' - '2.latest')
|
||||
|
||||
``--host <host>``
|
||||
Requested host to create servers. Admin only by default.
|
||||
(Supported by API versions '2.74' - '2.latest')
|
||||
|
||||
``--hypervisor-hostname <hypervisor-hostname>``
|
||||
Requested hypervisor hostname to create servers. Admin only by default.
|
||||
(Supported by API versions '2.74' - '2.latest')
|
||||
|
||||
.. _nova_cell-capacities:
|
||||
|
||||
nova cell-capacities
|
||||
|
@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
|
||||
# when client supported the max version, and bumped sequentially, otherwise
|
||||
# the client may break due to server side new version may include some
|
||||
# backward incompatible change.
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.73")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.74")
|
||||
|
@ -1743,3 +1743,99 @@ class ServersV273Test(ServersV268Test):
|
||||
self.assert_called('GET', '/servers/detail?locked=False')
|
||||
for s in sl:
|
||||
self.assertIsInstance(s, servers.Server)
|
||||
|
||||
|
||||
class ServersV274Test(ServersV273Test):
|
||||
|
||||
api_version = "2.74"
|
||||
|
||||
def test_create_server_with_host(self):
|
||||
self.cs.servers.create(
|
||||
name="My server",
|
||||
image=1,
|
||||
flavor=1,
|
||||
nics="auto",
|
||||
host="new-host"
|
||||
)
|
||||
self.assert_called('POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'imageRef': '1',
|
||||
'max_count': 1,
|
||||
'min_count': 1,
|
||||
'name': 'My server',
|
||||
'networks': 'auto',
|
||||
'host': 'new-host'
|
||||
}}
|
||||
)
|
||||
|
||||
def test_create_server_with_hypervisor_hostname(self):
|
||||
self.cs.servers.create(
|
||||
name="My server",
|
||||
image=1,
|
||||
flavor=1,
|
||||
nics="auto",
|
||||
hypervisor_hostname="new-host"
|
||||
)
|
||||
self.assert_called('POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'imageRef': '1',
|
||||
'max_count': 1,
|
||||
'min_count': 1,
|
||||
'name': 'My server',
|
||||
'networks': 'auto',
|
||||
'hypervisor_hostname': 'new-host'
|
||||
}}
|
||||
)
|
||||
|
||||
def test_create_server_with_host_and_hypervisor_hostname(self):
|
||||
self.cs.servers.create(
|
||||
name="My server",
|
||||
image=1,
|
||||
flavor=1,
|
||||
nics="auto",
|
||||
host="new-host",
|
||||
hypervisor_hostname="new-host"
|
||||
)
|
||||
self.assert_called('POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'imageRef': '1',
|
||||
'max_count': 1,
|
||||
'min_count': 1,
|
||||
'name': 'My server',
|
||||
'networks': 'auto',
|
||||
'host': 'new-host',
|
||||
'hypervisor_hostname': 'new-host'
|
||||
}}
|
||||
)
|
||||
|
||||
def test_create_server_with_host_pre_274_fails(self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.73')
|
||||
ex = self.assertRaises(exceptions.UnsupportedAttribute,
|
||||
self.cs.servers.create,
|
||||
name="My server", image=1, flavor=1,
|
||||
nics='auto', host="new-host")
|
||||
self.assertIn("'host' argument is only allowed since microversion "
|
||||
"2.74", six.text_type(ex))
|
||||
|
||||
def test_create_server_with_hypervisor_hostname_pre_274_fails(self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.73')
|
||||
ex = self.assertRaises(exceptions.UnsupportedAttribute,
|
||||
self.cs.servers.create,
|
||||
name="My server", image=1, flavor=1,
|
||||
nics='auto', hypervisor_hostname="new-host")
|
||||
self.assertIn("'hypervisor_hostname' argument is only allowed since "
|
||||
"microversion 2.74", six.text_type(ex))
|
||||
|
||||
def test_create_server_with_host_and_hypervisor_hostname_pre_274_fails(
|
||||
self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.73')
|
||||
ex = self.assertRaises(exceptions.UnsupportedAttribute,
|
||||
self.cs.servers.create,
|
||||
name="My server", image=1, flavor=1,
|
||||
nics='auto', host="new-host",
|
||||
hypervisor_hostname="new-host")
|
||||
self.assertIn("'host' argument is only allowed since microversion "
|
||||
"2.74", six.text_type(ex))
|
||||
|
@ -1374,6 +1374,83 @@ class ShellTest(utils.TestCase):
|
||||
self.assertIn('Instance %s could not be found.' % FAKE_UUID_1,
|
||||
six.text_type(ex))
|
||||
|
||||
def test_boot_with_host_v274(self):
|
||||
self.run_command('boot --flavor 1 --image %s '
|
||||
'--host new-host --nic auto '
|
||||
'some-server' % FAKE_UUID_1,
|
||||
api_version='2.74')
|
||||
self.assert_called_anytime(
|
||||
'POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'name': 'some-server',
|
||||
'imageRef': FAKE_UUID_1,
|
||||
'min_count': 1,
|
||||
'max_count': 1,
|
||||
'networks': 'auto',
|
||||
'host': 'new-host',
|
||||
}},
|
||||
)
|
||||
|
||||
def test_boot_with_hypervisor_hostname_v274(self):
|
||||
self.run_command('boot --flavor 1 --image %s --nic auto '
|
||||
'--hypervisor-hostname new-host '
|
||||
'some-server' % FAKE_UUID_1,
|
||||
api_version='2.74')
|
||||
self.assert_called_anytime(
|
||||
'POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'name': 'some-server',
|
||||
'imageRef': FAKE_UUID_1,
|
||||
'min_count': 1,
|
||||
'max_count': 1,
|
||||
'networks': 'auto',
|
||||
'hypervisor_hostname': 'new-host',
|
||||
}},
|
||||
)
|
||||
|
||||
def test_boot_with_host_and_hypervisor_hostname_v274(self):
|
||||
self.run_command('boot --flavor 1 --image %s '
|
||||
'--host new-host --nic auto '
|
||||
'--hypervisor-hostname new-host '
|
||||
'some-server' % FAKE_UUID_1,
|
||||
api_version='2.74')
|
||||
self.assert_called_anytime(
|
||||
'POST', '/servers',
|
||||
{'server': {
|
||||
'flavorRef': '1',
|
||||
'name': 'some-server',
|
||||
'imageRef': FAKE_UUID_1,
|
||||
'min_count': 1,
|
||||
'max_count': 1,
|
||||
'networks': 'auto',
|
||||
'host': 'new-host',
|
||||
'hypervisor_hostname': 'new-host',
|
||||
}},
|
||||
)
|
||||
|
||||
def test_boot_with_host_pre_v274(self):
|
||||
cmd = ('boot --flavor 1 --image %s --nic auto '
|
||||
'--host new-host some-server'
|
||||
% FAKE_UUID_1)
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
cmd, api_version='2.73')
|
||||
|
||||
def test_boot_with_hypervisor_hostname_pre_v274(self):
|
||||
cmd = ('boot --flavor 1 --image %s --nic auto '
|
||||
'--hypervisor-hostname new-host some-server'
|
||||
% FAKE_UUID_1)
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
cmd, api_version='2.73')
|
||||
|
||||
def test_boot_with_host_and_hypervisor_hostname_pre_v274(self):
|
||||
cmd = ('boot --flavor 1 --image %s --nic auto '
|
||||
'--host new-host --hypervisor-hostname new-host some-server'
|
||||
% FAKE_UUID_1)
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
cmd, api_version='2.73')
|
||||
|
||||
def test_flavor_list(self):
|
||||
out, _ = self.run_command('flavor-list')
|
||||
self.assert_called_anytime('GET', '/flavors/detail')
|
||||
@ -4185,6 +4262,7 @@ class ShellTest(utils.TestCase):
|
||||
70, # There are no version-wrapped shell method changes for this.
|
||||
71, # There are no version-wrapped shell method changes for this.
|
||||
72, # There are no version-wrapped shell method changes for this.
|
||||
74, # There are no version-wrapped shell method changes for this.
|
||||
])
|
||||
versions_supported = set(range(0,
|
||||
novaclient.API_MAX_VERSION.ver_minor + 1))
|
||||
|
@ -694,7 +694,8 @@ class ServerManager(base.BootingManagerWithFind):
|
||||
block_device_mapping_v2=None, nics=None, scheduler_hints=None,
|
||||
config_drive=None, admin_pass=None, disk_config=None,
|
||||
access_ip_v4=None, access_ip_v6=None, description=None,
|
||||
tags=None, trusted_image_certificates=None, **kwargs):
|
||||
tags=None, trusted_image_certificates=None,
|
||||
host=None, hypervisor_hostname=None, **kwargs):
|
||||
"""
|
||||
Create (boot) a new server.
|
||||
"""
|
||||
@ -817,6 +818,12 @@ class ServerManager(base.BootingManagerWithFind):
|
||||
body['server']['trusted_image_certificates'] = (
|
||||
trusted_image_certificates)
|
||||
|
||||
if host:
|
||||
body['server']['host'] = host
|
||||
|
||||
if hypervisor_hostname:
|
||||
body['server']['hypervisor_hostname'] = hypervisor_hostname
|
||||
|
||||
return self._create('/servers', body, response_key,
|
||||
return_raw=return_raw, **kwargs)
|
||||
|
||||
@ -1267,7 +1274,9 @@ class ServerManager(base.BootingManagerWithFind):
|
||||
nics=None, scheduler_hints=None,
|
||||
config_drive=None, disk_config=None, admin_pass=None,
|
||||
access_ip_v4=None, access_ip_v6=None,
|
||||
trusted_image_certificates=None, **kwargs):
|
||||
trusted_image_certificates=None,
|
||||
host=None, hypervisor_hostname=None,
|
||||
**kwargs):
|
||||
# TODO(anthony): indicate in doc string if param is an extension
|
||||
# and/or optional
|
||||
"""
|
||||
@ -1334,6 +1343,10 @@ class ServerManager(base.BootingManagerWithFind):
|
||||
server as tags (allowed since microversion 2.52)
|
||||
:param trusted_image_certificates: A list of trusted certificate IDs
|
||||
(allowed since microversion 2.63)
|
||||
:param host: requested host to create servers
|
||||
(allowed since microversion 2.74)
|
||||
:param hypervisor_hostname: requested hypervisor hostname to create
|
||||
servers (allowed since microversion 2.74)
|
||||
"""
|
||||
if not min_count:
|
||||
min_count = 1
|
||||
@ -1388,6 +1401,15 @@ class ServerManager(base.BootingManagerWithFind):
|
||||
"Block device volume_type is not supported before "
|
||||
"microversion 2.67")
|
||||
|
||||
host_microversion = api_versions.APIVersion("2.74")
|
||||
if host and self.api_version < host_microversion:
|
||||
raise exceptions.UnsupportedAttribute("host", "2.74")
|
||||
hypervisor_hostname_microversion = api_versions.APIVersion("2.74")
|
||||
if (hypervisor_hostname and
|
||||
self.api_version < hypervisor_hostname_microversion):
|
||||
raise exceptions.UnsupportedAttribute(
|
||||
"hypervisor_hostname", "2.74")
|
||||
|
||||
boot_kwargs = dict(
|
||||
meta=meta, files=files, userdata=userdata,
|
||||
reservation_id=reservation_id, min_count=min_count,
|
||||
@ -1396,7 +1418,9 @@ class ServerManager(base.BootingManagerWithFind):
|
||||
scheduler_hints=scheduler_hints, config_drive=config_drive,
|
||||
disk_config=disk_config, admin_pass=admin_pass,
|
||||
access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6,
|
||||
trusted_image_certificates=trusted_image_certificates, **kwargs)
|
||||
trusted_image_certificates=trusted_image_certificates,
|
||||
host=host, hypervisor_hostname=hypervisor_hostname,
|
||||
**kwargs)
|
||||
|
||||
if block_device_mapping:
|
||||
boot_kwargs['block_device_mapping'] = block_device_mapping
|
||||
|
@ -517,6 +517,12 @@ def _boot(cs, args):
|
||||
if 'tags' in args and args.tags:
|
||||
boot_kwargs["tags"] = args.tags.split(',')
|
||||
|
||||
if 'host' in args and args.host:
|
||||
boot_kwargs["host"] = args.host
|
||||
|
||||
if 'hypervisor_hostname' in args and args.hypervisor_hostname:
|
||||
boot_kwargs["hypervisor_hostname"] = args.hypervisor_hostname
|
||||
|
||||
if include_files:
|
||||
boot_kwargs['files'] = files
|
||||
|
||||
@ -942,6 +948,21 @@ def _boot(cs, args):
|
||||
'May be specified multiple times to pass multiple trusted image '
|
||||
'certificate IDs.'),
|
||||
start_version="2.63")
|
||||
@utils.arg(
|
||||
'--host',
|
||||
metavar='<host>',
|
||||
dest='host',
|
||||
default=None,
|
||||
help=_('Requested host to create servers. Admin only by default.'),
|
||||
start_version="2.74")
|
||||
@utils.arg(
|
||||
'--hypervisor-hostname',
|
||||
metavar='<hypervisor-hostname>',
|
||||
dest='hypervisor_hostname',
|
||||
default=None,
|
||||
help=_('Requested hypervisor hostname to create servers. Admin only by '
|
||||
'default.'),
|
||||
start_version="2.74")
|
||||
def do_boot(cs, args):
|
||||
"""Boot a new server."""
|
||||
boot_args, boot_kwargs = _boot(cs, args)
|
||||
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Support is added for the `2.74 microversion`_ which allows specifying the
|
||||
``--host`` and ``--hypervisor-hostname`` options on the ``nova boot``
|
||||
command. The ``novaclient.v2.servers.ServerManager.create()`` method now
|
||||
also supports ``host`` and ``hypervisor_hostname`` parameters.
|
||||
|
||||
.. _2.74 microversion: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id66
|
Loading…
Reference in New Issue
Block a user