[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50499 - Fix npm audit issues
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new 095b122 Issue 50499 - Fix npm audit issues
095b122 is described below
commit 095b122fb3cbdce6794b90c64fc8c65129b75423
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri Dec 6 16:12:20 2019 -0500
Issue 50499 - Fix npm audit issues
---
src/cockpit/389-console/package-lock.json | 46 ++++++++++++++++++-------------
src/cockpit/389-console/package.json | 2 +-
2 files changed, 28 insertions(+), 20 deletions(-)
diff --git a/src/cockpit/389-console/package-lock.json b/src/cockpit/389-console/package-lock.json
index f61e489..a280954 100644
--- a/src/cockpit/389-console/package-lock.json
+++ b/src/cockpit/389-console/package-lock.json
@@ -6053,9 +6053,9 @@
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
},
"handlebars": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.2.tgz",
- "integrity": "sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg==",
+ "version": "4.5.3",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
+ "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
"requires": {
"neo-async": "^2.6.0",
"optimist": "^0.6.1",
@@ -6063,26 +6063,10 @@
"uglify-js": "^3.1.4"
},
"dependencies": {
- "commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "optional": true
- },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- },
- "uglify-js": {
- "version": "3.6.9",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.9.tgz",
- "integrity": "sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw==",
- "optional": true,
- "requires": {
- "commander": "~2.20.3",
- "source-map": "~0.6.1"
- }
}
}
},
@@ -10154,6 +10138,30 @@
}
}
},
+ "uglify-js": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.1.tgz",
+ "integrity": "sha512-pnOF7jY82wdIhATVn87uUY/FHU+MDUdPLkmGFvGoclQmeu229eTkbG5gjGGBi3R7UuYYSEeYXY/TTY5j2aym2g==",
+ "optional": true,
+ "requires": {
+ "commander": "~2.20.3",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "optional": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "optional": true
+ }
+ }
+ },
"uglifyjs-webpack-plugin": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plu...",
diff --git a/src/cockpit/389-console/package.json b/src/cockpit/389-console/package.json
index fb24496..adf8dff 100644
--- a/src/cockpit/389-console/package.json
+++ b/src/cockpit/389-console/package.json
@@ -52,7 +52,7 @@
"@patternfly/react-core": "^3.58.1",
"bootstrap": "^4.3.1",
"file-loader": "^4.1.0",
- "handlebars": "^4.5.2",
+ "handlebars": "^4.5.3",
"node-sass": "4.12.0",
"patternfly": "^3.59.3",
"patternfly-react": "^2.34.3",
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50753 - Dumping the changelog to a file doesn't work
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new 876ce73 Issue 50753 - Dumping the changelog to a file doesn't work
876ce73 is described below
commit 876ce73739f2b6c62786087f7fafa1990770f0f4
Author: Simon Pichugin <spichugi(a)redhat.com>
AuthorDate: Tue Dec 3 23:27:51 2019 +0100
Issue 50753 - Dumping the changelog to a file doesn't work
Description: Pass the logging object to the code branch where
-i CHANGELOG_FILE is not specified, so -o OUTPUT_FILE works
correctly in that case too.
https://pagure.io/389-ds-base/issue/50753
Reviewed by: mreynolds (Thanks!)
---
src/lib389/lib389/cli_conf/replication.py | 3 ++-
src/lib389/lib389/replica.py | 11 +++++++----
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py
index 58bbd13..47f530a 100644
--- a/src/lib389/lib389/cli_conf/replication.py
+++ b/src/lib389/lib389/cli_conf/replication.py
@@ -1000,7 +1000,8 @@ def dump_cl(inst, basedn, log, args):
if not args.changelog_ldif:
replicas.process_and_dump_changelog(replica_roots=args.replica_roots,
csn_only=args.csn_only,
- preserve_ldif_done=args.preserve_ldif_done)
+ preserve_ldif_done=args.preserve_ldif_done,
+ log=log)
else:
try:
assert os.path.exists(args.changelog_ldif)
diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
index 9b84d8f..9ba97ff 100644
--- a/src/lib389/lib389/replica.py
+++ b/src/lib389/lib389/replica.py
@@ -1648,7 +1648,7 @@ class Replicas(DSLdapObjects):
replica._populate_suffix()
return replica
- def process_and_dump_changelog(self, replica_roots=[], csn_only=False, preserve_ldif_done=False):
+ def process_and_dump_changelog(self, replica_roots=[], csn_only=False, preserve_ldif_done=False, log=None):
"""Dump and decode Directory Server replication change log
:param replica_roots: Replica suffixes that need to be processed
@@ -1657,6 +1657,9 @@ class Replicas(DSLdapObjects):
:type csn_only: bool
"""
+ if log is None:
+ log = self._log
+
repl_roots = []
try:
cl = Changelog5(self._instance)
@@ -1677,7 +1680,7 @@ class Replicas(DSLdapObjects):
got_ldif = False
current_time = time.time()
replica = self.get(repl_root)
- self._log.info(f"# Replica Root: {repl_root}")
+ log.info(f"# Replica Root: {repl_root}")
replica.replace("nsDS5Task", 'CL2LDIF')
# Decode the dumped changelog
@@ -1687,7 +1690,7 @@ class Replicas(DSLdapObjects):
if os.path.getmtime(file_path) < current_time:
continue
got_ldif = True
- cl_ldif = ChangelogLDIF(file_path, self._log)
+ cl_ldif = ChangelogLDIF(file_path, log)
if csn_only:
cl_ldif.grep_csn()
@@ -1700,7 +1703,7 @@ class Replicas(DSLdapObjects):
os.remove(file_path)
if not got_ldif:
- self._log.info("LDIF file: Not found")
+ log.info("LDIF file: Not found")
class BootstrapReplicationManager(DSLdapObject):
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50734 - lib389 creates non-SSCA cert DBs with misleading README.txt
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new ae87936 Issue 50734 - lib389 creates non-SSCA cert DBs with misleading README.txt
ae87936 is described below
commit ae87936e479e7fda4ee19ede56f45214f82c14a5
Author: Matus Honek <mhonek(a)redhat.com>
AuthorDate: Thu Aug 8 11:31:34 2019 +0200
Issue 50734 - lib389 creates non-SSCA cert DBs with misleading README.txt
Bug Description:
`NssSsl` always creates `README.txt` which describes the purpose of SSCA, even
when creating only an instance-specific certificate database.
Fix Description:
Create the README.txt only when creating cert DB for a specified DS instance.
Fixes https://pagure.io/389-ds-base/issue/50734
Author: Matus Honek <mhonek(a)redhat.com>
Review by: Mark, William (thanks!)
---
src/lib389/lib389/instance/setup.py | 2 +-
src/lib389/lib389/nss_ssl.py | 13 +++++++------
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py
index bb0ff32..073c7c7 100644
--- a/src/lib389/lib389/instance/setup.py
+++ b/src/lib389/lib389/instance/setup.py
@@ -822,7 +822,7 @@ class SetupDs(object):
assert_c(ds_instance.exists(), "Instance failed to install, does not exist when expected")
# Create a certificate database.
- tlsdb = NssSsl(dbpath=slapd['cert_dir'])
+ tlsdb = NssSsl(dirsrv=ds_instance, dbpath=slapd['cert_dir'])
if not tlsdb._db_exists():
tlsdb.reinit()
diff --git a/src/lib389/lib389/nss_ssl.py b/src/lib389/lib389/nss_ssl.py
index 9801274..587adcd 100644
--- a/src/lib389/lib389/nss_ssl.py
+++ b/src/lib389/lib389/nss_ssl.py
@@ -151,18 +151,19 @@ class NssSsl(object):
except FileExistsError:
pass
- # Write a README to let people know what this is
- readme_file = '%s/%s' % (self._certdb, 'README.txt')
- if not os.path.exists(readme_file):
- with open(readme_file, 'w') as f:
- f.write("""
+ if self.dirsrv is None:
+ # Write a README to let people know what this is
+ readme_file = '%s/%s' % (self._certdb, 'README.txt')
+ if not os.path.exists(readme_file):
+ with open(readme_file, 'w') as f:
+ f.write("""
SSCA - Simple Self-Signed Certificate Authority
This is part of the 389 Directory Server project's lib389 toolkit. It
creates a simple, standalone certificate authority for testing and
development purposes. It's suitable for evaluation and testing purposes
only.
- """)
+ """)
# In the future we may add the needed option to avoid writing the pin
# files.
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months
[389-ds-base] branch 389-ds-base-1.3.10 updated: Ticket 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.3.10
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.10 by this push:
new e415129 Ticket 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid
e415129 is described below
commit e415129d2ae44cc6096134795f5802c164366077
Author: Thierry Bordaz <tbordaz(a)redhat.com>
AuthorDate: Mon Nov 25 10:59:44 2019 +0100
Ticket 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid
Bug Description:
If config of retroCL trimming contains invalid value for trim-interval
and/or maxage, then the trimming initialization is skipped.
In such case the trimming structures are not allocated and if they
are freed at shutdown it triggers a crash
Fix Description:
When trimming mechanism is stopped (at shutdown) check that
it was successfully initialized before freeing the structs
https://pagure.io/389-ds-base/issue/50736
Reviewed by: Mark Reynolds
Platforms tested: F30
Flag Day: no
Doc impact: no
---
.../tests/suites/replication/changelog_test.py | 185 +++++++++++++++++++++
ldap/servers/plugins/retrocl/retrocl_trim.c | 17 +-
2 files changed, 196 insertions(+), 6 deletions(-)
diff --git a/dirsrvtests/tests/suites/replication/changelog_test.py b/dirsrvtests/tests/suites/replication/changelog_test.py
index 0b6b886..0d3e85b 100755
--- a/dirsrvtests/tests/suites/replication/changelog_test.py
+++ b/dirsrvtests/tests/suites/replication/changelog_test.py
@@ -16,6 +16,12 @@ from lib389.replica import Replicas
from lib389.idm.user import UserAccounts
from lib389.topologies import topology_m2 as topo
from lib389._constants import *
+from lib389.plugins import RetroChangelogPlugin
+from lib389.dseldif import DSEldif
+from lib389.tasks import *
+from lib389.utils import *
+
+pytestmark = pytest.mark.tier1
TEST_ENTRY_NAME = 'replusr'
NEW_RDN_NAME = 'cl5usr'
@@ -235,6 +241,185 @@ def test_verify_changelog_offline_backup(topo):
_check_changelog_ldif(topo, changelog_ldif)
+(a)pytest.mark.ds47669
+def test_changelog_maxage(topo, changelog_init):
+ """Check nsslapd-changelog max age values
+
+ :id: d284ff27-03b2-412c-ac74-ac4f2d2fae3b
+ :setup: Replication with two master, change nsslapd-changelogdir to
+ '/var/lib/dirsrv/slapd-master1/changelog' and
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
+ :steps:
+ 1. Set nsslapd-changelogmaxage in cn=changelog5,cn=config to values - '12345','10s','30M','12h','2D','4w'
+ 2. Set nsslapd-changelogmaxage in cn=changelog5,cn=config to values - '-123','xyz'
+
+ :expectedresults:
+ 1. Operation should be successful
+ 2. Operation should be unsuccessful
+ """
+ log.info('1. Test nsslapd-changelogmaxage in cn=changelog5,cn=config')
+
+ # bind as directory manager
+ topo.ms["master1"].log.info("Bind as %s" % DN_DM)
+ topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
+
+ add_and_check(topo, CHANGELOG, MAXAGE, '12345', True)
+ add_and_check(topo, CHANGELOG, MAXAGE, '10s', True)
+ add_and_check(topo, CHANGELOG, MAXAGE, '30M', True)
+ add_and_check(topo, CHANGELOG, MAXAGE, '12h', True)
+ add_and_check(topo, CHANGELOG, MAXAGE, '2D', True)
+ add_and_check(topo, CHANGELOG, MAXAGE, '4w', True)
+ add_and_check(topo, CHANGELOG, MAXAGE, '-123', False)
+ add_and_check(topo, CHANGELOG, MAXAGE, 'xyz', False)
+
+
+(a)pytest.mark.ds47669
+def test_ticket47669_changelog_triminterval(topo, changelog_init):
+ """Check nsslapd-changelog triminterval values
+
+ :id: 8f850c37-7e7c-49dd-a4e0-9344638616d6
+ :setup: Replication with two master, change nsslapd-changelogdir to
+ '/var/lib/dirsrv/slapd-master1/changelog' and
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
+ :steps:
+ 1. Set nsslapd-changelogtrim-interval in cn=changelog5,cn=config to values -
+ '12345','10s','30M','12h','2D','4w'
+ 2. Set nsslapd-changelogtrim-interval in cn=changelog5,cn=config to values - '-123','xyz'
+
+ :expectedresults:
+ 1. Operation should be successful
+ 2. Operation should be unsuccessful
+ """
+ log.info('2. Test nsslapd-changelogtrim-interval in cn=changelog5,cn=config')
+
+ # bind as directory manager
+ topo.ms["master1"].log.info("Bind as %s" % DN_DM)
+ topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
+
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '12345', True)
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '10s', True)
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '30M', True)
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '12h', True)
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '2D', True)
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '4w', True)
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '-123', False)
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, 'xyz', False)
+
+
+(a)pytest.mark.ds47669
+def test_changelog_compactdbinterval(topo, changelog_init):
+ """Check nsslapd-changelog compactdbinterval values
+
+ :id: 0f4b3118-9dfa-4c2a-945c-72847b42a48c
+ :setup: Replication with two master, change nsslapd-changelogdir to
+ '/var/lib/dirsrv/slapd-master1/changelog' and
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
+ :steps:
+ 1. Set nsslapd-changelogcompactdb-interval in cn=changelog5,cn=config to values -
+ '12345','10s','30M','12h','2D','4w'
+ 2. Set nsslapd-changelogcompactdb-interval in cn=changelog5,cn=config to values -
+ '-123','xyz'
+
+ :expectedresults:
+ 1. Operation should be successful
+ 2. Operation should be unsuccessful
+ """
+ log.info('3. Test nsslapd-changelogcompactdb-interval in cn=changelog5,cn=config')
+
+ # bind as directory manager
+ topo.ms["master1"].log.info("Bind as %s" % DN_DM)
+ topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
+
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '12345', True)
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '10s', True)
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '30M', True)
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '12h', True)
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '2D', True)
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '4w', True)
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '-123', False)
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, 'xyz', False)
+
+
+(a)pytest.mark.ds47669
+def test_retrochangelog_maxage(topo, changelog_init):
+ """Check nsslapd-retrochangelog max age values
+
+ :id: 0cb84d81-3e86-4dbf-84a2-66aefd8281db
+ :setup: Replication with two master, change nsslapd-changelogdir to
+ '/var/lib/dirsrv/slapd-master1/changelog' and
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
+ :steps:
+ 1. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to values -
+ '12345','10s','30M','12h','2D','4w'
+ 2. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to values -
+ '-123','xyz'
+
+ :expectedresults:
+ 1. Operation should be successful
+ 2. Operation should be unsuccessful
+ """
+ log.info('4. Test nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config')
+
+ # bind as directory manager
+ topo.ms["master1"].log.info("Bind as %s" % DN_DM)
+ topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
+
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '12345', True)
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '10s', True)
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '30M', True)
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '12h', True)
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '2D', True)
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '4w', True)
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '-123', False)
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, 'xyz', False)
+
+ topo.ms["master1"].log.info("ticket47669 was successfully verified.")
+
+(a)pytest.mark.ds50736
+def test_retrochangelog_trimming_crash(topo, changelog_init):
+ """Check that when retroCL nsslapd-retrocthangelog contains invalid
+ value, then the instance does not crash at shutdown
+
+ :id: 5d9bd7ca-e9bf-4be9-8fc8-902aa5513052
+ :setup: Replication with two master, change nsslapd-changelogdir to
+ '/var/lib/dirsrv/slapd-master1/changelog' and
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
+ :steps:
+ 1. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to value '-1'
+ This value is invalid. To disable retroCL trimming it should be set to 0
+ 2. Do several restart
+ 3. check there is no 'Detected Disorderly Shutdown' message (crash)
+ 4. restore valid value for nsslapd-changelogmaxage '1w'
+
+ :expectedresults:
+ 1. Operation should be successful
+ 2. Operation should be successful
+ 3. Operation should be successful
+ 4. Operation should be successful
+ """
+ log.info('1. Test retroCL trimming crash in cn=Retro Changelog Plugin,cn=plugins,cn=config')
+
+ # set the nsslapd-changelogmaxage directly on dse.ldif
+ # because the set value is invalid
+ topo.ms["master1"].log.info("ticket50736 start verification")
+ topo.ms["master1"].stop()
+ retroPlugin = RetroChangelogPlugin(topo.ms["master1"])
+ dse_ldif = DSEldif(topo.ms["master1"])
+ dse_ldif.replace(retroPlugin.dn, 'nsslapd-changelogmaxage', '-1')
+ topo.ms["master1"].start()
+
+ # The crash should be systematic, but just in case do several restart
+ # with a delay to let all plugin init
+ for i in range(5):
+ time.sleep(1)
+ topo.ms["master1"].stop()
+ topo.ms["master1"].start()
+
+ assert not topo.ms["master1"].detectDisorderlyShutdown()
+
+ topo.ms["master1"].log.info("ticket 50736 was successfully verified.")
+
+
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
index a465349..0378eb7 100644
--- a/ldap/servers/plugins/retrocl/retrocl_trim.c
+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
@@ -481,11 +481,16 @@ retrocl_init_trimming(void)
void
retrocl_stop_trimming(void)
{
- retrocl_trimming = 0;
- if (retrocl_trim_ctx) {
- slapi_eq_cancel(retrocl_trim_ctx);
- retrocl_trim_ctx = NULL;
+ if (retrocl_trimming) {
+ /* RetroCL trimming config was valid and trimming struct allocated
+ * Let's free them
+ */
+ retrocl_trimming = 0;
+ if (retrocl_trim_ctx) {
+ slapi_eq_cancel(retrocl_trim_ctx);
+ retrocl_trim_ctx = NULL;
+ }
+ PR_DestroyLock(ts.ts_s_trim_mutex);
+ ts.ts_s_trim_mutex = NULL;
}
- PR_DestroyLock(ts.ts_s_trim_mutex);
- ts.ts_s_trim_mutex = NULL;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months
[389-ds-base] branch 389-ds-base-1.4.0 updated: Ticket 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.0
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.0 by this push:
new 881a53f Ticket 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid
881a53f is described below
commit 881a53f2552416e3b1476f54c6b75fb9926f1099
Author: Thierry Bordaz <tbordaz(a)redhat.com>
AuthorDate: Mon Nov 25 10:59:44 2019 +0100
Ticket 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid
Bug Description:
If config of retroCL trimming contains invalid value for trim-interval
and/or maxage, then the trimming initialization is skipped.
In such case the trimming structures are not allocated and if they
are freed at shutdown it triggers a crash
Fix Description:
When trimming mechanism is stopped (at shutdown) check that
it was successfully initialized before freeing the structs
https://pagure.io/389-ds-base/issue/50736
Reviewed by: Mark Reynolds
Platforms tested: F30
Flag Day: no
Doc impact: no
---
.../tests/suites/replication/changelog_test.py | 47 ++++++++++++++++++++++
ldap/servers/plugins/retrocl/retrocl_trim.c | 17 +++++---
2 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/dirsrvtests/tests/suites/replication/changelog_test.py b/dirsrvtests/tests/suites/replication/changelog_test.py
index b4ae7c6..211adec 100755
--- a/dirsrvtests/tests/suites/replication/changelog_test.py
+++ b/dirsrvtests/tests/suites/replication/changelog_test.py
@@ -16,6 +16,8 @@ from lib389.replica import Replicas
from lib389.idm.user import UserAccounts
from lib389.topologies import topology_m2 as topo
from lib389._constants import *
+from lib389.plugins import RetroChangelogPlugin
+from lib389.dseldif import DSEldif
from lib389.tasks import *
from lib389.utils import *
@@ -450,6 +452,51 @@ def test_retrochangelog_maxage(topo, changelog_init):
topo.ms["master1"].log.info("ticket47669 was successfully verified.")
+(a)pytest.mark.ds50736
+def test_retrochangelog_trimming_crash(topo, changelog_init):
+ """Check that when retroCL nsslapd-retrocthangelog contains invalid
+ value, then the instance does not crash at shutdown
+
+ :id: 5d9bd7ca-e9bf-4be9-8fc8-902aa5513052
+ :setup: Replication with two master, change nsslapd-changelogdir to
+ '/var/lib/dirsrv/slapd-master1/changelog' and
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
+ :steps:
+ 1. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to value '-1'
+ This value is invalid. To disable retroCL trimming it should be set to 0
+ 2. Do several restart
+ 3. check there is no 'Detected Disorderly Shutdown' message (crash)
+ 4. restore valid value for nsslapd-changelogmaxage '1w'
+
+ :expectedresults:
+ 1. Operation should be successful
+ 2. Operation should be successful
+ 3. Operation should be successful
+ 4. Operation should be successful
+ """
+ log.info('1. Test retroCL trimming crash in cn=Retro Changelog Plugin,cn=plugins,cn=config')
+
+ # set the nsslapd-changelogmaxage directly on dse.ldif
+ # because the set value is invalid
+ topo.ms["master1"].log.info("ticket50736 start verification")
+ topo.ms["master1"].stop()
+ retroPlugin = RetroChangelogPlugin(topo.ms["master1"])
+ dse_ldif = DSEldif(topo.ms["master1"])
+ dse_ldif.replace(retroPlugin.dn, 'nsslapd-changelogmaxage', '-1')
+ topo.ms["master1"].start()
+
+ # The crash should be systematic, but just in case do several restart
+ # with a delay to let all plugin init
+ for i in range(5):
+ time.sleep(1)
+ topo.ms["master1"].stop()
+ topo.ms["master1"].start()
+
+ assert not topo.ms["master1"].detectDisorderlyShutdown()
+
+ topo.ms["master1"].log.info("ticket 50736 was successfully verified.")
+
+
if __name__ == '__main__':
# Run isolated
diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
index a465349..0378eb7 100644
--- a/ldap/servers/plugins/retrocl/retrocl_trim.c
+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
@@ -481,11 +481,16 @@ retrocl_init_trimming(void)
void
retrocl_stop_trimming(void)
{
- retrocl_trimming = 0;
- if (retrocl_trim_ctx) {
- slapi_eq_cancel(retrocl_trim_ctx);
- retrocl_trim_ctx = NULL;
+ if (retrocl_trimming) {
+ /* RetroCL trimming config was valid and trimming struct allocated
+ * Let's free them
+ */
+ retrocl_trimming = 0;
+ if (retrocl_trim_ctx) {
+ slapi_eq_cancel(retrocl_trim_ctx);
+ retrocl_trim_ctx = NULL;
+ }
+ PR_DestroyLock(ts.ts_s_trim_mutex);
+ ts.ts_s_trim_mutex = NULL;
}
- PR_DestroyLock(ts.ts_s_trim_mutex);
- ts.ts_s_trim_mutex = NULL;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Ticket 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new 7e39425 Ticket 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid
7e39425 is described below
commit 7e39425a9d71f62caeecc76da3186758b70a63cd
Author: Thierry Bordaz <tbordaz(a)redhat.com>
AuthorDate: Mon Nov 25 10:59:44 2019 +0100
Ticket 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid
Bug Description:
If config of retroCL trimming contains invalid value for trim-interval
and/or maxage, then the trimming initialization is skipped.
In such case the trimming structures are not allocated and if they
are freed at shutdown it triggers a crash
Fix Description:
When trimming mechanism is stopped (at shutdown) check that
it was successfully initialized before freeing the structs
https://pagure.io/389-ds-base/issue/50736
Reviewed by: Mark Reynolds
Platforms tested: F30
Flag Day: no
Doc impact: no
---
.../tests/suites/replication/changelog_test.py | 47 ++++++++++++++++++++++
ldap/servers/plugins/retrocl/retrocl_trim.c | 17 +++++---
2 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/dirsrvtests/tests/suites/replication/changelog_test.py b/dirsrvtests/tests/suites/replication/changelog_test.py
index a257e02..e648478 100644
--- a/dirsrvtests/tests/suites/replication/changelog_test.py
+++ b/dirsrvtests/tests/suites/replication/changelog_test.py
@@ -16,6 +16,8 @@ from lib389.replica import Replicas
from lib389.idm.user import UserAccounts
from lib389.topologies import topology_m2 as topo
from lib389._constants import *
+from lib389.plugins import RetroChangelogPlugin
+from lib389.dseldif import DSEldif
from lib389.tasks import *
from lib389.utils import *
@@ -452,6 +454,51 @@ def test_retrochangelog_maxage(topo, changelog_init):
topo.ms["master1"].log.info("ticket47669 was successfully verified.")
+(a)pytest.mark.ds50736
+def test_retrochangelog_trimming_crash(topo, changelog_init):
+ """Check that when retroCL nsslapd-retrocthangelog contains invalid
+ value, then the instance does not crash at shutdown
+
+ :id: 5d9bd7ca-e9bf-4be9-8fc8-902aa5513052
+ :setup: Replication with two master, change nsslapd-changelogdir to
+ '/var/lib/dirsrv/slapd-master1/changelog' and
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
+ :steps:
+ 1. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to value '-1'
+ This value is invalid. To disable retroCL trimming it should be set to 0
+ 2. Do several restart
+ 3. check there is no 'Detected Disorderly Shutdown' message (crash)
+ 4. restore valid value for nsslapd-changelogmaxage '1w'
+
+ :expectedresults:
+ 1. Operation should be successful
+ 2. Operation should be successful
+ 3. Operation should be successful
+ 4. Operation should be successful
+ """
+ log.info('1. Test retroCL trimming crash in cn=Retro Changelog Plugin,cn=plugins,cn=config')
+
+ # set the nsslapd-changelogmaxage directly on dse.ldif
+ # because the set value is invalid
+ topo.ms["master1"].log.info("ticket50736 start verification")
+ topo.ms["master1"].stop()
+ retroPlugin = RetroChangelogPlugin(topo.ms["master1"])
+ dse_ldif = DSEldif(topo.ms["master1"])
+ dse_ldif.replace(retroPlugin.dn, 'nsslapd-changelogmaxage', '-1')
+ topo.ms["master1"].start()
+
+ # The crash should be systematic, but just in case do several restart
+ # with a delay to let all plugin init
+ for i in range(5):
+ time.sleep(1)
+ topo.ms["master1"].stop()
+ topo.ms["master1"].start()
+
+ assert not topo.ms["master1"].detectDisorderlyShutdown()
+
+ topo.ms["master1"].log.info("ticket 50736 was successfully verified.")
+
+
if __name__ == '__main__':
# Run isolated
diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
index a465349..0378eb7 100644
--- a/ldap/servers/plugins/retrocl/retrocl_trim.c
+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
@@ -481,11 +481,16 @@ retrocl_init_trimming(void)
void
retrocl_stop_trimming(void)
{
- retrocl_trimming = 0;
- if (retrocl_trim_ctx) {
- slapi_eq_cancel(retrocl_trim_ctx);
- retrocl_trim_ctx = NULL;
+ if (retrocl_trimming) {
+ /* RetroCL trimming config was valid and trimming struct allocated
+ * Let's free them
+ */
+ retrocl_trimming = 0;
+ if (retrocl_trim_ctx) {
+ slapi_eq_cancel(retrocl_trim_ctx);
+ retrocl_trim_ctx = NULL;
+ }
+ PR_DestroyLock(ts.ts_s_trim_mutex);
+ ts.ts_s_trim_mutex = NULL;
}
- PR_DestroyLock(ts.ts_s_trim_mutex);
- ts.ts_s_trim_mutex = NULL;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50439 - Update docker integration for Fedora
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new 6200037 Issue 50439 - Update docker integration for Fedora
6200037 is described below
commit 6200037e876bc33d0311cff49d3588602330eb5e
Author: Matus Honek <mhonek(a)redhat.com>
AuthorDate: Tue Nov 19 19:40:32 2019 +0100
Issue 50439 - Update docker integration for Fedora
Bug Description:
Fedora Dockerfile has been unbuildable/broken for sometime.
Fix Description:
Update the Dockerfile to make it work while mimicking ideas from the
SUSE's counterpart.
Additionaly, changing wget to curl in rpm.mk since wget does not seem to
be available in the minimal image.
Relates https://pagure.io/389-ds-base/issue/50439
Relates https://pagure.io/389-ds-base/pull-request/50441#comment-88961
Author: Matus Honek <mhonek(a)redhat.com>
Review by: firstyear, vashirov (thanks!)
---
docker.mk | 3 ++
docker/389-ds-fedora/Dockerfile | 63 ++++++++++++++++++++++-------------------
rpm.mk | 2 +-
3 files changed, 38 insertions(+), 30 deletions(-)
diff --git a/docker.mk b/docker.mk
index 4f07cec..0f42b0b 100644
--- a/docker.mk
+++ b/docker.mk
@@ -1,3 +1,6 @@
suse:
docker build -t 389-ds-suse:master -f docker/389-ds-suse/Dockerfile .
+
+fedora:
+ docker build -t 389-ds-fedora:master -f docker/389-ds-fedora/Dockerfile .
diff --git a/docker/389-ds-fedora/Dockerfile b/docker/389-ds-fedora/Dockerfile
index d61df8c..ba901e1 100644
--- a/docker/389-ds-fedora/Dockerfile
+++ b/docker/389-ds-fedora/Dockerfile
@@ -6,41 +6,46 @@
# See LICENSE for details.
# --- END COPYRIGHT BLOCK ---
-FROM fedora:26
+FROM fedora:latest
MAINTAINER 389-devel(a)lists.fedoraproject.org
-EXPOSE 389 636
-ENV container docker
-
-RUN mkdir -p /usr/local/src
-WORKDIR /usr/local/src
+EXPOSE 3389 3636
ADD ./ /usr/local/src/389-ds-base
-
-RUN dnf upgrade -y && \
- dnf install --setopt=strict=False -y \
- @buildsys-build rpm-build make bzip2 git rsync \
- `grep -E "^(Build)?Requires" 389-ds-base/rpm/389-ds-base.spec.in | grep -v -E '(name|MODULE)' | awk '{ print $2 }' | sed 's/%{python3_pkgversion}/3/g' | grep -v "^/" | grep -v pkgversion | sort | uniq | tr '\n' ' '` && \
+WORKDIR /usr/local/src/389-ds-base
+
+# install dependencies
+RUN dnf upgrade -y \
+ && dnf install --setopt=strict=False -y @buildsys-build rpm-build make bzip2 git rsync \
+ `grep -E "^(Build)?Requires" rpm/389-ds-base.spec.in \
+ | grep -v -E '(name|MODULE)' \
+ | awk '{ print $2 }' \
+ | sed 's/%{python3_pkgversion}/3/g' \
+ | grep -v "^/" \
+ | grep -v pkgversion \
+ | sort | uniq \
+ | tr '\n' ' '` \
+ && dnf clean all
+
+# build
+RUN make -f rpm.mk rpms || sh -c 'echo "build failed, sleeping for some time to allow you debug" ; sleep 3600'
+
+RUN dnf install -y dist/rpms/*389*.rpm && \
dnf clean all
+# Link some known static locations to point to /data
+RUN mkdir -p /data/config && \
+ mkdir -p /data/ssca && \
+ mkdir -p /data/run && \
+ mkdir -p /var/run/dirsrv && \
+ ln -s /data/config /etc/dirsrv/slapd-localhost && \
+ ln -s /data/ssca /etc/dirsrv/ssca && \
+ ln -s /data/run /var/run/dirsrv
-### CHANGE THIS TO A ./configure and build that way.
-
-RUN cd 389-ds-base && \
- PERL_ON=0 RUST_ON=1 make -f rpm.mk rpms
-
-RUN dnf install -y 389-ds-base/dist/rpms/*389*.rpm && \
- dnf clean all
-
-# Create the example setup inf. It's valid for containers!
-# Build the instance from the new installer tools.
-RUN /usr/sbin/dscreate create-template > /root/ds-setup.inf && /usr/sbin/dscreate -v from-file /root/ds-setup.inf --containerised
+VOLUME /data
-# Finally add the volumes, they will inherit the contents of these directories.
-VOLUME /etc/dirsrv
-VOLUME /var/log/dirsrv
-VOLUME /var/lib/dirsrv
+#USER dirsrv
-# Or, run them as dirsrv
-USER dirsrv
-CMD ["/usr/sbin/ns-slapd", "-d", "0", "-D", "/etc/dirsrv/slapd-localhost", "-i", "/var/run/dirsrv/slapd-localhost.pid"]
+HEALTHCHECK --start-period=5m --timeout=5s --interval=5s --retries=2 \
+ CMD /usr/sbin/dscontainer -H
+CMD [ "/usr/sbin/dscontainer", "-r" ]
diff --git a/rpm.mk b/rpm.mk
index 1b2d02e..28275f1 100644
--- a/rpm.mk
+++ b/rpm.mk
@@ -63,7 +63,7 @@ tarballs: local-archive
rm -rf dist/$(NAME_VERSION)
cd dist/sources ; \
if [ $(BUNDLE_JEMALLOC) -eq 1 ]; then \
- wget $(JEMALLOC_URL) ; \
+ curl -LO $(JEMALLOC_URL) ; \
fi
rpmroot:
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months
[389-ds-base] branch 389-ds-base-1.4.0 updated: Issue 50747 - Port readnsstate to dsctl
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.0
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.0 by this push:
new b1fb4bb Issue 50747 - Port readnsstate to dsctl
b1fb4bb is described below
commit b1fb4bb7c53af4f0b0bf50c70777b70792ba8b6f
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue Dec 3 21:00:30 2019 -0500
Issue 50747 - Port readnsstate to dsctl
Description: Port the legacy tool readnsstate to dsctl, and add a healthcheck
for local and remote offset that are close to triggering
replication time skew errors
relates: https://pagure.io/389-ds-base/issue/50747
Reviewed by: tbordaz(Thanks!)
Revise lint messages per Thierry's requests
adjust skew calculation
Update man page
---
src/lib389/cli/dsctl | 4 +-
src/lib389/lib389/cli_ctl/health.py | 5 +-
src/lib389/lib389/cli_ctl/nsstate.py | 64 ++++++++++++++
src/lib389/lib389/dseldif.py | 165 ++++++++++++++++++++++++++++++++++-
src/lib389/lib389/lint.py | 52 +++++++++++
src/lib389/lib389/utils.py | 41 +++++++++
6 files changed, 326 insertions(+), 5 deletions(-)
diff --git a/src/lib389/cli/dsctl b/src/lib389/cli/dsctl
index 5cf7a43..1d88cb3 100755
--- a/src/lib389/cli/dsctl
+++ b/src/lib389/cli/dsctl
@@ -1,7 +1,7 @@
#!/usr/bin/python3
# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2016 Red Hat, Inc.
+# Copyright (C) 2019 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
@@ -20,6 +20,7 @@ from lib389 import DirSrv
from lib389.cli_ctl import instance as cli_instance
from lib389.cli_ctl import dbtasks as cli_dbtasks
from lib389.cli_ctl import health as cli_health
+from lib389.cli_ctl import nsstate as cli_nsstate
from lib389.cli_ctl.instance import instance_remove_all
from lib389.cli_base import (
_get_arg,
@@ -56,6 +57,7 @@ if not os.path.exists(DSRC_CONTAINER):
cli_instance.create_parser(subparsers)
cli_dbtasks.create_parser(subparsers)
cli_health.create_parser(subparsers)
+cli_nsstate.create_parser(subparsers)
argcomplete.autocomplete(parser)
diff --git a/src/lib389/lib389/cli_ctl/health.py b/src/lib389/lib389/cli_ctl/health.py
index d8f3d73..a420163 100644
--- a/src/lib389/lib389/cli_ctl/health.py
+++ b/src/lib389/lib389/cli_ctl/health.py
@@ -1,5 +1,5 @@
# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2016 Red Hat, Inc.
+# Copyright (C) 2019 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
@@ -15,7 +15,7 @@ from lib389.config import Encryption, Config
from lib389.monitor import MonitorDiskSpace
from lib389.replica import Replica, Changelog5
from lib389.nss_ssl import NssSsl
-from lib389.dseldif import FSChecks
+from lib389.dseldif import FSChecks, DSEldif
from lib389 import plugins
from lib389._constants import DSRC_HOME
@@ -33,6 +33,7 @@ CHECK_OBJECTS = [
MonitorDiskSpace,
Replica,
Changelog5,
+ DSEldif,
NssSsl,
]
diff --git a/src/lib389/lib389/cli_ctl/nsstate.py b/src/lib389/lib389/cli_ctl/nsstate.py
new file mode 100644
index 0000000..6a74178
--- /dev/null
+++ b/src/lib389/lib389/cli_ctl/nsstate.py
@@ -0,0 +1,64 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2019 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import json
+from lib389.dseldif import DSEldif
+
+
+def get_nsstate(inst, log, args):
+ """Process the nsState attribute"""
+ dse_ldif = DSEldif(inst)
+ states = dse_ldif.readNsState(suffix=args.suffix, flip=args.flip)
+ if args.json:
+ log.info(json.dumps(states))
+ else:
+ for state in states:
+ log.info("Replica DN: " + state['dn'])
+ log.info("Replica Suffix: " + state['suffix'])
+ log.info("Replica ID: " + state['rid'])
+ log.info("Gen Time: " + state['gen_time'])
+ log.info("Gen Time String: " + state['gen_time_str'])
+ log.info("Gen as CSN: " + state['gencsn'])
+ log.info("Local Offset: " + state['local_offset'])
+ log.info("Local Offset String: " + state['local_offset_str'])
+ log.info("Remote Offset: " + state['remote_offset'])
+ log.info("Remote Offset String: " + state['remote_offset_str'])
+ log.info("Time Skew: " + state['time_skew'])
+ log.info("Time Skew String: " + state['time_skew_str'])
+ log.info("Seq Num: " + state['seq_num'])
+ log.info("System Time: " + state['sys_time'])
+ log.info("Diff in Seconds: " + state['diff_secs'])
+ log.info("Diff in days/secs: " + state['diff_days_secs'])
+ log.info("Endian: " + state['endian'])
+ log.info("")
+
+
+def create_parser(subparsers):
+ repl_get_nsstate = subparsers.add_parser('get-nsstate', help="""Get the replication nsState in a human readable format
+
+Replica DN: The DN of the replication configuration entry
+Replica SUffix: The replicated suffix
+Replica ID: The Replica identifier
+Gen Time The time the CSN generator was created
+Gen Time String: The time string of generator
+Gen as CSN: The generation CSN
+Local Offset: The offset due to the local clock being set back
+Local Offset String: The offset in a nice human format
+Remote Offset: The offset due to clock difference with remote systems
+Remote Offset String: The offset in a nice human format
+Time Skew: The time skew between this server and its replicas
+Time Skew String: The time skew in a nice human format
+Seq Num: The number of multiple csns within a second
+System Time: The local system time
+Diff in Seconds: The time difference in seconds from the CSN generator creation to now
+Diff in days/secs: The time difference broken up into days and seconds
+Endian: Little/Big Endian
+""")
+ repl_get_nsstate.add_argument('--suffix', default=False, help='The DN of the replication suffix to read the state from')
+ repl_get_nsstate.add_argument('--flip', default=False, help='Flip between Little/Big Endian, this might be required for certain architectures')
+ repl_get_nsstate.set_defaults(func=get_nsstate)
diff --git a/src/lib389/lib389/dseldif.py b/src/lib389/lib389/dseldif.py
index de2a63d..36e7758 100644
--- a/src/lib389/lib389/dseldif.py
+++ b/src/lib389/lib389/dseldif.py
@@ -9,9 +9,22 @@
import copy
import os
+import sys
+import base64
+import time
+from struct import pack, unpack
+from datetime import timedelta
from stat import ST_MODE
+# from lib389.utils import print_nice_time
from lib389.paths import Paths
-from lib389.lint import DSPERMLE0001, DSPERMLE0002
+from lib389.lint import (
+ DSPERMLE0001,
+ DSPERMLE0002,
+ DSSKEWLE0001,
+ DSSKEWLE0002,
+ DSSKEWLE0003
+)
+
class DSEldif(object):
"""A class for working with dse.ldif file
@@ -38,7 +51,38 @@ class DSEldif(object):
if line.startswith('dn'):
self._contents.append(line.lower())
else:
- self._contents.append(line)
+ processed_line = processed_line[:-1] + line[1:]
+ self._lint_functions = [self._lint_nsstate]
+
+ def lint(self):
+ results = []
+ for fn in self._lint_functions:
+ for result in fn():
+ if result is not None:
+ results.append(result)
+ return results
+
+ def _lint_nsstate(self):
+ suffixes = self.readNsState()
+ for suffix in suffixes:
+ # Check the local offset first
+ report = None
+ skew = int(suffix['time_skew'])
+ if skew >= 86400:
+ # 24 hours - replication will break
+ report = copy.deepcopy(DSSKEWLE0003)
+ elif skew >= 43200:
+ # 12 hours
+ report = copy.deepcopy(DSSKEWLE0002)
+ elif skew >= 21600:
+ # 6 hours
+ report = copy.deepcopy(DSSKEWLE0001)
+ if report is not None:
+ report['items'].append(suffix['suffix'])
+ report['items'].append('Time Skew')
+ report['items'].append('Skew: ' + suffix['time_skew_str'])
+ report['fix'] = report['fix'].replace('YOUR_INSTANCE', self._instance.serverid)
+ yield report
def _update(self):
"""Update the dse.ldif with a new contents"""
@@ -152,6 +196,123 @@ class DSEldif(object):
self.add(entry_dn, attr, value)
self._update()
+ # Read NsState helper functions
+ def _flipend(self, end):
+ if end == '<':
+ return '>'
+ if end == '>':
+ return '<'
+
+ def _getGenState(self, dn, replica_suffix, nsstate, flip):
+ """Return a dict ofall the nsState properties
+ """
+ from lib389.utils import print_nice_time
+ if pack('<h', 1) == pack('=h',1):
+ endian = "Little Endian"
+ end = '<'
+ if flip:
+ end = flipend(end)
+ elif pack('>h', 1) == pack('=h',1):
+ endian = "Big Endian"
+ end = '>'
+ if flip:
+ end = flipend(end)
+ else:
+ raise ValueError("Unknown endian, unable to proceed")
+
+ thelen = len(nsstate)
+ if thelen <= 20:
+ pad = 2 # padding for short H values
+ timefmt = 'I' # timevals are unsigned 32-bit int
+ else:
+ pad = 6 # padding for short H values
+ timefmt = 'Q' # timevals are unsigned 64-bit int
+
+ base_fmtstr = "H%dx3%sH%dx" % (pad, timefmt, pad)
+ fmtstr = end + base_fmtstr
+ (rid, sampled_time, local_offset, remote_offset, seq_num) = unpack(fmtstr, nsstate)
+ now = int(time.time())
+ tdiff = now-sampled_time
+ wrongendian = False
+ try:
+ tdelta = timedelta(seconds=tdiff)
+ wrongendian = tdelta.days > 10*365
+ except OverflowError: # int overflow
+ wrongendian = True
+
+ # if the sampled time is more than 20 years off, this is
+ # probably the wrong endianness
+ if wrongendian:
+ end = flipend(end)
+ fmtstr = end + base_fmtstr
+ (rid, sampled_time, local_offset, remote_offset, seq_num) = unpack(fmtstr, nsstate)
+ tdiff = now-sampled_time
+ tdelta = timedelta(seconds=tdiff)
+
+ return {
+ 'dn': dn,
+ 'suffix': replica_suffix,
+ 'endian': endian,
+ 'rid': str(rid),
+ 'gen_time': str(sampled_time),
+ 'gencsn': "%08x%04d%04d0000" % (sampled_time, seq_num, rid),
+ 'gen_time_str': time.ctime(sampled_time),
+ 'local_offset': str(local_offset),
+ 'local_offset_str': print_nice_time(local_offset),
+ 'remote_offset': str(remote_offset),
+ 'remote_offset_str': print_nice_time(remote_offset),
+ 'time_skew': str(local_offset + remote_offset),
+ 'time_skew_str': print_nice_time(local_offset + remote_offset),
+ 'seq_num': str(seq_num),
+ 'sys_time': str(time.ctime(now)),
+ 'diff_secs': str(tdiff),
+ 'diff_days_secs': "%d:%d" % (tdelta.days, tdelta.seconds),
+ }
+
+ def readNsState(self, suffix=None, flip=False):
+ """Look for the nsState attribute in replication configuration entries,
+ then decode the base64 value and provide a dict of all stats it
+ contains
+
+ :param suffix: specific suffix to read nsState from
+ :type suffix: str
+ """
+ found_replica = False
+ found_suffix = False
+ replica_suffix = ""
+ nsstate = ""
+ states = []
+
+ for line in self._contents:
+ if line.startswith("dn: "):
+ dn = line[4:].strip()
+ if dn.startswith("cn=replica"):
+ found_replica = True
+ else:
+ found_replica = False
+ else:
+ if line.lower().startswith("nsstate:: ") and dn.startswith("cn=replica"):
+ b64val = line[10:].strip()
+ nsstate = base64.decodebytes(b64val.encode())
+ elif line.lower().startswith("nsds5replicaroot"):
+ found_suffix = True
+ replica_suffix = line.lower().split(':')[1].strip()
+
+ if found_replica and found_suffix and nsstate != "":
+ # We have everything we need to proceed
+ if suffix is not None and suffix == replica_suffix:
+ states.append(self._getGenState(dn, replica_suffix, nsstate, flip))
+ break
+ else:
+ states.append(self._getGenState(dn, replica_suffix, nsstate, flip))
+ # reset flags for next round...
+ found_replica = False
+ found_suffix = False
+ replica_suffix = ""
+ nsstate = ""
+
+ return states
+
class FSChecks(object):
"""This is for the healthcheck feature, check commonly used system config files the
diff --git a/src/lib389/lib389/lint.py b/src/lib389/lib389/lint.py
index 736dffa..b2bd8cd 100644
--- a/src/lib389/lib389/lint.py
+++ b/src/lib389/lib389/lint.py
@@ -344,3 +344,55 @@ security database pin/password files should only be readable by Directory Server
# chmod PERMS FILE"""
}
+
+# NsState time skew issues
+DSSKEWLE0001 = {
+ 'dsle': 'DSSKEWLE0001',
+ 'severity': 'Low',
+ 'items' : ['Replication'],
+ 'detail': """The time skew is over 6 hours. If this time skew continues to increase
+to 24 hours then replication can potentially stop working. Please continue to
+monitor the time skew offsets for increasing values.""",
+ 'fix' : """Monitor the time skew and avoid making changes to the system time.
+Also look at https://access.redhat.com/documentation/en-us/red_hat_directory_server/11...
+and find the paragraph "Too much time skew"."""
+}
+
+DSSKEWLE0002 = {
+ 'dsle': 'DSSKEWLE0002',
+ 'severity': 'Medium',
+ 'items' : ['Replication'],
+ 'detail': """The time skew is over 12 hours. If this time skew continues to increase
+to 24 hours then replication can potentially stop working. Please continue to
+monitor the time skew offsets for increasing values. Setting nsslapd-ignore-time-skew
+to "on" on each replica will allow replication to continue, but if the time skew
+continues to increase other more serious replication problems can occur.""",
+ 'fix' : """Monitor the time skew and avoid making changes to the system time.
+If you get close to 24 hours of time skew replication may stop working.
+In that case configure the server to ignore the time skew until the system
+times can be fixed/synchronized:
+
+ # dsconf slapd-YOUR_INSTANCE config replace nsslapd-ignore-time-skew=on
+
+Also look at https://access.redhat.com/documentation/en-us/red_hat_directory_server/11...
+and find the paragraph "Too much time skew"."""
+}
+
+DSSKEWLE0003 = {
+ 'dsle': 'DSSKEWLE0003',
+ 'severity': 'High',
+ 'items' : ['Replication'],
+ 'detail': """The time skew is over 24 hours. Setting nsslapd-ignore-time-skew
+to "on" on each replica will allow replication to continue, but if the
+time skew continues to increase other serious replication problems can
+occur.""",
+ 'fix' : """Avoid making changes to the system time, and make sure the clocks
+on all the replicas are correct. If you haven't set the server's
+"ignore time skew" setting then do the following on all the replicas
+until the time issues have been resolved:
+
+ # dsconf slapd-YOUR_INSTANCE config replace nsslapd-ignore-time-skew=on
+
+Also look at https://access.redhat.com/documentation/en-us/red_hat_directory_server/11...
+and find the paragraph "Too much time skew"."""
+}
diff --git a/src/lib389/lib389/utils.py b/src/lib389/lib389/utils.py
index a0b063a..046f4c0 100644
--- a/src/lib389/lib389/utils.py
+++ b/src/lib389/lib389/utils.py
@@ -1314,3 +1314,44 @@ def convert_bytes(bytes):
pow = math.pow(1024, i)
siz = round(bytes / pow, 2)
return "{} {}".format(siz, size_name[i])
+
+
+def search_filter_escape_bytes(bytes_value):
+ """ Convert a byte sequence to a properly escaped for LDAP (format BACKSLASH HEX HEX) string"""
+ # copied from https://github.com/cannatag/ldap3/blob/master/ldap3/utils/conv.py
+ if str is not bytes:
+ if isinstance(bytes_value, str):
+ bytes_value = bytearray(bytes_value, encoding='utf-8')
+ return ''.join([('\\%02x' % int(b)) for b in bytes_value])
+ else:
+ raise RuntimeError('Running with Python 2 is unsupported')
+
+
+def print_nice_time(seconds):
+ """Convert seconds to a pretty format
+ """
+ seconds = int(seconds)
+ d, s = divmod(seconds, 24*60*60)
+ h, s = divmod(s, 60*60)
+ m, s = divmod(s, 60)
+ d_plural = ""
+ h_plural = ""
+ m_plural = ""
+ s_plural = ""
+ if d > 1:
+ d_plural = "s"
+ if h != 1:
+ h_plural = "s"
+ if m != 1:
+ m_plural = "s"
+ if s != 1:
+ s_plural = "s"
+ if d > 0:
+ return f'{d:d} day{d_plural}, {h:d} hour{h_plural}, {m:d} minute{m_plural}, {s:d} second{s_plural}'
+ elif h > 0:
+ return f'{h:d} hour{h_plural}, {m:d} minute{m_plural}, {s:d} second{s_plural}'
+ elif m > 0:
+ return f'{m:d} minute{m_plural}, {s:d} second{s_plural}'
+ else:
+ return f'{s:d} second{s_plural}'
+
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50747 - Port readnsstate to dsctl
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new 76f4a48 Issue 50747 - Port readnsstate to dsctl
76f4a48 is described below
commit 76f4a4841e6e5db233d4d785a6fa4e793e2a1a11
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue Dec 3 21:00:30 2019 -0500
Issue 50747 - Port readnsstate to dsctl
Description: Port the legacy tool readnsstate to dsctl, and add a healthcheck
for local and remote offset that are close to triggering
replication time skew errors
relates: https://pagure.io/389-ds-base/issue/50747
Reviewed by: tbordaz(Thanks!)
Revise lint messages per Thierry's requests
adjust skew calculation
Update man page
---
src/lib389/cli/dsctl | 4 +-
src/lib389/lib389/cli_ctl/health.py | 5 +-
src/lib389/lib389/cli_ctl/nsstate.py | 64 ++++++++++++++
src/lib389/lib389/dseldif.py | 165 ++++++++++++++++++++++++++++++++++-
src/lib389/lib389/lint.py | 52 +++++++++++
src/lib389/lib389/utils.py | 41 +++++++++
6 files changed, 326 insertions(+), 5 deletions(-)
diff --git a/src/lib389/cli/dsctl b/src/lib389/cli/dsctl
index 5cf7a43..1d88cb3 100755
--- a/src/lib389/cli/dsctl
+++ b/src/lib389/cli/dsctl
@@ -1,7 +1,7 @@
#!/usr/bin/python3
# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2016 Red Hat, Inc.
+# Copyright (C) 2019 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
@@ -20,6 +20,7 @@ from lib389 import DirSrv
from lib389.cli_ctl import instance as cli_instance
from lib389.cli_ctl import dbtasks as cli_dbtasks
from lib389.cli_ctl import health as cli_health
+from lib389.cli_ctl import nsstate as cli_nsstate
from lib389.cli_ctl.instance import instance_remove_all
from lib389.cli_base import (
_get_arg,
@@ -56,6 +57,7 @@ if not os.path.exists(DSRC_CONTAINER):
cli_instance.create_parser(subparsers)
cli_dbtasks.create_parser(subparsers)
cli_health.create_parser(subparsers)
+cli_nsstate.create_parser(subparsers)
argcomplete.autocomplete(parser)
diff --git a/src/lib389/lib389/cli_ctl/health.py b/src/lib389/lib389/cli_ctl/health.py
index d8f3d73..a420163 100644
--- a/src/lib389/lib389/cli_ctl/health.py
+++ b/src/lib389/lib389/cli_ctl/health.py
@@ -1,5 +1,5 @@
# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2016 Red Hat, Inc.
+# Copyright (C) 2019 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
@@ -15,7 +15,7 @@ from lib389.config import Encryption, Config
from lib389.monitor import MonitorDiskSpace
from lib389.replica import Replica, Changelog5
from lib389.nss_ssl import NssSsl
-from lib389.dseldif import FSChecks
+from lib389.dseldif import FSChecks, DSEldif
from lib389 import plugins
from lib389._constants import DSRC_HOME
@@ -33,6 +33,7 @@ CHECK_OBJECTS = [
MonitorDiskSpace,
Replica,
Changelog5,
+ DSEldif,
NssSsl,
]
diff --git a/src/lib389/lib389/cli_ctl/nsstate.py b/src/lib389/lib389/cli_ctl/nsstate.py
new file mode 100644
index 0000000..6a74178
--- /dev/null
+++ b/src/lib389/lib389/cli_ctl/nsstate.py
@@ -0,0 +1,64 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2019 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import json
+from lib389.dseldif import DSEldif
+
+
+def get_nsstate(inst, log, args):
+ """Process the nsState attribute"""
+ dse_ldif = DSEldif(inst)
+ states = dse_ldif.readNsState(suffix=args.suffix, flip=args.flip)
+ if args.json:
+ log.info(json.dumps(states))
+ else:
+ for state in states:
+ log.info("Replica DN: " + state['dn'])
+ log.info("Replica Suffix: " + state['suffix'])
+ log.info("Replica ID: " + state['rid'])
+ log.info("Gen Time: " + state['gen_time'])
+ log.info("Gen Time String: " + state['gen_time_str'])
+ log.info("Gen as CSN: " + state['gencsn'])
+ log.info("Local Offset: " + state['local_offset'])
+ log.info("Local Offset String: " + state['local_offset_str'])
+ log.info("Remote Offset: " + state['remote_offset'])
+ log.info("Remote Offset String: " + state['remote_offset_str'])
+ log.info("Time Skew: " + state['time_skew'])
+ log.info("Time Skew String: " + state['time_skew_str'])
+ log.info("Seq Num: " + state['seq_num'])
+ log.info("System Time: " + state['sys_time'])
+ log.info("Diff in Seconds: " + state['diff_secs'])
+ log.info("Diff in days/secs: " + state['diff_days_secs'])
+ log.info("Endian: " + state['endian'])
+ log.info("")
+
+
+def create_parser(subparsers):
+ repl_get_nsstate = subparsers.add_parser('get-nsstate', help="""Get the replication nsState in a human readable format
+
+Replica DN: The DN of the replication configuration entry
+Replica SUffix: The replicated suffix
+Replica ID: The Replica identifier
+Gen Time The time the CSN generator was created
+Gen Time String: The time string of generator
+Gen as CSN: The generation CSN
+Local Offset: The offset due to the local clock being set back
+Local Offset String: The offset in a nice human format
+Remote Offset: The offset due to clock difference with remote systems
+Remote Offset String: The offset in a nice human format
+Time Skew: The time skew between this server and its replicas
+Time Skew String: The time skew in a nice human format
+Seq Num: The number of multiple csns within a second
+System Time: The local system time
+Diff in Seconds: The time difference in seconds from the CSN generator creation to now
+Diff in days/secs: The time difference broken up into days and seconds
+Endian: Little/Big Endian
+""")
+ repl_get_nsstate.add_argument('--suffix', default=False, help='The DN of the replication suffix to read the state from')
+ repl_get_nsstate.add_argument('--flip', default=False, help='Flip between Little/Big Endian, this might be required for certain architectures')
+ repl_get_nsstate.set_defaults(func=get_nsstate)
diff --git a/src/lib389/lib389/dseldif.py b/src/lib389/lib389/dseldif.py
index de2a63d..36e7758 100644
--- a/src/lib389/lib389/dseldif.py
+++ b/src/lib389/lib389/dseldif.py
@@ -9,9 +9,22 @@
import copy
import os
+import sys
+import base64
+import time
+from struct import pack, unpack
+from datetime import timedelta
from stat import ST_MODE
+# from lib389.utils import print_nice_time
from lib389.paths import Paths
-from lib389.lint import DSPERMLE0001, DSPERMLE0002
+from lib389.lint import (
+ DSPERMLE0001,
+ DSPERMLE0002,
+ DSSKEWLE0001,
+ DSSKEWLE0002,
+ DSSKEWLE0003
+)
+
class DSEldif(object):
"""A class for working with dse.ldif file
@@ -38,7 +51,38 @@ class DSEldif(object):
if line.startswith('dn'):
self._contents.append(line.lower())
else:
- self._contents.append(line)
+ processed_line = processed_line[:-1] + line[1:]
+ self._lint_functions = [self._lint_nsstate]
+
+ def lint(self):
+ results = []
+ for fn in self._lint_functions:
+ for result in fn():
+ if result is not None:
+ results.append(result)
+ return results
+
+ def _lint_nsstate(self):
+ suffixes = self.readNsState()
+ for suffix in suffixes:
+ # Check the local offset first
+ report = None
+ skew = int(suffix['time_skew'])
+ if skew >= 86400:
+ # 24 hours - replication will break
+ report = copy.deepcopy(DSSKEWLE0003)
+ elif skew >= 43200:
+ # 12 hours
+ report = copy.deepcopy(DSSKEWLE0002)
+ elif skew >= 21600:
+ # 6 hours
+ report = copy.deepcopy(DSSKEWLE0001)
+ if report is not None:
+ report['items'].append(suffix['suffix'])
+ report['items'].append('Time Skew')
+ report['items'].append('Skew: ' + suffix['time_skew_str'])
+ report['fix'] = report['fix'].replace('YOUR_INSTANCE', self._instance.serverid)
+ yield report
def _update(self):
"""Update the dse.ldif with a new contents"""
@@ -152,6 +196,123 @@ class DSEldif(object):
self.add(entry_dn, attr, value)
self._update()
+ # Read NsState helper functions
+ def _flipend(self, end):
+ if end == '<':
+ return '>'
+ if end == '>':
+ return '<'
+
+ def _getGenState(self, dn, replica_suffix, nsstate, flip):
+ """Return a dict ofall the nsState properties
+ """
+ from lib389.utils import print_nice_time
+ if pack('<h', 1) == pack('=h',1):
+ endian = "Little Endian"
+ end = '<'
+ if flip:
+ end = flipend(end)
+ elif pack('>h', 1) == pack('=h',1):
+ endian = "Big Endian"
+ end = '>'
+ if flip:
+ end = flipend(end)
+ else:
+ raise ValueError("Unknown endian, unable to proceed")
+
+ thelen = len(nsstate)
+ if thelen <= 20:
+ pad = 2 # padding for short H values
+ timefmt = 'I' # timevals are unsigned 32-bit int
+ else:
+ pad = 6 # padding for short H values
+ timefmt = 'Q' # timevals are unsigned 64-bit int
+
+ base_fmtstr = "H%dx3%sH%dx" % (pad, timefmt, pad)
+ fmtstr = end + base_fmtstr
+ (rid, sampled_time, local_offset, remote_offset, seq_num) = unpack(fmtstr, nsstate)
+ now = int(time.time())
+ tdiff = now-sampled_time
+ wrongendian = False
+ try:
+ tdelta = timedelta(seconds=tdiff)
+ wrongendian = tdelta.days > 10*365
+ except OverflowError: # int overflow
+ wrongendian = True
+
+ # if the sampled time is more than 20 years off, this is
+ # probably the wrong endianness
+ if wrongendian:
+ end = flipend(end)
+ fmtstr = end + base_fmtstr
+ (rid, sampled_time, local_offset, remote_offset, seq_num) = unpack(fmtstr, nsstate)
+ tdiff = now-sampled_time
+ tdelta = timedelta(seconds=tdiff)
+
+ return {
+ 'dn': dn,
+ 'suffix': replica_suffix,
+ 'endian': endian,
+ 'rid': str(rid),
+ 'gen_time': str(sampled_time),
+ 'gencsn': "%08x%04d%04d0000" % (sampled_time, seq_num, rid),
+ 'gen_time_str': time.ctime(sampled_time),
+ 'local_offset': str(local_offset),
+ 'local_offset_str': print_nice_time(local_offset),
+ 'remote_offset': str(remote_offset),
+ 'remote_offset_str': print_nice_time(remote_offset),
+ 'time_skew': str(local_offset + remote_offset),
+ 'time_skew_str': print_nice_time(local_offset + remote_offset),
+ 'seq_num': str(seq_num),
+ 'sys_time': str(time.ctime(now)),
+ 'diff_secs': str(tdiff),
+ 'diff_days_secs': "%d:%d" % (tdelta.days, tdelta.seconds),
+ }
+
+ def readNsState(self, suffix=None, flip=False):
+ """Look for the nsState attribute in replication configuration entries,
+ then decode the base64 value and provide a dict of all stats it
+ contains
+
+ :param suffix: specific suffix to read nsState from
+ :type suffix: str
+ """
+ found_replica = False
+ found_suffix = False
+ replica_suffix = ""
+ nsstate = ""
+ states = []
+
+ for line in self._contents:
+ if line.startswith("dn: "):
+ dn = line[4:].strip()
+ if dn.startswith("cn=replica"):
+ found_replica = True
+ else:
+ found_replica = False
+ else:
+ if line.lower().startswith("nsstate:: ") and dn.startswith("cn=replica"):
+ b64val = line[10:].strip()
+ nsstate = base64.decodebytes(b64val.encode())
+ elif line.lower().startswith("nsds5replicaroot"):
+ found_suffix = True
+ replica_suffix = line.lower().split(':')[1].strip()
+
+ if found_replica and found_suffix and nsstate != "":
+ # We have everything we need to proceed
+ if suffix is not None and suffix == replica_suffix:
+ states.append(self._getGenState(dn, replica_suffix, nsstate, flip))
+ break
+ else:
+ states.append(self._getGenState(dn, replica_suffix, nsstate, flip))
+ # reset flags for next round...
+ found_replica = False
+ found_suffix = False
+ replica_suffix = ""
+ nsstate = ""
+
+ return states
+
class FSChecks(object):
"""This is for the healthcheck feature, check commonly used system config files the
diff --git a/src/lib389/lib389/lint.py b/src/lib389/lib389/lint.py
index 736dffa..b2bd8cd 100644
--- a/src/lib389/lib389/lint.py
+++ b/src/lib389/lib389/lint.py
@@ -344,3 +344,55 @@ security database pin/password files should only be readable by Directory Server
# chmod PERMS FILE"""
}
+
+# NsState time skew issues
+DSSKEWLE0001 = {
+ 'dsle': 'DSSKEWLE0001',
+ 'severity': 'Low',
+ 'items' : ['Replication'],
+ 'detail': """The time skew is over 6 hours. If this time skew continues to increase
+to 24 hours then replication can potentially stop working. Please continue to
+monitor the time skew offsets for increasing values.""",
+ 'fix' : """Monitor the time skew and avoid making changes to the system time.
+Also look at https://access.redhat.com/documentation/en-us/red_hat_directory_server/11...
+and find the paragraph "Too much time skew"."""
+}
+
+DSSKEWLE0002 = {
+ 'dsle': 'DSSKEWLE0002',
+ 'severity': 'Medium',
+ 'items' : ['Replication'],
+ 'detail': """The time skew is over 12 hours. If this time skew continues to increase
+to 24 hours then replication can potentially stop working. Please continue to
+monitor the time skew offsets for increasing values. Setting nsslapd-ignore-time-skew
+to "on" on each replica will allow replication to continue, but if the time skew
+continues to increase other more serious replication problems can occur.""",
+ 'fix' : """Monitor the time skew and avoid making changes to the system time.
+If you get close to 24 hours of time skew replication may stop working.
+In that case configure the server to ignore the time skew until the system
+times can be fixed/synchronized:
+
+ # dsconf slapd-YOUR_INSTANCE config replace nsslapd-ignore-time-skew=on
+
+Also look at https://access.redhat.com/documentation/en-us/red_hat_directory_server/11...
+and find the paragraph "Too much time skew"."""
+}
+
+DSSKEWLE0003 = {
+ 'dsle': 'DSSKEWLE0003',
+ 'severity': 'High',
+ 'items' : ['Replication'],
+ 'detail': """The time skew is over 24 hours. Setting nsslapd-ignore-time-skew
+to "on" on each replica will allow replication to continue, but if the
+time skew continues to increase other serious replication problems can
+occur.""",
+ 'fix' : """Avoid making changes to the system time, and make sure the clocks
+on all the replicas are correct. If you haven't set the server's
+"ignore time skew" setting then do the following on all the replicas
+until the time issues have been resolved:
+
+ # dsconf slapd-YOUR_INSTANCE config replace nsslapd-ignore-time-skew=on
+
+Also look at https://access.redhat.com/documentation/en-us/red_hat_directory_server/11...
+and find the paragraph "Too much time skew"."""
+}
diff --git a/src/lib389/lib389/utils.py b/src/lib389/lib389/utils.py
index a2f16de..19f0b93 100644
--- a/src/lib389/lib389/utils.py
+++ b/src/lib389/lib389/utils.py
@@ -1314,3 +1314,44 @@ def convert_bytes(bytes):
pow = math.pow(1024, i)
siz = round(bytes / pow, 2)
return "{} {}".format(siz, size_name[i])
+
+
+def search_filter_escape_bytes(bytes_value):
+ """ Convert a byte sequence to a properly escaped for LDAP (format BACKSLASH HEX HEX) string"""
+ # copied from https://github.com/cannatag/ldap3/blob/master/ldap3/utils/conv.py
+ if str is not bytes:
+ if isinstance(bytes_value, str):
+ bytes_value = bytearray(bytes_value, encoding='utf-8')
+ return ''.join([('\\%02x' % int(b)) for b in bytes_value])
+ else:
+ raise RuntimeError('Running with Python 2 is unsupported')
+
+
+def print_nice_time(seconds):
+ """Convert seconds to a pretty format
+ """
+ seconds = int(seconds)
+ d, s = divmod(seconds, 24*60*60)
+ h, s = divmod(s, 60*60)
+ m, s = divmod(s, 60)
+ d_plural = ""
+ h_plural = ""
+ m_plural = ""
+ s_plural = ""
+ if d > 1:
+ d_plural = "s"
+ if h != 1:
+ h_plural = "s"
+ if m != 1:
+ m_plural = "s"
+ if s != 1:
+ s_plural = "s"
+ if d > 0:
+ return f'{d:d} day{d_plural}, {h:d} hour{h_plural}, {m:d} minute{m_plural}, {s:d} second{s_plural}'
+ elif h > 0:
+ return f'{h:d} hour{h_plural}, {m:d} minute{m_plural}, {s:d} second{s_plural}'
+ elif m > 0:
+ return f'{m:d} minute{m_plural}, {s:d} second{s_plural}'
+ else:
+ return f'{s:d} second{s_plural}'
+
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Ticket 50745: ns-slapd hangs during CleanAllRUV tests
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new ef9d7d4 Ticket 50745: ns-slapd hangs during CleanAllRUV tests
ef9d7d4 is described below
commit ef9d7d4f82ffabaf3a0a140cb807a88494238d7e
Author: Thierry Bordaz <tbordaz(a)redhat.com>
AuthorDate: Wed Nov 27 14:04:14 2019 +0100
Ticket 50745: ns-slapd hangs during CleanAllRUV tests
Bug Description:
The hang condition:
- is not systematic
- occurs in rare case, for example here during the deletion of a replica.
- a thread is waiting for a dblock that an other thread "forgot" to
release.
- have always existed, at least since 1.4.0 but likely since 1.2.x
When deleting a replica, the replica is retrieved from
mapping tree structure (mtnode).
The replica is also retrieved through the mapping tree
when writing updates to the changelog.
When deleting the replica, mapping tree structure is cleared
after the changelog is deleted (that can take some cycles).
There is a window where an update can retrieve the replica,
from the not yet cleared MT, while the changelog being removed.
At the end, the update will update the changelog that is
currently removed and keeps an unfree lock in the DB.
Fix description:
Ideally mapping tree should be protected by a lock but it
is not done systematically (e.g. slapi_get_mapping_tree_node).
Using a lock looks an overkill and can probably introduce
deadlock and performance hit.
The idea of the fix is to reduce the window, moving the
mapping tree clear before the changelog removal.
https://pagure.io/389-ds-base/issue/50745
Reviewed by: Mark Reynolds, Ludwig Krispenz
---
ldap/servers/plugins/replication/repl5_replica_config.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 79b2575..02b36f6 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -757,6 +757,10 @@ replica_config_delete(Slapi_PBlock *pb __attribute__((unused)),
if (mtnode_ext->replica) {
/* remove object from the hash */
r = (Replica *)object_get_data(mtnode_ext->replica);
+ mtnode_ext->replica = NULL; /* moving it before deleting the CL because
+ * deletion can take some time giving the opportunity
+ * to an operation to start while CL is deleted
+ */
PR_ASSERT(r);
/* The changelog for this replica is no longer valid, so we should remove it. */
slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "replica_config_delete - "
@@ -765,7 +769,6 @@ replica_config_delete(Slapi_PBlock *pb __attribute__((unused)),
slapi_sdn_get_dn(replica_get_root(r)));
cl5DeleteDBSync(r);
replica_delete_by_name(replica_get_name(r));
- mtnode_ext->replica = NULL;
}
PR_Unlock(s_configLock);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 4 months