1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
|
package SystemInstaller::Package;
# $Header: /cvsroot/systeminstaller/systeminstaller/lib/SystemInstaller/Package.pm,v 1.57 2003/04/11 21:09:03 mchasal Exp $
# Copyright (c) 2001 International Business Machines
# 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; either version 2 of the License, or
# (at your option) any later version.
# 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
# Michael Chase-Salerno <salernom@us.ibm.com>
# Modified by Amit Pabalkar <amit.p@californiadigital.com>
use strict;
use base qw(Exporter);
use vars qw($VERSION @EXPORT @EXPORT_OK);
use SystemInstaller::Log qw (verbose);
use Carp;
use Cwd;
@EXPORT = qw(pkg_install);
@EXPORT_OK = qw(pkglist_read files_find files_install);
$VERSION = sprintf("%d.%02d", q$Revision: 1.57 $ =~ /(\d+)\.(\d+)/);
use SystemInstaller::Package::RpmNoScripts;
use SystemInstaller::Package::Rpm;
use SystemInstaller::Package::Suse;
use SystemInstaller::Package::Deb;
use SystemInstaller::Package::Deboot;
my @PKGMODS=qw(Deboot Deb Suse RpmNoScripts Rpm);
sub pkg_install {
# Head sub to do all the steps, use this or the individual subs below.
# Input: pkg dir name, image dir name, arch, list of pkg files
# Output: boolean
my $pkgpath=shift;
my $imgpath=shift;
my $arch=shift;
my @pkglistfiles=@_;
my @pkglist; my @pkgfiles;
my $outlines=13; #Extra lines of output for GUI count below.
&verbose("Checking package path.");
unless (-e $pkgpath) {
carp("Package location $pkgpath not found!");
return 0;
}
&verbose("Reading package list files.");
unless (@pkglist=&pkglist_read(@pkglistfiles)) {
carp("Failed to read package files.");
return 0;
}
&verbose("Checking for required packages");
my @missing;
if (@missing=&check_reqd_pkgs(@pkglist)){
my $pkgstring=join("\n\t",@missing);
carp("WARNING: Missing required packages, continuing:\n\t$pkgstring\n");
}
# Display the line count for GUI status bars.
my $linecount = ((scalar(@pkglist) * 2) + $outlines);
&verbose("Expected lines of output: $linecount");
&verbose("Finding package install files.");
unless (@pkgfiles=&files_find($pkgpath, $arch, @pkglist)) {
carp("Failed to find files for all packages.");
return 0;
}
&verbose("Performing pre-install.");
unless (&files_pre_install($pkgpath, $imgpath)) {
carp("Pre-install failed.");
return 0;
}
&verbose("Installing package install files.");
unless (&files_install($pkgpath, $imgpath, @pkgfiles)) {
carp("Failed to install files.");
if ($main::config->pkginstfail) { return 0;};
}
&verbose("Performing post-install.");
unless (&files_post_install($pkgpath, $imgpath)) {
carp("Post-install failed, your image may not be quite right.");
if ($main::config->postinstfail) { return 0;};
}
return 1;
} #pkg_install
sub pkglist_read {
# Read in the specified files
# Input: list of pkg files.
# Returns: list of pkgs or null if failure
my @filelist=@_;
my @pkglist;
my $line;
local *PFILE;
foreach my $fn (@filelist) {
&verbose("Opening package file $fn.");
if (! open(PFILE,$fn)) {
carp("Unable to open package file $fn");
return;
}
&verbose("Parsing package file.");
while ($line=<PFILE>) {
chomp $line;
if (($line =~ /^\s*$/) || ($line =~ /^#/)) {
next;
}
$line=~s/\s//g;
# Found a package name, save it
push (@pkglist,$line);
}
close(PFILE);
}
# get rid of dupes and return the list
&verbose("Deleting duplicate package entries.");
return &pkglist_uniq(@pkglist);
} #pkglist_read
sub pkglist_uniq {
# Gets rid of dupe package names while maintaining the order.
# Input: list of pkgs
# Output: list of unique pkgs
my $ptype; my $pkg;
my %found=();
my @upkgs=();
foreach $pkg (@_) {
if (! defined $found{$pkg} ) {
$found{$pkg}++;
push (@upkgs,$pkg);
}
}
return @upkgs;
} #pkglist_uniq
sub check_reqd_pkgs {
# Ensure that required packages are in the list
# Input: list of pkgs
# Output: list of missing pkgs or null if OK
my @pkglist=@_;
my @req_pkgs=qw(systemconfigurator);
my @missing=();
foreach my $pkg (@req_pkgs){
unless (grep(/^$pkg.*/,@pkglist)) {
push(@missing, $pkg);
}
}
return @missing;
}# check_reqd_pkgs
sub files_find {
# Find the filenames corresponding to the package lists
# Input: pkg dir, arch, pkg list
# Output: file list or null on failure.
my $path=shift;
my $arch=shift;
my @pkglist=@_;
foreach my $mod (@PKGMODS){
my $class="SystemInstaller::Package::$mod";
if ($class->footprint("files",$path)) {
&verbose("Finding files with module $class");
return $class->files_find($path,$arch,@pkglist);
}
}
return;
} #files_find
sub files_pre_install {
# Perform any pre install actions
# Input: pkg dir, imagedir
# Output: Boolean
my $path=shift;
my $imgpath=shift;
my @file=@_;
foreach my $mod (@PKGMODS){
my $class="SystemInstaller::Package::$mod";
if ($class->footprint("pre_install",$path)) {
&verbose("Performing pre-install with module $class");
return $class->files_pre_install($imgpath,$path);
}
}
return;
} #files_pre_install
sub files_install {
# Install the pkgs
# Input: pkg dir, imagedir, file list
# Output: file list or null on failure.
my $path=shift;
my $imgpath=shift;
my @file=@_;
foreach my $mod (@PKGMODS){
my $class="SystemInstaller::Package::$mod";
if ($class->footprint("install",$path)) {
&verbose("Installing with module $class");
return $class->files_install($imgpath,$path,@file);
}
}
return;
} #files_install
sub files_post_install {
# Perform any post install actions
# Input: pkg dir, imagedir
# Output: Boolean
my $path=shift;
my $imgpath=shift;
my @file=@_;
foreach my $mod (@PKGMODS){
my $class="SystemInstaller::Package::$mod";
if ($class->footprint("post_install",$path,$imgpath)) {
&verbose("Performing post-install with module $class");
return $class->files_post_install($imgpath,$path);
}
}
return;
} #files_post_install
### POD from here down
=head1 NAME
SystemInstaller::Package - Interface to packaging for SystemInstaller
=head1 SYNOPSIS
use SystemInstaller::Package;
$location= "<package file location>";
$root= "<image root location>";
$arch= "<image architecture>";
@filename= "<package list filenames>";
unless (&pkg_install($location,$root,$arch,@filename) {
printf "install failed\n";
}
=head1 DESCRIPTION
SystemInstaller::Package provides an interface to package installation
for SystemInstaller.
=head1 ARGUMENTS
=over 4
=item $location
The location (directory) that contains the package install files.
=item $root
The directory that will contain the image.
=item $arch
The target architecture for the image.
=item @filename
A list of package list files.
=back
=head1 Module API specification
SystemInstaller::Package uses Perl modules to provide the actual functions
for specific package types. In order to add support for a new package
type the following must be provided in a perl module file named
<pkgtype>.pm in the Package subdirectory of the SystemInstaller library.
Additionally, the module name must be added to the @PKGMODS array in
the Package.pm module. The order of the modules in the array
determines the heirarchy. The Rpm module should remain last as the default.
Finally, a use statement must be added for the new module in the Package.pm
library.
THIS API IS NOT YET FINAL!!! It may (and probably will) change somewhat
in the near future.
=over 4
=item sub files_find($class,$path,$arch,@pkglist)
Find the best files for the given packages. $path contains the location
of the package files, $arch is the desired image architecture, @pkglist
contains the names of the desired packages. Returns: list of filenames
(without leading directories) or 0 on failure.
=item sub files_pre_install($class,$imgpath,$path)
Perform any required pre-installation action in the image.
$imgpath contains the root directory for the image, $path contains the
location of package files.
Returns: 1 on success, 0 on failure.
=item sub files_install($class,$imgpath,$path,@filelist)
Install the package files into the image. $imgpath contains the root
directory for the image, $path contains the location of package files,
@filelist contains the list of filenames as returned from &files_find.
Returns: 1 on success, 0 on failure.
=item sub files_post_install($class,$imgpath,$path)
Perform any required post-installation action in the image.
$imgpath contains the root directory for the image, $path contains the
location of package files.
Returns: 1 on success, 0 on failure.
=item sub footprint($class,$mode,$path,$imgpath);
Determine if this modules subroutine for the specific mode should be used.
$path contains the location of the package files. $imgpath is the location
of the image and is only available for B<post_install> and B<kernel> modes.
Returns: 1 if this module's subroutine is to be used, 0 if not.
Valid modes are:
=over 4
=item files
Finding the best files to use, the &files_find subroutine.
=item pre_install
Before the packages are installed, the &files_pre_install subroutine.
=item install
Installing the packages, the &files_install subroutine.
=item post_install
After the packages are installed, the &files_post_install subroutine.
=back
=back
=head1 AUTHOR
Michael Chase-Salerno <mchasal@users.sourceforge.net>
=head1 SEE ALSO
L<SystemInstaller::Package::Rpm>
L<SystemInstaller::Package::Deb>
L<SystemInstaller::Package::Suse>
L<SystemInstaller::Package::Turbo>
L<mksiimage>
=cut
1;
|