def test_makeService_patches_tftp_service(self): mock_tftp_patch = ( self.patch(plugin_module, 'add_patches_to_txtftp')) options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service_maker.makeService(options, clock=None) self.assertThat(mock_tftp_patch, MockCalledOnceWith())
def test_makeService_not_in_debug(self): """ Only the site service is created when no options are given. """ self.patch(settings, "DEBUG", False) options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") self.patch(service_maker, '_loadSettings') service = service_maker.makeService(options, clock=None) self.assertIsInstance(service, MultiService) expected_services = [ "dhcp_probe", "networks_monitor", "image_download", "lease_socket_service", "node_monitor", "ntp", "rpc", "rpc-ping", "tftp", "http_image_service", "service_monitor", ] self.assertThat(service.namedServices, KeysEqual(*expected_services)) self.assertEqual(len(service.namedServices), len(service.services), "Not all services are named.") self.assertEqual(service, provisioningserver.services) self.assertThat(crochet.no_setup, MockCalledOnceWith()) self.assertThat( logger.configure, MockCalledOnceWith(options["verbosity"], logger.LoggingMode.TWISTD))
def test_tftp_service(self): # A TFTP service is configured and added to the top-level service. interfaces = [ factory.getRandomIPAddress(), factory.getRandomIPAddress(), ] self.patch( plugin, "get_all_interface_addresses", lambda: interfaces) config = { "tftp": { "generator": "http://candlemass/solitude", "root": self.tempdir, "port": factory.getRandomPort(), }, } options = Options() options["config-file"] = self.write_config(config) service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options) tftp_services = service.getServiceNamed("tftp") # The "tftp" service is a multi-service containing UDP servers for # each interface defined by get_all_interface_addresses(). self.assertIsInstance(tftp_services, MultiService) services = [ tftp_services.getServiceNamed(interface) for interface in interfaces ] expected_backend = MatchesAll( IsInstance(TFTPBackend), AfterPreprocessing( lambda backend: backend.base.path, Equals(config["tftp"]["root"])), AfterPreprocessing( lambda backend: backend.generator_url.geturl(), Equals(config["tftp"]["generator"]))) expected_protocol = MatchesAll( IsInstance(TFTP), AfterPreprocessing( lambda protocol: protocol.backend, expected_backend)) expected_service = MatchesAll( IsInstance(UDPServer), AfterPreprocessing( lambda service: len(service.args), Equals(2)), AfterPreprocessing( lambda service: service.args[0], # port Equals(config["tftp"]["port"])), AfterPreprocessing( lambda service: service.args[1], # protocol expected_protocol)) self.assertThat(services, AllMatch(expected_service)) # Only the interface used for each service differs. self.assertEqual( [svc.kwargs for svc in services], [{"interface": interface} for interface in interfaces])
def test_makeService(self): """ Only the site service is created when no options are given. """ options = Options() options["config-file"] = self.write_config({}) service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options) self.assertIsInstance(service, MultiService) self.assertSequenceEqual(["log", "oops", "tftp"], sorted(service.namedServices)) self.assertEqual(len(service.namedServices), len(service.services), "Not all services are named.")
def test_tftp_service(self): # A TFTP service is configured and added to the top-level service. interfaces = [ factory.getRandomIPAddress(), factory.getRandomIPAddress(), ] self.patch(plugin, "get_all_interface_addresses", lambda: interfaces) config = { "tftp": { "generator": "http://candlemass/solitude", "root": self.tempdir, "port": factory.getRandomPort(), }, } options = Options() options["config-file"] = self.write_config(config) service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options) tftp_services = service.getServiceNamed("tftp") # The "tftp" service is a multi-service containing UDP servers for # each interface defined by get_all_interface_addresses(). self.assertIsInstance(tftp_services, MultiService) services = [ tftp_services.getServiceNamed(interface) for interface in interfaces ] expected_backend = MatchesAll( IsInstance(TFTPBackend), AfterPreprocessing(lambda backend: backend.base.path, Equals(config["tftp"]["root"])), AfterPreprocessing(lambda backend: backend.generator_url.geturl(), Equals(config["tftp"]["generator"]))) expected_protocol = MatchesAll( IsInstance(TFTP), AfterPreprocessing(lambda protocol: protocol.backend, expected_backend)) expected_service = MatchesAll( IsInstance(UDPServer), AfterPreprocessing(lambda service: len(service.args), Equals(2)), AfterPreprocessing( lambda service: service.args[0], # port Equals(config["tftp"]["port"])), AfterPreprocessing( lambda service: service.args[1], # protocol expected_protocol)) self.assertThat(services, AllMatch(expected_service)) # Only the interface used for each service differs. self.assertEqual([svc.kwargs for svc in services], [{ "interface": interface } for interface in interfaces])
def test_makeService_cleanup_prometheus_dir(self): tmpdir = Path(self.useFixture(TempDirectory()).path) self.useFixture( EnvironmentVariable("prometheus_multiproc_dir", str(tmpdir))) pid = os.getpid() file1 = tmpdir / "histogram_{}.db".format(pid) file1.touch() file2 = tmpdir / "histogram_{}.db".format(self.get_unused_pid()) file2.touch() service_maker = ProvisioningServiceMaker("Harry", "Hill") service_maker.makeService(Options(), clock=None) self.assertTrue(file1.exists()) self.assertFalse(file2.exists())
def test_makeService_with_EXPERIMENTAL_tftp_offload_service(self): """ Only the site service is created when no options are given. """ # Activate the offload service by setting port to 0. self.useFixture(ClusterConfigurationFixture(tftp_port=0)) options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) self.assertIsInstance(service, MultiService) self.assertThat(service.namedServices, Not(Contains("tftp"))) self.assertThat(service.namedServices, Contains("tftp-offload")) tftp_offload_service = service.getServiceNamed("tftp-offload") self.assertThat(tftp_offload_service, IsInstance(TFTPOffloadService))
def test_makeService(self): """ Only the site service is created when no options are given. """ options = Options() options["config-file"] = self.write_config({}) service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options) self.assertIsInstance(service, MultiService) self.assertSequenceEqual( ["log", "oops", "tftp"], sorted(service.namedServices)) self.assertEqual( len(service.namedServices), len(service.services), "Not all services are named.")
def test_makeService_with_broker(self): """ The log, oops, site, and amqp services are created when the broker user and password options are given. """ options = Options() options["config-file"] = self.write_config( {"broker": {"username": "******", "password": "******"}}) service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options) self.assertIsInstance(service, MultiService) self.assertSequenceEqual( ["amqp", "log", "oops", "tftp"], sorted(service.namedServices)) self.assertEqual( len(service.namedServices), len(service.services), "Not all services are named.")
def test_image_service(self): options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) image_service = service.getServiceNamed("image_service") self.assertIsInstance(image_service, BootImageEndpointService) self.assertIsInstance(image_service.site, Site) self.assertThat(image_service.site, MatchesStructure( _logFormatter=Is(reducedWebLogFormatter))) resource = image_service.site.resource root = resource.getChildWithDefault(b"images", request=None) self.assertThat(root, IsInstance(FilePath)) with ClusterConfiguration.open() as config: resource_root = FilePath(config.tftp_root) self.assertEqual(resource_root, root)
def test_makeService_with_broker(self): """ The log, oops, site, and amqp services are created when the broker user and password options are given. """ options = Options() options["config-file"] = self.write_config( {"broker": { "username": "******", "password": "******" }}) service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options) self.assertIsInstance(service, MultiService) self.assertSequenceEqual(["amqp", "log", "oops", "tftp"], sorted(service.namedServices)) self.assertEqual(len(service.namedServices), len(service.services), "Not all services are named.")
def test_makeService_no_shared_secret(self): self.mock_get_shared_secret.return_value = None service_maker = ProvisioningServiceMaker("foo", "bar") self.patch(service_maker, "_loadSettings") clock = Clock() attempts = count() def advance(seconds): next(attempts) clock.advance(seconds) service = service_maker.makeService(Options(), clock=clock, sleep=advance) self.assertIsInstance(service, MultiService) self.assertEqual(service.namedServices, {}) self.mock_generate_certificate.assert_not_called() # All 300 attempts (e.g. 5 minutes) fail, next is 301 self.assertEqual(next(attempts), 301)
def test_makeService_eventual_shared_secret(self): # First two times we look, there's no secret self.mock_get_shared_secret.side_effect = [None, None, "secret"] service_maker = ProvisioningServiceMaker("foo", "bar") self.patch(service_maker, "_loadSettings") clock = Clock() attempts = count(1) def advance(seconds): next(attempts) clock.advance(60) service = service_maker.makeService(Options(), clock=clock, sleep=advance) self.assertIsInstance(service, MultiService) self.assertNotEqual(service.namedServices, {}) # First two fail, the third one succeeds self.assertEqual(next(attempts), 3)
def test_tftp_service(self): # A TFTP service is configured and added to the top-level service. options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) tftp_service = service.getServiceNamed("tftp") self.assertIsInstance(tftp_service, TFTPService) with ClusterConfiguration.open() as config: tftp_root = config.tftp_root tftp_port = config.tftp_port expected_backend = MatchesAll( IsInstance(TFTPBackend), AfterPreprocessing(lambda backend: backend.base.path, Equals(tftp_root)), ) self.assertThat( tftp_service, MatchesStructure(backend=expected_backend, port=Equals(tftp_port)), )
def test_http_image_service(self): options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) lease_socket_service = service.getServiceNamed("http_image_service") self.assertIsInstance(lease_socket_service, HTTPImageService)
def test_rpc_ping_service(self): options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) rpc_ping = service.getServiceNamed("rpc-ping") self.assertIsInstance(rpc_ping, ClusterClientCheckerService)
def test_service_monitor_service(self): options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) service_monitor = service.getServiceNamed("service_monitor") self.assertIsInstance(service_monitor, ServiceMonitorService)
def test_dhcp_probe_service(self): options = Options() service_maker = ProvisioningServiceMaker("Spike", "Milligan") service = service_maker.makeService(options, clock=None) dhcp_probe = service.getServiceNamed("dhcp_probe") self.assertIsInstance(dhcp_probe, DHCPProbeService)
def test_networks_monitor_service(self): options = Options() service_maker = ProvisioningServiceMaker("Spike", "Milligan") service = service_maker.makeService(options, clock=None) networks_monitor = service.getServiceNamed("networks_monitor") self.assertIsInstance(networks_monitor, RackNetworksMonitoringService)
def test_image_download_service(self): options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) image_service = service.getServiceNamed("image_download") self.assertIsInstance(image_service, ImageDownloadService)
twisted.internet.reactor = reactor sys.modules['twisted.internet.reactor'] = reactor from twisted.python import usage from twisted.scripts._twistd_unix import ServerOptions, UnixApplicationRunner # Load the available MAAS plugins. twistd_plugins = [] try: from provisioningserver.plugin import ProvisioningServiceMaker except ImportError: pass else: # Rackd service that twisted will spawn. twistd_plugins.append( ProvisioningServiceMaker("maas-rackd", "The MAAS Rack Controller daemon.")) try: from maasserver.plugin import ( RegionAllInOneServiceMaker, RegionMasterServiceMaker, RegionWorkerServiceMaker, ) except ImportError: pass else: # Regiond services that twisted could spawn. twistd_plugins.append( RegionMasterServiceMaker("maas-regiond-master", "The MAAS Region Controller master process.")) twistd_plugins.append(
def test_http_service(self): options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) http_service = service.getServiceNamed("http_service") self.assertIsInstance(http_service, StreamServerEndpointService)
def test_external_service(self): options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) external_service = service.getServiceNamed("external") self.assertIsInstance(external_service, RackExternalService)
def test_version_update_service(self): options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) version_check_service = service.getServiceNamed("version_update_check") self.assertIsInstance(version_check_service, VersionUpdateCheckService)
def test_init(self): service_maker = ProvisioningServiceMaker("Harry", "Hill") self.assertEqual("Harry", service_maker.tapname) self.assertEqual("Hill", service_maker.description)
def test_dns_service(self): options = Options() service_maker = ProvisioningServiceMaker("Harry", "Hill") service = service_maker.makeService(options, clock=None) dns_service = service.getServiceNamed("dns") self.assertIsInstance(dns_service, RackDNSService)
# Copyright 2012 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """Twisted Application Plugin for the MAAS provisioning server.""" from __future__ import ( absolute_import, print_function, unicode_literals, ) str = None __metaclass__ = type __all__ = [] try: from provisioningserver.plugin import ProvisioningServiceMaker except ImportError: pass # Ignore. else: # Construct objects which *provide* the relevant interfaces. The name of # these variables is irrelevant, as long as there are *some* names bound # to providers of IPlugin and IServiceMaker. service = ProvisioningServiceMaker("maas-pserv", "...") # TODO: finish