saltstack源码-启动2-parsers.py选项初始化1
class MasterOptionParser(OptionParser, ConfigDirMixIn, MergeConfigMixIn, LogLevelMixIn, RunUserMixin, DaemonMixIn, PidfileMixin):#这些差不多全是salt初始化的类,有的minion也会调用 __metaclass__ = OptionParserMeta #指定他的元类 description = 'The Salt master, used to control the Salt minions.' # ConfigDirMixIn config filename attribute _config_filename_ = 'master'#默认配置文件名 # LogLevelMixIn attributes _default_logging_logfile_ = os.path.join(syspaths.LOGS_DIR, 'master') #这里是得到他的日志文件路径/var/log/salt/master def setup_config(self): return config.master_config(self.get_config_file_path())
接下来就是查找他的元类
python类在初始化的时候,经历了两个阶段,第一个阶段是分配空间__new__(),第二个阶段是初始化值__init__()。当类被创建时,python会首先寻找__metaclass__是否存在,
如果存在则调用__metaclass__。如果此类没定义__metaclass__就去看父类,父类没有就去模块里找(全局变量__metaclass__),
模块里再没有就把__metaclass__ = type作为类的metaclass。
mcs代表调用__new__函数的class,name代表对象的__name__值,也就是名称,bases代表对象的父类元组,attrs代表类的属性字典.
class MixInMeta(type): # This attribute here won't actually do anything. But, if you need to # specify an order or a dependency within the mix-ins, please define the # attribute on your own MixIn _mixin_prio_ = 0 def __new__(mcs, name, bases, attrs): instance = super(MixInMeta, mcs).__new__(mcs, name, bases, attrs) if not hasattr(instance, '_mixin_setup'): raise RuntimeError( 'Don\'t subclass {0} in {1} if you\'re not going to use it ' 'as a salt parser mix-in.'.format(mcs.__name__, name) ) return instance class OptionParserMeta(MixInMeta): def __new__(mcs, name, bases, attrs): instance = super(OptionParserMeta, mcs).__new__(mcs, name, bases, attrs) #上面调用父类的MinInMeta.__new__方法 if not hasattr(instance, '_mixin_setup_funcs'): instance._mixin_setup_funcs = [] if not hasattr(instance, '_mixin_process_funcs'): instance._mixin_process_funcs = [] if not hasattr(instance, '_mixin_after_parsed_funcs'): instance._mixin_after_parsed_funcs = [] #这条语句分别创建了3个空列表 for base in _sorted(bases + (instance,)): #这里是把基类和子类进行排序 func = getattr(base, '_mixin_setup', None)#得到所有类_mixin_setup属性方法,没有就赋值为None if func is not None and func not in instance._mixin_setup_funcs: instance._mixin_setup_funcs.append(func) #for循环过后得到的列表 _mixin_setup_funcs[ConfigDirMixIn._mixin_setup, # LogLevelMixIn._mixin_setup, # RunUserMixin._mixin_setup, # DaemonMixIn_mixin_setup, # PidfileMixin._mixin_setup, # ] #这些类方法是初始化salt的选项命令 func = getattr(base, '_mixin_after_parsed', None)##得到所有类_mixin_after_parsed属性方法,没有就赋值为None if func is not None and func not in \ instance._mixin_after_parsed_funcs: instance._mixin_after_parsed_funcs.append(func) #这个列表如果是启动的话在这是空列表,不过会在OptionParser的parse_args方法里面实现添加 # Mark process_<opt> functions with the base priority for sorting for func in dir(base): if not func.startswith('process_'): continue func = getattr(base, func) if getattr(func, '_mixin_prio_', None) is not None: # Function already has the attribute set, don't override it continue func.__func__._mixin_prio_ = getattr( base, '_mixin_prio_', 1000 ) #这个for循环把所有没_mixin_prio属性的基类 设置属性值1000 return instance #返回实例
接下来就是调用OptionParser的__init__()方法来初始化了
接着调用的OptionParser的parse_args方法
def parse_args(self, args=None, values=None): options, args = optparse.OptionParser.parse_args(self, args, values) #上面这句options的值是{'daemon': False, 'log_level': None, 'versions_report': None, 'user': None, 'log_file': None, 'config_dir': '/etc/salt', 'pidfile': '/var/run/salt.pid', 'log_level_logfile': None} #惭愧 到现在都还没找到这些值是怎么来的,找了好久都没找到,后来干脆就不找了,现往下看完再说,别吊死在这 if options.versions_report: self.print_versions_report() self.options, self.args = options, args # Let's get some proper sys.stderr logging as soon as possible!!! # This logging handler will be removed once the proper console or # logfile logging is setup. log.setup_temp_logger( getattr(self.options, 'log_level', 'error') ) # Gather and run the process_<option> functions in the proper order process_option_funcs = [] for option_key in options.__dict__.keys(): process_option_func = getattr( self, 'process_{0}'.format(option_key), None ) if process_option_func is not None: process_option_funcs.append(process_option_func) #下面分别执行这3个方法process_config_dir process_log_level process_log_file for process_option_func in _sorted(process_option_funcs): try: process_option_func() except Exception as err: logging.getLogger(__name__).exception(err) self.error( 'Error while processing {0}: {1}'.format( process_option_func, traceback.format_exc(err) ) ) #首先看一下ConfigDirMixIn.process_config_dir 方法 def process_config_dir(self): if not os.path.isdir(self.options.config_dir): # No logging is configured yet sys.stderr.write( 'WARNING: {0!r} directory does not exist.\n'.format( self.options.config_dir ) ) # Make sure we have an absolute path self.options.config_dir = os.path.abspath(self.options.config_dir) if hasattr(self, 'setup_config'): try: self.config = self.setup_config() #这里调用子类的MasterOptionParser.setup_config 方法,其方法原型如下: #def setup_config(self): # return config.master_config(self.get_config_file_path()) except (IOError, OSError) as exc: self.error( 'Failed to load configuration: {0}'.format(exc) )
那个get_config_file_path()返回配置文件的绝对路径然后作为参数传至config.py里面的master_config()方法
草!又调到config.py了,4个编辑器完全不够我用的...妈的继续往下去看