Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib/models
diff options
context:
space:
mode:
authorDaniel <blackrabbit256@gmail.com>2022-04-22 21:24:12 +1000
committerGitHub <noreply@github.com>2022-04-22 13:24:12 +0200
commit477b5b120e120766d789a691fce60cec843aff43 (patch)
treed2580a7510c2c3ffff694d6145ee1b93c1fd6ea6 /archinstall/lib/models
parent2529d6a5f59eb6a16f95bf9d1117a6033c527df9 (diff)
Support for multiple network interfaces (#1052)
* Support for multiple network interfaces * Fix mypy * Fix flake8 Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
Diffstat (limited to 'archinstall/lib/models')
-rw-r--r--archinstall/lib/models/network_configuration.py220
1 files changed, 127 insertions, 93 deletions
diff --git a/archinstall/lib/models/network_configuration.py b/archinstall/lib/models/network_configuration.py
index eb4c25ee..16136177 100644
--- a/archinstall/lib/models/network_configuration.py
+++ b/archinstall/lib/models/network_configuration.py
@@ -2,7 +2,12 @@ from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
-from typing import List, Optional, Dict
+from typing import List, Optional, Dict, Union, Any, TYPE_CHECKING
+
+from ..output import log
+
+if TYPE_CHECKING:
+ _: Any
class NicType(str, Enum):
@@ -14,11 +19,11 @@ class NicType(str, Enum):
@dataclass
class NetworkConfiguration:
type: NicType
- iface: str = None
- ip: str = None
+ iface: Optional[str] = None
+ ip: Optional[str] = None
dhcp: bool = True
- gateway: str = None
- dns: List[str] = None
+ gateway: Optional[str] = None
+ dns: Union[None, List[str]] = None
def __str__(self):
if self.is_iso():
@@ -37,63 +42,6 @@ class NetworkConfiguration:
def json(self):
return self.__dict__
- @classmethod
- def parse_arguments(cls, config: Union[str,Dict[str, str]]) -> Optional["NetworkConfiguration"]:
- from ... import log
-
- nic_type = config.get('type', None)
-
- if not nic_type:
- # old style definitions
- if isinstance(config,str): # is a ISO network
- return NetworkConfiguration(NicType.ISO)
- elif config.get('NetworkManager'): # is a network manager configuration
- return NetworkConfiguration(NicType.NM)
- elif 'ip' in config:
- return NetworkConfiguration(
- NicType.MANUAL,
- iface=config.get('nic', ''),
- ip=config.get('ip'),
- gateway=config.get('gateway', ''),
- dns=config.get('dns', []),
- dhcp=False
- )
- elif 'nic' in config:
- return NetworkConfiguration(
- NicType.MANUAL,
- iface=config.get('nic', ''),
- dhcp=True
- )
- else: # not recognized
- return None
-
- try:
- type = NicType(nic_type)
- except ValueError:
- options = [e.value for e in NicType]
- log(_('Unknown nic type: {}. Possible values are {}').format(nic_type, options), fg='red')
- exit(1)
-
- if type == NicType.MANUAL:
- if config.get('dhcp', False) or not any([config.get(v) for v in ['ip', 'gateway', 'dns']]):
- return NetworkConfiguration(type, iface=config.get('iface', ''))
-
- ip = config.get('ip', '')
- if not ip:
- log('Manual nic configuration with no auto DHCP requires an IP address', fg='red')
- exit(1)
-
- return NetworkConfiguration(
- type,
- iface=config.get('iface', ''),
- ip=ip,
- gateway=config.get('gateway', ''),
- dns=config.get('dns', []),
- dhcp=False
- )
- else:
- return NetworkConfiguration(type)
-
def is_iso(self) -> bool:
return self.type == NicType.ISO
@@ -103,37 +51,123 @@ class NetworkConfiguration:
def is_manual(self) -> bool:
return self.type == NicType.MANUAL
- def config_installer(self, installation: 'Installer'):
- # If user selected to copy the current ISO network configuration
- # Perform a copy of the config
- if self.is_iso():
- installation.copy_iso_network_config(enable_services=True) # Sources the ISO network configuration to the install medium.
- elif self.is_network_manager():
- installation.add_additional_packages("networkmanager")
- installation.enable_service('NetworkManager.service')
- # Otherwise, if a interface was selected, configure that interface
- elif self.is_manual():
- installation.configure_nic(self)
+
+class NetworkConfigurationHandler:
+ def __init__(self, config: Union[None, NetworkConfiguration, List[NetworkConfiguration]] = None):
+ self._configuration = config
+
+ @property
+ def configuration(self):
+ return self._configuration
+
+ def config_installer(self, installation: Any):
+ if self._configuration is None:
+ return
+
+ if isinstance(self._configuration, list):
+ for config in self._configuration:
+ installation.configure_nic(config)
+
installation.enable_service('systemd-networkd')
installation.enable_service('systemd-resolved')
-
- def get(self, key :str, default_value :Any = None) -> Any:
- result = self.__getitem__(key)
- if result is None:
- return default_value
- else:
- return result
-
- def __getitem__(self, key :str) -> Any:
- if key == 'type':
- return self.type
- elif key == 'iface':
- return self.iface
- elif key == 'gateway':
- return self.gateway
- elif key == 'dns':
- return self.dns
- elif key == 'dhcp':
- return self.dhcp
else:
- raise KeyError(f"key {key} not available at NetworkConfiguration")
+ # If user selected to copy the current ISO network configuration
+ # Perform a copy of the config
+ if self._configuration.is_iso():
+ installation.copy_iso_network_config(
+ enable_services=True) # Sources the ISO network configuration to the install medium.
+ elif self._configuration.is_network_manager():
+ installation.add_additional_packages("networkmanager")
+ installation.enable_service('NetworkManager.service')
+
+ def _backwards_compability_config(self, config: Union[str,Dict[str, str]]) -> Union[List[NetworkConfiguration], NetworkConfiguration, None]:
+ def get(config: Dict[str, str], key: str) -> List[str]:
+ if (value := config.get(key, None)) is not None:
+ return [value]
+ return []
+
+ if isinstance(config, str): # is a ISO network
+ return NetworkConfiguration(NicType.ISO)
+ elif config.get('NetworkManager'): # is a network manager configuration
+ return NetworkConfiguration(NicType.NM)
+ elif 'ip' in config:
+ return [NetworkConfiguration(
+ NicType.MANUAL,
+ iface=config.get('nic', ''),
+ ip=config.get('ip'),
+ gateway=config.get('gateway', ''),
+ dns=get(config, 'dns'),
+ dhcp=False
+ )]
+ elif 'nic' in config:
+ return [NetworkConfiguration(
+ NicType.MANUAL,
+ iface=config.get('nic', ''),
+ dhcp=True
+ )]
+ else: # not recognized
+ return None
+
+ def _parse_manual_config(self, config: Dict[str, Any]) -> Union[None, List[NetworkConfiguration]]:
+ manual_configs: List = config.get('config', [])
+
+ if not manual_configs:
+ return None
+
+ if not isinstance(manual_configs, list):
+ log(_('Manual configuration setting must be a list'))
+ exit(1)
+
+ configurations = []
+
+ for manual_config in manual_configs:
+ iface = manual_config.get('iface', None)
+
+ if iface is None:
+ log(_('No iface specified for manual configuration'))
+ exit(1)
+
+ if manual_config.get('dhcp', False) or not any([manual_config.get(v, '') for v in ['ip', 'gateway', 'dns']]):
+ configurations.append(
+ NetworkConfiguration(NicType.MANUAL, iface=iface)
+ )
+ else:
+ ip = config.get('ip', '')
+ if not ip:
+ log(_('Manual nic configuration with no auto DHCP requires an IP address'), fg='red')
+ exit(1)
+
+ configurations.append(
+ NetworkConfiguration(
+ NicType.MANUAL,
+ iface=iface,
+ ip=ip,
+ gateway=config.get('gateway', ''),
+ dns=config.get('dns', []),
+ dhcp=False
+ )
+ )
+
+ return configurations
+
+ def parse_arguments(self, config: Any):
+ nic_type = config.get('type', None)
+
+ if not nic_type:
+ # old style definitions
+ network_config = self._backwards_compability_config(config)
+ if network_config:
+ return network_config
+ return None
+
+ try:
+ type_ = NicType(nic_type)
+ except ValueError:
+ options = [e.value for e in NicType]
+ log(_('Unknown nic type: {}. Possible values are {}').format(nic_type, options), fg='red')
+ exit(1)
+
+ if type_ != NicType.MANUAL:
+ self._configuration = NetworkConfiguration(type_)
+ else: # manual configuration settings
+ self._configuration = self._parse_manual_config(config)