mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-02-11 08:23:49 +00:00
firewall: Reload firewalld so it works with newly installed services
firewalld has no problem retrieving service information for just-installed files, it only fails when adding/removing those services to zones. A reload is needed before those services can be used. Don't perform firewalld reload during setup.py or debian/postinst. Instead reload when firewalld throws an error that it does not know a service. This approach is more minimally intrusive and does not run reload operations when no services need to be loaded, during Debian package building etc. Closes: #376. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
b763391dfb
commit
55f4573e93
@ -142,6 +142,45 @@ def ignore_dbus_error(dbus_error=None, service_error=None):
|
||||
raise
|
||||
|
||||
|
||||
def parse_dbus_error(exception):
|
||||
"""Parse a GDBus error."""
|
||||
parts = exception.message.split(':')
|
||||
if parts[0] != 'GDBus.Error' or \
|
||||
parts[1] != 'org.fedoraproject.FirewallD1.Exception':
|
||||
return None
|
||||
|
||||
return parts[2].strip()
|
||||
|
||||
|
||||
def reload():
|
||||
"""Reload firewalld."""
|
||||
logger.info('Reloading firewalld')
|
||||
with ignore_dbus_error(dbus_error='ServiceUnknown'):
|
||||
proxy = _get_dbus_proxy(_FIREWALLD_OBJECT, _FIREWALLD_INTERFACE)
|
||||
proxy.reload()
|
||||
|
||||
|
||||
def try_with_reload(operation):
|
||||
"""Try an operation and retry after firewalld reload.
|
||||
|
||||
When a service file is newly installed into /usr/lib/firewalld/services,
|
||||
it's information can be immediately queried but the service can't be
|
||||
added/removed from a zone. A firewalld reload is necessary. So, try an
|
||||
operation and if it fails with INVALID_SERVICE error, reload firewalld and
|
||||
try again.
|
||||
|
||||
"""
|
||||
try:
|
||||
operation()
|
||||
except glib.Error as exception:
|
||||
error = parse_dbus_error(exception)
|
||||
if error != 'INVALID_SERVICE':
|
||||
raise
|
||||
|
||||
reload()
|
||||
operation()
|
||||
|
||||
|
||||
def get_enabled_status():
|
||||
"""Return whether firewall is enabled"""
|
||||
output = _run(['get-status'], superuser=True)
|
||||
|
||||
@ -51,7 +51,10 @@ class Firewall(app.FollowerComponent):
|
||||
def enable(self):
|
||||
"""Open firewall ports when the component is enabled."""
|
||||
super().enable()
|
||||
firewall.try_with_reload(self._enable)
|
||||
|
||||
def _enable(self):
|
||||
"""Open firewall ports."""
|
||||
internal_enabled_ports = firewall.get_enabled_services(zone='internal')
|
||||
external_enabled_ports = firewall.get_enabled_services(zone='external')
|
||||
|
||||
@ -66,7 +69,10 @@ class Firewall(app.FollowerComponent):
|
||||
def disable(self):
|
||||
"""Close firewall ports when the component is disabled."""
|
||||
super().disable()
|
||||
firewall.try_with_reload(self._disable)
|
||||
|
||||
def _disable(self):
|
||||
"""Close firewall ports."""
|
||||
internal_enabled_ports = firewall.get_enabled_services(zone='internal')
|
||||
external_enabled_ports = firewall.get_enabled_services(zone='external')
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user