View on GitHub

Open Source Cluster Application Resources

Download this project as a .zip file Download this project as a tar.gz file

Documentations > Developer Documentations > OSCAR infrastructure

PackMan - An Package Manager Abstraction

Managing chroot environments

PackMan provides a simple scripts that can be used to create and management chroot environments. The benefit of Packman is to enable the management of chroot environments that can be based on Debian or RPM Linux distributions.

More more details about how to use the packman script, simply refer to the packman man page.


Bootstrapping of a new chroot environment and installation of the apache2

If you want to create a new chroot environment in /tmp/test based on a minimal ubuntu-7-i386 system and the apache2 package, simply execute the following command: packman –root /tmp/test/ –distro ubuntu-7-i386 install apache2. This command will automatically bootstrap a ubuntu environment and install the apache2 package.

Note that the distribution identifier is based on the OS_Detect syntax and that you need to have repositories setup to access binary packages (configuration files in /tftpboot/distro/ and /tftpboot/oscar/).

PackMan - The Perl extension for Package Manager abstraction

PackMan is essentially an abstract class, even though Perl doesn’t have them. It’s expected there will be additional modules under PackMan:: to handle concrete package managers while PackMan itself acts as the front-door API.


  use PackMan;
  $pm = PackMan->new;

Concrete package managers will always be available directly as:

  use PackMan::<conc>;
  $pm = <conc>->new;

  use PackMan;
  $pm = PackMan-><conc>;

  use PackMan;
  $pm = PackMan::<conc>->new; Currently, the only valid value for <conc> is RPM. DEB is in the works.


Clone one PackMan instance

  $new_pm = $pm->clone;

The $pm instance can act on the current “/” directory (install packages on the currently running system) or act onto a directory, i.e. install/remove packages into a chroot tree. The chroot directory can be switched as described below:

  $pm->chroot ("/mnt/other_root");

  $pm->chroot ("/");    # wrong, will cause chroot argument substitute anyway
  $pm->chroot (undef);  # right, no chroot argument will be used

  my $pm_chroot = $pm->chroot;

Smart install methods

Detect smart capability:

  if ($pm->is_smart) {
     # go with smart methods

Specify the package repositories for the smart installer:


Generate the metadata cache for each package repository (where applicable):


Install, remove or update packages by invoking the smart package manager under the hood. For RPM packages this is the yum(e) package manager. Smart package managers resolve dependencies on their own and typically use package repositories and package metadata caches of some form (see above):

  ($err,$outref) = $pm->smart_install("pkg1",...);

  ($err,$outref) = $pm->smart_remove("pkg1",...);

  ($err,$outref) = $pm->smart_update("pkg1",...);

Callback handler on package manager output:

  $pm->output_callback(\&function,\$arg1,...); The specified function will be called with the specified arguments and additionally the last output line for each output line generated by the package manager working under the hood. An implicit callback called `->progress_handler` is allways called, this one is specific to the package manager and should is implemented in the concrete package manager module (e.g.

Export repositories through HTTPD

  $err = $pm->repo_export;

  $err = $pm->repo_unexport;


Potentially obsolete methods

Following methods will probably become obsolete [EF: I think the query methods will remain useful]

  if ($pm->install [<file> ...]) {
    # everything installed fine
  } else {
    # one or more failed to install

  if ($pm->update [<file> ...]) {
    # everything updated fine
  } else {
    # one or more failed to update

  if ($pm->remove [<package> ...]) {
    # everything was removed fine
  } else {
    # one or more failed to get removed

  my ($installed, $not_installed) = $pm->query_installed [<package> ...];
  # $installed and $not_installed are array refs

  my @versions = $pm->query_versions [<package> ...];
  # undef (as a member within the list) means no version of that package was
  # installed

[[BR]][[BR]] ‘‘[EF: following text is taken directly from the POD, is a bit obsolete but still informative]

All constructors take an optional argument of the root directory upon which to operate (if different from ‘/’);


The current root can be changed at any time with the chroot() method.

$pm->chroot (“/mnt/other_root”);

When setting root, another method call may be chained off of it for quick, one-off commands:

PackMan->new->chroot (“/mnt/other_root”)->install qw(list of files);

If you create a PackMan object with an alternative root and want to remember that chrooted PackMan:

$pm = PackMan->new (“/mnt/my_root”); $chrooted_pm = $pm->clone;

You can now change $pm back to “/”:

$pm->chroot (“/”); # or $pm->chroot (undef);

And $chrooted_pm remains pointing at the other directory:

$chrooted_pm->chroot # returns “/mnt/my_root”

All arguments to the chroot method must be absolute paths (begin with “/”), and contain no spaces.


PackMan was written by Jeff Squyres and Matt Garrett.

Smart PackMan methods and repository handling were introduced by Erich Focht for OSCAR5.

Yum doesn’t generate progress output if it’s not running from a tty. Packman uses a trick for getting this output, it calls yum(e) through ptty_try which runs the command under a pseudo-tty. This probably slows down the yum execution on 1-CPU machines at the price of getting progress output during the generation of images with SystemInstaller. We have some choices be faster here:

  • remove or rename ptty_try: packman won’t find it and go without it.
  • modify yum to produce output while installing and remove ptty_try;
  • find some other hack to run through a ptty. [[BR]][[BR]]

Binary Packages for Packman

A single binary package provides packman, both under Debian and RPM based systems. Note that in order to ease the creation of binary packages, a make dist command is available that creates a tarball for packman.

Debian Package

Files have been added into the Packman repository for the automatic creation of Debian packages. All the files are in the deb directory.

To create the package, you just need to execute the command make deb. Before executing the make command, be sure the file debian/changelog is up-to-date in order to specify the correct version number (you can use the dch command ).

RPM Package

To create the RPM for packman, just execute rpmbuild -ba.