docs: def request_instance(vm_=None, call=None):
      '''
      Put together all of the information necessary to request an instance
      through Novaclient and then fire off the request the instance.
  
      Returns data about the instance
      '''
      if call == 'function':
          # Technically this function may be called other ways too, but it
          # definitely cannot be called with --function.
          raise SaltCloudSystemExit(
              'The request_instance action must be called with -a or --action.'
          )
      log.info('Creating Cloud VM %s', vm_['name'])
      salt.utils.cloud.check_name(vm_['name'], 'a-zA-Z0-9._-')
      conn = get_conn()
      kwargs = vm_.copy()
  
      try:
          kwargs['image_id'] = get_image(conn, vm_)
      except Exception as exc:
          raise SaltCloudSystemExit(
              'Error creating {0} on OPENSTACK\n\n'
              'Could not find image {1}: {2}\n'.format(
                  vm_['name'], vm_['image'], exc
              )
          )
  
      try:
          kwargs['flavor_id'] = get_size(conn, vm_)
      except Exception as exc:
          raise SaltCloudSystemExit(
              'Error creating {0} on OPENSTACK\n\n'
              'Could not find size {1}: {2}\n'.format(
                  vm_['name'], vm_['size'], exc
              )
          )
  
      kwargs['key_name'] = config.get_cloud_config_value(
          'ssh_key_name', vm_, __opts__, search_global=False
      )
  
      security_groups = config.get_cloud_config_value(
          'security_groups', vm_, __opts__, search_global=False
      )
      if security_groups is not None:
          vm_groups = security_groups
          avail_groups = conn.secgroup_list()
          group_list = []
  
          for vmg in vm_groups:
              if vmg in [name for name, details in six.iteritems(avail_groups)]:
                  group_list.append(vmg)
              else:
                  raise SaltCloudNotFound(
                      'No such security group: \'{0}\''.format(vmg)
                  )
  
          kwargs['security_groups'] = group_list
  
      avz = config.get_cloud_config_value(
          'availability_zone', vm_, __opts__, default=None, search_global=False
      )
      if avz is not None:
          kwargs['availability_zone'] = avz
  
      kwargs['nics'] = config.get_cloud_config_value(
          'networks', vm_, __opts__, search_global=False, default=None
      )
  
      files = config.get_cloud_config_value(
          'files', vm_, __opts__, search_global=False
      )
      if files:
          kwargs['files'] = {}
          for src_path in files:
              if os.path.exists(files[src_path]):
                  with salt.utils.files.fopen(files[src_path], 'r') as fp_:
                      kwargs['files'][src_path] = fp_.read()
              else:
                  kwargs['files'][src_path] = files[src_path]
  
      userdata_file = config.get_cloud_config_value(
          'userdata_file', vm_, __opts__, search_global=False, default=None
      )
      if userdata_file is not None:
          try:
              with salt.utils.files.fopen(userdata_file, 'r') as fp_:
                  kwargs['userdata'] = salt.utils.cloud.userdata_template(
                      __opts__, vm_, fp_.read()
                  )
          except Exception as exc:
              log.exception(
                  'Failed to read userdata from %s: %s', userdata_file, exc)
  
      kwargs['config_drive'] = config.get_cloud_config_value(
          'config_drive', vm_, __opts__, search_global=False
      )
  
      kwargs.update(get_block_mapping_opts(vm_))
  
      event_kwargs = {
          'name': kwargs['name'],
          'image': kwargs.get('image_id', 'Boot From Volume'),
          'size': kwargs['flavor_id'],
      }
  
      __utils__['cloud.fire_event'](
          'event',
          'requesting instance',
          'salt/cloud/{0}/requesting'.format(vm_['name']),
          args={
              'kwargs': __utils__['cloud.filter_event']('requesting', event_kwargs, list(event_kwargs)),
          },
          sock_dir=__opts__['sock_dir'],
          transport=__opts__['transport']
      )
  
      try:
          data = conn.boot(**kwargs)
      except Exception as exc:
          raise SaltCloudSystemExit(
              'Error creating {0} on Nova\n\n'
              'The following exception was thrown by libcloud when trying to '
              'run the initial deployment: {1}\n'.format(
                  vm_['name'], exc
              )
          )
      if data.extra.get('password', None) is None and vm_.get('key_filename', None) is None:
          raise SaltCloudSystemExit('No password returned.  Set ssh_key_file.')
  
      floating_ip_conf = config.get_cloud_config_value('floating_ip',
                                                       vm_,
                                                       __opts__,
                                                       search_global=False,
                                                       default={})
      if floating_ip_conf.get('auto_assign', False):
          floating_ip = None
          if floating_ip_conf.get('ip_address', None) is not None:
              ip_address = floating_ip_conf.get('ip_address', None)
              try:
                  fl_ip_dict = conn.floating_ip_show(ip_address)
                  floating_ip = fl_ip_dict['ip']
              except Exception as err:
                  raise SaltCloudSystemExit(
                      'Error assigning floating_ip for {0} on Nova\n\n'
                      'The following exception was thrown by libcloud when trying to '
                      'assign a floating ip: {1}\n'.format(
                          vm_['name'], err
                      )
                  )
  
          else:
              pool = floating_ip_conf.get('pool', 'public')
              try:
                  floating_ip = conn.floating_ip_create(pool)['ip']
              except Exception:
                  log.info('A new IP address was unable to be allocated. '
                           'An IP address will be pulled from the already allocated list, '
                           'This will cause a race condition when building in parallel.')
                  for fl_ip, opts in six.iteritems(conn.floating_ip_list()):
                      if opts['fixed_ip'] is None and opts['pool'] == pool:
                          floating_ip = fl_ip
                          break
                  if floating_ip is None:
                      log.error('No IP addresses available to allocate for this server: %s', vm_['name'])
  
          def __query_node_data(vm_):
              try:
                  node = show_instance(vm_['name'], 'action')
                  log.debug('Loaded node data for %s:\n%s', vm_['name'], pprint.pformat(node))
              except Exception as err:
                  log.error(
                      'Failed to get nodes list: %s', err,
                      # Show the traceback if the debug logging level is enabled
                      exc_info_on_loglevel=logging.DEBUG
                  )
                  # Trigger a failure in the wait for IP function
                  return False
              return node['state'] == 'ACTIVE' or None
  
          # if we associate the floating ip here,then we will fail.
          # As if we attempt to associate a floating IP before the Nova instance has completed building,
          # it will fail.So we should associate it after the Nova instance has completed building.
          try:
              salt.utils.cloud.wait_for_ip(
                  __query_node_data,
                  update_args=(vm_,)
              )
          except (SaltCloudExecutionTimeout, SaltCloudExecutionFailure) as exc:
              try:
                  # It might be already up, let's destroy it!
                  destroy(vm_['name'])
              except SaltCloudSystemExit:
                  pass
              finally:
                  raise SaltCloudSystemExit(six.text_type(exc))
  
          try:
              conn.floating_ip_associate(vm_['name'], floating_ip)
              vm_['floating_ip'] = floating_ip
          except Exception as exc:
              raise SaltCloudSystemExit(
                  'Error assigning floating_ip for {0} on Nova\n\n'
                  'The following exception was thrown by libcloud when trying to '
                  'assign a floating ip: {1}\n'.format(
                      vm_['name'], exc
                  )
              )
  
      if not vm_.get('password', None):
          vm_['password'] = data.extra.get('password', '')
  
      return data, vm_