def _bring_up(self, service): """Brings up the given service. :params ``supervisor.Service`` service: Service to bring up. """ _LOGGER.info('Bringing up service %r', service) try: # Check in one step the service is supervised and *not* up (we # expect it to be down). supervisor.wait_service(service.directory, supervisor.ServiceWaitAction.up, timeout=100) # Service is up, nothing to do. return except subproc.CalledProcessError as err: if err.returncode == supervisor.ERR_NO_SUP: # Watching a directory without supervisor, nothing to do. return elif err.returncode == supervisor.ERR_TIMEOUT: # Service is down, make sure finish script is done. supervisor.wait_service( service.directory, supervisor.ServiceWaitAction.really_down, timeout=(60 * 1000)) else: raise # Bring the service back up. supervisor.control_service(service.directory, supervisor.ServiceControlAction.up)
def execute(self, data): """Put the container into the down state which will trigger cleanup. """ _LOGGER.critical('Container down: %r', data) unique_name, service_name = data['id'].split(',') container_dir = os.path.join(self._tm_env.apps_dir, unique_name) container_svc = supervisor.open_service(container_dir) data_dir = container_svc.data_dir exitinfo_file = os.path.join(os.path.join(data_dir, EXIT_INFO)) try: with io.open(exitinfo_file, 'x') as f: _LOGGER.info('Creating exitinfo file: %s', exitinfo_file) if os.name == 'posix': os.fchmod(f.fileno(), 0o644) f.writelines( utils.json_genencode({ 'service': service_name, 'return_code': data['return_code'], 'signal': data['signal'], 'timestamp': data['timestamp'] })) except FileExistsError as err: _LOGGER.info('exitinfo file already exists: %s', exitinfo_file) try: supervisor.control_service(container_svc.directory, supervisor.ServiceControlAction.down) except subproc.CalledProcessError as err: _LOGGER.warning('Failed to bring down container: %s', unique_name) return True
def _blackout_terminate(tm_env): """Blackout by terminating all containers in running dir. """ _LOGGER.info('Terminating init1.') supervisor.control_service(os.path.join(tm_env.init_dir, 'start_init1'), supervisor.ServiceControlAction.down, wait=supervisor.ServiceWaitAction.down)
def execute(self, data): """Put the container into the down state which will trigger cleanup. """ unique_name, service_name = data['id'].split(',') container_dir = os.path.join(self._tm_env.apps_dir, unique_name) container_svc = supervisor.open_service(container_dir) _LOGGER.critical('Container down: %r', data) data_dir = container_svc.data_dir fs.write_safe( os.path.join(data_dir, EXIT_INFO), lambda f: f.writelines( utils.json_genencode({ 'service': service_name, 'return_code': data['return_code'], 'signal': data['signal'], 'timestamp': data['timestamp'] })), mode='w', prefix='.tmp', permission=0o644) try: supervisor.control_service(container_svc.directory, supervisor.ServiceControlAction.down) except subproc.CalledProcessError as err: _LOGGER.warning('Failed to bring down container: %r', unique_name) return True
def _start_service_sup(container_dir): """Safely start services supervisor.""" try: supervisor.control_service( os.path.join(container_dir, 'sys', 'start_container'), supervisor.ServiceControlAction.once) except subproc.CalledProcessError: raise exc.ContainerSetupError('start_container')
def _start_init1(tm_env): """Start init1 supervision.""" _LOGGER.info('Starting init1.') supervisor.control_service( os.path.join(tm_env.init_dir, 'start_init1'), supervisor.ServiceControlAction.up, wait=supervisor.ServiceWaitAction.up )
def abort(container_dir, why=None, payload=None): """Abort a running application. Called when some initialization failed in a running container. """ flag_aborted(container_dir, why, payload) container_dir = os.path.realpath(os.path.join(container_dir, '../')) supervisor.control_service(container_dir, supervisor.ServiceControlAction.down)
def test_control_service_wait(self): """Tests controlling a service and wait""" # Disable W0212(protected-access) # pylint: disable=W0212 # shutdown supervised service res = supervisor.control_service( self.root, supervisor.ServiceControlAction.down, wait=supervisor.ServiceWaitAction.down, timeout=100, ) treadmill.subproc.check_call.assert_called_with( [supervisor._get_cmd('svc'), '-d', self.root] ) treadmill.supervisor.wait_service.assert_called_with( self.root, treadmill.supervisor.ServiceWaitAction.down, timeout=100 ) self.assertTrue(res) # shutdown service timeouts treadmill.subproc.check_call.reset_mock() supervisor.wait_service.side_effect = \ subproc.CalledProcessError(99, supervisor._get_cmd('svwait')) res = supervisor.control_service( self.root, supervisor.ServiceControlAction.down, wait=supervisor.ServiceWaitAction.down, timeout=100, ) treadmill.subproc.check_call.assert_called_with( [supervisor._get_cmd('svc'), '-d', self.root] ) treadmill.supervisor.wait_service.assert_called_with( self.root, treadmill.supervisor.ServiceWaitAction.down, timeout=100 ) self.assertFalse(res) # shutdown unsupervised service treadmill.subproc.check_call.reset_mock() treadmill.subproc.check_call.side_effect = \ subproc.CalledProcessError(100, supervisor._get_cmd('svc')) with self.assertRaises(subproc.CalledProcessError): supervisor.control_service( self.root, supervisor.ServiceControlAction.down, wait=supervisor.ServiceWaitAction.down, timeout=100, )
def kill(self): services_dir = os.path.join(self._service.data_dir, 'sys', 'start_container') try: supervisor.control_service(services_dir, supervisor.ServiceControlAction.kill) except subproc.CalledProcessError as err: if err.returncode in (supervisor.ERR_COMMAND, supervisor.ERR_NO_SUP): # Ignore the error if there is no supervisor _LOGGER.info('Cannot control supervisor of %r.', services_dir) else: raise
def _start_service_sup(tm_env, manifest, container_dir): """Safely start services supervisor.""" for service in manifest['services']: if service['trace']: appevents.post( tm_env.app_events_dir, traceevents.ServiceRunningTraceEvent( instanceid=manifest['name'], uniqueid=manifest['uniqueid'], service=service['name'])) try: supervisor.control_service( os.path.join(container_dir, 'sys', 'start_container'), supervisor.ServiceControlAction.once) except subproc.CalledProcessError: raise exc.ContainerSetupError('start_container')
def test_control_service(self): """Tests controlling a service. """ # Disable W0212(protected-access) # pylint: disable=W0212 self.assertTrue(supervisor.control_service( self.root, supervisor.ServiceControlAction.down )) treadmill.subproc.check_call.assert_called_with( [supervisor._get_cmd('svc'), '-d', self.root] ) self.assertTrue(supervisor.control_service( self.root, ( supervisor.ServiceControlAction.up, supervisor.ServiceControlAction.once_at_most, ), timeout=100, # Should not be used )) treadmill.subproc.check_call.assert_called_with( [supervisor._get_cmd('svc'), '-uO', self.root] ) self.assertTrue(supervisor.control_service( self.root, supervisor.ServiceControlAction.up, wait=supervisor.ServiceWaitAction.up, timeout=100, )) treadmill.subproc.check_call.assert_called_with( [supervisor._get_cmd('svwait'), '-t100', '-u', self.root] ) treadmill.subproc.check_call.side_effect = \ subproc.CalledProcessError(1, supervisor._get_cmd('svc')) self.assertRaises( subproc.CalledProcessError, supervisor.control_service, self.root, supervisor.ServiceControlAction.down ) treadmill.subproc.check_call.assert_called_with( [supervisor._get_cmd('svc'), '-d', self.root] )
def execute(self, data): """Execute the down action. :returns ``bool``: ``True`` - Monitor should keep running. ``False`` - Monitor should stop. """ _LOGGER.critical('Container down: %r', data) data_dir = self._container_svc.data_dir fs.write_safe(os.path.join(data_dir, EXIT_INFO), lambda f: f.writelines(utils.json_genencode(data)), mode='w', prefix='.tmp', permission=0o644) # NOTE: This will take down this container's monitor service as well. # NOTE: The supervisor has to be running as we call from inside the # container. supervisor.control_service(self._container_svc.directory, supervisor.ServiceControlAction.down) return False