summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Megginson <rmeggins@redhat.com>2009-02-27 14:33:12 +0000
committerRich Megginson <rmeggins@redhat.com>2009-02-27 14:33:12 +0000
commit463bac4de552803d0a937617999c384181aa4ea5 (patch)
treef804a58416ecd75f0067ce4891dccc3e5fb617fb
parent489e3dd14c62e55fd26135a676f66dbe0627ecaf (diff)
downloadds-463bac4de552803d0a937617999c384181aa4ea5.tar.gz
ds-463bac4de552803d0a937617999c384181aa4ea5.tar.xz
ds-463bac4de552803d0a937617999c384181aa4ea5.zip
Resolves: bug 480869
Bug Description: DS console: Can not delete DS instance Reviewed by: nkinder (Thanks!) Fix Description: As it turns out, my assumption that ds_remove in CGI mode also did the unregistration was false. It is the console that does the unregistration, only after the ds_remove CGI returns success. So, ds_remove needs to run with AdminSDK off, just like the other "special" CGI programs. In addition, ds_remove needs to be more robust - if there is an error during ds_remove, you should be allowed to try again after fixing something. However, the way the error handling worked did not differentiate between fatal errors and errors that could be ignored. In order to do this properly, we need to propagate the errors back up to the top level (oh how I wish perl had real exception handling . . .). The main type of error we need to ignore is file not found or process not found. If we attempted to remove before and that attempt failed for some reason, and left a partial instance, we need to be able to run the remove command again, skipping over the things we shutdown or removed already, and clean up the stuff we need to remove. This can also happen if you use the console to create a ds instance, and remove-ds.pl to remove the instance. The instance will still show up in the console. We need to be able to use the Remove Server in the console to remove the instance from the console, even through there is no physical instance on disk any more. Since the console will only do the unregistration if the CGI returns success, we need to make sure the CGI returns success even though there is no instance on disk. When ds_remove is run via ds_removal, it will do the unregistration. I also took this opportunity to refactor the remove code, creating a removeDSInstance method in DSCreate.pm, and moving some of the other removal helper functions to Util.pm. That simplified the code in both ds_remove and remove-ds.pl. I added a remove-ds-admin.pl script - one of the problems that users have is that they run setup-ds-admin.pl, then hit some error (e.g. bad DNS setup), then find that they cannot restore the system to the state before they ran setup-ds-admin.pl. remove-ds-admin.pl does this. Finally, I added some man pages to the admin package for those commonly used commands. Platforms tested: RHEL4 Flag Day: no Doc impact: no
-rw-r--r--ldap/admin/src/scripts/DSCreate.pm.in132
-rw-r--r--ldap/admin/src/scripts/DSMigration.pm.in26
-rw-r--r--ldap/admin/src/scripts/FileConn.pm21
-rw-r--r--ldap/admin/src/scripts/Inf.pm10
-rw-r--r--ldap/admin/src/scripts/SetupLog.pm5
-rw-r--r--ldap/admin/src/scripts/Util.pm.in106
-rwxr-xr-xldap/admin/src/scripts/remove-ds.pl.in198
-rw-r--r--ldap/admin/src/scripts/setup-ds.res.in4
-rw-r--r--man/man8/migrate-ds.pl.811
-rw-r--r--man/man8/remove-ds.pl.85
10 files changed, 321 insertions, 197 deletions
diff --git a/ldap/admin/src/scripts/DSCreate.pm.in b/ldap/admin/src/scripts/DSCreate.pm.in
index 89f0ba00..471c9dd9 100644
--- a/ldap/admin/src/scripts/DSCreate.pm.in
+++ b/ldap/admin/src/scripts/DSCreate.pm.in
@@ -54,6 +54,7 @@ use File::Temp qw(tempfile tempdir);
use File::Path;
use File::Copy;
use File::Basename qw(basename dirname);
+use POSIX qw(:errno_h);
# load perldap
use Mozilla::LDAP::Conn;
@@ -63,8 +64,8 @@ use Mozilla::LDAP::LDIF;
use Exporter;
@ISA = qw(Exporter);
-@EXPORT = qw(createDSInstance);
-@EXPORT_OK = qw(createDSInstance);
+@EXPORT = qw(createDSInstance removeDSInstance);
+@EXPORT_OK = qw(createDSInstance removeDSInstance);
use strict;
@@ -897,6 +898,133 @@ sub createDSInstance {
return @errs;
}
+sub stopServer {
+ my $instancedir = shift;
+ my $prog = $instancedir . "/stop-slapd";
+ if (-x $prog) {
+ $? = 0;
+ # run the stop command
+ my $output = `$prog 2>&1`;
+ my $status = $?;
+ debug(3, "stopping server $instancedir returns status $status: output $output\n");
+ if ($status) {
+ debug(1,"Warning: Could not stop directory server: status $status: output $output\n");
+ # if the server is not running, that's ok
+ if ($output =~ /not running/) {
+ $! = ENOENT;
+ return 1;
+ }
+ # else, some other error (e.g. permission) - return false for error
+ return;
+ }
+ } else {
+ debug(1, "stopping server: no such program $prog: cannot stop server\n");
+ return;
+ }
+
+ debug(1, "Successfully stopped server $instancedir\n");
+ return 1;
+}
+
+# NOTE: Returns a list of array ref - each array ref is suitable for passing
+# to Resource::getText
+sub removeDSInstance {
+ my $inst = shift;
+ my $force = shift;
+ my $baseconfigdir = $ENV{DS_CONFIG_DIR} || "@instconfigdir@";
+ my $instname = "slapd-$inst";
+ my $configdir = "$baseconfigdir/$instname";
+ my @errs;
+ if ( ! -d $configdir )
+ {
+ debug(1, "Error: $configdir does not exist: $!\n");
+ return ( [ 'error_no_such_instance', $configdir, $! ] );
+ }
+ # read the config file to find out the paths
+ my $dseldif = "$configdir/dse.ldif";
+ my $conn = new FileConn($dseldif, 1);
+ if (!$conn) {
+ debug(1, "Error: Could not open config file $dseldif: Error $!\n");
+ return ( [ 'error_opening_dseldif', $dseldif, $! ] );
+ }
+
+ my $dn = "cn=config";
+ my $entry = $conn->search($dn, "base", "(cn=*)", 0);
+ if (!$entry)
+ {
+ debug(1, "Error: Search $dn in $dseldif failed: $entry\n");
+ push @errs, [ 'error_finding_config_entry', $dn, $dseldif, $conn->getErrorString() ];
+ }
+
+ $dn = "cn=config,cn=ldbm database,cn=plugins,cn=config";
+ my $dbentry = $conn->search($dn, "base", "(cn=*)", 0);
+ if (!$dbentry)
+ {
+ debug(1, "Error: Search $dn in $dseldif failed: $dbentry\n");
+ push @errs, [ 'error_finding_config_entry', $dn, $dseldif, $conn->getErrorString() ];
+ }
+ $conn->close();
+
+ # stop the server
+ my $instdir = "";
+ if ($entry) {
+ foreach my $path ( @{$entry->{"nsslapd-instancedir"}} )
+ {
+ if (!stopServer($path)) {
+ if ($force) {
+ debug(1, "Warning: Could not stop directory server - Error: $! - forcing continue\n");
+ } elsif ($! == ENOENT) { # stop script not found or server not running
+ debug(1, "Warning: Could not stop directory server: already removed or not running\n");
+ push @errs, [ 'error_stopping_server', $path, $! ];
+ } else { # real error
+ debug(1, "Error: Could not stop directory server - aborting - use -f flag to force removal\n");
+ push @errs, [ 'error_stopping_server', $path, $! ];
+ return @errs;
+ }
+ }
+ $instdir = $path;
+ }
+ }
+
+ # remove physical dirs/files
+ if ($dbentry) {
+ push @errs, remove_tree($dbentry, "nsslapd-directory", $instname, 1);
+ push @errs, remove_tree($dbentry, "nsslapd-db-logdirectory", $instname, 1);
+ }
+ if ($entry) {
+ push @errs, remove_tree($entry, "nsslapd-lockdir", $instname);
+ push @errs, remove_tree($entry, "nsslapd-tmpdir", $instname);
+ push @errs, remove_tree($entry, "nsslapd-bakdir", $instname, 1);
+ push @errs, remove_tree($entry, "nsslapd-errorlog", $instname, 1);
+ }
+
+ # instance dir
+ if ( -d $instdir && $instdir =~ /$instname/ )
+ {
+ # clean up pid files (if any)
+ remove_pidfile("STARTPIDFILE", $instdir, $instname);
+ remove_pidfile("PIDFILE", $instdir, $instname);
+
+ my $rc = rmtree($instdir);
+ if ( 0 == $rc )
+ {
+ push @errs, [ 'error_removing_path', $instdir, $! ];
+ debug(1, "Warning: $instdir was not removed. Error: $!\n");
+ }
+ }
+ # Finally, config dir
+ push @errs, remove_tree($entry, "nsslapd-schemadir", $instname, 1, "\.db\$");
+
+ # if we got here, report success
+ if (@errs) {
+ debug(1, "Could not successfully remove $instname\n");
+ } else {
+ debug(1, "Instance $instname removed.\n");
+ }
+
+ return @errs;
+}
+
1;
# emacs settings
diff --git a/ldap/admin/src/scripts/DSMigration.pm.in b/ldap/admin/src/scripts/DSMigration.pm.in
index da51d4df..58f6227a 100644
--- a/ldap/admin/src/scripts/DSMigration.pm.in
+++ b/ldap/admin/src/scripts/DSMigration.pm.in
@@ -363,7 +363,10 @@ sub migrateNetscapeRoot {
($fh, $tmpldiffile) = tempfile("nsrootXXXXXX", UNLINK => 0,
SUFFIX => ".ldif", OPEN => 1,
DIR => File::Spec->tmpdir);
- open( MYLDIF, "$ldiffile" ) || confess "Can't open $ldiffile: $!";
+ if (!open( MYLDIF, "$ldiffile" )) {
+ debug(1, "Error: Can't open $ldiffile: $!");
+ return;
+ }
my $in = new Mozilla::LDAP::LDIF(*MYLDIF);
while (my $ent = readOneEntry $in) {
my $dn = $ent->getDN();
@@ -443,12 +446,16 @@ sub migrateDatabases {
my $deleteflag = 0;
if ($fname =~ /NetscapeRoot.ldif$/) {
$fname = migrateNetscapeRoot($fname);
- # make sure $fname is owned by the server user
- my $cfgent = $dest->search("cn=config", "base", "(objectclass=*)");
- my $user = $cfgent->getValues('nsslapd-localuser');
- my $uid = getpwnam $user;
- chown $uid, -1, $fname;
- $deleteflag = 1;
+ if ($fname) {
+ # make sure $fname is owned by the server user
+ my $cfgent = $dest->search("cn=config", "base", "(objectclass=*)");
+ my $user = $cfgent->getValues('nsslapd-localuser');
+ my $uid = getpwnam $user;
+ chown $uid, -1, $fname;
+ $deleteflag = 1;
+ } else {
+ return ("error_creating_templdif", $!);
+ }
}
my $cmd = "$inst_dir/ldif2db -n \"$dbname\" -i \"$fname\"";
debug(1, "migrateDatabases: executing command $cmd\n");
@@ -838,7 +845,10 @@ sub migrateSchema {
my %intattrs = ();
for (glob("$newschemadir/*.ldif")) {
# read in schema entry from LDIF
- open( MYSCHEMA, $_ ) || die "Can't open $_: $!";
+ if (!open( MYSCHEMA, $_ )) {
+ debug(0, "Can't open schema file $_: $!\n");
+ next;
+ }
my $in = new Mozilla::LDAP::LDIF(*MYSCHEMA);
while (my $ent = readOneEntry $in) {
my @attrs = $ent->getValues('attributeTypes');
diff --git a/ldap/admin/src/scripts/FileConn.pm b/ldap/admin/src/scripts/FileConn.pm
index f1ac4d2d..2ed0fe2d 100644
--- a/ldap/admin/src/scripts/FileConn.pm
+++ b/ldap/admin/src/scripts/FileConn.pm
@@ -46,7 +46,7 @@ use Mozilla::LDAP::API qw(:constant ldap_explode_dn ldap_err2string); # Direct a
use Mozilla::LDAP::Utils qw(normalizeDN);
use Mozilla::LDAP::LDIF;
-use Carp;
+use Util qw(debug);
require Exporter;
@ISA = qw(Exporter Mozilla::LDAP::Conn);
@@ -96,7 +96,7 @@ sub read {
}
if (!open( MYLDIF, "$filename" )) {
- confess "Can't open $filename: $!";
+ debug(1, "Could not open $filename: $!\n");
return 0;
}
@@ -104,7 +104,7 @@ sub read {
$self->{reading} = 1;
while ($ent = readOneEntry $in) {
if (!$self->add($ent)) {
- confess "Error: could not add entry ", $ent->getDN(), ":", $self->getErrorString();
+ debug(1, "Error: could not add entry " . $ent->getDN() . ":" . $self->getErrorString());
}
}
delete $self->{reading};
@@ -187,7 +187,7 @@ sub write {
}
if (!open( MYLDIF, ">$filename" )) {
- confess "Can't write $filename: $!";
+ debug(1, "Can't write $filename: $!\n");
return 0;
}
@@ -416,11 +416,15 @@ sub update {
my $dn = $entry->getDN();
my $ndn = normalizeDN($dn);
- confess "Attempt to modify read only $self->{filename} entry $dn" if ($self->{readonly});
+ if ($self->{readonly}) {
+ debug(1, "Attempt to update read only $self->{filename} entry $dn\n");
+ return 0;
+ }
$self->setErrorCode(0);
if (!exists($self->{$ndn})) {
$self->setErrorCode(LDAP_NO_SUCH_OBJECT);
+ debug(1, "Attempt to update entry $dn that does not exist\n");
return 0;
}
@@ -435,7 +439,10 @@ sub delete {
my $self = shift;
my $dn = shift;
- confess "Attempt to modify read only $self->{filename} entry $dn" if ($self->{readonly});
+ if ($self->{readonly}) {
+ debug(1, "Attempt to delete read only $self->{filename} entry $dn\n");
+ return 0;
+ }
if (ref($dn)) {
$dn = $dn->getDN(); # an Entry
@@ -445,11 +452,13 @@ sub delete {
$self->setErrorCode(0);
if (!exists($self->{$ndn})) {
$self->setErrorCode(LDAP_NO_SUCH_OBJECT);
+ debug(1, "Attempt to delete entry $dn that does not exist\n");
return 0;
}
if (@{$self->{$ndn}->{children}}) {
$self->setErrorCode(LDAP_NOT_ALLOWED_ON_NONLEAF);
+ debug(1, "Attempt to delete entry $dn that has children\n");
return 0;
}
diff --git a/ldap/admin/src/scripts/Inf.pm b/ldap/admin/src/scripts/Inf.pm
index 0ac11a41..091940be 100644
--- a/ldap/admin/src/scripts/Inf.pm
+++ b/ldap/admin/src/scripts/Inf.pm
@@ -82,7 +82,10 @@ sub read {
if ($filename eq "-") {
$inffh = \*STDIN;
} else {
- open INF, $filename or die "Error: could not open inf file $filename: $!";
+ if (!open(INF, $filename)) {
+ print STDERR "Error: could not open inf file $filename: $!\n";
+ return;
+ }
$inffh = \*INF;
}
while (<$inffh>) {
@@ -180,7 +183,10 @@ sub write {
return if ($filename eq "-");
- open INF, ">$filename" or die "Error: could not write inf file $filename: $!";
+ if (!open(INF, ">$filename")) {
+ print STDERR "Error: could not write inf file $filename: $!\n";
+ return;
+ }
# write General section first
$self->writeSection('General', \*INF);
print INF "\n";
diff --git a/ldap/admin/src/scripts/SetupLog.pm b/ldap/admin/src/scripts/SetupLog.pm
index f51329fc..9ff3c32f 100644
--- a/ldap/admin/src/scripts/SetupLog.pm
+++ b/ldap/admin/src/scripts/SetupLog.pm
@@ -67,7 +67,10 @@ sub new {
($fh, $filename) = tempfile("${prefix}XXXXXX", UNLINK => 0,
SUFFIX => ".log", DIR => File::Spec->tmpdir);
} else {
- open LOGFILE, ">$filename" or die "Error: could not open logfile $filename: $!";
+ if (!open(LOGFILE, ">$filename")) {
+ print STDERR "Error: could not open logfile $filename: $!\n";
+ return;
+ }
$fh = \*LOGFILE;
}
$self->{fh} = $fh;
diff --git a/ldap/admin/src/scripts/Util.pm.in b/ldap/admin/src/scripts/Util.pm.in
index 660461e7..57473833 100644
--- a/ldap/admin/src/scripts/Util.pm.in
+++ b/ldap/admin/src/scripts/Util.pm.in
@@ -48,11 +48,11 @@ require Exporter;
@EXPORT = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
process_maptbl check_and_add_entry getMappedEntries
getHashedPassword debug createInfFromConfig
- isValidServerID isValidUser makePaths getLogin);
+ isValidServerID isValidUser makePaths getLogin remove_tree remove_pidfile);
@EXPORT_OK = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
process_maptbl check_and_add_entry getMappedEntries
getHashedPassword debug createInfFromConfig
- isValidServerID isValidUser makePaths getLogin);
+ isValidServerID isValidUser makePaths getLogin remove_tree remove_pidfile);
use strict;
@@ -60,6 +60,9 @@ use Socket;
use File::Temp qw(tempfile tempdir);
use File::Basename qw(dirname);
+use File::Path qw(rmtree);
+
+use Carp;
$Util::debuglevel = 0;
# use like this:
@@ -115,8 +118,10 @@ sub isValidServerID {
# we want the name of the effective user id of this process e.g. if someone did
# an su root, we want getLogin to return "root" not the originating id (getlogin)
# in perl, $> is the effective numeric user id - we need to turn it into a string
+# use confess here because if we cannot determine the user, something is really,
+# really wrong and we need to abort immediately
sub getLogin {
- return (getpwuid($>))[0] || $ENV{USER} || die "Error: could not determine the current user ID: $!";
+ return (getpwuid($>))[0] || $ENV{USER} || confess "Error: could not determine the current user ID: $!";
}
sub isValidUser {
@@ -814,6 +819,101 @@ sub makePaths {
return ();
}
+# remove_tree($centry, $key, $instname, [$isparent, [$dontremove]])
+# $centry: entry to look for the path to be removed
+# $key: key to look for the path in the entry
+# $instname: instance name "slapd-<ID>" to check the path
+# $isparent: specify 1 to remove from the parent dir
+# $dontremove: pattern not to be removed (e.g., ".db$")
+sub remove_tree
+{
+ my $centry = shift;
+ my $key = shift;
+ my $instname = shift;
+ my $isparent = shift;
+ my $dontremove = shift;
+ my @errs = (); # a list of array refs - each array ref is suitable for passing to Resource::getText
+
+ foreach my $path ( @{$centry->{$key}} )
+ {
+ my $rmdir = "";
+ my $rc = 0;
+ if ( 1 == $isparent )
+ {
+ $rmdir = dirname($path);
+ }
+ else
+ {
+ $rmdir = $path;
+ }
+ if ( -d $rmdir && $rmdir =~ /$instname/ )
+ {
+ if ( "" eq "$dontremove" )
+ {
+ $rc = rmtree($rmdir);
+ if ( 0 == $rc )
+ {
+ push @errs, [ 'error_removing_path', $rmdir, $! ];
+ debug(1, "Warning: $rmdir was not removed. Error: $!\n");
+ }
+ }
+ else
+ {
+ # Skip the dontremove files
+ $rc = opendir(DIR, $rmdir);
+ if ($rc)
+ {
+ while (defined(my $file = readdir(DIR)))
+ {
+ next if ( "$file" =~ /$dontremove/ );
+ next if ( "$file" eq "." );
+ next if ( "$file" eq ".." );
+ my $rmfile = $rmdir . "/" . $file;
+ my $rc0 = rmtree($rmfile);
+ if ( 0 == $rc0 )
+ {
+ push @errs, [ 'error_removing_path', $rmfile, $! ];
+ debug(1, "Warning: $rmfile was not removed. Error: $!\n");
+ }
+ }
+ closedir(DIR);
+ }
+ my $newrmdir = $rmdir . ".removed";
+ my $rc1 = 1;
+ if ( -d $newrmdir )
+ {
+ $rc1 = rmtree($newrmdir);
+ if ( 0 == $rc1 )
+ {
+ push @errs, [ 'error_removing_path', $newrmdir, $! ];
+ debug(1, "Warning: $newrmdir was not removed. Error: $!\n");
+ }
+ }
+ if ( 0 < $rc1 )
+ {
+ rename($rmdir, $newrmdir);
+ }
+ }
+ }
+ }
+
+ return @errs; # a list of array refs - if (!@errs) then success
+}
+
+sub remove_pidfile
+{
+ my ($type, $instdir, $instname) = @_;
+
+ my $pattern = "^" . $type . ".*=";
+ my $pidline = `grep $pattern $instdir/start-slapd`;
+ chomp($pidline);
+ my ($key, $pidfile) = split(/=/, $pidline);
+ if ( -e $pidfile && $pidfile =~ /$instname/ )
+ {
+ unlink($pidfile);
+ }
+}
+
1;
# emacs settings
diff --git a/ldap/admin/src/scripts/remove-ds.pl.in b/ldap/admin/src/scripts/remove-ds.pl.in
index 492ccc7e..d82a1816 100755
--- a/ldap/admin/src/scripts/remove-ds.pl.in
+++ b/ldap/admin/src/scripts/remove-ds.pl.in
@@ -24,111 +24,22 @@ use strict;
use File::Basename;
use File::Path;
use Util;
-use FileConn;
+use Resource;
+use DSCreate qw(removeDSInstance);
+
+my $res = new Resource("@propertydir@/setup-ds.res");
sub usage {
- print(STDERR "Usage: $0 [-f] -i instance\n\n");
+ print(STDERR "Usage: $0 [-f] [-d -d ... -d] -i instance\n\n");
print(STDERR " Opts: -f - force removal\n");
- print(STDERR " -i instance - instance name to remove (e.g. - slapd-example)\n");
-}
-
-# remove_tree($centry, $key, $instname, [$isparent, [$dontremove]])
-# $centry: entry to look for the path to be removed
-# $key: key to look for the path in the entry
-# $instname: instance name "slapd-<ID>" to check the path
-# $isparent: specify 1 to remove from the parent dir
-# $dontremove: pattern not to be removed (e.g., ".db$")
-sub remove_tree
-{
- my $centry = shift;
- my $key = shift;
- my $instname = shift;
- my $isparent = shift;
- my $dontremove = shift;
-
- foreach my $path ( @{$centry->{$key}} )
- {
- my $rmdir = "";
- my $rc = 0;
- if ( 1 == $isparent )
- {
- $rmdir = dirname($path);
- }
- else
- {
- $rmdir = $path;
- }
- if ( -d $rmdir && $rmdir =~ /$instname/ )
- {
- if ( "" eq "$dontremove" )
- {
- $rc = rmtree($rmdir);
- if ( 0 == $rc )
- {
- print STDERR "Warning: $rmdir was not removed.\n";
- }
- }
- else
- {
- # Skip the dontremove files
- $rc = opendir(DIR, $rmdir);
- if ($rc)
- {
- while (defined(my $file = readdir(DIR)))
- {
- next if ( "$file" =~ /$dontremove/ );
- next if ( "$file" eq "." );
- next if ( "$file" eq ".." );
- my $rmfile = $rmdir . "/" . $file;
- my $rc0 = rmtree($rmfile);
- if ( 0 == $rc0 )
- {
- print STDERR "Warning: $rmfile was not removed.\n";
- }
- }
- closedir(DIR);
- }
- my $newrmdir = $rmdir . ".removed";
- my $rc1 = 1;
- if ( -d $newrmdir )
- {
- $rc1 = rmtree($newrmdir);
- if ( 0 == $rc1 )
- {
- print STDERR "Warning: $newrmdir was not removed.\n";
- }
- }
- if ( 0 < $rc1 )
- {
- rename($rmdir, $newrmdir);
- }
- }
- }
- }
-}
-
-sub remove_pidfile
-{
- my ($type, $instdir, $instname) = @_;
-
- my $pattern = "^" . $type . ".*=";
- my $pidline = `grep $pattern $instdir/start-slapd`;
- chomp($pidline);
- my ($key, $pidfile) = split(/=/, $pidline);
- if ( -e $pidfile && $pidfile =~ /$instname/ )
- {
- unlink($pidfile);
- }
+ print(STDERR " -i instance - instance name to remove (e.g. - slapd-example)\n");
+ print(STDERR " -d - turn on debugging output\n");
}
my $i = 0;
my $force = "";
my $instname = "";
-if ($#ARGV > 2) {
- &usage; exit(1);
-}
-
# load args from the command line
while ($i <= $#ARGV) {
if ( "$ARGV[$i]" eq "-f" ) {
@@ -136,6 +47,10 @@ while ($i <= $#ARGV) {
} elsif ("$ARGV[$i]" eq "-i") {
$i++;
$instname = $ARGV[$i];
+ } elsif ("$ARGV[$i]" eq "-d") {
+ $Util::debuglevel++;
+ } else {
+ &usage; exit(1);
}
$i++;
}
@@ -152,86 +67,23 @@ unless ($inst) {
exit 1;
}
-my $configdir = "@instconfigdir@/slapd-$inst";
-if ( ! -d $configdir )
-{
- print STDERR "Error: $configdir does not exist\n";
- exit 1;
-}
-
-# read the config file to find out the paths
-my $dseldif = "@instconfigdir@/$instname/dse.ldif";
-my $conn = new FileConn($dseldif);
-if (!$conn) {
- print STDERR "Error: Could not open config file $dseldif: Error $!\n";
- exit 1;
-}
-
-my $dn = "cn=config";
-my $entry = $conn->search($dn, "base", "(cn=*)", 0);
-if (!$entry)
-{
- print STDERR "Error: Search $dn in $dseldif failed: $entry\n";
- exit 1;
-}
-
-$dn = "cn=config,cn=ldbm database,cn=plugins,cn=config";
-my $dbentry = $conn->search($dn, "base", "(cn=*)", 0);
-if (!$dbentry)
-{
- print "Error: Search $dn in $dseldif failed: $dbentry\n";
- exit 1;
-}
-$conn->close();
-
-# stop the server
-my $instdir = "";
-foreach my $path ( @{$entry->{"nsslapd-instancedir"}} )
-{
- if ( -d $path )
- {
- my $prog = $path . "/stop-slapd";
- if (-x $prog) {
- $? = 0;
- # run the stop command
- my $output = `$prog 2>&1`;
- my $status = $?;
- if ($status) {
- # Ignore the stop failure
- print STDERR "Warning: Could not stop directory server: $output\n";
- }
- $instdir = $path; # need to use it later...
- } elsif (!$force) {
- print STDERR "Error: The program $prog does not exist\n";
- exit 1;
- }
- }
-}
-
-# remove physical dirs/files
-remove_tree($dbentry, "nsslapd-directory", $instname, 1);
-remove_tree($dbentry, "nsslapd-db-logdirectory", $instname, 1);
-remove_tree($entry, "nsslapd-lockdir", $instname);
-remove_tree($entry, "nsslapd-tmpdir", $instname);
-remove_tree($entry, "nsslapd-bakdir", $instname, 1);
-remove_tree($entry, "nsslapd-errorlog", $instname, 1);
-
-# instance dir
-if ( -d $instdir && $instdir =~ /$instname/ )
-{
- # clean up pid files (if any)
- remove_pidfile("STARTPIDFILE", $instdir, $instname);
- remove_pidfile("PIDFILE", $instdir, $instname);
-
- my $rc = rmtree($instdir);
- if ( 0 == $rc )
- {
- print STDERR "Warning: $instdir was not removed.\n";
+my @errs = removeDSInstance($inst, $force);
+if (@errs) {
+ print STDERR "The following errors occurred during removal:\n";
+ for (@errs) {
+ print STDERR $res->getText($_);
}
+ print STDERR "Error: could not remove directory server $inst\n";
+ exit 1;
}
-# Finally, config dir
-remove_tree($entry, "nsslapd-schemadir", $instname, 1, "\.db\$");
# if we got here, report success
print "Instance $instname removed.\n";
exit 0;
+
+# emacs settings
+# Local Variables:
+# mode:perl
+# indent-tabs-mode: nil
+# tab-width: 4
+# End:
diff --git a/ldap/admin/src/scripts/setup-ds.res.in b/ldap/admin/src/scripts/setup-ds.res.in
index a89b1274..6502951c 100644
--- a/ldap/admin/src/scripts/setup-ds.res.in
+++ b/ldap/admin/src/scripts/setup-ds.res.in
@@ -120,6 +120,7 @@ error_copying_file = Could not copy file '%s' to '%s'. Error: %s\n
error_enabling_feature = Could not enable the directory server feature '%s'. Error: %s\n
error_importing_ldif = Could not import LDIF file '%s'. Error: %s. Output: %s\n
error_starting_server = Could not start the directory server using command '%s'. The last line from the error log was '%s'. Error: %s\n
+error_stopping_server = Could not stop the directory server '%s'. Error: %s\n
error_missing_port_and_ldapi = Either ServerPort or ldapifilepath must be specified. The server must listen to something.\n
error_missing_port = No ServerPort specified. The server must have a port number to listen to (default 389).\n
error_server_already_exists = Error: the server already exists at '%s'\
@@ -131,3 +132,6 @@ error_opening_dseldif = Could not open the DSE config file '%s'. Error: %s\n
error_opening_tempinf = Could not create temporary .inf file for config. Error: %s\n
error_writing_ldif = Could not write the LDIF file '%s'. Error: %s\n
error_creating_templdif = Could not create temporary LDIF file. Error: %s\n
+error_no_such_instance = Error: could not find directory server configuration directory '%s'. Error: %s\n
+error_finding_config_entry = Error: could not find the config entry '%s' in '%s'. Error: %s\n
+error_removing_path = Error: could not remove path '%s'. Error: %s\n
diff --git a/man/man8/migrate-ds.pl.8 b/man/man8/migrate-ds.pl.8
index b3a53ece..5036cf50 100644
--- a/man/man8/migrate-ds.pl.8
+++ b/man/man8/migrate-ds.pl.8
@@ -125,14 +125,23 @@ to LDIF format, and the LDIF file must be in the default database directory
the same name as the database instance directory, with a ".ldif". For
example, if you have
.IP
-/opt/fedora\-ds/slapd\-instance/db/userRoot/ and
+.ad l
+.nf
+/opt/fedora\-ds/slapd\-instance/db/userRoot/
+and
/opt/fedora\-ds/slapd\-instance/db/NetscapeRoot/
+.na
+.fi
.PP
you must first use db2ldif to export these databases to LDIF e.g.
.IP
+.ad l
+.nf
cd /opt/fedora\-ds/slapd\-instance
\&./db2ldif \fB\-n\fR userRoot \fB\-a\fR /opt/fedora\-ds/slapd\-instance/db/userRoot.ldif and
\&./db2ldif \fB\-n\fR NetscapeRoot \fB\-a\fR /opt/fedora\-ds/slapd\-instance/db/NetscapeRoot.ldif
+.fi
+.na
.PP
Then you must somehow make your old server root directory available on
the destination machine, either by creating a tar archive on the source
diff --git a/man/man8/remove-ds.pl.8 b/man/man8/remove-ds.pl.8
index c430b0c8..c74b8234 100644
--- a/man/man8/remove-ds.pl.8
+++ b/man/man8/remove-ds.pl.8
@@ -19,7 +19,7 @@
remove\-ds.pl \- Remove an instance of Directory Server
.SH SYNOPSIS
.B remove-ds.pl
-[\-f] \-i \fIinstance\fR
+[\-f] [\-d \-d ... \-d] \-i \fIinstance\fR
.SH DESCRIPTION
Removes a Directory Server instance from the system. The instance
will be shutdown and the files will be removed. The certificate
@@ -36,6 +36,9 @@ A summary of options is included below:
.B \fB\-f\fR
Force removal
.TP
+.B \fB\-d\fR
+Enable debugging - adding more -d will make output more verbose
+.TP
.B \fB\-i\fR \fIinstance\fR
The full name of the instance to remove (e.g. slapd-example)
.br