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