# A plugin for yum which only leaves n 'kernel' packages installed instead
# of infinitely doing installonly
#
# Copyright 2005  Red Hat, Inc.
# Jeremy Katz <katzj@redhat.com>
#
# 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.
#
# version 0.92

import os
from rpmUtils import miscutils
from yum.plugins import TYPE_CORE
from yum.packages import YumInstalledPackage, comparePoEVR

requires_api_version = '2.4'
plugin_type = TYPE_CORE

def get_running_kernel_version_release():
    """This takes the output of uname and figures out the (version, release)
    tuple for the running kernel."""
    ver = os.uname()[2]
    for s in ("bigmem", "enterprise", "smp", "hugemem", "PAE",
              "guest", "hypervisor", "xen0", "xenU", "xen"):
        if ver.endswith(s):
            ver = ver.replace(s, "")
    if ver.find("-") != -1:
        (v, r) = ver.split("-", 1)
        return (v, r)
    return (None, None)

def config_hook(conduit):
    global num_tokeep
    num_tokeep = conduit.confInt('main', 'tokeep', default=2)
    
def postresolve_hook(conduit):
    ts = conduit.getTsInfo()
    rpmdb = conduit.getRpmDB()
    conf = conduit.getConf()
    mems = ts.getMembers()
    toremove = []
    for instpkg in conf.installonlypkgs:
        for m in mems:
            if (m.name == instpkg or instpkg in m.po.provides_names) \
                   and m.ts_state in ('i', 'u'):
                installed = rpmdb.searchNevra(name=m.name)
                if len(installed) >= num_tokeep - 1: # since we're adding one
                    numleft = len(installed) - num_tokeep + 1
                    (curv, curr) = get_running_kernel_version_release()
                    
                    installed.sort(comparePoEVR)
                    for po in installed:
                        if (po.version, po.release) == (curv, curr): 
                            # don't remove running
                            continue
                        if numleft == 0:
                            break
                        toremove.append(po)
                        numleft -= 1
                        
    map(lambda x: ts.addErase(x), toremove)
