1. /usr/bin/salt-minion
    1. from salt.scripts import salt_minion
    2. salt_minion()
      1. while true:
      2. queue = multiprocessing.Queue()
      3. process = multiprocessing.Process(target=minion_process, args=(queue,))
      4. process.start()
        1. os.fork()
        2. minion_process(queue)
          1. minion = salt.cli.daemons.Minion()
          2. # 继承 parsers.MinionOptionParser
          3. # 继承 MasterOptionParser
          4. # 重写setup_config函数,解析minion配置文件 def setup_config(self): return config.minion_config(self.get_config_file_path(), cache_minion_id=True)
          5. MinionOptionParser与MasterOptionParser几乎一样, 都是解析命令行参数和解析YAML配置文件,唯一区别只是配置文件不同, 具体的讲解可以参考salt-master启动过程.
          6. minion.start()
          7. self.prepare()
          8. # 解析命令行参数及minion配置文件 self.parse_args()
          9. # 是否以守护进程运行 self.daemonize_if_required()
          10. self.minion = salt.minion.Minion(self.config)
          11. # 继承 MinionBase
          12. def __init__(self, opts, timeout=60,       safe=True, loaded_base_name=None):
          13. # 加载grains模块 opts['grains'] = salt.loader.grains(opts)
          14. # 评估master连接及认证 opts['master'] = self.eval_master(opts, timeout, safe)
          15.  # 加载pillar self.opts['pillar'] = salt.pillar.get_pillar( opts, opts['grains'], opts['id'], opts['environment'] ).compile_pillar()
          16. self.minion.tune_in()
          17. # 绑定zmq pub pull事件系统 self._prepare_minion_event_system()
          18. self._init_context_and_poller()
          19. self.context = zmq.Context() self.poller = zmq.Poller()
          20. self.epub_sock = self.context.socket(zmq.PUB)
          21. self.epull_sock = self.context.socket(zmq.PULL)
          22. self.epub_sock.bind(epub_uri)
          23. self.epull_sock.bind(epull_uri)
          24. self.socket = self.context.socket(zmq.SUB)
          25. self._set_reconnect_ivl()
          26. self.socket.setsockopt(zmq.RECONNECT_IVL, recon_delay)
          27. # 设置订阅主题 self._setsockopts()
          28. self._set_monitor_socket()
          29. self.monitor_socket = self.socket.get_monitor_socket()
          30. t = threading.Thread(target=self._socket_monitor, args=(self.monitor_socket,))
          31. t.start()
          32. # 连接master pub消息服务器 self.socket.connect(self.master_pub)
          33. self.poller.register(self.socket, zmq.POLLIN) self.poller.register(self.epull_sock, zmq.POLLIN)
          34. # 连接master的ReqServer,默认端口为4506,通知minion已启动 self._fire_master_minion_start()
          35. self._state_run()
          36. while self._running is True:
          37. loop_interval = self.process_schedule(self, loop_interval)
          38. socks = self._do_poll(loop_interval)
          39. # 接收来自master的pub 消息,并执行_handle_payload self._do_socket_recv(socks)
          40. messages = self.socket.recv_multipart(zmq.NOBLOCK) payload = self.serial.loads(messages[1])
          41. self._handle_payload(payload)
          42. # 接收来自本地的push event,执行hand_event, # 并publish给本地 self._do_event_poll(socks)
          43. package = self.epull_sock.recv(zmq.NOBLOCK)
          44. self.handle_event(package)
          45. self.epub_sock.send(package)
          46. # 执行beacons系统 self._process_beacons()
          47. # 如果出现异常 queue.put(random_delay)
      5. process.join()
      6. # 到这步就表示子进程退出了, # 如果restart_delay为0,表示子进程为正常退出,不需要重启 restart_delay = queue.get(block=False)
      7. # 等待几秒钟重新启动 time.sleep(restart_delay)