trivial: Remove use of kwargs
Make use of a "sentinel" object to allow us to remove the use of kwargs and provide a more helpful docstring. With any luck, Python will support these objects natively in a future release [1]. [1] https://www.python.org/dev/peps/pep-0661/ Change-Id: I411c0393754c8fe8a6698f0d278b73f12209ace8 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
@@ -29,6 +29,7 @@ from novaclient import crypto
|
|||||||
from novaclient import exceptions
|
from novaclient import exceptions
|
||||||
from novaclient.i18n import _
|
from novaclient.i18n import _
|
||||||
|
|
||||||
|
_SENTINEL = object()
|
||||||
|
|
||||||
REBOOT_SOFT, REBOOT_HARD = 'SOFT', 'HARD'
|
REBOOT_SOFT, REBOOT_HARD = 'SOFT', 'HARD'
|
||||||
|
|
||||||
@@ -404,34 +405,90 @@ class Server(base.Resource):
|
|||||||
"""
|
"""
|
||||||
return self.manager.reboot(self, reboot_type)
|
return self.manager.reboot(self, reboot_type)
|
||||||
|
|
||||||
def rebuild(self, image, password=None, preserve_ephemeral=False,
|
# NOTE(stephenfin): It would be nice to make everything bar image a
|
||||||
**kwargs):
|
# kwarg-only argument but there are backwards-compatbility concerns
|
||||||
|
def rebuild(
|
||||||
|
self,
|
||||||
|
image,
|
||||||
|
password=None,
|
||||||
|
preserve_ephemeral=False,
|
||||||
|
*,
|
||||||
|
disk_config=None,
|
||||||
|
name=None,
|
||||||
|
meta=None,
|
||||||
|
files=None,
|
||||||
|
description=_SENTINEL,
|
||||||
|
key_name=_SENTINEL,
|
||||||
|
userdata=_SENTINEL,
|
||||||
|
trusted_image_certificates=_SENTINEL,
|
||||||
|
hostname=_SENTINEL,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Rebuild -- shut down and then re-image -- this server.
|
Rebuild -- shut down and then re-image -- this server.
|
||||||
|
|
||||||
: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 the admin password on the rebuilt
|
:param password: String to set as password on the rebuilt server.
|
||||||
server.
|
|
||||||
: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.
|
||||||
|
:param disk_config: Partitioning mode to use on the rebuilt server.
|
||||||
|
Valid values are 'AUTO' or 'MANUAL'
|
||||||
|
:param name: Something to name the server.
|
||||||
|
:param meta: A dict of arbitrary key/value metadata to store for this
|
||||||
|
server. Both keys and values must be <=255 characters.
|
||||||
|
:param files: A dict of files to overwrite on the server upon boot.
|
||||||
|
Keys are file names (i.e. ``/etc/passwd``) and values are the file
|
||||||
|
contents (either as a string or as a file-like object). A maximum
|
||||||
|
of five entries is allowed, and each file must be 10k or less.
|
||||||
|
(deprecated starting with microversion 2.57)
|
||||||
|
:param description: Optional description of the server. If None is
|
||||||
|
specified, the existing description will be unset.
|
||||||
|
(starting from microversion 2.19)
|
||||||
|
: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)
|
||||||
|
:param userdata: Optional user data to pass to be exposed by the
|
||||||
|
metadata server; this can be a file type object as well or a
|
||||||
|
string. If None is specified, the existing user_data is unset.
|
||||||
|
(starting from microversion 2.57)
|
||||||
|
:param trusted_image_certificates: A list of trusted certificate IDs
|
||||||
|
or None to unset/reset the servers trusted image certificates
|
||||||
|
(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`
|
||||||
"""
|
"""
|
||||||
return self.manager.rebuild(self, image, password=password,
|
return self.manager.rebuild(
|
||||||
preserve_ephemeral=preserve_ephemeral,
|
self,
|
||||||
**kwargs)
|
image,
|
||||||
|
password=password,
|
||||||
|
disk_config=disk_config,
|
||||||
|
preserve_ephemeral=preserve_ephemeral,
|
||||||
|
name=name,
|
||||||
|
meta=meta,
|
||||||
|
files=files,
|
||||||
|
description=description,
|
||||||
|
key_name=key_name,
|
||||||
|
userdata=userdata,
|
||||||
|
trusted_image_certificates=trusted_image_certificates,
|
||||||
|
hostname=hostname,
|
||||||
|
)
|
||||||
|
|
||||||
def resize(self, flavor, **kwargs):
|
def resize(self, flavor, *, disk_config=None):
|
||||||
"""
|
"""
|
||||||
Resize the server's resources.
|
Resize the server's resources.
|
||||||
|
|
||||||
:param flavor: the :class:`Flavor` (or its ID) to resize to.
|
:param flavor: The :class:`Flavor` (or its ID) to resize to.
|
||||||
|
:param disk_config: Partitioning mode to use on the rebuilt server.
|
||||||
|
Valid values are 'AUTO' or 'MANUAL'.
|
||||||
:returns: An instance of novaclient.base.TupleWithMeta
|
:returns: An instance of novaclient.base.TupleWithMeta
|
||||||
|
|
||||||
Until a resize event is confirmed with :meth:`confirm_resize`, the old
|
Until a resize event is confirmed with :meth:`confirm_resize`, the old
|
||||||
server will be kept around and you'll be able to roll back to the old
|
server will be kept around and you'll be able to roll back to the old
|
||||||
flavor quickly with :meth:`revert_resize`. All resizes are
|
flavor quickly with :meth:`revert_resize`. All resizes are
|
||||||
automatically confirmed after 24 hours.
|
automatically confirmed after 24 hours by default.
|
||||||
"""
|
"""
|
||||||
return self.manager.resize(self, flavor, **kwargs)
|
return self.manager.resize(self, flavor, disk_config=disk_config)
|
||||||
|
|
||||||
def create_image(self, image_name, metadata=None):
|
def create_image(self, image_name, metadata=None):
|
||||||
"""
|
"""
|
||||||
@@ -743,16 +800,38 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
|
|
||||||
return base64.b64encode(userdata).decode('utf-8')
|
return base64.b64encode(userdata).decode('utf-8')
|
||||||
|
|
||||||
def _boot(self, response_key, name, image, flavor,
|
def _boot(
|
||||||
meta=None, files=None, userdata=None,
|
self,
|
||||||
reservation_id=False, return_raw=False, min_count=None,
|
response_key,
|
||||||
max_count=None, security_groups=None, key_name=None,
|
name,
|
||||||
availability_zone=None, block_device_mapping=None,
|
image,
|
||||||
block_device_mapping_v2=None, nics=None, scheduler_hints=None,
|
flavor,
|
||||||
config_drive=None, admin_pass=None, disk_config=None,
|
meta=None,
|
||||||
access_ip_v4=None, access_ip_v6=None, description=None,
|
files=None,
|
||||||
tags=None, trusted_image_certificates=None,
|
userdata=None,
|
||||||
host=None, hypervisor_hostname=None, hostname=None, **kwargs):
|
reservation_id=False,
|
||||||
|
return_raw=False,
|
||||||
|
min_count=None,
|
||||||
|
max_count=None,
|
||||||
|
security_groups=None,
|
||||||
|
key_name=None,
|
||||||
|
availability_zone=None,
|
||||||
|
block_device_mapping=None,
|
||||||
|
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,
|
||||||
|
host=None,
|
||||||
|
hypervisor_hostname=None,
|
||||||
|
hostname=None,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Create (boot) a new server.
|
Create (boot) a new server.
|
||||||
"""
|
"""
|
||||||
@@ -884,8 +963,9 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
if hostname:
|
if hostname:
|
||||||
body['server']['hostname'] = hostname
|
body['server']['hostname'] = hostname
|
||||||
|
|
||||||
return self._create('/servers', body, response_key,
|
return self._create(
|
||||||
return_raw=return_raw, **kwargs)
|
'/servers', body, response_key, return_raw=return_raw,
|
||||||
|
)
|
||||||
|
|
||||||
def get(self, server):
|
def get(self, server):
|
||||||
"""
|
"""
|
||||||
@@ -1390,17 +1470,39 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
raise ValueError('nics must be a list or a tuple, not %s' %
|
raise ValueError('nics must be a list or a tuple, not %s' %
|
||||||
type(nics))
|
type(nics))
|
||||||
|
|
||||||
def create(self, name, image, flavor, meta=None, files=None,
|
# NOTE(stephenfin): It would be nice to make everything bar name, image and
|
||||||
reservation_id=False, min_count=None,
|
# flavor a kwarg-only argument but there are backwards-compatbility
|
||||||
max_count=None, security_groups=None, userdata=None,
|
# concerns
|
||||||
key_name=None, availability_zone=None,
|
def create(
|
||||||
block_device_mapping=None, block_device_mapping_v2=None,
|
self,
|
||||||
nics=None, scheduler_hints=None,
|
name,
|
||||||
config_drive=None, disk_config=None, admin_pass=None,
|
image,
|
||||||
access_ip_v4=None, access_ip_v6=None,
|
flavor,
|
||||||
trusted_image_certificates=None,
|
meta=None,
|
||||||
host=None, hypervisor_hostname=None, hostname=None,
|
files=None,
|
||||||
**kwargs):
|
reservation_id=False,
|
||||||
|
min_count=None,
|
||||||
|
max_count=None,
|
||||||
|
security_groups=None,
|
||||||
|
userdata=None,
|
||||||
|
key_name=None,
|
||||||
|
availability_zone=None,
|
||||||
|
block_device_mapping=None,
|
||||||
|
block_device_mapping_v2=None,
|
||||||
|
nics=None,
|
||||||
|
scheduler_hints=None,
|
||||||
|
config_drive=None,
|
||||||
|
disk_config=None,
|
||||||
|
admin_pass=None,
|
||||||
|
access_ip_v4=None,
|
||||||
|
access_ip_v6=None,
|
||||||
|
description=None,
|
||||||
|
tags=None,
|
||||||
|
trusted_image_certificates=None,
|
||||||
|
host=None,
|
||||||
|
hypervisor_hostname=None,
|
||||||
|
hostname=None,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Create (boot) a new server.
|
Create (boot) a new server.
|
||||||
|
|
||||||
@@ -1412,65 +1514,59 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
:param image: The :class:`Image` to boot with.
|
:param image: The :class:`Image` to boot with.
|
||||||
:param flavor: The :class:`Flavor` to boot onto.
|
:param flavor: The :class:`Flavor` to boot onto.
|
||||||
: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 contents (either as a string or as a
|
are the file contents (either as a string or as a
|
||||||
file-like object). A maximum of five entries is allowed,
|
file-like object). A maximum 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 reservation_id: return a reservation_id for the set of
|
:param reservation_id: Return a reservation_id for the set of
|
||||||
servers being requested, boolean.
|
servers being requested, boolean.
|
||||||
:param min_count: (optional extension) The minimum number of
|
:param min_count: The minimum number of servers to launch.
|
||||||
servers to launch.
|
:param max_count: The maximum number of servers to launch.
|
||||||
:param max_count: (optional extension) The maximum number of
|
|
||||||
servers to launch.
|
|
||||||
:param security_groups: A list of security group names
|
:param security_groups: A list of security group names
|
||||||
:param userdata: user data to pass to be exposed by the metadata
|
:param userdata: User data to pass to be exposed by the metadata
|
||||||
server this can be a file type object as well or a
|
server this can be a file type object as well or a string.
|
||||||
string.
|
:param key_name: Name of previously created keypair to inject into the
|
||||||
:param key_name: (optional extension) name of previously created
|
instance.
|
||||||
keypair to inject into the instance.
|
|
||||||
:param availability_zone: Name of the availability zone for instance
|
:param availability_zone: Name of the availability zone for instance
|
||||||
placement.
|
placement.
|
||||||
:param block_device_mapping: (optional extension) A dict of block
|
:param block_device_mapping: A dict of block device mappings for this
|
||||||
device mappings for this server.
|
server.
|
||||||
:param block_device_mapping_v2: (optional extension) A list of block
|
:param block_device_mapping_v2: A list of block device mappings (dicts)
|
||||||
device mappings (dicts) for this server.
|
for this server.
|
||||||
:param nics: An ordered list of nics (dicts) to be added to this
|
:param nics: An ordered list of nics (dicts) to be added to this
|
||||||
server, with information about connected networks,
|
server, with information about connected networks, fixed IPs, port
|
||||||
fixed IPs, port etc.
|
etc. Beginning in microversion 2.37 this field is required and also
|
||||||
Beginning in microversion 2.37 this field is required and
|
supports a single string value of 'auto' or 'none'. The 'auto'
|
||||||
also supports a single string value of 'auto' or 'none'.
|
value means the Compute service will automatically allocate a
|
||||||
The 'auto' value means the Compute service will
|
network for the project if one is not available. This is the same
|
||||||
automatically allocate a network for the project if one
|
behavior as not passing anything for nics before microversion 2.37.
|
||||||
is not available. This is the same behavior as not
|
The 'none' value tells the Compute service to not allocate any
|
||||||
passing anything for nics before microversion 2.37. The
|
networking for the server.
|
||||||
'none' value tells the Compute service to not allocate
|
:param scheduler_hints: Arbitrary key-value pairs specified by the
|
||||||
any networking for the server.
|
client to help boot an instance.
|
||||||
:param scheduler_hints: (optional extension) arbitrary key-value pairs
|
:param config_drive: A boolean value to enable config drive.
|
||||||
specified by the client to help boot an instance
|
:param disk_config: Control how the disk is partitioned when the server
|
||||||
:param config_drive: (optional extension) a boolean value to enable
|
is created. Possible values are 'AUTO' or 'MANUAL'.
|
||||||
config drive
|
:param admin_pass: Add a user supplied admin password.
|
||||||
:param disk_config: (optional extension) control how the disk is
|
:param access_ip_v4: Add alternative access IP (v4)
|
||||||
partitioned when the server is created. possible
|
:param access_ip_v6: Add alternative access IP (v6)
|
||||||
values are 'AUTO' or 'MANUAL'.
|
:param description: Optional description of the server
|
||||||
:param admin_pass: (optional extension) add a user supplied admin
|
(allowed since microversion 2.19)
|
||||||
password.
|
:param tags: A list of arbitrary strings to be added to the server as
|
||||||
:param access_ip_v4: (optional extension) add alternative access ip v4
|
tags
|
||||||
:param access_ip_v6: (optional extension) add alternative access ip v6
|
(allowed since microversion 2.52)
|
||||||
:param description: optional description of the server (allowed since
|
|
||||||
microversion 2.19)
|
|
||||||
:param tags: A list of arbitrary strings to be added to the
|
|
||||||
server as tags (allowed since microversion 2.52)
|
|
||||||
:param trusted_image_certificates: A list of trusted certificate IDs
|
:param trusted_image_certificates: A list of trusted certificate IDs
|
||||||
(allowed since microversion 2.63)
|
(allowed since microversion 2.63)
|
||||||
:param host: requested host to create servers
|
:param host: Requested host to create servers
|
||||||
(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
|
||||||
:param hostname: requested hostname of server (allowed since
|
(allowed since microversion 2.74)
|
||||||
microversion 2.90)
|
: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
|
||||||
@@ -1481,8 +1577,7 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
|
|
||||||
boot_args = [name, image, flavor]
|
boot_args = [name, image, flavor]
|
||||||
|
|
||||||
descr_microversion = api_versions.APIVersion("2.19")
|
if description and self.api_version < api_versions.APIVersion("2.19"):
|
||||||
if "description" in kwargs and self.api_version < descr_microversion:
|
|
||||||
raise exceptions.UnsupportedAttribute("description", "2.19")
|
raise exceptions.UnsupportedAttribute("description", "2.19")
|
||||||
|
|
||||||
self._validate_create_nics(nics)
|
self._validate_create_nics(nics)
|
||||||
@@ -1503,8 +1598,7 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
"unsupported before microversion "
|
"unsupported before microversion "
|
||||||
"2.32")
|
"2.32")
|
||||||
|
|
||||||
boot_tags_microversion = api_versions.APIVersion("2.52")
|
if tags and self.api_version < api_versions.APIVersion("2.52"):
|
||||||
if "tags" in kwargs and self.api_version < boot_tags_microversion:
|
|
||||||
raise exceptions.UnsupportedAttribute("tags", "2.52")
|
raise exceptions.UnsupportedAttribute("tags", "2.52")
|
||||||
|
|
||||||
personality_files_deprecation = api_versions.APIVersion('2.57')
|
personality_files_deprecation = api_versions.APIVersion('2.57')
|
||||||
@@ -1546,9 +1640,10 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
scheduler_hints=scheduler_hints, config_drive=config_drive,
|
scheduler_hints=scheduler_hints, config_drive=config_drive,
|
||||||
disk_config=disk_config, admin_pass=admin_pass,
|
disk_config=disk_config, admin_pass=admin_pass,
|
||||||
access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6,
|
access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6,
|
||||||
|
description=description, tags=tags,
|
||||||
trusted_image_certificates=trusted_image_certificates,
|
trusted_image_certificates=trusted_image_certificates,
|
||||||
host=host, hypervisor_hostname=hypervisor_hostname,
|
host=host, hypervisor_hostname=hypervisor_hostname,
|
||||||
hostname=hostname, **kwargs)
|
hostname=hostname)
|
||||||
|
|
||||||
if block_device_mapping:
|
if block_device_mapping:
|
||||||
boot_kwargs['block_device_mapping'] = block_device_mapping
|
boot_kwargs['block_device_mapping'] = block_device_mapping
|
||||||
@@ -1665,10 +1760,25 @@ 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
|
# NOTE(stephenfin): It would be nice to make everything bar server and
|
||||||
def rebuild(self, server, image, password=None, disk_config=None,
|
# image a kwarg-only argument but there are backwards-compatbility concerns
|
||||||
preserve_ephemeral=False, name=None, meta=None, files=None,
|
def rebuild(
|
||||||
**kwargs):
|
self,
|
||||||
|
server,
|
||||||
|
image,
|
||||||
|
password=None,
|
||||||
|
disk_config=None,
|
||||||
|
preserve_ephemeral=False,
|
||||||
|
name=None,
|
||||||
|
meta=None,
|
||||||
|
files=None,
|
||||||
|
*,
|
||||||
|
description=_SENTINEL,
|
||||||
|
key_name=_SENTINEL,
|
||||||
|
userdata=_SENTINEL,
|
||||||
|
trusted_image_certificates=_SENTINEL,
|
||||||
|
hostname=_SENTINEL,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Rebuild -- shut down and then re-image -- a server.
|
Rebuild -- shut down and then re-image -- a server.
|
||||||
|
|
||||||
@@ -1705,63 +1815,80 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
(starting from microversion 2.90)
|
(starting from microversion 2.90)
|
||||||
:returns: :class:`Server`
|
:returns: :class:`Server`
|
||||||
"""
|
"""
|
||||||
descr_microversion = api_versions.APIVersion("2.19")
|
# Microversion 2.19 adds the optional 'description' parameter
|
||||||
if "description" in kwargs and self.api_version < descr_microversion:
|
if (
|
||||||
raise exceptions.UnsupportedAttribute("description", "2.19")
|
description is not _SENTINEL and
|
||||||
|
self.api_version < api_versions.APIVersion('2.19')
|
||||||
|
):
|
||||||
|
raise exceptions.UnsupportedAttribute('description', '2.19')
|
||||||
|
|
||||||
# Starting from microversion 2.54,
|
# Microversion 2.54 adds the optional 'key_name' parameter
|
||||||
# the optional 'key_name' parameter has been added.
|
if (
|
||||||
if ('key_name' in kwargs and
|
key_name is not _SENTINEL and
|
||||||
self.api_version < api_versions.APIVersion('2.54')):
|
self.api_version < api_versions.APIVersion('2.54')
|
||||||
|
):
|
||||||
raise exceptions.UnsupportedAttribute('key_name', '2.54')
|
raise exceptions.UnsupportedAttribute('key_name', '2.54')
|
||||||
|
|
||||||
# Microversion 2.57 deprecates personality files and adds support
|
# Microversion 2.57 deprecates personality files and adds support
|
||||||
# for user_data.
|
# for user_data.
|
||||||
files_and_userdata = api_versions.APIVersion('2.57')
|
if files and self.api_version >= api_versions.APIVersion('2.57'):
|
||||||
if files and self.api_version >= files_and_userdata:
|
|
||||||
raise exceptions.UnsupportedAttribute('files', '2.0', '2.56')
|
raise exceptions.UnsupportedAttribute('files', '2.0', '2.56')
|
||||||
if 'userdata' in kwargs and self.api_version < files_and_userdata:
|
|
||||||
raise exceptions.UnsupportedAttribute('userdata', '2.57')
|
|
||||||
|
|
||||||
trusted_certs_microversion = api_versions.APIVersion("2.63")
|
|
||||||
# trusted_image_certificates is intentionally *not* a named kwarg
|
|
||||||
# so that trusted_image_certificates=None is not confused with an
|
|
||||||
# intentional unset/reset request.
|
|
||||||
if ("trusted_image_certificates" in kwargs and
|
|
||||||
self.api_version < trusted_certs_microversion):
|
|
||||||
raise exceptions.UnsupportedAttribute("trusted_image_certificates",
|
|
||||||
"2.63")
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
'hostname' in kwargs and
|
userdata is not _SENTINEL and
|
||||||
self.api_version < api_versions.APIVersion("2.90")
|
self.api_version < api_versions.APIVersion('2.57')
|
||||||
|
):
|
||||||
|
raise exceptions.UnsupportedAttribute('userdata', '2.57')
|
||||||
|
|
||||||
|
# Microversion 2.63 adds trusted image certificate support
|
||||||
|
if (
|
||||||
|
trusted_image_certificates is not _SENTINEL and
|
||||||
|
self.api_version < api_versions.APIVersion('2.63')
|
||||||
|
):
|
||||||
|
raise exceptions.UnsupportedAttribute(
|
||||||
|
'trusted_image_certificates', '2.63')
|
||||||
|
|
||||||
|
# Microversion 2.90 adds the optional 'hostname' parameter
|
||||||
|
if (
|
||||||
|
hostname is not _SENTINEL and
|
||||||
|
self.api_version < api_versions.APIVersion('2.90')
|
||||||
):
|
):
|
||||||
raise exceptions.UnsupportedAttribute('hostname', '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
|
||||||
|
|
||||||
if disk_config is not None:
|
if disk_config is not None:
|
||||||
body['OS-DCF:diskConfig'] = disk_config
|
body['OS-DCF:diskConfig'] = disk_config
|
||||||
|
|
||||||
if preserve_ephemeral is not False:
|
if preserve_ephemeral is not False:
|
||||||
body['preserve_ephemeral'] = True
|
body['preserve_ephemeral'] = True
|
||||||
|
|
||||||
if name is not None:
|
if name is not None:
|
||||||
body['name'] = name
|
body['name'] = name
|
||||||
if "description" in kwargs:
|
|
||||||
body["description"] = kwargs["description"]
|
if description is not _SENTINEL:
|
||||||
if 'key_name' in kwargs:
|
body["description"] = description
|
||||||
body['key_name'] = kwargs['key_name']
|
|
||||||
if "trusted_image_certificates" in kwargs:
|
if key_name is not _SENTINEL:
|
||||||
body["trusted_image_certificates"] = kwargs[
|
body['key_name'] = key_name
|
||||||
"trusted_image_certificates"]
|
|
||||||
if "hostname" in kwargs:
|
if trusted_image_certificates is not _SENTINEL:
|
||||||
body["hostname"] = kwargs["hostname"]
|
body["trusted_image_certificates"] = trusted_image_certificates
|
||||||
|
|
||||||
|
if hostname is not _SENTINEL:
|
||||||
|
body["hostname"] = hostname
|
||||||
|
|
||||||
if meta:
|
if meta:
|
||||||
body['metadata'] = meta
|
body['metadata'] = meta
|
||||||
|
|
||||||
if files:
|
if files:
|
||||||
personality = body['personality'] = []
|
personality = body['personality'] = []
|
||||||
for filepath, file_or_string in sorted(files.items(),
|
for filepath, file_or_string in sorted(
|
||||||
key=lambda x: x[0]):
|
files.items(), key=lambda x: x[0],
|
||||||
|
):
|
||||||
if hasattr(file_or_string, 'read'):
|
if hasattr(file_or_string, 'read'):
|
||||||
data = file_or_string.read()
|
data = file_or_string.read()
|
||||||
else:
|
else:
|
||||||
@@ -1772,15 +1899,17 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
'path': filepath,
|
'path': filepath,
|
||||||
'contents': cont,
|
'contents': cont,
|
||||||
})
|
})
|
||||||
if 'userdata' in kwargs:
|
|
||||||
|
if userdata is not _SENTINEL:
|
||||||
# If userdata is specified but None, it means unset the existing
|
# If userdata is specified but None, it means unset the existing
|
||||||
# user_data on the instance.
|
# user_data on the instance.
|
||||||
userdata = kwargs['userdata']
|
userdata = userdata
|
||||||
body['user_data'] = (userdata if userdata is None else
|
body['user_data'] = (userdata if userdata is None else
|
||||||
self.transform_userdata(userdata))
|
self.transform_userdata(userdata))
|
||||||
|
|
||||||
resp, body = self._action_return_resp_and_body('rebuild', server,
|
resp, body = self._action_return_resp_and_body(
|
||||||
body, **kwargs)
|
'rebuild', server, body,
|
||||||
|
)
|
||||||
return Server(self, body['server'], resp=resp)
|
return Server(self, body['server'], resp=resp)
|
||||||
|
|
||||||
@api_versions.wraps("2.0", "2.55")
|
@api_versions.wraps("2.0", "2.55")
|
||||||
@@ -1809,26 +1938,28 @@ class ServerManager(base.BootingManagerWithFind):
|
|||||||
|
|
||||||
return self._action('migrate', server, info)
|
return self._action('migrate', server, info)
|
||||||
|
|
||||||
def resize(self, server, flavor, disk_config=None, **kwargs):
|
# NOTE(stephenfin): It would be nice to make disk_config a kwarg-only
|
||||||
|
# argument but there are backwards-compatbility concerns
|
||||||
|
def resize(self, server, flavor, disk_config=None):
|
||||||
"""
|
"""
|
||||||
Resize a server's resources.
|
Resize a server's resources.
|
||||||
|
|
||||||
:param server: The :class:`Server` (or its ID) to share onto.
|
:param server: The :class:`Server` (or its ID) to share onto.
|
||||||
:param flavor: the :class:`Flavor` (or its ID) to resize to.
|
:param flavor: The :class:`Flavor` (or its ID) to resize to.
|
||||||
: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'.
|
||||||
:returns: An instance of novaclient.base.TupleWithMeta
|
:returns: An instance of novaclient.base.TupleWithMeta
|
||||||
|
|
||||||
Until a resize event is confirmed with :meth:`confirm_resize`, the old
|
Until a resize event is confirmed with :meth:`confirm_resize`, the old
|
||||||
server will be kept around and you'll be able to roll back to the old
|
server will be kept around and you'll be able to roll back to the old
|
||||||
flavor quickly with :meth:`revert_resize`. All resizes are
|
flavor quickly with :meth:`revert_resize`. All resizes are
|
||||||
automatically confirmed after 24 hours.
|
automatically confirmed after 24 hours by default.
|
||||||
"""
|
"""
|
||||||
info = {'flavorRef': base.getid(flavor)}
|
info = {'flavorRef': base.getid(flavor)}
|
||||||
if disk_config is not None:
|
if disk_config is not None:
|
||||||
info['OS-DCF:diskConfig'] = disk_config
|
info['OS-DCF:diskConfig'] = disk_config
|
||||||
|
|
||||||
return self._action('resize', server, info=info, **kwargs)
|
return self._action('resize', server, info=info)
|
||||||
|
|
||||||
def confirm_resize(self, server):
|
def confirm_resize(self, server):
|
||||||
"""
|
"""
|
||||||
|
@@ -2057,14 +2057,15 @@ def do_rebuild(cs, args):
|
|||||||
server = _find_server(cs, args.server)
|
server = _find_server(cs, args.server)
|
||||||
image = _find_image(cs, args.image)
|
image = _find_image(cs, args.image)
|
||||||
|
|
||||||
if args.rebuild_password is not False:
|
|
||||||
_password = args.rebuild_password
|
|
||||||
else:
|
|
||||||
_password = None
|
|
||||||
|
|
||||||
kwargs = {'preserve_ephemeral': args.preserve_ephemeral,
|
kwargs = {'preserve_ephemeral': args.preserve_ephemeral,
|
||||||
'name': args.name,
|
'name': args.name,
|
||||||
'meta': _meta_parsing(args.meta)}
|
'meta': _meta_parsing(args.meta)}
|
||||||
|
|
||||||
|
if args.rebuild_password is not False:
|
||||||
|
kwargs['password'] = args.rebuild_password
|
||||||
|
else:
|
||||||
|
kwargs['password'] = None
|
||||||
|
|
||||||
if 'description' in args:
|
if 'description' in args:
|
||||||
kwargs['description'] = args.description
|
kwargs['description'] = args.description
|
||||||
|
|
||||||
@@ -2145,7 +2146,7 @@ def do_rebuild(cs, args):
|
|||||||
if 'hostname' in args and args.hostname is not None:
|
if 'hostname' in args and args.hostname is not None:
|
||||||
kwargs['hostname'] = args.hostname
|
kwargs['hostname'] = args.hostname
|
||||||
|
|
||||||
server = server.rebuild(image, _password, **kwargs)
|
server = server.rebuild(image, **kwargs)
|
||||||
_print_server(cs, args, server)
|
_print_server(cs, args, server)
|
||||||
|
|
||||||
if args.poll:
|
if args.poll:
|
||||||
|
Reference in New Issue
Block a user