From 9d1c85b9c5ec09ea781f431ef5c729c76fa5482d Mon Sep 17 00:00:00 2001 From: Andrew Walker Date: Tue, 23 Apr 2024 05:39:51 -0700 Subject: [PATCH] Allow configuring ha_propagate default per-service There are many services on TrueNAS for which we should not propogate service changes to standby controller. Historically the default has been to always propagate these changes to the standby controller. This commit allows changing the default on a per-service basis, which reduces risk of introducing issues by forgetting to specify not to propagate to other controller. --- src/middlewared/middlewared/plugins/service.py | 16 +++++++++++++++- .../plugins/service_/services/base_interface.py | 1 + .../plugins/service_/services/cifs.py | 1 + .../plugins/service_/services/idmap.py | 1 + .../plugins/service_/services/mdns.py | 1 + .../middlewared/plugins/service_/services/nfs.py | 1 + .../plugins/service_/services/nslcd.py | 1 + .../plugins/service_/services/pseudo/misc.py | 1 + .../middlewared/plugins/service_/services/wsd.py | 1 + 9 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/middlewared/middlewared/plugins/service.py b/src/middlewared/middlewared/plugins/service.py index 113e3c69cc933..59323b5e2f4df 100644 --- a/src/middlewared/middlewared/plugins/service.py +++ b/src/middlewared/middlewared/plugins/service.py @@ -89,6 +89,12 @@ def result(task): async def service_extend(self, svc, ctx): return svc | ctx.get(svc['service'], {'state': 'UNKNOWN', 'pids': []}) + async def __normalize_service_options(self, svc_obj, options): + if options.get('ha_propagate') != None: + return options + + return options | {'ha_propagate': svc_obj.default_ha_propagate} + @filterable async def query(self, filters, options): """ @@ -149,7 +155,7 @@ async def do_update(self, app, id_or_name, data): Str('service'), Dict( 'service-control', - Bool('ha_propagate', default=True), + Bool('ha_propagate'), Bool('silent', default=True), register=True, ), @@ -166,6 +172,8 @@ async def start(self, app, service, options): """ service_object = await self.middleware.call('service.object', service) + options = await self.__normalize_service_options(service_object, options) + if not app_has_write_privilege_for_service(app, service): raise CallError(f'{service}: authenticated session lacks privilege to start service', errno.EPERM) @@ -249,6 +257,8 @@ async def stop(self, app, service, options): """ service_object = await self.middleware.call('service.object', service) + options = await self.__normalize_service_options(service_object, options) + if not app_has_write_privilege_for_service(app, service): raise CallError(f'{service}: authenticated session lacks privilege to stop service') @@ -285,6 +295,8 @@ async def restart(self, app, service, options): """ service_object = await self.middleware.call('service.object', service) + options = await self.__normalize_service_options(service_object, options) + if not app_has_write_privilege_for_service(app, service): raise CallError(f'{service}: authenticated session lacks privilege to restart service', errno.EPERM) @@ -347,6 +359,8 @@ async def reload(self, app, service, options): """ service_object = await self.middleware.call('service.object', service) + options = await self.__normalize_service_options(service_object, options) + if not app_has_write_privilege_for_service(app, service): raise CallError(f'{service}: authenticated session lacks privilege to restart service', errno.EPERM) diff --git a/src/middlewared/middlewared/plugins/service_/services/base_interface.py b/src/middlewared/middlewared/plugins/service_/services/base_interface.py index 68f99cb30377a..e7638ae016437 100644 --- a/src/middlewared/middlewared/plugins/service_/services/base_interface.py +++ b/src/middlewared/middlewared/plugins/service_/services/base_interface.py @@ -5,6 +5,7 @@ class ServiceInterface: restartable = False # Implements `restart` method instead of `stop` + `start` reloadable = False # Implements `reload` method deprecated = False # Alert if service is running + default_ha_propagate = True # If HA propagate service changes to other node def __init__(self, middleware): self.middleware = middleware diff --git a/src/middlewared/middlewared/plugins/service_/services/cifs.py b/src/middlewared/middlewared/plugins/service_/services/cifs.py index c886b77a313e3..4d661b5f5c330 100644 --- a/src/middlewared/middlewared/plugins/service_/services/cifs.py +++ b/src/middlewared/middlewared/plugins/service_/services/cifs.py @@ -7,6 +7,7 @@ class CIFSService(SimpleService): name = "cifs" reloadable = True + default_ha_propagate = False etc = ["smb"] diff --git a/src/middlewared/middlewared/plugins/service_/services/idmap.py b/src/middlewared/middlewared/plugins/service_/services/idmap.py index 9756909856c88..b83d2f498f51f 100644 --- a/src/middlewared/middlewared/plugins/service_/services/idmap.py +++ b/src/middlewared/middlewared/plugins/service_/services/idmap.py @@ -5,6 +5,7 @@ class IdmapService(SimpleService): name = "idmap" reloadable = True restartable = True + default_ha_propagate = False systemd_unit = "winbind" diff --git a/src/middlewared/middlewared/plugins/service_/services/mdns.py b/src/middlewared/middlewared/plugins/service_/services/mdns.py index e307a96717968..9e0e28635fa60 100644 --- a/src/middlewared/middlewared/plugins/service_/services/mdns.py +++ b/src/middlewared/middlewared/plugins/service_/services/mdns.py @@ -4,6 +4,7 @@ class MDNSService(SimpleService): name = "mdns" reloadable = True + default_ha_propagate = False etc = ["mdns"] diff --git a/src/middlewared/middlewared/plugins/service_/services/nfs.py b/src/middlewared/middlewared/plugins/service_/services/nfs.py index 7dbed671fadc9..407fe7b160932 100644 --- a/src/middlewared/middlewared/plugins/service_/services/nfs.py +++ b/src/middlewared/middlewared/plugins/service_/services/nfs.py @@ -6,6 +6,7 @@ class NFSService(SimpleService): name = "nfs" reloadable = True + default_ha_propagate = False etc = ["nfsd"] diff --git a/src/middlewared/middlewared/plugins/service_/services/nslcd.py b/src/middlewared/middlewared/plugins/service_/services/nslcd.py index 4a84bcbf53612..771fa12bd48cc 100644 --- a/src/middlewared/middlewared/plugins/service_/services/nslcd.py +++ b/src/middlewared/middlewared/plugins/service_/services/nslcd.py @@ -3,5 +3,6 @@ class NSSPamLdapdService(SimpleService): name = "nslcd" + default_ha_propagate = False systemd_unit = "nslcd" diff --git a/src/middlewared/middlewared/plugins/service_/services/pseudo/misc.py b/src/middlewared/middlewared/plugins/service_/services/pseudo/misc.py index 7c620a9852c2e..7dfa4a9fdd2a2 100644 --- a/src/middlewared/middlewared/plugins/service_/services/pseudo/misc.py +++ b/src/middlewared/middlewared/plugins/service_/services/pseudo/misc.py @@ -199,6 +199,7 @@ async def reload(self): class DSCacheService(PseudoServiceBase): name = "dscache" + default_ha_propagate = False async def start(self): await self.middleware.call('dscache.refresh') diff --git a/src/middlewared/middlewared/plugins/service_/services/wsd.py b/src/middlewared/middlewared/plugins/service_/services/wsd.py index 548c652e6f2be..e6880a5852d53 100644 --- a/src/middlewared/middlewared/plugins/service_/services/wsd.py +++ b/src/middlewared/middlewared/plugins/service_/services/wsd.py @@ -3,6 +3,7 @@ class WSDService(SimpleService): name = "wsdd" + default_ha_propagate = False etc = ["wsd"]