Translate

Archives

YUM Package Installation Updating and Removal Forensics

In previous posts I examined the internals of RPM packages and the RPM database itself. In this post, I explore how to trace RPM package installation, update and removal on Linux distributions which use YUM (YellowDog Update Modified).

If you examine /var/log/yum.log, an example of which is shown below, you will note that the date component of each entry includes the day and month but not the year.

Feb 15 10:00:44 Updated: ibus-1.5.5-1.fc20.x86_64
Feb 15 10:00:45 Updated: ibus-gtk2-1.5.5-1.fc20.x86_64
Feb 15 10:00:47 Updated: python-boto-2.23.0-1.fc20.noarch
Feb 15 10:00:48 Installed: python-dropbox-1.6-4.fc20.noarch
Feb 15 10:00:56 Installed: python-crypto-2.6.1-1.fc20.x86_64
Feb 15 10:00:57 Installed: python-paramiko-1.10.1-2.fc20.noarch
Feb 15 10:00:58 Updated: firewalld-0.3.9.3-1.fc20.noarch

We can figure out the year by lookimg at the package install date if it is currently installed and has not be updated or deleted from the system. For example:

# rpm -qi  python-dropbox
Name        : python-dropbox
Version     : 1.6
Release     : 4.fc20
Architecture: noarch
Install Date: Sat 15 Feb 2014 10:00:48 AM EST
Group       : Unspecified
Size        : 300146
License     : MIT
Signature   : RSA/SHA256, Thu 08 Aug 2013 06:38:41 PM EDT, Key ID 2eb161fa246110c1
Source RPM  : python-dropbox-1.6-4.fc20.src.rpm
Build Date  : Sun 04 Aug 2013 05:33:16 AM EDT
Build Host  : arm02-builder04.arm.fedoraproject.org
Relocations : (not relocatable)
Packager    : Fedora Project
Vendor      : Fedora ProjectURL         : https://www.dropbox.com/developers/core/sdks
Summary     : Official Dropbox REST API Client
Description :
A Python library that for Dropbox's HTTP-based Core API.

But how can we figure out the full installation date for a particular version of a package if the package was updated? Consider the firewalld package, for example:

# rpm -qi firewalld
Name        : firewalld
Version     : 0.3.11
Release     : 3.fc20
Architecture: noarch
Install Date: Fri 03 Jul 2014 12:00:23 PM EDT
Group       : Unspecified
Size        : 2261709
License     : GPLv2+
Signature   : RSA/SHA256, Thu 28 Aug 2014 12:33:01 AM EDT, Key ID 2eb161fa246110c1
Source RPM  : firewalld-0.3.11-3.fc20.src.rpm
Build Date  : Wed 27 Jun 2014 04:55:42 AM EDT
Build Host  : arm04-builder23.arm.fedoraproject.org
Relocations : (not relocatable)
Packager    : Fedora Project
Vendor      : Fedora Project
URL         : http://fedorahosted.org/firewalld
Summary     : A firewall daemon with D-Bus interface providing a dynamic firewall
Description :
firewalld is a firewall service daemon that provides a dynamic customizable
firewall with a D-Bus interface.


This is obviously a later version of the firewalld package that was installed on February 15th. Was this the only update to the package since February 15th or had a series of updates occurred? From a forensics point of view, this is an important question.

The question cannot be answered using any of the various RPM tools or the RPM database. The only way to answer the question is to use the YUM history command.

# yum history
Loaded plugins: langpacks, refresh-packagekit
ID     | Login user               | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
    39 | Finnbarr P. Murphy <fpm> | 2014-08-24 11:19 | E, I, U        |   45   
    38 | Finnbarr P. Murphy <fpm> | 2014-08-16 17:35 | E, I, U        |   77   
    37 | Finnbarr P. Murphy <fpm> | 2014-08-01 16:07 | E, I, U        |   77 EE
    36 | Finnbarr P. Murphy <fpm> | 2014-07-25 16:36 | E, I, U        |  112   
    35 | Finnbarr P. Murphy <fpm> | 2014-07-13 14:09 | E, I, U        |   94   
    34 | Finnbarr P. Murphy <fpm> | 2014-06-28 15:48 | Update         |   59   
    33 | System <unset>           | 2014-06-22 11:56 | Install        |    5   
    32 | System <unset>           | 2014-06-22 09:28 | Install        |    1   
    31 | Finnbarr P. Murphy <fpm> | 2014-06-21 13:12 | E, I, U        |   55   
    30 | Finnbarr P. Murphy <fpm> | 2014-06-14 16:53 | E, I, U        |   86   
    29 | Finnbarr P. Murphy <fpm> | 2014-06-07 23:21 | E, I, U        |   43   
    28 | Finnbarr P. Murphy <fpm> | 2014-06-01 08:08 | Update         |   48   
    27 | Finnbarr P. Murphy <fpm> | 2014-05-23 23:09 | Update         |   34   
    26 | Finnbarr P. Murphy <fpm> | 2014-05-17 10:20 | E, I, O, U     |   76 EE
    25 | Finnbarr P. Murphy <fpm> | 2014-05-11 08:53 | E, I, U        |   60 EE
    24 | Finnbarr P. Murphy <fpm> | 2014-05-10 13:50 | Install        |    1   
history list


Look up the YUM manpage for the meaning of the various action codes. YUM is tranaction-based and the history command only shows the successfully completed transactions as far as I can tell. A tranaction can be a single RPM package or a group of packages.

This command initially appeared in Fedora 14 back in 2010 and has been enhanced a number of times since then. Thus the history command is not available on older RPM-based distributions. You require YUM 3.2.25 or later.

Note that this command can be disabled and rendered useless if the history_record boolean in /etc/yum.conf is unset or set to zero. Enabling the YUM history functionality requires extra space on a system and more processing time but it allows you to obtain a lot of information of what has occurred w.r.t. packages over time. This boolean is enabled by default.

As you are probably aware if you read my posts, the RPM subsytem maintains its own dbm-based database (rpmdb) under /var/lib/rpm. The YUM history command also has it’s own database but instead of using (n)dbm routines, it is based on sqlite. I will show you how to directly interact with that database later in this post.

If you wish to see all history, use history list all:

# yum history list all
Loaded plugins: langpacks, refresh-packagekit
ID     | Login user               | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
    39 | Finnbarr P. Murphy <fpm> | 2014-08-24 11:19 | E, I, U        |   45   
    38 | Finnbarr P. Murphy <fpm> | 2014-08-16 17:35 | E, I, U        |   77   
    37 | Finnbarr P. Murphy <fpm> | 2014-08-01 16:07 | E, I, U        |   77 EE
    36 | Finnbarr P. Murphy <fpm> | 2014-07-25 16:36 | E, I, U        |  112   
    35 | Finnbarr P. Murphy <fpm> | 2014-07-13 14:09 | E, I, U        |   94   
    34 | Finnbarr P. Murphy <fpm> | 2014-06-28 15:48 | Update         |   59   
    33 | System <unset>           | 2014-06-22 11:56 | Install        |    5   
    32 | System <unset>           | 2014-06-22 09:28 | Install        |    1   
    31 | Finnbarr P. Murphy <fpm> | 2014-06-21 13:12 | E, I, U        |   55   
    30 | Finnbarr P. Murphy <fpm> | 2014-06-14 16:53 | E, I, U        |   86   
    29 | Finnbarr P. Murphy <fpm> | 2014-06-07 23:21 | E, I, U        |   43   
    28 | Finnbarr P. Murphy <fpm> | 2014-06-01 08:08 | Update         |   48   
    27 | Finnbarr P. Murphy <fpm> | 2014-05-23 23:09 | Update         |   34   
    26 | Finnbarr P. Murphy <fpm> | 2014-05-17 10:20 | E, I, O, U     |   76 EE
    25 | Finnbarr P. Murphy <fpm> | 2014-05-11 08:53 | E, I, U        |   60 EE
    24 | Finnbarr P. Murphy <fpm> | 2014-05-10 13:50 | Install        |    1   
    23 | Finnbarr P. Murphy <fpm> | 2014-05-09 20:51 | Install        |    3   
    22 | Finnbarr P. Murphy <fpm> | 2014-05-06 22:28 | Install        |    2   
    21 | Finnbarr P. Murphy <fpm> | 2014-05-04 10:36 | E, I, U        |  112 EE
    20 | Finnbarr P. Murphy <fpm> | 2014-04-26 22:21 | Update         |   60   
    19 | Finnbarr P. Murphy <fpm> | 2014-04-20 11:45 | E, I, U        |  122   
    18 | Finnbarr P. Murphy <fpm> | 2014-04-12 15:29 | E, I, U        |   80   
    17 | Finnbarr P. Murphy <fpm> | 2014-04-05 20:39 | E, I, U        |   51 EE
    16 | Finnbarr P. Murphy <fpm> | 2014-03-29 23:28 | Install        |    1   
    15 | Finnbarr P. Murphy <fpm> | 2014-03-29 15:48 | E, I, U        |   58   
    14 | Finnbarr P. Murphy <fpm> | 2014-03-23 10:00 | Update         |  114   
    13 | System <unset>           | 2014-03-15 09:37 | E, I, U        |   99   
    12 | Finnbarr P. Murphy <fpm> | 2014-03-02 22:12 | E, I, U        |  121   
    11 | Finnbarr P. Murphy <fpm> | 2014-02-22 11:20 | E, I, U        |   59   
    10 | Finnbarr P. Murphy <fpm> | 2014-02-16 00:13 | Install        |    9   
     9 | Finnbarr P. Murphy <fpm> | 2014-02-15 09:57 | E, I, U        |  270 EE
     8 | Finnbarr P. Murphy <fpm> | 2014-02-09 00:25 | Install        |    1   
     7 | Finnbarr P. Murphy <fpm> | 2014-02-08 18:49 | I, U           |  159   
     6 | Finnbarr P. Murphy <fpm> | 2013-12-28 18:20 | I, U           |   17   
     5 | Finnbarr P. Murphy <fpm> | 2013-12-26 18:50 | Install        |    4   
     4 | Finnbarr P. Murphy <fpm> | 2013-12-26 16:09 | Install        |    2   
     3 | Finnbarr P. Murphy <fpm> | 2013-12-26 15:50 | Install        |    2   
     2 | Finnbarr P. Murphy <fpm> | 2013-12-26 14:00 | I, O, U        |  271   
     1 | System <unset>           | 2013-12-26 12:23 | Install        | 1536   
history list

If you wish to see detailed information about a particular YUM transaction, use history info:

# yum history info 9
Loaded plugins: langpacks, refresh-packagekit
Transaction ID : 9
Begin time     : Sat Feb 15 09:57:23 2014
Begin rpmdb    : 1559:e820a4aec9e8485cea5a4a6cdb38732646cd027d
End time       :            10:19:06 2014 (21 minutes)
End rpmdb      : 1564:6bed291925efb37803306f9b07fb2dc2fbc9dec6
User           : Finnbarr P. Murphy 
Return-Code    : Success
Command Line   : update
Transaction performed with:
    Updated       rpm-4.11.1-7.fc20.x86_64  @anaconda
    Updated       yum-3.4.3-129.fc20.noarch @updates
Packages Altered:
    Dep-Install GraphicsMagick-1.3.18-4.fc20.x86_64                                @fedora
    Updated     NetworkManager-1:0.9.9.0-23.git20131003.fc20.x86_64                @updates
    Update                     1:0.9.9.0-28.git20131003.fc20.x86_64                @updates
    Updated     NetworkManager-glib-1:0.9.9.0-23.git20131003.fc20.x86_64           @updates
    Update                          1:0.9.9.0-28.git20131003.fc20.x86_64           @updates

    ....

    Updated     python-2.7.5-9.fc20.x86_64                                         @anaconda
    Update             2.7.5-10.fc20.x86_64                                        @updates
    Updated     python-boto-2.13.3-1.fc20.noarch                                   @anaconda
    Update                  2.23.0-1.fc20.noarch                                   @updates
    Dep-Install python-crypto-2.6.1-1.fc20.x86_64                                  @fedora
    Updated     python-cssselect-0.8-1.fc20.noarch                                 @anaconda
    Update                       0.9.1-1.fc20.noarch                               @updates
    Dep-Install python-dropbox-1.6-4.fc20.noarch                                   @fedora
    Updated     python-libs-2.7.5-9.fc20.x86_64                                    @anaconda
    Update                  2.7.5-10.fc20.x86_64                                   @updates
    Dep-Install python-paramiko-1.10.1-2.fc20.noarch                               @fedora
    Updated     python-pycurl-7.19.0-17.20120408git9b8f4e38.fc20.x86_64            @anaconda
    Update                    7.19.3-1.fc20.x86_64                                 @updates
    Updated     python3-3.3.2-8.fc20.x86_64                                        @anaconda
    Update              3.3.2-9.fc20.x86_64                                        @updates
    Updated     python3-libs-3.3.2-8.fc20.x86_64                                   @anaconda
    Update                   3.3.2-9.fc20.x86_64                                   @updates

    ....

    Updated     webkitgtk-2.2.3-1.fc20.x86_64                                      @updates
    Update                2.2.4-1.fc20.x86_64                                      @updates
    Updated     webkitgtk3-2.2.3-1.fc20.x86_64                                     @updates
    Update                 2.2.4-1.fc20.x86_64                                     @updates
    Updated     xemacs-filesystem-21.5.34-4.fc20.noarch                            @anaconda
    Update                        21.5.34-5.fc20.noarch                            @updates
    Updated     xorg-x11-glamor-0.5.1-1.20131009gitba209eee.fc20.x86_64            @anaconda
    Update                      0.5.1-3.20140115gitfb4d046c.fc20.x86_64            @updates
    Updated     xorg-x11-server-Xorg-1.14.4-5.fc20.x86_64                          @anaconda
    Update                           1.14.4-6.fc20.x86_64                          @updates
    Updated     xorg-x11-server-common-1.14.4-5.fc20.x86_64                        @anaconda
    Update                             1.14.4-6.fc20.x86_64                        @updates
    Updated     xulrunner-26.0-2.fc20.x86_64                                       @updates
    Update                27.0-1.fc20.x86_64                                       @updates
    Updated     yum-3.4.3-129.fc20.noarch                                          @updates
    Update          3.4.3-132.fc20.noarch                                          @updates


In the interests of brevity I have not shown all of the output from the above command.

So the big question is can we trace all the updates to a particular package on a system? It turns out that we can as the following example demonstrates using the python-2.7.5 package.

# yum history package-list python-2.7.5
Loaded plugins: langpacks, refresh-packagekit
ID     | Action(s)      | Package                                              
-------------------------------------------------------------------------------
    35 | Updated        | python-2.7.5-12.fc20.x86_64                          
    35 | Update         |        2.7.5-13.fc20.x86_64                          
    34 | Updated        | python-2.7.5-11.fc20.x86_64                          
    34 | Update         |        2.7.5-12.fc20.x86_64                          
    12 | Updated        | python-2.7.5-10.fc20.x86_64                          
    12 | Update         |        2.7.5-11.fc20.x86_64                          
     9 | Updated        | python-2.7.5-9.fc20.x86_64                         EE
     9 | Update         |        2.7.5-10.fc20.x86_64                        EE
     1 | Dep-Install    | python-2.7.5-9.fc20.x86_64                           
history package-list

So where does the YUM history command get it’s information from? As mentioned earlier in this post, YUM stores the transaction history in a single SQLite database file. That is where the information comes from. If the database is damaged, the information may be lost or become unavailable and thus the history command rendered useless.

Here is the YUM history database:

# pwd
/var/lib/yum/history
# ls -al
total 5504
drwxr-xr-x. 1 root root     136 Dec 26  2013 .
drwxr-xr-x. 1 root root      68 Oct  9 17:56 ..
drwxr-xr-x. 1 root root     154 Oct  9 17:55 2013-12-26
-rw-------. 1 root root 5479424 Oct  9 17:56 history-2013-12-26.sqlite
-rw-------. 1 root root  153248 Oct  9 17:56 history-2013-12-26.sqlite-journal
# 


It shows that the history datebase was set up on December 26th 2013.

Notice that each YUM transaction has it’s own subdirectory:

# pwd
/var/lib/yum/history/2013-12-26
# ls -l
total 0
drwx------. 1 root root 46 Dec 26  2013 1
drwx------. 1 root root 62 Feb 16  2014 10
drwx------. 1 root root 62 Feb 22  2014 11
drwx------. 1 root root 62 Mar  2  2014 12
drwx------. 1 root root 62 Mar 15  2014 13
drwx------. 1 root root 62 Mar 23  2014 14
drwx------. 1 root root 62 Mar 29  2014 15
drwx------. 1 root root 62 Mar 29  2014 16
drwx------. 1 root root 62 Apr  5  2014 17
drwx------. 1 root root 62 Apr 12  2014 18
drwx------. 1 root root 62 Apr 20 11:45 19
drwx------. 1 root root 62 Dec 26  2013 2
drwx------. 1 root root 62 Apr 26 22:21 20
drwx------. 1 root root 62 May  4 10:36 21
drwx------. 1 root root 62 May  6 22:28 22
drwx------. 1 root root 62 May  9 20:51 23
drwx------. 1 root root 62 May 10 13:50 24
drwx------. 1 root root 62 May 11 08:53 25
drwx------. 1 root root 62 May 17 10:20 26
drwx------. 1 root root 62 May 23 23:09 27
drwx------. 1 root root 62 Jun  1 08:08 28
drwx------. 1 root root 62 Jun  7 23:21 29
drwx------. 1 root root 62 Dec 26  2013 3
drwx------. 1 root root 62 Jun 14 16:53 30
drwx------. 1 root root 62 Jun 21 13:12 31
drwx------. 1 root root 62 Jun 22 09:28 32
drwx------. 1 root root 62 Jun 22 11:56 33
drwx------. 1 root root 62 Jun 28 15:48 34
drwx------. 1 root root 62 Jul 13 14:09 35
drwx------. 1 root root 62 Jul 25 16:36 36
drwx------. 1 root root 62 Aug  1 16:07 37
drwx------. 1 root root 62 Dec 26  2013 4
drwx------. 1 root root 62 Dec 26  2013 5
drwx------. 1 root root 62 Dec 28  2013 6
drwx------. 1 root root 62 Feb  8  2014 7
drwx------. 1 root root 62 Feb  9  2014 8
drwx------. 1 root root 62 Oct 11 21:21 9
# 

You can also view additional information, such as what configuration options were used at the time of the transaction, or from what repository and why certain packages were installed. For example, to determine what additional information is available for transaction number 8:

# yum history addon-info 8
Loaded plugins: langpacks, refresh-packagekit
Transaction ID: 8
Available additional history information:
  config-main
  config-repos
  saved_tx

history addon-info

Looking deeper into tranaction number 8, here are the contents of the above three files:

# cd 8
# ls -al
total 16
drwx------. 1 root root   62 Feb  9  2014 .
drwxr-xr-x. 1 root root  154 Oct  9 17:55 ..
-rw-r--r--. 1 root root 3398 Feb  9  2014 config-main
-rw-r--r--. 1 root root 7339 Feb  9  2014 config-repos
-rw-r--r--. 1 root root  243 Feb  9  2014 saved_tx

# cat config-main
[main]
alwaysprompt = True
assumeno = False
assumeyes = False
autocheck_running_kernel = True
bandwidth = 0
bugtracker_url = https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&version=rawhide&component=yum
cache = 0
cachedir = /var/cache/yum/x86_64/20
check_config_file_age = True
clean_requirements_on_remove = False
color = auto
color_list_available_downgrade = dim,cyan
color_list_available_install = normal
color_list_available_reinstall = bold,underline,green
color_list_available_running_kernel = bold,underline
color_list_available_upgrade = bold,blue
color_list_installed_extra = bold,red
color_list_installed_newer = bold,yellow
color_list_installed_older = bold
color_list_installed_reinstall = normal
color_list_installed_running_kernel = bold,underline
color_search_match = bold
color_update_installed = normal
color_update_local = bold
color_update_remote = normal
commands = install,
   ksh
debuglevel = 2
deltarpm = 2
deltarpm_metadata_percentage = 100
deltarpm_percentage = 75
depsolve_loop_limit = 100
disable_includes = 
diskspacecheck = True
distroverpkg = system-release(releasever),
   redhat-release
downloaddir = 
downloadonly = 
enable_group_conditionals = True
enabled = True
enablegroups = True
errorlevel = 2
exactarch = True
exactarchlist = 
exclude = 
exit_on_lock = False
failovermethod = priority
fssnap_automatic_keep = 1
fssnap_automatic_post = False
fssnap_automatic_pre = False
fssnap_devices = !*/swap,
   !*/lv_swap
fssnap_percentage = 100
gaftonmode = False
gpgcheck = True
group_command = objects
group_package_types = mandatory,
   default
groupremove_leaf_only = False
history_list_view = single-user-commands
history_record = True
history_record_packages = yum,
   rpm
http_caching = all
installonly_limit = 3
installonlypkgs = kernel,
   kernel-devel,
   kernel-source,
   installonlypkg(kernel),
   installonlypkg(kernel-module),
   installonlypkg(vm)
installroot = /
ip_resolve = 
keepalive = True
keepcache = False
kernelpkgnames = kernel,
   kernel-smp,
   kernel-enterprise,
   kernel-bigmem,
   kernel-BOOT,
   kernel-PAE,
   kernel-PAE-debug
loadts_ignoremissing = False
loadts_ignorenewrpm = False
loadts_ignorerpm = False
localpkg_gpgcheck = False
logfile = /var/log/yum.log
max_connections = 0
mddownloadpolicy = sqlite
mdpolicy = group:small
metadata_expire = 21600
metadata_expire_filter = read-only:present
minrate = 0
mirrorlist_expire = 86400
multilib_policy = best
obsoletes = True
overwrite_groups = False
password = 
persistdir = /var/lib/yum
pluginconfpath = /etc/yum/pluginconf.d
pluginpath = /usr/share/yum-plugins,
   /usr/lib/yum-plugins
plugins = True
progess_obj = 
protected_multilib = True
protected_packages = yum,
   systemd
proxy = False
proxy_password = 
proxy_username = 
recent = 7
recheck_installed_requires = True
remove_leaf_only = False
repo_gpgcheck = False
repopkgsremove_leaf_only = False
reposdir = /etc/yum/repos.d,
   /etc/yum.repos.d
reset_nice = True
retries = 10
rpm_check_debug = True
rpmverbosity = info
showdupesfromrepos = False
skip_broken = False
ssl_check_cert_permissions = True
sslcacert = 
sslclientcert = 
sslclientkey = 
sslverify = True
syslog_device = /dev/log
syslog_facility = LOG_USER
syslog_ident = 
throttle = 0
timeout = 30.0
tolerant = True
tsflags = 
ui_repoid_vars = releasever,
   basearch
upgrade_group_objects_upgrade = True
upgrade_requirements_on_install = False
username = 

# cat config-repos
[fedora]
async = True
bandwidth = 0
base_persistdir = /var/lib/yum/repos/x86_64/20
baseurl = http://mirror.pnl.gov/fedora/linux/releases/20/Everything/x86_64/os/,
   http://mirror.itc.virginia.edu/fedora/releases/20/Everything/x86_64/os/,
   http://mirror.fdcservers.net/fedora/releases/20/Everything/x86_64/os/,
   http://mirror.east.ig2ad.com/Fedora/linux/releases/20/Everything/x86_64/os/,
   http://mirror.csclub.uwaterloo.ca/fedora/linux/releases/20/Everything/x86_64/os/,
   http://mirror.us.as6453.net/fedora/linux/releases/20/Everything/x86_64/os/,
http://mirrors.ucr.ac.cr/fedora/releases/20/Everything/x86_64/os/
cache = 0
cachedir = /var/cache/yum/x86_64/20/fedora
check_config_file_age = True
cost = 1000
deltarpm_metadata_percentage = 100
deltarpm_percentage = 
enabled = True
enablegroups = True
exclude = 
failovermethod = priority
gpgcadir = /var/lib/yum/repos/x86_64/20/fedora/gpgcadir
gpgcakey = 
gpgcheck = True
gpgdir = /var/lib/yum/repos/x86_64/20/fedora/gpgdir
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-20-x86_64
hdrdir = /var/cache/yum/x86_64/20/fedora/headers
http_caching = all
includepkgs = 
ip_resolve = 
keepalive = True
keepcache = False
mddownloadpolicy = sqlite
mdpolicy = group:small
mediaid = 
metadata_expire = 604800
metadata_expire_filter = read-only:present
metalink = https://mirrors.fedoraproject.org/metalink?repo=fedora-20&arch=x86_64
metalink_filename = /var/cache/yum/x86_64/20/fedora/metalink.xml
minrate = 0
mirrorlist = 
mirrorlist_expire = 86400
name = Fedora 20 - x86_64
old_base_cache_dir = 
password = 
persistdir = /var/lib/yum/repos/x86_64/20/fedora
pkgdir = /var/cache/yum/x86_64/20/fedora/packages
proxy = False
proxy_dict = 
proxy_password = 
proxy_username = 
repo_gpgcheck = False
retries = 10
skip_if_unavailable = False
ssl_check_cert_permissions = True
sslcacert = 
sslclientcert = 
sslclientkey = 
sslverify = True
throttle = 0
timeout = 30.0
ui_id = fedora/20/x86_64
ui_repoid_vars = releasever,
   basearch
username = 

[updates]
async = True
bandwidth = 0
base_persistdir = /var/lib/yum/repos/x86_64/20
baseurl = 
cache = 0
cachedir = /var/cache/yum/x86_64/20/updates
check_config_file_age = True
cost = 1000
deltarpm_metadata_percentage = 100
deltarpm_percentage = 
enabled = True
enablegroups = True
exclude = 
failovermethod = priority
gpgcadir = /var/lib/yum/repos/x86_64/20/updates/gpgcadir
gpgcakey = 
gpgcheck = True
gpgdir = /var/lib/yum/repos/x86_64/20/updates/gpgdir
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-20-x86_64
hdrdir = /var/cache/yum/x86_64/20/updates/headers
http_caching = all
includepkgs = 
ip_resolve = 
keepalive = True
keepcache = False
mddownloadpolicy = sqlite
mdpolicy = group:small
mediaid = 
metadata_expire = 21600
metadata_expire_filter = read-only:present
metalink = https://mirrors.fedoraproject.org/metalink?repo=updates-released-f20&arch=x86_64
minrate = 0
mirrorlist = 
mirrorlist_expire = 86400
name = Fedora 20 - x86_64 - Updates
old_base_cache_dir = 
password = 
persistdir = /var/lib/yum/repos/x86_64/20/updates
pkgdir = /var/cache/yum/x86_64/20/updates/packages
proxy = False
proxy_dict = 
proxy_password = 
proxy_username = 
repo_gpgcheck = False
retries = 10
skip_if_unavailable = False
ssl_check_cert_permissions = True
sslcacert = 
sslclientcert = 
sslclientkey = 
sslverify = True
throttle = 0
timeout = 30.0
ui_id = updates/20/x86_64
ui_repoid_vars = releasever,
   basearch
username = 

# cat saved_tx
1558:2ffaa7779b4772d4562ede4dc86c46e2da144a5d
0
1
installed:1559:e820a4aec9e8485cea5a4a6cdb38732646cd027d
1
mbr: ksh,x86_64,0,20120801,11.fc20 70
  repo: fedora
  ts_state: u
  output_state: 20
  isDep: False
  reason: user
  reinstall: False


As you can see from above output, three types of information are available in the three files:

  • config-main: Global YUM options that were in use during the transaction.
  • config-repos: Options for individual YUM repositories in use during the transaction.
  • saved_tx: Data that can be used by the YUM load-transaction command to repeat the transaction on another system. See the YUM manpage for more information.

YUM has its own yumdb command for working with the YUM database. Here is an example of yumdb output:

# yumdb info yum
Loaded plugins: langpacks, refresh-packagekit
yum-3.4.3-152.fc20.noarch
     changed_by = 1000
     checksum_data = 0d243a5f9a063a56752568ed85fe93abfdda8e145d9086786b31a64c5a7d1ce3
     checksum_type = sha256
     command_line = update
     from_repo = updates
     from_repo_revision = 1405211629
     from_repo_timestamp = 1405215330
     installed_by = 4294967295
     reason = user
     releasever = 20


However, I am not going to use that command in this post. Instead, I am going to use sqlite to examine the YUM history database.

To list the tables, views and indices available to you, the quickest way is to examine the database schema as shown below:

# sqlite3 history-2013-12-26.sqlite
SQLite version 3.8.6 2014-08-15 11:46:33
Enter ".help" for usage hints.
sqlite> .fullschema
CREATE TABLE trans_beg (
     tid INTEGER PRIMARY KEY,
     timestamp INTEGER NOT NULL, rpmdb_version TEXT NOT NULL,
     loginuid INTEGER);
CREATE TABLE trans_end (
     tid INTEGER PRIMARY KEY REFERENCES trans_beg,
     timestamp INTEGER NOT NULL, rpmdb_version TEXT NOT NULL,
     return_code INTEGER NOT NULL);
CREATE TABLE trans_with_pkgs (
     tid INTEGER NOT NULL REFERENCES trans_beg,
     pkgtupid INTEGER NOT NULL REFERENCES pkgtups);
CREATE TABLE trans_error (
     mid INTEGER PRIMARY KEY,
     tid INTEGER NOT NULL REFERENCES trans_beg,
     msg TEXT NOT NULL);
CREATE TABLE trans_script_stdout (
     lid INTEGER PRIMARY KEY,
     tid INTEGER NOT NULL REFERENCES trans_beg,
     line TEXT NOT NULL);
CREATE TABLE trans_data_pkgs (
     tid INTEGER NOT NULL REFERENCES trans_beg,
     pkgtupid INTEGER NOT NULL REFERENCES pkgtups,
     done BOOL NOT NULL DEFAULT FALSE, state TEXT NOT NULL);
CREATE TABLE pkgtups (
     pkgtupid INTEGER PRIMARY KEY,     name TEXT NOT NULL, arch TEXT NOT NULL,
     epoch TEXT NOT NULL, version TEXT NOT NULL, release TEXT NOT NULL,
     checksum TEXT);
CREATE INDEX i_pkgtup_naevr ON pkgtups (name, arch, epoch, version, release);
CREATE TABLE trans_skip_pkgs (
     tid INTEGER NOT NULL REFERENCES trans_beg,
     pkgtupid INTEGER NOT NULL REFERENCES pkgtups);
CREATE TABLE trans_cmdline (
     tid INTEGER NOT NULL REFERENCES trans_beg,
     cmdline TEXT NOT NULL);
CREATE TABLE trans_rpmdb_problems (
     rpid INTEGER PRIMARY KEY,
     tid INTEGER NOT NULL REFERENCES trans_beg,
     problem TEXT NOT NULL, msg TEXT NOT NULL);
CREATE TABLE trans_prob_pkgs (
     rpid INTEGER NOT NULL REFERENCES trans_rpmdb_problems,
     pkgtupid INTEGER NOT NULL REFERENCES pkgtups,
     main BOOL NOT NULL DEFAULT FALSE);
CREATE VIEW vtrans_data_pkgs AS
     SELECT tid,name,epoch,version,release,arch,pkgtupid,
            state,done,
            name || '-' || epoch || ':' ||
            version || '-' || release || '.' || arch AS nevra
     FROM trans_data_pkgs JOIN pkgtups USING(pkgtupid)
     ORDER BY name;
CREATE VIEW vtrans_with_pkgs AS
     SELECT tid,name,epoch,version,release,arch,pkgtupid,
            name || '-' || epoch || ':' ||
            version || '-' || release || '.' || arch AS nevra
     FROM trans_with_pkgs JOIN pkgtups USING(pkgtupid)
     ORDER BY name;
CREATE VIEW vtrans_skip_pkgs AS
     SELECT tid,name,epoch,version,release,arch,pkgtupid,
            name || '-' || epoch || ':' ||
            version || '-' || release || '.' || arch AS nevra
     FROM trans_skip_pkgs JOIN pkgtups USING(pkgtupid)
     ORDER BY name;
CREATE VIEW vtrans_prob_pkgs2 AS
     SELECT tid,rpid,name,epoch,version,release,arch,pkgtups.pkgtupid,
            main,problem,msg,
            name || '-' || epoch || ':' ||
            version || '-' || release || '.' || arch AS nevra
     FROM (SELECT * FROM trans_prob_pkgs,trans_rpmdb_problems WHERE
           trans_prob_pkgs.rpid=trans_rpmdb_problems.rpid)
           JOIN pkgtups USING(pkgtupid)
     ORDER BY name;
CREATE TABLE pkg_rpmdb (
     pkgtupid INTEGER NOT NULL REFERENCES pkgtups,
     rpmdb_key TEXT NOT NULL,
     rpmdb_val TEXT NOT NULL);
CREATE INDEX i_pkgkey_rpmdb ON pkg_rpmdb (pkgtupid, rpmdb_key);
CREATE TABLE pkg_yumdb (
     pkgtupid INTEGER NOT NULL REFERENCES pkgtups,
     yumdb_key TEXT NOT NULL,
     yumdb_val TEXT NOT NULL);
CREATE INDEX i_pkgkey_yumdb ON pkg_yumdb (pkgtupid, yumdb_key);
/* No STAT tables available */
sqlite>

If you want to list all the packages in all the tranactions, the simpliest way is to use the vtran_data_pkgs view:

sqlite> select * from vtrans_data_pkgs;
1|Field3D|0|1.3.2|12.fc20|x86_64|270|Dep-Install|TRUE|Field3D-0:1.3.2-12.fc20.x86_64
1|GConf2|0|3.2.6|7.fc20|x86_64|333|Dep-Install|TRUE|GConf2-0:3.2.6-7.fc20.x86_64
1|GREYCstoration|0|2.8|16.fc20|x86_64|843|Install|TRUE|GREYCstoration-0:2.8-16.fc20.x86_64
9|GraphicsMagick|0|1.3.18|4.fc20|x86_64|2128|Dep-Install|TRUE|GraphicsMagick-0:1.3.18-4.fc20.x86_64
26|GraphicsMagick|0|1.3.18|4.fc20|x86_64|2128|Obsoleted|TRUE|GraphicsMagick-0:1.3.18-4.fc20.x86_64
26|GraphicsMagick|0|1.3.19|6.fc20|x86_64|3207|Obsoleting|TRUE|GraphicsMagick-0:1.3.19-6.fc20.x86_64
40|GraphicsMagick|0|1.3.19|6.fc20|x86_64|3207|Updated|TRUE|GraphicsMagick-0:1.3.19-6.fc20.x86_64
40|GraphicsMagick|0|1.3.20|1.fc20|x86_64|4015|Update|TRUE|GraphicsMagick-0:1.3.20-1.fc20.x86_64
41|GraphicsMagick|0|1.3.20|1.fc20|x86_64|4015|Updated|TRUE|GraphicsMagick-0:1.3.20-1.fc20.x86_64
41|GraphicsMagick|0|1.3.20|3.fc20|x86_64|4076|Update|TRUE|GraphicsMagick-0:1.3.20-3.fc20.x86_64
26|GraphicsMagick-doc|0|1.3.19|6.fc20|noarch|3221|Obsoleting|TRUE|GraphicsMagick-doc-0:1.3.19-6.fc20.noarch
40|GraphicsMagick-doc|0|1.3.20|1.fc20|noarch|3995|Update|TRUE|GraphicsMagick-doc-0:1.3.20-1.fc20.noarch
40|GraphicsMagick-doc|0|1.3.19|6.fc20|noarch|3221|Updated|TRUE|GraphicsMagick-doc-0:1.3.19-6.fc20.noarch
41|GraphicsMagick-doc|0|1.3.20|1.fc20|noarch|3995|Updated|TRUE|GraphicsMagick-doc-0:1.3.20-1.fc20.noarch
41|GraphicsMagick-doc|0|1.3.20|3.fc20|noarch|4124|Update|TRUE|GraphicsMagick-doc-0:1.3.20-3.fc20.noarch
1|ImageMagick|0|6.8.6.3|3.fc20|x86_64|660|Dep-Install|TRUE|ImageMagick-0:6.8.6.3-3.fc20.x86_64
19|ImageMagick|0|6.8.6.3|3.fc20|x86_64|660|Updated|TRUE|ImageMagick-0:6.8.6.3-3.fc20.x86_64
19|ImageMagick|0|6.8.6.3|4.fc20|x86_64|2914|Update|TRUE|ImageMagick-0:6.8.6.3-4.fc20.x86_64
1|ImageMagick-c++|0|6.8.6.3|3.fc20|x86_64|969|Dep-Install|TRUE|ImageMagick-c++-0:6.8.6.3-3.fc20.x86_64
19|ImageMagick-c++|0|6.8.6.3|3.fc20|x86_64|969|Updated|TRUE|ImageMagick-c++-0:6.8.6.3-3.fc20.x86_64
19|ImageMagick-c++|0|6.8.6.3|4.fc20|x86_64|2928|Update|TRUE|ImageMagick-c++-0:6.8.6.3-4.fc20.x86_64
1|ImageMagick-libs|0|6.8.6.3|3.fc20|x86_64|405|Dep-Install|TRUE|ImageMagick-libs-0:6.8.6.3-3.fc20.x86_64
19|ImageMagick-libs|0|6.8.6.3|4.fc20|x86_64|2835|Update|TRUE|ImageMagick-libs-0:6.8.6.3-4.fc20.x86_64
19|ImageMagick-libs|0|6.8.6.3|3.fc20|x86_64|405|Updated|TRUE|ImageMagick-libs-0:6.8.6.3-3.fc20.x86_64
1|LibRaw|0|0.15.4|1.fc20|x86_64|415|Dep-Install|TRUE|LibRaw-0:0.15.4-1.fc20.x86_64
1|ModemManager|0|1.1.0|2.git20130913.fc20|x86_64|713|Install|TRUE|ModemManager-0:1.1.0-2.git20130913.fc20.x86_64
1|ModemManager-glib|0|1.1.0|2.git20130913.fc20|x86_64|1519|Dep-Install|TRUE|ModemManager-glib-0:1.1.0-2.git20130913.fc20.x86_64
....
sqlite>

If you wish to view all the packages for a particular tranaction, here is an example of how to do that for transaction number 5 using the SQL where operator:

sqlite> select * from vtrans_data_pkgs where tid = 5;
5|libvirt-python|0|1.1.3.1|2.fc20|x86_64|1814|Dep-Install|TRUE|libvirt-python-0:1.1.3.1-2.fc20.x86_64
5|python-ipaddr|0|2.1.10|1.fc20|noarch|1813|Dep-Install|TRUE|python-ipaddr-0:2.1.10-1.fc20.noarch
5|virt-manager|0|0.10.0|5.git1ffcc0cc.fc20|noarch|1812|Install|TRUE|virt-manager-0:0.10.0-5.git1ffcc0cc.fc20.noarch
5|virt-manager-common|0|0.10.0|5.git1ffcc0cc.fc20|noarch|1811|Dep-Install|TRUE|virt-manager-common-0:0.10.0-5.git1ffcc0cc.fc20.noarch
sqlite>

If you wish to view all the transactions assocated with all python packages, here is one way of doing it using the like pattern matching operator:

sqlite> select * from vtrans_data_pkgs where name like "python-%";
1|python-GnuPGInterface|0|0.3.2|12.fc20|noarch|873|Dep-Install|TRUE|python-GnuPGInterface-0:0.3.2-12.fc20.noarch
1|python-IPy|0|0.75|6.fc20|noarch|889|Dep-Install|TRUE|python-IPy-0:0.75-6.fc20.noarch
7|python-augeas|0|0.4.1|4.fc20|noarch|1922|Dep-Install|TRUE|python-augeas-0:0.4.1-4.fc20.noarch
1|python-backports|0|1.0|3.fc20|x86_64|399|Dep-Install|TRUE|python-backports-0:1.0-3.fc20.x86_64
1|python-backports-ssl_match_hostname|0|3.4.0.2|1.fc20|noarch|312|Dep-Install|TRUE|python-backports-ssl_match_hostname-0:3.4.0.2-1.fc20.noarch
41|python-backports-ssl_match_hostname|0|3.4.0.2|4.fc20|noarch|4123|Update|TRUE|python-backports-ssl_match_hostname-0:3.4.0.2-4.fc20.noarch
41|python-backports-ssl_match_hostname|0|3.4.0.2|1.fc20|noarch|312|Updated|TRUE|python-backports-ssl_match_hostname-0:3.4.0.2-1.fc20.noarch
1|python-boto|0|2.13.3|1.fc20|noarch|389|Dep-Install|TRUE|python-boto-0:2.13.3-1.fc20.noarch
9|python-boto|0|2.13.3|1.fc20|noarch|389|Updated|TRUE|python-boto-0:2.13.3-1.fc20.noarch
9|python-boto|0|2.23.0|1.fc20|noarch|2139|Update|TRUE|python-boto-0:2.23.0-1.fc20.noarch
12|python-boto|0|2.25.0|2.fc20|noarch|2336|Update|TRUE|python-boto-0:2.25.0-2.fc20.noarch
12|python-boto|0|2.23.0|1.fc20|noarch|2139|Updated|TRUE|python-boto-0:2.23.0-1.fc20.noarch
19|python-boto|0|2.25.0|2.fc20|noarch|2336|Updated|TRUE|python-boto-0:2.25.0-2.fc20.noarch
19|python-boto|0|2.27.0|1.fc20|noarch|2848|Update|TRUE|python-boto-0:2.27.0-1.fc20.noarch
41|python-boto|0|2.27.0|1.fc20|noarch|2848|Updated|TRUE|python-boto-0:2.27.0-1.fc20.noarch
41|python-boto|0|2.32.1|1.fc20|noarch|4207|Update|TRUE|python-boto-0:2.32.1-1.fc20.noarch
1|python-caribou|0|0.4.13|1.fc20|noarch|937|Dep-Install|TRUE|python-caribou-0:0.4.13-1.fc20.noarch
1|python-chardet|0|2.0.1|7.fc20|noarch|922|Dep-Install|TRUE|python-chardet-0:2.0.1-7.fc20.noarch
1|python-cloudfiles|0|1.7.10|4.fc20|noarch|1177|Dep-Install|TRUE|python-cloudfiles-0:1.7.10-4.fc20.noarch
9|python-crypto|0|2.6.1|1.fc20|x86_64|2206|Dep-Install|TRUE|python-crypto-0:2.6.1-1.fc20.x86_64
1|python-cssselect|0|0.8|1.fc20|noarch|825|Dep-Install|TRUE|python-cssselect-0:0.8-1.fc20.noarch
9|python-cssselect|0|0.8|1.fc20|noarch|825|Updated|TRUE|python-cssselect-0:0.8-1.fc20.noarch
9|python-cssselect|0|0.9.1|1.fc20|noarch|2221|Update|TRUE|python-cssselect-0:0.9.1-1.fc20.noarch
1|python-cups|0|1.9.63|4.fc20|x86_64|1503|Dep-Install|TRUE|python-cups-0:1.9.63-4.fc20.x86_64
14|python-cups|0|1.9.65|1.fc20|x86_64|2539|Update|TRUE|python-cups-0:1.9.65-1.fc20.x86_64
14|python-cups|0|1.9.63|4.fc20|x86_64|1503|Updated|TRUE|python-cups-0:1.9.63-4.fc20.x86_64
38|python-cups|0|1.9.65|1.fc20|x86_64|2539|Updated|TRUE|python-cups-0:1.9.65-1.fc20.x86_64
38|python-cups|0|1.9.65|2.fc20|x86_64|3899|Update|TRUE|python-cups-0:1.9.65-2.fc20.x86_64
1|python-decorator|0|3.4.0|3.fc20|noarch|1326|Dep-Install|TRUE|python-decorator-0:3.4.0-3.fc20.noarch
1|python-decoratortools|0|1.8|7.fc20|noarch|1000|Dep-Install|TRUE|python-decoratortools-0:1.8-7.fc20.noarch
1|python-deltarpm|0|3.6|3.fc20|x86_64|1240|Dep-Install|TRUE|python-deltarpm-0:3.6-3.fc20.x86_64
9|python-dropbox|0|1.6|4.fc20|noarch|2173|Dep-Install|TRUE|python-dropbox-0:1.6-4.fc20.noarch
1|python-iniparse|0|0.4|9.fc20|noarch|324|Dep-Install|TRUE|python-iniparse-0:0.4-9.fc20.noarch
1|python-inotify|0|0.9.4|4.fc20|noarch|1053|Dep-Install|TRUE|python-inotify-0:0.9.4-4.fc20.noarch
5|python-ipaddr|0|2.1.10|1.fc20|noarch|1813|Dep-Install|TRUE|python-ipaddr-0:2.1.10-1.fc20.noarch
1|python-javapackages|0|3.4.1|1.fc20|noarch|304|Dep-Install|TRUE|python-javapackages-0:3.4.1-1.fc20.noarch
1|python-kitchen|0|1.1.1|5.fc20|noarch|127|Dep-Install|TRUE|python-kitchen-0:1.1.1-5.fc20.noarch
1|python-krbV|0|1.0.90|7.fc20|x86_64|728|Dep-Install|TRUE|python-krbV-0:1.0.90-7.fc20.x86_64
1|python-libs|0|2.7.5|9.fc20|x86_64|1010|Dep-Install|TRUE|python-libs-0:2.7.5-9.fc20.x86_64
9|python-libs|0|2.7.5|10.fc20|x86_64|2101|Update|TRUE|python-libs-0:2.7.5-10.fc20.x86_64
9|python-libs|0|2.7.5|9.fc20|x86_64|1010|Updated|TRUE|python-libs-0:2.7.5-9.fc20.x86_64
12|python-libs|0|2.7.5|11.fc20|x86_64|2369|Update|TRUE|python-libs-0:2.7.5-11.fc20.x86_64
12|python-libs|0|2.7.5|10.fc20|x86_64|2101|Updated|TRUE|python-libs-0:2.7.5-10.fc20.x86_64
34|python-libs|0|2.7.5|11.fc20|x86_64|2369|Updated|TRUE|python-libs-0:2.7.5-11.fc20.x86_64
34|python-libs|0|2.7.5|12.fc20|x86_64|3564|Update|TRUE|python-libs-0:2.7.5-12.fc20.x86_64
35|python-libs|0|2.7.5|13.fc20|x86_64|3635|Update|TRUE|python-libs-0:2.7.5-13.fc20.x86_64
35|python-libs|0|2.7.5|12.fc20|x86_64|3564|Updated|TRUE|python-libs-0:2.7.5-12.fc20.x86_64
41|python-libs|0|2.7.5|14.fc20|x86_64|4075|Update|TRUE|python-libs-0:2.7.5-14.fc20.x86_64
41|python-libs|0|2.7.5|13.fc20|x86_64|3635|Updated|TRUE|python-libs-0:2.7.5-13.fc20.x86_64
25|python-lockfile|1|0.9.1|5.fc20|noarch|3142|Dep-Install|TRUE|python-lockfile-1:0.9.1-5.fc20.noarch
1|python-lxml|0|3.2.4|1.fc20|x86_64|1281|Dep-Install|TRUE|python-lxml-0:3.2.4-1.fc20.x86_64
14|python-lxml|0|3.3.3|1.fc20|x86_64|2562|Update|TRUE|python-lxml-0:3.3.3-1.fc20.x86_64
14|python-lxml|0|3.2.4|1.fc20|x86_64|1281|Updated|TRUE|python-lxml-0:3.2.4-1.fc20.x86_64
19|python-lxml|0|3.3.3|1.fc20|x86_64|2562|Updated|TRUE|python-lxml-0:3.3.3-1.fc20.x86_64
19|python-lxml|0|3.3.3|4.fc20|x86_64|2897|Update|TRUE|python-lxml-0:3.3.3-4.fc20.x86_64
21|python-lxml|0|3.3.3|4.fc20|x86_64|2897|Updated|TRUE|python-lxml-0:3.3.3-4.fc20.x86_64
21|python-lxml|0|3.3.5|1.fc20|x86_64|3114|Update|TRUE|python-lxml-0:3.3.5-1.fc20.x86_64
41|python-lxml|0|3.3.6|1.fc20|x86_64|4024|Update|TRUE|python-lxml-0:3.3.6-1.fc20.x86_64
41|python-lxml|0|3.3.5|1.fc20|x86_64|3114|Updated|TRUE|python-lxml-0:3.3.5-1.fc20.x86_64
1|python-nose|0|1.3.0|1.fc20|noarch|639|Dep-Install|TRUE|python-nose-0:1.3.0-1.fc20.noarch
9|python-paramiko|0|1.10.1|2.fc20|noarch|2008|Dep-Install|TRUE|python-paramiko-0:1.10.1-2.fc20.noarch
1|python-pillow|0|2.2.1|2.fc20|x86_64|1115|Dep-Install|TRUE|python-pillow-0:2.2.1-2.fc20.x86_64
14|python-pillow|0|2.2.1|3.fc20|x86_64|2546|Update|TRUE|python-pillow-0:2.2.1-3.fc20.x86_64
14|python-pillow|0|2.2.1|2.fc20|x86_64|1115|Updated|TRUE|python-pillow-0:2.2.1-2.fc20.x86_64
21|python-pillow|0|2.2.1|3.fc20|x86_64|2546|Updated|TRUE|python-pillow-0:2.2.1-3.fc20.x86_64
21|python-pillow|0|2.2.1|4.fc20|x86_64|3028|Update|TRUE|python-pillow-0:2.2.1-4.fc20.x86_64
40|python-pillow|0|2.2.1|4.fc20|x86_64|3028|Updated|TRUE|python-pillow-0:2.2.1-4.fc20.x86_64
40|python-pillow|0|2.2.1|5.fc20|x86_64|4001|Update|TRUE|python-pillow-0:2.2.1-5.fc20.x86_64
1|python-pwquality|0|1.2.3|1.fc20|x86_64|604|Dep-Install|TRUE|python-pwquality-0:1.2.3-1.fc20.x86_64
1|python-pycurl|0|7.19.0|17.20120408git9b8f4e38.fc20|x86_64|1256|Dep-Install|TRUE|python-pycurl-0:7.19.0-17.20120408git9b8f4e38.fc20.x86_64
9|python-pycurl|0|7.19.0|17.20120408git9b8f4e38.fc20|x86_64|1256|Updated|TRUE|python-pycurl-0:7.19.0-17.20120408git9b8f4e38.fc20.x86_64
9|python-pycurl|0|7.19.3|1.fc20|x86_64|2123|Update|TRUE|python-pycurl-0:7.19.3-1.fc20.x86_64
1|python-reportlab|0|2.5|8.fc20|x86_64|449|Dep-Install|TRUE|python-reportlab-0:2.5-8.fc20.x86_64
25|python-reportlab|0|3.1.8|1.fc20|x86_64|3147|Update|TRUE|python-reportlab-0:3.1.8-1.fc20.x86_64
25|python-reportlab|0|2.5|8.fc20|x86_64|449|Updated|TRUE|python-reportlab-0:2.5-8.fc20.x86_64
1|python-setuptools|0|1.3.1|1.fc20|noarch|38|Dep-Install|TRUE|python-setuptools-0:1.3.1-1.fc20.noarch
2|python-setuptools|0|1.3.1|1.fc20|noarch|38|Updated|TRUE|python-setuptools-0:1.3.1-1.fc20.noarch
2|python-setuptools|0|1.4|1.fc20|noarch|1682|Update|TRUE|python-setuptools-0:1.4-1.fc20.noarch
7|python-setuptools|0|1.4|1.fc20|noarch|1682|Updated|TRUE|python-setuptools-0:1.4-1.fc20.noarch
7|python-setuptools|0|1.4.2|1.fc20|noarch|1959|Update|TRUE|python-setuptools-0:1.4.2-1.fc20.noarch
1|python-six|0|1.4.1|1.fc20|noarch|342|Dep-Install|TRUE|python-six-0:1.4.1-1.fc20.noarch
19|python-six|0|1.5.2|1.fc20|noarch|2838|Update|TRUE|python-six-0:1.5.2-1.fc20.noarch
19|python-six|0|1.4.1|1.fc20|noarch|342|Updated|TRUE|python-six-0:1.4.1-1.fc20.noarch
26|python-six|0|1.5.2|1.fc20|noarch|2838|Updated|TRUE|python-six-0:1.5.2-1.fc20.noarch
26|python-six|0|1.6.1|1.fc20|noarch|3242|Update|TRUE|python-six-0:1.6.1-1.fc20.noarch
38|python-six|0|1.6.1|1.fc20|noarch|3242|Updated|TRUE|python-six-0:1.6.1-1.fc20.noarch
38|python-six|0|1.7.3|1.fc20|noarch|3918|Update|TRUE|python-six-0:1.7.3-1.fc20.noarch
1|python-slip|0|0.6.0|1.fc20|noarch|714|Dep-Install|TRUE|python-slip-0:0.6.0-1.fc20.noarch
1|python-slip-dbus|0|0.6.0|1.fc20|noarch|1528|Dep-Install|TRUE|python-slip-dbus-0:0.6.0-1.fc20.noarch
1|python-sssdconfig|0|1.11.2|1.fc20|noarch|1448|Dep-Install|TRUE|python-sssdconfig-0:1.11.2-1.fc20.noarch
7|python-sssdconfig|0|1.11.2|1.fc20|noarch|1448|Updated|TRUE|python-sssdconfig-0:1.11.2-1.fc20.noarch
7|python-sssdconfig|0|1.11.3|1.fc20|noarch|1925|Update|TRUE|python-sssdconfig-0:1.11.3-1.fc20.noarch
12|python-sssdconfig|0|1.11.3|1.fc20|noarch|1925|Updated|TRUE|python-sssdconfig-0:1.11.3-1.fc20.noarch
12|python-sssdconfig|0|1.11.4|1.fc20|noarch|2437|Update|TRUE|python-sssdconfig-0:1.11.4-1.fc20.noarch
18|python-sssdconfig|0|1.11.4|3.fc20|noarch|2758|Update|TRUE|python-sssdconfig-0:1.11.4-3.fc20.noarch
18|python-sssdconfig|0|1.11.4|1.fc20|noarch|2437|Updated|TRUE|python-sssdconfig-0:1.11.4-1.fc20.noarch
20|python-sssdconfig|0|1.11.5.1|1.fc20|noarch|2971|Update|TRUE|python-sssdconfig-0:1.11.5.1-1.fc20.noarch
20|python-sssdconfig|0|1.11.4|3.fc20|noarch|2758|Updated|TRUE|python-sssdconfig-0:1.11.4-3.fc20.noarch
35|python-sssdconfig|0|1.11.5.1|1.fc20|noarch|2971|Updated|TRUE|python-sssdconfig-0:1.11.5.1-1.fc20.noarch
35|python-sssdconfig|0|1.11.6|1.fc20|noarch|3643|Update|TRUE|python-sssdconfig-0:1.11.6-1.fc20.noarch
41|python-sssdconfig|0|1.11.6|3.fc20|noarch|4125|Update|TRUE|python-sssdconfig-0:1.11.6-3.fc20.noarch
41|python-sssdconfig|0|1.11.6|1.fc20|noarch|3643|Updated|TRUE|python-sssdconfig-0:1.11.6-1.fc20.noarch
42|python-sssdconfig|0|1.11.6|3.fc20|noarch|4125|Updated|TRUE|python-sssdconfig-0:1.11.6-3.fc20.noarch
42|python-sssdconfig|0|1.11.7|2.fc20|noarch|4246|Update|TRUE|python-sssdconfig-0:1.11.7-2.fc20.noarch
1|python-urlgrabber|0|3.9.1|32.fc20|noarch|1215|Dep-Install|TRUE|python-urlgrabber-0:3.9.1-32.fc20.noarch
29|python-urlgrabber|0|3.10.1|0.fc20|noarch|3338|Update|TRUE|python-urlgrabber-0:3.10.1-0.fc20.noarch
29|python-urlgrabber|0|3.9.1|32.fc20|noarch|1215|Updated|TRUE|python-urlgrabber-0:3.9.1-32.fc20.noarch
sqlite>>

And if you wish only to see the tranactions assocated with the python package:

sqlite> select * from vtrans_data_pkgs where name like "python";
1|python|0|2.7.5|9.fc20|x86_64|856|Dep-Install|TRUE|python-0:2.7.5-9.fc20.x86_64
9|python|0|2.7.5|9.fc20|x86_64|856|Updated|TRUE|python-0:2.7.5-9.fc20.x86_64
9|python|0|2.7.5|10.fc20|x86_64|2115|Update|TRUE|python-0:2.7.5-10.fc20.x86_64
12|python|0|2.7.5|11.fc20|x86_64|2351|Update|TRUE|python-0:2.7.5-11.fc20.x86_64
12|python|0|2.7.5|10.fc20|x86_64|2115|Updated|TRUE|python-0:2.7.5-10.fc20.x86_64
34|python|0|2.7.5|12.fc20|x86_64|3521|Update|TRUE|python-0:2.7.5-12.fc20.x86_64
34|python|0|2.7.5|11.fc20|x86_64|2351|Updated|TRUE|python-0:2.7.5-11.fc20.x86_64
35|python|0|2.7.5|12.fc20|x86_64|3521|Updated|TRUE|python-0:2.7.5-12.fc20.x86_64
35|python|0|2.7.5|13.fc20|x86_64|3628|Update|TRUE|python-0:2.7.5-13.fc20.x86_64
sqlite>

Note that root may start a new transaction history database at anytime:

# yum history new

This will create a new, empty database in the /var/lib/yum/history/ directory. The old transaction history is kept in the old database files, but will not be accessible as long as a newer database file is present in the directory. To access the old transaction history, you will have to use sqlite.

Well that is all for now. Assuming the existance of a suitable YUM history database, you should now be able to determine the precise history of any specific package on a system.

3 comments to YUM Package Installation Updating and Removal Forensics

  • Thanks, useful and informative.

  • Thiago

    Nice post.
    How do I get the installation date from the sqlite3 database?

    I am developing an EnScript where I would like to extract all packages installed on a Linux Red Hat and their related installation dates.

    Thanks.

    • The YUM database is not the way to find this information because users may have used the rpm utility to install packages.

      Instead use something like the following:

      # rpm -qa –queryformat ‘ (%{installtime:day}) %-40{name}%{distribution}\n’