def test_configure(self): servers = [ factory.make_ipv4_address(), factory.make_ipv6_address(), factory.make_hostname(), ] peers = [ factory.make_ipv4_address(), factory.make_ipv6_address(), factory.make_hostname(), ] offset = randrange(0, 5) config.configure(servers, peers, offset) ntp_conf_path = get_data_path("etc", config._ntp_conf_name) ntp_maas_conf_path = get_data_path("etc", config._ntp_maas_conf_name) ntp_conf = read_configuration(ntp_conf_path) self.assertThat(extract_servers_and_pools(ntp_conf), Equals([])) self.assertThat(extract_included_files(ntp_conf), Equals([ntp_maas_conf_path])) ntp_maas_conf = read_configuration(ntp_maas_conf_path) self.assertThat(extract_servers_and_pools(ntp_maas_conf), Equals(servers)) self.assertThat(extract_peers(ntp_maas_conf), Equals(peers)) self.assertThat(extract_tos_options(ntp_maas_conf), Equals([str(offset + 8), "orphan"]))
def test_can_write_file_in_development(self): filename = get_data_path("/var/lib/maas/dhcpd.conf") contents = factory.make_bytes() # Binary safe. mode = random.randint(0o000, 0o777) | 0o400 # Always u+r. sudo_write_file(filename, contents, mode) self.assertThat(filename, FileContains(contents)) self.assertThat(os.stat(filename).st_mode & 0o777, Equals(mode))
def _makeTFTPService(self, tftp_root, tftp_port, rpc_service): """Create the dynamic TFTP service.""" from provisioningserver.rackdservices.tftp import TFTPService tftp_service = TFTPService(resource_root=tftp_root, port=tftp_port, client_service=rpc_service) tftp_service.setName("tftp") # *** EXPERIMENTAL *** # https://code.launchpad.net/~allenap/maas/tftp-offload/+merge/312146 # If the TFTP port has been set to zero, use the experimental offload # service. Otherwise stick to the normal in-process TFTP service. if tftp_port == 0: from provisioningserver.path import get_data_path from provisioningserver.rackdservices import tftp_offload from twisted.internet.endpoints import UNIXServerEndpoint tftp_offload_socket = get_data_path( "/var/lib/maas/tftp-offload.sock") tftp_offload_endpoint = UNIXServerEndpoint(reactor, tftp_offload_socket, wantPID=False) tftp_offload_service = tftp_offload.TFTPOffloadService( reactor, tftp_offload_endpoint, tftp_service.backend) tftp_offload_service.setName("tftp-offload") return tftp_offload_service # *** /EXPERIMENTAL *** return tftp_service
def test_delete(self): self.set_envvar(None) example_file = factory.make_name("config") self.example_configuration.DEFAULT_FILENAME = example_file del self.example_configuration.DEFAULT_FILENAME self.assertEqual(get_data_path(self.example_configuration.default), self.example_configuration.DEFAULT_FILENAME) # The delete does not fail when called multiple times. del self.example_configuration.DEFAULT_FILENAME
def get_config_v4(template_name: str, global_dhcp_snippets: Sequence[dict], failover_peers: Sequence[dict], shared_networks: Sequence[dict], hosts: Sequence[dict], omapi_key: str) -> str: """Return a DHCP config file based on the supplied parameters. :param template_name: Template file name: `dhcpd.conf.template` for the IPv4 template. :return: A full configuration, as a string. """ platform_codename = linux_distribution()[2] template = load_template('dhcp', template_name) dhcp_socket = get_data_path('/var/lib/maas/dhcpd.sock') # Helper functions to stuff into the template namespace. helpers = { "oneline": normalise_whitespace, "commalist": normalise_any_iterable_to_comma_list, "quoted_commalist": normalise_any_iterable_to_quoted_comma_list, "running_in_snap": snappy.running_in_snap(), } rack_addrs = [ IPAddress(addr) for addr in net_utils.get_all_interface_addresses() ] for shared_network in shared_networks: for subnet in shared_network["subnets"]: cidr = IPNetwork(subnet['subnet_cidr']) rack_ips = [ str(rack_addr) for rack_addr in rack_addrs if rack_addr in cidr ] if len(rack_ips) > 0: subnet["next_server"] = rack_ips[0] subnet["bootloader"] = compose_conditional_bootloader( False, rack_ips[0]) ntp_servers = subnet["ntp_servers"] # Is a list. ntp_servers_ipv4, ntp_servers_ipv6 = _get_addresses(*ntp_servers) subnet["ntp_servers_ipv4"] = ", ".join(ntp_servers_ipv4) subnet["ntp_servers_ipv6"] = ", ".join(ntp_servers_ipv6) try: return template.substitute( global_dhcp_snippets=global_dhcp_snippets, hosts=hosts, failover_peers=failover_peers, shared_networks=shared_networks, platform_codename=platform_codename, omapi_key=omapi_key, dhcp_helper=(get_path('/usr/sbin/maas-dhcp-helper')), dhcp_socket=dhcp_socket, **helpers) except (KeyError, NameError) as error: raise DHCPConfigError( "Failed to render DHCP configuration.") from error
def __init__(self, name, reactor=None): if not isinstance(name, str): raise TypeError("Lock name must be str, not %s" % type(name).__qualname__) elif not self.ACCEPTABLE_CHARACTERS.issuperset(name): illegal = set(name) - self.ACCEPTABLE_CHARACTERS raise ValueError("Lock name contains illegal characters: %s" % "".join(sorted(illegal))) else: lockpath = get_data_path("run", "lock", "maas:%s" % name) super(NamedLock, self).__init__(lockpath, reactor=reactor)
def setUp(self): """Ensures each test starts cleanly, with no pre-existing secret.""" get_secret = self.patch(security, "get_shared_secret_filesystem_path") # Ensure each test uses a different filename for the shared secret, # so that tests cannot interfere with each other. get_secret.return_value = get_data_path( "var", "lib", "maas", "secret-%s" % factory.make_string(16)) # Extremely unlikely, but just in case. self.delete_secret() self.addCleanup( setattr, security, "DEFAULT_ITERATION_COUNT", security.DEFAULT_ITERATION_COUNT) # The default high iteration count would make the tests very slow. security.DEFAULT_ITERATION_COUNT = 2 super().setUp()
def set_maas_id(system_id): """Set the system_id for this rack/region permanently for MAAS.""" global _maas_id system_id = _normalise_maas_id(system_id) with _maas_id_lock: maas_id_path = get_data_path("/var/lib/maas/maas_id") if system_id is None: try: atomic_delete(maas_id_path) except FileNotFoundError: _maas_id = None # Job done already. else: _maas_id = None else: atomic_write(system_id.encode("ascii"), maas_id_path) _maas_id = system_id
def get_maas_id(): """Return the system_id for this rack/region controller that is created when either the rack or region first starts. """ global _maas_id with _maas_id_lock: if _maas_id is None: maas_id_path = get_data_path("/var/lib/maas/maas_id") try: with open(maas_id_path, "r", encoding="ascii") as fp: contents = fp.read().strip() except FileNotFoundError: return None else: _maas_id = _normalise_maas_id(contents) return _maas_id else: return _maas_id
def toggle_cprofile(process_name, signum=None, stack=None): """Toggle cProfile profiling of the process. If it's called when no profiling is enabled, profiling will start. If it's called when profiling is enabled, profiling is stopped and the stats are written to MAAS_ROOT/var/lib/maas/profiling, with the process name and pid in the name. """ global _profile if _profile is None: _profile = cProfile.Profile() _profile.enable() print('Profiling enabled') else: base_dir = Path('/') / 'var' / 'lib' / 'maas' / 'profiling' current_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f') output_filepath = ( base_dir / f'{process_name}-{os.getpid()}-{current_time}.pyprof') full_filepath = get_data_path(str(output_filepath)) _profile.create_stats() _profile.dump_stats(full_filepath) _profile = None print(f'Profiling disabled. Output written to {full_filepath}')
def __init__(self, path, reactor=None): abspath = FilePath(path).asTextMode().path.lstrip("/") discriminator = abspath.replace(":", "::").replace("/", ":") lockpath = get_data_path("run", "lock", "maas@%s" % discriminator) super(RunLock, self).__init__(lockpath, reactor=reactor)
def get_socket_path(): """Return path to dhcpd.sock.""" return os.path.join(get_data_path("/var/lib/maas"), "dhcpd.sock")
def get_shared_secret_filesystem_path(): """Return the path to shared-secret on the filesystem.""" return get_data_path("var", "lib", "maas", "secret")
def test_falls_back_to_default(self): self.set_envvar(None) self.assertEqual(get_data_path(self.example_configuration.default), self.example_configuration.DEFAULT_FILENAME)
def test_can_delete_file_in_development(self): filename = get_data_path("/var/lib/maas/dhcpd.conf") with open(filename, "wb") as fd: fd.write(factory.make_bytes()) sudo_delete_file(filename) self.assertThat(filename, Not(FileExists()))
class ExampleConfigurationMeta(ConfigurationMeta): envvar = "MAAS_TESTING_SETTINGS" default = get_data_path("example.db") backend = None # Define this in sub-classes.
def setUp(self): super(TestMAASID, self).setUp() self.maas_id_path = get_data_path("/var/lib/maas/maas_id") self.addCleanup(env.set_maas_id, None) env.set_maas_id(None)
def get_maas_user_gpghome(): """Return the GPG directory for the `maas` user. Set $GPGHOME to this value ad-hoc when needed. """ return get_data_path('/var/lib/maas/gnupg')