Makefile.am | 1
Makefile.in | 1
ldap/admin/src/scripts/70upgradefromldif.pl | 112 ++++++++++++++++++++++++++++
ldap/admin/src/scripts/setup-ds.res.in | 3
4 files changed, 116 insertions(+), 1 deletion(-)
New commits:
commit 0580a92aed03dbbf4f6fa8c0da679307c67056ed
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri May 6 13:05:07 2011 -0600
Bug 703990 - Support upgrade from Red Hat Directory Server
https://bugzilla.redhat.com/show_bug.cgi?id=703990
Resolves: bug 703990
Bug Description: Support upgrade from Red Hat Directory Server
Reviewed by: nkinder (Thanks!)
When doing an upgrade to a machine of a new architecture, allow the
database to be upgraded "in place" by setup-ds.pl -u with LDIF files.
If there is a file in the database ldif directory called
backendname.upgrade.ldif, this file will be imported and renamed
if the import was successful.
Also fixed a bug in setup-ds.res
Flag Day: yes
Docs: yes
diff --git a/Makefile.am b/Makefile.am
index d9c5352..b22d003 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -470,6 +470,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
ldap/admin/src/scripts/50refintprecedence.ldif \
ldap/admin/src/scripts/50retroclprecedence.ldif \
ldap/admin/src/scripts/60upgradeschemafiles.pl \
+ ldap/admin/src/scripts/70upgradefromldif.pl \
ldap/admin/src/scripts/90subtreerename.pl \
ldap/admin/src/scripts/80upgradednformat.pl \
ldap/admin/src/scripts/81changelog.pl \
diff --git a/Makefile.in b/Makefile.in
index 2c3c311..c6e9742 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1659,6 +1659,7 @@ update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
ldap/admin/src/scripts/50refintprecedence.ldif \
ldap/admin/src/scripts/50retroclprecedence.ldif \
ldap/admin/src/scripts/60upgradeschemafiles.pl \
+ ldap/admin/src/scripts/70upgradefromldif.pl \
ldap/admin/src/scripts/90subtreerename.pl \
ldap/admin/src/scripts/80upgradednformat.pl \
ldap/admin/src/scripts/81changelog.pl \
diff --git a/ldap/admin/src/scripts/70upgradefromldif.pl
b/ldap/admin/src/scripts/70upgradefromldif.pl
new file mode 100644
index 0000000..a6ec644
--- /dev/null
+++ b/ldap/admin/src/scripts/70upgradefromldif.pl
@@ -0,0 +1,112 @@
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Entry;
+use Mozilla::LDAP::Utils qw(normalizeDN);
+use Mozilla::LDAP::API qw(:constant ldap_url_parse ldap_explode_dn);
+use File::Basename;
+use File::Copy;
+use DSUtil qw(debug);
+
+# Used to upgrade from an older version whose database might not be
+# compatible - also for an upgrade from a machine of a different
+# architecture
+# For each backend instance, the ldif directory should contain
+# a file called BACKEND.ldif e.g. userRoot.ldif NetscapeRoot.ldif etc.
+# each file will be imported
+# if the import is successful, the file will be renamed so that if
+# upgrade is run again, it will not attempt to import it again, but
+# it will be left around as a backup
+sub runinst {
+ my ($inf, $inst, $dseldif, $conn) = @_;
+
+ my @errs;
+
+ my $config = "cn=config";
+ my $config_entry = $conn->search($config, "base", "(cn=*)");
+ if (!$config_entry) {
+ return ("error_no_configuration_entry", $!);
+ }
+ my $ldifdir = $config_entry->getValues('nsslapd-ldifdir');
+ if (!$ldifdir) {
+ debug(1, "No such attribute nsslapd-ldifdir in cn=config in $inst\n");
+ return (); # nothing to do
+ }
+ my $rundir = $config_entry->getValues('nsslapd-rundir');
+ my $instdir = $config_entry->getValues('nsslapd-instancedir');
+ my $isrunning = 0;
+ # Check if the server is up or not
+ my $pidfile = $rundir . "/" . $inst . ".pid";
+ if (-e $pidfile) {
+ $isrunning = 1;
+ }
+
+ for my $file (glob("$ldifdir/*.upgrade.ldif")) {
+ # assumes file name is backendname.upgrade.ldif
+ my $dbinst = basename($file, ".upgrade.ldif");
+ @errs = importLDIF($conn, $file, $dbinst, $isrunning, $instdir);
+ if (@errs) {
+ return @errs;
+ }
+ # else ok - rename file so we don't try to import again
+ my $newfile = $file . ".importok";
+ rename($file, $newfile);
+ }
+
+ return ();
+}
+
+sub startTaskAndWait {
+ my ($conn, $entry) = @_;
+
+ my $dn = $entry->getDN();
+ # start the task
+ $conn->add($entry);
+ my $rc;
+ if ($rc = $conn->getErrorCode()) {
+ debug(0, "Couldn't add entry $dn: " . $conn->getErrorString());
+ return $rc;
+ }
+
+ # wait for task completion - task is complete when the nsTaskExitCode attr is set
+ my @attrlist = qw(nsTaskLog nsTaskStatus nsTaskExitCode nsTaskCurrentItem
nsTaskTotalItems);
+ my $done = 0;
+ my $exitCode = 0;
+ while (! $done) {
+ sleep 1;
+ $entry = $conn->search($dn, "base", "(objectclass=*)", 0,
@attrlist);
+ if ($entry->exists('nsTaskExitCode')) {
+ $exitCode = $entry->getValues('nsTaskExitCode');
+ $done = 1;
+ } else {
+ debug(1, $entry->getValues('nsTaskLog') . "\n");
+ }
+ }
+
+ return $exitCode;
+}
+
+sub importLDIF {
+ my ($conn, $file, $be, $isrunning, $rc) = @_;
+
+ if ($isrunning) {
+ my $cn = "import" . time;
+ my $dn = "cn=$cn,cn=import,cn=tasks,cn=config";
+ my $entry = new Mozilla::LDAP::Entry();
+ $entry->setDN($dn);
+ $entry->setValues('objectclass', 'top',
'extensibleObject');
+ $entry->setValues('cn', $cn);
+ $entry->setValues('nsFilename', $file);
+ $entry->setValues('nsInstance', $be);
+ $rc = startTaskAndWait($conn, $entry);
+ if ($rc) {
+ return ('error_import_check_log', $file, $be, $rc . ":" .
$conn->getErrorString());
+ }
+ } else { # server down - use ldif2db
+ $? = 0; # clear
+ if ($rc = system("$instdir/ldif2db -n $be -i $file > /dev/null
2>&1")) {
+ debug(0, "Could not import $file to database $be - check errors
log\n");
+ return ('error_import_check_log', $file, $be, $rc);
+ }
+ }
+
+ return ();
+}
diff --git a/ldap/admin/src/scripts/setup-ds.res.in
b/ldap/admin/src/scripts/setup-ds.res.in
index 1814493..9d164e9 100644
--- a/ldap/admin/src/scripts/setup-ds.res.in
+++ b/ldap/admin/src/scripts/setup-ds.res.in
@@ -185,7 +185,7 @@ or use offline mode.\n\n
error_offline_update = Could not read the server config file '%s'. Error: %s\n\n
error_no_mapping_tree_entries = Could not find a mapping tree entry. Error: %s\n
error_no_configuration_entry = Could not find a configuration entry. Error: %s\n
-error_no_configuration_entry = Could not find a backend entry. Error: %s\n
+error_no_backend_entry = Could not find a backend entry. Error: %s\n
error_invalid_dbinst_dir = Invalid database instance dir '%s'.\n
error_cant_backup_db = Failed to back up backend instance '%s'. Error: %s\n
error_cant_convert_db = Failed to convert backend instance '%s'. Error: %s\n
@@ -200,3 +200,4 @@ Please check the spelling of the hostname and/or your network
configuration.\
If you proceed with this hostname, you may encounter problems.\
\
Do you want to proceed with hostname '%s'?
+error_import_check_log = Error: unable to import file '%s' for backend
'%s' - %s. Check the errrors log for additional information\n