# BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2007 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK # ########################### # # This perl module provides a way to set up a new installation after # the binaries have already been extracted. This is typically after # using native packaging support to install the package e.g. RPM, # pkgadd, depot, etc. This script will show the license, readme, # dsktune, then run the usual setup pre and post installers. # ########################## package Migration; use Setup; use Exporter (); @ISA = qw(Exporter Setup); @EXPORT = qw(); @EXPORT_OK = qw(); # hostname use Net::Domain qw(hostfqdn); # load perldap use Mozilla::LDAP::Conn; use Mozilla::LDAP::Utils qw(normalizeDN); use Mozilla::LDAP::API qw(ldap_explode_dn); use Mozilla::LDAP::LDIF; use Getopt::Long; use SetupLog; use DSUtil; # process command line options Getopt::Long::Configure(qw(bundling)); # bundling allows -ddddd sub VersionMessage { print "@capbrand@ Directory Server Migration Program Version @PACKAGE_VERSION@\n"; } sub HelpMessage { print <{res} = shift; my ($silent, $inffile, $keep, $preonly, $logfile, $oldsroot, $actualsroot, $crossplatform); my @instances; GetOptions('help|h|?' => sub { VersionMessage(); HelpMessage(); exit 0 }, 'version|v' => sub { VersionMessage(); exit 0 }, 'debug|d+' => \$DSUtil::debuglevel, 'silent|s' => \$silent, 'file|f=s' => \$inffile, 'keepcache|k' => \$keep, 'preonly|p' => \$preonly, 'logfile|l=s' => \$logfile, 'oldsroot|o=s' => \$oldsroot, 'actualsroot|a=s' => \$actualsroot, 'crossplatform|cross|c|x' => \$crossplatform, 'instance|i=s' => \@instances ); my $pkgname = "@package_name@"; # this is the new pkgname which may be something like # 389-ds-base - we have to strip off the -suffix if ($pkgname =~ /-(core|base)$/) { $pkgname =~ s/-(core|base)$//; } my $oldpkgname = "@brand@-ds"; $self->{pkgname} = $pkgname; $oldsroot =~ s/\/+$//; # trim trailing '/'s, if any $self->{oldsroot} = $oldsroot || "/opt/$oldpkgname"; $actualsroot =~ s/\/+$//; # trim trailing '/'s, if any $self->{actualsroot} = $actualsroot || $self->{oldsroot}; $self->{silent} = $silent; $self->{keep} = $keep; $self->{preonly} = $preonly; $self->{logfile} = $logfile; $self->{crossplatform} = $crossplatform; $self->{log} = new SetupLog($self->{logfile}, "migrate"); DSUtil::setDebugLog($self->{log}); $self->{start_servers} = 1; # start servers as soon as they are migrated # if user supplied inf file, use that to initialize if (defined($inffile)) { $self->{inf} = new Inf($inffile); } else { $self->{inf} = new Inf; } # see if user passed in default inf values - also, command line # arguments override those passed in via an inf file - this # allows the reuse of .inf files with some parameters overridden if (!$self->{inf}->updateFromArgs(@ARGV)) { HelpMessage(); exit 1; } # this is the base config directory - the directory containing # the slapd-instance instance specific config directories $self->{configdir} = $ENV{DS_CONFIG_DIR} || "@instconfigdir@"; # get list of instances to migrate if (! @instances) { # an instance must be a directory called $oldsroot/slapd-something and the file # $oldsroot/slapd-something/config/dse.ldif must exist @instances = grep { -d && -f "$_/config/dse.ldif" && ($_ =~ s,$self->{oldsroot}/,,) } glob("$self->{oldsroot}/slapd-*"); } if (!@instances) { $self->msg($FATAL, "error_no_instances", $self->{oldsroot}); VersionMessage(); HelpMessage(); exit 1; } $self->{instances} = \@instances; } # log only goes the the logfile sub log { my $self = shift; my $level = shift; $self->{log}->logMessage($level, "Migration", @_); } sub doExit { my $self = shift; my $code = shift; if (!defined($code)) { $code = 1; } if ($code) { $self->msg($FATAL, 'migration_exiting', $self->{log}->{filename}); } else { $self->msg($SUCCESS, 'migration_exiting', $self->{log}->{filename}); } exit $code; } sub migrateSecurityFiles { my $self = shift; my $inst = shift; my $destdir = shift; my $oldroot = $self->{oldsroot}; if (! -d "$oldroot/alias") { $self->msg('old_secdir_error', "$oldroot/alias", $!); return 0; } elsif (! -d $destdir) { $self->msg('new_secdir_error', $destdir, $!); return 0; } else { if (-f "$oldroot/alias/$inst-cert8.db") { $self->log($INFO, "Copying $oldroot/alias/$inst-cert8.db to $destdir/cert8.db\n"); if (system ("cp -p $oldroot/alias/$inst-cert8.db $destdir/cert8.db")) { $self->msg($FATAL, 'error_copying_certdb', "$oldroot/alias/$inst-cert8.db", "$destdir/cert8.db", $!); return 0; } } else { $self->log($DEBUG, "No file to migrate: $oldroot/alias/$inst-cert8.db\n"); } if (-f "$oldroot/alias/$inst-key3.db") { $self->log($INFO, "Copying $oldroot/alias/$inst-key3.db to $destdir/key3.db\n"); if (system ("cp -p $oldroot/alias/$inst-key3.db $destdir/key3.db")) { $self->msg($FATAL, 'error_copying_keydb', "$oldroot/alias/$inst-key3.db", "$destdir/key3.db", $!); return 0; } } else { $self->log($DEBUG, "No file to migrate: $oldroot/alias/$inst-key3.db\n"); } if (-f "$oldroot/alias/secmod.db") { $self->log($INFO, "Copying $oldroot/alias/secmod.db to $destdir/secmod.db\n"); if (system ("cp -p $oldroot/alias/secmod.db $destdir/secmod.db")) { $self->msg($FATAL, 'error_copying_secmoddb', "$oldroot/alias/secmod.db", "$destdir/secmod.db", $!); return 0; } } else { $self->log($DEBUG, "No file to migrate: $oldroot/alias/secmod.db\n"); } if (-f "$oldroot/alias/$inst-pin.txt") { $self->log($INFO, "Copying $oldroot/alias/$inst-pin.txt to $destdir/pin.txt\n"); if (system ("cp -p $oldroot/alias/$inst-pin.txt $destdir/pin.txt")) { $self->msg($FATAL, 'error_copying_pinfile', "$oldroot/alias/$inst-pin.txt", "$destdir/pin.txt", $!); return 0; } } else { $self->log($INFO, "No $oldroot/alias/$inst-pin.txt to migrate\n"); } if (-f "$oldroot/shared/config/certmap.conf") { $self->log($INFO, "Copying $oldroot/shared/config/certmap.conf to $destdir/certmap.conf\n"); if (system ("cp -p $oldroot/shared/config/certmap.conf $destdir/certmap.conf")) { $self->msg($FATAL, 'error_copying_certmap', "$oldroot/shared/config/certmap.conf", "$destdir/certmap.conf", $!); return 0; } } else { $self->log($INFO, "No $oldroot/shared/config/certmap.conf to migrate\n"); } } return 1; } ############################################################################# # Mandatory TRUE return value. # 1; # emacs settings # Local Variables: # mode:perl # indent-tabs-mode: nil # tab-width: 4 # End: