# 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 Setup; use Exporter (); @ISA = qw(Exporter); @EXPORT = qw($SILENT $EXPRESS $TYPICAL $CUSTOM); @EXPORT_OK = qw($SILENT $EXPRESS $TYPICAL $CUSTOM); # tempfiles use File::Temp qw(tempfile tempdir); # 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 File::Temp qw(tempfile tempdir); use SetupLog; use Util; use Inf; use strict; use vars qw($EXPRESS $TYPICAL $CUSTOM $SILENT); # the setup types $EXPRESS = 1; $TYPICAL = 2; $CUSTOM = 3; $SILENT = 4; # process command line options Getopt::Long::Configure(qw(bundling)); # bundling allows -ddddd sub VersionMessage { print "@capbrand@ Directory Server Setup Program Version @PACKAGE_VERSION@\n"; } sub HelpMessage { print <init(@_); return $self; } sub init { my $self = shift; $self->{res} = shift; my ($silent, $inffile, $keep, $preonly, $logfile, $update, $force); GetOptions('help|h|?' => sub { VersionMessage(); HelpMessage(); exit 0 }, 'version|v' => sub { VersionMessage(); exit 0 }, 'debug|d+' => \$Util::debuglevel, 'silent|s' => \$silent, 'file|f=s' => \$inffile, 'keepcache|k' => \$keep, 'preonly|p' => \$preonly, 'logfile|l=s' => \$logfile, 'update|u' => \$update, 'continue|force|c' => \$force ); $self->{silent} = $silent; $self->{inffile} = $inffile; $self->{keep} = $keep; $self->{preonly} = $preonly; $self->{update} = $update; $self->{force} = $force; $self->{logfile} = $logfile; $self->{log} = new SetupLog($self->{logfile}); # if user supplied inf file, use that to initialize if (defined($self->{inffile})) { $self->{inf} = new Inf($self->{inffile}); } else { $self->{inf} = new Inf; } my $fh; # create a temp inf file for writing for other processes # never overwrite the user supplied inf file ($fh, $self->{inffile}) = tempfile("setupXXXXXX", UNLINK => !$keep, SUFFIX => ".inf", OPEN => 0, DIR => File::Spec->tmpdir); $self->{inf}->{filename} = $self->{inffile}; # 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@"; } # log only goes the the logfile sub log { my $self = shift; my $level = shift; $self->{log}->logMessage($level, "Setup", @_); } # msg does to the screen and optionally to the log file # if you use msg like this: # msg(0, "some message") # it will go only to the screen # if you use msg like this: # msg($WARN, "some message") # it will go to the screen and to the log at the $WARN level # all messages are localizable - you must define a resource key # the first string passed to this method is a resource key # additional strings are used as "arguments" to that resource key # if you want to print un-localizable messages, use debug or write # directly to the log or screen sub msg { my $self = shift; my $level = shift; my @ary = @_; if (!$level && @ary) { # e.g. msg(0, "string") - no logging } elsif ($level and @ary and grep {/^$level$/} $self->{log}->levels()) { # e.g. msg($WARN, "string") - print and log } else { # log at default INFO level unshift @ary, $level; $level = $INFO; } # @text is an array of strings for one message or # an array of array refs, each one is a message while (@ary) { my @text = shift @ary; last if (!@text or !$text[0]); # element is an array ref - just pass to getText # else is a list of strings # NOTE: this will NOT work if ary contains # consecutive simple string errors not separated # by an array ref e.g. this will work # ARRAY, 'errkey', arg, arg, ARRAY # this will not work # ARRAY, 'errkey', arg, 'errkey2', arg2, ARRAY while (@ary and !ref($ary[0])) { push @text, shift @ary; } my $string = $self->{res}->getText(@text); if ($level) { $self->log($level, $string); } print $string; } } sub doExit { my $self = shift; my $code = shift; if (!defined($code)) { $code = 1; } if ($code) { $self->msg($FATAL, 'setup_exiting', $self->{log}->{filename}); } else { $self->msg($SUCCESS, 'setup_exiting', $self->{log}->{filename}); } exit $code; } # get a list of the directory servers in configdir sub getDirServers { my $self = shift; if (!$self->{dirservers}) { $self->{dirservers} = []; for my $dir (glob("$self->{configdir}/slapd-*")) { next if ($dir =~ /\.removed$/); # skip removed instances if (-d $dir) { $dir =~ s,$self->{configdir}/,,; # strip off dir part push @{$self->{dirservers}}, $dir; } } } return @{$self->{dirservers}}; } ############################################################################# # Mandatory TRUE return value. # 1; # emacs settings # Local Variables: # mode:perl # indent-tabs-mode: nil # tab-width: 4 # End: