From e373f3928991af051a459336b1bba05f14083101 Mon Sep 17 00:00:00 2001 From: William Brown Date: Feb 15 2019 00:46:32 +0000 Subject: Ticket 50208 - make instances mark off based on dse.ldif not sysconfig Bug Description: As sysconfig isn't cross platform compatible, and there are some potential plans to remove it from our systemd files, we need to make sure that lib389 can handle this file not being present in new installs. Fix Description: Thankfully, we have a file we can always guarantee exists: dse.ldif. This makes /etc/dirsrv/slapd-instance the only fixed location in the server now, all other locations can be "moved". This patch: * Fixes a large number of removal regressions * Add comments and warnings throughout remove and setup to help prevent future regresions * Create no longer creates /etc/sysconfig/dirsrv-instance * Create makes dse.ldif *first* as it's the marker location * Remove works when there is no marker file (but will remove if it exists) * Listing now ignores /etc/sysconfig, and reads dse.ldif instead with a follow up https://pagure.io/389-ds-base/issue/50207 to parse data from this file for offline https://pagure.io/389-ds-base/issue/50208 Author: William Brown Review by: spichugi, abbra (Thanks) --- diff --git a/Makefile.am b/Makefile.am index 617ab45..ec65c1d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -647,7 +647,6 @@ dist_noinst_DATA = \ $(srcdir)/LICENSE.* \ $(srcdir)/VERSION.sh \ $(srcdir)/wrappers/*.in \ - $(srcdir)/wrappers/systemd.template.sysconfig \ $(srcdir)/dirsrvtests \ $(srcdir)/src/lib389/setup.py \ $(srcdir)/src/lib389 @@ -900,14 +899,9 @@ init_SCRIPTS = wrappers/$(PACKAGE_NAME) \ endif endif -if SYSTEMD -initconfig_DATA = ldap/admin/src/$(PACKAGE_NAME) \ - wrappers/$(PACKAGE_NAME).systemd -else if INITDDIR initconfig_DATA = ldap/admin/src/$(PACKAGE_NAME) endif -endif inf_DATA = ldap/admin/src/slapd.inf \ ldap/admin/src/scripts/dscreate.map \ @@ -2342,10 +2336,6 @@ endif fi; \ $(fixupcmd) $$service_template > $@ -%/$(PACKAGE_NAME).systemd: %/systemd.template.sysconfig - if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@) ; fi - $(fixupcmd) $^ > $@ - %/$(systemdgroupname): %/systemd.group.in if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@) ; fi $(fixupcmd) $^ > $@ diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in index 7e76be6..ff0160e 100644 --- a/rpm/389-ds-base.spec.in +++ b/rpm/389-ds-base.spec.in @@ -599,8 +599,6 @@ exit 0 %config(noreplace)%{_sysconfdir}/%{pkgname}/config/slapd-collations.conf %config(noreplace)%{_sysconfdir}/%{pkgname}/config/certmap.conf %config(noreplace)%{_sysconfdir}/%{pkgname}/config/template-initconfig -%config(noreplace)%{_sysconfdir}/sysconfig/%{pkgname} -%config(noreplace)%{_sysconfdir}/sysconfig/%{pkgname}.systemd %{_datadir}/%{pkgname} %exclude %{_datadir}/%{pkgname}/script-templates %exclude %{_datadir}/%{pkgname}/updates diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py index 46e8b9d..5e91dbc 100644 --- a/src/lib389/lib389/__init__.py +++ b/src/lib389/lib389/__init__.py @@ -601,10 +601,7 @@ class DirSrv(SimpleLDAPObject, object): def list(self, all=False, serverid=None): """ Returns a list dictionary. For a created instance that is on the - local file system (e.g. /etc/dirsrv/slapd-*), it exists - a file describing its properties - (environment): /etc/sysconfig/dirsrv- or - $HOME/.dirsrv/dirsv- + local file system (e.g. /etc/dirsrv/slapd-*/dse.ldif). A dictionary is created with the following properties: CONF_SERVER_DIR CONF_SERVERBIN_DIR @@ -628,16 +625,8 @@ class DirSrv(SimpleLDAPObject, object): @raise IOError - if the file containing the properties is not foundable or readable """ - def test_and_set(prop, propname, variable, value): - ''' - If variable is 'propname' it adds to - 'prop' dictionary the propname:value - ''' - if variable == propname: - prop[propname] = value - return 1 - return 0 + ### This inner function WILL BE REMOVED soon. def _parse_configfile(filename=None, serverid=None): ''' This method read 'filename' and build a dictionary with @@ -653,46 +642,24 @@ class DirSrv(SimpleLDAPObject, object): prop = {} prop[CONF_SERVER_ID] = serverid prop[SER_SERVERID_PROP] = serverid - myfile = open(filename, 'r') - for line in myfile: - # retrieve the value in line:: - # = [';' export ] - - # skip comment lines - if line.startswith('#'): - continue - - # skip lines without assignment - if '=' not in line: - continue - value = line.split(';', 1)[0] - - # skip lines without assignment - if '=' not in value: - continue - variable = value.split('=', 1)[0] - value = value.split('=', 1)[1] - value = value.strip(' \t\n') - for property in (CONF_SERVER_DIR, - CONF_SERVERBIN_DIR, - CONF_CONFIG_DIR, - CONF_INST_DIR, - CONF_RUN_DIR, - CONF_DS_ROOT, - CONF_PRODUCT_NAME): - if test_and_set(prop, property, variable, value): - break - - # Now, we have passed the sysconfig environment file. - # read in and parse the dse.ldif to determine our SER_* values. - # probably should use path join? - dsefile = '%s/dse.ldif' % prop[CONF_CONFIG_DIR] - if os.path.exists(dsefile): - ldifconn = LDIFConn(dsefile) - configentry = ldifconn.get(DN_CONFIG) - for key in args_dse_keys: - prop[key] = configentry.getValue(args_dse_keys[key]) + inst_paths = Paths(serverid) + + # WARNING: This is not correct, but is a stop gap until: https://pagure.io/389-ds-base/issue/50207 + # Once that's done, this will "just work". Saying this, the whole prop dictionary + # concept is fundamentally broken, and we should be using ds_paths anyway. + prop[CONF_SERVER_DIR] = inst_paths.lib_dir + prop[CONF_SERVERBIN_DIR] = inst_paths.sbin_dir + prop[CONF_CONFIG_DIR] = inst_paths.config_dir + prop[CONF_INST_DIR] = inst_paths.inst_dir + prop[CONF_RUN_DIR] = inst_paths.run_dir + prop[CONF_DS_ROOT] = '' + prop[CONF_PRODUCT_NAME] = 'slapd' + + ldifconn = LDIFConn(filename) + configentry = ldifconn.get(DN_CONFIG) + for key in args_dse_keys: + prop[key] = configentry.getValue(args_dse_keys[key]) # SER_HOST (host) nsslapd-localhost # SER_PORT (port) nsslapd-port # SER_SECURE_PORT (sslport) nsslapd-secureport @@ -702,73 +669,19 @@ class DirSrv(SimpleLDAPObject, object): # nsslapd-defaultnamingcontext # SER_USER_ID (userid) nsslapd-localuser # SER_SERVERID_PROP (serverid) Already have this - # SER_GROUP_ID (groupid) ??? + # SER_GROUP_ID (groupid) # SER_DEPLOYED_DIR (prefix) Already provided to for # discovery - # SER_BACKUP_INST_DIR (backupdir) nsslapd-bakdir <<-- maybe? + # SER_BACKUP_INST_DIR (backupdir) nsslapd-bakdir # We need to convert these two to int # because other routines get confused if we don't for intkey in [SER_PORT, SER_SECURE_PORT]: - if prop[intkey] is not None: + if intkey in prop and prop[intkey] is not None: prop[intkey] = int(prop[intkey]) return prop + ### end _parse_configfile - def search_dir(instances, pattern, stop_value=None): - ''' - It search all the files matching pattern. - It there is not stop_value, it adds the properties found in - each file to the 'instances' - Else it searches the specific stop_value (instance's serverid) - to add only its properties in the 'instances' - - @param instances - list of dictionary containing the instances - properties - @param pattern - pattern to find the files containing the - properties - @param stop_value - serverid value if we are looking only for - one specific instance - - @return True or False - If stop_value is None it returns False. - If stop_value is specified, it returns - True if it added the property - dictionary in instances. Or False if it - did not find it. - ''' - added = False - for instance in glob.glob(pattern): - serverid = os.path.basename(instance)[len(DEFAULT_ENV_HEAD):] - - # skip removed instance and admin server entry - if '.removed' in serverid or 'dirsrv-admin' in instance: - continue - - # it is found, store its properties in the list - if stop_value: - if stop_value == serverid: - instances.append(_parse_configfile(instance, serverid)) - added = True - break - else: - # this is not the searched value, continue - continue - else: - # we are not looking for a specific value, just add it - instances.append(_parse_configfile(instance, serverid)) - - return added - - # Retrieves all instances under '/etc/sysconfig' and '/etc/dirsrv' - - # Instances/Environment are - # - # file: /etc/sysconfig/dirsrv- (env) - # inst: /etc/dirsrv/slapd- (conf) - # - # or - # - # file: $HOME/.dirsrv/dirsrv- (env) - # inst: /etc/dirsrv/slapd- (conf) - # + # Retrieves all instances under '/etc/dirsrv' # Don't need a default value now since it's set in init. if serverid is None and hasattr(self, 'serverid'): @@ -776,68 +689,35 @@ class DirSrv(SimpleLDAPObject, object): elif serverid is not None: serverid = serverid.replace('slapd-', '') - # first identify the directories we will scan - sysconfig_head = self.ds_paths.initconfig_dir - privconfig_head = os.path.expanduser(os.path.join('~', ENV_LOCAL_DIR)) - if not os.path.isdir(sysconfig_head): - privconfig_head = None - self.log.debug("dir (sys) : %s", sysconfig_head) - if privconfig_head: - self.log.debug("dir (priv): %s", privconfig_head) - # list of the found instances instances = [] # now prepare the list of instances properties if not all: + dse_ldif = os.path.join(self.ds_paths.config_dir, 'dse.ldif') # easy case we just look for the current instance - - # we have two location to retrieve the self.serverid - # privconfig_head and sysconfig_head - - # first check the private repository - if privconfig_head: - pattern = "%s*" % os.path.join(privconfig_head, - DEFAULT_ENV_HEAD) - found = search_dir(instances, pattern, serverid) - if len(instances) > 0: - self.log.debug("List from %s", privconfig_head) - for instance in instances: - self.log.debug("list instance %r\n", instance) - if found: - assert len(instances) == 1 - else: - assert len(instances) == 0 + if os.path.exists(dse_ldif): + # It's real + # Now just populate that instance dict (soon to be changed ...) + instances.append(_parse_configfile(dse_ldif, serverid)) else: - found = False - - # second, if not already found, search the system repository - if not found: - pattern = "%s*" % os.path.join(sysconfig_head, - DEFAULT_ENV_HEAD) - search_dir(instances, pattern, serverid) - if len(instances) > 0: - self.log.debug("List from %s", privconfig_head) - for instance in instances: - self.log.debug("list instance %r\n", instance) + # it's not + self.log.debug("list instance not found: %s\n", serverid) else: - # all instances must be retrieved - if privconfig_head: - pattern = "%s*" % os.path.join(privconfig_head, - DEFAULT_ENV_HEAD) - search_dir(instances, pattern) - if len(instances) > 0: - self.log.debug("List from %s", privconfig_head) - for instance in instances: - self.log.debug("list instance %r\n", instance) - - pattern = "%s*" % os.path.join(sysconfig_head, DEFAULT_ENV_HEAD) - search_dir(instances, pattern) - if len(instances) > 0: - self.log.debug("List from %s", privconfig_head) - for instance in instances: - self.log.debug("list instance %r\n", instance) + # For each dir that starts with slapd-* + potential_inst = [ + f for f + in os.listdir(self.ds_paths.sysconf_dir) + if os.path.isdir(f) and f.startswith('slapd-')] + # check it has dse.ldif + for pi in potential_inst: + pi_dse_ldif = os.path.join(potential_inst, 'dse.ldif') + # Takes /etc/dirsrv/slapd-instance -> slapd-instance -> instance + pi_name = pi.split('/')[-1].split('-')[-1] + # parse + append + if os.path.exists(pi_dse_ldif): + instances.append(_parse_configfile(pi_dse_ldif, pi_name)) return instances diff --git a/src/lib389/lib389/instance/remove.py b/src/lib389/lib389/instance/remove.py index 2d8ce99..9e7f3ee 100644 --- a/src/lib389/lib389/instance/remove.py +++ b/src/lib389/lib389/instance/remove.py @@ -9,12 +9,30 @@ import os import shutil import subprocess -from lib389.utils import selinux_label_port +from lib389.nss_ssl import NssSsl +from lib389.utils import selinux_label_port, assert_c + + +######################## WARNING ############################# +# DO NOT CHANGE THIS FILE OR ITS CONTENTS WITHOUT READING +# ALL OF THE COMMENTS FIRST. THERE ARE VERY DELICATE +# AND DETAILED INTERACTIONS OF COMPONENTS IN THIS FILE. +# +# IF IN DOUBT CONTACT WILLIAM BROWN def remove_ds_instance(dirsrv, force=False): """ - This will delete the instance as it is define. This must be a local instance. + This will delete the instance as it is define. This must be a local instance. This is + designed to raise exceptions quickly and often if *any* error is hit. However, this can + be run repeatedly, and only when the instance is truely removed, will this program fail + to run further. + + :param dirsrv: A directory server instance + :type dirsrv: DirSrv + :param force: A psycological aid, for people who think force means do something, harder. Does + literally nothing in this program because state machines are a thing. + :type force: bool """ _log = dirsrv.log.getChild('remove_ds') _log.debug("Removing instance %s" % dirsrv.serverid) @@ -38,30 +56,22 @@ def remove_ds_instance(dirsrv, force=False): # remove_paths['run_dir'] = dirsrv.ds_paths.run_dir remove_paths['tmpfiles_d'] = dirsrv.ds_paths.tmpfiles_d + "/dirsrv-" + dirsrv.serverid + ".conf" remove_paths['inst_dir'] = dirsrv.ds_paths.inst_dir + remove_paths['etc_sysconfig'] = "%s/sysconfig/dirsrv-%s" % (dirsrv.ds_paths.sysconf_dir, dirsrv.serverid) - marker_path = "%s/sysconfig/dirsrv-%s" % (dirsrv.ds_paths.sysconf_dir, dirsrv.serverid) + # These are handled in a special way. etc_dirsrv_path = os.path.join(dirsrv.ds_paths.sysconf_dir, 'dirsrv/') - ssca_path = os.path.join(etc_dirsrv_path, 'ssca/') + dse_ldif_path = os.path.join(etc_dirsrv_path, 'dse.ldif') # Check the marker exists. If it *does not* warn about this, and say that to # force removal you should touch this file. - _log.debug("Checking for instance marker at %s" % marker_path) - assert os.path.exists(marker_path) - - # Move the config_dir to config_dir.removed - config_dir = dirsrv.ds_paths.config_dir - config_dir_rm = "{}.removed".format(config_dir) - - if os.path.exists(config_dir_rm): - _log.debug("Removing previously existed %s" % config_dir_rm) - shutil.rmtree(config_dir_rm) + _log.debug("Checking for instance marker at %s" % dse_ldif_path) + if not os.path.exists(dse_ldif_path): + _log.info("Instance configuration not found, no action will be taken") + _log.info("If you want us to cleanup anyway, recreate '%s'" % dse_ldif_path) + return - _log.debug("Copying %s to %s" % (config_dir, config_dir_rm)) - try: - shutil.copytree(config_dir, config_dir_rm) - except FileNotFoundError: - pass + ### ANY NEW REMOVAL ACTION MUST BE BELOW THIS LINE!!! # Remove these paths: # for path in ('backup_dir', 'cert_dir', 'config_dir', 'db_dir', @@ -73,36 +83,53 @@ def remove_ds_instance(dirsrv, force=False): # Remove parent (/var/lib/dirsrv/slapd-INST) shutil.rmtree(remove_paths['db_dir'].replace('db', ''), ignore_errors=True) - # Finally remove the sysconfig marker. - os.remove(marker_path) - _log.debug("Removing %s" % marker_path) + # We can not assume we have systemd ... + if dirsrv.ds_paths.with_systemd: + # Remove the systemd symlink + _log.debug("Removing the systemd symlink") + subprocess.check_call(["systemctl", "disable", "dirsrv@{}".format(dirsrv.serverid)]) - # Remove the systemd symlink - _log.debug("Removing the systemd symlink") - subprocess.check_call(["systemctl", "disable", "dirsrv@{}".format(dirsrv.serverid)]) - - # Remove selinux port label - _log.debug("Removing the port label") - try: + # Nor can we assume we have selinux. Try docker sometime ;) + if dirsrv.ds_paths.with_selinux: + # Remove selinux port label + _log.debug("Removing the port labels") selinux_label_port(dirsrv.port, remove_label=True) - except ValueError as e: - if force: - pass - else: - _log.error(str(e)) - raise e - if dirsrv.sslport is not None: - selinux_label_port(dirsrv.sslport, remove_label=True) + # This is a compatability with ancient installs, all modern install have tls port + if dirsrv.sslport is not None: + selinux_label_port(dirsrv.sslport, remove_label=True) - # If this was the last instance, remove the ssca directory + # If this was the last instance, remove the ssca instance insts = dirsrv.list(all=True) if len(insts) == 0: - # Remove /etc/dirsrv/ssca - try: - shutil.rmtree(ssca_path) - except FileNotFoundError: - pass + ssca = NssSsl(dbpath=dirsrv.get_ssca_dir()) + ssca.remove_db() + + ### ANY NEW REMOVAL ACTIONS MUST BE ABOVE THIS LINE!!! + + # Finally means FINALLY, the last thing, the LAST LAST thing. By doing this absolutely + # last, it means that we can have any failure above, and continue to re-run until resolved + # because this instance marker (dse.ldif) continues to exist! + # Move the config_dir to config_dir.removed + config_dir = dirsrv.ds_paths.config_dir + config_dir_rm = "{}.removed".format(config_dir) + + if os.path.exists(config_dir_rm): + _log.debug("Removing previously existed %s" % config_dir_rm) + shutil.rmtree(config_dir_rm) + + assert_c(not os.path.exists(config_dir_rm)) + + # That's it, everything before this MUST have suceeded, so now we can move the + # config dir (containing dse.ldif, the marker) out of the way. + _log.debug("Moving %s to %s" % (config_dir, config_dir_rm)) + try: + shutil.move(config_dir, config_dir_rm) + except FileNotFoundError: + pass + + # DO NOT PUT ANY CODE BELOW THIS COMMENT BECAUSE THAT WOULD VIOLATE THE ASSERTIONS OF THE + # ABOVE CODE. # Done! _log.debug("Complete") diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py index 423a1db..b2e19e3 100644 --- a/src/lib389/lib389/instance/setup.py +++ b/src/lib389/lib389/instance/setup.py @@ -654,37 +654,72 @@ class SetupDs(object): """ Actually install the Ds from the dicts provided. - You should never call this directly, as it bypasses assert_cions. + You should never call this directly, as it bypasses assertions. """ - # register the instance to /etc/sysconfig - # We do this first so that we can trick remove-ds.pl if needed. - # There may be a way to create this from template like the dse.ldif ... - initconfig = "" - with open("%s/dirsrv/config/template-initconfig" % slapd['sysconf_dir']) as template_init: - for line in template_init.readlines(): - initconfig += line.replace('{{', '{', 1).replace('}}', '}', 1).replace('-', '_') + ######################## WARNING ############################# + # DO NOT CHANGE THIS FUNCTION OR ITS CONTENTS WITHOUT READING + # ALL OF THE COMMENTS FIRST. THERE ARE VERY DELICATE + # AND DETAILED INTERACTIONS OF COMPONENTS IN THIS FUNCTION. + # + # IF IN DOUBT CONTACT WILLIAM BROWN + + + ### This first section is about creating the *minimal* required paths and config to get + # directory server to start: After this, we then perform all configuration as online + # changes from after this point. + + # Create dse.ldif with a temporary root password. + # This is done first, because instances are found for removal and listing by detecting + # the present of their dse.ldif!!!! + # The template is in slapd['data_dir']/dirsrv/data/template-dse.ldif + # Variables are done with %KEY%. + self.log.debug("ACTION: Creating dse.ldif") try: - # /etc/sysconfig - os.makedirs("%s" % slapd['initconfig_dir'], mode=0o770) - except FileExistsError: + os.umask(0o007) # For parent dirs that get created -> sets 770 for perms + os.makedirs(slapd['config_dir'], mode=0o770) + except OSError: pass - sysconfig_filename = "%s/dirsrv-%s" % (slapd['initconfig_dir'], slapd['instance_name']) - with open(sysconfig_filename, 'w') as f: - f.write(initconfig.format( - SERVER_DIR=slapd['lib_dir'], - SERVERBIN_DIR=slapd['sbin_dir'], - CONFIG_DIR=slapd['config_dir'], - INST_DIR=slapd['inst_dir'], - RUN_DIR=slapd['run_dir'], - DS_ROOT='', - PRODUCT_NAME='slapd', + + # Get suffix for some plugin defaults (if possible) + # annoyingly for legacy compat backend takes TWO key types + # and we have to now deal with that .... + # + # Create ds_suffix here else it won't be in scope .... + ds_suffix = '' + if len(backends) > 0: + ds_suffix = normalizeDN(backends[0]['nsslapd-suffix']) + + dse = "" + with open(os.path.join(slapd['data_dir'], 'dirsrv', 'data', 'template-dse.ldif')) as template_dse: + for line in template_dse.readlines(): + dse += line.replace('%', '{', 1).replace('%', '}', 1) + + with open(os.path.join(slapd['config_dir'], 'dse.ldif'), 'w') as file_dse: + file_dse.write(dse.format( + schema_dir=slapd['schema_dir'], + lock_dir=slapd['lock_dir'], + tmp_dir=slapd['tmp_dir'], + cert_dir=slapd['cert_dir'], + ldif_dir=slapd['ldif_dir'], + bak_dir=slapd['backup_dir'], + run_dir=slapd['run_dir'], + inst_dir=slapd['inst_dir'], + log_dir=slapd['log_dir'], + fqdn=general['full_machine_name'], + ds_port=slapd['port'], + ds_user=slapd['user'], + rootdn=slapd['root_dn'], + ds_passwd=self._secure_password, # We set our own password here, so we can connect and mod. + # This is because we never know the users input root password as they can validily give + # us a *hashed* input. + ds_suffix=ds_suffix, + config_dir=slapd['config_dir'], + db_dir=slapd['db_dir'], )) - os.chmod(sysconfig_filename, 0o440) - os.chown(sysconfig_filename, slapd['user_uid'], slapd['group_gid']) # Create all the needed paths # we should only need to make bak_dir, cert_dir, config_dir, db_dir, ldif_dir, lock_dir, log_dir, run_dir? - for path in ('backup_dir', 'cert_dir', 'config_dir', 'db_dir', 'ldif_dir', 'lock_dir', 'log_dir', 'run_dir'): + for path in ('backup_dir', 'cert_dir', 'db_dir', 'ldif_dir', 'lock_dir', 'log_dir', 'run_dir'): self.log.debug("ACTION: creating %s", slapd[path]) try: os.umask(0o007) # For parent dirs that get created -> sets 770 for perms @@ -745,51 +780,12 @@ class SetupDs(object): # Bind sockets to our type? - # Get suffix for some plugin defaults (if possible) - # annoyingly for legacy compat backend takes TWO key types - # and we have to now deal with that .... - # - # Create ds_suffix here else it won't be in scope .... - ds_suffix = '' - if len(backends) > 0: - ds_suffix = normalizeDN(backends[0]['nsslapd-suffix']) # Create certdb in sysconfidir self.log.debug("ACTION: Creating certificate database is %s", slapd['cert_dir']) - # Create dse.ldif with a temporary root password. - # The template is in slapd['data_dir']/dirsrv/data/template-dse.ldif - # Variables are done with %KEY%. - # You could cheat and read it in, do a replace of % to { and } then use format? - self.log.debug("ACTION: Creating dse.ldif") - dse = "" - with open(os.path.join(slapd['data_dir'], 'dirsrv', 'data', 'template-dse.ldif')) as template_dse: - for line in template_dse.readlines(): - dse += line.replace('%', '{', 1).replace('%', '}', 1) - - with open(os.path.join(slapd['config_dir'], 'dse.ldif'), 'w') as file_dse: - file_dse.write(dse.format( - schema_dir=slapd['schema_dir'], - lock_dir=slapd['lock_dir'], - tmp_dir=slapd['tmp_dir'], - cert_dir=slapd['cert_dir'], - ldif_dir=slapd['ldif_dir'], - bak_dir=slapd['backup_dir'], - run_dir=slapd['run_dir'], - inst_dir=slapd['inst_dir'], - log_dir=slapd['log_dir'], - fqdn=general['full_machine_name'], - ds_port=slapd['port'], - ds_user=slapd['user'], - rootdn=slapd['root_dn'], - # ds_passwd=slapd['root_password'], - ds_passwd=self._secure_password, # We set our own password here, so we can connect and mod. - ds_suffix=ds_suffix, - config_dir=slapd['config_dir'], - db_dir=slapd['db_dir'], - )) - - # open the connection to the instance. + # BELOWE THIS LINE - all actions are now ONLINE changes to the directory server. + # if it all possible, ALWAYS ADD NEW INSTALLER CHANGES AS ONLINE ACTIONS. # Should I move this import? I think this prevents some recursion from lib389 import DirSrv diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in index 3c1d368..4d1c2c7 100644 --- a/wrappers/systemd.template.service.in +++ b/wrappers/systemd.template.service.in @@ -23,22 +23,48 @@ Type=notify NotifyAccess=all TimeoutStartSec=0 TimeoutStopSec=600 -EnvironmentFile=@initconfigdir@/@package_name@ -EnvironmentFile=@initconfigdir@/@package_name@-%i +EnvironmentFile=-@initconfigdir@/@package_name@ +EnvironmentFile=-@initconfigdir@/@package_name@-%i PIDFile=@localstatedir@/run/@package_name@/slapd-%i.pid ExecStartPre=@libexecdir@/ds_systemd_ask_password_acl @instconfigdir@/slapd-%i/dse.ldif ExecStart=@sbindir@/ns-slapd -D @instconfigdir@/slapd-%i -i @localstatedir@/run/@package_name@/slapd-%i.pid +#### To change any of these values or directives, you should use a drop in file +# such as: /etc/systemd/system/dirsrv@.d/custom.conf + +# These are from man systemd.exec and man systemd.resource-control + +# This controls the resources to the direct child of systemd, in +# this case ns-slapd. Because we are type notify we recieve these +# limits correctly. + +# This controls the number of file handles avaliable. File handles +# correlate to sockets for the process, and our access to logs and +# databases. +LimitNOFILE=16384 + +# You can limit the memory in the cgroup with these, and ns-slapd +# will account for them in it's autotuning. +# Memory account may be controlled by DefaultMemoryAccounting= in systemd-system.conf +# MemoryAccounting=true +# MemoryLimit=bytes + +# Limits on the size of coredump that may be produced by the process. It's not +# specified how this interacts with coredumpd. +# 0 means not to produce cores. +# This value is 64G +LimitCORE=68719476736 + +# Limit number of processes (threads) we may spawn. We don't advise you change +# this as DS will autodetect your threads / cpus and adjust as needed. +# LimitNPROC= + # Hardening options: # PrivateDevices=true # ProtectSystem=true # ProtectHome=true # PrivateTmp=true -# if you need to set other directives e.g. LimitNOFILE=8192 -# set them in this file -.include @initconfigdir@/@package_name@.systemd - [Install] WantedBy=multi-user.target diff --git a/wrappers/systemd.template.sysconfig b/wrappers/systemd.template.sysconfig deleted file mode 100644 index 903876b..0000000 --- a/wrappers/systemd.template.sysconfig +++ /dev/null @@ -1,29 +0,0 @@ -[Service] -# These are from man systemd.exec and man systemd.resource-control - -# This controls the resources to the direct child of systemd, in -# this case ns-slapd. Because we are type notify we recieve these -# limits correctly. - -# This controls the number of file handles avaliable. File handles -# correlate to sockets for the process, and our access to logs and -# databases. -LimitNOFILE=16384 - -# You can limit the memory in the cgroup with these, and ns-slapd -# will account for them in it's autotuning. -# Memory account may be controlled by DefaultMemoryAccounting= in systemd-system.conf -# MemoryAccounting=true -# MemoryLimit=bytes - -# Limits on the size of coredump that may be produced by the process. It's not -# specified how this interacts with coredumpd. -# 0 means not to produce cores. -# This value is 64G -LimitCORE=68719476736 - -# Limit number of processes (threads) we may spawn. We don't advise you change -# this as DS will autodetect your threads / cpus and adjust as needed. -# LimitNPROC= - - diff --git a/wrappers/systemd.template.xsan.service.in b/wrappers/systemd.template.xsan.service.in index 1a4d7dc..541392f 100644 --- a/wrappers/systemd.template.xsan.service.in +++ b/wrappers/systemd.template.xsan.service.in @@ -35,15 +35,42 @@ LimitCORE=infinity ExecStartPre=@libexecdir@/ds_systemd_ask_password_acl @instconfigdir@/slapd-%i/dse.ldif ExecStart=@sbindir@/ns-slapd -D @instconfigdir@/slapd-%i -i @localstatedir@/run/@package_name@/slapd-%i.pid +#### To change any of these values or directives, you should use a drop in file +# such as: /etc/systemd/system/dirsrv@.d/custom.conf + +# These are from man systemd.exec and man systemd.resource-control + +# This controls the resources to the direct child of systemd, in +# this case ns-slapd. Because we are type notify we recieve these +# limits correctly. + +# This controls the number of file handles avaliable. File handles +# correlate to sockets for the process, and our access to logs and +# databases. +LimitNOFILE=16384 + +# You can limit the memory in the cgroup with these, and ns-slapd +# will account for them in it's autotuning. +# Memory account may be controlled by DefaultMemoryAccounting= in systemd-system.conf +# MemoryAccounting=true +# MemoryLimit=bytes + +# Limits on the size of coredump that may be produced by the process. It's not +# specified how this interacts with coredumpd. +# 0 means not to produce cores. +# This value is 64G +LimitCORE=68719476736 + +# Limit number of processes (threads) we may spawn. We don't advise you change +# this as DS will autodetect your threads / cpus and adjust as needed. +# LimitNPROC= + # Hardening options: # PrivateDevices=true # ProtectSystem=true # ProtectHome=true # PrivateTmp=true -# if you need to set other directives e.g. LimitNOFILE=8192 -# set them in this file -.include @initconfigdir@/@package_name@.systemd [Install] WantedBy=multi-user.target