Microversion 2.90 - Configurable hostnames
Change-Id: Icd4362a07196e59bafcdfaff44323ce1386d4f55 Signed-off-by: Stephen Finucane <stephenfin@redhat.com> Depends-On: https://review.opendev.org/c/openstack/nova/+/778550/
This commit is contained in:
parent
01c7a3aa10
commit
8066f8c745
@ -975,6 +975,7 @@ nova boot
|
|||||||
[--trusted-image-certificate-id <trusted-image-certificate-id>]
|
[--trusted-image-certificate-id <trusted-image-certificate-id>]
|
||||||
[--host <host>]
|
[--host <host>]
|
||||||
[--hypervisor-hostname <hypervisor-hostname>]
|
[--hypervisor-hostname <hypervisor-hostname>]
|
||||||
|
[--hostname <hostname>]
|
||||||
<name>
|
<name>
|
||||||
|
|
||||||
Boot a new server.
|
Boot a new server.
|
||||||
@ -1149,6 +1150,12 @@ quality of service support, microversion ``2.72`` is required.
|
|||||||
Requested hypervisor hostname to create servers. Admin only by default.
|
Requested hypervisor hostname to create servers. Admin only by default.
|
||||||
(Supported by API versions '2.74' - '2.latest')
|
(Supported by API versions '2.74' - '2.latest')
|
||||||
|
|
||||||
|
``--hostname <hostname>``
|
||||||
|
Hostname for the instance. This sets the hostname stored in the
|
||||||
|
metadata server: a utility such as cloud-init running on the guest
|
||||||
|
is required to propagate these changes to the guest.
|
||||||
|
(Supported by API versions '2.90' - '2.latest')
|
||||||
|
|
||||||
.. _nova_clear-password:
|
.. _nova_clear-password:
|
||||||
|
|
||||||
nova clear-password
|
nova clear-password
|
||||||
@ -2885,6 +2892,7 @@ nova rebuild
|
|||||||
[--user-data <user-data>] [--user-data-unset]
|
[--user-data <user-data>] [--user-data-unset]
|
||||||
[--trusted-image-certificate-id <trusted-image-certificate-id>]
|
[--trusted-image-certificate-id <trusted-image-certificate-id>]
|
||||||
[--trusted-image-certificates-unset]
|
[--trusted-image-certificates-unset]
|
||||||
|
[--hostname <hostname>]
|
||||||
<server> <image>
|
<server> <image>
|
||||||
|
|
||||||
Shutdown, re-image, and re-boot a server.
|
Shutdown, re-image, and re-boot a server.
|
||||||
@ -2958,6 +2966,12 @@ Shutdown, re-image, and re-boot a server.
|
|||||||
specified with the ``--trusted-image-certificate-id`` option.
|
specified with the ``--trusted-image-certificate-id`` option.
|
||||||
(Supported by API versions '2.63' - '2.latest')
|
(Supported by API versions '2.63' - '2.latest')
|
||||||
|
|
||||||
|
``--hostname <hostname>``
|
||||||
|
New hostname for the instance. This only updates the hostname
|
||||||
|
stored in the metadata server: a utility running on the guest
|
||||||
|
is required to propagate these changes to the guest.
|
||||||
|
(Supported by API versions '2.90' - '2.latest')
|
||||||
|
|
||||||
.. _nova_refresh-network:
|
.. _nova_refresh-network:
|
||||||
|
|
||||||
nova refresh-network
|
nova refresh-network
|
||||||
@ -3795,9 +3809,11 @@ nova update
|
|||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
usage: nova update [--name <name>] [--description <description>] <server>
|
usage: nova update [--name <name>] [--description <description>]
|
||||||
|
[--hostname <hostname>]
|
||||||
|
<server>
|
||||||
|
|
||||||
Update the name or the description for a server.
|
Update attributes of a server.
|
||||||
|
|
||||||
**Positional arguments:**
|
**Positional arguments:**
|
||||||
|
|
||||||
@ -3815,6 +3831,12 @@ Update the name or the description for a server.
|
|||||||
will be removed. (Supported by API versions
|
will be removed. (Supported by API versions
|
||||||
'2.19' - '2.latest')
|
'2.19' - '2.latest')
|
||||||
|
|
||||||
|
``--hostname <hostname>``
|
||||||
|
New hostname for the instance. This only updates the hostname
|
||||||
|
stored in the metadata server: a utility running on the guest
|
||||||
|
is required to propagate these changes to the guest.
|
||||||
|
(Supported by API versions '2.90' - '2.latest')
|
||||||
|
|
||||||
.. _nova_usage:
|
.. _nova_usage:
|
||||||
|
|
||||||
nova usage
|
nova usage
|
||||||
|
@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
|
|||||||
# when client supported the max version, and bumped sequentially, otherwise
|
# when client supported the max version, and bumped sequentially, otherwise
|
||||||
# the client may break due to server side new version may include some
|
# the client may break due to server side new version may include some
|
||||||
# backward incompatible change.
|
# backward incompatible change.
|
||||||
API_MAX_VERSION = api_versions.APIVersion("2.89")
|
API_MAX_VERSION = api_versions.APIVersion("2.90")
|
||||||
|
@ -1905,3 +1905,90 @@ class ServersV278Test(ServersV273Test):
|
|||||||
self.cs.api_version = api_versions.APIVersion('2.77')
|
self.cs.api_version = api_versions.APIVersion('2.77')
|
||||||
s = self.cs.servers.get(1234)
|
s = self.cs.servers.get(1234)
|
||||||
self.assertRaises(exceptions.VersionNotFoundForAPIMethod, s.topology)
|
self.assertRaises(exceptions.VersionNotFoundForAPIMethod, s.topology)
|
||||||
|
|
||||||
|
|
||||||
|
class ServersV290Test(ServersV278Test):
|
||||||
|
|
||||||
|
api_version = '2.90'
|
||||||
|
|
||||||
|
def test_create_server_with_hostname(self):
|
||||||
|
self.cs.servers.create(
|
||||||
|
name='My server',
|
||||||
|
image=1,
|
||||||
|
flavor=1,
|
||||||
|
nics='auto',
|
||||||
|
hostname='new-hostname',
|
||||||
|
)
|
||||||
|
self.assert_called(
|
||||||
|
'POST', '/servers',
|
||||||
|
{
|
||||||
|
'server': {
|
||||||
|
'flavorRef': '1',
|
||||||
|
'imageRef': '1',
|
||||||
|
'max_count': 1,
|
||||||
|
'min_count': 1,
|
||||||
|
'name': 'My server',
|
||||||
|
'networks': 'auto',
|
||||||
|
'hostname': 'new-hostname'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_create_server_with_hostname_pre_290_fails(self):
|
||||||
|
self.cs.api_version = api_versions.APIVersion('2.89')
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exceptions.UnsupportedAttribute,
|
||||||
|
self.cs.servers.create,
|
||||||
|
name='My server',
|
||||||
|
image=1,
|
||||||
|
flavor=1,
|
||||||
|
nics='auto',
|
||||||
|
hostname='new-hostname')
|
||||||
|
self.assertIn(
|
||||||
|
"'hostname' argument is only allowed since microversion 2.90",
|
||||||
|
str(ex))
|
||||||
|
|
||||||
|
def test_rebuild_server_with_hostname(self):
|
||||||
|
s = self.cs.servers.get(1234)
|
||||||
|
ret = s.rebuild(image="1", hostname='new-hostname')
|
||||||
|
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||||
|
self.assert_called(
|
||||||
|
'POST', '/servers/1234/action',
|
||||||
|
{
|
||||||
|
'rebuild': {
|
||||||
|
'imageRef': '1',
|
||||||
|
'hostname': 'new-hostname',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_rebuild_server_with_hostname_pre_290_fails(self):
|
||||||
|
self.cs.api_version = api_versions.APIVersion('2.89')
|
||||||
|
ex = self.assertRaises(
|
||||||
|
exceptions.UnsupportedAttribute,
|
||||||
|
self.cs.servers.rebuild,
|
||||||
|
'1234', fakes.FAKE_IMAGE_UUID_1,
|
||||||
|
hostname='new-hostname')
|
||||||
|
self.assertIn('hostname', str(ex))
|
||||||
|
|
||||||
|
def test_update_server_with_hostname(self):
|
||||||
|
s = self.cs.servers.get(1234)
|
||||||
|
|
||||||
|
s.update(hostname='new-hostname')
|
||||||
|
self.assert_called(
|
||||||
|
'PUT', '/servers/1234',
|
||||||
|
{
|
||||||
|
'server': {
|
||||||
|
'hostname': 'new-hostname',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_update_with_hostname_pre_290_fails(self):
|
||||||
|
self.cs.api_version = api_versions.APIVersion('2.89')
|
||||||
|
s = self.cs.servers.get(1234)
|
||||||
|
ex = self.assertRaises(
|
||||||
|
TypeError,
|
||||||
|
s.update,
|
||||||
|
hostname='new-hostname')
|
||||||
|
self.assertIn('hostname', str(ex))
|
||||||
|
@ -1502,6 +1502,34 @@ class ShellTest(utils.TestCase):
|
|||||||
self.assertRaises(SystemExit, self.run_command,
|
self.assertRaises(SystemExit, self.run_command,
|
||||||
cmd, api_version='2.73')
|
cmd, api_version='2.73')
|
||||||
|
|
||||||
|
def test_boot_with_hostname(self):
|
||||||
|
self.run_command(
|
||||||
|
'boot --flavor 1 --image %s '
|
||||||
|
'--hostname my-hostname --nic auto '
|
||||||
|
'some-server' % FAKE_UUID_1,
|
||||||
|
api_version='2.90')
|
||||||
|
self.assert_called_anytime(
|
||||||
|
'POST', '/servers',
|
||||||
|
{'server': {
|
||||||
|
'flavorRef': '1',
|
||||||
|
'name': 'some-server',
|
||||||
|
'imageRef': FAKE_UUID_1,
|
||||||
|
'min_count': 1,
|
||||||
|
'max_count': 1,
|
||||||
|
'networks': 'auto',
|
||||||
|
'hostname': 'my-hostname',
|
||||||
|
}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_boot_with_hostname_pre_v290(self):
|
||||||
|
cmd = (
|
||||||
|
'boot --flavor 1 --image %s --nic auto '
|
||||||
|
'--hostname my-hostname some-server' % FAKE_UUID_1
|
||||||
|
)
|
||||||
|
self.assertRaises(
|
||||||
|
SystemExit, self.run_command,
|
||||||
|
cmd, api_version='2.89')
|
||||||
|
|
||||||
def test_flavor_list(self):
|
def test_flavor_list(self):
|
||||||
out, _ = self.run_command('flavor-list')
|
out, _ = self.run_command('flavor-list')
|
||||||
self.assert_called_anytime('GET', '/flavors/detail')
|
self.assert_called_anytime('GET', '/flavors/detail')
|
||||||
@ -2258,6 +2286,31 @@ class ShellTest(utils.TestCase):
|
|||||||
self.assertNotIn('server_groups', out)
|
self.assertNotIn('server_groups', out)
|
||||||
self.assertNotIn('a67359fb-d397-4697-88f1-f55e3ee7c499', out)
|
self.assertNotIn('a67359fb-d397-4697-88f1-f55e3ee7c499', out)
|
||||||
|
|
||||||
|
def test_rebuild_with_hostname(self):
|
||||||
|
self.run_command(
|
||||||
|
'rebuild sample-server %s --hostname new-hostname' % FAKE_UUID_1,
|
||||||
|
api_version='2.90')
|
||||||
|
self.assert_called('GET', '/servers?name=sample-server', pos=0)
|
||||||
|
self.assert_called('GET', '/servers/1234', pos=1)
|
||||||
|
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2)
|
||||||
|
self.assert_called(
|
||||||
|
'POST', '/servers/1234/action',
|
||||||
|
{
|
||||||
|
'rebuild': {
|
||||||
|
'imageRef': FAKE_UUID_1,
|
||||||
|
'description': None,
|
||||||
|
'hostname': 'new-hostname',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pos=3)
|
||||||
|
self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4)
|
||||||
|
|
||||||
|
def test_rebuild_with_hostname_pre_v290(self):
|
||||||
|
self.assertRaises(
|
||||||
|
SystemExit, self.run_command,
|
||||||
|
'rebuild sample-server %s --hostname hostname' % FAKE_UUID_1,
|
||||||
|
api_version='2.89')
|
||||||
|
|
||||||
def test_start(self):
|
def test_start(self):
|
||||||
self.run_command('start sample-server')
|
self.run_command('start sample-server')
|
||||||
self.assert_called('POST', '/servers/1234/action', {'os-start': None})
|
self.assert_called('POST', '/servers/1234/action', {'os-start': None})
|
||||||
@ -2424,6 +2477,25 @@ class ShellTest(utils.TestCase):
|
|||||||
'update --description new-description sample-server',
|
'update --description new-description sample-server',
|
||||||
api_version='2.18')
|
api_version='2.18')
|
||||||
|
|
||||||
|
def test_update_with_hostname(self):
|
||||||
|
self.run_command(
|
||||||
|
'update --hostname new-hostname sample-server',
|
||||||
|
api_version='2.90')
|
||||||
|
expected_put_body = {
|
||||||
|
"server": {
|
||||||
|
"hostname": "new-hostname"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.assert_called('GET', '/servers/1234', pos=-2)
|
||||||
|
self.assert_called('PUT', '/servers/1234', expected_put_body, pos=-1)
|
||||||
|
|
||||||
|
def test_update_with_hostname_pre_v290(self):
|
||||||
|
self.assertRaises(
|
||||||
|
SystemExit,
|
||||||
|
self.run_command,
|
||||||
|
'update --hostname new-hostname sample-server',
|
||||||
|
api_version='2.89')
|
||||||
|
|
||||||
def test_resize(self):
|
def test_resize(self):
|
||||||
self.run_command('resize sample-server 1')
|
self.run_command('resize sample-server 1')
|
||||||
self.assert_called('POST', '/servers/1234/action',
|
self.assert_called('POST', '/servers/1234/action',
|
||||||
|
@ -67,17 +67,17 @@ class Server(base.Resource):
|
|||||||
@api_versions.wraps("2.0", "2.18")
|
@api_versions.wraps("2.0", "2.18")
|
||||||
def update(self, name=None):
|
def update(self, name=None):
|
||||||
"""
|
"""
|
||||||
Update the name for this server.
|
Update attributes of this server.
|
||||||
|
|
||||||
:param name: Update the server's name.
|
:param name: Update the server's name.
|
||||||
:returns: :class:`Server`
|
:returns: :class:`Server`
|
||||||
"""
|
"""
|
||||||
return self.manager.update(self, name=name)
|
return self.manager.update(self, name=name)
|
||||||
|
|
||||||
@api_versions.wraps("2.19")
|
@api_versions.wraps("2.19", "2.89")
|
||||||
def update(self, name=None, description=None):
|
def update(self, name=None, description=None):
|
||||||
"""
|
"""
|
||||||
Update the name and the description for this server.
|
Update attributes of this server.
|
||||||
|
|
||||||
:param name: Update the server's name.
|
:param name: Update the server's name.
|
||||||
:param description: Update the server's description.
|
:param description: Update the server's description.
|
||||||
@ -88,6 +88,23 @@ class Server(base.Resource):
|
|||||||
update_kwargs["description"] = description
|
update_kwargs["description"] = description
|
||||||
return self.manager.update(self, **update_kwargs)
|
return self.manager.update(self, **update_kwargs)
|
||||||
|
|
||||||
|
@api_versions.wraps("2.90")
|
||||||
|
def update(self, name=None, description=None, hostname=None):
|
||||||
|
"""
|
||||||
|
Update attributes of this server.
|
||||||
|
|
||||||
|
:param name: Update the server's name.
|
||||||
|
:param description: Update the server's description.
|
||||||
|
:param hostname: Update the server's hostname.
|
||||||
|
:returns: :class:`Server`
|
||||||
|
"""
|
||||||
|
update_kwargs = {"name": name}
|
||||||
|
if description is not None:
|
||||||
|
update_kwargs["description"] = description
|
||||||
|
if hostname is not None:
|
||||||
|
update_kwargs["hostname"] = hostname
|
||||||
|
return self.manager.update(self, **update_kwargs)
|
||||||
|
|
||||||
def get_console_output(self, length=None):
|
def get_console_output(self, length=None):
|
||||||
"""
|
"""
|
||||||
Get text console log output from Server.
|
Get text console log output from Server.
|
||||||
@ -704,7 +721,7 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
config_drive=None, admin_pass=None, disk_config=None,
|
config_drive=None, admin_pass=None, disk_config=None,
|
||||||
access_ip_v4=None, access_ip_v6=None, description=None,
|
access_ip_v4=None, access_ip_v6=None, description=None,
|
||||||
tags=None, trusted_image_certificates=None,
|
tags=None, trusted_image_certificates=None,
|
||||||
host=None, hypervisor_hostname=None, **kwargs):
|
host=None, hypervisor_hostname=None, hostname=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Create (boot) a new server.
|
Create (boot) a new server.
|
||||||
"""
|
"""
|
||||||
@ -833,6 +850,9 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
if hypervisor_hostname:
|
if hypervisor_hostname:
|
||||||
body['server']['hypervisor_hostname'] = hypervisor_hostname
|
body['server']['hypervisor_hostname'] = hypervisor_hostname
|
||||||
|
|
||||||
|
if hostname:
|
||||||
|
body['server']['hostname'] = hostname
|
||||||
|
|
||||||
return self._create('/servers', body, response_key,
|
return self._create('/servers', body, response_key,
|
||||||
return_raw=return_raw, **kwargs)
|
return_raw=return_raw, **kwargs)
|
||||||
|
|
||||||
@ -1318,10 +1338,8 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
config_drive=None, disk_config=None, admin_pass=None,
|
config_drive=None, disk_config=None, admin_pass=None,
|
||||||
access_ip_v4=None, access_ip_v6=None,
|
access_ip_v4=None, access_ip_v6=None,
|
||||||
trusted_image_certificates=None,
|
trusted_image_certificates=None,
|
||||||
host=None, hypervisor_hostname=None,
|
host=None, hypervisor_hostname=None, hostname=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
# TODO(anthony): indicate in doc string if param is an extension
|
|
||||||
# and/or optional
|
|
||||||
"""
|
"""
|
||||||
Create (boot) a new server.
|
Create (boot) a new server.
|
||||||
|
|
||||||
@ -1390,6 +1408,8 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
(allowed since microversion 2.74)
|
(allowed since microversion 2.74)
|
||||||
:param hypervisor_hostname: requested hypervisor hostname to create
|
:param hypervisor_hostname: requested hypervisor hostname to create
|
||||||
servers (allowed since microversion 2.74)
|
servers (allowed since microversion 2.74)
|
||||||
|
:param hostname: requested hostname of server (allowed since
|
||||||
|
microversion 2.90)
|
||||||
"""
|
"""
|
||||||
if not min_count:
|
if not min_count:
|
||||||
min_count = 1
|
min_count = 1
|
||||||
@ -1453,6 +1473,10 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
raise exceptions.UnsupportedAttribute(
|
raise exceptions.UnsupportedAttribute(
|
||||||
"hypervisor_hostname", "2.74")
|
"hypervisor_hostname", "2.74")
|
||||||
|
|
||||||
|
hostname_microversion = api_versions.APIVersion("2.90")
|
||||||
|
if hostname and self.api_version < hostname_microversion:
|
||||||
|
raise exceptions.UnsupportedAttribute("hostname", "2.90")
|
||||||
|
|
||||||
boot_kwargs = dict(
|
boot_kwargs = dict(
|
||||||
meta=meta, files=files, userdata=userdata,
|
meta=meta, files=files, userdata=userdata,
|
||||||
reservation_id=reservation_id, min_count=min_count,
|
reservation_id=reservation_id, min_count=min_count,
|
||||||
@ -1463,7 +1487,7 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6,
|
access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6,
|
||||||
trusted_image_certificates=trusted_image_certificates,
|
trusted_image_certificates=trusted_image_certificates,
|
||||||
host=host, hypervisor_hostname=hypervisor_hostname,
|
host=host, hypervisor_hostname=hypervisor_hostname,
|
||||||
**kwargs)
|
hostname=hostname, **kwargs)
|
||||||
|
|
||||||
if block_device_mapping:
|
if block_device_mapping:
|
||||||
boot_kwargs['block_device_mapping'] = block_device_mapping
|
boot_kwargs['block_device_mapping'] = block_device_mapping
|
||||||
@ -1479,10 +1503,11 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
@api_versions.wraps("2.0", "2.18")
|
@api_versions.wraps("2.0", "2.18")
|
||||||
def update(self, server, name=None):
|
def update(self, server, name=None):
|
||||||
"""
|
"""
|
||||||
Update the name for a server.
|
Update attributes of a server.
|
||||||
|
|
||||||
:param server: The :class:`Server` (or its ID) to update.
|
:param server: The :class:`Server` (or its ID) to update.
|
||||||
:param name: Update the server's name.
|
:param name: Update the server's name.
|
||||||
|
:returns: :class:`Server`
|
||||||
"""
|
"""
|
||||||
if name is None:
|
if name is None:
|
||||||
return
|
return
|
||||||
@ -1495,15 +1520,16 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
|
|
||||||
return self._update("/servers/%s" % base.getid(server), body, "server")
|
return self._update("/servers/%s" % base.getid(server), body, "server")
|
||||||
|
|
||||||
@api_versions.wraps("2.19")
|
@api_versions.wraps("2.19", "2.89")
|
||||||
def update(self, server, name=None, description=None):
|
def update(self, server, name=None, description=None):
|
||||||
"""
|
"""
|
||||||
Update the name or the description for a server.
|
Update attributes of a server.
|
||||||
|
|
||||||
:param server: The :class:`Server` (or its ID) to update.
|
:param server: The :class:`Server` (or its ID) to update.
|
||||||
:param name: Update the server's name.
|
:param name: Update the server's name.
|
||||||
:param description: Update the server's description. If it equals to
|
:param description: Update the server's description. If it equals to
|
||||||
empty string(i.g. ""), the server description will be removed.
|
empty string(i.g. ""), the server description will be removed.
|
||||||
|
:returns: :class:`Server`
|
||||||
"""
|
"""
|
||||||
if name is None and description is None:
|
if name is None and description is None:
|
||||||
return
|
return
|
||||||
@ -1518,6 +1544,36 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
|
|
||||||
return self._update("/servers/%s" % base.getid(server), body, "server")
|
return self._update("/servers/%s" % base.getid(server), body, "server")
|
||||||
|
|
||||||
|
@api_versions.wraps("2.90")
|
||||||
|
def update(self, server, name=None, description=None, hostname=None):
|
||||||
|
"""
|
||||||
|
Update attributes of a server.
|
||||||
|
|
||||||
|
:param server: The :class:`Server` (or its ID) to update.
|
||||||
|
:param name: Update the server's name.
|
||||||
|
:param description: Update the server's description. If it equals to
|
||||||
|
empty string(i.g. ""), the server description will be removed.
|
||||||
|
:param hostname: Update the server's hostname as recorded by the
|
||||||
|
metadata service. Note that a separate utility running on the
|
||||||
|
guest will be necessary to reflect these changes in the guest
|
||||||
|
itself.
|
||||||
|
:returns: :class:`Server`
|
||||||
|
"""
|
||||||
|
if name is None and description is None and hostname is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
body = {"server": {}}
|
||||||
|
if name:
|
||||||
|
body["server"]["name"] = name
|
||||||
|
if description == "":
|
||||||
|
body["server"]["description"] = None
|
||||||
|
elif description:
|
||||||
|
body["server"]["description"] = description
|
||||||
|
if hostname:
|
||||||
|
body["server"]["hostname"] = hostname
|
||||||
|
|
||||||
|
return self._update("/servers/%s" % base.getid(server), body, "server")
|
||||||
|
|
||||||
def change_password(self, server, password):
|
def change_password(self, server, password):
|
||||||
"""
|
"""
|
||||||
Update the password for a server.
|
Update the password for a server.
|
||||||
@ -1548,6 +1604,7 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
"""
|
"""
|
||||||
return self._action('reboot', server, {'type': reboot_type})
|
return self._action('reboot', server, {'type': reboot_type})
|
||||||
|
|
||||||
|
# TODO(stephenfin): Expand out kwargs
|
||||||
def rebuild(self, server, image, password=None, disk_config=None,
|
def rebuild(self, server, image, password=None, disk_config=None,
|
||||||
preserve_ephemeral=False, name=None, meta=None, files=None,
|
preserve_ephemeral=False, name=None, meta=None, files=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
@ -1555,9 +1612,9 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
Rebuild -- shut down and then re-image -- a server.
|
Rebuild -- shut down and then re-image -- a server.
|
||||||
|
|
||||||
:param server: The :class:`Server` (or its ID) to share onto.
|
:param server: The :class:`Server` (or its ID) to share onto.
|
||||||
:param image: the :class:`Image` (or its ID) to re-image with.
|
:param image: The :class:`Image` (or its ID) to re-image with.
|
||||||
:param password: string to set as password on the rebuilt server.
|
:param password: String to set as password on the rebuilt server.
|
||||||
:param disk_config: partitioning mode to use on the rebuilt server.
|
:param disk_config: Partitioning mode to use on the rebuilt server.
|
||||||
Valid values are 'AUTO' or 'MANUAL'
|
Valid values are 'AUTO' or 'MANUAL'
|
||||||
:param preserve_ephemeral: If True, request that any ephemeral device
|
:param preserve_ephemeral: If True, request that any ephemeral device
|
||||||
be preserved when rebuilding the instance. Defaults to False.
|
be preserved when rebuilding the instance. Defaults to False.
|
||||||
@ -1565,24 +1622,26 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
:param meta: A dict of arbitrary key/value metadata to store for this
|
:param meta: A dict of arbitrary key/value metadata to store for this
|
||||||
server. Both keys and values must be <=255 characters.
|
server. Both keys and values must be <=255 characters.
|
||||||
:param files: A dict of files to overwrite on the server upon boot.
|
:param files: A dict of files to overwrite on the server upon boot.
|
||||||
Keys are file names (i.e. ``/etc/passwd``) and values
|
Keys are file names (i.e. ``/etc/passwd``) and values are the file
|
||||||
are the file contents (either as a string or as a
|
contents (either as a string or as a file-like object). A maximum
|
||||||
file-like object). A maximum of five entries is allowed,
|
of five entries is allowed, and each file must be 10k or less.
|
||||||
and each file must be 10k or less.
|
|
||||||
(deprecated starting with microversion 2.57)
|
(deprecated starting with microversion 2.57)
|
||||||
:param description: optional description of the server (allowed since
|
:param description: Optional description of the server. If None is
|
||||||
microversion 2.19)
|
specified, the existing description will be unset.
|
||||||
:param key_name: optional key pair name for rebuild operation; passing
|
(starting from microversion 2.19)
|
||||||
None will unset the key for the server instance
|
:param key_name: Optional key pair name for rebuild operation. If None
|
||||||
|
is specified, the existing key will be unset.
|
||||||
(starting from microversion 2.54)
|
(starting from microversion 2.54)
|
||||||
:param userdata: optional user data to pass to be exposed by the
|
:param userdata: Optional user data to pass to be exposed by the
|
||||||
metadata server; this can be a file type object as
|
metadata server; this can be a file type object as well or a
|
||||||
well or a string. If None is specified, the existing
|
string. If None is specified, the existing user_data is unset.
|
||||||
user_data is unset.
|
|
||||||
(starting from microversion 2.57)
|
(starting from microversion 2.57)
|
||||||
:param trusted_image_certificates: A list of trusted certificate IDs
|
:param trusted_image_certificates: A list of trusted certificate IDs
|
||||||
or None to unset/reset the servers trusted image
|
or None to unset/reset the servers trusted image certificates
|
||||||
certificates (allowed since microversion 2.63)
|
(starting from microversion 2.63)
|
||||||
|
:param hostname: Optional hostname to configure for the instance. If
|
||||||
|
None is specified, the existing hostname will be unset.
|
||||||
|
(starting from microversion 2.90)
|
||||||
:returns: :class:`Server`
|
:returns: :class:`Server`
|
||||||
"""
|
"""
|
||||||
descr_microversion = api_versions.APIVersion("2.19")
|
descr_microversion = api_versions.APIVersion("2.19")
|
||||||
@ -1612,6 +1671,12 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
raise exceptions.UnsupportedAttribute("trusted_image_certificates",
|
raise exceptions.UnsupportedAttribute("trusted_image_certificates",
|
||||||
"2.63")
|
"2.63")
|
||||||
|
|
||||||
|
if (
|
||||||
|
'hostname' in kwargs and
|
||||||
|
self.api_version < api_versions.APIVersion("2.90")
|
||||||
|
):
|
||||||
|
raise exceptions.UnsupportedAttribute('hostname', '2.90')
|
||||||
|
|
||||||
body = {'imageRef': base.getid(image)}
|
body = {'imageRef': base.getid(image)}
|
||||||
if password is not None:
|
if password is not None:
|
||||||
body['adminPass'] = password
|
body['adminPass'] = password
|
||||||
@ -1628,6 +1693,8 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
if "trusted_image_certificates" in kwargs:
|
if "trusted_image_certificates" in kwargs:
|
||||||
body["trusted_image_certificates"] = kwargs[
|
body["trusted_image_certificates"] = kwargs[
|
||||||
"trusted_image_certificates"]
|
"trusted_image_certificates"]
|
||||||
|
if "hostname" in kwargs:
|
||||||
|
body["hostname"] = kwargs["hostname"]
|
||||||
if meta:
|
if meta:
|
||||||
body['metadata'] = meta
|
body['metadata'] = meta
|
||||||
if files:
|
if files:
|
||||||
|
@ -532,8 +532,10 @@ def _boot(cs, args):
|
|||||||
if include_files:
|
if include_files:
|
||||||
boot_kwargs['files'] = files
|
boot_kwargs['files'] = files
|
||||||
|
|
||||||
if ('trusted_image_certificates' in args and
|
if (
|
||||||
args.trusted_image_certificates):
|
'trusted_image_certificates' in args and
|
||||||
|
args.trusted_image_certificates
|
||||||
|
):
|
||||||
boot_kwargs['trusted_image_certificates'] = (
|
boot_kwargs['trusted_image_certificates'] = (
|
||||||
args.trusted_image_certificates)
|
args.trusted_image_certificates)
|
||||||
elif utils.env('OS_TRUSTED_IMAGE_CERTIFICATE_IDS'):
|
elif utils.env('OS_TRUSTED_IMAGE_CERTIFICATE_IDS'):
|
||||||
@ -545,6 +547,9 @@ def _boot(cs, args):
|
|||||||
"OS_TRUSTED_IMAGE_CERTIFICATE_IDS",
|
"OS_TRUSTED_IMAGE_CERTIFICATE_IDS",
|
||||||
"2.63")
|
"2.63")
|
||||||
|
|
||||||
|
if 'hostname' in args and args.hostname:
|
||||||
|
boot_kwargs['hostname'] = args.hostname
|
||||||
|
|
||||||
return boot_args, boot_kwargs
|
return boot_args, boot_kwargs
|
||||||
|
|
||||||
|
|
||||||
@ -970,6 +975,14 @@ def _boot(cs, args):
|
|||||||
help=_('Requested hypervisor hostname to create servers. Admin only by '
|
help=_('Requested hypervisor hostname to create servers. Admin only by '
|
||||||
'default.'),
|
'default.'),
|
||||||
start_version="2.74")
|
start_version="2.74")
|
||||||
|
@utils.arg(
|
||||||
|
'--hostname',
|
||||||
|
help=_(
|
||||||
|
'Hostname for the instance. This sets the hostname stored in the '
|
||||||
|
'metadata server: a utility such as cloud-init running on the guest '
|
||||||
|
'is required to propagate these changes to the guest.'
|
||||||
|
),
|
||||||
|
start_version='2.90')
|
||||||
def do_boot(cs, args):
|
def do_boot(cs, args):
|
||||||
"""Boot a new server."""
|
"""Boot a new server."""
|
||||||
boot_args, boot_kwargs = _boot(cs, args)
|
boot_args, boot_kwargs = _boot(cs, args)
|
||||||
@ -2031,6 +2044,14 @@ def do_reboot(cs, args):
|
|||||||
help=_("Unset trusted_image_certificates in the server. Cannot be "
|
help=_("Unset trusted_image_certificates in the server. Cannot be "
|
||||||
"specified with the '--trusted-image-certificate-id' option."),
|
"specified with the '--trusted-image-certificate-id' option."),
|
||||||
start_version="2.63")
|
start_version="2.63")
|
||||||
|
@utils.arg(
|
||||||
|
'--hostname',
|
||||||
|
help=_(
|
||||||
|
'New hostname for the instance. This only updates the hostname '
|
||||||
|
'stored in the metadata server: a utility running on the guest '
|
||||||
|
'is required to propagate these changes to the guest.'
|
||||||
|
),
|
||||||
|
start_version='2.90')
|
||||||
def do_rebuild(cs, args):
|
def do_rebuild(cs, args):
|
||||||
"""Shutdown, re-image, and re-boot a server."""
|
"""Shutdown, re-image, and re-boot a server."""
|
||||||
server = _find_server(cs, args.server)
|
server = _find_server(cs, args.server)
|
||||||
@ -2121,6 +2142,9 @@ def do_rebuild(cs, args):
|
|||||||
"OS_TRUSTED_IMAGE_CERTIFICATE_IDS",
|
"OS_TRUSTED_IMAGE_CERTIFICATE_IDS",
|
||||||
"2.63")
|
"2.63")
|
||||||
|
|
||||||
|
if 'hostname' in args and args.hostname is not None:
|
||||||
|
kwargs['hostname'] = args.hostname
|
||||||
|
|
||||||
server = server.rebuild(image, _password, **kwargs)
|
server = server.rebuild(image, _password, **kwargs)
|
||||||
_print_server(cs, args, server)
|
_print_server(cs, args, server)
|
||||||
|
|
||||||
@ -2145,6 +2169,14 @@ def do_rebuild(cs, args):
|
|||||||
help=_('New description for the server. If it equals to empty string '
|
help=_('New description for the server. If it equals to empty string '
|
||||||
'(i.g. ""), the server description will be removed.'),
|
'(i.g. ""), the server description will be removed.'),
|
||||||
start_version="2.19")
|
start_version="2.19")
|
||||||
|
@utils.arg(
|
||||||
|
'--hostname',
|
||||||
|
help=_(
|
||||||
|
'New hostname for the instance. This only updates the hostname '
|
||||||
|
'stored in the metadata server: a utility running on the guest '
|
||||||
|
'is required to propagate these changes to the guest.'
|
||||||
|
),
|
||||||
|
start_version='2.90')
|
||||||
def do_update(cs, args):
|
def do_update(cs, args):
|
||||||
"""Update the name or the description for a server."""
|
"""Update the name or the description for a server."""
|
||||||
update_kwargs = {}
|
update_kwargs = {}
|
||||||
@ -2152,6 +2184,8 @@ def do_update(cs, args):
|
|||||||
update_kwargs["name"] = args.name
|
update_kwargs["name"] = args.name
|
||||||
if "description" in args and args.description is not None:
|
if "description" in args and args.description is not None:
|
||||||
update_kwargs["description"] = args.description
|
update_kwargs["description"] = args.description
|
||||||
|
if "hostname" in args and args.hostname is not None:
|
||||||
|
update_kwargs["hostname"] = args.hostname
|
||||||
_find_server(cs, args.server).update(**update_kwargs)
|
_find_server(cs, args.server).update(**update_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
13
releasenotes/notes/microversion-v2_90-259779668e67dfb5.yaml
Normal file
13
releasenotes/notes/microversion-v2_90-259779668e67dfb5.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added support for `microversion 2.90`_. This microversion provides the
|
||||||
|
ability to manually configure the instance ``hostname`` attribute when
|
||||||
|
creating a new instance (``nova boot --hostname HOSTNAME ...``), updating
|
||||||
|
an existing instance (``nova update --hostname HOSTNAME ...``), or
|
||||||
|
rebuilding an existing instance (``nova rebuild --hostname HOSTNAME``).
|
||||||
|
This attribute is published via the metadata service and config drive and
|
||||||
|
can be used by init scripts such as ``cloud-init`` to configure the guest's
|
||||||
|
hostname.
|
||||||
|
|
||||||
|
.. _microversion 2.90: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#microversion-2-90
|
Loading…
Reference in New Issue
Block a user