diff --git a/iocage/lib/Config/Jail/BaseConfig.py b/iocage/lib/Config/Jail/BaseConfig.py index 1cfe1be1..3fd685dd 100644 --- a/iocage/lib/Config/Jail/BaseConfig.py +++ b/iocage/lib/Config/Jail/BaseConfig.py @@ -664,9 +664,6 @@ def __dir__(self) -> typing.List[str]: if not prop.startswith("_"): properties.add(prop) - for key in self.data.keys(): - properties.add(key) - return list(properties) def keys(self) -> typing.KeysView[str]: @@ -696,8 +693,12 @@ def __len__(self) -> int: @property def all_properties(self) -> typing.List[str]: - """Return a list of all user configured settings.""" - return list(self._sorted_user_properties) + """Return a list of config object attributes.""" + properties: typing.Set[str] = set() + properties = properties.union(self.data.keys()) + special_properties = iocage.lib.Config.Jail.Properties.properties + properties = properties.union(special_properties) + return list(properties) @property def _sorted_user_properties(self) -> typing.List[str]: diff --git a/iocage/lib/Config/Jail/JailConfig.py b/iocage/lib/Config/Jail/JailConfig.py index 872e625e..a0cbc37f 100644 --- a/iocage/lib/Config/Jail/JailConfig.py +++ b/iocage/lib/Config/Jail/JailConfig.py @@ -92,6 +92,21 @@ def __setitem__( skip_on_error: bool=False ) -> None: """Set a configuration value.""" + # require the config property to be defined in the defaults + key_is_default = key in self.host.defaults.config.keys() + key_is_setter = f"_set_{key}" in dict.__dir__(self) + key_is_special = key in iocage.lib.Config.Jail.Properties.properties + + if (key_is_default or key_is_setter or key_is_special) is False: + err = iocage.lib.errors.UnknownJailConfigProperty( + jail=self.jail, + key=key, + logger=self.logger, + level=("warn" if skip_on_error else None) + ) + if skip_on_error is False: + raise err + BaseConfig.__setitem__( self, key=key, @@ -118,5 +133,6 @@ def all_properties(self) -> list: """Return a list of all config properties (default and custom).""" jail_config_properties = set(super().all_properties) default_config_properties = set( - self.host.default_config.all_properties) + self.host.default_config.all_properties + ) return sorted(list(jail_config_properties | default_config_properties)) diff --git a/iocage/lib/Config/Jail/Properties/__init__.py b/iocage/lib/Config/Jail/Properties/__init__.py index d8910f96..db90daab 100644 --- a/iocage/lib/Config/Jail/Properties/__init__.py +++ b/iocage/lib/Config/Jail/Properties/__init__.py @@ -34,6 +34,12 @@ 'iocage.lib.Config.Jail.Properties.Resolver.ResolverProp' ] +properties: typing.List[str] = [ + "ip4_addr", + "ip6_addr", + "interfaces", + "resolver" +] + ResourceLimit.properties def _get_class(property_name: str) -> Property: diff --git a/iocage/lib/errors.py b/iocage/lib/errors.py index d09cc80d..c178e0dd 100644 --- a/iocage/lib/errors.py +++ b/iocage/lib/errors.py @@ -388,6 +388,23 @@ def __init__( # noqa: T484 IocageException.__init__(self, msg, *args, **kwargs) +class UnknownJailConfigProperty(IocageException, KeyError): + """Raised when a unknown jail config property was used.""" + + def __init__( # noqa: T484 + self, + key: str, + jail: iocage.lib.Jail.JailGenerator, + *args, + **kwargs + ) -> None: + msg = ( + f"The config property '{key}' " + f"of jail '{jail.humanreadable_name}' is unknown." + ) + IocageException.__init__(self, msg, *args, **kwargs) + + # Backup