'Convert the volume to be of the new type.
Returns a boolean indicating whether the retype occurred.
:param ctxt: Context
:param volume: A dictionary describing the volume to migrate
:param new_type: A dictionary describing the volume type to convert to
:param diff: A dictionary with the difference between the two types
:param host: A dictionary describing the host to migrate to, where
host[\'host\'] is its name, and host[\'capabilities\'] is a
dictionary of its reported capabilities.'

def retype(self, ctxt, volume, new_type, diff, host):

    def retype_iogrp_property(volume, new, old):
        if (new != old):
            self._helpers.change_vdisk_iogrp(volume['name'], self._state, (new, old))
    LOG.debug('enter:    retype:    id=%(id)s,    new_type=%(new_type)s,diff=%(diff)s,    host=%(host)s', {'id': volume['id'], 'new_type': new_type, 'diff': diff, 'host': host})
    no_copy_keys = ['warning', 'autoexpand', 'easytier']
    copy_keys = ['rsize', 'grainsize', 'compression']
    all_keys = (no_copy_keys + copy_keys)
    old_opts = self._get_vdisk_params(volume['volume_type_id'], volume_metadata=volume.get('volume_matadata'))
    new_opts = self._get_vdisk_params(new_type['id'], volume_type=new_type)
    vdisk_changes = []
    need_copy = False
    change_mirror = False
    for key in all_keys:
        if (old_opts[key] != new_opts[key]):
            if (key in copy_keys):
                need_copy = True
                break
            elif (key in no_copy_keys):
                vdisk_changes.append(key)
    if (utils.extract_host(volume['host'], 'pool') != utils.extract_host(host['host'], 'pool')):
        need_copy = True
    if (old_opts['mirror_pool'] != new_opts['mirror_pool']):
        change_mirror = True
    model_update = None
    new_rep_type = self._get_specs_replicated_type(new_type)
    old_rep_type = self._get_volume_replicated_type(ctxt, volume)
    old_io_grp = self._helpers.get_volume_io_group(volume['name'])
    new_io_grp = self._helpers.select_io_group(self._state, new_opts)
    self._verify_retype_params(volume, new_opts, old_opts, need_copy, change_mirror, new_rep_type, old_rep_type)
    if need_copy:
        self._check_volume_copy_ops()
        dest_pool = self._helpers.can_migrate_to_host(host, self._state)
        if (dest_pool is None):
            return False
        retype_iogrp_property(volume, new_io_grp, old_io_grp)
        try:
            self.add_vdisk_copy(volume['name'], dest_pool, new_type, auto_delete=True)
        except exception.VolumeDriverException:
            retype_iogrp_property(volume, old_io_grp, new_io_grp)
            msg = (_('Unable    to    retype:        A    copy    of    volume    %s    exists.    Retyping    would    exceed    the    limit    of    2    copies.'), volume['id'])
            raise exception.VolumeDriverException(message=msg)
    else:
        retype_iogrp_property(volume, new_io_grp, old_io_grp)
        self._helpers.change_vdisk_options(volume['name'], vdisk_changes, new_opts, self._state)
        if change_mirror:
            copies = self._helpers.get_vdisk_copies(volume.name)
            if ((not old_opts['mirror_pool']) and new_opts['mirror_pool']):
                self.add_vdisk_copy(volume['name'], new_opts['mirror_pool'], new_type)
            elif (old_opts['mirror_pool'] and (not new_opts['mirror_pool'])):
                secondary = copies['secondary']
                if secondary:
                    self._helpers.rm_vdisk_copy(volume.name, secondary['copy_id'])
            else:
                self._helpers.migratevdisk(volume.name, new_opts['mirror_pool'], copies['secondary']['copy_id'])
    if new_opts['qos']:
        self._helpers.update_vdisk_qos(volume['name'], new_opts['qos'])
    elif old_opts['qos']:
        self._helpers.disable_vdisk_qos(volume['name'], old_opts['qos'])
    if (old_rep_type and (not new_rep_type)):
        self._aux_backend_helpers.delete_rc_volume(volume['name'], target_vol=True)
        if (storwize_const.GMCV == old_rep_type):
            self._helpers.delete_vdisk((storwize_const.REPLICA_CHG_VOL_PREFIX + volume['name']), False)
        model_update = {'replication_status': fields.ReplicationStatus.DISABLED, 'replication_driver_data': None, 'replication_extended_status': None}
    if ((not old_rep_type) and new_rep_type):
        replica_obj = self._get_replica_obj(new_rep_type)
        replica_obj.volume_replication_setup(ctxt, volume)
        if (storwize_const.GMCV == new_rep_type):
            self._helpers.change_relationship_cycleperiod(volume['name'], new_opts.get('cycle_period_seconds'))
        model_update = {'replication_status': fields.ReplicationStatus.ENABLED}
    LOG.debug('exit:    retype:    ild=%(id)s,    new_type=%(new_type)s,diff=%(diff)s,    host=%(host)s', {'id': volume['id'], 'new_type': new_type, 'diff': diff, 'host': host['host']})
    return (True, model_update)
