Improve validation of --instance and --backend options in ipa-restore

https://fedorahosted.org/freeipa/ticket/4744

Reviewed-By: David Kupka <dkupka@redhat.com>
This commit is contained in:
Jan Cholasta 2014-12-01 12:12:15 +00:00
parent 1f6fff2b5a
commit 7b0149f32b
3 changed files with 46 additions and 31 deletions

View File

@ -263,7 +263,7 @@ class BasePathNamespace(object):
VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE = "/var/lib/dirsrv/scripts-%s" VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE = "/var/lib/dirsrv/scripts-%s"
VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s" VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s"
SLAPD_INSTANCE_BACKUP_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/bak/%s" SLAPD_INSTANCE_BACKUP_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/bak/%s"
IPACA_DIRSRV_INSTANCE_DB_TEMPLATE = "/var/lib/dirsrv/slapd-%s/db/ipaca" SLAPD_INSTANCE_DB_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/db/%s"
SLAPD_INSTANCE_LDIF_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/ldif" SLAPD_INSTANCE_LDIF_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/ldif"
VAR_LIB_SLAPD_PKI_IPA_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-PKI-IPA" VAR_LIB_SLAPD_PKI_IPA_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-PKI-IPA"
VAR_LIB_IPA = "/var/lib/ipa" VAR_LIB_IPA = "/var/lib/ipa"

View File

@ -292,7 +292,7 @@ class Backup(admintool.AdminTool):
for instance in [realm_to_serverid(api.env.realm), 'PKI-IPA']: for instance in [realm_to_serverid(api.env.realm), 'PKI-IPA']:
if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % instance): if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % instance):
if os.path.exists(paths.IPACA_DIRSRV_INSTANCE_DB_TEMPLATE % instance): if os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE % (instance, 'ipaca')):
self.db2ldif(instance, 'ipaca', online=options.online) self.db2ldif(instance, 'ipaca', online=options.online)
self.db2ldif(instance, 'userRoot', online=options.online) self.db2ldif(instance, 'userRoot', online=options.online)
self.db2bak(instance, online=options.online) self.db2bak(instance, online=options.online)

View File

@ -187,15 +187,35 @@ class Restore(admintool.AdminTool):
self.log.info("Preparing restore from %s on %s", self.log.info("Preparing restore from %s on %s",
self.backup_dir, api.env.host) self.backup_dir, api.env.host)
if not options.instance: if options.instance and options.backend:
instances = [] database = (options.instance, options.backend)
for instance in [realm_to_serverid(api.env.realm), 'PKI-IPA']: if not os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % instance): database):
instances.append(instance) raise admintool.ScriptError(
"Instance %s with backend %s does not exist" % database)
databases = [database]
else: else:
instances = [options.instance] if options.instance:
if options.data_only and not instances: instances = [options.instance]
raise admintool.ScriptError('No instances to restore to') else:
instances = [realm_to_serverid(api.env.realm), 'PKI-IPA']
if options.backend:
backends = [options.backend]
else:
backends = ['userRoot', 'ipaca']
databases = []
for instance in instances:
for backend in backends:
database = (instance, backend)
if os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
database):
databases.append(database)
if options.data_only and not databases:
raise admintool.ScriptError('No instances to restore to')
create_ds_user() create_ds_user()
pent = pwd.getpwnam(DS_USER) pent = pwd.getpwnam(DS_USER)
@ -222,7 +242,7 @@ class Restore(admintool.AdminTool):
# These two checks would normally be in the validate method but # These two checks would normally be in the validate method but
# we need to know the type of backup we're dealing with. # we need to know the type of backup we're dealing with.
if (self.backup_type != 'FULL' and not options.data_only and if (self.backup_type != 'FULL' and not options.data_only and
not instances): not databases):
raise admintool.ScriptError('Cannot restore a data backup into an empty system') raise admintool.ScriptError('Cannot restore a data backup into an empty system')
if (self.backup_type == 'FULL' and not options.data_only and if (self.backup_type == 'FULL' and not options.data_only and
(options.instance or options.backend)): (options.instance or options.backend)):
@ -243,6 +263,15 @@ class Restore(admintool.AdminTool):
not user_input("Continue to restore?", False)): not user_input("Continue to restore?", False)):
raise admintool.ScriptError("Aborted") raise admintool.ScriptError("Aborted")
self.extract_backup(options.gpg_keyring)
for database in databases:
ldifname = '%s-%s.ldif' % database
ldiffile = os.path.join(self.dir, ldifname)
if not os.path.exists(ldiffile):
raise admintool.ScriptError(
"Instance %s with backend %s not in backup" % database)
# Big fat warning # Big fat warning
if (not options.unattended and if (not options.unattended and
not user_input("Restoring data will overwrite existing live data. Continue to restore?", False)): not user_input("Restoring data will overwrite existing live data. Continue to restore?", False)):
@ -260,7 +289,6 @@ class Restore(admintool.AdminTool):
self.log.info("Disabling all replication.") self.log.info("Disabling all replication.")
self.disable_agreements() self.disable_agreements()
self.extract_backup(options.gpg_keyring)
if options.data_only: if options.data_only:
if not options.online: if not options.online:
self.log.info('Stopping Directory Server') self.log.info('Stopping Directory Server')
@ -294,16 +322,8 @@ class Restore(admintool.AdminTool):
# userRoot backend in it and the main IPA instance. If we # userRoot backend in it and the main IPA instance. If we
# have a unified instance we need to restore both userRoot and # have a unified instance we need to restore both userRoot and
# ipaca. # ipaca.
for instance in instances: for instance, backend in databases:
if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % instance): self.ldif2db(instance, backend, online=options.online)
if options.backend is None:
self.ldif2db(instance, 'userRoot', online=options.online)
if os.path.exists(paths.IPACA_DIRSRV_INSTANCE_DB_TEMPLATE % instance):
self.ldif2db(instance, 'ipaca', online=options.online)
else:
self.ldif2db(instance, options.backend, online=options.online)
else:
raise admintool.ScriptError('389-ds instance %s does not exist' % instance)
if options.data_only: if options.data_only:
if not options.online: if not options.online:
@ -446,20 +466,15 @@ class Restore(admintool.AdminTool):
try: try:
conn.add_entry(ent) conn.add_entry(ent)
except Exception, e: except Exception, e:
raise admintool.ScriptError( self.log.error("Unable to bind to LDAP server: %s" % e)
'Unable to bind to LDAP server: %s' % e) return
self.log.info("Waiting for LDIF to finish") self.log.info("Waiting for LDIF to finish")
wait_for_task(conn, dn) wait_for_task(conn, dn)
else: else:
args = ['%s/ldif2db' % self.__find_scripts_dir(instance), args = ['%s/ldif2db' % self.__find_scripts_dir(instance),
'-i', ldiffile] '-i', ldiffile,
if backend is not None: '-n', backend]
args.append('-n')
args.append(backend)
else:
args.append('-n')
args.append('userRoot')
(stdout, stderr, rc) = run(args, raiseonerr=False) (stdout, stderr, rc) = run(args, raiseonerr=False)
if rc != 0: if rc != 0:
self.log.critical("ldif2db failed: %s" % stderr) self.log.critical("ldif2db failed: %s" % stderr)