###
### Copyright 2000-2004 University of Illinois Board of Trustees
### All rights reserved.
###
### PSGConf::Action::PackageManager::Solaris - Solaris pkg action type for psgconf
###
### Campus Information Technologies and Educational Services
### University of Illinois at Urbana-Champaign
###
package PSGConf::Action::PackageManager::Solaris;
use strict;
use PSGConf::Action::PackageManager::FTPArchive;
use PSGConf::Data::String;
use File::Basename;
our @ISA = qw(PSGConf::Action::PackageManager::FTPArchive);
###############################################################################
### configuration constructor
###############################################################################
sub conf
{
my ($class, $psgconf) = @_;
my ($arch, $arch2);
$arch = `/usr/bin/uname -m`;
$arch2 = `/usr/bin/uname -p`;
chomp $arch;
chomp $arch2;
if ( $arch eq "i86pc" ) {
$arch = 'i';
### Hacks to fix the mess from sunfreeware.com
$arch2 = '((intel)|(i386)|(x86))';
} else {
$arch =~ s/sun4//;
}
PSGConf::Action::PackageManager::FTPArchive->conf($psgconf);
$psgconf->register_data(
pkg_add_cmd => PSGConf::Data::String->new(
value => "/usr/sbin/pkgadd"
),
pkg_rm_cmd => PSGConf::Data::String->new(
value => "/usr/sbin/pkgrm"
),
pkg_info_cmd => PSGConf::Data::String->new(
value => "/usr/bin/pkginfo"
),
pkg_trans_cmd => PSGConf::Data::String->new(
value => "/usr/bin/pkgtrans"
),
pkg_gzip_cmd => PSGConf::Data::String->new(
value => "/usr/bin/gzip"
),
pkg_admin_file => PSGConf::Data::String->new(
value => "dontask"
),
pkg_dir => PSGConf::Data::String->new(
value => "/var/sadm/pkg/"
),
pkg_regex => PSGConf::Data::String->new(
value => "\-sol[0-9]+\-${arch2}\-local\.gz"
),
pkg_arch => PSGConf::Data::String->new(
value => $arch
)
);
}
###############################################################################
### pkg_get_installed() method
###############################################################################
sub pkg_get_installed
{
my ($self, $psgconf) = @_;
my (%pkg_installed_list);
my ($cmd, $pkg, $ver);
local *FP;
$cmd = $psgconf->data_obj('pkg_info_cmd')->get();
$pkg = undef; $ver = undef;
if (open (FP, "$cmd -l |")) {
while (<FP>) {
chomp;
if ( m/PKGINST: /o ) {
s/^.*PKGINST: *//;
$pkg = $_;
}
if ( m/VERSION: /o ) {
s/^.*VERSION: *//;
s/,REV=/_/;
###
### Hacks to clean up the version info from
### TSM and Emulex Packages
###
s/^Release //;
s/^Version //;
s/ Release /./;
s/ Level /./;
$ver = $_;
}
if ( defined $pkg && defined $ver ) {
push (@{$pkg_installed_list{$pkg}}, $ver);
$ver = undef; $pkg = undef;
}
}
close FP;
} else {
warn "\t!!! pkginfo failed: $!\n";
}
return \%pkg_installed_list;
}
###############################################################################
### pkg_get_latest_version() method
###############################################################################
sub pkg_get_latest_version
{
my ($self, $psgconf, $pkg) = @_;
my ($regex) = "(\Q${pkg}\E(\."
. $psgconf->data_obj('pkg_arch')->get()
. ")?\-[^-]+)"
. $psgconf->data_obj('pkg_regex')->get();
return $self->get_latest_version (
$psgconf,
$pkg,
$psgconf->data_obj('env_vars')->find('SOL_PKG_UPDATE_PATH'),
qr{$regex}
);
}
###############################################################################
### pkg_get_dependencies() method
###############################################################################
sub pkg_get_dependencies
{
my ($self, $psgconf, $pkg) = @_;
my ($pkg2) = $self->Parse($pkg);
my (@deps, $cmd, $file, $dir, @files);
my ($regex) = "\Q${pkg}\E" . $psgconf->data_obj('pkg_regex')->get();
local *FP;
###
### IF we are working with a datastream package format covert
### to the directory format
###
if ( ! -d $psgconf->data_obj('pkg_dir')->get() . $pkg2 ) {
# Else find the package on the server
# Need to escape the + and . in the package name, hence \Q and \E
@files = $self->list_files_from_url(
$psgconf,
$psgconf->data_obj('env_vars')->find('SOL_PKG_UPDATE_PATH'),
qr{$regex});
# we should have only found one entry
if ( scalar @files == 1 ) {
# See if we have the package tarball 'cached'.
$file = &basename ($files[0]);
$file = $self->get_file_from_url($psgconf, $files[0])
if ( ! -f "$psgconf->{tmpdir}/$file" );
if ( -f $file ) {
$cmd = $psgconf->data_obj('pkg_gzip_cmd')->get();
$cmd .= ' -d ' . $psgconf->{tmpdir} . '/' . $file;
&PSGConf::Util::RunCommand($cmd);
$file =~ s/.gz$//;
if ( -f $file ) {
$cmd = $psgconf->data_obj('pkg_trans_cmd')->get();
$cmd .= ' ' . $file . ' . all';
&PSGConf::Util::RunCommand($cmd);
$dir = $psgconf->{tmpdir} . '/' . $pkg2 . '/install';
}
}
} elsif ( ! scalar @files ) {
warn "\tCould not find URL for ($pkg)\n";
} else {
warn "\tFound too many URLs for ($pkg)\n";
}
} else {
$dir = $psgconf->data_obj('pkg_dir')->get() . $pkg2 . '/install';
}
###
### Now that we are in directory format (or it is already installed)
### read the depend file.
###
if ( -f "$dir/depend" ) {
if (open (FP, "$dir/depend" )) {
grep (/^P ([^\s]*) /o && (push @deps, $1), <FP>);
close FP;
} else {
warn "\t!!! dependency file ($dir/depend) for ($pkg) could not be read\n";
}
}
return @deps;
}
###############################################################################
### pkg_install() method
###############################################################################
sub pkg_install
{
my ($self, $psgconf, $pkg) = @_;
my ($cmd, $err, $file, @files);
my ($regex) = "\Q${pkg}\E" . $psgconf->data_obj('pkg_regex')->get();
###
### Find the location of the package
###
@files = $self->list_files_from_url(
$psgconf,
$psgconf->data_obj('env_vars')->find('SOL_PKG_UPDATE_PATH'),
qr{$regex});
# We must not have found any packages, so return right away
return -1
if ( ! scalar @files );
###
### Download it it in the tmp area.
###
$file = &basename ($files[0]);
$file = $self->get_file_from_url($psgconf, $files[0])
if ( ! -f "$psgconf->{tmpdir}/$file" );
# We must not have downloaded the file, so return right away.
return -1
if ( ! -f "$psgconf->{tmpdir}/$file" );
###
### Unpack it.
###
$cmd = $psgconf->data_obj('pkg_gzip_cmd')->get();
$cmd .= ' -d ' . $psgconf->{tmpdir} . '/' . $file;
return $err
if (($err=&PSGConf::Util::RunCommand($cmd)));
$file =~ s/.gz$//;
###
### Now that we have the package staged, install it.
###
$cmd = $psgconf->data_obj('pkg_add_cmd')->get();
$cmd .= ' -na ' . $psgconf->data_obj('pkg_admin_file')->get();
$cmd .= ' -v '
if ($psgconf->{verbose});
$cmd .= ' -d ' . $psgconf->{tmpdir} . '/' . $file;
$cmd .= ' all';
$err=&PSGConf::Util::RunCommand($cmd);
print "\n"
if ($psgconf->{verbose});
return $err;
}
###############################################################################
### pkg_remove() method
###############################################################################
sub pkg_remove
{
my ($self, $psgconf, $pkg, $force) = @_;
my ($cmd, $err);
###
### Remove the version of the package if we have
### pkg_number_of_versions set to 1
###
($pkg) = $self->Parse($pkg)
if ( $self->{number_of_versions} <= 1 );
###
### The force option is actually solved via the admin file.
###
$cmd = $psgconf->data_obj('pkg_rm_cmd')->get();
$cmd .= ' -na ' . $psgconf->data_obj('pkg_admin_file')->get();
$cmd .= ' -v'
if ($psgconf->{verbose});
$cmd .= ' ' . $pkg;
$err=&PSGConf::Util::RunCommand($cmd);
print "\n"
if ($psgconf->{verbose});
return $err;
}
###############################################################################
### documentation
###############################################################################
1;
__END__
=head1 NAME
PSGConf::Action::PackageManager::Solaris - install Solaris packages
=head1 SYNOPSIS
use PSGConf::Action::PackageManager::Solaris;
$psgconf->register_actions(
PSGConf::Action::PackageManager::Solaris->new(
'quiet' => 1
),
...
);
=head1 DESCRIPTION
The B<PSGConf::Action::PackageManager::Solaris> module provides a B<PSGConf>
action class for updating Solaris packages.
The B<PSGConf::Action::PackageManager::Solaris> class is derived from the
B<PSGConf::Action::PackageManager::FTPArchive> class, but it defines/overrides
the following methods:
=over 4
=item I<pkg_get_installed()>
A method that will assign values to the I<pkg_installed_list>, which
will be all the packages currently installed. The I<pkg_installed_list>
is a reference to a hash of arrays. The array is sorted to have
versions in ascending order. Called from the
B<PSGConf::Action::PackageManager::check()> method.
=item I<pkg_get_latest_version($pkg)>
A method that will return a B<PSGConf::Data::String> that contains
the latest version of $pkg from the package repository. Called from the
B<PSGConf::Action::PackageManager::check()> method.
=item I<pkg_get_dependencies($pkg)>
A method that will return a B<PSGConf::Data::List> that contains
all the packages that $pkg will depend upon, regardless
if they have been installed or not. This is for the package on
the package repository and $pkg will have the version in it as well.
Called from the B<PSGConf::Action::PackageManager::diff()> method.
=item I<pkg_install($pkg)>
A method that will install a $pkg on the system. Returns 0 for a
successfull install, non-zero for a failure. Called from
B<PSGConf::Action::PackageManager::do()> method.
=item I<pkg_remove($pkg, $force)>
A method that will remove $pkg from the system, and may have to force
the removal, depending on the value of $force, which will be a
B<PSGConf::Data::Boolean>. Returns 0 for a successfull install,
non-zero for a failure. Called from
B<PSGConf::Action::PackageManager::do()> method.
=back
The constructor also registers the following data objects:
=over 4
=item I<pkg_add_cmd>
A B<PSGConf::Data::String> object that determines where the F<pkgadd>
command is. The default is I</usr/sbin/pkgadd>.
=item I<pkg_rm_cmd>
A B<PSGConf::Data::String> object that determines where the F<pkgrm>
command is. The default is I</usr/sbin/pkgrm>.
=item I<pkg_info_cmd>
A B<PSGConf::Data::String> object that determines where the F<pkginfo>
command is. The default is I</usr/bin/pkginfo>.
=item I<pkg_trans_cmd>
A B<PSGConf::Data::String> object that determines where the F<pkgtrans>
command is. The default is I</usr/bin/pkgtrans>.
=item I<pkg_gzip_cmd>
A B<PSGConf::Data::String> object that determines where gzip is located.
Used to unpack the data stream for installation.
The default is I</usr/bin/gzip>.
=item I<pkg_admin_file>
A B<PSGConf::Data::String> object that determines where the F<pkgadd>
and F<pkgrm> command will use for the admin file, C<-a> option.
The default is I<dontask>.
=item I<pkg_dir>
A B<PSGConf::Data::String> object that determines where the information
related to installed packages is stored. The default is I</var/sadm/pkg/>.
=item I<pkg_regex>
A B<PSGConf::Data::String> object that determines what the regex is to
match against the FTPArchive listing.
The default is I<\-sol[0-9]+\-(sparc|intel)\-local\.gz>.
=item I<pkg_arch>
A B<PSGConf::Data::String> object that determines the specific package
architecture for installing SVR4 packages. Defaults to the output
of C<uname -m>, sans F<sun4>, on sparc platforms and I<i> on x86.
=back
=head1 SEE ALSO
L<perl>
L<PSGConf>
L<PSGConf::Action>
L<PSGConf::Action::PackageManager::FTPArchive>
L<PSGConf::Data::String>
L<File::Basename>
C<CE<lt>pkgadd(1)E<gt>>
C<CE<lt>pkginfo(1)E<gt>>
C<CE<lt>pkgrm(1)E<gt>>
=cut
syntax highlighted by Code2HTML, v. 0.9.1