Get grains for minion.

    .. code-block: bash

        salt '*' nxos.cmd grains
178236
def grains(**kwargs):
    '''
    
    '''
    if not DEVICE_DETAILS['grains_cache']:
        ret = salt.utils.nxos.system_info(show_ver(**kwargs))
        log.debug(ret)
        DEVICE_DETAILS['grains_cache'].update(ret['nxos'])
    return DEVICE_DETAILS['grains_cache']
388354
def run_wfunc(self):
        '''
        
        '''
        # Ensure that opts/grains are up to date
        # Execute routine
        data_cache = False
        data = None
        cdir = os.path.join(self.opts['cachedir'], 'minions', self.id)
        if not os.path.isdir(cdir):
            os.makedirs(cdir)
        datap = os.path.join(cdir, 'ssh_data.p')
        refresh = False
        if not os.path.isfile(datap):
            refresh = True
        else:
            passed_time = (time.time() - os.stat(datap).st_mtime) / 60
            if passed_time > self.opts.get('cache_life', 60):
                refresh = True

        if self.opts.get('refresh_cache'):
            refresh = True
        conf_grains = {}
        # Save conf file grains before they get clobbered
        if 'ssh_grains' in self.opts:
            conf_grains = self.opts['ssh_grains']
        if not data_cache:
            refresh = True
        if refresh:
            # Make the datap
            # TODO: Auto expire the datap
            pre_wrapper = salt.client.ssh.wrapper.FunctionWrapper(
                self.opts,
                self.id,
                fsclient=self.fsclient,
                minion_opts=self.minion_opts,
                **self.target)
            opts_pkg = pre_wrapper['test.opts_pkg']()  # pylint: disable=E1102
            if '_error' in opts_pkg:
                #Refresh failed
                retcode = opts_pkg['retcode']
                ret = salt.utils.json.dumps({'local': opts_pkg})
                return ret, retcode

            opts_pkg['file_roots'] = self.opts['file_roots']
            opts_pkg['pillar_roots'] = self.opts['pillar_roots']
            opts_pkg['ext_pillar'] = self.opts['ext_pillar']
            opts_pkg['extension_modules'] = self.opts['extension_modules']
            opts_pkg['module_dirs'] = self.opts['module_dirs']
            opts_pkg['_ssh_version'] = self.opts['_ssh_version']
            opts_pkg['__master_opts__'] = self.context['master_opts']
            if 'known_hosts_file' in self.opts:
                opts_pkg['known_hosts_file'] = self.opts['known_hosts_file']
            if '_caller_cachedir' in self.opts:
                opts_pkg['_caller_cachedir'] = self.opts['_caller_cachedir']
            else:
                opts_pkg['_caller_cachedir'] = self.opts['cachedir']
            # Use the ID defined in the roster file
            opts_pkg['id'] = self.id

            retcode = 0

            # Restore master grains
            for grain in conf_grains:
                opts_pkg['grains'][grain] = conf_grains[grain]
            # Enable roster grains support
            if 'grains' in self.target:
                for grain in self.target['grains']:
                    opts_pkg['grains'][grain] = self.target['grains'][grain]

            popts = {}
            popts.update(opts_pkg)

            # Master centric operations such as mine.get must have master option loaded.
            # The pillar must then be compiled by passing master opts found in opts_pkg['__master_opts__']
            # which causes the pillar renderer to loose track of salt master options
            #
            # Depending on popts merge order, it will overwrite some options found in opts_pkg['__master_opts__']
            master_centric_funcs = [
              "pillar.items",
              "mine.get"
            ]

            # Pillar compilation is a master centric operation.
            # Master options take precedence during Pillar compilation
            popts.update(opts_pkg['__master_opts__'])

            pillar = salt.pillar.Pillar(
                    popts,
                    opts_pkg['grains'],
                    opts_pkg['id'],
                    opts_pkg.get('saltenv', 'base')
                    )
            pillar_data = pillar.compile_pillar()

            # Once pillar has been compiled, restore priority of minion opts
            if self.fun not in master_centric_funcs:
                log.debug('%s is a minion function', self.fun)
                popts.update(opts_pkg)
            else:
                log.debug('%s is a master function', self.fun)

            # TODO: cache minion opts in datap in master.py
            data = {'opts': opts_pkg,
                    'grains': opts_pkg['grains'],
                    'pillar': pillar_data}
            if data_cache:
                with salt.utils.files.fopen(datap, 'w+b') as fp_:
                    fp_.write(
                            self.serial.dumps(data)
                            )
        if not data and data_cache:
            with salt.utils.files.fopen(datap, 'rb') as fp_:
                data = self.serial.load(fp_)
        opts = data.get('opts', {})
        opts['grains'] = data.get('grains')

        # Restore master grains
        for grain in conf_grains:
            opts['grains'][grain] = conf_grains[grain]
        # Enable roster grains support
        if 'grains' in self.target:
            for grain in self.target['grains']:
                opts['grains'][grain] = self.target['grains'][grain]

        opts['pillar'] = data.get('pillar')
        wrapper = salt.client.ssh.wrapper.FunctionWrapper(
            opts,
            self.id,
            fsclient=self.fsclient,
            minion_opts=self.minion_opts,
            **self.target)
        self.wfuncs = salt.loader.ssh_wrapper(opts, wrapper, self.context)
        wrapper.wfuncs = self.wfuncs

        # We're running in the mine, need to fetch the arguments from the
        # roster, pillar, master config (in that order)
        if self.mine:
            mine_args = None
            mine_fun_data = None
            mine_fun = self.fun

            if self.mine_functions and self.fun in self.mine_functions:
                mine_fun_data = self.mine_functions[self.fun]
            elif opts['pillar'] and self.fun in opts['pillar'].get('mine_functions', {}):
                mine_fun_data = opts['pillar']['mine_functions'][self.fun]
            elif self.fun in self.context['master_opts'].get('mine_functions', {}):
                mine_fun_data = self.context['master_opts']['mine_functions'][self.fun]

            if isinstance(mine_fun_data, dict):
                mine_fun = mine_fun_data.pop('mine_function', mine_fun)
                mine_args = mine_fun_data
            elif isinstance(mine_fun_data, list):
                for item in mine_fun_data[:]:
                    if isinstance(item, dict) and 'mine_function' in item:
                        mine_fun = item['mine_function']
                        mine_fun_data.pop(mine_fun_data.index(item))
                mine_args = mine_fun_data
            else:
                mine_args = mine_fun_data

            # If we found mine_args, replace our command's args
            if isinstance(mine_args, dict):
                self.args = []
                self.kwargs = mine_args
            elif isinstance(mine_args, list):
                self.args = mine_args
                self.kwargs = {}

        try:
            if self.mine:
                result = wrapper[mine_fun](*self.args, **self.kwargs)
            else:
                result = self.wfuncs[self.fun](*self.args, **self.kwargs)
        except TypeError as exc:
            result = 'TypeError encountered executing {0}: {1}'.format(self.fun, exc)
            log.error(result, exc_info_on_loglevel=logging.DEBUG)
            retcode = 1
        except Exception as exc:
            result = 'An Exception occurred while executing {0}: {1}'.format(self.fun, exc)
            log.error(result, exc_info_on_loglevel=logging.DEBUG)
            retcode = 1
        # Mimic the json data-structure that "salt-call --local" will
        # emit (as seen in ssh_py_shim.py)
        if isinstance(result, dict) and 'local' in result:
            ret = salt.utils.json.dumps({'local': result['local']})
        else:
            ret = salt.utils.json.dumps({'local': {'return': result}})
        return ret, retcode
97137
def process(self, salt_data, token, opts):
        '''
        
        '''
        parts = salt_data['tag'].split('/')
        if len(parts) < 2:
            return

        # TBD: Simplify these conditional expressions
        if parts[1] == 'job':
            if parts[3] == 'new':
                self.process_new_job_event(salt_data)
                if salt_data['data']['fun'] == 'grains.items':
                    self.minions = {}
            elif parts[3] == 'ret':
                self.process_ret_job_event(salt_data)
                if salt_data['data']['fun'] == 'grains.items':
                    self.process_minion_update(salt_data)
        if parts[1] == 'key':
            self.process_key_event(salt_data)
        if parts[1] == 'presence':
            self.process_presence_events(salt_data, token, opts)
594663
def _get_grain(name, proxy=None):
    '''
    
    '''
    grains = _retrieve_grains_cache(proxy=proxy)
    if grains.get('result', False) and grains.get('out', {}):
        return grains.get('out').get(name)
704552
def _list_nodes(call=None):
    '''
    
    '''
    local = salt.client.LocalClient()
    ret = local.cmd('salt-cloud:driver:vagrant', 'grains.items', '', tgt_type='grain')
    return ret
200371
def get_select(self, ret_dict=False, qnodes=None, memory_policy=None):
        
        hw, mem_per_proc = self.hw, int(self.mem_per_proc)
        #dist = self.distribute(self.mpi_procs, self.omp_threads, mem_per_proc)
        """
        if self.pure_mpi:
            num_nodes, rest_cores = hw.divmod_node(self.mpi_procs, self.omp_threads)

            if num_nodes == 0:
                logger.info("IN_CORE PURE MPI: %s" % self.run_info)
                chunks = 1
                ncpus = rest_cores
                mpiprocs = rest_cores
                mem = mem_per_proc * ncpus
                ompthreads = 1

            elif rest_cores == 0:
                # Can allocate entire nodes because self.mpi_procs is divisible by cores_per_node.
                logger.info("PURE MPI run commensurate with cores_per_node %s" % self.run_info)
                chunks = num_nodes
                ncpus = hw.cores_per_node
                mpiprocs = hw.cores_per_node
                mem = ncpus * mem_per_proc
                ompthreads = 1

            else:
                logger.info("OUT-OF-CORE PURE MPI (not commensurate with cores_per_node): %s" % self.run_info)
                chunks = self.mpi_procs
                ncpus = 1
                mpiprocs = 1
                mem = mem_per_proc
                ompthreads = 1

        elif self.pure_omp:
            # Pure OMP run.
            logger.info("PURE OPENMP run: %s" % self.run_info)
            assert hw.can_use_omp_threads(self.omp_threads)
            chunks = 1
            ncpus = self.omp_threads
            mpiprocs = 1
            mem = mem_per_proc
            ompthreads = self.omp_threads

        elif self.hybrid_mpi_omp:
            assert hw.can_use_omp_threads(self.omp_threads)
            num_nodes, rest_cores = hw.divmod_node(self.mpi_procs, self.omp_threads)
            #print(num_nodes, rest_cores)
            # TODO: test this

            if rest_cores == 0 or num_nodes == 0:
                logger.info("HYBRID MPI-OPENMP run, perfectly divisible among nodes: %s" % self.run_info)
                chunks = max(num_nodes, 1)
                mpiprocs = self.mpi_procs // chunks

                chunks = chunks
                ncpus = mpiprocs * self.omp_threads
                mpiprocs = mpiprocs
                mem = mpiprocs * mem_per_proc
                ompthreads = self.omp_threads

            else:
                logger.info("HYBRID MPI-OPENMP, NOT commensurate with nodes: %s" % self.run_info)
                chunks=self.mpi_procs
                ncpus=self.omp_threads
                mpiprocs=1
                mem= mem_per_proc
                ompthreads=self.omp_threads

        else:
            raise RuntimeError("You should not be here")
        """
        if memory_policy is None:
            memory_policy = self.memory_policy
        if qnodes is None:
            qnodes = self.qnodes
        else:
            if qnodes not in ["standard", "shared", "exclusive"]:
                raise ValueError("Nodes must be either in standard, shared or exclusive mode "
                                 "while qnodes parameter was {}".format(self.qnodes))
        if qnodes == "standard":
            return self._get_select_standard(ret_dict=ret_dict, memory_policy=memory_policy)
        else:
            return self._get_select_with_master_mem_overhead(ret_dict=ret_dict, qnodes=qnodes,
                                                             memory_policy=memory_policy)
450704
def ext_pillar(minion_id,  # pylint: disable=W0613
               pillar,  # pylint: disable=W0613
               command):
    '''
    
    '''
    try:
        command = command.replace('%s', minion_id)
        return salt.utils.json.loads(__salt__['cmd.run'](command))
    except Exception:
        log.critical('JSON data from %s failed to parse', command)
        return {}
766118
def process(self, salt_data, token, opts):
        '''
        
        '''
        log.debug('In process %s', threading.current_thread())
        log.debug(salt_data['tag'])
        log.debug(salt_data)

        parts = salt_data['tag'].split('/')
        if len(parts) < 2:
            return

        # TBD: Simplify these conditional expressions
        if parts[1] == 'job':
            log.debug('In job part 1')
            if parts[3] == 'new':
                log.debug('In new job')
                self.process_new_job_event(salt_data)
                # if salt_data['data']['fun'] == 'grains.items':
                #     self.minions = {}
            elif parts[3] == 'ret':
                log.debug('In ret')
                self.process_ret_job_event(salt_data)
                if salt_data['data']['fun'] == 'grains.items':
                    self.process_minion_update(salt_data)
        elif parts[1] == 'key':
            log.debug('In key')
            self.process_key_event(salt_data)
        elif parts[1] == 'presence':
            self.process_presence_events(salt_data, token, opts)
197634
def get_iter_returns(
            self,
            jid,
            minions,
            timeout=None,
            tgt='*',
            tgt_type='glob',
            expect_minions=False,
            block=True,
            **kwargs):
        '''
        
        '''
        if not isinstance(minions, set):
            if isinstance(minions, six.string_types):
                minions = set([minions])
            elif isinstance(minions, (list, tuple)):
                minions = set(list(minions))

        if timeout is None:
            timeout = self.opts['timeout']
        gather_job_timeout = int(kwargs.get('gather_job_timeout', self.opts['gather_job_timeout']))
        start = int(time.time())

        # timeouts per minion, id_ -> timeout time
        minion_timeouts = {}

        found = set()
        missing = set()
        # Check to see if the jid is real, if not return the empty dict
        try:
            if self.returners['{0}.get_load'.format(self.opts['master_job_cache'])](jid) == {}:
                log.warning('jid does not exist')
                yield {}
                # stop the iteration, since the jid is invalid
                raise StopIteration()
        except Exception as exc:
            log.warning('Returner unavailable: %s', exc, exc_info_on_loglevel=logging.DEBUG)
        # Wait for the hosts to check in
        last_time = False
        # iterator for this job's return
        if self.opts['order_masters']:
            # If we are a MoM, we need to gather expected minions from downstreams masters.
            ret_iter = self.get_returns_no_block('(salt/job|syndic/.*)/{0}'.format(jid), 'regex')
        else:
            ret_iter = self.get_returns_no_block('salt/job/{0}'.format(jid))
        # iterator for the info of this job
        jinfo_iter = []
        # open event jids that need to be un-subscribed from later
        open_jids = set()
        timeout_at = time.time() + timeout
        gather_syndic_wait = time.time() + self.opts['syndic_wait']
        # are there still minions running the job out there
        # start as True so that we ping at least once
        minions_running = True
        log.debug(
            'get_iter_returns for jid %s sent to %s will timeout at %s',
            jid, minions, datetime.fromtimestamp(timeout_at).time()
        )
        while True:
            # Process events until timeout is reached or all minions have returned
            for raw in ret_iter:
                # if we got None, then there were no events
                if raw is None:
                    break
                if 'minions' in raw.get('data', {}):
                    minions.update(raw['data']['minions'])
                    if 'missing' in raw.get('data', {}):
                        missing.update(raw['data']['missing'])
                    continue
                if 'return' not in raw['data']:
                    continue
                if kwargs.get('raw', False):
                    found.add(raw['data']['id'])
                    yield raw
                else:
                    found.add(raw['data']['id'])
                    ret = {raw['data']['id']: {'ret': raw['data']['return']}}
                    if 'out' in raw['data']:
                        ret[raw['data']['id']]['out'] = raw['data']['out']
                    if 'retcode' in raw['data']:
                        ret[raw['data']['id']]['retcode'] = raw['data']['retcode']
                    if 'jid' in raw['data']:
                        ret[raw['data']['id']]['jid'] = raw['data']['jid']
                    if kwargs.get('_cmd_meta', False):
                        ret[raw['data']['id']].update(raw['data'])
                    log.debug('jid %s return from %s', jid, raw['data']['id'])
                    yield ret

            # if we have all of the returns (and we aren't a syndic), no need for anything fancy
            if len(found.intersection(minions)) >= len(minions) and not self.opts['order_masters']:
                # All minions have returned, break out of the loop
                log.debug('jid %s found all minions %s', jid, found)
                break
            elif len(found.intersection(minions)) >= len(minions) and self.opts['order_masters']:
                if len(found) >= len(minions) and len(minions) > 0 and time.time() > gather_syndic_wait:
                    # There were some minions to find and we found them
                    # However, this does not imply that *all* masters have yet responded with expected minion lists.
                    # Therefore, continue to wait up to the syndic_wait period (calculated in gather_syndic_wait) to see
                    # if additional lower-level masters deliver their lists of expected
                    # minions.
                    break
            # If we get here we may not have gathered the minion list yet. Keep waiting
            # for all lower-level masters to respond with their minion lists

            # let start the timeouts for all remaining minions

            for id_ in minions - found:
                # if we have a new minion in the list, make sure it has a timeout
                if id_ not in minion_timeouts:
                    minion_timeouts[id_] = time.time() + timeout

            # if the jinfo has timed out and some minions are still running the job
            # re-do the ping
            if time.time() > timeout_at and minions_running:
                # since this is a new ping, no one has responded yet
                jinfo = self.gather_job_info(jid, list(minions - found), 'list', **kwargs)
                minions_running = False
                # if we weren't assigned any jid that means the master thinks
                # we have nothing to send
                if 'jid' not in jinfo:
                    jinfo_iter = []
                else:
                    jinfo_iter = self.get_returns_no_block('salt/job/{0}'.format(jinfo['jid']))
                timeout_at = time.time() + gather_job_timeout
                # if you are a syndic, wait a little longer
                if self.opts['order_masters']:
                    timeout_at += self.opts.get('syndic_wait', 1)

            # check for minions that are running the job still
            for raw in jinfo_iter:
                # if there are no more events, lets stop waiting for the jinfo
                if raw is None:
                    break
                try:
                    if raw['data']['retcode'] > 0:
                        log.error('saltutil returning errors on minion %s', raw['data']['id'])
                        minions.remove(raw['data']['id'])
                        break
                except KeyError as exc:
                    # This is a safe pass. We're just using the try/except to
                    # avoid having to deep-check for keys.
                    missing_key = exc.__str__().strip('\'"')
                    if missing_key == 'retcode':
                        log.debug('retcode missing from client return')
                    else:
                        log.debug(
                            'Passing on saltutil error. Key \'%s\' missing '
                            'from client return. This may be an error in '
                            'the client.', missing_key
                        )
                # Keep track of the jid events to unsubscribe from later
                open_jids.add(jinfo['jid'])

                # TODO: move to a library??
                if 'minions' in raw.get('data', {}):
                    minions.update(raw['data']['minions'])
                    continue
                if 'syndic' in raw.get('data', {}):
                    minions.update(raw['syndic'])
                    continue
                if 'return' not in raw.get('data', {}):
                    continue

                # if the job isn't running there anymore... don't count
                if raw['data']['return'] == {}:
                    continue

                # if the minion throws an exception containing the word "return"
                # the master will try to handle the string as a dict in the next
                # step. Check if we have a string, log the issue and continue.
                if isinstance(raw['data']['return'], six.string_types):
                    log.error("unexpected return from minion: %s", raw)
                    continue

                if 'return' in raw['data']['return'] and \
                    raw['data']['return']['return'] == {}:
                    continue

                # if we didn't originally target the minion, lets add it to the list
                if raw['data']['id'] not in minions:
                    minions.add(raw['data']['id'])
                # update this minion's timeout, as long as the job is still running
                minion_timeouts[raw['data']['id']] = time.time() + timeout
                # a minion returned, so we know its running somewhere
                minions_running = True

            # if we have hit gather_job_timeout (after firing the job) AND
            # if we have hit all minion timeouts, lets call it
            now = time.time()
            # if we have finished waiting, and no minions are running the job
            # then we need to see if each minion has timedout
            done = (now > timeout_at) and not minions_running
            if done:
                # if all minions have timeod out
                for id_ in minions - found:
                    if now < minion_timeouts[id_]:
                        done = False
                        break
            if done:
                break

            # don't spin
            if block:
                time.sleep(0.01)
            else:
                yield

        # If there are any remaining open events, clean them up.
        if open_jids:
            for jid in open_jids:
                self.event.unsubscribe(jid)

        if expect_minions:
            for minion in list((minions - found)):
                yield {minion: {'failed': True}}

        # Filter out any minions marked as missing for which we received
        # returns (prevents false events sent due to higher-level masters not
        # knowing about lower-level minions).
        missing -= found

        # Report on missing minions
        if missing:
            for minion in missing:
                yield {minion: {'failed': True}}
731150
def get(tgt, fun, tgt_type='glob'):
    '''
    
    '''
    ret = salt.utils.minions.mine_get(tgt, fun, tgt_type, __opts__)
    return ret
600443
def print_grains(self):
        '''
        
        '''
        grains = self.minion.opts.get('grains') or salt.loader.grains(self.opts)
        salt.output.display_output({'local': grains}, 'grains', self.opts)
325841
def get_load(jid):
    '''
    
    '''
    jid_dir = salt.utils.jid.jid_dir(jid, _job_dir(), __opts__['hash_type'])
    load_fn = os.path.join(jid_dir, LOAD_P)
    if not os.path.exists(jid_dir) or not os.path.exists(load_fn):
        return {}
    serial = salt.payload.Serial(__opts__)
    ret = {}
    load_p = os.path.join(jid_dir, LOAD_P)
    num_tries = 5
    for index in range(1, num_tries + 1):
        with salt.utils.files.fopen(load_p, 'rb') as rfh:
            try:
                ret = serial.load(rfh)
                break
            except Exception as exc:
                if index == num_tries:
                    time.sleep(0.25)
    else:
        log.critical('Failed to unpack %s', load_p)
        raise exc
    if ret is None:
        ret = {}
    minions_cache = [os.path.join(jid_dir, MINIONS_P)]
    minions_cache.extend(
        glob.glob(os.path.join(jid_dir, SYNDIC_MINIONS_P.format('*')))
    )
    all_minions = set()
    for minions_path in minions_cache:
        log.debug('Reading minion list from %s', minions_path)
        try:
            with salt.utils.files.fopen(minions_path, 'rb') as rfh:
                all_minions.update(serial.load(rfh))
        except IOError as exc:
            salt.utils.files.process_read_exception(exc, minions_path)

    if all_minions:
        ret['Minions'] = sorted(all_minions)

    return ret
479901
def _zfs_pool_data():
    '''
    
    '''
    grains = {}

    # collect zpool data
    zpool_list_cmd = __utils__['zfs.zpool_command'](
        'list',
        flags=['-H'],
        opts={'-o': 'name,size'},
    )
    for zpool in __salt__['cmd.run'](zpool_list_cmd, ignore_retcode=True).splitlines():
        if 'zpool' not in grains:
            grains['zpool'] = {}
        zpool = zpool.split()
        grains['zpool'][zpool[0]] = __utils__['zfs.to_size'](zpool[1], False)

    # return grain data
    return grains
232716
def _get_device_grain(name, proxy=None):
    '''
    
    '''
    device = _retrieve_device_cache(proxy=proxy)
    return device.get(name.upper())
409258
def get_cli_event_returns(
            self,
            jid,
            minions,
            timeout=None,
            tgt='*',
            tgt_type='glob',
            verbose=False,
            progress=False,
            show_timeout=False,
            show_jid=False,
            **kwargs):
        '''
        
        '''
        log.trace('func get_cli_event_returns()')

        if verbose:
            msg = 'Executing job with jid {0}'.format(jid)
            print(msg)
            print('-' * len(msg) + '\n')
        elif show_jid:
            print('jid: {0}'.format(jid))

        # lazy load the connected minions
        connected_minions = None
        return_count = 0

        for ret in self.get_iter_returns(jid,
                                         minions,
                                         timeout=timeout,
                                         tgt=tgt,
                                         tgt_type=tgt_type,
                                         # (gtmanfred) expect_minions is popped here incase it is passed from a client
                                         # call. If this is not popped, then it would be passed twice to
                                         # get_iter_returns.
                                         expect_minions=(kwargs.pop('expect_minions', False) or verbose or show_timeout),
                                         **kwargs
                                         ):
            log.debug('return event: %s', ret)
            return_count = return_count + 1
            if progress:
                for id_, min_ret in six.iteritems(ret):
                    if not min_ret.get('failed') is True:
                        yield {'minion_count': len(minions), 'return_count': return_count}
            # replace the return structure for missing minions
            for id_, min_ret in six.iteritems(ret):
                if min_ret.get('failed') is True:
                    if connected_minions is None:
                        connected_minions = salt.utils.minions.CkMinions(self.opts).connected_ids()
                    if self.opts['minion_data_cache'] \
                            and salt.cache.factory(self.opts).contains('minions/{0}'.format(id_), 'data') \
                            and connected_minions \
                            and id_ not in connected_minions:

                        yield {
                            id_: {
                                'out': 'no_return',
                                'ret': 'Minion did not return. [Not connected]',
                                'retcode': salt.defaults.exitcodes.EX_GENERIC
                            }
                        }
                    else:
                        # don't report syndics as unresponsive minions
                        if not os.path.exists(os.path.join(self.opts['syndic_dir'], id_)):
                            yield {
                                id_: {
                                    'out': 'no_return',
                                    'ret': 'Minion did not return. [No response]'
                                    '\nThe minions may not have all finished running and any '
                                    'remaining minions will return upon completion. To look '
                                    'up the return data for this job later, run the following '
                                    'command:\n\n'
                                    'salt-run jobs.lookup_jid {0}'.format(jid),
                                    'retcode': salt.defaults.exitcodes.EX_GENERIC
                                }
                            }
                else:
                    yield {id_: min_ret}

        self._clean_up_subscriptions(jid)
390089
def __prep_mod_opts(self, opts):
        '''
        
        '''
        if '__grains__' not in self.pack:
            grains = opts.get('grains', {})

            if isinstance(grains, ThreadLocalProxy):
                grains = ThreadLocalProxy.unproxy(grains)

            self.context_dict['grains'] = grains
            self.pack['__grains__'] = salt.utils.context.NamespacedDictWrapper(self.context_dict, 'grains')

        if '__pillar__' not in self.pack:
            pillar = opts.get('pillar', {})

            if isinstance(pillar, ThreadLocalProxy):
                pillar = ThreadLocalProxy.unproxy(pillar)

            self.context_dict['pillar'] = pillar
            self.pack['__pillar__'] = salt.utils.context.NamespacedDictWrapper(self.context_dict, 'pillar')

        mod_opts = {}
        for key, val in list(opts.items()):
            if key == 'logger':
                continue
            mod_opts[key] = val
        return mod_opts
1019417
def grains():
    '''
    
    '''
    if not DETAILS['grains_cache']:
        ret = system_info()
        log.debug(ret)
        DETAILS['grains_cache'].update(ret)
    return {'onyx': DETAILS['grains_cache']}