def write_network_script(self, device, network_config, dummy=False): script_name = 'ifcfg-%s' % device.devname script_path = self.join_root( os.path.join(self.network_scripts_path, script_name)) if dummy: _template = networking.DummyInterfaceTemplate(device.devname) else: if network_config.get('type', 'AF_INET') == 'AF_INET6': self.enable_ipv6() interface_template = networking.IPv6InterfaceTemplate else: interface_template = networking.InterfaceTemplate ip_address = network_config.get('ip_address') gateway = network_config.get('gateway') prefix = network_config.get('prefix') if not prefix: prefix = ipaddress.ip_network( u"{ip_address}/{netmask}".format(**network_config), strict=False).prefixlen _template = interface_template(device.devname, default_route=network_config.get( 'default_route', False), ip_address=ip_address, prefix=prefix, gateway=gateway) log.info('Writing %s' % script_path) deployment.write(script_path, _template.generate())
def write_mdadm_configuration(self): mdraid_data = self.chroot('mdadm --detail --scan') log.info('Writing mdadm.conf') log.debug(mdraid_data) deployment.write(self.join_root(self.mdadm_conf), mdraid_data + '\n', append=True)
def set_timezone(self, timezone): timezone_path = '/etc/timezone' localtime_path = '/etc/localtime' deployment.remove_file(self.join_root(timezone_path)) deployment.remove_file(self.join_root(localtime_path)) deployment.write(self.join_root(timezone_path), timezone) self.reconfigure_package('tzdata')
def add_source(self, name, mirror): path_name = name.lower().replace(" ", "_") log.info('Creating "{name}" sources file'.format(name=name)) sources_path = self.join_root( '/etc/apt/sources.list.d/{name}.list'.format(name=path_name)) source = 'deb %s %s openmanage\n' % (mirror, self.dist) deployment.write(sources_path, source)
def add_pseudo_mounts(self): """ EL6 needs a few items in fstab that other press distros didn't: <filesystem> <dir> <type> <options> <dump pass> tmpfs /dev/shm tmpfs defaults,nosuid,nodev,noexec 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 """ pseudo_mounts = [ dict(filesystem='tmpfs', directory='/dev/shm', options='defaults,nosuid,nodev,noexec'), dict(filesystem='devpts', directory='/dev/pts', options='gid=5,mode=620'), dict(filesystem='sysfs', directory='/sys'), dict(filesystem='proc', directory='/proc') ] fstab_entry = '' for mount in pseudo_mounts: fstab_entry += self.generate_pseudo_mount_entry(**mount) fstab_file = self.join_root('/etc/fstab') log.info('Writing pseudo filesystem mounts to /etc/fstab.') deployment.write(fstab_file, fstab_entry, append=True)
def write_interfaces(path, network_configuration, os_name=None): """ Write a network interface configuration file to configure network on the target. Args: path (str): The network configuration file that will be created for configuring network. network_configuration (dict): A dictionary containing network configuration. os_name (str): A string representing the OS name of the target. The OS name will determine the the type of configuration file to write (interfaces vs netplan). (optional) """ interfaces = network_configuration.get('interfaces', list()) networks = network_configuration.get('networks') for interface in interfaces: name, device = util.networking.lookup_interface( interface, interface.get('missing_ok', False)) for network in networks: if os_name == 'ubuntu_1804' and 'netmask' in network and 'prefix' not in network: # convert netmask to a 'prefix' value used by netplan_interface.template network['prefix'] = sum([ bin(int(x)).count('1') for x in network['netmask'].split('.') ]) if name == network.get('interface'): network['device'] = device.devname network['type'] = network.get('type', 'AF_INET') if os_name == 'ubuntu_1804': template = NETPLAN_TEMPLATE deployment.write(path, render_template(template, network_configuration)) else: template = INTERFACES_TEMPLATE deployment.write(path, render_template(template, networks))
def set_hostname(self): network_configuration = self.press_configuration.get( 'networking', dict()) hostname = network_configuration.get('hostname') if not hostname: log.warn('Hostname not defined') return log.info('Setting hostname: %s' % hostname) deployment.write(self.join_root('/etc/hostname'), hostname + '\n')
def update_grub_configuration(self, match, newvalue): grub_configuration = deployment.read( self.join_root(self.grub2_cmdline_config_path)) log.info('Setting {} in {}'.format(newvalue, self.grub2_cmdline_config_path)) updated_grub_configuration = deployment.replace_line_matching( grub_configuration, match, newvalue) deployment.write( self.join_root(self.grub2_cmdline_config_path), updated_grub_configuration)
def copy_udev_rules(self, create_if_missing=False): rules_file = '/etc/udev/rules.d/70-persistent-net.rules' if not os.path.exists(rules_file): log.warn('Host 70-persistent-net.rules is missing') if create_if_missing: log.info('Generating 70-persistent-net.rules') deployment.write( self.join_root(rules_file), "\n\n".join(self.generate_udev_rules()) + "\n") return deployment.write(self.join_root(rules_file), deployment.read(rules_file))
def ensure_ifupdown_enabled(self): # linking the self.netplan_systemd_generator_file to /dev/null prevents netplan from starting # at boot, and enabling networking.service and setting CONFIGURE_INTERFACES=yes enables ifupdown deployment.recursive_makedir(self.systemd_generators_directory) deployment.create_symlink('/dev/null', self.netplan_systemd_generator_file) self.chroot('systemctl unmask networking.service') self.chroot('systemctl enable networking.service') deployment.replace_line_in_file(self.default_networking, 'CONFIGURE_INTERFACES', 'CONFIGURE_INTERFACES=yes') deployment.write(self.netplan_readme_file, self.netplan_readme_msg)
def set_hostname(self): network_configuration = self.press_configuration.get( 'networking', dict()) hostname = network_configuration.get('hostname') if not hostname: log.warn('Hostname not defined') return log.info('Setting hostname: %s' % hostname) sysconfig_network = deployment.read( self.join_root('/etc/sysconfig/network')) updated_sysconfig_network = deployment.replace_line_matching( sysconfig_network, 'HOSTNAME', 'HOSTNAME=%s' % hostname) deployment.write(self.join_root('/etc/sysconfig/network'), updated_sysconfig_network) deployment.write(self.join_root('/etc/hostname'), hostname + '\n')
def write_network_script(self, device, network_config, dummy=False): def generate_script_name(devname, vlan=None): if not vlan: return 'ifcfg-{0}'.format(devname) return 'ifcfg-{0}.{1}'.format(devname, vlan) def generate_script_path(script_name): return self.join_root( os.path.join(self.network_scripts_path, script_name)) if dummy: _template = networking.DummyInterfaceTemplate(device.devname) vlan = None else: if network_config.get('type', 'AF_INET') == 'AF_INET6': self.enable_ipv6() interface_template = networking.IPv6InterfaceTemplate else: interface_template = networking.InterfaceTemplate ip_address = network_config.get('ip_address') gateway = network_config.get('gateway') prefix = network_config.get('prefix') vlan = network_config.get('vlan') if not prefix: prefix = ipaddress.ip_network( "{ip_address}/{netmask}".format(**network_config), strict=False).prefixlen _template = interface_template(device.devname, default_route=network_config.get( 'default_route', False), ip_address=ip_address, prefix=prefix, gateway=gateway, vlan=vlan) if vlan: script_name = generate_script_name(device.devname) script_path = generate_script_path(script_name) log.info('Writing {0}'.format(script_path)) deployment.write(script_path, _template.generate_parent_interface()) script_name = generate_script_name(device.devname, vlan) script_path = generate_script_path(script_name) log.info('Writing {0}'.format(script_path)) deployment.write(script_path, _template.generate())
def add_key(self, gpgkey, local=False): key_name = "key.{0}".format(uuid.uuid4().hex) if local: with open(gpgkey, "r") as f: key_data = f.read() else: r = requests.get(gpgkey, stream=True) key_data = r.content destination = os.path.join(self.join_root(self.chroot_staging_dir), key_name) deployment.write(destination, key_data) log.info('Importing public key "{gpgkey}"'.format(gpgkey=gpgkey)) self.chroot('apt-key add %s' % os.path.join(self.chroot_staging_dir, key_name))
def add_repo(self, name, mirror, gpgkey): path_name = name.lower().replace(" ", "_") log.info('Creating repo file for "{name}"'.format(name=name)) sources_path = self.join_root( '/etc/yum.repos.d/{name}.repo'.format(name=path_name)) source = "[{lower_name}]\n" \ "name={formal_name}\n" \ "baseurl={mirror}\n" \ "enabled=1".format(lower_name=path_name, formal_name=name, mirror=mirror) if gpgkey: source += "\ngpgcheck=1" source += "\ngpgkey={gpgkey}".format(gpgkey=gpgkey) else: source += "\ngpgcheck=0" deployment.write(sources_path, source)
def update_etc_hosts(self): hostname = self.network_configuration.get('hostname') if not hostname: return networks = self.network_configuration.get('networks') if not networks: return for network in networks: default_route = network.get('default_route') if default_route: data = '%s %s\n' % (network.get('ip_address'), hostname) log.info('Adding %s to /etc/hosts' % data) deployment.write(self.join_root('/etc/hosts'), data, append=True) break
def write_resolvconf(self): network_configuration = self.press_configuration.get( 'networking', dict()) dns_config = network_configuration.get('dns') if not dns_config: log.warn('Static DNS configuration is missing') return header = '# Generated by Press v%s\n' % package.get_press_version() log.info('Writing resolv.conf') search_domains = dns_config.get('search') nameservers = dns_config.get('nameservers') if nameservers or search_domains: for domain in search_domains: header += 'search %s\n' % domain for nameserver in nameservers: header += 'nameserver %s\n' % nameserver deployment.write(self.join_root('/etc/resolv.conf'), header) else: log.warn('No nameservers or search domains are defined')
def insert_no_start_hack(self): log.info('Inserting NOSTART hack') deployment.write(self.join_root(self.__start_hack_path), self.__start_hack_script, mode=0o755)
def set_language(self, language): _locale = 'LANG=%s\nLC_MESSAGES=C\n' % language deployment.write(self.join_root('/etc/locale.conf'), _locale)
def copy_resolvconf(self): if not os.path.exists('/etc/resolv.conf'): log.warn('Host resolv.conf is missing') return deployment.write(self.join_root('/etc/resolv.conf'), deployment.read('/etc/resolv.conf'))
def authentication(self): configuration = self.press_configuration.get('auth') if not configuration: log.warn('No authentication configuration found') return users = configuration.get('users') if not users: log.warn('No users have been defined') for user in users: _u = users[user] if user != 'root': home_dir = _u.get('home', '/home/%s' % user) # Add user groups if 'group' in _u: self.__groupadd(_u['group'], _u.get('gid')) groups = _u.get('groups') if groups: for group in groups: self.__groupadd(group) # Add user if not util.auth.user_exists(user, self.root): log.info('Creating user: %s' % user) self.chroot( util.auth.format_useradd(user, _u.get('uid'), _u.get('group'), _u.get('groups'), home_dir, _u.get('shell'), _u.get('create_home', True), _u.get('system', False))) else: log.warn('Defined user, %s, already exists' % user) # Set password else: home_dir = _u.get('home', '/root') password = _u.get('password') if password: password_options = _u.get('password_options', dict()) is_encrypted = password_options.get('encrypted', True) log.info('Setting password for %s' % user) self.chroot( util.auth.format_change_password(user, password, is_encrypted)) else: log.warn('User %s has no password defined' % user) authorized_keys = _u.get('authorized_keys', list()) if authorized_keys: log.info('Adding authorized_keys for %s' % user) ssh_config_path = self.join_root('%s/.ssh' % home_dir) log.debug(ssh_config_path) if not os.path.exists(ssh_config_path): log.info('Creating .ssh directory: %s' % ssh_config_path) deployment.recursive_makedir(ssh_config_path, mode=0o700) if authorized_keys: public_keys_string = '\n'.join( authorized_keys).strip() + '\n' log.debug('Adding public key: %s' % public_keys_string) deployment.write(os.path.join(ssh_config_path, 'authorized_keys'), public_keys_string, append=True) # Create system groups groups = configuration.get('groups') if groups: for group in groups: _g = groups[group] or dict( ) # a group with no options will be null self.__groupadd(group, _g.get('gid'), _g.get('system'))
def write_route_script(self, routes): script_name = 'static-routes' script_path = self.join_root( os.path.join(self.sysconfig_scripts_path, script_name)) log.info('Writing %s' % script_path) deployment.write(script_path, self.generate_static_routes(routes))
def write_route_script(self, device, routes): script_name = 'route-%s' % device.devname script_path = self.join_root( os.path.join(self.network_scripts_path, script_name)) log.info('Writing %s' % script_path) deployment.write(script_path, networking.generate_routes(routes))