def yum_groupinstall(packages, excludelist = [], roles = " ".join([item.lower() for item in get_roles()])): print '@Installing packages with groupinstall' regex1 = re.compile('^Error: .+ conflicts with ') excludes = ' '.join(["--exclude=%s" % exclude for exclude in excludelist]) (stdin, output) = os.popen4("/usr/bin/yum %s groupinstall %s" % (excludes, roles)) for line in output.readlines(): print line.strip() ## TODO: remove if line.startswith('Error: ') or line.endswith(' is not signed') or regex1.match(line) != None: raise Exception return def yum_chunkinstall(packages, excludelist = [], chunksize = 15): print '@Installing packages chunkwise' excludes = ' '.join(["--exclude=%s" % exclude for exclude in excludelist]) regex1 = re.compile('^Error: .+ conflicts with ') total = len(packages)/chunksize for chunk in range(len(packages)/chunksize): chunkstart = chunksize * chunk chunkend = chunkstart + chunksize print "@Installing piece %s of %s" % (chunk + 1, total) piece = ' '.join(packages[chunkstart:chunkend]) print piece messages = [] blocks = [] (stdin, output) = os.popen4("/usr/bin/yum -y %s install %s" % (excludes, piece)) for line in output.readlines(): print "@%s" % line.strip() messages.append(line.strip()) if line.startswith('Error: ') or line.endswith(' is not signed') or regex1.match(line) != None: print '@Chunkwise install failed' # try: ## TODO: reinstate try block print "@@A %s" % blocks ## diagnostic newblocks = yum_pruneinstall(packages[chunkstart:chunkend], excludelist, messages) print "@@C %s" % newblocks ## diagnostic blocks.extend(newblocks) print "@@D" ## diagnostic blocks = list(set(blocks)) print "@@E" ## diagnostic excludelist.extend(blocks) print "@@F" ## diagnostic excludelist = list(set(excludelist)) print "@@G" ## diagnostic # except: # print "@Install failed for packages: %s" % piece # blocks.extend(packages[chunkstart:chunkend]) update_log() return blocks def yum_pruneinstall(packages, blocks = [], messages = [], iteration = 0, maxiterations = 16): print "@Pruning blocks (try %s of %s)" % (iteration, maxiterations) regex1 = re.compile('^Error: .+ conflicts with ') errored = False piece = ' '.join(packages) print piece for line in messages: if line.startswith('Error: Missing Dependency: '): # Missing dependencies blocks.append(line.split()[-1]) errored = True elif line.endswith(' is not signed'): # Unsigned packages blocks.append(line.split('.', 1)[0].split('-', 1)[-1].split()[1]) errored = True elif regex1.match(line) != None: # Conflicting packages blocks.append(line.split()[1]) errored = True if not errored: update_log() print "@Piece succeeded!" ## TODO: remove print "@@B %s" % blocks ## diagnostic return blocks else: if iteration == maxiterations: print '@Giving up' ## TODO: remove raise Exception # Remove duplicates blocks = list(set(blocks)) print "#Blocks: %s" % blocks ## TODO: remove # Run yum again and restart excludes = ' '.join(['--exclude=%s' % block for block in blocks]) messages = [] (stdin, output) = os.popen4("/usr/bin/yum -y %s install %s" % (excludes, piece)) for line in output.readlines(): messages.append(line.strip()) print "@%s" % line.strip() ## TODO: remove yum_pruneinstall(packages, blocks, messages, iteration + 1)