Destroy the named VMs

def destroy(self, names, cached=False):
        '''
        Destroy the named VMs
        '''
        processed = {}
        names = set(names)
        matching = self.get_running_by_names(names, cached=cached)
        vms_to_destroy = set()
        parallel_data = []
        for alias, drivers in six.iteritems(matching):
            for driver, vms in six.iteritems(drivers):
                for name in vms:
                    if name in names:
                        vms_to_destroy.add((alias, driver, name))
                        if self.opts['parallel']:
                            parallel_data.append({
                                'opts': self.opts,
                                'name': name,
                                'alias': alias,
                                'driver': driver,
                            })

        # destroying in parallel
        if self.opts['parallel'] and parallel_data:
            # set the pool size based on configuration or default to
            # the number of machines we're destroying
            if 'pool_size' in self.opts:
                pool_size = self.opts['pool_size']
            else:
                pool_size = len(parallel_data)
            log.info('Destroying in parallel mode; '
                     'Cloud pool size: %s', pool_size)

            # kick off the parallel destroy
            output_multip = enter_mainloop(
                _destroy_multiprocessing, parallel_data, pool_size=pool_size)

            # massage the multiprocessing output a bit
            ret_multip = {}
            for obj in output_multip:
                ret_multip.update(obj)

            # build up a data structure similar to what the non-parallel
            # destroy uses
            for obj in parallel_data:
                alias = obj['alias']
                driver = obj['driver']
                name = obj['name']
                if alias not in processed:
                    processed[alias] = {}
                if driver not in processed[alias]:
                    processed[alias][driver] = {}
                processed[alias][driver][name] = ret_multip[name]
                if name in names:
                    names.remove(name)

        # not destroying in parallel
        else:
            log.info('Destroying in non-parallel mode.')
            for alias, driver, name in vms_to_destroy:
                fun = '{0}.destroy'.format(driver)
                with salt.utils.context.func_globals_inject(
                    self.clouds[fun],
                    __active_provider_name__=':'.join([alias, driver])
                ):
                    ret = self.clouds[fun](name)
                if alias not in processed:
                    processed[alias] = {}
                if driver not in processed[alias]:
                    processed[alias][driver] = {}
                processed[alias][driver][name] = ret
                if name in names:
                    names.remove(name)

        # now the processed data structure contains the output from either
        # the parallel or non-parallel destroy and we should finish up
        # with removing minion keys if necessary
        for alias, driver, name in vms_to_destroy:
            ret = processed[alias][driver][name]
            if not ret:
                continue

            vm_ = {
                'name': name,
                'profile': None,
                'provider': ':'.join([alias, driver]),
                'driver': driver
            }
            minion_dict = salt.config.get_cloud_config_value(
                'minion', vm_, self.opts, default={}
            )
            key_file = os.path.join(
                self.opts['pki_dir'], 'minions', minion_dict.get('id', name)
            )
            globbed_key_file = glob.glob('{0}.*'.format(key_file))

            if not os.path.isfile(key_file) and not globbed_key_file:
                # There's no such key file!? It might have been renamed
                if isinstance(ret, dict) and 'newname' in ret:
                    salt.utils.cloud.remove_key(
                        self.opts['pki_dir'], ret['newname']
                    )
                continue

            if os.path.isfile(key_file) and not globbed_key_file:
                # Single key entry. Remove it!
                salt.utils.cloud.remove_key(self.opts['pki_dir'], os.path.basename(key_file))
                continue

            # Since we have globbed matches, there are probably some keys for which their minion
            # configuration has append_domain set.
            if not os.path.isfile(key_file) and globbed_key_file and len(globbed_key_file) == 1:
                # Single entry, let's remove it!
                salt.utils.cloud.remove_key(
                    self.opts['pki_dir'],
                    os.path.basename(globbed_key_file[0])
                )
                continue

            # Since we can't get the profile or map entry used to create
            # the VM, we can't also get the append_domain setting.
            # And if we reached this point, we have several minion keys
            # who's name starts with the machine name we're deleting.
            # We need to ask one by one!?
            print(
                'There are several minion keys who\'s name starts '
                'with \'{0}\'. We need to ask you which one should be '
                'deleted:'.format(
                    name
                )
            )
            while True:
                for idx, filename in enumerate(globbed_key_file):
                    print(' {0}: {1}'.format(
                        idx, os.path.basename(filename)
                    ))
                selection = input(
                    'Which minion key should be deleted(number)? '
                )
                try:
                    selection = int(selection)
                except ValueError:
                    print(
                        '\'{0}\' is not a valid selection.'.format(selection)
                    )

                try:
                    filename = os.path.basename(
                        globbed_key_file.pop(selection)
                    )
                except Exception:
                    continue

                delete = input(
                    'Delete \'{0}\'? [Y/n]? '.format(filename)
                )
                if delete == '' or delete.lower().startswith('y'):
                    salt.utils.cloud.remove_key(
                        self.opts['pki_dir'], filename
                    )
                    print('Deleted \'{0}\''.format(filename))
                    break

                print('Did not delete \'{0}\''.format(filename))
                break

        if names and not processed:
            # These machines were asked to be destroyed but could not be found
            raise SaltCloudSystemExit(
                'The following VM\'s were not found: {0}'.format(
                    ', '.join(names)
                )
            )

        elif names and processed:
            processed['Not Found'] = names

        elif not processed:
            raise SaltCloudSystemExit('No machines were destroyed!')

        return processed