1.2. Using the package manager

1.2.1. Introduction

This is a short introduction into using the package manager interface from within YCP code.

It describes the required Pkg calls and how to use them in actual code.

1.2.2. Implementation

The new package manager does all package related handling inside C++ code and uses callbacks for user interaction.

This reduces the amount of ycp code needed for package installation (or removal) to a few lines.

The package manager keeps a list of installed (on the system) and available (on the CD or other installation media) packages and their status (install, delete, no change). YCP code can query the package manager for installed or available packages and set their status. The actual package installation or deletion takes place with a final commit call.

This call goes through the package list and deletes all packages marked as such. Then it orderes the packages marked for installation according to their "PreRequires" rpm tag and the media number (so you usually install CDs in ascending order).

All user interaction is done via callbacks from inside the package manager. If no callback is defined, the user doesn't see anything and also isn't requested to change CDs. Especially the latter case makes it important to set up appropriate callbacks.

1.2.3. Querying the package manager

1.2.3.1. Checking an installed package

Pkg::IsProvided checks if a rpm tag (a package name or any other symbolic name provided by a package) is installed.

It does a 'rpm -q' and if this fails a 'rpm -q --whatprovides' for the given tag.

It does not start the complete package manager.

1.2.3.2. Checking the installation sources

Pkg::IsAvailable checks if a rpm package is available for installation. (It currently does not check for other tags provided, this will be implemented in a future version.)

It starts the package manager if it isn't running already. Starting the package manager may take some time since it must read all it's caches about the installation sources and set up the internal data structures.

1.2.3.3. Deleting a package

Pkg::PkgDelete marks an installed package for deletion. It does not immediately run 'rpm -e' but just sets the internal status of the package in the package manager.

The actual deletion must be triggered with Pkg::PkgCommit().

1.2.3.4. Installing a package

Pkg::PkgInstall marks an available package for installation. It does not immediately run 'rpm -Uhv' but just sets the internal status of the package in the package manager.

The actual installation must be triggered with Pkg::PkgCommit().

1.2.3.5. Solving dependencies

Pkg::PkgSolve() tries to solve open package dependencies and marks other (dependant) packages for installation/deletion.

(It currently does an automatic solving without user interaction. Callbacks for user interaction will be added later.)

1.2.3.6. Committing the changes

Pkg::PkgCommit does the 'rpm' calls needed to install or delete packages.

It sorts the packages according to their pre-requires and their location on the media (CD order), handles mouting/unmounting of the media, does the package download (if the media is an ftp or http server), and calls rpm.

All these actions might trigger callbacks for user information or user actions (i.e. media change).

The module PackageCallbacks from yast2-packager.rpm defined default callbacks for all these actions and should be imported by any code using Pkg::PkgCommit(0).

The integer parameter given to Pkg::PkgCommit(0) must be zero for the normal usage. Non-zero values are only allowed during system installation when no media change is possible.

1.2.4. Example code

{
    import "PackageCallbacks";

    // installing netscape and cups
    Pkg::PkgInstall ("netscape");
    Pkg::PkgInstall ("cups");

    // deleting lprng if it is installed
    if (Pkg::IsProvided ("lprng"))
    Pkg::PkgDelete ("lprng");

    // fill open dependencies
    Pkg::PkgSolve();

    // do the rpm calls
    Pkg::PkgCommit();

}