Add preserve_ephemeral support for rebuilding

Currently we don't support preserving ephemeral partition when
requesting to rebuild, we need to expose the ability to users.

Change-Id: Ia10ab6a8d6dd6beba8837e7d0414dc6984dd2426
Closes-Bug: #1714852
This commit is contained in:
Zhenguo Niu 2017-09-04 14:26:25 +08:00
parent 6e28762b40
commit 7d78b09a01
9 changed files with 37 additions and 17 deletions

View File

@ -580,6 +580,13 @@ power_state_target:
in: body in: body
required: true required: true
type: string type: string
preserve_ephemeral:
description: |
Indicates whether the server is rebuilt with the preservation of the ephemeral
partition (``true``).
in: body
required: false
type: boolean
project_id_body: project_id_body:
description: | description: |
The UUID of the project in a multi-tenancy cloud. The UUID of the project in a multi-tenancy cloud.

View File

@ -1,4 +1,5 @@
{ {
"target": "rebuild", "target": "rebuild",
"image_uuid":"9145be5b-38d0-4a05-8dd6-837a8ec15281" "image_uuid": "9145be5b-38d0-4a05-8dd6-837a8ec15281",
"preserve_ephemeral": True
} }

View File

@ -130,6 +130,7 @@ Request
- server_uuid: server_ident - server_uuid: server_ident
- target: provision_state - target: provision_state
- image_uuid: image_ident - image_uuid: image_ident
- preserve_ephemeral: preserve_ephemeral
**Example request to rebuild a Server:** **Example request to rebuild a Server:**

View File

@ -161,8 +161,9 @@ class ServerStatesController(ServerControllerBase):
@policy.authorize_wsgi("mogan:server", "set_provision_state") @policy.authorize_wsgi("mogan:server", "set_provision_state")
@expose.expose(None, types.uuid, wtypes.text, types.uuid, @expose.expose(None, types.uuid, wtypes.text, types.uuid,
status_code=http_client.ACCEPTED) types.boolean, status_code=http_client.ACCEPTED)
def provision(self, server_uuid, target, image_uuid=None): def provision(self, server_uuid, target, image_uuid=None,
preserve_ephemeral=None):
"""Asynchronous trigger the provisioning of the server. """Asynchronous trigger the provisioning of the server.
This will set the target provision state of the server, and This will set the target provision state of the server, and
@ -174,6 +175,8 @@ class ServerStatesController(ServerControllerBase):
:param server_uuid: UUID of a server. :param server_uuid: UUID of a server.
:param target: The desired provision state of the server or verb. :param target: The desired provision state of the server or verb.
:param image_uuid: UUID of the image rebuilt with.
:param preserve_ephemeral: whether preserve the ephemeral parition.
""" """
# Currently we only support rebuild target # Currently we only support rebuild target
@ -184,7 +187,7 @@ class ServerStatesController(ServerControllerBase):
db_server = self._resource or self._get_resource(server_uuid) db_server = self._resource or self._get_resource(server_uuid)
if target == states.REBUILD: if target == states.REBUILD:
pecan.request.engine_api.rebuild(pecan.request.context, db_server, pecan.request.engine_api.rebuild(pecan.request.context, db_server,
image_uuid) image_uuid, preserve_ephemeral)
# Set the HTTP Location Header # Set the HTTP Location Header
url_args = '/'.join([server_uuid, 'states']) url_args = '/'.join([server_uuid, 'states'])

View File

@ -136,7 +136,7 @@ class IronicDriver(base_driver.BaseEngineDriver):
} }
return dic return dic
def _add_server_info_to_node(self, node, server): def _add_server_info_to_node(self, node, server, preserve_ephemeral=None):
patch = list() patch = list()
# Associate the node with a server # Associate the node with a server
patch.append({'path': '/instance_uuid', 'op': 'add', patch.append({'path': '/instance_uuid', 'op': 'add',
@ -147,6 +147,9 @@ class IronicDriver(base_driver.BaseEngineDriver):
# TODO(zhenguo) Add partition support # TODO(zhenguo) Add partition support
patch.append({'path': '/instance_info/root_gb', 'op': 'add', patch.append({'path': '/instance_info/root_gb', 'op': 'add',
'value': str(node.properties.get('local_gb', 0))}) 'value': str(node.properties.get('local_gb', 0))})
if preserve_ephemeral is not None:
patch.append({'path': '/instance_info/preserve_ephemeral',
'op': 'add', 'value': str(preserve_ephemeral)})
try: try:
# FIXME(lucasagomes): The "retry_on_conflict" parameter was added # FIXME(lucasagomes): The "retry_on_conflict" parameter was added
@ -516,17 +519,18 @@ class IronicDriver(base_driver.BaseEngineDriver):
self._wait_for_power_state, server, state) self._wait_for_power_state, server, state)
timer.start(interval=CONF.ironic.api_retry_interval).wait() timer.start(interval=CONF.ironic.api_retry_interval).wait()
def rebuild(self, context, server): def rebuild(self, context, server, preserve_ephemeral):
"""Rebuild/redeploy a server. """Rebuild/redeploy a server.
:param context: The security context. :param context: The security context.
:param server: The server object. :param server: The server object.
:param preserve_ephemeral: whether preserve ephemeral partition
""" """
LOG.debug('Rebuild called for server', server=server) LOG.debug('Rebuild called for server', server=server)
node_ident = server.node_ident node_ident = server.node_ident
node = self._get_node(node_ident) node = self._get_node(node_ident)
self._add_server_info_to_node(node, server) self._add_server_info_to_node(node, server, preserve_ephemeral)
# trigger the node rebuild # trigger the node rebuild
try: try:

View File

@ -397,7 +397,8 @@ class API(object):
@check_server_lock @check_server_lock
@check_server_maintenance @check_server_maintenance
def rebuild(self, context, server, image_uuid=None): def rebuild(self, context, server, image_uuid=None,
preserve_ephemeral=None):
"""Rebuild a server.""" """Rebuild a server."""
LOG.debug("Going to try to rebuild server %s", server.uuid) LOG.debug("Going to try to rebuild server %s", server.uuid)
if not image_uuid: if not image_uuid:
@ -417,7 +418,7 @@ class API(object):
server=server) server=server)
return return
self.engine_rpcapi.rebuild_server(context, server) self.engine_rpcapi.rebuild_server(context, server, preserve_ephemeral)
def list_availability_zones(self, context): def list_availability_zones(self, context):
"""Get availability zone list.""" """Get availability zone list."""

View File

@ -515,26 +515,27 @@ class EngineManager(base_manager.BaseEngineManager):
LOG.info('Successfully set node power state: %s', LOG.info('Successfully set node power state: %s',
state, server=server) state, server=server)
def _rebuild_server(self, context, server): def _rebuild_server(self, context, server, preserve_ephemeral):
"""Perform rebuild action on the specified server.""" """Perform rebuild action on the specified server."""
# TODO(zhenguo): Add delete notification # TODO(zhenguo): Add rebuild notification
self.driver.rebuild(context, server) self.driver.rebuild(context, server, preserve_ephemeral)
@wrap_server_fault @wrap_server_fault
def rebuild_server(self, context, server): def rebuild_server(self, context, server, preserve_ephemeral):
"""Destroy and re-make this server. """Destroy and re-make this server.
:param context: mogan request context :param context: mogan request context
:param server: server object :param server: server object
:param preserve_ephemeral: whether preserve ephemeral partition
""" """
LOG.debug('Rebuilding server: %s', server) LOG.debug('Rebuilding server: %s', server)
fsm = utils.get_state_machine(start_state=server.status) fsm = utils.get_state_machine(start_state=server.status)
try: try:
self._rebuild_server(context, server) self._rebuild_server(context, server, preserve_ephemeral)
except Exception as e: except Exception as e:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
utils.process_event(fsm, server, event='error') utils.process_event(fsm, server, event='error')

View File

@ -73,10 +73,11 @@ class EngineAPI(object):
return cctxt.cast(context, 'set_power_state', return cctxt.cast(context, 'set_power_state',
server=server, state=state) server=server, state=state)
def rebuild_server(self, context, server): def rebuild_server(self, context, server, preserve_ephemeral):
"""Signal to engine service to rebuild a server.""" """Signal to engine service to rebuild a server."""
cctxt = self.client.prepare(topic=self.topic, server=CONF.host) cctxt = self.client.prepare(topic=self.topic, server=CONF.host)
return cctxt.cast(context, 'rebuild_server', server=server) return cctxt.cast(context, 'rebuild_server', server=server,
preserve_ephemeral=preserve_ephemeral)
def get_serial_console(self, context, server, console_type): def get_serial_console(self, context, server, console_type):
cctxt = self.client.prepare(topic=self.topic, server=CONF.host) cctxt = self.client.prepare(topic=self.topic, server=CONF.host)

View File

@ -130,4 +130,5 @@ class RPCAPITestCase(base.DbTestCase):
self._test_rpcapi('rebuild_server', self._test_rpcapi('rebuild_server',
'cast', 'cast',
version='1.0', version='1.0',
server=self.fake_server_obj) server=self.fake_server_obj,
preserve_ephemeral=True)