Blame SOURCES/BZ-1470647-add-pre-transaction-actions-plugin.patch

911d2c
diff -up yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.conf.orig yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.conf
911d2c
--- yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.conf.orig	2017-10-27 17:30:16.579550073 +0200
911d2c
+++ yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.conf	2017-10-27 17:30:16.579550073 +0200
911d2c
@@ -0,0 +1,3 @@
911d2c
+[main]
911d2c
+enabled = 1
911d2c
+actiondir = /etc/yum/pre-actions/
911d2c
diff -up yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py.orig yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py
911d2c
--- yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py.orig	2017-10-27 17:30:16.579550073 +0200
911d2c
+++ yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py	2017-10-27 17:30:16.579550073 +0200
911d2c
@@ -0,0 +1,164 @@
911d2c
+# This program is free software; you can redistribute it and/or modify
911d2c
+# it under the terms of the GNU General Public License as published by
911d2c
+# the Free Software Foundation; either version 2 of the License, or
911d2c
+# (at your option) any later version.
911d2c
+#
911d2c
+# This program is distributed in the hope that it will be useful,
911d2c
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
911d2c
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
911d2c
+# GNU Library General Public License for more details.
911d2c
+#
911d2c
+# You should have received a copy of the GNU General Public License
911d2c
+# along with this program; if not, write to the Free Software
911d2c
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
911d2c
+
911d2c
+# Copyright 2008 Red Hat, Inc
911d2c
+# written by Seth Vidal <skvidal@fedoraproject.org>
911d2c
+
911d2c
+"""
911d2c
+This plugin runs actions prior to the transaction based on the content of the
911d2c
+transaction.
911d2c
+"""
911d2c
+
911d2c
+
911d2c
+from yum.plugins import TYPE_CORE
911d2c
+from yum.constants import *
911d2c
+import yum.misc
911d2c
+from yum.parser import varReplace
911d2c
+from yum.packages import parsePackages
911d2c
+import fnmatch
911d2c
+import re
911d2c
+import os
911d2c
+import glob
911d2c
+import shlex
911d2c
+
911d2c
+requires_api_version = '2.4'
911d2c
+plugin_type = (TYPE_CORE,)
911d2c
+
911d2c
+def parse_actions(ddir, conduit):
911d2c
+    """read in .action files from ddir path. 
911d2c
+       store content in a list of tuples"""
911d2c
+    action_tuples = [] # (action key, action_state, shell command)
911d2c
+    action_file_list = []
911d2c
+    if os.access(ddir, os.R_OK): 
911d2c
+        action_file_list.extend(glob.glob(ddir + "*.action"))
911d2c
+
911d2c
+    if action_file_list:
911d2c
+        for f in action_file_list:
911d2c
+            for line in open(f).readlines():
911d2c
+                line = line.strip()
911d2c
+                if line and line[0] != "#":
911d2c
+                    try:
911d2c
+                        (a_key, a_state, a_command) = line.split(':', 2)
911d2c
+                    except ValueError,e:
911d2c
+                        conduit.error(2,'Bad Action Line: %s' % line)
911d2c
+                        continue
911d2c
+                    else:
911d2c
+                        action_tuples.append((a_key, a_state, a_command))
911d2c
+
911d2c
+    return action_tuples
911d2c
+
911d2c
+def _convert_vars(txmbr, command):
911d2c
+    """converts %options on the command to their values from the package it
911d2c
+       is running it for: takes $name, $arch, $ver, $rel, $epoch, 
911d2c
+       $state, $repoid"""
911d2c
+    state_dict = { TS_INSTALL: 'install',
911d2c
+                   TS_TRUEINSTALL: 'install',
911d2c
+                   TS_OBSOLETING: 'obsoleting',
911d2c
+                   TS_UPDATE: 'updating',
911d2c
+                   TS_ERASE: 'remove',
911d2c
+                   TS_OBSOLETED: 'obsoleted',
911d2c
+                   TS_UPDATED: 'updated'}
911d2c
+    try:
911d2c
+        state = state_dict[txmbr.output_state]
911d2c
+    except KeyError:
911d2c
+        state = 'unknown - %s' % txmbr.output_state
911d2c
+
911d2c
+    vardict = {'name': txmbr.name,
911d2c
+               'arch': txmbr.arch,
911d2c
+               'ver': txmbr.version,
911d2c
+               'rel': txmbr.release,
911d2c
+               'epoch': txmbr.epoch,
911d2c
+               'repoid': txmbr.repoid,
911d2c
+               'state':  state }
911d2c
+
911d2c
+    result = varReplace(command, vardict)
911d2c
+    return result
911d2c
+            
911d2c
+
911d2c
+def pretrans_hook(conduit):
911d2c
+    # we have provides/requires for everything
911d2c
+    # we do not have filelists for erasures
911d2c
+    # we have to fetch filelists for the package object for installs/updates
911d2c
+    action_dir = conduit.confString('main','actiondir','/etc/yum/pre-actions/')
911d2c
+    action_tuples = parse_actions(action_dir, conduit)
911d2c
+    commands_to_run = {}
911d2c
+    ts = conduit.getTsInfo()
911d2c
+    all = ts.getMembers()
911d2c
+    removes = ts.getMembersWithState(output_states=TS_REMOVE_STATES)
911d2c
+    installs = ts.getMembersWithState(output_states=TS_INSTALL_STATES)
911d2c
+    updates = ts.getMembersWithState(output_states=[TS_UPDATE, TS_OBSOLETING])
911d2c
+
911d2c
+    for (a_k, a_s, a_c) in action_tuples:
911d2c
+        #print 'if %s in state %s the run %s' %( a_k, a_s, a_c)
911d2c
+        if a_s  == 'update':
911d2c
+            pkgset = updates
911d2c
+        elif a_s == 'install':
911d2c
+            pkgset = installs
911d2c
+        elif a_s == 'remove':
911d2c
+            pkgset = removes
911d2c
+        elif a_s == 'any':
911d2c
+            pkgset = all
911d2c
+        else:
911d2c
+            # no idea what this is skip it
911d2c
+            conduit.error(2,'whaa? %s' % a_s)
911d2c
+            continue
911d2c
+
911d2c
+        if a_k.startswith('/'):
911d2c
+            if yum.misc.re_glob(a_k):
911d2c
+                restring = fnmatch.translate(a_k)
911d2c
+                c_string = re.compile(restring)
911d2c
+
911d2c
+            for txmbr in pkgset:
911d2c
+                matched = False
911d2c
+                thispo = txmbr.po
911d2c
+        
911d2c
+                if not yum.misc.re_glob(a_k):
911d2c
+                    if a_k in thispo.filelist + thispo.dirlist + thispo.ghostlist:
911d2c
+                        thiscommand = _convert_vars(txmbr, a_c)
911d2c
+                        commands_to_run[thiscommand] = 1
911d2c
+                        matched = True
911d2c
+                else:
911d2c
+                    for name in thispo.filelist + thispo.dirlist + thispo.ghostlist:
911d2c
+                        if c_string.match(name):
911d2c
+                            thiscommand = _convert_vars(txmbr, a_c)
911d2c
+                            commands_to_run[thiscommand] = 1
911d2c
+                            matched = True
911d2c
+                            break
911d2c
+                
911d2c
+                if matched:
911d2c
+                    break
911d2c
+            continue
911d2c
+        
911d2c
+        if a_k.find('/') == -1: # pkgspec
911d2c
+            pkgs = [ txmbr.po for txmbr in pkgset ]
911d2c
+            e,m,u = parsePackages(pkgs, [a_k])
911d2c
+            if not u:
911d2c
+                for pkg in e+m:
911d2c
+                    for txmbr in ts.getMembers(pkgtup=pkg.pkgtup):
911d2c
+                        thiscommand = _convert_vars(txmbr, a_c)
911d2c
+                        commands_to_run[thiscommand] = 1
911d2c
+            continue
911d2c
+
911d2c
+    for comm in commands_to_run.keys():
911d2c
+        try:
911d2c
+            args = shlex.split(comm)
911d2c
+        except ValueError, e:
911d2c
+            conduit.error(2,"command was not parseable: %s" % comm)
911d2c
+            continue
911d2c
+        #try
911d2c
+        conduit.info(2,'Running pre transaction command: %s' % comm)
911d2c
+        p = os.system(comm)
911d2c
+        #except?
911d2c
+
911d2c
+
911d2c
diff -up yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action.orig yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action
911d2c
--- yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action.orig	2017-10-27 17:30:16.579550073 +0200
911d2c
+++ yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action	2017-10-27 17:30:16.579550073 +0200
911d2c
@@ -0,0 +1,21 @@
911d2c
+#action_key:transaction_state:command
911d2c
+# action_key can be: pkgglob, /path/to/file (wildcards allowed)
911d2c
+# transaction_state can be: install,update,remove,any
911d2c
+# command can be: any shell command
911d2c
+#  the following variables are allowed to be passed to any command:
911d2c
+#   $name - package name
911d2c
+#   $arch - package arch
911d2c
+#   $ver - package version
911d2c
+#   $rel - package release
911d2c
+#   $epoch - package epoch
911d2c
+#   $repoid - package repository id
911d2c
+#   $state - text string of state of the package in the transaction set
911d2c
+#
911d2c
+# file matches cannot be used with removes b/c we don't have the info available
911d2c
+
911d2c
+*:install:touch /tmp/$name-installed
911d2c
+zsh:remove:touch /tmp/zsh-removed
911d2c
+zsh:install:touch /tmp/zsh-installed-also
911d2c
+/bin/z*h:install:touch /tmp/bin-zsh-installed
911d2c
+z*h:any:touch /tmp/bin-zsh-any
911d2c
+