From 7df7f3b427739ff7d69da2ba218da0124822892c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Sun, 26 Nov 2017 23:39:48 +0000 Subject: Remove all .morph files and files from the old format --- extensions/simple-network.configure | 296 ------------------------------------ 1 file changed, 296 deletions(-) delete mode 100755 extensions/simple-network.configure (limited to 'extensions/simple-network.configure') diff --git a/extensions/simple-network.configure b/extensions/simple-network.configure deleted file mode 100755 index 67f46bc4..00000000 --- a/extensions/simple-network.configure +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/python2 -# Copyright (C) 2013,2015 Codethink Limited -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . - -'''A Morph deployment configuration extension to handle network configutation - -This extension prepares /etc/network/interfaces and networkd .network files -in /etc/systemd/network/ with the interfaces specified during deployment. - -If no network configuration is provided, eth0 will be configured for DHCP -with the hostname of the system in the case of /etc/network/interfaces. -In the case of networkd, any interface starting by e* will be configured -for DHCP -''' - - -import errno -import os -import sys - -import writeexts - - -class SimpleNetworkError(writeexts.ExtensionError): - '''Errors associated with simple network setup''' - pass - - -class SimpleNetworkConfigurationExtension(object): - '''Configure /etc/network/interfaces and generate networkd .network files - - Reading NETWORK_CONFIG, this extension sets up /etc/network/interfaces - and .network files in /etc/systemd/network/. - ''' - - def run(self, args): - network_config = os.environ.get("NETWORK_CONFIG") - - self.rename_networkd_chunk_file(args) - - if network_config is None: - self.generate_default_network_config(args) - else: - self.status(msg="Processing NETWORK_CONFIG=%(nc)s", - nc=network_config) - - stanzas = self.parse_network_stanzas(network_config) - - self.generate_interfaces_file(args, stanzas) - self.generate_networkd_files(args, stanzas) - - def rename_networkd_chunk_file(self, args): - """Rename the 10-dchp.network file generated in the systemd chunk - - The systemd chunk will place something in 10-dhcp.network, which will - have higher precedence than anything added in this extension (we - start at 50-*). - - We should check for that file and rename it instead remove it in - case the file is being used by the user. - - Until both the following happen, we should continue to rename that - default config file: - - 1. simple-network.configure is always run when systemd is included - 2. We've been building systems without systemd including that default - networkd config for long enough that nobody should be including - that config file. - """ - file_path = os.path.join(args[0], "etc", "systemd", "network", - "10-dhcp.network") - - if os.path.isfile(file_path): - try: - os.rename(file_path, file_path + ".morph") - self.status(msg="Renaming networkd file from systemd chunk: \ - %(f)s to %(f)s.morph", f=file_path) - except OSError: - pass - - def generate_default_network_config(self, args): - """Generate default network config: DHCP in all the interfaces""" - - default_network_config_interfaces = "lo:loopback;" \ - "eth0:dhcp,hostname=$(hostname)" - default_network_config_networkd = "e*:dhcp" - - stanzas_interfaces = self.parse_network_stanzas( - default_network_config_interfaces) - stanzas_networkd = self.parse_network_stanzas( - default_network_config_networkd) - - self.generate_interfaces_file(args, stanzas_interfaces) - self.generate_networkd_files(args, stanzas_networkd) - - def generate_interfaces_file(self, args, stanzas): - """Generate /etc/network/interfaces file""" - - iface_file = self.generate_iface_file(stanzas) - - directory_path = os.path.join(args[0], "etc", "network") - self.make_sure_path_exists(directory_path) - file_path = os.path.join(directory_path, "interfaces") - with open(file_path, "w") as f: - f.write(iface_file) - - def generate_iface_file(self, stanzas): - """Generate an interfaces file from the provided stanzas. - - The interfaces will be sorted by name, with loopback sorted first. - """ - - def cmp_iface_names(a, b): - a = a['name'] - b = b['name'] - if a == "lo": - return -1 - elif b == "lo": - return 1 - else: - return cmp(a,b) - - return "\n".join(self.generate_iface_stanza(stanza) - for stanza in sorted(stanzas, cmp=cmp_iface_names)) - - def generate_iface_stanza(self, stanza): - """Generate an interfaces stanza from the provided data.""" - - name = stanza['name'] - itype = stanza['type'] - lines = ["auto %s" % name, "iface %s inet %s" % (name, itype)] - lines += [" %s %s" % elem for elem in stanza['args'].items()] - lines += [""] - return "\n".join(lines) - - def generate_networkd_files(self, args, stanzas): - """Generate .network files""" - - for i, stanza in enumerate(stanzas, 50): - iface_file = self.generate_networkd_file(stanza) - - if iface_file is None: - continue - - directory_path = os.path.join(args[0], "etc", "systemd", "network") - self.make_sure_path_exists(directory_path) - file_path = os.path.join(directory_path, - "%s-%s.network" % (i, stanza['name'])) - - with open(file_path, "w") as f: - f.write(iface_file) - - def generate_networkd_file(self, stanza): - """Generate an .network file from the provided data.""" - - name = stanza['name'] - itype = stanza['type'] - pairs = stanza['args'].items() - - if itype == "loopback": - return - - lines = ["[Match]"] - lines += ["Name=%s\n" % name] - lines += ["[Network]"] - if itype == "dhcp": - lines += ["DHCP=yes"] - else: - lines += self.generate_networkd_entries(pairs) - - return "\n".join(lines) - - def generate_networkd_entries(self, pairs): - """Generate networkd configuration entries with the other parameters""" - - address = None - netmask = None - gateway = None - dns = None - lines = [] - - for pair in pairs: - if pair[0] == 'address': - address = pair[1] - elif pair[0] == 'netmask': - netmask = pair[1] - elif pair[0] == 'gateway': - gateway = pair[1] - elif pair[0] == 'dns': - dns = pair[1] - - if address and netmask: - network_suffix = self.convert_net_mask_to_cidr_suffix (netmask); - address_line = address + '/' + str(network_suffix) - lines += ["Address=%s" % address_line] - elif address or netmask: - raise SimpleNetworkError( - 'address and netmask must be specified together') - - if gateway: - lines += ["Gateway=%s" % gateway] - - if dns: - lines += ["DNS=%s" % dns] - - return lines - - def convert_net_mask_to_cidr_suffix(self, mask): - """Convert dotted decimal form of a subnet mask to CIDR suffix notation - - For example: 255.255.255.0 -> 24 - """ - return sum(bin(int(x)).count('1') for x in mask.split('.')) - - def parse_network_stanzas(self, config): - """Parse a network config environment variable into stanzas. - - Network config stanzas are semi-colon separated. - """ - - return [self.parse_network_stanza(s) for s in config.split(";")] - - def parse_network_stanza(self, stanza): - """Parse a network config stanza into name, type and arguments. - - Each stanza is of the form name:type[,arg=value]... - - For example: - lo:loopback - eth0:dhcp - eth1:static,address=10.0.0.1,netmask=255.255.0.0 - """ - elements = stanza.split(",") - lead = elements.pop(0).split(":") - if len(lead) != 2: - raise SimpleNetworkError("Stanza '%s' is missing its type" % - stanza) - iface = lead[0] - iface_type = lead[1] - - if iface_type not in ['loopback', 'static', 'dhcp']: - raise SimpleNetworkError("Stanza '%s' has unknown interface type" - " '%s'" % (stanza, iface_type)) - - argpairs = [element.split("=", 1) for element in elements] - output_stanza = { "name": iface, - "type": iface_type, - "args": {} } - for argpair in argpairs: - if len(argpair) != 2: - raise SimpleNetworkError("Stanza '%s' has bad argument '%r'" - % (stanza, argpair.pop(0))) - if argpair[0] in output_stanza["args"]: - raise SimpleNetworkError("Stanza '%s' has repeated argument" - " %s" % (stanza, argpair[0])) - output_stanza["args"][argpair[0]] = argpair[1] - - return output_stanza - - def make_sure_path_exists(self, path): - try: - os.makedirs(path) - except OSError as e: - if e.errno == errno.EEXIST and os.path.isdir(path): - pass - else: - raise SimpleNetworkError("Unable to create directory '%s'" - % path) - - def status(self, **kwargs): - '''Provide status output. - - The ``msg`` keyword argument is the actual message, - the rest are values for fields in the message as interpolated - by %. - - ''' - - sys.stdout.write('%s\n' % (kwargs['msg'] % kwargs)) - -try: - SimpleNetworkConfigurationExtension().run(sys.argv[1:]) -except SimpleNetworkError as e: - sys.stdout.write('ERROR: %s\n' % e) - sys.exit(1) -- cgit v1.2.1