=================================================
 mdvpkg - the mandriva package management daemon
=================================================

mdvpkg is a wrapper upon mandriva urpmi database to provide
non-privileged users access to package maintenance tasks (upgrade,
installing, searching). Its development was initiated to support the
implementation of Mandriva Package Manager.

The following features are aimed:

* D-Bus interface allowing the creation of specialized clients (like
  an update applet, or end-users application managers)

* Unprivileged management tasks through PolicyKit

* Support for urpmi input (like dep choices from clients)

* A command line client

* Python QT/QML widgets to manage package tasks

It's inspired on ideas from PackageKit and aptdaemon.

Overview
=========

Essentially mdvpkg provide a way for users to perform packaging tasks
on the rpm/urpmi databases.  To mdvpkg all tasks are configured and
monitored through Task objects.

To create a task object a client should call a task creation method on
the daemon bus (org.mandrivalinux.mdvpkg), passing any required
parameter.  mdvpkg will then create the task and return its dbus path
to the caller.  The caller then can use the new created task object to
configure it, cancel it or schedule it for running.

All task creation methods have the name of the task you want to create
(e.g. `InstallPackages()`). Here's a list of the currently Tasks, with
a description of its purpose:

- ListMedias: List the currently known medias to mdvpkg.

- ListGroups: List all package groups known in the urpmi/rpm database.

- ListPackages: List packages in the urpmi/rpm database. Filters are
  provided (including files).

- InstallPackages: Request installation of packages or upgrades.

- RemovePackages: Request removing of installed packages by name

- AddMedia: Add a urpmi media by name

- RemoveMedia: Remove a urpmi media my name

- Update: Update medias

Task objects will provide information for its caller through the use
of dbus signals.

Task State
==========

All tasks will have a state life-cycle, which can be monitored through
the StateChanged signal.  For all tasks there are at least the
following states:

- STATE_SETTING_UP: The task has not been queued, and is accepting
  method calls for configuring it's behavior.

- STATE_QUEUED: The task was scheduled for execution and is not
  accepting configuration method calls.

- STATE_READY: The task has finished it's execution and the expected
  results are ready.

- STATE_CANCELING: The task has been scheduled for cancellation.

All other states are considered "running states" and provide
information for a task that is currently running.  Each task has it's
own set of running states.  There is no state for error or exception
cases, which will be signaled through the Error() signal -- a task is
expected to pass through STATE_SETTING_UP to STATE_READY if no error
condition occurs.

Task Signals
============

During execution the task will emit several signals to the caller to
report back results and information.  Some of those signals are common
to all tasks:

- StateChanged(new_state)

  Notify caller that the task state has changed to new_state.

- Error(code, arg)

  Notify that the task could not continue it's operation because an
  error occurred.  The type of the error is passed through `code` and
  additional error information is passed through `arg` string (e.g. an
  error message, or list of packages that could not be installed).

- Finished(code)

  This signal is emitted right before the task object is removed from
  the bus.  After a Finished() signal the task object is no more in
  the bus.  `code` will contain information of how the task was at
  that point, which can be:

  1. EXIT_SUCCESS

     The task has executed successfully, i.e. it's state is STATE_READY.

  2. EXIT_FAILED

     The task didn't complete its operation because an error occurred.
     The error code and information was already signaled through
     Error() signal.

  3. EXIT_CANCELED

     The task was canceled by the caller request.

All other signals have specific meaning for each specific task,
e.g. Package(index, name, status, install_details, upgrade_details) --
signals a package found during ListPackages() task.


Task Methods
============

All mdvpkg tasks are required to have at least two methods, Run() and
Cancel().  Any other method is considered "optional configuration
methods" serving as a way for the client to change the task default
behavior.

- Run()
  
  Put the task in the execution queue, and it's state goes to
  STATE_QUEUED.  No other method can be called except for Cancel() 

- Cancel()

  Ask mdvpkg to cancel this task.  The task is simply removed from bus
  if it's not in any running state (TASK_SETTING_UP, TASK_QUEUED,
  TASK_READY), otherwise the task is scheduled for cancellation since
  the cancel operation in this case needs more work (like cleaning
  cache, or db locks etc.).

Task Cancellation
-----------------

Not all tasks can be easily canceled, for example, during package
installation.  So the cancel operation is only guaranteed to
immediately stop task operation in the non-running states.

After a Cancel() method is called the task will change it's state to
STATE_CANCELING and caller should wait for Finished(EXIT_CANCELED)
when the task has been canceled.

Cancellation operation is not supposed to fail.  Finished(EXIT_FAILED)
after cancellation is a signal of mdvpkg bug.

Task auto-cancellation
----------------------

In two cases the task will be auto-canceled and removed from the bus
(a) The task is in STATE_SETTING_UP or STATE_READY without any
configuration method calls for reasonable timeout period, and (b) The
client has disconnected from the bus.  For (a) the task will signal
Error(ERROR_INACTIVE) with Finished(EXIT_FAILED).  For (b) no signal
is emitted since the caller has disconnected.


Task result listing
-------------------

For some tasks it's possible to suppress result signal emission so that
later the client can consult the result in a list.  This is called
task caching, and the client must call `SetCached()` to enable it.

The task will signal when it's state is STATE_READY with a Ready()
signal, passing the size of it's listing and the client can access
data through the use of Get() methods.  Each task will have different
arguments to Get().
