def predownload_hook(conduit): """ Get a list of pkgs that should be downloaded by yum, and update the includepkgs / exclude field in the config. :param conduit: :class:`yum.plugins.DownloadPluginConduit` :raises: :class:`yum.plugins.PluginYumExit` if an error occurred when trying to build the pkgs list, or if "skip_install" config option == True """ repoid_to_pkgs = defaultdict(set) pkgs_to_dl = conduit.getDownloadPackages() errors = conduit.getErrors() if errors: conduit.info(2, errors) raise PluginYumExit( 'Error were detected in predownload_hook, aborting' ) for pkg in pkgs_to_dl: repoid_to_pkgs[pkg.repoid].add(pkg.name) set_include(cache['config_file_path'], repoid_to_pkgs) if conduit.confBool('main', 'skip_install', default=False): raise PluginYumExit('reposync_config_builder: Skipping install')
def doCheck(self, base, basecmd, extcmds): if base.conf.uid: raise PluginYumExit('You need to be root to perform this command.') if not len(extcmds): raise PluginYumExit('You need to specify a key to remove.') if hasattr(base, 'run_with_package_names'): base.run_with_package_names.add("yum-plugin-keys")
def doCommand(self, base, basecmd, extcmds): logger = logging.getLogger("yum.verbose.main") def msg(x): logger.log(logginglevels.INFO_2, x) def msg_warn(x): logger.warn(x) self._done_spkgs = {} self._pkgs = 0 self._spkgs = 0 self._changelogs = 0 self._since_all = False self._since_dto = None self._since_tt = None self._since_num = None if not len(extcmds): return 1, [basecmd + " " + self.getUsage()] since = extcmds[0] extcmds = extcmds[1:] if since == 'all': self._since_all = True else: try: num = int(since) if num <= 0: raise ValueError self._since_num = num except: if dateutil_parser is None: msg = "Dateutil module not available, so can't parse dates" raise PluginYumExit(msg) try: self._since_dto = dateutil_parser.parse(since, fuzzy=True) except ValueError: msg = "Argument -- %s -- is not \"all\", a positive number or a date" % since raise PluginYumExit(msg) try: tt = self._since_dto.timetuple() self._since_tt = time.mktime(tt) except ValueError, e: msg = "Argument -- %s -- is not valid: %s" % (since, to_str(e)) raise PluginYumExit(msg) if self._since_dto == dateutil_parser.parse('garbage', fuzzy=True): # 'since' was a package name, not a date extcmds.insert(0, since) # assume since="all" self._since_all = True self._since_dto = None self._since_tt = None
def pretrans_hook(conduit): conduit.info(2, 'etckeeper: pre transaction commit') servicecmd = conduit.confString('main', 'servicecmd', '/usr/bin/etckeeper') command = '%s %s' % (servicecmd, " pre-install") ret = os.system(command) if ret != 0: raise PluginYumExit('etckeeper returned %d' % (ret >> 8))
def postresolve_hook(conduit): opts, commands = conduit.getCmdLine() if opts.json: packages = {} for transaction in conduit.getTsInfo(): if transaction.name not in packages: packages[transaction.name] = {} version = { "version": transaction.version, "release": transaction.release, "epoch": transaction.epoch, "arch": transaction.arch, "state": transaction.ts_state, "repo": getattr(transaction.po, 'repoid') } if transaction.ts_state: packages[transaction.name]["pending"] = version else: packages[transaction.name]["current"] = version print(simplejson.dumps(packages)) raise PluginYumExit('')
def preresolve_hook(conduit): global relstr ts = conduit.getTsInfo() opts,commands = conduit.getCmdLine() if opts.relKey != None: relstr = opts.relKey installs = ts.getMembersWithState(output_states=[TS_INSTALL,TS_TRUEINSTALL]) updates = ts.getMembersWithState(output_states=[TS_UPDATE,TS_OBSOLETING]) removes = ts.getMembersWithState(output_states=TS_REMOVE_STATES) if (len(installs)>0) and (relstr is not None): global expk for p in conduit.getPackages(): if p.release.find(relstr)>0: expk[p.name] = p for pi in installs: if pi.name in expk: conduit.info(2,'Installation of package %s will deviate '\ 'from build' % pi.po) if opts.yumexit!=False: conduit.info(2,'Removing %s from install list' % pi.po) ts.remove(pi.pkgtup) conduit.info(2,'Adding %s to install list' % expk[pi.name]) ts.addInstall(expk[pi.name]) if _check_ups_rem_rel(updates,removes) == True: for pu in updates: for pr in removes: if pr.name == pu.name: protect = protect_release(pu,pr) if protect==True: conduit.info(2,'Upgrade of package %s will deviate '\ 'from build' % pu.name) if opts.yumexit != False: raise PluginYumExit('Upgrade operation terminated as new '\ 'package(s) will deviate from build')
def init_hook(conduit): conf = conduit.getConf() lockfile = conduit.confString('main', 'lockfile', default=None) if os.path.isfile(lockfile): raise PluginYumExit( "This system is currently locked for patching. Try again in a couple of days" )
def _read_locklist(): locklist = [] try: llfile = urlgrabber.urlopen(fileurl) for line in llfile.readlines(): if line.startswith('#') or line.strip() == '': continue locklist.append(line.rstrip()) llfile.close() except urlgrabber.grabber.URLGrabError, e: raise PluginYumExit('Unable to read version lock configuration: %s' % e)
def _load_whitelist(): try: if fileurl: llfile = urlgrabber.urlopen(fileurl) for line in llfile.readlines(): if line.startswith('#') or line.strip() == '': continue _package_whitelist.add(line.rstrip().lower()) llfile.close() except urlgrabber.grabber.URLGrabError, e: raise PluginYumExit( 'Unable to read Foreman protector"s configuration: %s' % e)
def pretrans_hook(conduit): ts = conduit.getTsInfo() packages = ts.updated + ts.installed + ts.depinstalled + ts.depupdated + ts.reinstalled + ts.downgraded prompt = [] for p in packages: for file in p.po.filelist: if file in puppet_files: prompt.append( "Installing %s overwrites puppet-managed file %s" % (str(p.po), file)) if prompt: if not conduit.promptYN('\n'.join(prompt)): raise PluginYumExit('Aborting')
def exclude_hook(conduit): if no_exclude: return conduit.info(3, 'Reading version lock configuration') if not fileurl: raise PluginYumExit('Locklist not set') for ent in _read_locklist(): neg = False if ent and ent[0] == '!': ent = ent[1:] neg = True (n, v, r, e, a) = splitFilename(ent) n = n.lower() v = v.lower() r = r.lower() e = e.lower() if e == '': e = '0' if neg: _version_lock_excluder_B_nevr.add("%s-%s:%s-%s" % (n, e, v, r)) continue _version_lock_excluder_n.add(n) _version_lock_excluder_nevr.add("%s-%s:%s-%s" % (n, e, v, r)) if (_version_lock_excluder_n and follow_obsoletes): # If anything obsoletes something that we have versionlocked ... then # remove all traces of that too. for (pkgtup, instTup) in conduit._base.up.getObsoletesTuples(): if instTup[0] not in _version_lock_excluder_n: continue _version_lock_excluder_n.add(pkgtup[0].lower()) total = len(_get_updates(conduit._base)) if show_hint else 0 if total: if total > 1: suffix = 's' what = 'them' else: suffix = '' what = 'it' conduit.info(2, 'Excluding %d update%s due to versionlock ' '(use "yum versionlock status" to show %s)' % (total, suffix, what)) if _version_lock_excluder_n: _add_versionlock_whitelist(conduit) if _version_lock_excluder_B_nevr: _add_versionlock_blacklist(conduit)
def _run_dir(dir, conduit, args=''): dir.rstrip('*') dir.rstrip('/') if not os.path.isdir(dir): return None # TODO/YAGNI?: if yum called w/ --quiet: hide output from system() && do not call conduit.info() # TODO/YAGNI?: if yum called w/ --verbose also output pre/post "running $cmd" region markers # TODO: under dry run do nto run scripts just note that they would have been for script in sorted(glob.glob(dir + "/*")): if (os.access(script, os.X_OK)): if (len(args)): exit = os.system(script + ' ' + args) if (exit != 0): if (exit == 65280): raise PluginYumExit("!!!! \"" + script + ' ' + args + "\" said it was time to stop") else: conduit.info( 2, "!!!! \"" + script + ' ' + args + "\" did not exit cleanly: " + str(exit)) else: exit = os.system(script) if (exit != 0): if (exit == 65280): raise PluginYumExit("!!!! " + script + " said it was time to stop") else: conduit.info( 2, "!!!! " + script + " did not exit cleanly: " + str(exit)) else: conduit.info(2, "!!!! " + script + ' is not executable')
def pretrans_hook(conduit): ts = conduit.getTsInfo() packages = [] for attr in ('updated', 'installed', 'depinstalled', 'depupdated', 'reinstalled', 'downgraded'): packages += getattr(ts, attr, []) prompt = [] for p in packages: for file in p.po.returnHeaderFromPackage().fiFromHeader(): (file, size, mode, mtime, flags, dev, inode, link, state, vflags, user, group, csum) = file if file in puppet_files and not flags & rpm.RPMFILE_NOREPLACE: prompt.append("Installing %s overwrites puppet-managed file %s" % (str(p.po), file)) if prompt: if not conduit.promptYN('\n'.join(prompt)): raise PluginYumExit('Aborting')
def postresolve_hook(conduit): global puppet_packages ts = conduit.getTsInfo() opts, args = conduit.getCmdLine() exit = False for pkgs in ts.pkgdict.values(): for pkg in pkgs: if pkg.ts_state == 'e' and nvra_match(pkg, puppet_packages)[0] not in (ABSENT, False): abort = True for pkgs2 in ts.pkgdict.values(): for pkg2 in pkgs2: if pkg.name == pkg2.name and pkg2.ts_state != 'e': # This is a downgrade abort = False break if abort and pkg.name not in (opts.allow_removal or []): conduit.info(2, "Cannot delete package %s, it's required by puppet" % pkg.name) exit = True if exit: raise PluginYumExit('')
def predownload_hook(conduit): packages = [p for p in conduit.getDownloadPackages() if p.name == 'vdsm'] if not packages: return if os.path.exists('/etc/vdsm/allow-live-upgrades'): return rpmdb = conduit.getRpmDB() try: if not rpmdb.searchNames(['vdsm']): return except PackageSackError: return for proc in os.listdir('/proc'): if proc.isdigit(): try: exe = os.readlink(os.path.join('/proc', proc, 'exe')) except OSError: continue if exe == '/usr/libexec/qemu-kvm': raise PluginYumExit('Running QEMU processes found, ' 'cannot upgrade Vdsm.')
def exclude_hook(conduit): conduit.info(3, 'Reading version lock configuration') if not fileurl: raise PluginYumExit('Locklist not set') for ent in _read_locklist(): neg = False if ent and ent[0] == '!': ent = ent[1:] neg = True (n, v, r, e, a) = splitFilename(ent) n = n.lower() v = v.lower() r = r.lower() e = e.lower() if e == '': e = '0' if neg: _version_lock_excluder_B_nevr.add("%s-%s:%s-%s" % (n, e, v, r)) continue _version_lock_excluder_n.add(n) _version_lock_excluder_nevr.add("%s-%s:%s-%s" % (n, e, v, r)) if (_version_lock_excluder_n and conduit.confBool('main', 'follow_obsoletes', default=False)): # If anything obsoletes something that we have versionlocked ... then # remove all traces of that too. for (pkgtup, instTup) in conduit._base.up.getObsoletesTuples(): if instTup[0] not in _version_lock_excluder_n: continue _version_lock_excluder_n.add(pkgtup[0].lower()) if _version_lock_excluder_n: _add_versionlock_whitelist(conduit) if _version_lock_excluder_B_nevr: _add_versionlock_blacklist(conduit)
def postreposetup_hook(conduit): raise PluginYumExit('Goodbye')
def _fail(msg): raise PluginYumExit(msg)
def postdownload_hook(conduit): conduit.info(3, conduit); conduit.info(3, '* *6* *'); # list of http://yum.baseurl.org/api/yum-3.2.27/yum.sqlitesack.YumAvailablePackageSqlite-class.html lorig = conduit.getDownloadPackages(); if not os.path.exists(path): os.makedirs(path) for s in lorig: #if package is subpackage, this is his parent. We will use it for matching basePackageName = s.base_package_name basePackageEpoch = getEpoch(s.envra)[0] #aprox, noarch needs special handling basePackageAproxArch = getArch(s.envra)[1] basePackageENVRA=basePackageEpoch+":"+basePackageName+"-"+getEpoch(s.printVer())[1]+"."+basePackageAproxArch #name = s.ui_envra #include epoch always if enabled name = s.envra #noarch subpackages may unpack to more then one arches of parent-package names = [] # epoch is included in regex anyway if pattern3.match(name): conduit.info(2, '***************************************************************'); group = False conduit.info(3, ID_PRFIX+name + ' matching ' + resrc3) if name == basePackageENVRA: conduit.info(2, ID_PRFIX+name+" is main package itself"); conduit.info(2, ID_PRFIX+"NOT grouping"); else: conduit.info(2, ID_PRFIX+name+" is subpackage of " + getArch(basePackageENVRA)[0]); if groupSubpackages.match(basePackageENVRA): conduit.info(2, ID_PRFIX+"Grouping! "+basePackageENVRA + ' matched ' + groupSubpackagesSrc); group = True else: conduit.info(2, ID_PRFIX+"NOT grouping "+basePackageENVRA + ' not matched ' + groupSubpackagesSrc); conduit.info(2, ID_PRFIX+"Proecessing:" + s.localPkg()); if group and basePackageAproxArch != "noarch": name=basePackageENVRA if group and basePackageAproxArch == "noarch": if isParentInTransactionArch(lorig, basePackageENVRA): conduit.info(2, ID_PRFIX+"Although this package is subpackage and is noarch, its parent seems to be noarch too, continue in grouping"); name=basePackageENVRA else: conduit.info(2, ID_PRFIX+"This package is subpackage and should be grupped. However is noarch and its parrent is not noarch. Trying to find arched parrent in transaction"); if isParentInTransaction(lorig, basePackageENVRA): found = getParentInTransaction(lorig, basePackageENVRA) conduit.info(3, ID_PRFIX+"Found: "+str(found)); names = [] for n in found: names.append(n.envra); if not names: names=[name] for lname in names: if trimEpoch: lname = getEpoch(lname)[1] xcwd=path+"/"+lname if not os.path.exists(xcwd): os.makedirs(xcwd) else: if (group): conduit.info(2, ID_PRFIX+'info(g) ' + lname + " already unpacked in " + path); else: conduit.info(2, ID_PRFIX+'WARNING ' + lname + " already unpacked in " + path); if debuglevel < 3: FNULL = open(os.devnull, 'w') else: FNULL=PIPE p1 = Popen(["rpm2cpio", s.localPkg()], stdout=PIPE, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=xcwd) p2 = Popen(["cpio", "-idmv"], stdin=p1.stdout, stdout=FNULL, stderr=FNULL, preexec_fn=None, close_fds=False, shell=False, cwd=xcwd) p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. output = p2.communicate()[0] conduit.info(2, ID_PRFIX+'Finished ' + s.envra + " to " + xcwd); else: conduit.info(2, ID_PRFIX+name + ' NOT matching ' + resrc3) if exitAfterUnpack: raise PluginYumExit(ID_PRFIX+'unpack plugin terminated YUM execution here. Done. Check ' + path + " for results.")
def doCheck(self, base, basecmd, extcmds): if recursive: # shouldn't happen raise PluginYumExit('And error has occurred for %s, please create a bug report') raise PluginYumExit('%s is an alias not a command, however recursive processing is turned off')
def exclude_hook(conduit): conduit.info(3, 'Reading pattern version lock configuration') if not fileurl: raise PluginYumExit('Patternlocklist not set') pkgs = {} patternlist = [] patternlistnegate = [] for ent in _read_patternlocklist(): if ent and ent[0] == '!': patternlistnegate.append(ent[1:]) continue patternlist.append(ent) if len(patternlist) == 0 and len(patternlistnegate) == 0: return 0 conduit.info(3, 'Applying pattern version lock configuration') if len(patternlistnegate) > 0: pkglistnegate = set() if verbosemode: print "Excluding the following(s) pattern(s)" for pattern in patternlistnegate: print " - " + pattern pkgs = conduit._base.pkgSack.returnPackages(patterns=patternlistnegate) for pkg in pkgs: # We ignore arch, so only add one entry for foo-1.i386 and # foo-1.x86_64. (n, a, e, v, r) = pkg.pkgtup a = '*' if (n, a, e, v, r) in pkglistnegate: continue pkglistnegate.add((n, a, e, v, r)) _pattern_vlock_excluder_B_nevr.add("%s-%s:%s-%s" % (n, e, v, r)) if len(patternlist) > 0: pkglist = set() if verbosemode: print "Incluing the following(s) pattern(s)" for pattern in patternlist: print " - " + pattern pkgs = conduit._base.pkgSack.returnPackages(patterns=patternlist) for pkg in pkgs: # We ignore arch, so only add one entry for foo-1.i386 and # foo-1.x86_64. (n, a, e, v, r) = pkg.pkgtup a = '*' if (n, a, e, v, r) in pkglist: continue _pattern_vlock_excluder_n.add(n) _pattern_vlock_excluder_nevr.add("%s-%s:%s-%s" % (n, e, v, r)) if (_pattern_vlock_excluder_n and conduit.confBool('main', 'follow_obsoletes', default=False)): # If anything obsoletes something that we have patternvlocked ... then # remove all traces of that too. for (pkgtup, instTup) in conduit._base.up.getObsoletesTuples(): if instTup[0] not in _pattern_vlock_excluder_n: continue _pattern_vlock_excluder_n.add(pkgtup[0].lower()) if _pattern_vlock_excluder_n: _add_patternvlock_whitelist(conduit) if _pattern_vlock_excluder_B_nevr: _add_patternvlock_blacklist(conduit)
def args_hook(conduit): args = conduit.getArgs() user = os.environ["USER"] if "SUDO_USER" in os.environ: user = os.environ["SUDO_USER"] cmd = None filter_args = [] host_list = [] # yum -a -b --host=h1 install yyy yyy --host=h2 -c -d for arg in args: if cmd == None and arg[0] != "-": cmd = arg # if cmd is 'ssh', clear the args before 'ssh' and continue if cmd == "ssh": filter_args = [] continue if arg[0:7] == "--host=": host_list.append(arg[7:]) elif arg[0:12] == "--host-file=": file = arg[12:] try: host_list.extend([line.strip() for line in open(file, "r")]) except: print "File '%s' not exists!" % (file) sys.exit() elif arg[0:7] == "--user="******" ".join(filter_args) if cmd != "ssh": remote_cmd = "sudo /usr/bin/yum " + remote_cmd for host in host_list: sts = ssh_command(conduit, user, host, remote_cmd) if sts == 0: succ_list.append(host) else: fail_list.append(host) if cmd != "ssh": print_summary(conduit, host_list, succ_list, fail_list) raise PluginYumExit('Goodbye!') elif cmd == "ssh": raise PluginYumExit("You must specific --host option")