URL: https://github.com/freeipa/freeipa/pull/1474
Author: tiran
 Title: #1474: Prepare migration of mod_nss NSSDB to sql format 
Action: opened

PR body:
"""
This is a reduced version of PR #1458, just refactoring and additional SQL 
format support without an actual migration. This bits and pieces are useful for 
master and 4.6. The missing pieces are only relevant for 4.6 support on rawhide.

- Refactor CertDB to look up values from its NSSDatabase.
- Add run_modutil() helpers to support sql format. modutil does not
  auto-detect the NSSDB format.
- Add migration helpers to CertDB.
- Restore SELinux context when migrating NSSDB.
- Add some debugging and sanity checks to httpinstance.

"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/1474/head:pr1474
git checkout pr1474
From 0e5f5021a128560f26f9329cf973ee9fc6f2963b Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Tue, 16 Jan 2018 13:43:25 +0100
Subject: [PATCH 1/2] certmonger: Use explicit storage format

Add storage='NSSDB' to various places. It makes it a bit easier to track
down NSSDB usage.

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 ipaclient/install/client.py       |  9 +++++++--
 ipaserver/install/certs.py        | 13 ++++++++-----
 ipaserver/install/dsinstance.py   |  4 +++-
 ipaserver/install/httpinstance.py |  4 +++-
 ipaserver/install/krbinstance.py  | 13 ++++++++-----
 5 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
index 5173d90bfe..5467e4695c 100644
--- a/ipaclient/install/client.py
+++ b/ipaclient/install/client.py
@@ -788,8 +788,13 @@ def configure_certmonger(
     try:
         certmonger.request_cert(
             certpath=paths.IPA_NSSDB_DIR,
-            nickname='Local IPA host', subject=subject, dns=[hostname],
-            principal=principal, passwd_fname=passwd_fname)
+            storage='NSSDB',
+            nickname='Local IPA host',
+            subject=subject,
+            dns=[hostname],
+            principal=principal,
+            passwd_fname=passwd_fname
+        )
     except Exception as ex:
         logger.error(
             "%s request for host certificate failed: %s",
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index 1579d5c09c..1bf11c4585 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -599,11 +599,14 @@ def export_pem_cert(self, nickname, location):
         return self.nssdb.export_pem_cert(nickname, location)
 
     def request_service_cert(self, nickname, principal, host):
-        certmonger.request_and_wait_for_cert(certpath=self.secdir,
-                                             nickname=nickname,
-                                             principal=principal,
-                                             subject=host,
-                                             passwd_fname=self.passwd_fname)
+        certmonger.request_and_wait_for_cert(
+            certpath=self.secdir,
+            storage='NSSDB',
+            nickname=nickname,
+            principal=principal,
+            subject=host,
+            passwd_fname=self.passwd_fname
+        )
 
     def is_ipa_issued_cert(self, api, nickname):
         """
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index f1c866136c..348f26cc07 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -832,6 +832,7 @@ def __enable_ssl(self):
                 cmd = 'restart_dirsrv %s' % self.serverid
                 certmonger.request_and_wait_for_cert(
                     certpath=dirname,
+                    storage='NSSDB',
                     nickname=self.nickname,
                     principal=self.principal,
                     passwd_fname=dsdb.passwd_fname,
@@ -839,7 +840,8 @@ def __enable_ssl(self):
                     ca='IPA',
                     profile=dogtag.DEFAULT_PROFILE,
                     dns=[self.fqdn],
-                    post_command=cmd)
+                    post_command=cmd
+                )
             finally:
                 if prev_helper is not None:
                     certmonger.modify_ca_helper('IPA', prev_helper)
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 8f3b5937fd..9d7c119cd3 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -437,6 +437,7 @@ def __setup_ssl(self):
             try:
                 certmonger.request_and_wait_for_cert(
                     certpath=db.secdir,
+                    storage='NSSDB',
                     nickname=self.cert_nickname,
                     principal=self.principal,
                     passwd_fname=db.passwd_fname,
@@ -444,7 +445,8 @@ def __setup_ssl(self):
                     ca='IPA',
                     profile=dogtag.DEFAULT_PROFILE,
                     dns=[self.fqdn],
-                    post_command='restart_httpd')
+                    post_command='restart_httpd'
+                )
             finally:
                 if prev_helper is not None:
                     certmonger.modify_ca_helper('IPA', prev_helper)
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
index 104761b28a..ebd8ac28d2 100644
--- a/ipaserver/install/krbinstance.py
+++ b/ipaserver/install/krbinstance.py
@@ -430,18 +430,21 @@ def _call_certmonger(self, certmonger_ca='IPA'):
                     '--agent-submit'
                 ]
                 helper = " ".join(ca_args)
-                prev_helper = certmonger.modify_ca_helper(certmonger_ca, helper)
+                prev_helper = certmonger.modify_ca_helper(
+                    certmonger_ca, helper
+                )
 
             certmonger.request_and_wait_for_cert(
-                certpath,
-                subject,
-                krbtgt,
+                certpath=certpath,
+                subject=subject,
+                principal=krbtgt,
                 ca=certmonger_ca,
                 dns=self.fqdn,
                 storage='FILE',
                 profile=KDC_PROFILE,
                 post_command='renew_kdc_cert',
-                perms=(0o644, 0o600))
+                perms=(0o644, 0o600)
+            )
         except dbus.DBusException as e:
             # if the certificate is already tracked, ignore the error
             name = e.get_dbus_name()

From 44132622c916e9fbf97c8e0e83798d0e32569ecb Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Tue, 16 Jan 2018 14:57:07 +0100
Subject: [PATCH 2/2] Prepare migration of mod_nss NSSDB to sql format

- Refactor CertDB to look up values from its NSSDatabase.
- Add run_modutil() helpers to support sql format. modutil does not
  auto-detect the NSSDB format.
- Add migration helpers to CertDB.
- Add explicit DB format to NSSCertificateDatabase stanza
- Restore SELinux context when migrating NSSDB.
- Add some debugging and sanity checks to httpinstance.

The actual database format is still dbm. Certmonger on Fedora 27 does
neither auto-detect DB format nor support SQL out of the box.

https://pagure.io/freeipa/issue/7354

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 .test_runner_config.yaml               |   1 +
 ipapython/certdb.py                    |  48 ++++++++++----
 ipaserver/install/certs.py             |  84 ++++++++++++++++++++++---
 ipaserver/install/httpinstance.py      | 110 +++++++++++++++++++++++----------
 ipaserver/install/service.py           |   2 +
 ipatests/test_ipapython/test_certdb.py |   6 ++
 6 files changed, 196 insertions(+), 55 deletions(-)

diff --git a/.test_runner_config.yaml b/.test_runner_config.yaml
index 59cb2a4511..c486d25aa2 100644
--- a/.test_runner_config.yaml
+++ b/.test_runner_config.yaml
@@ -43,6 +43,7 @@ steps:
       systemd_journal.log
       `find daemons -name '*.log' -print`
   - chown ${uid}:${gid} ${container_working_dir}/var_log.tar
+  - ls -laZ /etc/dirsrv/slapd-*/ /etc/httpd/alias/ /etc/pki/pki-tomcat/alias/ || true
   configure:
   - ./autogen.sh
   install_packages:
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index e7fe17beb1..36cc2e4429 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -34,6 +34,7 @@
 
 from ipaplatform.constants import constants
 from ipaplatform.paths import paths
+from ipaplatform.tasks import tasks
 from ipapython.dn import DN
 from ipapython.kerberos import Principal
 from ipapython import ipautil
@@ -239,19 +240,28 @@ def __init__(self, nssdir=None, dbtype='auto'):
         self.pwd_file = os.path.join(self.secdir, 'pwdfile.txt')
         self.dbtype = None
         self.certdb = self.keydb = self.secmod = None
+        # files in actual db
         self.filenames = ()
+        # all files that are handled by create_db(backup=True)
+        self.backup_filenames = ()
         self._set_filenames(dbtype)
 
     def _set_filenames(self, dbtype):
         self.dbtype = dbtype
+        dbmfiles = (
+            os.path.join(self.secdir, "cert8.db"),
+            os.path.join(self.secdir, "key3.db"),
+            os.path.join(self.secdir, "secmod.db")
+        )
+        sqlfiles = (
+            os.path.join(self.secdir, "cert9.db"),
+            os.path.join(self.secdir, "key4.db"),
+            os.path.join(self.secdir, "pkcs11.txt")
+        )
         if dbtype == 'dbm':
-            self.certdb = os.path.join(self.secdir, "cert8.db")
-            self.keydb = os.path.join(self.secdir, "key3.db")
-            self.secmod = os.path.join(self.secdir, "secmod.db")
+            self.certdb, self.keydb, self.secmod = dbmfiles
         elif dbtype == 'sql':
-            self.certdb = os.path.join(self.secdir, "cert9.db")
-            self.keydb = os.path.join(self.secdir, "key4.db")
-            self.secmod = os.path.join(self.secdir, "pkcs11.txt")
+            self.certdb, self.keydb, self.secmod = sqlfiles
         else:
             raise ValueError(dbtype)
         self.filenames = (
@@ -260,6 +270,9 @@ def _set_filenames(self, dbtype):
             self.secmod,
             self.pwd_file,
         )
+        self.backup_filenames = (
+            self.pwd_file,
+        ) + sqlfiles + dbmfiles
 
     def close(self):
         if self._is_temporary:
@@ -288,6 +301,19 @@ def run_pk12util(self, args, stdin=None, **kwargs):
         new_args.extend(args)
         return ipautil.run(new_args, stdin, **kwargs)
 
+    def run_modutil(self, args, stdin=None, **kwargs):
+        new_args = [
+            paths.MODUTIL,
+            '-dbdir', '{}:{}'.format(self.dbtype, self.secdir)
+        ]
+        new_args.extend(args)
+        return ipautil.run(new_args, stdin, **kwargs)
+
+    def exists(self):
+        """Check DB exists (all files are present)
+        """
+        return all(os.path.isfile(filename) for filename in self.filenames)
+
     def create_db(self, user=None, group=None, mode=None, backup=False):
         """Create cert DB
 
@@ -313,9 +339,8 @@ def create_db(self, user=None, group=None, mode=None, backup=False):
             gid = grp.getgrnam(group).gr_gid
 
         if backup:
-            for filename in self.filenames:
-                path = os.path.join(self.secdir, filename)
-                ipautil.backup_file(path)
+            for filename in self.backup_filenames:
+                ipautil.backup_file(filename)
 
         if not os.path.exists(self.secdir):
             os.makedirs(self.secdir, dirmode)
@@ -328,7 +353,8 @@ def create_db(self, user=None, group=None, mode=None, backup=False):
                 f.write(ipautil.ipa_generate_password())
                 f.flush()
 
-        self.run_certutil(["-N", "-f", self.pwd_file])
+        # -@ in case it's an old db and it must be migrated
+        self.run_certutil(['-N', '-@', self.pwd_file])
 
         # Finally fix up perms
         os.chown(self.secdir, uid, gid)
@@ -383,7 +409,7 @@ def convert_db(self, rename_old=True):
             oldstat = os.stat(oldname)
             os.chmod(newname, stat.S_IMODE(oldstat.st_mode))
             os.chown(newname, oldstat.st_uid, oldstat.st_gid)
-            # XXX also retain SELinux context?
+            tasks.restore_context(newname)
 
         self._set_filenames('sql')
         self.list_certs()  # self-test
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index 1bf11c4585..9f6a7cdd13 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -45,8 +45,10 @@
 from ipalib.install import certstore
 from ipalib.util import strip_csr_header
 from ipalib.text import _
+from ipaplatform.constants import constants
 from ipaplatform.paths import paths
 
+
 logger = logging.getLogger(__name__)
 
 
@@ -107,14 +109,10 @@ def __init__(self, realm, nssdir, fstore=None,
                  dbtype='auto'):
         self.nssdb = NSSDatabase(nssdir, dbtype=dbtype)
 
-        self.secdir = nssdir
         self.realm = realm
 
         self.noise_fname = os.path.join(self.secdir, "noise.txt")
 
-        self.certdb_fname = self.nssdb.certdb
-        self.keydb_fname = self.nssdb.keydb
-        self.secmod_fname = self.nssdb.secmod
         self.pk12_fname = os.path.join(self.secdir, "cacert.p12")
         self.pin_fname = os.path.join(self.secdir + "pin.txt")
         self.reqdir = None
@@ -165,6 +163,27 @@ def __init__(self, realm, nssdir, fstore=None,
     ca_subject = ipautil.dn_attribute_property('_ca_subject')
     subject_base = ipautil.dn_attribute_property('_subject_base')
 
+    # migration changes paths, just forward attribute lookup to nssdb
+    @property
+    def secdir(self):
+        return self.nssdb.secdir
+
+    @property
+    def dbtype(self):
+        return self.nssdb.dbtype
+
+    @property
+    def certdb_fname(self):
+        return self.nssdb.certdb
+
+    @property
+    def keydb_fname(self):
+        return self.nssdb.keydb
+
+    @property
+    def secmod_fname(self):
+        return self.nssdb.secmod
+
     @property
     def passwd_fname(self):
         return self.nssdb.pwd_file
@@ -173,10 +192,7 @@ def exists(self):
         """
         Checks whether all NSS database files + our pwd_file exist
         """
-        for f in self.nssdb.filenames:
-            if not os.path.exists(f):
-                return False
-        return True
+        return self.nssdb.exists()
 
     def __del__(self):
         if self.reqdir is not None:
@@ -221,6 +237,9 @@ def set_perms(self, fname, write=False):
     def run_certutil(self, args, stdin=None, **kwargs):
         return self.nssdb.run_certutil(args, stdin, **kwargs)
 
+    def run_modutil(self, args, stdin=None, **kwargs):
+        return self.nssdb.run_modutil(args, stdin, **kwargs)
+
     def create_noise_file(self):
         if os.path.isfile(self.noise_fname):
             os.remove(self.noise_fname)
@@ -238,8 +257,10 @@ def create_passwd_file(self, passwd=None):
                 f.write(ipautil.ipa_generate_password())
 
     def create_certdbs(self):
-        self.nssdb.create_db(user=self.user, group=self.group, mode=self.mode,
-                             backup=True)
+        self.nssdb.create_db(
+            user=self.user, group=self.group, mode=self.mode,
+            backup=True
+        )
         self.set_perms(self.passwd_fname, write=True)
 
     def restore(self):
@@ -633,6 +654,49 @@ def is_ipa_issued_cert(self, api, nickname):
 
         return DN(cert.issuer) == cacert_subject
 
+    def disable_system_trust(self):
+        """Disable system trust module of NSSDB
+        """
+        name = 'Root Certs'
+        try:
+            result = self.run_modutil(
+                ['-force', '-list', name],
+                env={},
+                capture_output=True
+            )
+        except ipautil.CalledProcessError as e:
+            if e.returncode == 29:  # ERROR: Module not found in database.
+                logger.debug(
+                    'Module %s not available, treating as disabled', name)
+                return False
+            raise
+
+        if 'Status: Enabled' in result.output:
+            self.run_modutil(
+                ['-force', '-disable', name],
+                env={}
+            )
+            return True
+
+        return False
+
+    def needs_upgrade_format(self):
+        """Check if NSSDB file format needs upgrade
+
+        Only upgrade if it's an existing dbm database and default
+        database type is no 'dbm'.
+        """
+        return (
+            self.nssdb.dbtype == 'dbm' and
+            self.nssdb.dbtype != constants.NSS_DEFAULT_DBTYPE and
+            self.exists()
+        )
+
+    def upgrade_format(self):
+        """Upgrade NSSDB to new file format
+        """
+        self.nssdb.convert_db()
+
 
 class _CrossProcessLock(object):
     _DATETIME_FORMAT = '%Y%m%d%H%M%S%f'
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 9d7c119cd3..1e3063b1e3 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -128,6 +128,18 @@ def __init__(self, fstore=None, cert_nickname='Server-Cert',
 
     subject_base = ipautil.dn_attribute_property('_subject_base')
 
+    def _get_certdb(self, create=False):
+        return certs.CertDB(
+            self.realm,
+            fstore=self.fstore,
+            nssdir=paths.HTTPD_ALIAS_DIR,
+            subject_base=self.subject_base,
+            user="root",
+            group=constants.HTTPD_GROUP,
+            create=create,
+            dbtype='auto'
+        )
+
     def create_instance(self, realm, fqdn, domain_name, dm_password=None,
                         pkcs12_info=None,
                         subject_base=None, auto_redirect=True, ca_file=None,
@@ -302,13 +314,45 @@ def __disable_mod_nss_ocsp(self):
             aug.set(ocsp_comment, '{} {}'.format(OCSP_DIRECTIVE, ocsp_state))
             aug.save()
 
-
     def set_mod_nss_cipher_suite(self):
         ciphers = ','.join(NSS_CIPHER_SUITE)
-        installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSCipherSuite', ciphers, False)
+        installutils.set_directive(
+            paths.HTTPD_NSS_CONF,
+            'NSSCipherSuite',
+            ciphers,
+            False
+        )
 
     def __set_mod_nss_passwordfile(self):
-        installutils.set_directive(paths.HTTPD_NSS_CONF, 'NSSPassPhraseDialog', 'file:' + paths.HTTPD_PASSWORD_CONF)
+        installutils.set_directive(
+            paths.HTTPD_NSS_CONF,
+            'NSSPassPhraseDialog', 'file:' + paths.HTTPD_PASSWORD_CONF
+        )
+
+    def set_mod_nss_certdb(self):
+        db = self._get_certdb()
+        if db.dbtype == 'sql':
+            certdb = '{}:{}'.format(db.dbtype, db.secdir)
+        else:
+            certdb = db.secdir
+        installutils.set_directive(
+            paths.HTTPD_NSS_CONF,
+            'NSSCertificateDatabase',
+            certdb
+        )
+
+    def migrate_nssdb_sql(self):
+        # need to shut down all access to NSSDB first
+        if self.is_running():
+            raise RuntimeError("Cannot upgrade while HTTPD is running")
+        db = self._get_certdb()
+        if db.needs_upgrade_format():
+            logger.info("Upgrading NSSDB")
+            db.upgrade_format()
+            logger.info(
+                "NSSDB successfully migrated %s:%s",
+                db.dbtype, db.secdir
+            )
 
     def __add_include(self):
         """This should run after __set_mod_nss_port so is already backed up"""
@@ -368,33 +412,22 @@ def create_password_conf(self):
         os.chmod(pwd_conf, 0o400)
 
     def disable_system_trust(self):
-        name = 'Root Certs'
-        args = [paths.MODUTIL, '-dbdir', paths.HTTPD_ALIAS_DIR, '-force']
-
-        try:
-            result = ipautil.run(args + ['-list', name],
-                                 env={},
-                                 capture_output=True)
-        except ipautil.CalledProcessError as e:
-            if e.returncode == 29:  # ERROR: Module not found in database.
-                logger.debug(
-                    'Module %s not available, treating as disabled', name)
-                return False
-            raise
-
-        if 'Status: Enabled' in result.output:
-            ipautil.run(args + ['-disable', name], env={})
-            return True
-
-        return False
+        db = self._get_certdb()
+        return db.disable_system_trust()
 
     def __setup_ssl(self):
-        db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
-                          subject_base=self.subject_base, user="root",
-                          group=constants.HTTPD_GROUP,
-                          create=True)
+        db = self._get_certdb(create=True)
+        if not db.exists() or db.dbtype != constants.NSS_DEFAULT_DBTYPE:
+            raise RuntimeError(
+                "DB creation failed: {}:{}".format(db.dbtype, db.secdir)
+            )
         self.disable_system_trust()
         self.create_password_conf()
+        logger.info(
+            "HTTPD NSSDB '%s': %s",
+            paths.HTTPD_ALIAS_DIR,
+            ", ".join(sorted(os.listdir(paths.HTTPD_ALIAS_DIR)))
+        )
 
         if self.pkcs12_info:
             if self.ca_is_configured:
@@ -452,6 +485,12 @@ def __setup_ssl(self):
                     certmonger.modify_ca_helper('IPA', prev_helper)
 
             self.cert = db.get_cert_from_db(self.cert_nickname)
+            if self.cert is None:
+                raise RuntimeError(
+                    "{} has no valid cert {}".format(
+                        db.secdir, self.cert_nickname
+                    )
+                )
 
             if prev_helper is not None:
                 self.add_cert_to_service()
@@ -465,14 +504,12 @@ def __setup_ssl(self):
         self.cacert_nickname = db.cacert_name
 
     def __import_ca_certs(self):
-        db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
-                          subject_base=self.subject_base)
+        db = self._get_certdb()
         self.import_ca_certs(db, self.ca_is_configured)
 
     def __publish_ca_cert(self):
-        ca_db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
-                             subject_base=self.subject_base)
-        ca_db.export_pem_cert(self.cacert_nickname, paths.CA_CRT)
+        db = self._get_certdb()
+        db.export_pem_cert(self.cacert_nickname, paths.CA_CRT)
 
     def is_kdcproxy_configured(self):
         """Check if KDC proxy has already been configured in the past"""
@@ -548,12 +585,17 @@ def uninstall(self):
                 ca_iface.Set('org.fedorahosted.certmonger.ca',
                              'external-helper', helper)
 
-        db = certs.CertDB(self.realm, paths.HTTPD_ALIAS_DIR)
+        db = self._get_certdb()
         db.restore()
 
-        for f in [paths.HTTPD_IPA_CONF, paths.HTTPD_SSL_CONF, paths.HTTPD_NSS_CONF]:
+        configs = [
+            paths.HTTPD_IPA_CONF,
+            paths.HTTPD_SSL_CONF,
+            paths.HTTPD_NSS_CONF
+        ]
+        for config in configs:
             try:
-                self.fstore.restore_file(f)
+                self.fstore.restore_file(config)
             except ValueError as error:
                 logger.debug("%s", error)
 
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
index 51e0a5932e..3bcf62de12 100644
--- a/ipaserver/install/service.py
+++ b/ipaserver/install/service.py
@@ -367,6 +367,8 @@ def add_cert_to_service(self):
 
         This server cert should be in DER format.
         """
+        if self.cert is None:
+            raise ValueError("{} has no cert".format(self.service_name))
         dn = DN(('krbprincipalname', self.principal), ('cn', 'services'),
                 ('cn', 'accounts'), self.suffix)
         entry = api.Backend.ldap2.get_entry(dn)
diff --git a/ipatests/test_ipapython/test_certdb.py b/ipatests/test_ipapython/test_certdb.py
index 0dc4505552..9ff38598d6 100644
--- a/ipatests/test_ipapython/test_certdb.py
+++ b/ipatests/test_ipapython/test_certdb.py
@@ -30,11 +30,13 @@ def test_dbm_tmp():
 
         for filename in nssdb.filenames:
             assert not os.path.isfile(filename)
+        assert not nssdb.exists()
 
         nssdb.create_db()
         for filename in nssdb.filenames:
             assert os.path.isfile(filename)
             assert os.path.dirname(filename) == nssdb.secdir
+        assert nssdb.exists()
 
         assert os.path.basename(nssdb.certdb) == 'cert8.db'
         assert nssdb.certdb in nssdb.filenames
@@ -48,11 +50,13 @@ def test_sql_tmp():
 
         for filename in nssdb.filenames:
             assert not os.path.isfile(filename)
+        assert not nssdb.exists()
 
         nssdb.create_db()
         for filename in nssdb.filenames:
             assert os.path.isfile(filename)
             assert os.path.dirname(filename) == nssdb.secdir
+        assert nssdb.exists()
 
         assert os.path.basename(nssdb.certdb) == 'cert9.db'
         assert nssdb.certdb in nssdb.filenames
@@ -65,6 +69,7 @@ def test_convert_db():
         assert nssdb.dbtype == 'dbm'
 
         nssdb.create_db()
+        assert nssdb.exists()
 
         create_selfsigned(nssdb)
 
@@ -74,6 +79,7 @@ def test_convert_db():
         assert len(oldkeys) == 1
 
         nssdb.convert_db()
+        assert nssdb.exists()
 
         assert nssdb.dbtype == 'sql'
         newcerts = nssdb.list_certs()
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org

Reply via email to