def start(self): ''' Turn on broker components ''' log.info('salt-broker is starting as user {0!r}'.format( salt.utils.get_user())) enable_sigusr1_handler() log.info('starting pub broker......') pub_broker = PubBroker(self.opts) pub_broker.start() log.info('starting ret broker......') ret_broker = RetBroker(self.opts) ret_broker.start() def sigterm_clean(signum, frame): ''' Clean broker processes when a SIGTERM is encountered. From: https://github.com/saltstack/salt/blob/v2014.1.13/salt/master.py#L470 ''' log.warn('Caught signal {0}, stopping salt-broker'.format(signum)) clean_proc(pub_broker) clean_proc(ret_broker) signal.signal(signal.SIGTERM, sigterm_clean)
def start(self): ''' Turn on broker components ''' log.info( 'salt-broker is starting as user {0!r}'.format( salt.utils.get_user()) ) enable_sigusr1_handler() log.info('starting pub broker......') pub_broker = PubBroker(self.opts) pub_broker.start() log.info('starting ret broker......') ret_broker = RetBroker(self.opts) ret_broker.start() def sigterm_clean(signum, frame): ''' Clean broker processes when a SIGTERM is encountered. From: https://github.com/saltstack/salt/blob/v2014.1.13/salt/master.py#L470 ''' log.warn('Caught signal {0}, stopping salt-broker'.format(signum)) clean_proc(pub_broker) clean_proc(ret_broker) signal.signal(signal.SIGTERM, sigterm_clean)
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' context = zmq.Context() poller = zmq.Poller() socket = context.socket(zmq.SUB) socket.setsockopt(zmq.SUBSCRIBE, '') if self.opts['sub_timeout']: socket.setsockopt(zmq.IDENTITY, self.opts['id']) socket.connect(self.master_pub) poller.register(socket, zmq.POLLIN) # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() if self.opts['sub_timeout']: last = time.time() while True: socks = dict(poller.poll(self.opts['sub_timeout'])) if socket in socks and socks[socket] == zmq.POLLIN: payload = self.serial.loads(socket.recv()) self._handle_payload(payload) last = time.time() if time.time() - last > self.opts['sub_timeout']: # It has been a while since the last command, make sure # the connection is fresh by reconnecting if self.opts['dns_check']: try: # Verify that the dns entry has not changed self.opts['master_ip'] = salt.utils.dns_check( self.opts['master'], safe=True) except SaltClientError: # Failed to update the dns, keep the old addr pass poller.unregister(socket) socket.close() socket = context.socket(zmq.SUB) socket.setsockopt(zmq.SUBSCRIBE, '') socket.setsockopt(zmq.IDENTITY, self.opts['id']) socket.connect(self.master_pub) poller.register(socket, zmq.POLLIN) last = time.time() time.sleep(0.05) multiprocessing.active_children() self.passive_refresh() else: while True: socks = dict(poller.poll(60)) if socket in socks and socks[socket] == zmq.POLLIN: payload = self.serial.loads(socket.recv()) self._handle_payload(payload) last = time.time() time.sleep(0.05) multiprocessing.active_children() self.passive_refresh()
def start(self): ''' Turn on the master server components ''' log.info( 'salt-master is starting as user \'{0}\''.format(getpass.getuser()) ) enable_sigusr1_handler() self.__set_max_open_files() clear_old_jobs_proc = multiprocessing.Process( target=self._clear_old_jobs) clear_old_jobs_proc.start() reqserv = ReqServer( self.opts, self.crypticle, self.key, self.master_key) reqserv.start_publisher() reqserv.start_event_publisher() def sigterm_clean(signum, frame): ''' Cleaner method for stopping multiprocessing processes when a SIGTERM is encountered. This is required when running a salt master under a process minder like daemontools ''' log.warn(('Caught signal {0}, stopping the Salt Master' .format(signum))) clean_proc(clear_old_jobs_proc) clean_proc(reqserv.publisher) clean_proc(reqserv.eventpublisher) for proc in reqserv.work_procs: clean_proc(proc) if os.path.isfile(self.opts['pidfile']): try: os.remove(self.opts['pidfile']) except (IOError, OSError): log.warn('Failed to remove master pidfile: {0}'.format( self.opts['pidfile'] )) raise MasterExit signal.signal(signal.SIGTERM, sigterm_clean) try: reqserv.run() except KeyboardInterrupt: # Shut the master down gracefully on SIGINT log.warn('Stopping the Salt Master') raise SystemExit('\nExiting on Ctrl-c')
def start(self): ''' Turn on the master server components ''' log.info('salt-master is starting as user \'{0}\''.format( getpass.getuser())) enable_sigusr1_handler() self.__set_max_open_files() clear_old_jobs_proc = multiprocessing.Process( target=self._clear_old_jobs) clear_old_jobs_proc.start() reqserv = ReqServer(self.opts, self.crypticle, self.key, self.master_key) reqserv.start_publisher() reqserv.start_event_publisher() def sigterm_clean(signum, frame): ''' Cleaner method for stopping multiprocessing processes when a SIGTERM is encountered. This is required when running a salt master under a process minder like daemontools ''' log.warn( ('Caught signal {0}, stopping the Salt Master'.format(signum))) clean_proc(clear_old_jobs_proc) clean_proc(reqserv.publisher) clean_proc(reqserv.eventpublisher) for proc in reqserv.work_procs: clean_proc(proc) if os.path.isfile(self.opts['pidfile']): try: os.remove(self.opts['pidfile']) except (IOError, OSError): log.warn('Failed to remove master pidfile: {0}'.format( self.opts['pidfile'])) raise MasterExit signal.signal(signal.SIGTERM, sigterm_clean) try: reqserv.run() except KeyboardInterrupt: # Shut the master down gracefully on SIGINT log.warn('Stopping the Salt Master') raise SystemExit('\nExiting on Ctrl-c')
def start(self): ''' Turn on the master server components ''' enable_sigusr1_handler() log.warn('Starting the Salt Master') clear_old_jobs_proc = multiprocessing.Process( target=self._clear_old_jobs) clear_old_jobs_proc.start() reqserv = ReqServer( self.opts, self.crypticle, self.key, self.master_key) reqserv.start_publisher() reqserv.start_event_publisher() def sigterm_clean(signum, frame): ''' Cleaner method for stopping multiprocessing processes when a SIGTERM is encountered. This is required when running a salt master under a process minder like daemontools ''' mypid = os.getpid() log.warn(('Caught signal {0}, stopping the Salt Master' .format(signum))) clean_proc(clear_old_jobs_proc) clean_proc(reqserv.publisher) clean_proc(reqserv.eventpublisher) for proc in reqserv.work_procs: clean_proc(proc) raise MasterExit signal.signal(signal.SIGTERM, sigterm_clean) try: reqserv.run() except KeyboardInterrupt: # Shut the master down gracefully on SIGINT log.warn('Stopping the Salt Master') raise SystemExit('\nExiting on Ctrl-c')
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' log.info( '{0} is starting as user \'{1}\''.format( self.__class__.__name__, getpass.getuser() ) ) log.debug('Minion "{0}" trying to tune in'.format(self.opts['id'])) self.context = zmq.Context() # Prepare the minion event system # # Start with the publish socket id_hash = hashlib.md5(self.opts['id']).hexdigest() epub_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pub.ipc'.format(id_hash) ) epull_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pull.ipc'.format(id_hash) ) self.epub_sock = self.context.socket(zmq.PUB) if self.opts.get('ipc_mode', '') == 'tcp': epub_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pub_port'] ) epull_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pull_port'] ) else: epub_uri = 'ipc://{0}'.format(epub_sock_path) epull_uri = 'ipc://{0}'.format(epull_sock_path) for uri in (epub_uri, epull_uri): if uri.startswith('tcp://'): # This check only applies to IPC sockets continue # The socket path is limited to 107 characters on Solaris and # Linux, and 103 characters on BSD-based systems. # Let's fail at the lower level so no system checks are # required. if len(uri) > 103: raise SaltSystemExit( 'The socket path length is more that what ZMQ allows. ' 'The length of {0!r} is more than 103 characters. ' 'Either try to reduce the length of this setting\'s ' 'path or switch to TCP; In the configuration file set ' '"ipc_mode: tcp"'.format( uri ) ) log.debug( '{0} PUB socket URI: {1}'.format( self.__class__.__name__, epub_uri ) ) log.debug( '{0} PULL socket URI: {1}'.format( self.__class__.__name__, epull_uri ) ) # Create the pull socket self.epull_sock = self.context.socket(zmq.PULL) # Bind the event sockets self.epub_sock.bind(epub_uri) self.epull_sock.bind(epull_uri) # Restrict access to the sockets if not self.opts.get('ipc_mode', '') == 'tcp': os.chmod( epub_sock_path, 448 ) os.chmod( epull_sock_path, 448 ) self.poller = zmq.Poller() self.epoller = zmq.Poller() self.socket = self.context.socket(zmq.SUB) self.socket.setsockopt(zmq.SUBSCRIBE, '') self.socket.setsockopt(zmq.IDENTITY, self.opts['id']) if hasattr(zmq, 'RECONNECT_IVL_MAX'): self.socket.setsockopt( zmq.RECONNECT_IVL_MAX, self.opts['recon_max'] ) if hasattr(zmq, 'TCP_KEEPALIVE'): self.socket.setsockopt( zmq.TCP_KEEPALIVE, self.opts['tcp_keepalive'] ) self.socket.setsockopt( zmq.TCP_KEEPALIVE_IDLE, self.opts['tcp_keepalive_idle'] ) self.socket.setsockopt( zmq.TCP_KEEPALIVE_CNT, self.opts['tcp_keepalive_cnt'] ) self.socket.setsockopt( zmq.TCP_KEEPALIVE_INTVL, self.opts['tcp_keepalive_intvl'] ) self.socket.connect(self.master_pub) self.poller.register(self.socket, zmq.POLLIN) self.epoller.register(self.epull_sock, zmq.POLLIN) # Send an event to the master that the minion is live self._fire_master( 'Minion {0} started at {1}'.format( self.opts['id'], time.asctime() ), 'minion_start' ) # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() # On first startup execute a state run if configured to do so self._state_run() while True: try: socks = dict(self.poller.poll(60000)) if self.socket in socks and socks[self.socket] == zmq.POLLIN: payload = self.serial.loads(self.socket.recv()) self._handle_payload(payload) time.sleep(0.05) # This next call(multiprocessing.active_children()) is # intentional, from docs, "Calling this has the side affect of # “joining” any processes which have already finished." multiprocessing.active_children() self.passive_refresh() self.cleanup_processes() # Check the event system if self.epoller.poll(1): try: package = self.epull_sock.recv(zmq.NOBLOCK) self.epub_sock.send(package) except Exception: pass except Exception: log.critical(traceback.format_exc())
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' log.info( '{0} is starting as user \'{1}\''.format( self.__class__.__name__, getpass.getuser() ) ) log.debug('Minion "{0}" trying to tune in'.format(self.opts['id'])) context = zmq.Context() # Prepare the minion event system # # Start with the publish socket id_hash = hashlib.md5(self.opts['id']).hexdigest() epub_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pub.ipc'.format(id_hash) ) epull_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pull.ipc'.format(id_hash) ) epub_sock = context.socket(zmq.PUB) if self.opts.get('ipc_mode', '') == 'tcp': epub_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pub_port'] ) epull_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pull_port'] ) else: epub_uri = 'ipc://{0}'.format(epub_sock_path) epull_uri = 'ipc://{0}'.format(epull_sock_path) log.debug( '{0} PUB socket URI: {1}'.format( self.__class__.__name__, epub_uri ) ) log.debug( '{0} PULL socket URI: {1}'.format( self.__class__.__name__, epull_uri ) ) # Create the pull socket epull_sock = context.socket(zmq.PULL) # Bind the event sockets epub_sock.bind(epub_uri) epull_sock.bind(epull_uri) # Restrict access to the sockets if not self.opts.get('ipc_mode', '') == 'tcp': os.chmod( epub_sock_path, 448 ) os.chmod( epull_sock_path, 448 ) poller = zmq.Poller() epoller = zmq.Poller() socket = context.socket(zmq.SUB) socket.setsockopt(zmq.SUBSCRIBE, '') if self.opts['sub_timeout']: socket.setsockopt(zmq.IDENTITY, self.opts['id']) socket.connect(self.master_pub) poller.register(socket, zmq.POLLIN) epoller.register(epull_sock, zmq.POLLIN) # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() # On first startup execute a state run if configured to do so self._state_run() if self.opts['sub_timeout']: last = time.time() while True: try: socks = dict(poller.poll(self.opts['sub_timeout'] * 1000)) if socket in socks and socks[socket] == zmq.POLLIN: self.passive_refresh() payload = self.serial.loads(socket.recv()) self._handle_payload(payload) last = time.time() if time.time() - last > self.opts['sub_timeout']: # It has been a while since the last command, make sure # the connection is fresh by reconnecting if self.opts['dns_check']: try: # Verify that the dns entry has not changed self.opts['master_ip'] = salt.utils.dns_check( self.opts['master'], safe=True) except SaltClientError: # Failed to update the dns, keep the old addr pass poller.unregister(socket) socket.close() socket = context.socket(zmq.SUB) socket.setsockopt(zmq.SUBSCRIBE, '') socket.setsockopt(zmq.IDENTITY, self.opts['id']) socket.connect(self.master_pub) poller.register(socket, zmq.POLLIN) last = time.time() time.sleep(0.05) multiprocessing.active_children() # Check the event system if epoller.poll(1): try: package = epull_sock.recv(zmq.NOBLOCK) epub_sock.send(package) except Exception: pass except Exception: log.critical(traceback.format_exc()) else: while True: try: socks = dict(poller.poll(60000)) if socket in socks and socks[socket] == zmq.POLLIN: payload = self.serial.loads(socket.recv()) self._handle_payload(payload) last = time.time() time.sleep(0.05) multiprocessing.active_children() self.passive_refresh() # Check the event system if epoller.poll(1): try: package = epull_sock.recv(zmq.NOBLOCK) epub_sock.send(package) except Exception: pass except Exception: log.critical(traceback.format_exc())
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' log.debug('Minion "{0}" trying to tune in'.format(self.opts['id'])) context = zmq.Context() # Prepare the minion event system # # Start with the publish socket epub_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pub.ipc'.format(self.opts['id'])) epull_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pull.ipc'.format(self.opts['id'])) epub_sock = context.socket(zmq.PUB) if self.opts.get('ipc_mode', '') == 'tcp': epub_uri = 'tcp://127.0.0.1:{0}'.format(self.opts['tcp_pub_port']) epull_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pull_port']) else: epub_uri = 'ipc://{0}'.format(epub_sock_path) epull_uri = 'ipc://{0}'.format(epull_sock_path) log.debug('{0} PUB socket URI: {1}'.format(self.__class__.__name__, epub_uri)) log.debug('{0} PULL socket URI: {1}'.format(self.__class__.__name__, epull_uri)) # Create the pull socket epull_sock = context.socket(zmq.PULL) # Bind the event sockets epub_sock.bind(epub_uri) epull_sock.bind(epull_uri) # Restrict access to the sockets if not self.opts.get('ipc_mode', '') == 'tcp': os.chmod(epub_sock_path, 448) os.chmod(epull_sock_path, 448) poller = zmq.Poller() epoller = zmq.Poller() socket = context.socket(zmq.SUB) socket.setsockopt(zmq.SUBSCRIBE, '') if self.opts['sub_timeout']: socket.setsockopt(zmq.IDENTITY, self.opts['id']) socket.connect(self.master_pub) poller.register(socket, zmq.POLLIN) epoller.register(epull_sock, zmq.POLLIN) # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() if self.opts['sub_timeout']: last = time.time() while True: try: socks = dict(poller.poll(self.opts['sub_timeout'])) if socket in socks and socks[socket] == zmq.POLLIN: payload = self.serial.loads(socket.recv()) self._handle_payload(payload) last = time.time() if time.time() - last > self.opts['sub_timeout']: # It has been a while since the last command, make sure # the connection is fresh by reconnecting if self.opts['dns_check']: try: # Verify that the dns entry has not changed self.opts['master_ip'] = salt.utils.dns_check( self.opts['master'], safe=True) except SaltClientError: # Failed to update the dns, keep the old addr pass poller.unregister(socket) socket.close() socket = context.socket(zmq.SUB) socket.setsockopt(zmq.SUBSCRIBE, '') socket.setsockopt(zmq.IDENTITY, self.opts['id']) socket.connect(self.master_pub) poller.register(socket, zmq.POLLIN) last = time.time() time.sleep(0.05) multiprocessing.active_children() self.passive_refresh() # Check the event system if epoller.poll(1): try: package = epull_sock.recv(zmq.NOBLOCK) epub_sock.send(package) except Exception: pass except Exception as exc: log.critical(traceback.format_exc()) else: while True: try: socks = dict(poller.poll(60)) if socket in socks and socks[socket] == zmq.POLLIN: payload = self.serial.loads(socket.recv()) self._handle_payload(payload) last = time.time() time.sleep(0.05) multiprocessing.active_children() self.passive_refresh() # Check the event system if epoller.poll(1): try: package = epull_sock.recv(zmq.NOBLOCK) epub_sock.send(package) except Exception: pass except Exception: log.critical(traceback.format_exc())
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' log.info( '{0} is starting as user \'{1}\''.format( self.__class__.__name__, getpass.getuser() ) ) log.debug('Minion "{0}" trying to tune in'.format(self.opts['id'])) self.context = zmq.Context() # Prepare the minion event system # # Start with the publish socket id_hash = hashlib.md5(self.opts['id']).hexdigest() epub_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pub.ipc'.format(id_hash) ) epull_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pull.ipc'.format(id_hash) ) self.epub_sock = self.context.socket(zmq.PUB) if self.opts.get('ipc_mode', '') == 'tcp': epub_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pub_port'] ) epull_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pull_port'] ) else: epub_uri = 'ipc://{0}'.format(epub_sock_path) epull_uri = 'ipc://{0}'.format(epull_sock_path) log.debug( '{0} PUB socket URI: {1}'.format( self.__class__.__name__, epub_uri ) ) log.debug( '{0} PULL socket URI: {1}'.format( self.__class__.__name__, epull_uri ) ) # Create the pull socket self.epull_sock = self.context.socket(zmq.PULL) # Bind the event sockets self.epub_sock.bind(epub_uri) self.epull_sock.bind(epull_uri) # Restrict access to the sockets if not self.opts.get('ipc_mode', '') == 'tcp': os.chmod( epub_sock_path, 448 ) os.chmod( epull_sock_path, 448 ) self.poller = zmq.Poller() self.epoller = zmq.Poller() self.socket = self.context.socket(zmq.SUB) self.socket.setsockopt(zmq.SUBSCRIBE, '') self.socket.setsockopt(zmq.IDENTITY, self.opts['id']) if hasattr(zmq, 'RECONNECT_IVL_MAX'): self.socket.setsockopt( zmq.RECONNECT_IVL_MAX, self.opts['recon_max'] ) self.socket.connect(self.master_pub) self.poller.register(self.socket, zmq.POLLIN) self.epoller.register(self.epull_sock, zmq.POLLIN) # Send an event to the master that the minion is live self._fire_master( 'Minion {0} started at {1}'.format( self.opts['id'], time.asctime() ), 'minion_start' ) # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() # On first startup execute a state run if configured to do so self._state_run() while True: try: socks = dict(self.poller.poll(60000)) if self.socket in socks and socks[self.socket] == zmq.POLLIN: payload = self.serial.loads(self.socket.recv()) self._handle_payload(payload) time.sleep(0.05) # This next call(multiprocessing.active_children()) is # intentional, from docs, "Calling this has the side affect of # “joining” any processes which have already finished." multiprocessing.active_children() self.passive_refresh() self.cleanup_processes() # Check the event system if self.epoller.poll(1): try: package = self.epull_sock.recv(zmq.NOBLOCK) self.epub_sock.send(package) except Exception: pass except Exception: log.critical(traceback.format_exc())
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' log.info('{0} is starting as user \'{1}\''.format( self.__class__.__name__, getpass.getuser())) log.debug('Minion "{0}" trying to tune in'.format(self.opts['id'])) self.context = zmq.Context() # Prepare the minion event system # # Start with the publish socket id_hash = hashlib.md5(self.opts['id']).hexdigest() epub_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pub.ipc'.format(id_hash)) epull_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pull.ipc'.format(id_hash)) self.epub_sock = self.context.socket(zmq.PUB) if self.opts.get('ipc_mode', '') == 'tcp': epub_uri = 'tcp://127.0.0.1:{0}'.format(self.opts['tcp_pub_port']) epull_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pull_port']) else: epub_uri = 'ipc://{0}'.format(epub_sock_path) salt.utils.check_ipc_path_max_len(epub_uri) epull_uri = 'ipc://{0}'.format(epull_sock_path) salt.utils.check_ipc_path_max_len(epull_uri) log.debug('{0} PUB socket URI: {1}'.format(self.__class__.__name__, epub_uri)) log.debug('{0} PULL socket URI: {1}'.format(self.__class__.__name__, epull_uri)) # Create the pull socket self.epull_sock = self.context.socket(zmq.PULL) # Bind the event sockets self.epub_sock.bind(epub_uri) self.epull_sock.bind(epull_uri) # Restrict access to the sockets if not self.opts.get('ipc_mode', '') == 'tcp': os.chmod(epub_sock_path, 448) os.chmod(epull_sock_path, 448) self.poller = zmq.Poller() self.epoller = zmq.Poller() self.socket = self.context.socket(zmq.SUB) self.socket.setsockopt(zmq.SUBSCRIBE, '') self.socket.setsockopt(zmq.IDENTITY, self.opts['id']) if hasattr(zmq, 'RECONNECT_IVL_MAX'): self.socket.setsockopt(zmq.RECONNECT_IVL_MAX, self.opts['recon_max']) if hasattr(zmq, 'TCP_KEEPALIVE'): self.socket.setsockopt(zmq.TCP_KEEPALIVE, self.opts['tcp_keepalive']) self.socket.setsockopt(zmq.TCP_KEEPALIVE_IDLE, self.opts['tcp_keepalive_idle']) self.socket.setsockopt(zmq.TCP_KEEPALIVE_CNT, self.opts['tcp_keepalive_cnt']) self.socket.setsockopt(zmq.TCP_KEEPALIVE_INTVL, self.opts['tcp_keepalive_intvl']) if hasattr(zmq, 'IPV4ONLY'): self.socket.setsockopt( zmq.IPV4ONLY, int(not int(self.opts.get('ipv6_enable', False)))) self.socket.connect(self.master_pub) self.poller.register(self.socket, zmq.POLLIN) self.epoller.register(self.epull_sock, zmq.POLLIN) # Send an event to the master that the minion is live self._fire_master( 'Minion {0} started at {1}'.format(self.opts['id'], time.asctime()), 'minion_start') if self.opts['multiprocessing'] and not salt.utils.is_windows(): signal.signal(signal.SIGCHLD, self.handle_sigchld) # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() # On first startup execute a state run if configured to do so self._state_run() while True: try: self.schedule.eval() socks = dict( self.poller.poll(self.opts['loop_interval'] * 1000)) if self.socket in socks and socks[self.socket] == zmq.POLLIN: payload = self.serial.loads(self.socket.recv()) self._handle_payload(payload) time.sleep(0.05) # Clean up the minion processes which have been executed and # have finished # Check if modules and grains need to be refreshed self.passive_refresh() # Check the event system if self.epoller.poll(1): try: package = self.epull_sock.recv(zmq.NOBLOCK) self.epub_sock.send(package) except Exception: pass except zmq.ZMQError: # This is thrown by the inturupt caused by python handling the # SIGCHLD. This is a safe error and we just start the poll # again continue except Exception: log.critical(traceback.format_exc())
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' log.info('{0} is starting as user \'{1}\''.format( self.__class__.__name__, getpass.getuser())) log.debug('Minion "{0}" trying to tune in'.format(self.opts['id'])) self.context = zmq.Context() # Prepare the minion event system # # Start with the publish socket id_hash = hashlib.md5(self.opts['id']).hexdigest() epub_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pub.ipc'.format(id_hash)) epull_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pull.ipc'.format(id_hash)) self.epub_sock = self.context.socket(zmq.PUB) if self.opts.get('ipc_mode', '') == 'tcp': epub_uri = 'tcp://127.0.0.1:{0}'.format(self.opts['tcp_pub_port']) epull_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pull_port']) else: epub_uri = 'ipc://{0}'.format(epub_sock_path) epull_uri = 'ipc://{0}'.format(epull_sock_path) log.debug('{0} PUB socket URI: {1}'.format(self.__class__.__name__, epub_uri)) log.debug('{0} PULL socket URI: {1}'.format(self.__class__.__name__, epull_uri)) # Create the pull socket self.epull_sock = self.context.socket(zmq.PULL) # Bind the event sockets self.epub_sock.bind(epub_uri) self.epull_sock.bind(epull_uri) # Restrict access to the sockets if not self.opts.get('ipc_mode', '') == 'tcp': os.chmod(epub_sock_path, 448) os.chmod(epull_sock_path, 448) self.poller = zmq.Poller() self.epoller = zmq.Poller() self.socket = self.context.socket(zmq.SUB) self.socket.setsockopt(zmq.SUBSCRIBE, '') self.socket.setsockopt(zmq.IDENTITY, self.opts['id']) if hasattr(zmq, 'RECONNECT_IVL_MAX'): self.socket.setsockopt(zmq.RECONNECT_IVL_MAX, self.opts['recon_max']) self.socket.connect(self.master_pub) self.poller.register(self.socket, zmq.POLLIN) self.epoller.register(self.epull_sock, zmq.POLLIN) # Send an event to the master that the minion is live self._fire_master( 'Minion {0} started at {1}'.format(self.opts['id'], time.asctime()), 'minion_start') # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() # On first startup execute a state run if configured to do so self._state_run() while True: try: socks = dict(self.poller.poll(60000)) if self.socket in socks and socks[self.socket] == zmq.POLLIN: payload = self.serial.loads(self.socket.recv()) self._handle_payload(payload) time.sleep(0.05) # This next call(multiprocessing.active_children()) is # intentional, from docs, "Calling this has the side affect of # “joining” any processes which have already finished." multiprocessing.active_children() self.passive_refresh() self.cleanup_processes() # Check the event system if self.epoller.poll(1): try: package = self.epull_sock.recv(zmq.NOBLOCK) self.epub_sock.send(package) except Exception: pass except Exception: log.critical(traceback.format_exc())
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' context = zmq.Context() # Prepare the minion event system # # Start with the publish socket epub_sock = context.socket(zmq.PUB) epub_uri = 'ipc://{0}'.format( os.path.join(self.opts['sock_dir'], 'minion_event_pub.ipc') ) # Create the pull socket epull_sock = context.socket(zmq.PULL) epull_uri = 'ipc://{0}'.format( os.path.join(self.opts['sock_dir'], 'minion_event_pull.ipc') ) # Bind the event sockets epub_sock.bind(epub_uri) epull_sock.bind(epull_uri) # Restrict access to the sockets os.chmod( os.path.join(self.opts['sock_dir'], 'minion_event_pub.ipc'), 448 ) os.chmod( os.path.join(self.opts['sock_dir'], 'minion_event_pull.ipc'), 448 ) poller = zmq.Poller() epoller = zmq.Poller() socket = context.socket(zmq.SUB) socket.setsockopt(zmq.SUBSCRIBE, '') if self.opts['sub_timeout']: socket.setsockopt(zmq.IDENTITY, self.opts['id']) socket.connect(self.master_pub) poller.register(socket, zmq.POLLIN) epoller.register(epull_sock, zmq.POLLIN) # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() if self.opts['sub_timeout']: last = time.time() while True: try: socks = dict(poller.poll(self.opts['sub_timeout'])) if socket in socks and socks[socket] == zmq.POLLIN: payload = self.serial.loads(socket.recv()) self._handle_payload(payload) last = time.time() if time.time() - last > self.opts['sub_timeout']: # It has been a while since the last command, make sure # the connection is fresh by reconnecting if self.opts['dns_check']: try: # Verify that the dns entry has not changed self.opts['master_ip'] = salt.utils.dns_check( self.opts['master'], safe=True) except SaltClientError: # Failed to update the dns, keep the old addr pass poller.unregister(socket) socket.close() socket = context.socket(zmq.SUB) socket.setsockopt(zmq.SUBSCRIBE, '') socket.setsockopt(zmq.IDENTITY, self.opts['id']) socket.connect(self.master_pub) poller.register(socket, zmq.POLLIN) last = time.time() time.sleep(0.05) multiprocessing.active_children() self.passive_refresh() # Check the event system if epoller.poll(1): try: package = epull_sock.recv(zmq.NOBLOCK) epub_sock.send(package) except Exception: pass except Exception as exc: log.critical(traceback.format_exc()) else: while True: try: socks = dict(poller.poll(60)) if socket in socks and socks[socket] == zmq.POLLIN: payload = self.serial.loads(socket.recv()) self._handle_payload(payload) last = time.time() time.sleep(0.05) multiprocessing.active_children() self.passive_refresh() # Check the event system if epoller.poll(1): try: package = epull_sock.recv(zmq.NOBLOCK) epub_sock.send(package) except Exception: pass except Exception as exc: log.critical(traceback.format_exc())
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' log.info( '{0} is starting as user \'{1}\''.format( self.__class__.__name__, getpass.getuser() ) ) log.debug('Minion "{0}" trying to tune in'.format(self.opts['id'])) self.context = zmq.Context() # Prepare the minion event system # # Start with the publish socket id_hash = hashlib.md5(self.opts['id']).hexdigest() epub_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pub.ipc'.format(id_hash) ) epull_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pull.ipc'.format(id_hash) ) self.epub_sock = self.context.socket(zmq.PUB) if self.opts.get('ipc_mode', '') == 'tcp': epub_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pub_port'] ) epull_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pull_port'] ) else: epub_uri = 'ipc://{0}'.format(epub_sock_path) salt.utils.check_ipc_path_max_len(epub_uri) epull_uri = 'ipc://{0}'.format(epull_sock_path) salt.utils.check_ipc_path_max_len(epull_uri) log.debug( '{0} PUB socket URI: {1}'.format( self.__class__.__name__, epub_uri ) ) log.debug( '{0} PULL socket URI: {1}'.format( self.__class__.__name__, epull_uri ) ) # Create the pull socket self.epull_sock = self.context.socket(zmq.PULL) # Bind the event sockets self.epub_sock.bind(epub_uri) self.epull_sock.bind(epull_uri) # Restrict access to the sockets if not self.opts.get('ipc_mode', '') == 'tcp': os.chmod( epub_sock_path, 448 ) os.chmod( epull_sock_path, 448 ) self.poller = zmq.Poller() self.epoller = zmq.Poller() self.socket = self.context.socket(zmq.SUB) self.socket.setsockopt(zmq.SUBSCRIBE, '') self.socket.setsockopt(zmq.IDENTITY, self.opts['id']) if hasattr(zmq, 'RECONNECT_IVL_MAX'): self.socket.setsockopt( zmq.RECONNECT_IVL_MAX, self.opts['recon_max'] ) if hasattr(zmq, 'TCP_KEEPALIVE'): self.socket.setsockopt( zmq.TCP_KEEPALIVE, self.opts['tcp_keepalive'] ) self.socket.setsockopt( zmq.TCP_KEEPALIVE_IDLE, self.opts['tcp_keepalive_idle'] ) self.socket.setsockopt( zmq.TCP_KEEPALIVE_CNT, self.opts['tcp_keepalive_cnt'] ) self.socket.setsockopt( zmq.TCP_KEEPALIVE_INTVL, self.opts['tcp_keepalive_intvl'] ) if hasattr(zmq, 'IPV4ONLY'): self.socket.setsockopt( zmq.IPV4ONLY, int(not int(self.opts.get('ipv6_enable', False))) ) self.socket.connect(self.master_pub) self.poller.register(self.socket, zmq.POLLIN) self.epoller.register(self.epull_sock, zmq.POLLIN) # Send an event to the master that the minion is live self._fire_master( 'Minion {0} started at {1}'.format( self.opts['id'], time.asctime() ), 'minion_start' ) if self.opts['multiprocessing'] and not salt.utils.is_windows(): signal.signal(signal.SIGCHLD, self.handle_sigchld) # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() # On first startup execute a state run if configured to do so self._state_run() while True: try: self.schedule.eval() socks = dict(self.poller.poll( self.opts['loop_interval'] * 1000) ) if self.socket in socks and socks[self.socket] == zmq.POLLIN: payload = self.serial.loads(self.socket.recv()) self._handle_payload(payload) time.sleep(0.05) # Clean up the minion processes which have been executed and # have finished # Check if modules and grains need to be refreshed self.passive_refresh() # Check the event system if self.epoller.poll(1): try: package = self.epull_sock.recv(zmq.NOBLOCK) self.epub_sock.send(package) except Exception: pass except zmq.ZMQError: # This is thrown by the inturupt caused by python handling the # SIGCHLD. This is a safe error and we just start the poll # again continue except Exception: log.critical(traceback.format_exc())
def tune_in(self): ''' Lock onto the publisher. This is the main event loop for the minion ''' log.info('{0} is starting as user \'{1}\''.format( self.__class__.__name__, getpass.getuser())) log.debug('Minion "{0}" trying to tune in'.format(self.opts['id'])) self.context = zmq.Context() # Prepare the minion event system # # Start with the publish socket id_hash = hashlib.md5(self.opts['id']).hexdigest() epub_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pub.ipc'.format(id_hash)) epull_sock_path = os.path.join( self.opts['sock_dir'], 'minion_event_{0}_pull.ipc'.format(id_hash)) self.epub_sock = self.context.socket(zmq.PUB) if self.opts.get('ipc_mode', '') == 'tcp': epub_uri = 'tcp://127.0.0.1:{0}'.format(self.opts['tcp_pub_port']) epull_uri = 'tcp://127.0.0.1:{0}'.format( self.opts['tcp_pull_port']) else: epub_uri = 'ipc://{0}'.format(epub_sock_path) epull_uri = 'ipc://{0}'.format(epull_sock_path) for uri in (epub_uri, epull_uri): if uri.startswith('tcp://'): # This check only applies to IPC sockets continue # The socket path is limited to 107 characters on Solaris and # Linux, and 103 characters on BSD-based systems. # Let's fail at the lower level so no system checks are # required. if len(uri) > 103: raise SaltSystemExit( 'The socket path length is more that what ZMQ allows. ' 'The length of {0!r} is more than 103 characters. ' 'Either try to reduce the length of this setting\'s ' 'path or switch to TCP; In the configuration file set ' '"ipc_mode: tcp"'.format(uri)) log.debug('{0} PUB socket URI: {1}'.format(self.__class__.__name__, epub_uri)) log.debug('{0} PULL socket URI: {1}'.format(self.__class__.__name__, epull_uri)) # Create the pull socket self.epull_sock = self.context.socket(zmq.PULL) # Bind the event sockets self.epub_sock.bind(epub_uri) self.epull_sock.bind(epull_uri) # Restrict access to the sockets if not self.opts.get('ipc_mode', '') == 'tcp': os.chmod(epub_sock_path, 448) os.chmod(epull_sock_path, 448) self.poller = zmq.Poller() self.epoller = zmq.Poller() self.socket = self.context.socket(zmq.SUB) self.socket.setsockopt(zmq.SUBSCRIBE, '') self.socket.setsockopt(zmq.IDENTITY, self.opts['id']) if hasattr(zmq, 'RECONNECT_IVL_MAX'): self.socket.setsockopt(zmq.RECONNECT_IVL_MAX, self.opts['recon_max']) if hasattr(zmq, 'TCP_KEEPALIVE'): self.socket.setsockopt(zmq.TCP_KEEPALIVE, self.opts['tcp_keepalive']) self.socket.setsockopt(zmq.TCP_KEEPALIVE_IDLE, self.opts['tcp_keepalive_idle']) self.socket.setsockopt(zmq.TCP_KEEPALIVE_CNT, self.opts['tcp_keepalive_cnt']) self.socket.setsockopt(zmq.TCP_KEEPALIVE_INTVL, self.opts['tcp_keepalive_intvl']) self.socket.connect(self.master_pub) self.poller.register(self.socket, zmq.POLLIN) self.epoller.register(self.epull_sock, zmq.POLLIN) # Send an event to the master that the minion is live self._fire_master( 'Minion {0} started at {1}'.format(self.opts['id'], time.asctime()), 'minion_start') # Make sure to gracefully handle SIGUSR1 enable_sigusr1_handler() # On first startup execute a state run if configured to do so self._state_run() while True: try: self.schedule.eval() socks = dict( self.poller.poll(self.opts['loop_interval'] * 1000)) if self.socket in socks and socks[self.socket] == zmq.POLLIN: payload = self.serial.loads(self.socket.recv()) self._handle_payload(payload) time.sleep(0.05) # Clean up the minion processes which have been executed and # have finished multiprocessing.active_children() # Check if modules and grains need to be refreshed self.passive_refresh() # Check the event system if self.epoller.poll(1): try: package = self.epull_sock.recv(zmq.NOBLOCK) self.epub_sock.send(package) except Exception: pass except Exception: log.critical(traceback.format_exc())