from __future__ import annotations from dataclasses import dataclass, field from enum import Enum from typing import List, Optional, Dict, Any, TYPE_CHECKING, Tuple from ..profile import ProfileConfiguration if TYPE_CHECKING: _: Any class NicType(Enum): ISO = "iso" NM = "nm" MANUAL = "manual" def display_msg(self) -> str: match self: case NicType.ISO: return str(_('Copy ISO network configuration to installation')) case NicType.NM: return str(_('Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)')) case NicType.MANUAL: return str(_('Manual configuration')) @dataclass class Nic: iface: Optional[str] = None ip: Optional[str] = None dhcp: bool = True gateway: Optional[str] = None dns: List[str] = field(default_factory=list) def table_data(self) -> Dict[str, Any]: return { 'iface': self.iface if self.iface else '', 'ip': self.ip if self.ip else '', 'dhcp': self.dhcp, 'gateway': self.gateway if self.gateway else '', 'dns': self.dns } def json(self) -> Dict[str, Any]: return { 'iface': self.iface, 'ip': self.ip, 'dhcp': self.dhcp, 'gateway': self.gateway, 'dns': self.dns } @staticmethod def parse_arg(arg: Dict[str, Any]) -> Nic: return Nic( iface=arg.get('iface', None), ip=arg.get('ip', None), dhcp=arg.get('dhcp', True), gateway=arg.get('gateway', None), dns=arg.get('dns', []), ) def as_systemd_config(self) -> str: match: List[Tuple[str, str]] = [] network: List[Tuple[str, str]] = [] if self.iface: match.append(('Name', self.iface)) if self.dhcp: network.append(('DHCP', 'yes')) else: if self.ip: network.append(('Address', self.ip)) if self.gateway: network.append(('Gateway', self.gateway)) for dns in self.dns: network.append(('DNS', dns)) config = {'Match': match, 'Network': network} config_str = '' for top, entries in config.items(): config_str += f'[{top}]\n' config_str += '\n'.join([f'{k}={v}' for k, v in entries]) config_str += '\n\n' return config_str @dataclass class NetworkConfiguration: type: NicType nics: List[Nic] = field(default_factory=list) def json(self) -> Dict[str, Any]: config: Dict[str, Any] = {'type': self.type.value} if self.nics: config['nics'] = [n.json() for n in self.nics] return config @staticmethod def parse_arg(config: Dict[str, Any]) -> Optional[NetworkConfiguration]: nic_type = config.get('type', None) if not nic_type: return None match NicType(nic_type): case NicType.ISO: return NetworkConfiguration(NicType.ISO) case NicType.NM: return NetworkConfiguration(NicType.NM) case NicType.MANUAL: nics_arg = config.get('nics', []) if nics_arg: nics = [Nic.parse_arg(n) for n in nics_arg] return NetworkConfiguration(NicType.MANUAL, nics) return None def install_network_config( self, installation: Any, profile_config: Optional[ProfileConfiguration] = None ): match self.type: case NicType.ISO: installation.copy_iso_network_config( enable_services=True # Sources the ISO network configuration to the install medium. ) case NicType.NM: installation.add_additional_packages(["networkmanager"]) if profile_config and profile_config.profile: if profile_config.profile.is_desktop_type_profile(): installation.add_additional_packages(["network-manager-applet"]) installation.enable_service('NetworkManager.service') case NicType.MANUAL: for nic in self.nics: installation.configure_nic(nic) installation.enable_service('systemd-networkd') installation.enable_service('systemd-resolved')