Ejemplo n.º 1
0
    def start(self):
        '''
        Execute this method to start up a syndic.
        '''
        verify_env([
            self.opts['pki_dir'],
            self.opts['cachedir'],
            os.path.dirname(self.opts['log_file']),
        ])
        import salt.log
        salt.log.setup_logfile_logger(self.opts['log_file'],
                                      self.opts['log_level'])
        for name, level in self.opts['log_granular_levels'].iteritems():
            salt.log.set_logger_level(name, level)

        import logging

        # Late import so logging works correctly
        import salt.minion
        log = logging.getLogger(__name__)
        if self.cli['daemon']:
            # Late import so logging works correctly
            import salt.utils
            salt.utils.daemonize()
        set_pidfile(self.cli['pidfile'])
        if check_user(self.opts['user'], log):
            try:
                syndic = salt.minion.Syndic(self.opts)
                syndic.tune_in()
            except KeyboardInterrupt:
                log.warn('Stopping the Salt Syndic Minion')
                raise SystemExit('\nExiting on Ctrl-c')
Ejemplo n.º 2
0
def has_battery():
    '''
    Return true if a battery exists.
    '''

    # We need to have the `acpi` binary installed to avoid having to do the
    # old vs new acpi detection our selves.
    acpi = salt.utils.which('acpi')
    if acpi is None or acpi == "":
        return {}

    # call ACPI binary: `acpi -b` to return the battery status.  As long as the
    # binary exists, it will return either the status of all batteries it knows
    # about in the following format:
    # 'Battery X: Full, YY%' or 'No support for device type: power_supply'
    # In the former, we return True, the latter we return False. I hope it's
    # obvious why. ;)
    result = salt.modules.cmdmod._run_quiet('acpi -b')
    if 'No support for device type' in result:
        return {'has_battery': 0}
    elif 'Battery ' in result:
        return {'has_battery': 1}
    else:
        log.warn('Unexpected output from `acpi -b`: {0}'.format(result))
        return {}
Ejemplo n.º 3
0
 def start(self):
     '''
     Execute this method to start up a minion.
     '''
     verify_env([
         self.opts['pki_dir'],
         self.opts['cachedir'],
         self.opts['extension_modules'],
         os.path.dirname(self.opts['log_file']),
     ])
     import salt.log
     salt.log.setup_logfile_logger(self.opts['log_file'],
                                   self.opts['log_level'])
     for name, level in self.opts['log_granular_levels'].iteritems():
         salt.log.set_logger_level(name, level)
     import logging
     # Late import so logging works correctly
     import salt.minion
     log = logging.getLogger(__name__)
     if self.cli['daemon']:
         # Late import so logging works correctly
         import salt.utils
         # If the minion key has not been accepted, then Salt enters a loop
         # waiting for it, if we daemonize later then the minion cound halt
         # the boot process waiting for a key to be accepted on the master.
         # This is the latest safe place to daemonize
         salt.utils.daemonize()
     minion = salt.minion.Minion(self.opts)
     set_pidfile(self.cli['pidfile'])
     if check_user(self.opts['user'], log):
         try:
             minion.tune_in()
         except KeyboardInterrupt:
             log.warn('Stopping the Salt Minion')
             raise SystemExit('\nExiting on Ctrl-c')
Ejemplo n.º 4
0
def include_config(include, opts, orig_path, verbose):
    '''
    Parses extra configuration file(s) specified in an include list in the
    main config file.
    '''

    # Protect against empty option
    if not include:
        return opts

    if isinstance(include, str):
        include = [include]

    for path in include:
        if not os.path.isabs(path):
            path = os.path.join(os.path.dirname(orig_path), path)

        # Catch situation where user typos path in config; also warns for
        # empty include dir (which might be by design)
        if len(glob.glob(path)) == 0:
            msg = "Warning parsing configuration file: 'include' path/glob '{0}' matches no files"
            if verbose: log.warn(msg.format(path))

        for fn_ in glob.glob(path):
            try:
                opts.update(_read_conf_file(fn_))
            except Exception as e:
                msg = 'Error parsing configuration file: {0} - {1}'
                log.warn(msg.format(fn_, e))
    return opts
Ejemplo n.º 5
0
def ext_pillar(
        minion_id,  # pylint: disable=W0613
        pillar,  # pylint: disable=W0613
        config_file):
    '''
    Execute LDAP searches and return the aggregated data
    '''
    if os.path.isfile(config_file):
        try:
            #open(config_file, 'r') as raw_config:
            config = _render_template(config_file) or {}
            opts = yaml.safe_load(config) or {}
            opts['conf_file'] = config_file
        except Exception as err:
            import salt.log
            msg = 'Error parsing configuration file: {0} - {1}'
            if salt.log.is_console_configured():
                log.warn(msg.format(config_file, err))
            else:
                print(msg.format(config_file, err))
    else:
        log.debug('Missing configuration file: {0}'.format(config_file))

    data = {}
    for source in opts['search_order']:
        config = opts[source]
        result = _do_search(config)
        print('source {0} got result {1}'.format(source, result))
        if result:
            data = _result_to_dict(data, result, config)
    return data
Ejemplo n.º 6
0
def has_battery():
    '''
	Return true if a battery exists.
	'''

    # We need to have the `acpi` binary installed to avoid having to do the
    # old vs new acpi detection our selves.
    acpi = salt.utils.which('acpi')
    if acpi == None or acpi == "":
        return {}

    # call ACPI binary: `acpi -b` to return the battery status.  As long as the
    # binary exists, it will return either the status of all batteries it knows
    # about in the following format:
    # 'Battery X: Full, YY%' or 'No support for device type: power_supply'
    # In the former, we return True, the latter we return False. I hope it's
    # obvious why. ;)
    result = salt.modules.cmdmod._run_quiet('acpi -b')
    if 'No support for device type' in result:
        return {'has_battery': 0}
    elif 'Battery ' in result:
        return {'has_battery': 1}
    else:
        log.warn('Unexpected output from `acpi -b`: %s' % result)
        return {}
Ejemplo n.º 7
0
def load_config(opts, path, env_var):
    '''
    Attempts to update ``opts`` dict by parsing either the file described by
    ``path`` or the environment variable described by ``env_var`` as YAML.
    '''
    if not path or not os.path.isfile(path):
        path = os.environ.get(env_var, path)
    # If the configuration file is missing, attempt to copy the template,
    # after removing the first header line.
    if not os.path.isfile(path):
        template = '{0}.template'.format(path)
        if os.path.isfile(template):
            with open(path, 'w') as out:
                with open(template, 'r') as f:
                    f.readline()  # skip first line
                    out.write(f.read())

    if os.path.isfile(path):
        try:
            opts.update(_read_conf_file(path))
            opts['conf_file'] = path
        except Exception as e:
            import salt.log
            msg = 'Error parsing configuration file: {0} - {1}'
            if salt.log.is_console_configured():
                log.warn(msg.format(path, e))
            else:
                print(msg.format(path, e))
    else:
        log.debug('Missing configuration file: {0}'.format(path))
Ejemplo n.º 8
0
def mine(tgt=None, expr_form='glob', outputter=None, **kwargs):
    '''
    Return cached mine data of the targeted minions

    CLI Example:

    .. code-block:: bash

        salt-run cache.mine
    '''
    deprecated_minion = kwargs.get('minion', None)
    if tgt is None and deprecated_minion is None:
        log.warn("DEPRECATION WARNING: {0}".format(deprecation_warning))
        tgt = '*'  # targat all minions for backward compatibility
    elif tgt is None and isinstance(deprecated_minion, string_types):
        log.warn("DEPRECATION WARNING: {0}".format(deprecation_warning))
        tgt = deprecated_minion
    elif tgt is None:
        return {}
    pillar_util = salt.utils.master.MasterPillarUtil(tgt,
                                                     expr_form,
                                                     use_cached_grains=False,
                                                     grains_fallback=False,
                                                     use_cached_pillar=False,
                                                     pillar_fallback=False,
                                                     opts=__opts__)
    cached_mine = pillar_util.get_cached_mine_data()
    salt.output.display_output(cached_mine, outputter, __opts__)
Ejemplo n.º 9
0
def pillar(tgt=None, expr_form='glob', outputter=None, **kwargs):
    '''
    Return cached pillars of the targeted minions

    CLI Example:

    .. code-block:: bash

        salt-run cache.pillar
    '''
    deprecated_minion = kwargs.get('minion', None)
    if tgt is None and deprecated_minion is None:
        log.warn("DEPRECATION WARNING: {0}".format(DEPRECATION_WARNING))
        tgt = '*'  # targat all minions for backward compatibility
    elif tgt is None and isinstance(deprecated_minion, string_types):
        log.warn("DEPRECATION WARNING: {0}".format(DEPRECATION_WARNING))
        tgt = deprecated_minion
    elif tgt is None:
        return {}
    pillar_util = salt.utils.master.MasterPillarUtil(tgt,
                                                     expr_form,
                                                     use_cached_grains=True,
                                                     grains_fallback=False,
                                                     use_cached_pillar=True,
                                                     pillar_fallback=False,
                                                     opts=__opts__)
    cached_pillar = pillar_util.get_minion_pillar()
    if outputter:
        return {'outputter': outputter, 'data': cached_pillar}
    else:
        return cached_pillar
Ejemplo n.º 10
0
    def start(self):
        '''
        Execute this method to start up a syndic.
        '''
        verify_env([self.opts['pki_dir'], self.opts['cachedir'],
                os.path.dirname(self.opts['log_file']),
                ])
        import salt.log
        salt.log.setup_logfile_logger(
            self.opts['log_file'], self.opts['log_level']
        )
        for name, level in self.opts['log_granular_levels'].iteritems():
            salt.log.set_logger_level(name, level)

        import logging

        # Late import so logging works correctly
        import salt.minion
        log = logging.getLogger(__name__)
        if check_user(self.opts['user'], log):
            try:
                syndic = salt.minion.Syndic(self.opts)
                if self.cli['daemon']:
                    # Late import so logging works correctly
                    import salt.utils
                    salt.utils.daemonize()
                set_pidfile(self.cli['pidfile'])
                syndic.tune_in()
            except KeyboardInterrupt:
                log.warn('Stopping the Salt Syndic Minion')
                raise SystemExit('\nExiting on Ctrl-c')
Ejemplo n.º 11
0
def ext_pillar(minion_id,  # pylint: disable=W0613
               pillar,  # pylint: disable=W0613
               config_file):
    '''
    Execute LDAP searches and return the aggregated data
    '''
    if os.path.isfile(config_file):
        try:
            #open(config_file, 'r') as raw_config:
            config = _render_template(config_file) or {}
            opts = yaml.safe_load(config) or {}
            opts['conf_file'] = config_file
        except Exception as err:
            import salt.log
            msg = 'Error parsing configuration file: {0} - {1}'
            if salt.log.is_console_configured():
                log.warn(msg.format(config_file, err))
            else:
                print(msg.format(config_file, err))
    else:
        log.debug('Missing configuration file: {0}'.format(config_file))

    data = {}
    for source in opts['search_order']:
        config = opts[source]
        result = _do_search(config)
        print('source {0} got result {1}'.format(source, result))
        if result:
            data = _result_to_dict(data, result, config)
    return data
Ejemplo n.º 12
0
def include_config(include, opts, orig_path, verbose):
    '''
    Parses extra configuration file(s) specified in an include list in the
    main config file.
    '''

    # Protect against empty option
    if not include:
        return opts

    if isinstance(include, str):
        include = [include]

    for path in include:
        if not os.path.isabs(path):
            path = os.path.join(os.path.dirname(orig_path), path)

        # Catch situation where user typos path in config; also warns for
        # empty include dir (which might be by design)
        if len(glob.glob(path)) == 0:
            msg = "Warning parsing configuration file: 'include' path/glob '{0}' matches no files"
            if verbose: log.warn(msg.format(path))

        for fn_ in glob.glob(path):
            try:
                opts.update(_read_conf_file(fn_))
            except Exception as e:
                msg = 'Error parsing configuration file: {0} - {1}'
                log.warn(msg.format(fn_, e))
    return opts
Ejemplo n.º 13
0
def load_config(opts, path, env_var):
    '''
    Attempts to update ``opts`` dict by parsing either the file described by
    ``path`` or the environment variable described by ``env_var`` as YAML.
    '''
    if not path or not os.path.isfile(path):
        path = os.environ.get(env_var, path)
    # If the configuration file is missing, attempt to copy the template,
    # after removing the first header line.
    if not os.path.isfile(path):
        template = '{0}.template'.format(path)
        if os.path.isfile(template):
            with open(path, 'w') as out:
                with open(template, 'r') as f:
                    f.readline()  # skip first line
                    out.write(f.read())

    if os.path.isfile(path):
        try:
            opts.update(_read_conf_file(path))
            opts['conf_file'] = path
        except Exception as e:
            import salt.log
            msg = 'Error parsing configuration file: {0} - {1}'
            if salt.log.is_console_configured():
                log.warn(msg.format(path, e))
            else:
                print(msg.format(path, e))
    else:
        log.debug('Missing configuration file: {0}'.format(path))
Ejemplo n.º 14
0
def mine(tgt=None, expr_form='glob', **kwargs):
    '''
    Return cached mine data of the targeted minions

    CLI Example:

    .. code-block:: bash

        salt-run cache.mine
    '''
    deprecated_minion = kwargs.get('minion', None)
    if tgt is None and deprecated_minion is None:
        log.warn("DEPRECATION WARNING: {0}".format(deprecation_warning))
        tgt = '*'  # targat all minions for backward compatibility
    elif tgt is None and isinstance(deprecated_minion, string_types):
        log.warn("DEPRECATION WARNING: {0}".format(deprecation_warning))
        tgt = deprecated_minion
    elif tgt is None:
        return {}
    pillar_util = salt.utils.master.MasterPillarUtil(tgt, expr_form,
                                                use_cached_grains=False,
                                                grains_fallback=False,
                                                use_cached_pillar=False,
                                                pillar_fallback=False,
                                                opts=__opts__)
    cached_mine = pillar_util.get_cached_mine_data()
    salt.output.display_output(cached_mine, None, __opts__)
Ejemplo n.º 15
0
 def start(self):
     '''
     Execute this method to start up a minion.
     '''
     verify_env([self.opts['pki_dir'],
         self.opts['cachedir'],
         self.opts['extension_modules'],
         os.path.dirname(self.opts['log_file']),
             ])
     import salt.log
     salt.log.setup_logfile_logger(
         self.opts['log_file'], self.opts['log_level']
     )
     for name, level in self.opts['log_granular_levels'].iteritems():
         salt.log.set_logger_level(name, level)
     import logging
     # Late import so logging works correctly
     import salt.minion
     log = logging.getLogger(__name__)
     if self.cli['daemon']:
         # Late import so logging works correctly
         import salt.utils
         # If the minion key has not been accepted, then Salt enters a loop
         # waiting for it, if we daemonize later then the minion cound halt
         # the boot process waiting for a key to be accepted on the master.
         # This is the latest safe place to daemonize
         salt.utils.daemonize()
     minion = salt.minion.Minion(self.opts)
     set_pidfile(self.cli['pidfile'])
     if check_user(self.opts['user'], log):
         try:
             minion.tune_in()
         except KeyboardInterrupt:
             log.warn('Stopping the Salt Minion')
             raise SystemExit('\nExiting on Ctrl-c')
Ejemplo n.º 16
0
def pillar(tgt=None, expr_form='glob', outputter=None, **kwargs):
    '''
    Return cached pillars of the targeted minions

    CLI Example:

    .. code-block:: bash

        salt-run cache.pillar
    '''
    deprecated_minion = kwargs.get('minion', None)
    if tgt is None and deprecated_minion is None:
        log.warn("DEPRECATION WARNING: {0}".format(DEPRECATION_WARNING))
        tgt = '*'  # targat all minions for backward compatibility
    elif tgt is None and isinstance(deprecated_minion, string_types):
        log.warn("DEPRECATION WARNING: {0}".format(DEPRECATION_WARNING))
        tgt = deprecated_minion
    elif tgt is None:
        return {}
    pillar_util = salt.utils.master.MasterPillarUtil(tgt, expr_form,
                                                     use_cached_grains=True,
                                                     grains_fallback=False,
                                                     use_cached_pillar=True,
                                                     pillar_fallback=False,
                                                     opts=__opts__)
    cached_pillar = pillar_util.get_minion_pillar()
    if outputter:
        return {'outputter': outputter, 'data': cached_pillar}
    else:
        return cached_pillar
Ejemplo n.º 17
0
Archivo: core.py Proyecto: herlo/salt
def _linux_gpu_data():
    '''
    num_gpus: int
    gpus:
      - vendor: nvidia|amd|ati|...
        model: string
    '''
    # dominant gpu vendors to search for (MUST be lowercase for matching below)
    known_vendors = ['nvidia', 'amd', 'ati', 'intel']

    devs = []
    try:
        lspci_out = __salt__['cmd.run']('lspci -vmm')

        cur_dev = {}
        error = False
        for line in lspci_out.splitlines():
            # check for record-separating empty lines
            if line == '':
                if cur_dev.get('Class', '') == 'VGA compatible controller':
                    devs.append(cur_dev)
                # XXX; may also need to search for "3D controller"
                cur_dev = {}
                continue
            if re.match(r'^\w+:\s+.*', line):
                key, val = line.split(':', 1)
                cur_dev[key.strip()] = val.strip()
            else:
                error = True
                log.debug('Unexpected lspci output: \'{0}\''.format(line))

        if error:
            log.warn(
                'Error loading grains, unexpected linux_gpu_data output, '
                'check that you have a valid shell configured and '
                'permissions to run lspci command'
            )
    except OSError:
        pass

    gpus = []
    for gpu in devs:
        vendor_strings = gpu['Vendor'].lower().split()
        # default vendor to 'unknown', overwrite if we match a known one
        vendor = 'unknown'
        for name in known_vendors:
            # search for an 'expected' vendor name in the list of strings
            if name in vendor_strings:
                vendor = name
                break
        gpus.append({'vendor': vendor, 'model': gpu['Device']})

    grains = {}
    grains['num_gpus'] = len(gpus)
    grains['gpus'] = gpus
    return grains
Ejemplo n.º 18
0
 def _get_live_minion_pillar(self, minion_id=None, minion_grains=None):
     # Returns a dict of pillar data for one minion
     if minion_id is None:
         return {}
     if not minion_grains:
         log.warn(
             'Cannot get pillar data for {0}: no grains supplied.'.format(
                 minion_id))
         return {}
     log.debug('Getting live pillar for {0}'.format(minion_id))
     pillar = salt.pillar.Pillar(self.opts, minion_grains, minion_id,
                                 self.saltenv, self.opts['ext_pillar'])
     log.debug('Compiling pillar for {0}'.format(minion_id))
     ret = pillar.compile_pillar()
     return ret
Ejemplo n.º 19
0
 def _get_live_minion_pillar(self, minion_id=None, minion_grains=None):
     # Returns a dict of pillar data for one minion
     if minion_id == None:
         return {}
     if not minion_grains:
         log.warn('Cannot get pillar data for {0}: no grains supplied.'.format(minion_id))
         return {}
     log.debug('Getting live pillar for {0}'.format(minion_id))
     pillar = salt.pillar.Pillar(
                         self.opts,
                         minion_grains,
                         minion_id,
                         self.env,
                         self.opts['ext_pillar'])
     log.debug('Compiling pillar for {0}'.format(minion_id))
     ret = pillar.compile_pillar()
     return ret
Ejemplo n.º 20
0
Archivo: config.py Proyecto: herlo/salt
def include_config(include, orig_path, verbose):
    '''
    Parses extra configuration file(s) specified in an include list in the
    main config file.
    '''
    # Protect against empty option
    if not include:
        return {}

    if orig_path is None:
        # When the passed path is None, we just want the configuration
        # defaults, not actually loading the whole configuration.
        return {}

    if isinstance(include, str):
        include = [include]

    configuration = {}
    for path in include:
        # Allow for includes like ~/foo
        path = os.path.expanduser(path)
        if not os.path.isabs(path):
            path = os.path.join(os.path.dirname(orig_path), path)

        # Catch situation where user typos path in configuration; also warns
        # for empty include directory (which might be by design)
        if len(glob.glob(path)) == 0:
            if verbose:
                log.warn(
                    'Warning parsing configuration file: "include" path/glob '
                    '"{0}" matches no files'.format(path)
                )

        for fn_ in sorted(glob.glob(path)):
            try:
                log.debug('Including configuration from {0}'.format(fn_))
                configuration.update(_read_conf_file(fn_))
            except Exception as err:
                log.warn(
                    'Error parsing configuration file: {0} - {1}'.format(
                        fn_, err
                    )
                )
    return configuration
Ejemplo n.º 21
0
def grains(tgt=None, expr_form='glob', **kwargs):
    '''
    Return cached grains of the targeted minions
    '''
    deprecated_minion = kwargs.get('minion', None)
    if tgt is None and deprecated_minion is None:
        log.warn("DEPRECATION WARNING: {0}".format(deprecation_warning))
        tgt = '*'  # targat all minions for backward compatibility
    elif tgt is None and isinstance(deprecated_minion, string_types):
        log.warn("DEPRECATION WARNING: {0}".format(deprecation_warning))
        tgt = deprecated_minion
    elif tgt is None:
        return {}
    pillar_util = salt.utils.master.MasterPillarUtil(tgt,
                                                     expr_form,
                                                     use_cached_grains=True,
                                                     grains_fallback=False,
                                                     opts=__opts__)
    cached_grains = pillar_util.get_minion_grains()
    salt.output.display_output(cached_grains, None, __opts__)
    return cached_grains
Ejemplo n.º 22
0
def include_config(include, orig_path, verbose):
    '''
    Parses extra configuration file(s) specified in an include list in the
    main config file.
    '''
    # Protect against empty option
    if not include:
        return {}

    if orig_path is None:
        # When the passed path is None, we just want the configuration
        # defaults, not actually loading the whole configuration.
        return {}

    if isinstance(include, str):
        include = [include]

    configuration = {}
    for path in include:
        # Allow for includes like ~/foo
        path = os.path.expanduser(path)
        if not os.path.isabs(path):
            path = os.path.join(os.path.dirname(orig_path), path)

        # Catch situation where user typos path in configuration; also warns
        # for empty include directory (which might be by design)
        if len(glob.glob(path)) == 0:
            if verbose:
                log.warn(
                    'Warning parsing configuration file: "include" path/glob '
                    '{0!r} matches no files'.format(path))

        for fn_ in sorted(glob.glob(path)):
            try:
                log.debug('Including configuration from {0!r}'.format(fn_))
                configuration.update(_read_conf_file(fn_))
            except Exception as err:
                log.warn('Error parsing configuration file: {0} - {1}'.format(
                    fn_, err))
    return configuration
Ejemplo n.º 23
0
def resolve_dns(opts):
    '''
    Resolves the master_ip and master_uri options
    '''
    ret = {}
    check_dns = True
    if opts.get('file_client', 'remote') == 'local' and check_dns:
        check_dns = False

    if check_dns is True:
        # Because I import salt.log below I need to re-import salt.utils here
        import salt.utils
        try:
            ret['master_ip'] = salt.utils.dns_check(opts['master'], True)
        except SaltClientError:
            if opts['retry_dns']:
                while True:
                    import salt.log
                    msg = ('Master hostname: {0} not found. Retrying in {1} '
                           'seconds').format(opts['master'], opts['retry_dns'])
                    if salt.log.is_console_configured():
                        log.warn(msg)
                    else:
                        print('WARNING: {0}'.format(msg))
                    time.sleep(opts['retry_dns'])
                    try:
                        ret['master_ip'] = salt.utils.dns_check(
                            opts['master'], True
                        )
                        break
                    except SaltClientError:
                        pass
            else:
                ret['master_ip'] = '127.0.0.1'
    else:
        ret['master_ip'] = '127.0.0.1'

    ret['master_uri'] = 'tcp://{ip}:{port}'.format(ip=ret['master_ip'],
                                                    port=opts['master_port'])
    return ret
Ejemplo n.º 24
0
Archivo: config.py Proyecto: herlo/salt
def load_config(path, env_var):
    '''
    Returns configuration dict from parsing either the file described by
    ``path`` or the environment variable described by ``env_var`` as YAML.
    '''
    if path is None:
        # When the passed path is None, we just want the configuration
        # defaults, not actually loading the whole configuration.
        return {}

    if not path or not os.path.isfile(path):
        path = os.environ.get(env_var, path)
    # If the configuration file is missing, attempt to copy the template,
    # after removing the first header line.
    if not os.path.isfile(path):
        template = '{0}.template'.format(path)
        if os.path.isfile(template):
            import salt.utils  # TODO: Need to re-import, need to find out why
            log.debug('Writing {0} based on {1}'.format(path, template))
            with salt.utils.fopen(path, 'w') as out:
                with salt.utils.fopen(template, 'r') as ifile:
                    ifile.readline()  # skip first line
                    out.write(ifile.read())

    if os.path.isfile(path):
        try:
            opts = _read_conf_file(path)
            opts['conf_file'] = path
            return opts
        except Exception as err:
            import salt.log
            msg = 'Error parsing configuration file: {0} - {1}'
            if salt.log.is_console_configured():
                log.warn(msg.format(path, err))
            else:
                print(msg.format(path, err))
    else:
        log.debug('Missing configuration file: {0}'.format(path))

    return {}
Ejemplo n.º 25
0
def resolve_dns(opts):
    '''
    Resolves the master_ip and master_uri options
    '''
    ret = {}
    check_dns = True
    if opts.get('file_client', 'remote') == 'local' and check_dns:
        check_dns = False

    if check_dns is True:
        # Because I import salt.log below I need to re-import salt.utils here
        import salt.utils
        try:
            ret['master_ip'] = salt.utils.dns_check(opts['master'], True)
        except SaltClientError:
            if opts['retry_dns']:
                while True:
                    import salt.log
                    msg = ('Master hostname: {0} not found. Retrying in {1} '
                           'seconds').format(opts['master'], opts['retry_dns'])
                    if salt.log.is_console_configured():
                        log.warn(msg)
                    else:
                        print('WARNING: {0}'.format(msg))
                    time.sleep(opts['retry_dns'])
                    try:
                        ret['master_ip'] = salt.utils.dns_check(
                            opts['master'], True)
                        break
                    except SaltClientError:
                        pass
            else:
                ret['master_ip'] = '127.0.0.1'
    else:
        ret['master_ip'] = '127.0.0.1'

    ret['master_uri'] = 'tcp://{ip}:{port}'.format(ip=ret['master_ip'],
                                                   port=opts['master_port'])
    return ret
Ejemplo n.º 26
0
def load_config(path, env_var):
    '''
    Returns configuration dict from parsing either the file described by
    ``path`` or the environment variable described by ``env_var`` as YAML.
    '''
    if path is None:
        # When the passed path is None, we just want the configuration
        # defaults, not actually loading the whole configuration.
        return {}

    if not path or not os.path.isfile(path):
        path = os.environ.get(env_var, path)
    # If the configuration file is missing, attempt to copy the template,
    # after removing the first header line.
    if not os.path.isfile(path):
        template = '{0}.template'.format(path)
        if os.path.isfile(template):
            import salt.utils  # TODO: Need to re-import, need to find out why
            with salt.utils.fopen(path, 'w') as out:
                with salt.utils.fopen(template, 'r') as ifile:
                    ifile.readline()  # skip first line
                    out.write(ifile.read())

    if os.path.isfile(path):
        try:
            opts = _read_conf_file(path)
            opts['conf_file'] = path
            return opts
        except Exception as err:
            import salt.log
            msg = 'Error parsing configuration file: {0} - {1}'
            if salt.log.is_console_configured():
                log.warn(msg.format(path, err))
            else:
                print(msg.format(path, err))
    else:
        log.debug('Missing configuration file: {0}'.format(path))

    return {}
Ejemplo n.º 27
0
Archivo: core.py Proyecto: 1mentat/salt
def _virtual(osdata):
    '''
    Returns what type of virtual hardware is under the hood, kvm or physical
    '''
    # This is going to be a monster, if you are running a vm you can test this
    # grain with please submit patches!
    # Provides:
    #   virtual
    #   virtual_subtype
    grains = {'virtual': 'physical'}
    for command in ('dmidecode', 'lspci', 'dmesg'):
        args = []
        if osdata['kernel'] == 'Darwin':
            command = 'system_profiler'
            args = ['SPDisplaysDataType']

        cmd = salt.utils.which(command)

        if not cmd:
            continue

        cmd = '%s %s' % (command, ' '.join(args))

        ret = __salt__['cmd.run_all'](cmd)

        if ret['retcode'] > 0:
            if salt.log.is_logging_configured():
                if salt.utils.is_windows():
                    continue
                log.warn(
                    'Although \'{0}\' was found in path, the current user '
                    'cannot execute it. Grains output might not be '
                    'accurate.'.format(command)
                )
            continue

        output = ret['stdout']
        if command == "system_profiler":
            macoutput = output.lower()
            if '0x1ab8' in macoutput:
                grains['virtual'] = 'Parallels'
            if 'parallels' in macoutput:
                grains['virtual'] = 'Parallels'
            if 'vmware' in macoutput:
                grains['virtual'] = 'VMware'
            if '0x15ad' in macoutput:
                grains['virtual'] = 'VMware'
            if 'virtualbox' in macoutput:
                grains['virtual'] = 'VirtualBox'
            # Break out of the loop so the next log message is not issued
            break

        elif command == 'dmidecode' or command == 'dmesg':
            # Product Name: VirtualBox
            if 'Vendor: QEMU' in output:
                # FIXME: Make this detect between kvm or qemu
                grains['virtual'] = 'kvm'
            if 'Vendor: Bochs' in output:
                grains['virtual'] = 'kvm'
            # Product Name: (oVirt) www.ovirt.org
            # Red Hat Community virtualization Project based on kvm
            elif 'Manufacturer: oVirt' in output:
                grains['virtual'] = 'kvm'
            elif 'VirtualBox' in output:
                grains['virtual'] = 'VirtualBox'
            # Product Name: VMware Virtual Platform
            elif 'VMware' in output:
                grains['virtual'] = 'VMware'
            # Manufacturer: Microsoft Corporation
            # Product Name: Virtual Machine
            elif ': Microsoft' in output and 'Virtual Machine' in output:
                grains['virtual'] = 'VirtualPC'
            # Manufacturer: Parallels Software International Inc.
            elif 'Parallels Software' in output:
                grains['virtual'] = 'Parallels'
            # Break out of the loop, lspci parsing is not necessary
            break
        elif command == 'lspci':
            # dmidecode not available or the user does not have the necessary
            # permissions
            model = output.lower()
            if 'vmware' in model:
                grains['virtual'] = 'VMware'
            # 00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service
            elif 'virtualbox' in model:
                grains['virtual'] = 'VirtualBox'
            elif 'qemu' in model:
                grains['virtual'] = 'kvm'
            elif 'virtio' in model:
                grains['virtual'] = 'kvm'
            # Break out of the loop so the next log message is not issued
            break
    else:
        log.warn(
            'The tools \'dmidecode\', \'lspci\' and \'dmesg\' failed to execute '
            'because they do not exist on the system of the user running '
            'this instance or the user does not have the necessary permissions '
            'to execute them. Grains output might not be accurate.'
        )

    choices = ('Linux', 'OpenBSD', 'HP-UX')
    isdir = os.path.isdir
    sysctl = salt.utils.which('sysctl')
    if osdata['kernel'] in choices:
        if isdir('/proc/vz'):
            if os.path.isfile('/proc/vz/version'):
                grains['virtual'] = 'openvzhn'
            else:
                grains['virtual'] = 'openvzve'
        elif isdir('/proc/sys/xen') or isdir('/sys/bus/xen') or isdir('/proc/xen'):
            if os.path.isfile('/proc/xen/xsd_kva'):
                # Tested on CentOS 5.3 / 2.6.18-194.26.1.el5xen
                # Tested on CentOS 5.4 / 2.6.18-164.15.1.el5xen
                grains['virtual_subtype'] = 'Xen Dom0'
            else:
                if grains.get('productname', '') == 'HVM domU':
                    # Requires dmidecode!
                    grains['virtual_subtype'] = 'Xen HVM DomU'
                elif os.path.isfile('/proc/xen/capabilities') and os.access('/proc/xen/capabilities', os.R_OK):
                    caps = salt.utils.fopen('/proc/xen/capabilities')
                    if 'control_d' not in caps.read():
                        # Tested on CentOS 5.5 / 2.6.18-194.3.1.el5xen
                        grains['virtual_subtype'] = 'Xen PV DomU'
                    else:
                        # Shouldn't get to this, but just in case
                        grains['virtual_subtype'] = 'Xen Dom0'
                    caps.close()
                # Tested on Fedora 10 / 2.6.27.30-170.2.82 with xen
                # Tested on Fedora 15 / 2.6.41.4-1 without running xen
                elif isdir('/sys/bus/xen'):
                    if 'xen:' in __salt__['cmd.run']('dmesg').lower():
                        grains['virtual_subtype'] = 'Xen PV DomU'
                    elif os.listdir('/sys/bus/xen/drivers'):
                        # An actual DomU will have several drivers
                        # whereas a paravirt ops kernel will  not.
                        grains['virtual_subtype'] = 'Xen PV DomU'
            # If a Dom0 or DomU was detected, obviously this is xen
            if 'dom' in grains.get('virtual_subtype', '').lower():
                grains['virtual'] = 'xen'
        if os.path.isfile('/proc/cpuinfo'):
            if 'QEMU Virtual CPU' in salt.utils.fopen('/proc/cpuinfo', 'r').read():
                grains['virtual'] = 'kvm'
    elif osdata['kernel'] == 'FreeBSD':
        kenv = salt.utils.which('kenv')
        if kenv:
            product = __salt__['cmd.run']('{0} smbios.system.product'.format(kenv))
            maker = __salt__['cmd.run']('{0} smbios.system.maker'.format(kenv))
            if product.startswith('VMware'):
                grains['virtual'] = 'VMware'
            if maker.startswith('Xen'):
                grains['virtual_subtype'] = '{0} {1}'.format(maker, product)
                grains['virtual'] = 'xen'
        if sysctl:
            model = __salt__['cmd.run']('{0} hw.model'.format(sysctl))
            jail = __salt__['cmd.run']('{0} -n security.jail.jailed'.format(sysctl))
            if jail == '1':
                grains['virtual_subtype'] = 'jail'
            if 'QEMU Virtual CPU' in model:
                grains['virtual'] = 'kvm'
    elif osdata['kernel'] == 'SunOS':
        # Check if it's a "regular" zone. (i.e. Solaris 10/11 zone)
        zonename = salt.utils.which('zonename')
        if zonename:
            zone = __salt__['cmd.run']('{0}'.format(zonename))
            if zone != 'global':
                grains['virtual'] = 'zone'
                if osdata['os'] == 'SmartOS':
                    grains.update(_smartos_zone_data())
        # Check if it's a branded zone (i.e. Solaris 8/9 zone)
        if isdir('/.SUNWnative'):
            grains['virtual'] = 'zone'
    elif osdata['kernel'] == 'NetBSD':
        if sysctl:
            if 'QEMU Virtual CPU' in __salt__['cmd.run'](
                    '{0} -n machdep.cpu_brand'.format(sysctl)):
                grains['virtual'] = 'kvm'
            elif not 'invalid' in __salt__['cmd.run'](
                    '{0} -n machdep.xen.suspend'.format(sysctl)):
                grains['virtual'] = 'Xen PV DomU'
            elif 'VMware' in __salt__['cmd.run'](
                    '{0} -n machdep.dmi.system-vendor'.format(sysctl)):
                grains['virtual'] = 'VMware'
            # NetBSD has Xen dom0 support
            elif __salt__['cmd.run'](
                    '{0} -n machdep.idle-mechanism'.format(sysctl)) == 'xen':
                if os.path.isfile('/var/run/xenconsoled.pid'):
                    grains['virtual_subtype'] = 'Xen Dom0'

    return grains
Ejemplo n.º 28
0
def apply_minion_config(overrides=None, check_dns=True, defaults=None):
    '''
    Returns minion configurations dict.
    '''
    if defaults is None:
        defaults = DEFAULT_MINION_OPTS

    opts = defaults.copy()
    if overrides:
        opts.update(overrides)

    if len(opts['sock_dir']) > len(opts['cachedir']) + 10:
        opts['sock_dir'] = os.path.join(opts['cachedir'], '.salt-unix')

    if 'append_domain' in opts:
        opts['id'] = _append_domain(opts)

    if opts.get('file_client', 'remote') == 'local' and check_dns:
        check_dns = False

    if check_dns is True:
        # Because I import salt.log below I need to re-import salt.utils here
        import salt.utils
        try:
            opts['master_ip'] = salt.utils.dns_check(opts['master'], True)
        except SaltClientError:
            if opts['retry_dns']:
                while True:
                    import salt.log
                    msg = ('Master hostname: {0} not found. Retrying in {1} '
                           'seconds').format(opts['master'], opts['retry_dns'])
                    if salt.log.is_console_configured():
                        log.warn(msg)
                    else:
                        print('WARNING: {0}'.format(msg))
                    time.sleep(opts['retry_dns'])
                    try:
                        opts['master_ip'] = salt.utils.dns_check(
                            opts['master'], True
                        )
                        break
                    except SaltClientError:
                        pass
            else:
                opts['master_ip'] = '127.0.0.1'
    else:
        opts['master_ip'] = '127.0.0.1'

    opts['master_uri'] = 'tcp://{ip}:{port}'.format(ip=opts['master_ip'],
                                                    port=opts['master_port'])

    # Enabling open mode requires that the value be set to True, and
    # nothing else!
    opts['open_mode'] = opts['open_mode'] is True

    # set up the extension_modules location from the cachedir
    opts['extension_modules'] = (
        opts.get('extension_modules') or
        os.path.join(opts['cachedir'], 'extmods')
    )

    # Prepend root_dir to other paths
    prepend_root_dirs = [
        'pki_dir', 'cachedir', 'sock_dir', 'extension_modules', 'pidfile',
    ]

    # These can be set to syslog, so, not actual paths on the system
    for config_key in ('log_file', 'key_logfile'):
        if urlparse.urlparse(opts.get(config_key, '')).scheme == '':
            prepend_root_dirs.append(config_key)

    prepend_root_dir(opts, prepend_root_dirs)
    return opts
Ejemplo n.º 29
0
def _virtual(osdata):
    '''
    Returns what type of virtual hardware is under the hood, kvm or physical
    '''
    # This is going to be a monster, if you are running a vm you can test this
    # grain with please submit patches!
    # Provides:
    #   virtual
    grains = {'virtual': 'physical'}
    lspci = salt.utils.which('lspci')
    dmidecode = salt.utils.which('dmidecode')

    for command in ('dmidecode', 'lspci'):
        which = salt.utils.which(command)

        if which is None:
            continue

        ret = __salt__['cmd.run_all'](which)

        if ret['retcode'] > 0:
            if salt.log.is_logging_configured():
                log.warn(
                    'Although \'{0}\' was found in path, the current user '
                    'cannot execute it. Grains output might not be '
                    'accurate.'.format(command)
                )
            continue

        output = ret['stdout']

        if command == 'dmidecode':
            # Product Name: VirtualBox
            if 'Vendor: QEMU' in output:
                # FIXME: Make this detect between kvm or qemu
                grains['virtual'] = 'kvm'
            if 'Vendor: Bochs' in output:
                grains['virtual'] = 'kvm'
            elif 'VirtualBox' in output:
                grains['virtual'] = 'VirtualBox'
            # Product Name: VMware Virtual Platform
            elif 'VMware' in output:
                grains['virtual'] = 'VMware'
            # Manufacturer: Microsoft Corporation
            # Product Name: Virtual Machine
            elif 'Manufacturer: Microsoft' in output and 'Virtual Machine' in output:
                grains['virtual'] = 'VirtualPC'
            # Manufacturer: Parallels Software International Inc.
            elif 'Parallels Software' in output:
                grains['virtual'] = 'Parallels'
            # Break out of the loop, lspci parsing is not necessary
            break
        elif command == 'lspci':
            # dmidecode not available or the user does not have the necessary
            # permissions
            model = output.lower()
            if 'vmware' in model:
                grains['virtual'] = 'VMware'
            # 00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service
            elif 'virtualbox' in model:
                grains['virtual'] = 'VirtualBox'
            elif 'qemu' in model:
                grains['virtual'] = 'kvm'
            elif 'virtio' in model:
                grains['virtual'] = 'kvm'
            # Break out of the loop so the next log message is not issued
            break
    else:
        log.warn(
            'Both \'dmidecode\' and \'lspci\' failed to execute, either '
            'because they do not exist on the system of the user running '
            'this instance does not have the necessary permissions to '
            'execute them. Grains output might not be accurate.'
        )

    choices = ('Linux', 'OpenBSD', 'HP-UX')
    isdir = os.path.isdir
    if osdata['kernel'] in choices:
        if isdir('/proc/vz'):
            if os.path.isfile('/proc/vz/version'):
                grains['virtual'] = 'openvzhn'
            else:
                grains['virtual'] = 'openvzve'
        elif isdir('/proc/sys/xen') or isdir('/sys/bus/xen') or isdir('/proc/xen'):
            if os.path.isfile('/proc/xen/xsd_kva'):
                # Tested on CentOS 5.3 / 2.6.18-194.26.1.el5xen
                # Tested on CentOS 5.4 / 2.6.18-164.15.1.el5xen
                grains['virtual_subtype'] = 'Xen Dom0'
            else:
                if grains.get('productname', '') == 'HVM domU':
                    # Requires dmidecode!
                    grains['virtual_subtype'] = 'Xen HVM DomU'
                elif os.path.isfile('/proc/xen/capabilities') and os.access('/proc/xen/capabilities', os.R_OK):
                    caps = open('/proc/xen/capabilities')
                    if 'control_d' not in caps.read():
                        # Tested on CentOS 5.5 / 2.6.18-194.3.1.el5xen
                        grains['virtual_subtype'] = 'Xen PV DomU'
                    else:
                        # Shouldn't get to this, but just in case
                        grains['virtual_subtype'] = 'Xen Dom0'
                    caps.close()
                # Tested on Fedora 10 / 2.6.27.30-170.2.82 with xen
                # Tested on Fedora 15 / 2.6.41.4-1 without running xen
                elif isdir('/sys/bus/xen'):
                    if 'xen' in __salt__['cmd.run']('dmesg').lower():
                        grains['virtual_subtype'] = 'Xen PV DomU'
                    elif os.listdir('/sys/bus/xen/drivers'):
                        # An actual DomU will have several drivers
                        # whereas a paravirt ops kernel will  not.
                        grains['virtual_subtype'] = 'Xen PV DomU'
            # If a Dom0 or DomU was detected, obviously this is xen
            if 'dom' in grains.get('virtual_subtype', '').lower():
                grains['virtual'] = 'xen'
        if os.path.isfile('/proc/cpuinfo'):
            if 'QEMU Virtual CPU' in open('/proc/cpuinfo', 'r').read():
                grains['virtual'] = 'kvm'
    elif osdata['kernel'] == 'FreeBSD':
        sysctl = salt.utils.which('sysctl')
        kenv = salt.utils.which('kenv')
        if kenv:
            product = __salt__['cmd.run']('{0} smbios.system.product'.format(kenv)).strip()
            if product.startswith('VMware'):
                grains['virtual'] = 'VMware'
        if sysctl:
            model = __salt__['cmd.run']('{0} hw.model'.format(sysctl)).strip()
            jail = __salt__['cmd.run']('{0} -n security.jail.jailed'.format(sysctl)).strip()
            if jail:
                grains['virtual_subtype'] = 'jail'
            if 'QEMU Virtual CPU' in model:
                grains['virtual'] = 'kvm'
    elif osdata['kernel'] == 'SunOS':
        # Check if it's a "regular" zone. (i.e. Solaris 10/11 zone)
        zonename = salt.utils.which('zonename')
        if zonename:
            zone = __salt__['cmd.run']('{0}'.format(zonename)).strip()
            if zone != "global":
                grains['virtual'] = 'zone'
        # Check if it's a branded zone (i.e. Solaris 8/9 zone)
        if isdir('/.SUNWnative'):
            grains['virtual'] = 'zone'
    return grains
Ejemplo n.º 30
0
Archivo: core.py Proyecto: 1mentat/salt
def _linux_gpu_data():
    '''
    num_gpus: int
    gpus:
      - vendor: nvidia|amd|ati|...
        model: string
    '''
    lspci = salt.utils.which('lspci')
    if not lspci:
        log.info(
            'The `lspci` binary is not available on the system. GPU grains '
            'will not be available.'
        )
        return {}

    elif __opts__.get('enable_gpu_grains', None) is False:
        log.info(
            'Skipping lspci call because enable_gpu_grains was set to False '
            'in the config. GPU grains will not be available.'
        )
        return {}

    # dominant gpu vendors to search for (MUST be lowercase for matching below)
    known_vendors = ['nvidia', 'amd', 'ati', 'intel']

    devs = []
    try:
        lspci_out = __salt__['cmd.run']('lspci -vmm')

        cur_dev = {}
        error = False
        # Add a blank element to the lspci_out.splitlines() list,
        # otherwise the last device is not evaluated as a cur_dev and ignored.
        lspci_list = lspci_out.splitlines()
        lspci_list.append('')
        for line in lspci_list:
            # check for record-separating empty lines
            if line == '':
                if cur_dev.get('Class', '') == 'VGA compatible controller':
                    devs.append(cur_dev)
                # XXX; may also need to search for "3D controller"
                cur_dev = {}
                continue
            if re.match(r'^\w+:\s+.*', line):
                key, val = line.split(':', 1)
                cur_dev[key.strip()] = val.strip()
            else:
                error = True
                log.debug('Unexpected lspci output: \'{0}\''.format(line))

        if error:
            log.warn(
                'Error loading grains, unexpected linux_gpu_data output, '
                'check that you have a valid shell configured and '
                'permissions to run lspci command'
            )
    except OSError:
        pass

    gpus = []
    for gpu in devs:
        vendor_strings = gpu['Vendor'].lower().split()
        # default vendor to 'unknown', overwrite if we match a known one
        vendor = 'unknown'
        for name in known_vendors:
            # search for an 'expected' vendor name in the list of strings
            if name in vendor_strings:
                vendor = name
                break
        gpus.append({'vendor': vendor, 'model': gpu['Device']})

    grains = {}
    grains['num_gpus'] = len(gpus)
    grains['gpus'] = gpus
    return grains
Ejemplo n.º 31
0
def minion_config(path, check_dns=True):
    '''
    Reads in the minion configuration file and sets up special options
    '''
    opts = {
        'master': 'salt',
        'master_port': '4506',
        'master_finger': '',
        'user': '******',
        'root_dir': '/',
        'pki_dir': '/etc/salt/pki/minion',
        'id': socket.getfqdn(),
        'cachedir': '/var/cache/salt/minion',
        'cache_jobs': False,
        'conf_file': path,
        'sock_dir': '/var/run/salt/minion',
        'backup_mode': '',
        'renderer': 'yaml_jinja',
        'failhard': False,
        'autoload_dynamic_modules': True,
        'environment': None,
        'state_top': 'top.sls',
        'startup_states': '',
        'sls_list': [],
        'top_file': '',
        'file_client': 'remote',
        'file_roots': {
            'base': ['/srv/salt'],
        },
        'pillar_roots': {
            'base': ['/srv/pillar'],
        },
        'hash_type': 'md5',
        'external_nodes': '',
        'disable_modules': [],
        'disable_returners': [],
        'module_dirs': [],
        'returner_dirs': [],
        'states_dirs': [],
        'render_dirs': [],
        'providers': {},
        'clean_dynamic_modules': True,
        'open_mode': False,
        'multiprocessing': True,
        'sub_timeout': 0,
        'ipc_mode': 'ipc',
        'tcp_pub_port': 4510,
        'tcp_pull_port': 4511,
        'log_file': '/var/log/salt/minion',
        'log_level': None,
        'log_level_logfile': None,
        'log_datefmt': __dflt_log_datefmt,
        'log_fmt_console': __dflt_log_fmt_console,
        'log_fmt_logfile': __dflt_log_fmt_logfile,
        'log_granular_levels': {},
        'test': False,
        'cython_enable': False,
        'state_verbose': True,
        'state_output': 'full',
        'acceptance_wait_time': 10,
        'dns_check': True,
        'verify_env': True,
        'grains': {},
        'permissive_pki_access': False,
        'default_include': 'minion.d/*.conf',
        'update_url': False,
        'update_restart_services': [],
        'retry_dns': 30,
        'recon_max': 5000,
        'pidfile': '/var/run/salt-minion.pid',
    }

    if len(opts['sock_dir']) > len(opts['cachedir']) + 10:
        opts['sock_dir'] = os.path.join(opts['cachedir'], '.salt-unix')

    load_config(opts, path, 'SALT_MINION_CONFIG')

    default_include = opts.get('default_include', [])
    include = opts.get('include', [])

    opts = include_config(default_include, opts, path, verbose=False)
    opts = include_config(include, opts, path, verbose=True)

    if 'append_domain' in opts:
        opts['id'] = _append_domain(opts)

    if opts.get('file_client', 'remote') == 'local' and check_dns:
        check_dns = False

    if check_dns is True:
        # Because I import salt.log below I need to re-import salt.utils here
        import salt.utils
        try:
            opts['master_ip'] = salt.utils.dns_check(opts['master'], True)
        except SaltClientError:
            if opts['retry_dns']:
                while True:
                    import salt.log
                    msg = ('Master hostname: {0} not found. Retrying in {1} '
                           'seconds').format(opts['master'], opts['retry_dns'])
                    if salt.log.is_console_configured():
                        log.warn(msg)
                    else:
                        print('WARNING: {0}'.format(msg))
                    time.sleep(opts['retry_dns'])
                    try:
                        opts['master_ip'] = salt.utils.dns_check(
                            opts['master'], True)
                        break
                    except SaltClientError:
                        pass
            else:
                opts['master_ip'] = '127.0.0.1'
    else:
        opts['master_ip'] = '127.0.0.1'

    opts['master_uri'] = 'tcp://{ip}:{port}'.format(ip=opts['master_ip'],
                                                    port=opts['master_port'])

    # Enabling open mode requires that the value be set to True, and
    # nothing else!
    opts['open_mode'] = opts['open_mode'] is True

    # set up the extension_modules location from the cachedir
    opts['extension_modules'] = (opts.get('extension_modules')
                                 or os.path.join(opts['cachedir'], 'extmods'))

    # Prepend root_dir to other paths
    prepend_root_dirs = [
        'pki_dir',
        'cachedir',
        'sock_dir',
        'extension_modules',
        'pidfile',
    ]

    # These can be set to syslog, so, not actual paths on the system
    for config_key in ('log_file', 'key_logfile'):
        if urlparse.urlparse(opts.get(config_key, '')).scheme == '':
            prepend_root_dirs.append(config_key)

    prepend_root_dir(opts, prepend_root_dirs)
    return opts
Ejemplo n.º 32
0
def _virtual(osdata):
    '''
    Returns what type of virtual hardware is under the hood, kvm or physical
    '''
    # This is going to be a monster, if you are running a vm you can test this
    # grain with please submit patches!
    # Provides:
    #   virtual
    #   virtual_subtype
    grains = {'virtual': 'physical'}
    for command in ('dmidecode', 'lspci'):
        cmd = salt.utils.which(command)

        if not cmd:
            continue

        ret = __salt__['cmd.run_all'](cmd)

        if ret['retcode'] > 0:
            if salt.log.is_logging_configured():
                log.warn(
                    'Although \'{0}\' was found in path, the current user '
                    'cannot execute it. Grains output might not be '
                    'accurate.'.format(command))
            continue

        output = ret['stdout']

        if command == 'dmidecode':
            # Product Name: VirtualBox
            if 'Vendor: QEMU' in output:
                # FIXME: Make this detect between kvm or qemu
                grains['virtual'] = 'kvm'
            if 'Vendor: Bochs' in output:
                grains['virtual'] = 'kvm'
            elif 'VirtualBox' in output:
                grains['virtual'] = 'VirtualBox'
            # Product Name: VMware Virtual Platform
            elif 'VMware' in output:
                grains['virtual'] = 'VMware'
            # Manufacturer: Microsoft Corporation
            # Product Name: Virtual Machine
            elif 'Manufacturer: Microsoft' in output and 'Virtual Machine' in output:
                grains['virtual'] = 'VirtualPC'
            # Manufacturer: Parallels Software International Inc.
            elif 'Parallels Software' in output:
                grains['virtual'] = 'Parallels'
            # Break out of the loop, lspci parsing is not necessary
            break
        elif command == 'lspci':
            # dmidecode not available or the user does not have the necessary
            # permissions
            model = output.lower()
            if 'vmware' in model:
                grains['virtual'] = 'VMware'
            # 00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service
            elif 'virtualbox' in model:
                grains['virtual'] = 'VirtualBox'
            elif 'qemu' in model:
                grains['virtual'] = 'kvm'
            elif 'virtio' in model:
                grains['virtual'] = 'kvm'
            # Break out of the loop so the next log message is not issued
            break
    else:
        log.warn('Both \'dmidecode\' and \'lspci\' failed to execute, either '
                 'because they do not exist on the system of the user running '
                 'this instance does not have the necessary permissions to '
                 'execute them. Grains output might not be accurate.')

    choices = ('Linux', 'OpenBSD', 'HP-UX')
    isdir = os.path.isdir
    if osdata['kernel'] in choices:
        if isdir('/proc/vz'):
            if os.path.isfile('/proc/vz/version'):
                grains['virtual'] = 'openvzhn'
            else:
                grains['virtual'] = 'openvzve'
        elif isdir('/proc/sys/xen') or isdir('/sys/bus/xen') or isdir(
                '/proc/xen'):
            if os.path.isfile('/proc/xen/xsd_kva'):
                # Tested on CentOS 5.3 / 2.6.18-194.26.1.el5xen
                # Tested on CentOS 5.4 / 2.6.18-164.15.1.el5xen
                grains['virtual_subtype'] = 'Xen Dom0'
            else:
                if grains.get('productname', '') == 'HVM domU':
                    # Requires dmidecode!
                    grains['virtual_subtype'] = 'Xen HVM DomU'
                elif os.path.isfile('/proc/xen/capabilities') and os.access(
                        '/proc/xen/capabilities', os.R_OK):
                    caps = salt.utils.fopen('/proc/xen/capabilities')
                    if 'control_d' not in caps.read():
                        # Tested on CentOS 5.5 / 2.6.18-194.3.1.el5xen
                        grains['virtual_subtype'] = 'Xen PV DomU'
                    else:
                        # Shouldn't get to this, but just in case
                        grains['virtual_subtype'] = 'Xen Dom0'
                    caps.close()
                # Tested on Fedora 10 / 2.6.27.30-170.2.82 with xen
                # Tested on Fedora 15 / 2.6.41.4-1 without running xen
                elif isdir('/sys/bus/xen'):
                    if 'xen' in __salt__['cmd.run']('dmesg').lower():
                        grains['virtual_subtype'] = 'Xen PV DomU'
                    elif os.listdir('/sys/bus/xen/drivers'):
                        # An actual DomU will have several drivers
                        # whereas a paravirt ops kernel will  not.
                        grains['virtual_subtype'] = 'Xen PV DomU'
            # If a Dom0 or DomU was detected, obviously this is xen
            if 'dom' in grains.get('virtual_subtype', '').lower():
                grains['virtual'] = 'xen'
        if os.path.isfile('/proc/cpuinfo'):
            if 'QEMU Virtual CPU' in salt.utils.fopen('/proc/cpuinfo',
                                                      'r').read():
                grains['virtual'] = 'kvm'
    elif osdata['kernel'] == 'FreeBSD':
        sysctl = salt.utils.which('sysctl')
        kenv = salt.utils.which('kenv')
        if kenv:
            product = __salt__['cmd.run'](
                '{0} smbios.system.product'.format(kenv))
            if product.startswith('VMware'):
                grains['virtual'] = 'VMware'
        if sysctl:
            model = __salt__['cmd.run']('{0} hw.model'.format(sysctl))
            jail = __salt__['cmd.run'](
                '{0} -n security.jail.jailed'.format(sysctl))
            if jail == '1':
                grains['virtual_subtype'] = 'jail'
            if 'QEMU Virtual CPU' in model:
                grains['virtual'] = 'kvm'
    elif osdata['kernel'] == 'SunOS':
        # Check if it's a "regular" zone. (i.e. Solaris 10/11 zone)
        zonename = salt.utils.which('zonename')
        if zonename:
            zone = __salt__['cmd.run']('{0}'.format(zonename))
            if zone != "global":
                grains['virtual'] = 'zone'
        # Check if it's a branded zone (i.e. Solaris 8/9 zone)
        if isdir('/.SUNWnative'):
            grains['virtual'] = 'zone'
    return grains
Ejemplo n.º 33
0
def _linux_gpu_data():
    """
    num_gpus: int
    gpus:
      - vendor: nvidia|amd|ati|...
        model: string
    """
    lspci = salt.utils.which("lspci")
    if not lspci:
        log.info("The `lspci` binary is not available on the system. GPU grains " "will not be available.")
        return {}

    elif __opts__.get("enable_gpu_grains", None) is False:
        log.info(
            "Skipping lspci call because enable_gpu_grains was set to False "
            "in the config. GPU grains will not be available."
        )
        return {}

    # dominant gpu vendors to search for (MUST be lowercase for matching below)
    known_vendors = ["nvidia", "amd", "ati", "intel"]

    devs = []
    try:
        lspci_out = __salt__["cmd.run"]("lspci -vmm")

        cur_dev = {}
        error = False
        # Add a blank element to the lspci_out.splitlines() list,
        # otherwise the last device is not evaluated as a cur_dev and ignored.
        lspci_list = lspci_out.splitlines()
        lspci_list.append("")
        for line in lspci_list:
            # check for record-separating empty lines
            if line == "":
                if cur_dev.get("Class", "") == "VGA compatible controller":
                    devs.append(cur_dev)
                # XXX; may also need to search for "3D controller"
                cur_dev = {}
                continue
            if re.match(r"^\w+:\s+.*", line):
                key, val = line.split(":", 1)
                cur_dev[key.strip()] = val.strip()
            else:
                error = True
                log.debug("Unexpected lspci output: '{0}'".format(line))

        if error:
            log.warn(
                "Error loading grains, unexpected linux_gpu_data output, "
                "check that you have a valid shell configured and "
                "permissions to run lspci command"
            )
    except OSError:
        pass

    gpus = []
    for gpu in devs:
        vendor_strings = gpu["Vendor"].lower().split()
        # default vendor to 'unknown', overwrite if we match a known one
        vendor = "unknown"
        for name in known_vendors:
            # search for an 'expected' vendor name in the list of strings
            if name in vendor_strings:
                vendor = name
                break
        gpus.append({"vendor": vendor, "model": gpu["Device"]})

    grains = {}
    grains["num_gpus"] = len(gpus)
    grains["gpus"] = gpus
    return grains
Ejemplo n.º 34
0
def minion_config(path, check_dns=True):
    '''
    Reads in the minion configuration file and sets up special options
    '''
    opts = {'master': 'salt',
            'master_port': '4506',
            'master_finger': '',
            'user': '******',
            'root_dir': '/',
            'pki_dir': '/etc/salt/pki/minion',
            'id': socket.getfqdn(),
            'cachedir': '/var/cache/salt/minion',
            'cache_jobs': False,
            'conf_file': path,
            'sock_dir': '/var/run/salt/minion',
            'backup_mode': '',
            'renderer': 'yaml_jinja',
            'failhard': False,
            'autoload_dynamic_modules': True,
            'environment': None,
            'state_top': 'top.sls',
            'startup_states': '',
            'sls_list': [],
            'top_file': '',
            'file_client': 'remote',
            'file_roots': {
                'base': ['/srv/salt'],
                },
            'pillar_roots': {
                'base': ['/srv/pillar'],
                },
            'hash_type': 'md5',
            'external_nodes': '',
            'disable_modules': [],
            'disable_returners': [],
            'module_dirs': [],
            'returner_dirs': [],
            'states_dirs': [],
            'render_dirs': [],
            'providers': {},
            'clean_dynamic_modules': True,
            'open_mode': False,
            'multiprocessing': True,
            'sub_timeout': 0,
            'ipc_mode': 'ipc',
            'tcp_pub_port': 4510,
            'tcp_pull_port': 4511,
            'log_file': '/var/log/salt/minion',
            'log_level': None,
            'log_level_logfile': None,
            'log_datefmt': __dflt_log_datefmt,
            'log_fmt_console': __dflt_log_fmt_console,
            'log_fmt_logfile': __dflt_log_fmt_logfile,
            'log_granular_levels': {},
            'test': False,
            'cython_enable': False,
            'state_verbose': True,
            'state_output': 'full',
            'acceptance_wait_time': 10,
            'dns_check': True,
            'verify_env': True,
            'grains': {},
            'permissive_pki_access': False,
            'default_include': 'minion.d/*.conf',
            'update_url': False,
            'update_restart_services': [],
            'retry_dns': 30,
            'recon_max': 5000,
            }

    if len(opts['sock_dir']) > len(opts['cachedir']) + 10:
        opts['sock_dir'] = os.path.join(opts['cachedir'], '.salt-unix')

    load_config(opts, path, 'SALT_MINION_CONFIG')

    default_include = opts.get('default_include', [])
    include = opts.get('include', [])

    opts = include_config(default_include, opts, path, verbose=False)
    opts = include_config(include, opts, path, verbose=True)

    if 'append_domain' in opts:
        opts['id'] = _append_domain(opts)

    if opts.get('file_client', 'remote') == 'local' and check_dns:
        check_dns = False

    if check_dns is True:
        # Because I import salt.log below I need to re-import salt.utils here
        import salt.utils
        try:
            opts['master_ip'] = salt.utils.dns_check(opts['master'], True)
        except SaltClientError:
            if opts['retry_dns']:
                while True:
                    import salt.log
                    msg = ('Master hostname: {0} not found. Retrying in {1} '
                           'seconds').format(opts['master'], opts['retry_dns'])
                    if salt.log.is_console_configured():
                        log.warn(msg)
                    else:
                        print('WARNING: {0}'.format(msg))
                    time.sleep(opts['retry_dns'])
                    try:
                        opts['master_ip'] = salt.utils.dns_check(
                            opts['master'], True
                        )
                        break
                    except SaltClientError:
                        pass
            else:
                opts['master_ip'] = '127.0.0.1'
    else:
        opts['master_ip'] = '127.0.0.1'

    opts['master_uri'] = 'tcp://{ip}:{port}'.format(ip=opts['master_ip'],
                                                    port=opts['master_port'])

    # Enabling open mode requires that the value be set to True, and
    # nothing else!
    opts['open_mode'] = opts['open_mode'] is True

    # set up the extension_modules location from the cachedir
    opts['extension_modules'] = (
            opts.get('extension_modules') or
            os.path.join(opts['cachedir'], 'extmods')
            )

    # Prepend root_dir to other paths
    prepend_root_dirs = [
        'pki_dir', 'cachedir', 'sock_dir', 'extension_modules'
    ]

    # These can be set to syslog, so, not actual paths on the system
    for config_key in ('log_file', 'key_logfile'):
        if urlparse.urlparse(opts.get(config_key, '')).scheme == '':
            prepend_root_dirs.append(config_key)

    prepend_root_dir(opts, prepend_root_dirs)
    return opts
Ejemplo n.º 35
0
class Minion(object):
    '''
    Create a minion server
    '''
    def __init__(self):
        self.cli = self.__parse_cli()
        # command line overrides config
        if self.cli['user']:
            self.opts['user'] = self.cli['user']

    def __parse_cli(self):
        '''
        Parse the cli input
        '''
        import salt.log
        parser = optparse.OptionParser(version="%%prog %s" % __version__)
        parser.add_option('-d',
                          '--daemon',
                          dest='daemon',
                          default=False,
                          action='store_true',
                          help='Run the minion as a daemon')
        parser.add_option('-c',
                          '--config',
                          dest='config',
                          default='/etc/salt/minion',
                          help='Pass in an alternative configuration file')
        parser.add_option('-u',
                          '--user',
                          dest='user',
                          help='Specify user to run minion')
        parser.add_option('--pid-file',
                          dest='pidfile',
                          default='/var/run/salt-minion.pid',
                          help=('Specify the location of the pidfile. Default'
                                ' %default'))
        parser.add_option(
            '-l',
            '--log-level',
            dest='log_level',
            choices=list(salt.log.LOG_LEVELS),
            help='Console log level. One of %s. For the logfile settings '
            'see the config file. Default: \'warning\'.' %
            ', '.join([repr(l) for l in salt.log.SORTED_LEVEL_NAMES]))

        options, args = parser.parse_args()

        self.opts = salt.config.minion_config(options.config)

        if not options.log_level:
            options.log_level = self.opts['log_level']

        salt.log.setup_console_logger(options.log_level,
                                      log_format=self.opts['log_fmt_console'],
                                      date_format=self.opts['log_datefmt'])

        cli = {
            'daemon': options.daemon,
            'config': options.config,
            'user': options.user,
            'pidfile': options.pidfile
        }

        return cli

    def start(self):
        '''
        Execute this method to start up a minion.
        '''
        try:
            verify_env([
                self.opts['pki_dir'],
                self.opts['cachedir'],
                self.opts['sock_dir'],
                self.opts['extension_modules'],
                os.path.dirname(self.opts['log_file']),
            ],
                       self.opts['user'],
                       permissive=self.opts['permissive_pki_access'])
        except OSError, err:
            sys.exit(err.errno)

        import salt.log
        salt.log.setup_logfile_logger(self.opts['log_file'],
                                      self.opts['log_level_logfile']
                                      or self.opts['log_level'],
                                      log_format=self.opts['log_fmt_logfile'],
                                      date_format=self.opts['log_datefmt'])
        for name, level in self.opts['log_granular_levels'].items():
            salt.log.set_logger_level(name, level)

        import logging
        # Late import so logging works correctly
        import salt.minion
        log = logging.getLogger(__name__)
        if self.cli['daemon']:
            # Late import so logging works correctly
            import salt.utils
            # If the minion key has not been accepted, then Salt enters a loop
            # waiting for it, if we daemonize later then the minion could halt
            # the boot process waiting for a key to be accepted on the master.
            # This is the latest safe place to daemonize
            salt.utils.daemonize()
        try:
            minion = salt.minion.Minion(self.opts)
            set_pidfile(self.cli['pidfile'])
            if check_user(self.opts['user'], log):
                minion.tune_in()
        except KeyboardInterrupt:
            log.warn('Stopping the Salt Minion')
            raise SystemExit('\nExiting on Ctrl-c')
Ejemplo n.º 36
0
def _virtual(osdata):
    """
    Returns what type of virtual hardware is under the hood, kvm or physical
    """
    # This is going to be a monster, if you are running a vm you can test this
    # grain with please submit patches!
    # Provides:
    #   virtual
    #   virtual_subtype
    grains = {"virtual": "physical"}
    for command in ("dmidecode", "lspci", "dmesg"):
        args = []
        if osdata["kernel"] == "Darwin":
            command = "system_profiler"
            args = ["SPDisplaysDataType"]

        cmd = salt.utils.which(command)

        if not cmd:
            continue

        cmd = "%s %s" % (command, " ".join(args))

        ret = __salt__["cmd.run_all"](cmd)

        if ret["retcode"] > 0:
            if salt.log.is_logging_configured():
                if salt.utils.is_windows():
                    continue
                log.warn(
                    "Although '{0}' was found in path, the current user "
                    "cannot execute it. Grains output might not be "
                    "accurate.".format(command)
                )
            continue

        output = ret["stdout"]
        if command == "system_profiler":
            macoutput = output.lower()
            if "0x1ab8" in macoutput:
                grains["virtual"] = "Parallels"
            if "parallels" in macoutput:
                grains["virtual"] = "Parallels"
            if "vmware" in macoutput:
                grains["virtual"] = "VMware"
            if "0x15ad" in macoutput:
                grains["virtual"] = "VMware"
            if "virtualbox" in macoutput:
                grains["virtual"] = "VirtualBox"
            # Break out of the loop so the next log message is not issued
            break

        elif command == "dmidecode" or command == "dmesg":
            # Product Name: VirtualBox
            if "Vendor: QEMU" in output:
                # FIXME: Make this detect between kvm or qemu
                grains["virtual"] = "kvm"
            if "Vendor: Bochs" in output:
                grains["virtual"] = "kvm"
            # Product Name: (oVirt) www.ovirt.org
            # Red Hat Community virtualization Project based on kvm
            elif "Manufacturer: oVirt" in output:
                grains["virtual"] = "kvm"
            elif "VirtualBox" in output:
                grains["virtual"] = "VirtualBox"
            # Product Name: VMware Virtual Platform
            elif "VMware" in output:
                grains["virtual"] = "VMware"
            # Manufacturer: Microsoft Corporation
            # Product Name: Virtual Machine
            elif ": Microsoft" in output and "Virtual Machine" in output:
                grains["virtual"] = "VirtualPC"
            # Manufacturer: Parallels Software International Inc.
            elif "Parallels Software" in output:
                grains["virtual"] = "Parallels"
            # Break out of the loop, lspci parsing is not necessary
            break
        elif command == "lspci":
            # dmidecode not available or the user does not have the necessary
            # permissions
            model = output.lower()
            if "vmware" in model:
                grains["virtual"] = "VMware"
            # 00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service
            elif "virtualbox" in model:
                grains["virtual"] = "VirtualBox"
            elif "qemu" in model:
                grains["virtual"] = "kvm"
            elif "virtio" in model:
                grains["virtual"] = "kvm"
            # Break out of the loop so the next log message is not issued
            break
    else:
        log.warn(
            "The tools 'dmidecode', 'lspci' and 'dmesg' failed to execute "
            "because they do not exist on the system of the user running "
            "this instance or the user does not have the necessary permissions "
            "to execute them. Grains output might not be accurate."
        )

    choices = ("Linux", "OpenBSD", "HP-UX")
    isdir = os.path.isdir
    sysctl = salt.utils.which("sysctl")
    if osdata["kernel"] in choices:
        if os.path.isfile("/proc/1/cgroup"):
            if ":/lxc/" in salt.utils.fopen("/proc/1/cgroup", "r").read():
                grains["virtual_subtype"] = "LXC"
        if isdir("/proc/vz"):
            if os.path.isfile("/proc/vz/version"):
                grains["virtual"] = "openvzhn"
            else:
                grains["virtual"] = "openvzve"
        elif isdir("/proc/sys/xen") or isdir("/sys/bus/xen") or isdir("/proc/xen"):
            if os.path.isfile("/proc/xen/xsd_kva"):
                # Tested on CentOS 5.3 / 2.6.18-194.26.1.el5xen
                # Tested on CentOS 5.4 / 2.6.18-164.15.1.el5xen
                grains["virtual_subtype"] = "Xen Dom0"
            else:
                if grains.get("productname", "") == "HVM domU":
                    # Requires dmidecode!
                    grains["virtual_subtype"] = "Xen HVM DomU"
                elif os.path.isfile("/proc/xen/capabilities") and os.access("/proc/xen/capabilities", os.R_OK):
                    caps = salt.utils.fopen("/proc/xen/capabilities")
                    if "control_d" not in caps.read():
                        # Tested on CentOS 5.5 / 2.6.18-194.3.1.el5xen
                        grains["virtual_subtype"] = "Xen PV DomU"
                    else:
                        # Shouldn't get to this, but just in case
                        grains["virtual_subtype"] = "Xen Dom0"
                    caps.close()
                # Tested on Fedora 10 / 2.6.27.30-170.2.82 with xen
                # Tested on Fedora 15 / 2.6.41.4-1 without running xen
                elif isdir("/sys/bus/xen"):
                    if "xen:" in __salt__["cmd.run"]("dmesg").lower():
                        grains["virtual_subtype"] = "Xen PV DomU"
                    elif os.listdir("/sys/bus/xen/drivers"):
                        # An actual DomU will have several drivers
                        # whereas a paravirt ops kernel will  not.
                        grains["virtual_subtype"] = "Xen PV DomU"
            # If a Dom0 or DomU was detected, obviously this is xen
            if "dom" in grains.get("virtual_subtype", "").lower():
                grains["virtual"] = "xen"
        if os.path.isfile("/proc/cpuinfo"):
            if "QEMU Virtual CPU" in salt.utils.fopen("/proc/cpuinfo", "r").read():
                grains["virtual"] = "kvm"
    elif osdata["kernel"] == "FreeBSD":
        kenv = salt.utils.which("kenv")
        if kenv:
            product = __salt__["cmd.run"]("{0} smbios.system.product".format(kenv))
            maker = __salt__["cmd.run"]("{0} smbios.system.maker".format(kenv))
            if product.startswith("VMware"):
                grains["virtual"] = "VMware"
            if maker.startswith("Xen"):
                grains["virtual_subtype"] = "{0} {1}".format(maker, product)
                grains["virtual"] = "xen"
        if sysctl:
            model = __salt__["cmd.run"]("{0} hw.model".format(sysctl))
            jail = __salt__["cmd.run"]("{0} -n security.jail.jailed".format(sysctl))
            if jail == "1":
                grains["virtual_subtype"] = "jail"
            if "QEMU Virtual CPU" in model:
                grains["virtual"] = "kvm"
    elif osdata["kernel"] == "SunOS":
        # Check if it's a "regular" zone. (i.e. Solaris 10/11 zone)
        zonename = salt.utils.which("zonename")
        if zonename:
            zone = __salt__["cmd.run"]("{0}".format(zonename))
            if zone != "global":
                grains["virtual"] = "zone"
                if osdata["os"] == "SmartOS":
                    grains.update(_smartos_zone_data())
        # Check if it's a branded zone (i.e. Solaris 8/9 zone)
        if isdir("/.SUNWnative"):
            grains["virtual"] = "zone"
    elif osdata["kernel"] == "NetBSD":
        if sysctl:
            if "QEMU Virtual CPU" in __salt__["cmd.run"]("{0} -n machdep.cpu_brand".format(sysctl)):
                grains["virtual"] = "kvm"
            elif not "invalid" in __salt__["cmd.run"]("{0} -n machdep.xen.suspend".format(sysctl)):
                grains["virtual"] = "Xen PV DomU"
            elif "VMware" in __salt__["cmd.run"]("{0} -n machdep.dmi.system-vendor".format(sysctl)):
                grains["virtual"] = "VMware"
            # NetBSD has Xen dom0 support
            elif __salt__["cmd.run"]("{0} -n machdep.idle-mechanism".format(sysctl)) == "xen":
                if os.path.isfile("/var/run/xenconsoled.pid"):
                    grains["virtual_subtype"] = "Xen Dom0"

    return grains
Ejemplo n.º 37
0
class Syndic(object):
    '''
    Create a syndic server
    '''
    def __init__(self):
        self.cli = self.__parse_cli()
        # command line overrides config
        if self.cli['user']:
            self.opts['user'] = self.cli['user']

    def __prep_opts(self, cli):
        '''
        Generate the opts used by the syndic
        '''
        opts = salt.config.master_config(cli['master_config'])
        opts['_minion_conf_file'] = opts['conf_file']
        opts.update(salt.config.minion_config(cli['minion_config']))
        if 'syndic_master' in opts:
            # Some of the opts need to be changed to match the needed opts
            # in the minion class.
            opts['master'] = opts['syndic_master']
            opts['master_ip'] = salt.utils.dns_check(opts['master'])

            opts['master_uri'] = ('tcp://' + opts['master_ip'] + ':' +
                                  str(opts['master_port']))
            opts['_master_conf_file'] = opts['conf_file']
            opts.pop('conf_file')
            return opts
        err = ('The syndic_master needs to be configured in the salt master '
               'config, EXITING!\n')
        sys.stderr.write(err)
        sys.exit(2)

    def __parse_cli(self):
        '''
        Parse the cli for options passed to a syndic daemon
        '''
        import salt.log
        parser = optparse.OptionParser(version="%%prog %s" % __version__)
        parser.add_option('-d',
                          '--daemon',
                          dest='daemon',
                          default=False,
                          action='store_true',
                          help='Run the syndic as a daemon')
        parser.add_option(
            '--master-config',
            dest='master_config',
            default='/etc/salt/master',
            help='Pass in an alternative master configuration file')
        parser.add_option(
            '--minion-config',
            dest='minion_config',
            default='/etc/salt/minion',
            help='Pass in an alternative minion configuration file')
        parser.add_option('-u',
                          '--user',
                          dest='user',
                          help='Specify user to run syndic')
        parser.add_option('--pid-file',
                          dest='pidfile',
                          default='/var/run/salt-syndic.pid',
                          help=('Specify the location of the pidfile. Default'
                                ' %default'))
        parser.add_option(
            '-l',
            '--log-level',
            dest='log_level',
            choices=list(salt.log.LOG_LEVELS),
            help='Console log level. One of %s. For the logfile settings '
            'see the config file. Default: \'warning\'.' %
            ', '.join([repr(l) for l in salt.log.LOG_LEVELS]))

        options, args = parser.parse_args()

        cli = {
            'daemon': options.daemon,
            'minion_config': options.minion_config,
            'master_config': options.master_config,
            'pidfile': options.pidfile,
            'user': options.user
        }

        self.opts = self.__prep_opts(cli)

        if not options.log_level:
            options.log_level = self.opts['log_level']

        salt.log.setup_console_logger(options.log_level,
                                      log_format=self.opts['log_fmt_console'],
                                      date_format=self.opts['log_datefmt'])

        return cli

    def start(self):
        '''
        Execute this method to start up a syndic.
        '''
        try:
            verify_env([
                self.opts['pki_dir'],
                self.opts['cachedir'],
                os.path.dirname(self.opts['log_file']),
            ],
                       self.opts['user'],
                       permissive=self.opts['permissive_pki_access'])
        except OSError, err:
            sys.exit(err.errno)
        import salt.log
        salt.log.setup_logfile_logger(self.opts['log_file'],
                                      self.opts['log_level'])
        for name, level in self.opts['log_granular_levels'].items():
            salt.log.set_logger_level(name, level)

        import logging

        # Late import so logging works correctly
        import salt.minion
        log = logging.getLogger(__name__)
        if self.cli['daemon']:
            # Late import so logging works correctly
            import salt.utils
            salt.utils.daemonize()
        set_pidfile(self.cli['pidfile'])
        if check_user(self.opts['user'], log):
            try:
                syndic = salt.minion.Syndic(self.opts)
                syndic.tune_in()
            except KeyboardInterrupt:
                log.warn('Stopping the Salt Syndic Minion')
                raise SystemExit('\nExiting on Ctrl-c')
Ejemplo n.º 38
0
def _virtual(osdata):
    '''
    Returns what type of virtual hardware is under the hood, kvm or physical
    '''
    # This is going to be a monster, if you are running a vm you can test this
    # grain with please submit patches!
    # Provides:
    #   virtual
    #   virtual_subtype
    grains = {'virtual': 'physical'}
    for command in ('dmidecode', 'lspci', 'dmesg'):
        args = []
        if osdata['kernel'] == 'Darwin':
            command = 'system_profiler'
            args = ['SPDisplaysDataType']

        cmd = salt.utils.which(command)

        if not cmd:
            continue

        cmd = '%s %s' % (command, ' '.join(args))

        ret = __salt__['cmd.run_all'](cmd)

        if ret['retcode'] > 0:
            if salt.log.is_logging_configured():
                if salt.utils.is_windows():
                    continue
                log.warn(
                    'Although \'{0}\' was found in path, the current user '
                    'cannot execute it. Grains output might not be '
                    'accurate.'.format(command))
            continue

        output = ret['stdout']
        if command == "system_profiler":
            macoutput = output.lower()
            if '0x1ab8' in macoutput:
                grains['virtual'] = 'Parallels'
            if 'parallels' in macoutput:
                grains['virtual'] = 'Parallels'
            if 'vmware' in macoutput:
                grains['virtual'] = 'VMware'
            if '0x15ad' in macoutput:
                grains['virtual'] = 'VMware'
            if 'virtualbox' in macoutput:
                grains['virtual'] = 'VirtualBox'
            # Break out of the loop so the next log message is not issued
            break

        elif command == 'dmidecode' or command == 'dmesg':
            # Product Name: VirtualBox
            if 'Vendor: QEMU' in output:
                # FIXME: Make this detect between kvm or qemu
                grains['virtual'] = 'kvm'
            if 'Vendor: Bochs' in output:
                grains['virtual'] = 'kvm'
            # Product Name: (oVirt) www.ovirt.org
            # Red Hat Community virtualization Project based on kvm
            elif 'Manufacturer: oVirt' in output:
                grains['virtual'] = 'kvm'
            elif 'VirtualBox' in output:
                grains['virtual'] = 'VirtualBox'
            # Product Name: VMware Virtual Platform
            elif 'VMware' in output:
                grains['virtual'] = 'VMware'
            # Manufacturer: Microsoft Corporation
            # Product Name: Virtual Machine
            elif ': Microsoft' in output and 'Virtual Machine' in output:
                grains['virtual'] = 'VirtualPC'
            # Manufacturer: Parallels Software International Inc.
            elif 'Parallels Software' in output:
                grains['virtual'] = 'Parallels'
            # Break out of the loop, lspci parsing is not necessary
            break
        elif command == 'lspci':
            # dmidecode not available or the user does not have the necessary
            # permissions
            model = output.lower()
            if 'vmware' in model:
                grains['virtual'] = 'VMware'
            # 00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service
            elif 'virtualbox' in model:
                grains['virtual'] = 'VirtualBox'
            elif 'qemu' in model:
                grains['virtual'] = 'kvm'
            elif 'virtio' in model:
                grains['virtual'] = 'kvm'
            # Break out of the loop so the next log message is not issued
            break
    else:
        log.warn(
            'The tools \'dmidecode\', \'lspci\' and \'dmesg\' failed to execute '
            'because they do not exist on the system of the user running '
            'this instance or the user does not have the necessary permissions '
            'to execute them. Grains output might not be accurate.')

    choices = ('Linux', 'OpenBSD', 'HP-UX')
    isdir = os.path.isdir
    sysctl = salt.utils.which('sysctl')
    if osdata['kernel'] in choices:
        if os.path.isfile('/proc/1/cgroup'):
            try:
                if ':/lxc/' in salt.utils.fopen('/proc/1/cgroup', 'r').read():
                    grains['virtual_subtype'] = 'LXC'
            except IOError:
                pass
        if isdir('/proc/vz'):
            if os.path.isfile('/proc/vz/version'):
                grains['virtual'] = 'openvzhn'
            elif os.path.isfile('/proc/vz/veinfo'):
                grains['virtual'] = 'openvzve'
        elif isdir('/proc/sys/xen') or isdir('/sys/bus/xen') or isdir(
                '/proc/xen'):
            if os.path.isfile('/proc/xen/xsd_kva'):
                # Tested on CentOS 5.3 / 2.6.18-194.26.1.el5xen
                # Tested on CentOS 5.4 / 2.6.18-164.15.1.el5xen
                grains['virtual_subtype'] = 'Xen Dom0'
            else:
                if grains.get('productname', '') == 'HVM domU':
                    # Requires dmidecode!
                    grains['virtual_subtype'] = 'Xen HVM DomU'
                elif os.path.isfile('/proc/xen/capabilities') and os.access(
                        '/proc/xen/capabilities', os.R_OK):
                    caps = salt.utils.fopen('/proc/xen/capabilities')
                    if 'control_d' not in caps.read():
                        # Tested on CentOS 5.5 / 2.6.18-194.3.1.el5xen
                        grains['virtual_subtype'] = 'Xen PV DomU'
                    else:
                        # Shouldn't get to this, but just in case
                        grains['virtual_subtype'] = 'Xen Dom0'
                    caps.close()
                # Tested on Fedora 10 / 2.6.27.30-170.2.82 with xen
                # Tested on Fedora 15 / 2.6.41.4-1 without running xen
                elif isdir('/sys/bus/xen'):
                    if 'xen:' in __salt__['cmd.run']('dmesg').lower():
                        grains['virtual_subtype'] = 'Xen PV DomU'
                    elif os.listdir('/sys/bus/xen/drivers'):
                        # An actual DomU will have several drivers
                        # whereas a paravirt ops kernel will  not.
                        grains['virtual_subtype'] = 'Xen PV DomU'
            # If a Dom0 or DomU was detected, obviously this is xen
            if 'dom' in grains.get('virtual_subtype', '').lower():
                grains['virtual'] = 'xen'
        if os.path.isfile('/proc/cpuinfo'):
            if 'QEMU Virtual CPU' in salt.utils.fopen('/proc/cpuinfo',
                                                      'r').read():
                grains['virtual'] = 'kvm'
    elif osdata['kernel'] == 'FreeBSD':
        kenv = salt.utils.which('kenv')
        if kenv:
            product = __salt__['cmd.run'](
                '{0} smbios.system.product'.format(kenv))
            maker = __salt__['cmd.run']('{0} smbios.system.maker'.format(kenv))
            if product.startswith('VMware'):
                grains['virtual'] = 'VMware'
            if maker.startswith('Xen'):
                grains['virtual_subtype'] = '{0} {1}'.format(maker, product)
                grains['virtual'] = 'xen'
        if sysctl:
            model = __salt__['cmd.run']('{0} hw.model'.format(sysctl))
            jail = __salt__['cmd.run'](
                '{0} -n security.jail.jailed'.format(sysctl))
            if jail == '1':
                grains['virtual_subtype'] = 'jail'
            if 'QEMU Virtual CPU' in model:
                grains['virtual'] = 'kvm'
    elif osdata['kernel'] == 'SunOS':
        # Check if it's a "regular" zone. (i.e. Solaris 10/11 zone)
        zonename = salt.utils.which('zonename')
        if zonename:
            zone = __salt__['cmd.run']('{0}'.format(zonename))
            if zone != 'global':
                grains['virtual'] = 'zone'
                if osdata['os'] == 'SmartOS':
                    grains.update(_smartos_zone_data())
        # Check if it's a branded zone (i.e. Solaris 8/9 zone)
        if isdir('/.SUNWnative'):
            grains['virtual'] = 'zone'
    elif osdata['kernel'] == 'NetBSD':
        if sysctl:
            if 'QEMU Virtual CPU' in __salt__['cmd.run'](
                    '{0} -n machdep.cpu_brand'.format(sysctl)):
                grains['virtual'] = 'kvm'
            elif not 'invalid' in __salt__['cmd.run'](
                    '{0} -n machdep.xen.suspend'.format(sysctl)):
                grains['virtual'] = 'Xen PV DomU'
            elif 'VMware' in __salt__['cmd.run'](
                    '{0} -n machdep.dmi.system-vendor'.format(sysctl)):
                grains['virtual'] = 'VMware'
            # NetBSD has Xen dom0 support
            elif __salt__['cmd.run'](
                    '{0} -n machdep.idle-mechanism'.format(sysctl)) == 'xen':
                if os.path.isfile('/var/run/xenconsoled.pid'):
                    grains['virtual_subtype'] = 'Xen Dom0'

    return grains
Ejemplo n.º 39
0
def load_config(path, env_var, default_path=None):
    '''
    Returns configuration dict from parsing either the file described by
    ``path`` or the environment variable described by ``env_var`` as YAML.
    '''
    if path is None:
        # When the passed path is None, we just want the configuration
        # defaults, not actually loading the whole configuration.
        return {}

    if default_path is None:
        # This is most likely not being used from salt, ie, could be salt-cloud
        # or salt-api which have not yet migrated to the new default_path
        # argument. Let's issue a warning message that the environ vars won't
        # work.
        import inspect
        previous_frame = inspect.getframeinfo(inspect.currentframe().f_back)
        log.warning(
            'The function \'{0}()\' defined in {1!r} is not yet using the '
            'new \'default_path\' argument to `salt.config.load_config()`. '
            'As such, the {2!r} environment variable will be ignored'.format(
                previous_frame.function, previous_frame.filename, env_var))
        # In this case, maintain old behaviour
        default_path = DEFAULT_MASTER_OPTS['conf_file']

    # Default to the environment variable path, if it exists
    env_path = os.environ.get(env_var, path)
    if not env_path or not os.path.isfile(env_path):
        env_path = path
    # If non-default path from `-c`, use that over the env variable
    if path != default_path:
        env_path = path

    path = env_path

    # If the configuration file is missing, attempt to copy the template,
    # after removing the first header line.
    if not os.path.isfile(path):
        template = '{0}.template'.format(path)
        if os.path.isfile(template):
            import salt.utils  # TODO: Need to re-import, need to find out why
            log.debug('Writing {0} based on {1}'.format(path, template))
            with salt.utils.fopen(path, 'w') as out:
                with salt.utils.fopen(template, 'r') as ifile:
                    ifile.readline()  # skip first line
                    out.write(ifile.read())

    if os.path.isfile(path):
        try:
            opts = _read_conf_file(path)
            opts['conf_file'] = path
            return opts
        except Exception as err:
            import salt.log
            msg = 'Error parsing configuration file: {0} - {1}'
            if salt.log.is_console_configured():
                log.warn(msg.format(path, err))
            else:
                print(msg.format(path, err))
    else:
        log.debug('Missing configuration file: {0}'.format(path))

    return {}
Ejemplo n.º 40
0
def load_config(path, env_var, default_path=None):
    '''
    Returns configuration dict from parsing either the file described by
    ``path`` or the environment variable described by ``env_var`` as YAML.
    '''
    if path is None:
        # When the passed path is None, we just want the configuration
        # defaults, not actually loading the whole configuration.
        return {}

    if default_path is None:
        # This is most likely not being used from salt, ie, could be salt-cloud
        # or salt-api which have not yet migrated to the new default_path
        # argument. Let's issue a warning message that the environ vars won't
        # work.
        import inspect
        previous_frame = inspect.getframeinfo(inspect.currentframe().f_back)
        log.warning(
            'The function \'{0}()\' defined in {1!r} is not yet using the '
            'new \'default_path\' argument to `salt.config.load_config()`. '
            'As such, the {2!r} environment variable will be ignored'.format(
                previous_frame.function, previous_frame.filename, env_var
            )
        )
        # In this case, maintain old behaviour
        default_path = DEFAULT_MASTER_OPTS['conf_file']

    # Default to the environment variable path, if it exists
    env_path = os.environ.get(env_var, path)
    if not env_path or not os.path.isfile(env_path):
        env_path = path
    # If non-default path from `-c`, use that over the env variable
    if path != default_path:
        env_path = path

    path = env_path

    # If the configuration file is missing, attempt to copy the template,
    # after removing the first header line.
    if not os.path.isfile(path):
        template = '{0}.template'.format(path)
        if os.path.isfile(template):
            import salt.utils  # TODO: Need to re-import, need to find out why
            log.debug('Writing {0} based on {1}'.format(path, template))
            with salt.utils.fopen(path, 'w') as out:
                with salt.utils.fopen(template, 'r') as ifile:
                    ifile.readline()  # skip first line
                    out.write(ifile.read())

    if os.path.isfile(path):
        try:
            opts = _read_conf_file(path)
            opts['conf_file'] = path
            return opts
        except Exception as err:
            import salt.log
            msg = 'Error parsing configuration file: {0} - {1}'
            if salt.log.is_console_configured():
                log.warn(msg.format(path, err))
            else:
                print(msg.format(path, err))
    else:
        log.debug('Missing configuration file: {0}'.format(path))

    return {}
Ejemplo n.º 41
0
def _linux_gpu_data():
    '''
    num_gpus: int
    gpus:
      - vendor: nvidia|amd|ati|...
        model: string
    '''
    lspci = salt.utils.which('lspci')
    if not lspci:
        log.info(
            'The `lspci` binary is not available on the system. GPU grains '
            'will not be available.')
        return {}

    elif __opts__.get('enable_gpu_grains', None) is False:
        log.info(
            'Skipping lspci call because enable_gpu_grains was set to False '
            'in the config. GPU grains will not be available.')
        return {}

    # dominant gpu vendors to search for (MUST be lowercase for matching below)
    known_vendors = ['nvidia', 'amd', 'ati', 'intel']

    devs = []
    try:
        lspci_out = __salt__['cmd.run']('lspci -vmm')

        cur_dev = {}
        error = False
        # Add a blank element to the lspci_out.splitlines() list,
        # otherwise the last device is not evaluated as a cur_dev and ignored.
        lspci_list = lspci_out.splitlines()
        lspci_list.append('')
        for line in lspci_list:
            # check for record-separating empty lines
            if line == '':
                if cur_dev.get('Class', '') == 'VGA compatible controller':
                    devs.append(cur_dev)
                # XXX; may also need to search for "3D controller"
                cur_dev = {}
                continue
            if re.match(r'^\w+:\s+.*', line):
                key, val = line.split(':', 1)
                cur_dev[key.strip()] = val.strip()
            else:
                error = True
                log.debug('Unexpected lspci output: \'{0}\''.format(line))

        if error:
            log.warn('Error loading grains, unexpected linux_gpu_data output, '
                     'check that you have a valid shell configured and '
                     'permissions to run lspci command')
    except OSError:
        pass

    gpus = []
    for gpu in devs:
        vendor_strings = gpu['Vendor'].lower().split()
        # default vendor to 'unknown', overwrite if we match a known one
        vendor = 'unknown'
        for name in known_vendors:
            # search for an 'expected' vendor name in the list of strings
            if name in vendor_strings:
                vendor = name
                break
        gpus.append({'vendor': vendor, 'model': gpu['Device']})

    grains = {}
    grains['num_gpus'] = len(gpus)
    grains['gpus'] = gpus
    return grains