def prepare_cleaning_ports(task):
    """Prepare the Ironic ports of the node for cleaning.

    This method deletes the cleaning ports currently existing
    for all the ports of the node and then creates a new one
    for each one of them.  It also adds 'vif_port_id' to port.extra
    of each Ironic port, after creating the cleaning ports.

    :param task: a TaskManager object containing the node
    :raises NodeCleaningFailure: if the previous cleaning ports cannot
        be removed or if new cleaning ports cannot be created
    """
    provider = dhcp_factory.DHCPFactory()
    # If we have left over ports from a previous cleaning, remove them
    if getattr(provider.provider, 'delete_cleaning_ports', None):
        # Allow to raise if it fails, is caught and handled in conductor
        provider.provider.delete_cleaning_ports(task)

    # Create cleaning ports if necessary
    if getattr(provider.provider, 'create_cleaning_ports', None):
        # Allow to raise if it fails, is caught and handled in conductor
        ports = provider.provider.create_cleaning_ports(task)

        # Add vif_port_id for each of the ports because some boot
        # interfaces expects these to prepare for booting ramdisk.
        for port in task.ports:
            extra_dict = port.extra
            try:
                extra_dict['vif_port_id'] = ports[port.uuid]
            except __HOLE__:
                # This is an internal error in Ironic.  All DHCP providers
                # implementing create_cleaning_ports are supposed to
                # return a VIF port ID for all Ironic ports.  But
                # that doesn't seem to be true here.
                error = (_("When creating cleaning ports, DHCP provider "
                           "didn't return VIF port ID for %s") % port.uuid)
                raise exception.NodeCleaningFailure(
                    node=task.node.uuid, reason=error)
            else:
                port.extra = extra_dict
                port.save()
dataset/ETHPy150Open openstack/ironic/ironic/drivers/modules/deploy_utils.py/prepare_cleaning_ports