Class masteroptionparser (optionparser, configdirmixin, mergeconfigmixin, loglevelmixin, runusermixin, daemonmixin, pidfilemixin): # These are almost all classes initialized by salt, some minion will also call _ metaclass _ = optionparsermeta # specify its Meta class description = 'the salt master, used to control the salt minions. '# configdirmixin config filename attribute _ config_filename _ = 'master' # default configuration file name # loglevelmixin attributes _ default_logging_logfile _ = OS. path. join (syspaths. logs_dir, 'master') # The Path to the log file/var/log/salt/Master def setup_config (Self): Return config. master_config (self. get_config_file_path ())
The next step is to find his Meta class.
The Python class is initialized in two stages. The first stage is space allocation _ new _ (), and the second stage is the initialization value _ init __(). When a class is created, Python first looks for whether _ metaclass _ exists,
If yes, call _ metaclass __. If this class does not define _ metaclass _, you can view the parent class. If the parent class does not exist, you can find it in the module (global variable _ metaclass __),
In the module, _ metaclass _ = type is used as the metaclass of the class.
MCS indicates the class that calls the _ new _ function. name indicates the _ name _ value of the object, that is, the name. Bases indicates the parent class tuples of the object, attrs indicates the attribute Dictionary of the class.
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) # The mininmeta of the parent class is called above. _ new _ method 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 = [] # This statement creates three empty lists for base in _ sorted (bases + (instance ,)): # Sort the base classes and subclasses. func = getattr (base, '_ mixin_setup', none) # obtain the attribute methods of all classes _ mixin_setup, if none, the value is set to none if func is not none and func not in instance. _ mixin_setup_funcs: instance. _ mixin_setup_funcs.append (func) # list obtained after the for loop _ mixin_setup_funcs [configdirmixin. _ mixin_setup, # loglevelmixin. _ mixin_setup, # runusermixin. _ mixin_setup, # daemonmixin_mixin_setup, # pidfilemixin. _ mixin_setup, #] # These class methods are used to initialize the Options command func = getattr (base, '_ mixin_after_parsed', none) of the salt. # obtain the attribute methods of all class _ mixin_after_parsed, if none, the value is set to none if func is not none and func not in instance. _ mixin_after_parsed_funcs: instance. _ mixin_after_parsed_funcs.append (func) # This list is empty if it is started, however, the # MARK process _ <opt> functions with the base priority for sorting for func in Dir (base): If not func will be added in the parse_args method of optionparser. 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) # This For Loop sets the attribute value 1000 return instance for all base classes without the _ mixin_prio attribute # returns the instance
The next step is to call the _ init _ () method of optionparser to initialize
Next, call the parse_args method of optionparser.
Def parse_args (self, argS = none, values = none): Options, argS = optparse. optionparser. parse_args (self, argS, values) # The options value above is {'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} # Why haven't these values been found yet? I haven't found them for a long time, and I just stopped searching, now let's look at it later. Don't stick it here if options. versions_report: Self. print_v Ersions_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: Warn (warn) # execute the three methods process_config_dir process_log_level process_log_file for processing in _ sorted (process_option_funcs): Try: retry () failed t exception as ERR: logging. getlogger (_ name __). exception (ERR) self. error ('error while processing {0 }:{ 1 }'. format (process_option_func, traceback. format_exc (ERR) # first take a look at configdir Mixin. process_config_dir method 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 () # The masteroptionparser of the subclass is called here. the setup_config method is prototype: # def setup_config (Self): # Return config. master_config (self. get_config_file_path () handle T (ioerror, oserror) as exc: Self. error ('failed to load configuration: {0 }'. format (EXC ))
The get_config_file_path () method returns the absolute path of the configuration file and transmits it as a parameter to the master_config () method in config. py.
Grass! I adjusted it to config. py again, and the four editors are not enough for me to use... let's continue to look down.
Saltstack source code-start 2-parsers.py option initialization 1