def __init__(self, root): super(LinuxAppEnvironment, self).__init__(root) self.ctl_dir = os.path.join(self.root, self.CTL_DIR) self.metrics_dir = os.path.join(self.root, self.METRICS_DIR) self.mounts_dir = os.path.join(self.root, self.MOUNTS_DIR) self.rules_dir = os.path.join(self.root, self.RULES_DIR) self.services_tombstone_dir = os.path.join(self.tombstones_dir, self.SERVICES_DIR) self.spool_dir = os.path.join(self.root, self.SPOOL_DIR) self.svc_cgroup_dir = os.path.join(self.root, self.SVC_CGROUP_DIR) self.svc_localdisk_dir = os.path.join(self.root, self.SVC_LOCALDISK_DIR) self.svc_network_dir = os.path.join(self.root, self.SVC_NETWORK_DIR) self.svc_presence_dir = os.path.join(self.root, self.SVC_PRESENCE_DIR) self.rules_dir = os.path.join(self.root, self.RULES_DIR) self.services_tombstone_dir = os.path.join(self.tombstones_dir, self.SERVICES_DIR) self.ctl_dir = os.path.join(self.root, self.CTL_DIR) self.endpoints_dir = os.path.join(self.root, self.ENDPOINTS_DIR) self.rules = rulefile.RuleMgr(self.rules_dir, self.apps_dir) self.endpoints = endpoints.EndpointsMgr(self.endpoints_dir) # Services self.svc_cgroup = services.ResourceService( service_dir=self.svc_cgroup_dir, impl='cgroup') self.svc_localdisk = services.ResourceService( service_dir=self.svc_localdisk_dir, impl='localdisk') self.svc_network = services.ResourceService( service_dir=self.svc_network_dir, impl='network') self.svc_presence = services.ResourceService( service_dir=self.svc_presence_dir, impl='presence')
def __init__(self, root, host_ip=None): super(LinuxAppEnvironment, self).__init__(root, host_ip) self.svc_cgroup_dir = os.path.join(self.root, self.SVC_CGROUP_DIR) self.svc_localdisk_dir = os.path.join(self.root, self.SVC_LOCALDISK_DIR) self.svc_network_dir = os.path.join(self.root, self.SVC_NETWORK_DIR) self.rules_dir = os.path.join(self.root, self.RULES_DIR) # Make sure our directories exists. fs.mkdir_safe(self.svc_cgroup_dir) fs.mkdir_safe(self.svc_localdisk_dir) fs.mkdir_safe(self.svc_network_dir) fs.mkdir_safe(self.rules_dir) self.rules = rulefile.RuleMgr(self.rules_dir, self.apps_dir) # Services self.svc_cgroup = services.ResourceService( service_dir=self.svc_cgroup_dir, impl=('treadmill.services.cgroup_service.' 'CgroupResourceService'), ) self.svc_localdisk = services.ResourceService( service_dir=self.svc_localdisk_dir, impl=('treadmill.services.cgroup_service.' 'LocalDiskResourceService'), ) self.svc_network = services.ResourceService( service_dir=self.svc_network_dir, impl=('treadmill.services.cgroup_service.' 'NetworkResourceService'), )
def test_load(self): """Verifies that only valid classes are accepted as implementation. """ # Access to a protected member _load_impl of a client class # pylint: disable=W0212 self.assertRaises( AssertionError, services.ResourceService( service_dir=self.root, impl=object, )._load_impl ) self.assertRaises( KeyError, services.ResourceService( service_dir=self.root, impl='socket:socket', )._load_impl ) self.assertTrue( services.ResourceService( service_dir=self.root, impl=MyTestService, )._load_impl() )
def test_load(self): """Test loading service using alias.""" # pylint: disable=W0212 self.assertEqual( cgroup_service.CgroupResourceService, services.ResourceService(self.root, 'cgroup')._load_impl() )
def test_linux__run_events(self, mock_poll): """Test event dispatcher. """ # Access to a protected member _run_events of a client class # pylint: disable=W0212 instance = services.ResourceService( service_dir=self.root, impl='a.sample.module', ) mock_callbacks = { i: { 'callback': mock.Mock(return_value=i) } for i in range(3) } loop_poll = mock_poll.return_value loop_poll.poll.return_value = ((i, select.POLLIN) for i in range(2)) res = instance._run_events(loop_poll, 42, mock_callbacks) loop_poll.poll.assert_called_with(42 * 1000) self.assertTrue(mock_callbacks[0]['callback'].called) self.assertTrue(mock_callbacks[1]['callback'].called) self.assertFalse(mock_callbacks[2]['callback'].called) self.assertTrue(res)
def test_load(self): """Test loading service using alias.""" # pylint: disable=W0212 self.assertEqual( network_service.NetworkResourceService, services.ResourceService(self.root, 'network')._load_impl() )
def test_load(self): """Test loading service using alias.""" # pylint: disable=W0212 self.assertEqual( presence_service.PresenceResourceService, services.ResourceService(self.root, 'presence')._load_impl() )
def presence(zkid): """Runs the presence service. """ root_dir = local_ctx['root-dir'] watchdogs_dir = local_ctx['watchdogs-dir'] context.GLOBAL.zk.idpath = zkid context.GLOBAL.zk.add_listener(zkutils.exit_on_lost) def sigterm_handler(_signo, _stack_frame): """Handle sigterm. On sigterm, stop Zookeeper session and delete Zookeeper session id file. """ _LOGGER.info('Got SIGTERM, closing zk session and rm: %s', zkid) fs.rm_safe(zkid) if context.GLOBAL.zk.has_conn(): context.GLOBAL.zk.conn.stop() signal.signal(utils.term_signal(), sigterm_handler) svc = services.ResourceService( service_dir=os.path.join(root_dir, 'presence_svc'), impl='presence', ) svc.run(watchdogs_dir=os.path.join(root_dir, watchdogs_dir))
def presence(zkid): """Runs the presence service. """ root_dir = local_ctx['root-dir'] watchdogs_dir = local_ctx['watchdogs-dir'] # Explicitely create global zk connection, so that zk session id is # preserved. context.GLOBAL.zk.conn = zkutils.connect(context.GLOBAL.zk.url, idpath=zkid) def sigterm_handler(_signo, _stack_frame): """Handle sigterm. On sigterm, stop Zookeeper session and delete Zookeeper session id file. """ _LOGGER.info('Got SIGTERM, closing zk session and rm: %s', zkid) fs.rm_safe(zkid) context.GLOBAL.zk.conn.stop() signal.signal(utils.term_signal(), sigterm_handler) svc = services.ResourceService( service_dir=os.path.join(root_dir, 'presence_svc'), impl='presence', ) svc.run(watchdogs_dir=os.path.join(root_dir, watchdogs_dir))
def test_init(self): """Validate simple instanciation. """ instance = services.ResourceService( service_dir=self.root, impl='a.sample.module', ) self.assertEqual(instance.name, 'module')
def cgroup(): """Runs cgroup node service.""" root_dir = local_ctx['root-dir'] watchdogs_dir = local_ctx['watchdogs-dir'] svc = services.ResourceService( service_dir=os.path.join(root_dir, 'cgroup_svc'), impl='cgroup', ) svc.run( watchdogs_dir=os.path.join(root_dir, watchdogs_dir), tm_env=appenv.AppEnvironment(root_dir), )
def test_name(self): """Check how the name is derived from the class name. """ self.assertEqual( services.ResourceService( service_dir=self.root, impl='treadmill.services.MyClass', ).name, 'MyClass', ) self.assertEqual( services.ResourceService( service_dir=self.root, impl='treadmill.services.MyClass', ).name, 'MyClass', ) self.assertEqual( services.ResourceService( service_dir=self.root, impl=MyTestService, ).name, 'MyTestService', )
def network(ext_device, ext_ip, ext_mtu, ext_speed): """Runs the network service. """ root_dir = local_ctx['root-dir'] watchdogs_dir = local_ctx['watchdogs-dir'] svc = services.ResourceService( service_dir=os.path.join(root_dir, 'network_svc'), impl='network', ) svc.run(watchdogs_dir=os.path.join(root_dir, watchdogs_dir), ext_device=ext_device, ext_ip=ext_ip, ext_mtu=ext_mtu, ext_speed=ext_speed)
def test_load(self): """Test loading service using alias.""" # pylint: disable=W0212 self.assertEqual( localdisk_service.LocalDiskResourceService, services.ResourceService(self.root, 'localdisk')._load_impl())
def test_linux_run(self, mock_watchdog, mock_load_impl, mock_dirwatcher, mock_poll): """Test the run method setup before the main loop. """ # Access to a protected member _is_dead of a client class # pylint: disable=W0212 mock_impl_instance = mock_load_impl.return_value.return_value mock_impl_instance.configure_mock(WATCHDOG_HEARTBEAT_SEC=60) mock_impl_instance.report_status.return_value = {'hello': 'world'} mock_impl_instance.event_handlers.return_value = [ ('filenoA', 'eventsA', 'callbackA'), ('filenoB', 'eventsB', 'callbackB'), ] mock_dirwatcher.return_value.configure_mock(inotify='mock_inotiy', ) instance = services.ResourceService( service_dir=self.root, impl='MyTestService', ) instance._is_dead = True instance.run( os.path.join(self.root, 'watchdogs'), 'foo', bar='baz', ) mock_load_impl.assert_called_with() # Make sure the implementation was passed the correct parameters. mock_load_impl.return_value.assert_called_with( 'foo', bar='baz', ) # Watchdog should be set mock_watchdog.assert_called_with(os.path.join(self.root, 'watchdogs'), ) mock_watchdog.return_value.create.assert_called_with( content=mock.ANY, name='svc-MyTestService', timeout='60s') mock_watchdog_lease = mock_watchdog.return_value.create.return_value # Implementation should be given the root as argument to `initialize` mock_impl_instance.initialize.assert_called_with(self.root) # First watcher should be setup mock_dirwatcher.assert_called_with(os.path.join( self.root, 'resources')) # Then we check/cleanup pre-existing requests services.ResourceService._check_requests.assert_called_with() services.ResourceService._on_created.assert_has_calls([ mock.call(mock_impl_instance, 'foo-1'), mock.call(mock_impl_instance, 'foo-2'), ]) # Status should be queried first mock_impl_instance.report_status.assert_called_with() # The poll registration should be properly initialized mock_impl_instance.event_handlers.assert_called_with() instance._update_poll_registration.assert_called_with( mock_poll.return_value, {}, [ ('eventfd', mock.ANY, mock.ANY), ('mock_inotiy', mock.ANY, mock.ANY), ('status_socket', mock.ANY, mock.ANY), ('filenoA', mock.ANY, mock.ANY), ('filenoB', mock.ANY, mock.ANY), ], ) # Loop exits immediately # Watchdog lease should be cleared mock_watchdog_lease.remove.assert_called_with()
def localdisk(img_location, img_size, block_dev, vg_name, block_dev_configuration, block_dev_read_bps, block_dev_write_bps, block_dev_read_iops, block_dev_write_iops, default_read_bps, default_write_bps, default_read_iops, default_write_iops): """Runs localdisk service.""" root_dir = local_ctx['root-dir'] watchdogs_dir = local_ctx['watchdogs-dir'] svc = services.ResourceService(service_dir=os.path.join( root_dir, 'localdisk_svc'), impl='localdisk') block_dev_params = [ block_dev_read_bps, block_dev_write_bps, block_dev_read_iops, block_dev_write_iops ] if img_location is None: img_location = root_dir # prepare block device if block_dev is not None: underlying_device_uuid = fs_linux.blk_uuid(block_dev) else: underlying_device_uuid = fs_linux.blk_uuid( fs_linux.maj_min_to_blk( *fs_linux.maj_min_from_path(img_location))) block_dev = localdiskutils.init_block_dev( localdiskutils.TREADMILL_IMG, img_location, img_size) # prepare block device configuration read_bps = None write_bps = None read_iops = None write_iops = None # use block device config file if block_dev_configuration is not None and all( param is None for param in block_dev_params): try: current_benchmark = diskbenchmark.read( block_dev_configuration)[underlying_device_uuid] read_bps = current_benchmark['read_bps'] write_bps = current_benchmark['write_bps'] read_iops = int(current_benchmark['read_iops']) write_iops = int(current_benchmark['write_iops']) except IOError: _LOGGER.error('No benchmark found : %s', block_dev_configuration) except (KeyError, ValueError): _LOGGER.error( 'Incorrect disk benchmark for device %s in %s', underlying_device_uuid, block_dev_configuration) # use block device config parameters if all(param is not None for param in block_dev_params) and block_dev_configuration is None: read_bps = block_dev_read_bps write_bps = block_dev_write_bps read_iops = block_dev_read_iops write_iops = block_dev_write_iops if None in [read_bps, write_bps, read_iops, write_iops]: _LOGGER.error('Bad block dev configuration') read_bps = '200M' write_bps = '200M' read_iops = 3000 write_iops = 3000 svc.run( watchdogs_dir=os.path.join(root_dir, watchdogs_dir), block_dev=block_dev, vg_name=vg_name, read_bps=read_bps, write_bps=write_bps, read_iops=read_iops, write_iops=write_iops, default_read_bps=default_read_bps, default_write_bps=default_write_bps, default_read_iops=default_read_iops, default_write_iops=default_write_iops, )