Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 147516 | Differences between
and this patch

Collapse All | Expand All

(-)portage-2.1.1.orig/bin/emerge (-200 / +454 lines)
Lines 642-647 Link Here
642
		self.myopts = myopts
642
		self.myopts = myopts
643
		self.myparams = myparams
643
		self.myparams = myparams
644
		self.edebug = 0
644
		self.edebug = 0
645
		self.merge_slot = {}
645
		if settings.get("PORTAGE_DEBUG", "") == "1":
646
		if settings.get("PORTAGE_DEBUG", "") == "1":
646
			self.edebug = 1
647
			self.edebug = 1
647
		self.spinner = spinner
648
		self.spinner = spinner
Lines 693-703 Link Here
693
		"""
694
		"""
694
695
695
		jbigkey = " ".join(mybigkey) + " merge"
696
		jbigkey = " ".join(mybigkey) + " merge"
697
		if "--debug" in self.myopts:
698
			print "\ncreate:mybigkey is ",mybigkey,", myparent is ", myparent, ", jbigkey is ",jbigkey
699
700
		# if I have no parent, initialize the merge slot to zero and let the deps update it
701
		if not myparent and not mybigkey[2] in self.merge_slot.keys():
702
			self.merge_slot[mybigkey[2]] = 0
703
696
		if self.digraph.hasnode(jbigkey):
704
		if self.digraph.hasnode(jbigkey):
697
			if addme and jbigkey != myparent:
705
			if addme and jbigkey != myparent:
698
				# Refuse to make a node depend on itself so that the we don't
706
				# Refuse to make a node depend on itself so that the we don't
699
				# don't create a bogus circular dependency in self.altlist().
707
				# don't create a bogus circular dependency in self.altlist().
700
				self.digraph.addnode(jbigkey, myparent)
708
				self.digraph.addnode(jbigkey, myparent)
709
			try:
710
				if myparent and self.merge_slot[myparent.split()[2]] < self.merge_slot[jbigkey.split()[2]] + 1:
711
					self.merge_slot[myparent.split()[2]] = self.merge_slot[jbigkey.split()[2]] + 1
712
			except KeyError,e:
713
				if "--debug" in self.myopts:
714
					print "create:Error on key ",str(e)
715
				# Because the node is already present in the digraph, it is myparent key
716
				# which is not present and hence needs to be initialized
717
				self.merge_slot[myparent.split()[2]] = self.merge_slot[jbigkey.split()[2]] + 1
718
701
			return 1
719
			return 1
702
		jbigkey = " ".join(mybigkey) + " nomerge"
720
		jbigkey = " ".join(mybigkey) + " nomerge"
703
		if self.digraph.hasnode(jbigkey):
721
		if self.digraph.hasnode(jbigkey):
Lines 854-859 Link Here
854
			portage.writemsg("!!! Please notify the package maintainer " + \
872
			portage.writemsg("!!! Please notify the package maintainer " + \
855
				"that atoms must be fully-qualified.\n", noiselevel=-1)
873
				"that atoms must be fully-qualified.\n", noiselevel=-1)
856
			return 0
874
			return 0
875
857
		return 1
876
		return 1
858
877
859
	def select_files(self,myfiles):
878
	def select_files(self,myfiles):
Lines 1022-1027 Link Here
1022
				use_binaries=("--usepkgonly" in self.myopts),
1041
				use_binaries=("--usepkgonly" in self.myopts),
1023
				myroot=myroot, trees=self.trees)
1042
				myroot=myroot, trees=self.trees)
1024
1043
1044
			if "--debug" in self.myopts:
1045
				print "\nselect_dep:mycheck is ",mycheck
1046
1025
			if not mycheck[0]:
1047
			if not mycheck[0]:
1026
				mymerge=[]
1048
				mymerge=[]
1027
			else:
1049
			else:
Lines 1049-1055 Link Here
1049
				# determine satisfied deps via dep_wordreduce but it does not
1071
				# determine satisfied deps via dep_wordreduce but it does not
1050
				# account for merge order (merge order is later calculated
1072
				# account for merge order (merge order is later calculated
1051
				# in self.altlist() using data from the digraph).
1073
				# in self.altlist() using data from the digraph).
1052
				self.mydbapi[p_root].cpv_inject(p_key)
1074
				#
1075
				# I took it out because this interferes with slot calculations.
1076
				# The same effect can be achieved with just checking if the package
1077
				# is already in the digraph.
1078
1079
				# self.mydbapi[p_root].cpv_inject(p_key)
1053
1080
1054
				# Update old-style virtuals if this package provides any.
1081
				# Update old-style virtuals if this package provides any.
1055
				# These are needed for dep_virtual calls inside dep_check.
1082
				# These are needed for dep_virtual calls inside dep_check.
Lines 1057-1062 Link Here
1057
					self.trees[p_root][self.pkg_tree_map[p_type]].dbapi)
1084
					self.trees[p_root][self.pkg_tree_map[p_type]].dbapi)
1058
1085
1059
		if not mymerge:
1086
		if not mymerge:
1087
			# If portage_dep tells me I have all my deps checked out, I am good to go.
1088
			if myparent:
1089
				self.merge_slot[myparent.split()[2]] = 0
1060
			return 1
1090
			return 1
1061
1091
1062
		if "--debug" in self.myopts:
1092
		if "--debug" in self.myopts:
Lines 1176-1186 Link Here
1176
				# ordered by type preference ("ebuild" type is the last resort)
1206
				# ordered by type preference ("ebuild" type is the last resort)
1177
				selected_pkg =  matched_packages[0]
1207
				selected_pkg =  matched_packages[0]
1178
1208
1179
			if myparent:
1209
			# initialize slot for selected_pkg[2] if not already initialized
1210
			if not selected_pkg[2] in self.merge_slot.keys():
1211
				self.merge_slot[selected_pkg[2]] = 0
1212
1213
			# if the package exists in the digraph, go on to the next one
1214
			selected_pkg_key = " ".join(selected_pkg[0:3]) + " merge"
1215
			if self.digraph.hasnode(selected_pkg_key):
1216
				if "--debug" in self.myopts:
1217
					print "select_dep: digraph has the pkg ",selected_pkg
1218
				if myparent:
1219
					try:
1220
						if self.merge_slot[myparent.split()[2]] < self.merge_slot[selected_pkg[2]] + 1:
1221
							self.merge_slot[myparent.split()[2]] = self.merge_slot[selected_pkg[2]] + 1
1222
					except KeyError:
1223
						# Because selected_pkg[2] already has a slot,
1224
						# it must be myparent.split()[2] that's not there
1225
						self.merge_slot[myparent.split()[2]] = self.merge_slot[selected_pkg[2]] + 1
1226
			elif myparent:
1180
				#we are a dependency, so we want to be unconditionally added
1227
				#we are a dependency, so we want to be unconditionally added
1181
				if not self.create(selected_pkg[0:3], myparent,
1228
				if not self.create(selected_pkg[0:3], myparent,
1182
					myuse=selected_pkg[-1]):
1229
					myuse=selected_pkg[-1]):
1183
					return 0
1230
					return 0
1231
				try:
1232
					# merge slot for a package is 1 more than the max of the slot of each of its deps
1233
					if x[0]!="!" and self.merge_slot[myparent.split()[2]] < self.merge_slot[selected_pkg[2]] + 1:
1234
						self.merge_slot[myparent.split()[2]] = self.merge_slot[selected_pkg[2]] + 1
1235
				except KeyError,e:
1236
					if "--debug" in self.myopts:
1237
						print "select_dep:Key error on ",str(e)+" selected_pkg ",selected_pkg
1238
					# Because selected_pkg[2] already has a slot,
1239
					# it must be myparent.split()[2] that's not there
1240
					self.merge_slot[myparent.split()[2]] = self.merge_slot[selected_pkg[2]] + 1
1184
			else:
1241
			else:
1185
				#if mysource is not set, then we are a command-line dependency and should not be added
1242
				#if mysource is not set, then we are a command-line dependency and should not be added
1186
				#if --onlydeps is specified.
1243
				#if --onlydeps is specified.
Lines 1219-1226 Link Here
1219
			#	if not portage.db["/"]["vartree"].exists_specific(splitski[2]):
1276
			#	if not portage.db["/"]["vartree"].exists_specific(splitski[2]):
1220
			#		portage.db["/"]["merge"].append(splitski)
1277
			#		portage.db["/"]["merge"].append(splitski)
1221
			#else:
1278
			#else:
1279
1280
			# append the merge slot
1281
			if len(splitski) == 4:
1282
				splitski.append(str(self.merge_slot[splitski[2]]))
1222
			self.trees[splitski[1]]["merge"].append(splitski)
1283
			self.trees[splitski[1]]["merge"].append(splitski)
1223
			mygraph.delnode(mycurkey)
1284
			mygraph.delnode(mycurkey)
1285
1224
		for x in dolist:
1286
		for x in dolist:
1225
			for y in self.trees[x]["merge"]:
1287
			for y in self.trees[x]["merge"]:
1226
				retlist.append(y)
1288
				retlist.append(y)
Lines 1394-1407 Link Here
1394
1456
1395
		i = 0
1457
		i = 0
1396
		while i < len(mylist):
1458
		while i < len(mylist):
1397
			if mylist[i][-1]=="nomerge":
1459
			if mylist[i][-2]=="nomerge":
1398
				if "--tree" not in self.myopts:
1460
				if "--tree" not in self.myopts:
1399
					# we don't care about this elements
1461
					# we don't care about this elements
1400
					mylist.pop(i)
1462
					mylist.pop(i)
1401
					continue
1463
					continue
1402
				if (i == (len(mylist) - 1)) \
1464
				if (i == (len(mylist) - 1)) \
1403
				   or (mygraph.depth(string.join(mylist[i])) \
1465
				   or (mygraph.depth(string.join(mylist[i][:4])) \
1404
				       >= mygraph.depth(string.join(mylist[i+1]))):
1466
				       >= mygraph.depth(string.join(mylist[i+1][:4]))):
1405
					# end of a useless branch (may be the last one)
1467
					# end of a useless branch (may be the last one)
1406
					# -> delete the element and test the previous one
1468
					# -> delete the element and test the previous one
1407
					mylist.pop(i)
1469
					mylist.pop(i)
Lines 1585-1591 Link Here
1585
				if verbosity == 3:
1647
				if verbosity == 3:
1586
					# size verbose
1648
					# size verbose
1587
					mysize=0
1649
					mysize=0
1588
					if x[0] == "ebuild" and x[-1]!="nomerge":
1650
					if x[0] == "ebuild" and x[-2]!="nomerge":
1589
						myfilesdict = portdb.getfetchsizes(
1651
						myfilesdict = portdb.getfetchsizes(
1590
							pkg_key, useflags=self.useFlags[myroot][pkg_key],
1652
							pkg_key, useflags=self.useFlags[myroot][pkg_key],
1591
							debug=self.edebug)
1653
							debug=self.edebug)
Lines 1633-1639 Link Here
1633
1695
1634
				indent=""
1696
				indent=""
1635
				if "--tree" in self.myopts:
1697
				if "--tree" in self.myopts:
1636
					indent=" "*mygraph.depth(string.join(x))
1698
					indent=" "*mygraph.depth(string.join(x[:4]))
1637
1699
1638
				if myoldbest:
1700
				if myoldbest:
1639
					myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
1701
					myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
Lines 1791-1922 Link Here
1791
			self.pkgsettings["/"] = \
1853
			self.pkgsettings["/"] = \
1792
				portage.config(clone=trees["/"]["vartree"].settings)
1854
				portage.config(clone=trees["/"]["vartree"].settings)
1793
1855
1794
	def merge(self, mylist, favorites, mtimedb):
1856
	def restart_portage(self, x, mergecount, totalcount, mtimedb):
1795
		returnme=0
1796
		mymergelist=[]
1797
		ldpath_mtimes = mtimedb["ldpath"]
1798
		xterm_titles = "notitles" not in self.settings.features
1857
		xterm_titles = "notitles" not in self.settings.features
1799
1858
		# don't really restart if any of these is true
1800
		#check for blocking dependencies
1859
		# XXXXX - seems like redundant check, but what the hell! sky is not falling as yet.
1801
		if "--fetchonly" not in self.myopts and \
1860
		if "--pretend" in self.myopts or "--fetchonly" in self.myopts or \
1802
			"--buildpkgonly" not in self.myopts:
1861
			"--fetch-all-uri" in self.myopts or "--buildpkgonly" in self.myopts:
1803
			for x in mylist:
1862
			return
1804
				if x[0]=="blocks":
1863
1805
					print "\n!!! Error: the "+x[2]+" package conflicts with another package;"
1864
		mysplit=portage.pkgsplit(x[2])
1806
					print   "!!!        the two packages cannot be installed on the same system together."
1865
		myver=mysplit[1]+"-"+mysplit[2]
1807
					print   "!!!        Please use 'emerge --pretend' to determine blockers."
1866
		if myver[-3:]=='-r0':
1808
					if "--quiet" not in self.myopts:
1867
			myver=myver[:-3]
1809
						show_blocker_docs_link()
1868
		if (myver != portage.VERSION) and \
1810
					if "--pretend" not in self.myopts:
1869
		   "livecvsportage" not in self.settings.features:
1811
						try:
1870
			if totalcount > mergecount:
1812
							del mtimedb["resume"]
1871
				emergelog(xterm_titles,
1813
						except KeyError:
1872
					" ::: completed emerge ("+ \
1814
							pass
1873
					str(mergecount)+" of "+ \
1815
						sys.exit(1)
1874
					str(totalcount)+") "+ \
1816
1875
					x[2]+" to "+x[1])
1817
		#buildsyspkg: I need mysysdict also on resume (moved from the else block)
1876
				emergelog(xterm_titles, " *** RESTARTING " + \
1818
		mysysdict = genericdict(getlist(self.settings, "system"))
1877
					"emerge via exec() after change of " + \
1819
		if "--resume" in self.myopts:
1878
					"portage version.")
1820
			# We're resuming.
1879
				portage.run_exitfuncs()
1821
			print colorize("GOOD", "*** Resuming merge...")
1880
				mynewargv=[sys.argv[0],"--resume"]
1822
			emergelog(xterm_titles, " *** Resuming merge...")
1881
				badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume")
1823
			mymergelist=mtimedb["resume"]["mergelist"][:]
1882
				for arg in self.myopts:
1824
			if "--skipfirst" in self.myopts and mymergelist:
1883
					if arg in badlongopts:
1825
				del mtimedb["resume"]["mergelist"][0]
1826
				del mymergelist[0]
1827
				mtimedb.commit()
1828
			validate_merge_list(self.trees, mymergelist)
1829
		else:
1830
			myfavs = portage.grabfile(
1831
				os.path.join(self.target_root, portage.WORLD_FILE))
1832
			myfavdict=genericdict(myfavs)
1833
			for x in range(len(mylist)):
1834
				if mylist[x][3]!="nomerge":
1835
					# Add to the mergelist
1836
					mymergelist.append(mylist[x])
1837
				else:
1838
					myfavkey=portage.cpv_getkey(mylist[x][2])
1839
					if "--onlydeps" in self.myopts:
1840
						continue
1884
						continue
1841
					# Add to the world file. Since we won't be able to later.
1885
					mynewargv.append(arg)
1842
					if "--fetchonly" not in self.myopts and \
1886
				# priority only needs to be adjusted on the first run
1843
						myfavkey in favorites:
1887
				os.environ["PORTAGE_NICENESS"] = "0"
1844
						#don't record if already in system profile or already recorded
1888
				os.execv(mynewargv[0], mynewargv)
1845
						if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
1846
							#we don't have a favorites entry for this package yet; add one
1847
							myfavdict[myfavkey]=myfavkey
1848
							print ">>> Recording",myfavkey,"in \"world\" favorites file..."
1849
			if not ("--fetchonly" in self.myopts or \
1850
				"--fetch-all-uri" in self.myopts or \
1851
				"--pretend" in self.myopts):
1852
				portage.write_atomic(
1853
					os.path.join(self.target_root, portage.WORLD_FILE),
1854
					"\n".join(myfavdict.values()))
1855
1856
			mtimedb["resume"]["mergelist"]=mymergelist[:]
1857
			mtimedb.commit()
1858
1889
1890
	def fork_one_emerge(self, x, mergecount, totalcount, mtimedb, favorites, mysysdict):
1891
		xterm_titles = "notitles" not in self.settings.features
1859
		myfeat = self.settings.features[:]
1892
		myfeat = self.settings.features[:]
1860
1893
		ldpath_mtimes = mtimedb["ldpath"]
1861
		if "parallel-fetch" in myfeat and \
1894
		pid = os.fork()
1862
			not ("--ask" in self.myopts or \
1895
		if not pid:
1863
			"--pretend" in self.myopts or \
1864
			"--fetch-all-uri" in self.myopts or \
1865
			"--fetchonly" in self.myopts):
1866
			if "distlocks" not in myfeat:
1867
				print red("!!!")
1868
				print red("!!!")+" parallel-fetching requires the distlocks feature enabled"
1869
				print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled"
1870
				print red("!!!")
1871
			elif len(mymergelist) > 1:
1872
				print ">>> starting parallel fetching"
1873
				pid = os.fork()
1874
				if not pid:
1875
					sys.stdin.close()
1876
					sys.stdout.close()
1877
					sys.stderr.close()
1878
					time.sleep(3) # allow the parent to have first fetch
1879
					fetchlog = "/var/log/emerge-fetch.log"
1880
					sys.stdout = open(fetchlog, "w")
1881
					sys.stderr = sys.stdout
1882
					os.dup2(sys.stdout.fileno(), 1)
1883
					os.dup2(sys.stderr.fileno(), 2)
1884
					portage_util.apply_secpass_permissions(fetchlog,
1885
						uid=portage.portage_uid, gid=portage.portage_gid,
1886
						mode=0660)
1887
1888
					for myroot, pkgsettings in self.pkgsettings.iteritems():
1889
						for x in ("autoaddcvs", "cvs"):
1890
							while x in pkgsettings.features:
1891
								pkgsettings.features.remove(x)
1892
						pkgsettings["FEATURES"] = " ".join(pkgsettings.features)
1893
						pkgsettings.backup_changes("FEATURES")
1894
1895
					ret = 0
1896
					for x in mymergelist:
1897
						if x[0] != "ebuild":
1898
							continue
1899
						myroot = x[1]
1900
						portdb = self.trees[myroot]["porttree"].dbapi
1901
						pkgsettings = self.pkgsettings[myroot]
1902
						pkgsettings.reset()
1903
						pkgsettings.setcpv(x[2])
1904
						try:
1905
							ret = portage.doebuild(portdb.findname(x[2]),
1906
								"fetch", myroot, pkgsettings,
1907
								cleanup=0, fetchonly=True,
1908
								mydbapi=portdb,
1909
								tree="porttree")
1910
						except SystemExit:
1911
							raise
1912
						except Exception:
1913
							ret = 1
1914
					sys.exit(0)
1915
				portage.portage_exec.spawned_pids.append(pid)
1916
1917
		mergecount=0
1918
		for x in mymergelist:
1919
			mergecount+=1
1920
			myroot=x[1]
1896
			myroot=x[1]
1921
			pkg_key = x[2]
1897
			pkg_key = x[2]
1922
			pkgindex=2
1898
			pkgindex=2
Lines 1930-1939 Link Here
1930
			if "--pretend" not in self.myopts:
1906
			if "--pretend" not in self.myopts:
1931
				print "\n>>> Emerging (" + \
1907
				print "\n>>> Emerging (" + \
1932
					colorize("MERGE_LIST_PROGRESS", str(mergecount)) + " of " + \
1908
					colorize("MERGE_LIST_PROGRESS", str(mergecount)) + " of " + \
1933
					colorize("MERGE_LIST_PROGRESS", str(len(mymergelist))) + ") " + \
1909
					colorize("MERGE_LIST_PROGRESS", str(totalcount)) + ") " + \
1934
					colorize("GOOD", x[pkgindex]) + " to " + x[1]
1910
					colorize("GOOD", x[pkgindex]) + " to " + x[1]
1935
				emergelog(xterm_titles, " >>> emerge ("+\
1911
				emergelog(xterm_titles, " >>> emerge ("+\
1936
					str(mergecount)+" of "+str(len(mymergelist))+\
1912
					str(mergecount)+" of "+str(totalcount)+\
1937
					") "+x[pkgindex]+" to "+x[1])
1913
					") "+x[pkgindex]+" to "+x[1])
1938
1914
1939
			pkgsettings["EMERGE_FROM"] = x[0]
1915
			pkgsettings["EMERGE_FROM"] = x[0]
Lines 1964-1980 Link Here
1964
						print
1940
						print
1965
						print "!!! Fetch for",y,"failed, continuing..."
1941
						print "!!! Fetch for",y,"failed, continuing..."
1966
						print
1942
						print
1967
						returnme=1
1943
						sys.exit(1)
1968
					continue
1944
					sys.exit(0)
1969
				elif "--buildpkg" in self.myopts or issyspkg:
1945
				elif "--buildpkg" in self.myopts or issyspkg:
1970
					#buildsyspkg: Sounds useful to display something, but I don't know if we should also log it
1946
					#buildsyspkg: Sounds useful to display something, but I don't know if we should also log it
1971
					if issyspkg:
1947
					if issyspkg:
1972
						print ">>> This is a system package, let's pack a rescue tarball."
1948
						print ">>> This is a system package, let's pack a rescue tarball."
1973
						#emergelog(">>> This is a system package, let's pack a rescue tarball.")
1949
						#emergelog(">>> This is a system package, let's pack a rescue tarball.")
1974
					#create pkg, then merge pkg
1950
					#create pkg, then merge pkg
1975
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
1951
					short_msg = "emerge: ("+str(mergecount)+" of "+str(totalcount)+") "+x[pkgindex]+" Clean"
1976
					emergelog(xterm_titles, " === ("+str(mergecount)+\
1952
					emergelog(xterm_titles, " === ("+str(mergecount)+\
1977
						" of "+str(len(mymergelist))+") Cleaning ("+\
1953
						" of "+str(totalcount)+") Cleaning ("+\
1978
						x[pkgindex]+"::"+y+")", short_msg=short_msg)
1954
						x[pkgindex]+"::"+y+")", short_msg=short_msg)
1979
					retval = portage.doebuild(y, "clean", myroot,
1955
					retval = portage.doebuild(y, "clean", myroot,
1980
						pkgsettings, self.edebug, cleanup=1,
1956
						pkgsettings, self.edebug, cleanup=1,
Lines 1985-1993 Link Here
1985
						sys.exit(127)
1961
						sys.exit(127)
1986
					if retval:
1962
					if retval:
1987
						sys.exit(retval)
1963
						sys.exit(retval)
1988
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
1964
					short_msg = "emerge: ("+str(mergecount)+" of "+str(totalcount)+") "+x[pkgindex]+" Compile"
1989
					emergelog(xterm_titles, " === ("+str(mergecount)+\
1965
					emergelog(xterm_titles, " === ("+str(mergecount)+\
1990
						" of "+str(len(mymergelist))+\
1966
						" of "+str(totalcount)+\
1991
						") Compiling/Packaging ("+x[pkgindex]+"::"+y+\
1967
						") Compiling/Packaging ("+x[pkgindex]+"::"+y+\
1992
						")", short_msg=short_msg)
1968
						")", short_msg=short_msg)
1993
					retval = portage.doebuild(y, "package", myroot,
1969
					retval = portage.doebuild(y, "package", myroot,
Lines 2003-2012 Link Here
2003
					if "--buildpkgonly" not in self.myopts:
1979
					if "--buildpkgonly" not in self.myopts:
2004
						self.trees[myroot]["bintree"].inject(pkg_key)
1980
						self.trees[myroot]["bintree"].inject(pkg_key)
2005
						mytbz2 = self.trees[myroot]["bintree"].getname(pkg_key)
1981
						mytbz2 = self.trees[myroot]["bintree"].getname(pkg_key)
2006
						short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge"
1982
						short_msg = "emerge: ("+str(mergecount)+" of "+str(totalcount)+") "+x[pkgindex]+" Merge"
2007
						emergelog(xterm_titles, " === ("+\
1983
						emergelog(xterm_titles, " === ("+\
2008
							str(mergecount)+" of "+\
1984
							str(mergecount)+" of "+\
2009
							str(len(mymergelist))+") Merging ("+\
1985
							str(totalcount)+") Merging ("+\
2010
							x[pkgindex]+"::"+y+")", short_msg=short_msg)
1986
							x[pkgindex]+"::"+y+")", short_msg=short_msg)
2011
1987
2012
						retval = portage.merge(pkgsettings["CATEGORY"],
1988
						retval = portage.merge(pkgsettings["CATEGORY"],
Lines 2023-2031 Link Here
2023
						portage.doebuild(y, "clean", myroot, pkgsettings,
1999
						portage.doebuild(y, "clean", myroot, pkgsettings,
2024
							self.edebug, mydbapi=portdb, tree="porttree")
2000
							self.edebug, mydbapi=portdb, tree="porttree")
2025
				else:
2001
				else:
2026
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
2002
					short_msg = "emerge: ("+str(mergecount)+" of "+str(totalcount)+") "+x[pkgindex]+" Clean"
2027
					emergelog(xterm_titles, " === ("+str(mergecount)+\
2003
					emergelog(xterm_titles, " === ("+str(mergecount)+\
2028
						" of "+str(len(mymergelist))+") Cleaning ("+\
2004
						" of "+str(totalcount)+") Cleaning ("+\
2029
						x[pkgindex]+"::"+y+")", short_msg=short_msg)
2005
						x[pkgindex]+"::"+y+")", short_msg=short_msg)
2030
					retval = portage.doebuild(y, "clean", myroot,
2006
					retval = portage.doebuild(y, "clean", myroot,
2031
						pkgsettings, self.edebug, cleanup=1,
2007
						pkgsettings, self.edebug, cleanup=1,
Lines 2036-2044 Link Here
2036
						sys.exit(127)
2012
						sys.exit(127)
2037
					if retval:
2013
					if retval:
2038
						sys.exit(retval)
2014
						sys.exit(retval)
2039
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
2015
					short_msg = "emerge: ("+str(mergecount)+" of "+str(totalcount)+") "+x[pkgindex]+" Compile"
2040
					emergelog(xterm_titles, " === ("+str(mergecount)+\
2016
					emergelog(xterm_titles, " === ("+str(mergecount)+\
2041
						" of "+str(len(mymergelist))+\
2017
						" of "+str(totalcount)+\
2042
						") Compiling/Merging ("+x[pkgindex]+\
2018
						") Compiling/Merging ("+x[pkgindex]+\
2043
						"::"+y+")", short_msg=short_msg)
2019
						"::"+y+")", short_msg=short_msg)
2044
					retval = portage.doebuild(y, "merge", myroot,
2020
					retval = portage.doebuild(y, "merge", myroot,
Lines 2057-2065 Link Here
2057
				#merge the tbz2
2033
				#merge the tbz2
2058
				mytbz2 = self.trees[myroot]["bintree"].getname(pkg_key)
2034
				mytbz2 = self.trees[myroot]["bintree"].getname(pkg_key)
2059
				if self.trees[myroot]["bintree"].isremote(pkg_key):
2035
				if self.trees[myroot]["bintree"].isremote(pkg_key):
2060
					short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch"
2036
					short_msg = "emerge: ("+str(mergecount)+" of "+str(totalcount)+") "+x[pkgindex]+" Fetch"
2061
					emergelog(xterm_titles, " --- ("+str(mergecount)+\
2037
					emergelog(xterm_titles, " --- ("+str(mergecount)+\
2062
						" of "+str(len(mymergelist))+\
2038
						" of "+str(totalcount)+\
2063
						") Fetching Binary ("+x[pkgindex]+\
2039
						") Fetching Binary ("+x[pkgindex]+\
2064
						"::"+mytbz2+")", short_msg=short_msg)
2040
						"::"+mytbz2+")", short_msg=short_msg)
2065
					if not self.trees[myroot]["bintree"].gettbz2(pkg_key):
2041
					if not self.trees[myroot]["bintree"].gettbz2(pkg_key):
Lines 2067-2082 Link Here
2067
2043
2068
				if "--fetchonly" in self.myopts or \
2044
				if "--fetchonly" in self.myopts or \
2069
					"--fetch-all-uri" in self.myopts:
2045
					"--fetch-all-uri" in self.myopts:
2070
					continue
2046
					sys.exit(0)
2071
2047
2072
				short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
2048
				short_msg = "emerge: ("+str(mergecount)+" of "+str(totalcount)+") "+x[pkgindex]+" Merge Binary"
2073
				emergelog(xterm_titles, " === ("+str(mergecount)+\
2049
				emergelog(xterm_titles, " === ("+str(mergecount)+\
2074
					" of "+str(len(mymergelist))+") Merging Binary ("+\
2050
					" of "+str(totalcount)+") Merging Binary ("+\
2075
					x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
2051
					x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
2052
				logfile = None
2053
				if "PORT_LOGDIR" in self.settings:
2054
					pkg_cat = y.split("/")[0]
2055
					pkg_pf = y.split("/")[1]
2056
					logid_time = time.strftime("%Y%m%d-%H%M%S",
2057
						time.gmtime(os.stat(self.settings["PORTAGE_TMPDIR"]).st_mtime))
2058
					logfile = os.path.join( self.settings["PORT_LOGDIR"], "%s:%s:%s.log" % \
2059
						(pkg_cat, pkg_pf, logid_time))
2060
					del logid_time
2061
2076
				retval = portage.pkgmerge(mytbz2, x[1], pkgsettings,
2062
				retval = portage.pkgmerge(mytbz2, x[1], pkgsettings,
2077
					mydbapi=bindb,
2063
					mydbapi=bindb,
2078
					vartree=self.trees[myroot]["vartree"],
2064
					vartree=self.trees[myroot]["vartree"],
2079
					prev_mtimes=ldpath_mtimes)
2065
					prev_mtimes=ldpath_mtimes, logfile=logfile)
2080
				if retval is None:
2066
				if retval is None:
2081
					sys.exit(1)
2067
					sys.exit(1)
2082
				#need to check for errors
2068
				#need to check for errors
Lines 2095-2101 Link Here
2095
						print ">>> Recording",myfavkey,"in \"world\" favorites file..."
2081
						print ">>> Recording",myfavkey,"in \"world\" favorites file..."
2096
						emergelog(xterm_titles, " === ("+\
2082
						emergelog(xterm_titles, " === ("+\
2097
							str(mergecount)+" of "+\
2083
							str(mergecount)+" of "+\
2098
							str(len(mymergelist))+\
2084
							str(totalcount)+\
2099
							") Updating world file ("+x[pkgindex]+")")
2085
							") Updating world file ("+x[pkgindex]+")")
2100
						portage.write_atomic(
2086
						portage.write_atomic(
2101
						os.path.join(myroot, portage.WORLD_FILE),
2087
						os.path.join(myroot, portage.WORLD_FILE),
Lines 2118-2174 Link Here
2118
							+ " AUTOCLEAN is disabled.  This can cause serious"
2104
							+ " AUTOCLEAN is disabled.  This can cause serious"
2119
							+ " problems due to overlapping packages.\n")
2105
							+ " problems due to overlapping packages.\n")
2120
2106
2121
					# Figure out if we need a restart.
2122
					mysplit=portage.pkgsplit(x[2])
2123
					if mysplit[0] == "sys-apps/portage" and x[1] == "/":
2124
						myver=mysplit[1]+"-"+mysplit[2]
2125
						if myver[-3:]=='-r0':
2126
							myver=myver[:-3]
2127
						if (myver != portage.VERSION) and \
2128
						   "livecvsportage" not in self.settings.features:
2129
							if len(mymergelist) > mergecount:
2130
								emergelog(xterm_titles,
2131
									" ::: completed emerge ("+ \
2132
									str(mergecount)+" of "+ \
2133
									str(len(mymergelist))+") "+ \
2134
									x[2]+" to "+x[1])
2135
								emergelog(xterm_titles, " *** RESTARTING " + \
2136
									"emerge via exec() after change of " + \
2137
									"portage version.")
2138
								del mtimedb["resume"]["mergelist"][0]
2139
								mtimedb.commit()
2140
								portage.run_exitfuncs()
2141
								mynewargv=[sys.argv[0],"--resume"]
2142
								badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume")
2143
								for arg in self.myopts:
2144
									if arg in badlongopts:
2145
										continue
2146
									mynewargv.append(arg)
2147
								# priority only needs to be adjusted on the first run
2148
								os.environ["PORTAGE_NICENESS"] = "0"
2149
								os.execv(mynewargv[0], mynewargv)
2150
2151
			if "--pretend" not in self.myopts and \
2107
			if "--pretend" not in self.myopts and \
2152
				"--fetchonly" not in self.myopts and \
2108
				"--fetchonly" not in self.myopts and \
2153
				"--fetch-all-uri" not in self.myopts:
2109
				"--fetch-all-uri" not in self.myopts:
2154
				if "noclean" not in self.settings.features:
2110
				if "noclean" not in self.settings.features:
2155
					short_msg = "emerge: (%s of %s) %s Clean Post" % \
2111
					short_msg = "emerge: (%s of %s) %s Clean Post" % \
2156
						(mergecount, len(mymergelist), x[pkgindex])
2112
						(mergecount, totalcount, x[pkgindex])
2157
					emergelog(xterm_titles, (" === (%s of %s) " + \
2113
					emergelog(xterm_titles, (" === (%s of %s) " + \
2158
						"Post-Build Cleaning (%s::%s)") % \
2114
						"Post-Build Cleaning (%s::%s)") % \
2159
						(mergecount, len(mymergelist), x[pkgindex], y),
2115
						(mergecount, totalcount, x[pkgindex], y),
2160
						short_msg=short_msg)
2116
						short_msg=short_msg)
2161
				emergelog(xterm_titles, " ::: completed emerge ("+\
2117
				emergelog(xterm_titles, " ::: completed emerge ("+\
2162
					str(mergecount)+" of "+str(len(mymergelist))+") "+\
2118
					str(mergecount)+" of "+str(totalcount)+") "+\
2163
					x[2]+" to "+x[1])
2119
					x[2]+" to "+x[1])
2164
2120
2165
			# Unsafe for parallel merges
2121
			sys.exit(0)
2166
			del mtimedb["resume"]["mergelist"][0]
2122
2167
			# Commit after each merge so that --resume may still work in
2123
		return pid
2168
			# in the event that portage is not allowed to exit normally
2124
2169
			# due to power failure, SIGKILL, etc...
2125
2126
	def merge(self, mylist, favorites, mtimedb):
2127
		returnme=0
2128
		mymergelist=[]
2129
		ldpath_mtimes = mtimedb["ldpath"]
2130
		xterm_titles = "notitles" not in self.settings.features
2131
		parallel = "parallel" in self.settings.features
2132
2133
		# parallel merge will be painful to watch with debug or fetchonly. So, you get only one of these...:-)
2134
		if self.edebug or "--fetchonly" in self.myopts:
2135
			parallel = False
2136
2137
		#check for blocking dependencies
2138
		if "--fetchonly" not in self.myopts and \
2139
			"--buildpkgonly" not in self.myopts:
2140
			for x in mylist:
2141
				if x[0]=="blocks":
2142
					print "\n!!! Error: the "+x[2]+" package conflicts with another package;"
2143
					print   "!!!        the two packages cannot be installed on the same system together."
2144
					print   "!!!        Please use 'emerge --pretend' to determine blockers."
2145
					if "--quiet" not in self.myopts:
2146
						show_blocker_docs_link()
2147
					if "--pretend" not in self.myopts:
2148
						try:
2149
							del mtimedb["resume"]
2150
						except KeyError:
2151
							pass
2152
						sys.exit(1)
2153
2154
		#buildsyspkg: I need mysysdict also on resume (moved from the else block)
2155
		mysysdict = genericdict(getlist(self.settings, "system"))
2156
		if "--resume" in self.myopts:
2157
			# We're resuming.
2158
			print colorize("GOOD", "*** Resuming merge...")
2159
			emergelog(xterm_titles, " *** Resuming merge...")
2160
			mymergelist=mtimedb["resume"]["mergelist"][:]
2161
			if "--skipfirst" in self.myopts and mymergelist:
2162
				del mtimedb["resume"]["mergelist"][0]
2163
				del mymergelist[0]
2164
				mtimedb.commit()
2165
			validate_merge_list(self.trees, mymergelist)
2166
		else:
2167
			myfavs = portage.grabfile(
2168
				os.path.join(self.target_root, portage.WORLD_FILE))
2169
			myfavdict=genericdict(myfavs)
2170
			for x in range(len(mylist)):
2171
				if mylist[x][3]!="nomerge":
2172
					# Add to the mergelist
2173
					mymergelist.append(mylist[x])
2174
				else:
2175
					myfavkey=portage.cpv_getkey(mylist[x][2])
2176
					if "--onlydeps" in self.myopts:
2177
						continue
2178
					# Add to the world file. Since we won't be able to later.
2179
					if "--fetchonly" not in self.myopts and \
2180
						myfavkey in favorites:
2181
						#don't record if already in system profile or already recorded
2182
						if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
2183
							#we don't have a favorites entry for this package yet; add one
2184
							myfavdict[myfavkey]=myfavkey
2185
							print ">>> Recording",myfavkey,"in \"world\" favorites file..."
2186
			if not ("--fetchonly" in self.myopts or \
2187
				"--fetch-all-uri" in self.myopts or \
2188
				"--pretend" in self.myopts):
2189
				portage.write_atomic(
2190
					os.path.join(self.target_root, portage.WORLD_FILE),
2191
					"\n".join(myfavdict.values()))
2192
2193
			mtimedb["resume"]["mergelist"]=mymergelist[:]
2170
			mtimedb.commit()
2194
			mtimedb.commit()
2171
2195
2196
		myfeat = self.settings.features[:]
2197
		m_slots = mergelist_to_merge_slot(mymergelist)
2198
2199
		if "parallel-fetch" in myfeat and \
2200
			not ("--ask" in self.myopts or \
2201
			"--pretend" in self.myopts or \
2202
			"--fetch-all-uri" in self.myopts or \
2203
			"--fetchonly" in self.myopts):
2204
			if "distlocks" not in myfeat:
2205
				print red("!!!")
2206
				print red("!!!")+" parallel-fetching requires the distlocks feature enabled"
2207
				print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled"
2208
				print red("!!!")
2209
			elif len(mymergelist) > 1:
2210
				print ">>> starting parallel fetching"
2211
				pid = os.fork()
2212
				if not pid:
2213
					sys.stdin.close()
2214
					sys.stdout.close()
2215
					sys.stderr.close()
2216
					time.sleep(3) # allow the parent to have first fetch
2217
					fetchlog = "/var/log/emerge-fetch.log"
2218
					sys.stdout = open(fetchlog, "w")
2219
					sys.stderr = sys.stdout
2220
					os.dup2(sys.stdout.fileno(), 1)
2221
					os.dup2(sys.stderr.fileno(), 2)
2222
					portage_util.apply_secpass_permissions(fetchlog,
2223
						uid=portage.portage_uid, gid=portage.portage_gid,
2224
						mode=0660)
2225
2226
					for myroot, pkgsettings in self.pkgsettings.iteritems():
2227
						for x in ("autoaddcvs", "cvs"):
2228
							while x in pkgsettings.features:
2229
								pkgsettings.features.remove(x)
2230
						pkgsettings["FEATURES"] = " ".join(pkgsettings.features)
2231
						pkgsettings.backup_changes("FEATURES")
2232
2233
					ret = 0
2234
					for x in mymergelist:
2235
						if x[0] != "ebuild":
2236
							continue
2237
						myroot = x[1]
2238
						portdb = self.trees[myroot]["porttree"].dbapi
2239
						pkgsettings = self.pkgsettings[myroot]
2240
						pkgsettings.reset()
2241
						pkgsettings.setcpv(x[2])
2242
						try:
2243
							ret = portage.doebuild(portdb.findname(x[2]),
2244
								"fetch", myroot, pkgsettings,
2245
								cleanup=0, fetchonly=True,
2246
								mydbapi=portdb,
2247
								tree="porttree")
2248
						except SystemExit:
2249
							raise
2250
						except Exception:
2251
							ret = 1
2252
					sys.exit(0)
2253
				portage.portage_exec.spawned_pids.append(pid)
2254
2255
		totalcount = len(mymergelist)
2256
		mergecount=1
2257
		one_in_slot_failed=0
2258
		spawnd_pids=[]
2259
2260
		# dirty little trick to get number of cpus from the system
2261
		fd_cpuinfo = os.popen("cat /proc/cpuinfo","r")
2262
		cpu_count = 0
2263
		for data_cpuinfo in fd_cpuinfo.readlines():
2264
			if string.find(data_cpuinfo,'cpu MHz') > -1 :
2265
				cpu_count += 1
2266
		fd_cpuinfo.close()
2267
2268
		# if someone really screwed with /proc/cpuinfo output, we should not suffer
2269
		if cpu_count == 0:
2270
			cpu_count = 1
2271
2272
		spawnd_pkg = {}
2273
		failed_pid = 0
2274
		mylist = m_slots.keys()
2275
		mylist.sort()
2276
		for x in mylist:
2277
			# if slot is empty, go on
2278
			if not m_slots[x]:
2279
				continue
2280
2281
			# if previous slot failed, discontinue the emerge
2282
			if one_in_slot_failed and not ("--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts):
2283
				break
2284
2285
			# start multiple merges in parallel mode
2286
			if parallel:
2287
				num_at_atime = cpu_count + 1
2288
			else:
2289
				num_at_atime = 1
2290
2291
			for y in m_slots[x]:
2292
				# these all can go in parallel, so fork one after the other
2293
				# but num_at_atime at most
2294
				if num_at_atime:
2295
					onepid = self.fork_one_emerge(y, mergecount, totalcount, mtimedb, favorites, mysysdict)
2296
					spawnd_pids.append(onepid)
2297
					spawnd_pkg[onepid] = (y[2], x)
2298
					num_at_atime -= 1
2299
					mergecount += 1
2300
				else:
2301
					# let's wait for one of the jobs to finish
2302
					onepid = -1
2303
					while onepid not in spawnd_pids:
2304
						onepid , retval = os.waitpid(-1, 0)
2305
					spawnd_pids.remove(onepid)
2306
2307
					# if it failed, I need to fail next slot but continue to merge all in this slot
2308
					if retval:
2309
						one_in_slot_failed = retval
2310
						failed_pid = onepid
2311
					else:
2312
						# we need to remove this pkg from resume DB
2313
						# this is the dirtiest shit I have ever written
2314
						index = 0
2315
						pkg_compl = spawnd_pkg[onepid][0]
2316
						pkg_slot = spawnd_pkg[onepid][1]
2317
						for pkgs in mymergelist:
2318
							if pkgs[2] == pkg_compl:
2319
								del mymergelist[index]
2320
								del mtimedb["resume"]["mergelist"][index]
2321
								mtimedb.commit()
2322
								# check if we need to restart portage
2323
								mysplit=portage.pkgsplit(pkg_compl)
2324
								if mysplit[0] == "sys-apps/portage" and pkgs[1] == "/":
2325
									self.restart_portage(pkgs, mergecount, totalcount, mtimedb)
2326
								break
2327
							index += 1
2328
					onepid = self.fork_one_emerge(y, mergecount, totalcount, mtimedb, favorites, mysysdict)
2329
					spawnd_pids.append(onepid)
2330
					spawnd_pkg[onepid] = (y[2], x)
2331
					mergecount += 1
2332
2333
			# this slot is exhausted, so wait for all of the forks to finish
2334
			while spawnd_pids:
2335
				onepid = spawnd_pids.pop()
2336
				retval = os.waitpid(onepid, 0)[1]
2337
				if retval:
2338
					one_in_slot_failed = retval
2339
					failed_pid = onepid
2340
				else:
2341
					# we need to remove this pkg from resume DB
2342
					# this is the dirtiest shit I have ever written
2343
					index = 0
2344
					pkg_compl = spawnd_pkg[onepid][0]
2345
					pkg_slot = spawnd_pkg[onepid][1]
2346
					for pkgs in mymergelist:
2347
						if pkgs[2] == pkg_compl:
2348
							del mymergelist[index]
2349
							del mtimedb["resume"]["mergelist"][index]
2350
							mtimedb.commit()
2351
							# check if we need to restart portage
2352
							mysplit=portage.pkgsplit(pkg_compl)
2353
							if mysplit[0] == "sys-apps/portage" and pkgs[1] == "/":
2354
								self.restart_portage(pkgs, mergecount, totalcount, mtimedb)
2355
							break
2356
						index += 1
2357
2358
		if one_in_slot_failed:
2359
			if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
2360
				print "\n\n!!! Some fetch errors were encountered.  Please see above for details.\n\n"
2361
				sys.exit(1)
2362
2363
			logfile = None
2364
	                if "PORT_LOGDIR" in self.settings:
2365
				pkg_cat = spawnd_pkg[failed_pid][0].split("/")[0]
2366
				pkg_pf = spawnd_pkg[failed_pid][0].split("/")[1]
2367
				logid_path = os.path.join(self.settings["PORTAGE_TMPDIR"], "portage", pkg_pf, ".logid")
2368
				if os.path.exists(logid_path):
2369
					logid_time = time.strftime("%Y%m%d-%H%M%S", time.gmtime(os.stat(logid_path).st_mtime))
2370
					logfile = os.path.join( self.settings["PORT_LOGDIR"], "%s:%s:%s.log" % \
2371
						(pkg_cat, pkg_pf, logid_time))
2372
					del logid_time
2373
				del logid_path
2374
2375
			if logfile:
2376
				portage.portage_exec.spawn(('tail', '-n', '20', logfile), returnpid=False)
2377
2378
			portage.writemsg_stdout(red("Package "+spawnd_pkg[failed_pid][0]+" failed to emerge\n"))
2379
			if logfile:
2380
				portage.writemsg_stdout(red("Please take a look at the file "+logfile+"\n"))
2381
			sys.exit(one_in_slot_failed)
2382
2172
		if "--pretend" not in self.myopts:
2383
		if "--pretend" not in self.myopts:
2173
			emergelog(xterm_titles, " *** Finished. Cleaning up...")
2384
			emergelog(xterm_titles, " *** Finished. Cleaning up...")
2174
2385
Lines 2177-2190 Link Here
2177
			del mtimedb["resume"]
2388
			del mtimedb["resume"]
2178
		mtimedb.commit()
2389
		mtimedb.commit()
2179
2390
2180
		#by doing an exit this way, --fetchonly can continue to try to
2181
		#fetch everything even if a particular download fails.
2182
		if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
2391
		if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
2183
			if returnme:
2392
			sys.exit(0)
2184
				print "\n\n!!! Some fetch errors were encountered.  Please see above for details.\n\n"
2393
2185
				sys.exit(returnme)
2394
2186
			else:
2187
				sys.exit(0)
2188
2395
2189
def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files,
2396
def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files,
2190
	ldpath_mtimes, raise_on_missing=True):
2397
	ldpath_mtimes, raise_on_missing=True):
Lines 2419-2427 Link Here
2419
			emergelog(xterm_titles, "=== Unmerging... ("+y+")")
2626
			emergelog(xterm_titles, "=== Unmerging... ("+y+")")
2420
			mysplit=string.split(y,"/")
2627
			mysplit=string.split(y,"/")
2421
			#unmerge...
2628
			#unmerge...
2629
                        logfile = None
2630
                        if "PORT_LOGDIR" in settings:
2631
                                pkg_cat = y.split("/")[0]
2632
                                pkg_pf = y.split("/")[1]
2633
                                logid_time = time.strftime("%Y%m%d-%H%M%S",
2634
						time.gmtime(os.stat(settings["PORTAGE_TMPDIR"]).st_mtime))
2635
                                logfile = os.path.join( settings["PORT_LOGDIR"], "%s:%s:%s.log" % \
2636
                                        (pkg_cat, pkg_pf, logid_time))
2637
                                del logid_time
2638
2422
			retval = portage.unmerge(mysplit[0], mysplit[1], settings["ROOT"],
2639
			retval = portage.unmerge(mysplit[0], mysplit[1], settings["ROOT"],
2423
				mysettings, unmerge_action not in ["clean","prune"],
2640
				mysettings, unmerge_action not in ["clean","prune"],
2424
				vartree=vartree, ldpath_mtimes=ldpath_mtimes)
2641
				vartree=vartree, ldpath_mtimes=ldpath_mtimes, logfile=logfile)
2425
			if retval != os.EX_OK:
2642
			if retval != os.EX_OK:
2426
				emergelog(xterm_titles, " !!! unmerge FAILURE: "+y)
2643
				emergelog(xterm_titles, " !!! unmerge FAILURE: "+y)
2427
			else:
2644
			else:
Lines 2548-2554 Link Here
2548
def validate_merge_list(trees, mergelist):
2765
def validate_merge_list(trees, mergelist):
2549
	"""Validate the list to make sure all the packages are still available.
2766
	"""Validate the list to make sure all the packages are still available.
2550
	This is needed for --resume."""
2767
	This is needed for --resume."""
2551
	for (pkg_type, myroot, pkg_key, action) in mergelist:
2768
	for (pkg_type, myroot, pkg_key, action, merge_slot) in mergelist:
2552
		if pkg_type == "binary" and \
2769
		if pkg_type == "binary" and \
2553
			not trees[myroot]["bintree"].dbapi.match("="+pkg_key) or \
2770
			not trees[myroot]["bintree"].dbapi.match("="+pkg_key) or \
2554
			pkg_type == "ebuild" and \
2771
			pkg_type == "ebuild" and \
Lines 3390-3395 Link Here
3390
	else:
3607
	else:
3391
		print "Number removed:       "+str(len(cleanlist))
3608
		print "Number removed:       "+str(len(cleanlist))
3392
3609
3610
def mergelist_to_merge_slot(mergelist, printonly=False):
3611
	merge_slots = {}
3612
	for pkg in mergelist:
3613
		if pkg[3] == 'merge':
3614
			slot = int(pkg[4])
3615
			try:
3616
				if pkg not in merge_slots[slot]:
3617
					merge_slots[slot].append(pkg)
3618
			except KeyError:
3619
				merge_slots[slot] = [pkg]
3620
	# print the merge slots
3621
	max_slot = 0
3622
	mylist = merge_slots.keys()
3623
	mylist.sort()
3624
	for x in mylist:
3625
		if x > max_slot:
3626
			max_slot = x
3627
		print "Package list for slot = "+str(x)
3628
		for y in merge_slots[x]:
3629
			print "	",y
3630
	if printonly:
3631
		return
3632
3633
	# make one last pass at the merge_slots and initialize the missing slots to None
3634
	x = 0
3635
	while x < max_slot:
3636
		if x not in merge_slots.keys():
3637
			merge_slots[x] = None
3638
		x += 1
3639
	return merge_slots
3640
3393
def action_build(settings, trees, mtimedb,
3641
def action_build(settings, trees, mtimedb,
3394
	myopts, myaction, myfiles, spinner):
3642
	myopts, myaction, myfiles, spinner):
3395
	ldpath_mtimes = mtimedb["ldpath"]
3643
	ldpath_mtimes = mtimedb["ldpath"]
Lines 3491-3502 Link Here
3491
			if len(mymergelist) == 0:
3739
			if len(mymergelist) == 0:
3492
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
3740
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
3493
				sys.exit(0)
3741
				sys.exit(0)
3742
			mergelist_to_merge_slot(mymergelist, True)
3494
			mydepgraph.display(mymergelist)
3743
			mydepgraph.display(mymergelist)
3495
			prompt="Would you like to resume merging these packages?"
3744
			prompt="Would you like to resume merging these packages?"
3496
		else:
3745
		else:
3497
			mydepgraph.display(mydepgraph.altlist())
3746
			mymergelist = mydepgraph.altlist()
3747
			mergelist_to_merge_slot(mymergelist, True)
3748
			mydepgraph.display(mymergelist)
3498
			mergecount=0
3749
			mergecount=0
3499
			for x in mydepgraph.altlist():
3750
			for x in mymergelist:
3500
				if x[3]!="nomerge":
3751
				if x[3]!="nomerge":
3501
					mergecount+=1
3752
					mergecount+=1
3502
				#check for blocking dependencies
3753
				#check for blocking dependencies
Lines 3536-3544 Link Here
3536
			if len(mymergelist) == 0:
3787
			if len(mymergelist) == 0:
3537
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
3788
				print colorize("INFORM", "emerge: It seems we have nothing to resume...")
3538
				sys.exit(0)
3789
				sys.exit(0)
3790
			mergelist_to_merge_slot(mymergelist, True)
3539
			mydepgraph.display(mymergelist)
3791
			mydepgraph.display(mymergelist)
3540
		else:
3792
		else:
3541
			mydepgraph.display(mydepgraph.altlist())
3793
			mymergelist = mydepgraph.altlist()
3794
			mergelist_to_merge_slot(mymergelist, True)
3795
			mydepgraph.display(mymergelist)
3542
	else:
3796
	else:
3543
		if ("--buildpkgonly" in myopts):
3797
		if ("--buildpkgonly" in myopts):
3544
			if not mydepgraph.digraph.hasallzeros():
3798
			if not mydepgraph.digraph.hasallzeros():
(-)portage-2.1.1.orig/pym/portage.py (-70 / +85 lines)
Lines 2114-2126 Link Here
2114
										noiselevel=-1)
2114
										noiselevel=-1)
2115
									os.unlink(myfile_path)
2115
									os.unlink(myfile_path)
2116
							else:
2116
							else:
2117
								eout = output.EOutput()
2118
								eout.quiet = \
2119
									mysettings.get("PORTAGE_QUIET", None) == "1"
2120
								for digest_name in mydigests[myfile]:
2121
									eout.ebegin(
2122
										"%s %s ;-)" % (myfile, digest_name))
2123
									eout.eend(0)
2124
								continue # fetch any remaining files
2117
								continue # fetch any remaining files
2125
2118
2126
			for loc in filedict[myfile]:
2119
			for loc in filedict[myfile]:
Lines 2172-2177 Link Here
2172
					else:
2165
					else:
2173
						#normal mode:
2166
						#normal mode:
2174
						locfetch=fetchcommand
2167
						locfetch=fetchcommand
2168
					# assuming -q will work with customized FETCH and RESUME commands.
2169
					# It sure works with the default, which most people will leave alone
2170
					# I will check for wget anyway, to be on less destructive side...;)
2171
					if "parallel" in mysettings.features and locfetch.find("wget ") >= 0:
2172
						locfetch+=" -q"
2175
					writemsg_stdout(">>> Downloading '%s'\n" % \
2173
					writemsg_stdout(">>> Downloading '%s'\n" % \
2176
						re.sub(r'//(.+):.+@(.+)/',r'//\1:*password*@\2/', loc))
2174
						re.sub(r'//(.+):.+@(.+)/',r'//\1:*password*@\2/', loc))
2177
					myfetch=string.replace(locfetch,"${URI}",loc)
2175
					myfetch=string.replace(locfetch,"${URI}",loc)
Lines 2260-2270 Link Here
2260
									os.unlink(mysettings["DISTDIR"]+"/"+myfile)
2258
									os.unlink(mysettings["DISTDIR"]+"/"+myfile)
2261
									fetched=0
2259
									fetched=0
2262
								else:
2260
								else:
2263
									eout = output.EOutput()
2264
									eout.quiet = mysettings.get("PORTAGE_QUIET", None) == "1"
2265
									for x_key in mydigests[myfile].keys():
2266
										eout.ebegin("%s %s ;-)" % (myfile, x_key))
2267
										eout.eend(0)
2268
									fetched=2
2261
									fetched=2
2269
									break
2262
									break
2270
					else:
2263
					else:
Lines 2383-2401 Link Here
2383
	eout = output.EOutput()
2376
	eout = output.EOutput()
2384
	eout.quiet = mysettings.get("PORTAGE_QUIET", None) == "1"
2377
	eout.quiet = mysettings.get("PORTAGE_QUIET", None) == "1"
2385
	try:
2378
	try:
2386
		eout.ebegin("checking ebuild checksums ;-)")
2379
		myfullname = "/".join((mysettings["CATEGORY"], mysettings["PF"]))
2380
		eout.ebegin("Checking various checksums for "+myfullname+" ")
2387
		mf.checkTypeHashes("EBUILD")
2381
		mf.checkTypeHashes("EBUILD")
2388
		eout.eend(0)
2389
		eout.ebegin("checking auxfile checksums ;-)")
2390
		mf.checkTypeHashes("AUX")
2382
		mf.checkTypeHashes("AUX")
2391
		eout.eend(0)
2392
		eout.ebegin("checking miscfile checksums ;-)")
2393
		mf.checkTypeHashes("MISC", ignoreMissingFiles=True)
2383
		mf.checkTypeHashes("MISC", ignoreMissingFiles=True)
2394
		eout.eend(0)
2395
		for f in myfiles:
2384
		for f in myfiles:
2396
			eout.ebegin("checking %s ;-)" % f)
2397
			mf.checkFileHashes(mf.findFile(f), f)
2385
			mf.checkFileHashes(mf.findFile(f), f)
2398
			eout.eend(0)
2386
		eout.eend(0)
2399
	except KeyError, e:
2387
	except KeyError, e:
2400
		eout.eend(1)
2388
		eout.eend(1)
2401
		writemsg("\n!!! Missing digest for %s\n" % str(e), noiselevel=-1)
2389
		writemsg("\n!!! Missing digest for %s\n" % str(e), noiselevel=-1)
Lines 2425-2436 Link Here
2425
				return retval
2413
				return retval
2426
	kwargs = actionmap[mydo]["args"]
2414
	kwargs = actionmap[mydo]["args"]
2427
	mysettings["EBUILD_PHASE"] = mydo
2415
	mysettings["EBUILD_PHASE"] = mydo
2428
	phase_retval = spawn(actionmap[mydo]["cmd"] % mydo, mysettings, debug=debug, logfile=logfile, **kwargs)
2416
	phase_retval = spawn(actionmap[mydo]["cmd"] % mydo, mysettings, debug=debug, quiet=actionmap[mydo]["quiet"], logfile=logfile, **kwargs)
2429
	del mysettings["EBUILD_PHASE"]
2417
	del mysettings["EBUILD_PHASE"]
2430
	if phase_retval == os.EX_OK:
2418
	if phase_retval == os.EX_OK:
2431
		if mydo == "install":
2419
		if mydo == "install":
2432
			mycommand = " ".join([MISC_SH_BINARY, "install_qa_check"])
2420
			mycommand = " ".join([MISC_SH_BINARY, "install_qa_check"])
2433
			qa_retval = spawn(mycommand, mysettings, debug=debug, logfile=logfile, **kwargs)
2421
			qa_retval = spawn(mycommand, mysettings, debug=debug, quiet=actionmap[mydo]["quiet"], logfile=logfile, **kwargs)
2434
			if qa_retval:
2422
			if qa_retval:
2435
				writemsg("!!! install_qa_check failed; exiting.\n",
2423
				writemsg("!!! install_qa_check failed; exiting.\n",
2436
					noiselevel=-1)
2424
					noiselevel=-1)
Lines 2805-2814 Link Here
2805
			mystatus = prepare_build_dirs(myroot, mysettings, cleanup)
2793
			mystatus = prepare_build_dirs(myroot, mysettings, cleanup)
2806
			if mystatus:
2794
			if mystatus:
2807
				return mystatus
2795
				return mystatus
2808
		if mydo == "unmerge":
2809
			return unmerge(mysettings["CATEGORY"],
2810
				mysettings["PF"], myroot, mysettings, vartree=vartree)
2811
2812
		if "PORT_LOGDIR" in mysettings and builddir_lock:
2796
		if "PORT_LOGDIR" in mysettings and builddir_lock:
2813
			logid_path = os.path.join(mysettings["PORTAGE_BUILDDIR"], ".logid")
2797
			logid_path = os.path.join(mysettings["PORTAGE_BUILDDIR"], ".logid")
2814
			if not os.path.exists(logid_path):
2798
			if not os.path.exists(logid_path):
Lines 2823-2828 Link Here
2823
			mysettings["PORTAGE_LOG_FILE"] = logfile
2807
			mysettings["PORTAGE_LOG_FILE"] = logfile
2824
			del logid_path, logid_time
2808
			del logid_path, logid_time
2825
2809
2810
		if mydo == "unmerge":
2811
			return unmerge(mysettings["CATEGORY"],
2812
				mysettings["PF"], myroot, mysettings, vartree=vartree, logfile=logfile)
2813
2814
2826
		# if any of these are being called, handle them -- running them out of
2815
		# if any of these are being called, handle them -- running them out of
2827
		# the sandbox -- and stop now.
2816
		# the sandbox -- and stop now.
2828
		if mydo in ["clean","cleanrm"]:
2817
		if mydo in ["clean","cleanrm"]:
Lines 2830-2836 Link Here
2830
				debug=debug, free=1, logfile=None)
2819
				debug=debug, free=1, logfile=None)
2831
		elif mydo in ["help","setup"]:
2820
		elif mydo in ["help","setup"]:
2832
			return spawn(EBUILD_SH_BINARY + " " + mydo, mysettings,
2821
			return spawn(EBUILD_SH_BINARY + " " + mydo, mysettings,
2833
				debug=debug, free=1, logfile=logfile)
2822
				debug=debug, free=1, quiet=False, logfile=logfile)
2834
		elif mydo == "preinst":
2823
		elif mydo == "preinst":
2835
			if mysettings.get("EMERGE_FROM", None) == "binary":
2824
			if mysettings.get("EMERGE_FROM", None) == "binary":
2836
				mysettings.load_infodir(mysettings["O"])
2825
				mysettings.load_infodir(mysettings["O"])
Lines 2855-2861 Link Here
2855
		elif mydo in ["prerm","postrm","postinst","config"]:
2844
		elif mydo in ["prerm","postrm","postinst","config"]:
2856
			mysettings.load_infodir(mysettings["O"])
2845
			mysettings.load_infodir(mysettings["O"])
2857
			return spawn(EBUILD_SH_BINARY + " " + mydo,
2846
			return spawn(EBUILD_SH_BINARY + " " + mydo,
2858
				mysettings, debug=debug, free=1, logfile=logfile)
2847
				mysettings, debug=debug, free=1, quiet=(mydo != "postinst"), logfile=logfile)
2859
2848
2860
		mycpv = "/".join((mysettings["CATEGORY"], mysettings["PF"]))
2849
		mycpv = "/".join((mysettings["CATEGORY"], mysettings["PF"]))
2861
2850
Lines 2971-2984 Link Here
2971
2960
2972
		# args are for the to spawn function
2961
		# args are for the to spawn function
2973
		actionmap = {
2962
		actionmap = {
2974
"depend": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":0,         "sesandbox":0}},
2963
"depend": {"cmd":ebuild_sh, "quiet":True, "args":{"droppriv":1, "free":0,         "sesandbox":0}},
2975
"setup":  {"cmd":ebuild_sh, "args":{"droppriv":0, "free":1,         "sesandbox":0}},
2964
"setup":  {"cmd":ebuild_sh, "quiet":False, "args":{"droppriv":0, "free":1,         "sesandbox":0}},
2976
"unpack": {"cmd":ebuild_sh, "args":{"droppriv":1, "free":0,         "sesandbox":sesandbox}},
2965
"unpack": {"cmd":ebuild_sh, "quiet":True, "args":{"droppriv":1, "free":0,         "sesandbox":sesandbox}},
2977
"compile":{"cmd":ebuild_sh, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox}},
2966
"compile":{"cmd":ebuild_sh, "quiet":True, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox}},
2978
"test":   {"cmd":ebuild_sh, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox}},
2967
"test":   {"cmd":ebuild_sh, "quiet":True, "args":{"droppriv":1, "free":nosandbox, "sesandbox":sesandbox}},
2979
"install":{"cmd":ebuild_sh, "args":{"droppriv":0, "free":0,         "sesandbox":sesandbox}},
2968
"install":{"cmd":ebuild_sh, "quiet":True, "args":{"droppriv":0, "free":0,         "sesandbox":sesandbox}},
2980
"rpm":    {"cmd":misc_sh,   "args":{"droppriv":0, "free":0,         "sesandbox":0}},
2969
"rpm":    {"cmd":misc_sh,   "quiet":False, "args":{"droppriv":0, "free":0,         "sesandbox":0}},
2981
"package":{"cmd":misc_sh,   "args":{"droppriv":0, "free":0,         "sesandbox":0}},
2970
"package":{"cmd":misc_sh,   "quiet":False, "args":{"droppriv":0, "free":0,         "sesandbox":0}},
2982
		}
2971
		}
2983
2972
2984
		# merge the deps in so we have again a 'full' actionmap
2973
		# merge the deps in so we have again a 'full' actionmap
Lines 2986-2991 Link Here
2986
		for x in actionmap.keys():
2975
		for x in actionmap.keys():
2987
			if len(actionmap_deps.get(x, [])):
2976
			if len(actionmap_deps.get(x, [])):
2988
				actionmap[x]["dep"] = ' '.join(actionmap_deps[x])
2977
				actionmap[x]["dep"] = ' '.join(actionmap_deps[x])
2978
			# debug session should get all the junk in the screen
2979
			if debug and actionmap[x]["quiet"]:
2980
				actionmap[x]["quiet"] = False
2989
2981
2990
		if mydo in actionmap.keys():
2982
		if mydo in actionmap.keys():
2991
			if mydo=="package":
2983
			if mydo=="package":
Lines 3011-3017 Link Here
3011
				mysettings["CATEGORY"], mysettings["PF"], mysettings["D"],
3003
				mysettings["CATEGORY"], mysettings["PF"], mysettings["D"],
3012
				os.path.join(mysettings["PORTAGE_BUILDDIR"], "build-info"),
3004
				os.path.join(mysettings["PORTAGE_BUILDDIR"], "build-info"),
3013
				myroot, mysettings, myebuild=mysettings["EBUILD"], mytree=tree,
3005
				myroot, mysettings, myebuild=mysettings["EBUILD"], mytree=tree,
3014
				mydbapi=mydbapi, vartree=vartree, prev_mtimes=prev_mtimes)
3006
				mydbapi=mydbapi, vartree=vartree, prev_mtimes=prev_mtimes, logfile=logfile)
3015
		elif mydo=="merge":
3007
		elif mydo=="merge":
3016
			retval = spawnebuild("install", actionmap, mysettings, debug,
3008
			retval = spawnebuild("install", actionmap, mysettings, debug,
3017
				alwaysdep=1, logfile=logfile)
3009
				alwaysdep=1, logfile=logfile)
Lines 3020-3026 Link Here
3020
					mysettings["D"], os.path.join(mysettings["PORTAGE_BUILDDIR"],
3012
					mysettings["D"], os.path.join(mysettings["PORTAGE_BUILDDIR"],
3021
					"build-info"), myroot, mysettings,
3013
					"build-info"), myroot, mysettings,
3022
					myebuild=mysettings["EBUILD"], mytree=tree, mydbapi=mydbapi,
3014
					myebuild=mysettings["EBUILD"], mytree=tree, mydbapi=mydbapi,
3023
					vartree=vartree, prev_mtimes=prev_mtimes)
3015
					vartree=vartree, prev_mtimes=prev_mtimes, logfile=logfile)
3024
		else:
3016
		else:
3025
			print "!!! Unknown mydo:",mydo
3017
			print "!!! Unknown mydo:",mydo
3026
			return 1
3018
			return 1
Lines 3235-3249 Link Here
3235
	return newmtime
3227
	return newmtime
3236
3228
3237
def merge(mycat, mypkg, pkgloc, infloc, myroot, mysettings, myebuild=None,
3229
def merge(mycat, mypkg, pkgloc, infloc, myroot, mysettings, myebuild=None,
3238
	mytree=None, mydbapi=None, vartree=None, prev_mtimes=None):
3230
	mytree=None, mydbapi=None, vartree=None, prev_mtimes=None, logfile=None):
3239
	mylink = dblink(mycat, mypkg, myroot, mysettings, treetype=mytree,
3231
	mylink = dblink(mycat, mypkg, myroot, mysettings, treetype=mytree,
3240
		vartree=vartree)
3232
		vartree=vartree, logfile=logfile)
3241
	return mylink.merge(pkgloc, infloc, myroot, myebuild,
3233
	return mylink.merge(pkgloc, infloc, myroot, myebuild,
3242
		mydbapi=mydbapi, prev_mtimes=prev_mtimes)
3234
		mydbapi=mydbapi, prev_mtimes=prev_mtimes)
3243
3235
3244
def unmerge(cat, pkg, myroot, mysettings, mytrimworld=1, vartree=None, ldpath_mtimes=None):
3236
def unmerge(cat, pkg, myroot, mysettings, mytrimworld=1, vartree=None, ldpath_mtimes=None, logfile=None):
3245
	mylink = dblink(
3237
	mylink = dblink(
3246
		cat, pkg, myroot, mysettings, treetype="vartree", vartree=vartree)
3238
		cat, pkg, myroot, mysettings, treetype="vartree", vartree=vartree, logfile=logfile)
3247
	try:
3239
	try:
3248
		mylink.lockdb()
3240
		mylink.lockdb()
3249
		if mylink.exists():
3241
		if mylink.exists():
Lines 5541-5547 Link Here
5541
class dblink:
5533
class dblink:
5542
	"this class provides an interface to the standard text package database"
5534
	"this class provides an interface to the standard text package database"
5543
	def __init__(self, cat, pkg, myroot, mysettings, treetype=None,
5535
	def __init__(self, cat, pkg, myroot, mysettings, treetype=None,
5544
		vartree=None):
5536
		vartree=None, logfile=None):
5545
		"create a dblink object for cat/pkg.  This dblink entry may or may not exist"
5537
		"create a dblink object for cat/pkg.  This dblink entry may or may not exist"
5546
		self.cat     = cat
5538
		self.cat     = cat
5547
		self.pkg     = pkg
5539
		self.pkg     = pkg
Lines 5574-5579 Link Here
5574
		self.updateprotect = protect_obj.updateprotect
5566
		self.updateprotect = protect_obj.updateprotect
5575
		self.isprotected = protect_obj.isprotected
5567
		self.isprotected = protect_obj.isprotected
5576
		self.contentscache=[]
5568
		self.contentscache=[]
5569
		self.logfile = logfile
5570
		self.logfd = None
5577
5571
5578
	def lockdb(self):
5572
	def lockdb(self):
5579
		if self.lock_num == 0:
5573
		if self.lock_num == 0:
Lines 5717-5722 Link Here
5717
				writemsg("!!! FAILED prerm: "+str(a)+"\n", noiselevel=-1)
5711
				writemsg("!!! FAILED prerm: "+str(a)+"\n", noiselevel=-1)
5718
				sys.exit(123)
5712
				sys.exit(123)
5719
5713
5714
		if self.logfile:
5715
			self.logfd = open(self.logfile, "a")
5716
		else:
5717
			self.logfd = sys.stdout
5718
5720
		if pkgfiles:
5719
		if pkgfiles:
5721
			mykeys=pkgfiles.keys()
5720
			mykeys=pkgfiles.keys()
5722
			mykeys.sort()
5721
			mykeys.sort()
Lines 5747-5753 Link Here
5747
						#we skip this if we're dealing with a symlink
5746
						#we skip this if we're dealing with a symlink
5748
						#because os.stat() will operate on the
5747
						#because os.stat() will operate on the
5749
						#link target rather than the link itself.
5748
						#link target rather than the link itself.
5750
						writemsg_stdout("--- !found "+str(pkgfiles[objkey][0])+ " %s\n" % obj)
5749
						writemsg("--- !found "+str(pkgfiles[objkey][0])+ " %s\n" % obj, fd=self.logfd)
5751
						continue
5750
						continue
5752
				# next line includes a tweak to protect modules from being unmerged,
5751
				# next line includes a tweak to protect modules from being unmerged,
5753
				# but we don't protect modules from being overwritten if they are
5752
				# but we don't protect modules from being overwritten if they are
Lines 5755-5811 Link Here
5755
				# functionality for /lib/modules. For portage-ng both capabilities
5754
				# functionality for /lib/modules. For portage-ng both capabilities
5756
				# should be able to be independently specified.
5755
				# should be able to be independently specified.
5757
				if self.isprotected(obj) or ((len(obj) > len(modprotect)) and (obj[0:len(modprotect)]==modprotect)):
5756
				if self.isprotected(obj) or ((len(obj) > len(modprotect)) and (obj[0:len(modprotect)]==modprotect)):
5758
					writemsg_stdout("--- cfgpro %s %s\n" % (pkgfiles[objkey][0], obj))
5757
					writemsg("--- cfgpro %s %s\n" % (pkgfiles[objkey][0], obj), fd=self.logfd)
5759
					continue
5758
					continue
5760
5759
5761
				lmtime=str(lstatobj[stat.ST_MTIME])
5760
				lmtime=str(lstatobj[stat.ST_MTIME])
5762
				if (pkgfiles[objkey][0] not in ("dir","fif","dev")) and (lmtime != pkgfiles[objkey][1]):
5761
				if (pkgfiles[objkey][0] not in ("dir","fif","dev")) and (lmtime != pkgfiles[objkey][1]):
5763
					writemsg_stdout("--- !mtime %s %s\n" % (pkgfiles[objkey][0], obj))
5762
					writemsg("--- !mtime %s %s\n" % (pkgfiles[objkey][0], obj), fd=self.logfd)
5764
					continue
5763
					continue
5765
5764
5766
				if pkgfiles[objkey][0]=="dir":
5765
				if pkgfiles[objkey][0]=="dir":
5767
					if statobj is None or not stat.S_ISDIR(statobj.st_mode):
5766
					if statobj is None or not stat.S_ISDIR(statobj.st_mode):
5768
						writemsg_stdout("--- !dir   %s %s\n" % ("dir", obj))
5767
						writemsg("--- !dir   %s %s\n" % ("dir", obj), fd=self.logfd)
5769
						continue
5768
						continue
5770
					mydirs.append(obj)
5769
					mydirs.append(obj)
5771
				elif pkgfiles[objkey][0]=="sym":
5770
				elif pkgfiles[objkey][0]=="sym":
5772
					if not islink:
5771
					if not islink:
5773
						writemsg_stdout("--- !sym   %s %s\n" % ("sym", obj))
5772
						writemsg("--- !sym   %s %s\n" % ("sym", obj), fd=self.logfd)
5774
						continue
5773
						continue
5775
					try:
5774
					try:
5776
						os.unlink(obj)
5775
						os.unlink(obj)
5777
						writemsg_stdout("<<<        %s %s\n" % ("sym",obj))
5776
						writemsg("<<<        %s %s\n" % ("sym",obj), fd=self.logfd)
5778
					except (OSError,IOError),e:
5777
					except (OSError,IOError),e:
5779
						writemsg_stdout("!!!        %s %s\n" % ("sym",obj))
5778
						writemsg("!!!        %s %s\n" % ("sym",obj), fd=self.logfd)
5780
				elif pkgfiles[objkey][0]=="obj":
5779
				elif pkgfiles[objkey][0]=="obj":
5781
					if statobj is None or not stat.S_ISREG(statobj.st_mode):
5780
					if statobj is None or not stat.S_ISREG(statobj.st_mode):
5782
						writemsg_stdout("--- !obj   %s %s\n" % ("obj", obj))
5781
						writemsg("--- !obj   %s %s\n" % ("obj", obj), fd=self.logfd)
5783
						continue
5782
						continue
5784
					mymd5 = None
5783
					mymd5 = None
5785
					try:
5784
					try:
5786
						mymd5 = portage_checksum.perform_md5(obj, calc_prelink=1)
5785
						mymd5 = portage_checksum.perform_md5(obj, calc_prelink=1)
5787
					except portage_exception.FileNotFound, e:
5786
					except portage_exception.FileNotFound, e:
5788
						# the file has disappeared between now and our stat call
5787
						# the file has disappeared between now and our stat call
5789
						writemsg_stdout("--- !obj   %s %s\n" % ("obj", obj))
5788
						writemsg("--- !obj   %s %s\n" % ("obj", obj), fd=self.logfd)
5790
						continue
5789
						continue
5791
5790
5792
					# string.lower is needed because db entries used to be in upper-case.  The
5791
					# string.lower is needed because db entries used to be in upper-case.  The
5793
					# string.lower allows for backwards compatibility.
5792
					# string.lower allows for backwards compatibility.
5794
					if mymd5 != string.lower(pkgfiles[objkey][2]):
5793
					if mymd5 != string.lower(pkgfiles[objkey][2]):
5795
						writemsg_stdout("--- !md5   %s %s\n" % ("obj", obj))
5794
						writemsg("--- !md5   %s %s\n" % ("obj", obj), fd=self.logfd)
5796
						continue
5795
						continue
5797
					try:
5796
					try:
5798
						os.unlink(obj)
5797
						os.unlink(obj)
5799
					except (OSError,IOError),e:
5798
					except (OSError,IOError),e:
5800
						pass
5799
						pass
5801
					writemsg_stdout("<<<        %s %s\n" % ("obj",obj))
5800
					writemsg("<<<        %s %s\n" % ("obj",obj), fd=self.logfd)
5802
				elif pkgfiles[objkey][0]=="fif":
5801
				elif pkgfiles[objkey][0]=="fif":
5803
					if not stat.S_ISFIFO(lstatobj[stat.ST_MODE]):
5802
					if not stat.S_ISFIFO(lstatobj[stat.ST_MODE]):
5804
						writemsg_stdout("--- !fif   %s %s\n" % ("fif", obj))
5803
						writemsg("--- !fif   %s %s\n" % ("fif", obj), fd=self.logfd)
5805
						continue
5804
						continue
5806
					writemsg_stdout("---        %s %s\n" % ("fif",obj))
5805
					writemsg("---        %s %s\n" % ("fif",obj), fd=self.logfd)
5807
				elif pkgfiles[objkey][0]=="dev":
5806
				elif pkgfiles[objkey][0]=="dev":
5808
					writemsg_stdout("---        %s %s\n" % ("dev",obj))
5807
					writemsg("---        %s %s\n" % ("dev",obj), fd=self.logfd)
5809
5808
5810
			mydirs.sort()
5809
			mydirs.sort()
5811
			mydirs.reverse()
5810
			mydirs.reverse()
Lines 5815-5834 Link Here
5815
				if not last_non_empty.startswith(obj) and not listdir(obj):
5814
				if not last_non_empty.startswith(obj) and not listdir(obj):
5816
					try:
5815
					try:
5817
						os.rmdir(obj)
5816
						os.rmdir(obj)
5818
						writemsg_stdout("<<<        %s %s\n" % ("dir",obj))
5817
						writemsg("<<<        %s %s\n" % ("dir",obj), fd=self.logfd)
5819
						last_non_empty = ""
5818
						last_non_empty = ""
5820
						continue
5819
						continue
5821
					except (OSError,IOError),e:
5820
					except (OSError,IOError),e:
5822
						#immutable?
5821
						#immutable?
5823
						pass
5822
						pass
5824
5823
5825
				writemsg_stdout("--- !empty dir %s\n" % obj)
5824
				writemsg("--- !empty dir %s\n" % obj, fd=self.logfd)
5826
				last_non_empty = obj
5825
				last_non_empty = obj
5827
				continue
5826
				continue
5828
5827
5829
		#remove self from vartree database so that our own virtual gets zapped if we're the last node
5828
		#remove self from vartree database so that our own virtual gets zapped if we're the last node
5830
		self.vartree.zap(self.mycpv)
5829
		self.vartree.zap(self.mycpv)
5831
5830
5831
		# close out the logfile now
5832
		self.logfd.flush()
5833
		if self.logfile:
5834
			self.logfd.close()
5835
5832
		#do original postrm
5836
		#do original postrm
5833
		if myebuildpath and os.path.exists(myebuildpath):
5837
		if myebuildpath and os.path.exists(myebuildpath):
5834
			# XXX: This should be the old config, not the current one.
5838
			# XXX: This should be the old config, not the current one.
Lines 6015-6020 Link Here
6015
		prevmask   = os.umask(0)
6019
		prevmask   = os.umask(0)
6016
		secondhand = []
6020
		secondhand = []
6017
6021
6022
		if self.logfile:
6023
			self.logfd = open(self.logfile, "a")
6024
		else:
6025
			self.logfd = sys.stdout
6026
6018
		# we do a first merge; this will recurse through all files in our srcroot but also build up a
6027
		# we do a first merge; this will recurse through all files in our srcroot but also build up a
6019
		# "second hand" of symlinks to merge later
6028
		# "second hand" of symlinks to merge later
6020
		if self.mergeme(srcroot,destroot,outfile,secondhand,"",cfgfiledict,mymtime):
6029
		if self.mergeme(srcroot,destroot,outfile,secondhand,"",cfgfiledict,mymtime):
Lines 6049-6060 Link Here
6049
		outfile.flush()
6058
		outfile.flush()
6050
		outfile.close()
6059
		outfile.close()
6051
6060
6061
		# close the log file. unmerge will open it again. Can't leave it open because unmerge does
6062
		# doebuild which will screw the logfile
6063
		self.logfd.flush()
6064
		if self.logfile:
6065
			self.logfd.close()
6066
6052
		if os.path.exists(self.dbpkgdir):
6067
		if os.path.exists(self.dbpkgdir):
6053
			writemsg_stdout(">>> Safely unmerging already-installed instance...\n")
6068
			writemsg_stdout(">>> Safely unmerging already-installed instance of "+self.mycpv+" ...\n")
6054
			self.dbdir = self.dbpkgdir
6069
			self.dbdir = self.dbpkgdir
6055
			self.unmerge(oldcontents, trimworld=0, ldpath_mtimes=prev_mtimes)
6070
			self.unmerge(oldcontents, trimworld=0, ldpath_mtimes=prev_mtimes)
6056
			self.dbdir = self.dbtmpdir
6071
			self.dbdir = self.dbtmpdir
6057
			writemsg_stdout(">>> Original instance of package unmerged safely.\n")
6072
			writemsg_stdout(">>> Original instance of "+self.mycpv+" unmerged safely.\n")
6058
6073
6059
		# We hold both directory locks.
6074
		# We hold both directory locks.
6060
		self.dbdir = self.dbpkgdir
6075
		self.dbdir = self.dbpkgdir
Lines 6213-6219 Link Here
6213
				# unlinking no longer necessary; "movefile" will overwrite symlinks atomically and correctly
6228
				# unlinking no longer necessary; "movefile" will overwrite symlinks atomically and correctly
6214
				mymtime=movefile(mysrc,mydest,newmtime=thismtime,sstat=mystat, mysettings=self.settings)
6229
				mymtime=movefile(mysrc,mydest,newmtime=thismtime,sstat=mystat, mysettings=self.settings)
6215
				if mymtime!=None:
6230
				if mymtime!=None:
6216
					writemsg_stdout(">>> %s -> %s\n" % (mydest, myto))
6231
					writemsg(">>> %s -> %s\n" % (mydest, myto), fd=self.logfd)
6217
					outfile.write("sym "+myrealdest+" -> "+myto+" "+str(mymtime)+"\n")
6232
					outfile.write("sym "+myrealdest+" -> "+myto+" "+str(mymtime)+"\n")
6218
				else:
6233
				else:
6219
					print "!!! Failed to move file."
6234
					print "!!! Failed to move file."
Lines 6242-6248 Link Here
6242
6257
6243
					if stat.S_ISLNK(mydmode) or stat.S_ISDIR(mydmode):
6258
					if stat.S_ISLNK(mydmode) or stat.S_ISDIR(mydmode):
6244
						# a symlink to an existing directory will work for us; keep it:
6259
						# a symlink to an existing directory will work for us; keep it:
6245
						writemsg_stdout("--- %s/\n" % mydest)
6260
						writemsg("--- %s/\n" % mydest, fd=self.logfd)
6246
						if bsd_chflags:
6261
						if bsd_chflags:
6247
							bsd_chflags.lchflags(mydest, dflags)
6262
							bsd_chflags.lchflags(mydest, dflags)
6248
					else:
6263
					else:
Lines 6260-6266 Link Here
6260
							bsd_chflags.lchflags(mydest, dflags)
6275
							bsd_chflags.lchflags(mydest, dflags)
6261
						os.chmod(mydest,mystat[0])
6276
						os.chmod(mydest,mystat[0])
6262
						os.chown(mydest,mystat[4],mystat[5])
6277
						os.chown(mydest,mystat[4],mystat[5])
6263
						writemsg_stdout(">>> %s/\n" % mydest)
6278
						writemsg(">>> %s/\n" % mydest, fd=self.logfd)
6264
				else:
6279
				else:
6265
					#destination doesn't exist
6280
					#destination doesn't exist
6266
					if self.settings.selinux_enabled():
6281
					if self.settings.selinux_enabled():
Lines 6272-6278 Link Here
6272
					if bsd_chflags:
6287
					if bsd_chflags:
6273
						bsd_chflags.lchflags(mydest, bsd_chflags.lgetflags(mysrc))
6288
						bsd_chflags.lchflags(mydest, bsd_chflags.lgetflags(mysrc))
6274
					os.chown(mydest,mystat[4],mystat[5])
6289
					os.chown(mydest,mystat[4],mystat[5])
6275
					writemsg_stdout(">>> %s/\n" % mydest)
6290
					writemsg(">>> %s/\n" % mydest, fd=self.logfd)
6276
				outfile.write("dir "+myrealdest+"\n")
6291
				outfile.write("dir "+myrealdest+"\n")
6277
				# recurse and merge this directory
6292
				# recurse and merge this directory
6278
				if self.mergeme(srcroot, destroot, outfile, secondhand,
6293
				if self.mergeme(srcroot, destroot, outfile, secondhand,
Lines 6290-6296 Link Here
6290
					if stat.S_ISDIR(mydmode):
6305
					if stat.S_ISDIR(mydmode):
6291
						# install of destination is blocked by an existing directory with the same name
6306
						# install of destination is blocked by an existing directory with the same name
6292
						moveme=0
6307
						moveme=0
6293
						writemsg_stdout("!!! %s\n" % mydest)
6308
						writemsg("!!! %s\n" % mydest, fd=self.logfd)
6294
					elif stat.S_ISREG(mydmode) or (stat.S_ISLNK(mydmode) and os.path.exists(mydest) and stat.S_ISREG(os.stat(mydest)[stat.ST_MODE])):
6309
					elif stat.S_ISREG(mydmode) or (stat.S_ISLNK(mydmode) and os.path.exists(mydest) and stat.S_ISREG(os.stat(mydest)[stat.ST_MODE])):
6295
						cfgprot=0
6310
						cfgprot=0
6296
						# install of destination is blocked by an existing regular file,
6311
						# install of destination is blocked by an existing regular file,
Lines 6393-6399 Link Here
6393
				if mymtime!=None:
6408
				if mymtime!=None:
6394
					zing=">>>"
6409
					zing=">>>"
6395
					outfile.write("obj "+myrealdest+" "+mymd5+" "+str(mymtime)+"\n")
6410
					outfile.write("obj "+myrealdest+" "+mymd5+" "+str(mymtime)+"\n")
6396
				writemsg_stdout("%s %s\n" % (zing,mydest))
6411
				writemsg("%s %s\n" % (zing,mydest), fd=self.logfd)
6397
			else:
6412
			else:
6398
				# we are merging a fifo or device node
6413
				# we are merging a fifo or device node
6399
				zing="!!!"
6414
				zing="!!!"
Lines 6407-6413 Link Here
6407
							outfile.write("fif "+myrealdest+"\n")
6422
							outfile.write("fif "+myrealdest+"\n")
6408
					else:
6423
					else:
6409
						sys.exit(1)
6424
						sys.exit(1)
6410
				writemsg_stdout(zing+" "+mydest+"\n")
6425
				writemsg(zing+" "+mydest+"\n", fd=self.logfd)
6411
6426
6412
	def merge(self, mergeroot, inforoot, myroot, myebuild=None, cleanup=0,
6427
	def merge(self, mergeroot, inforoot, myroot, myebuild=None, cleanup=0,
6413
		mydbapi=None, prev_mtimes=None):
6428
		mydbapi=None, prev_mtimes=None):
Lines 6490-6496 Link Here
6490
		os.unlink(settings["PORTAGE_TMPDIR"]+"/portage/"+mypkg+"/temp/environment")
6505
		os.unlink(settings["PORTAGE_TMPDIR"]+"/portage/"+mypkg+"/temp/environment")
6491
	os.chdir(origdir)
6506
	os.chdir(origdir)
6492
6507
6493
def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes=None):
6508
def pkgmerge(mytbz2, myroot, mysettings, mydbapi=None, vartree=None, prev_mtimes=None, logfile=None):
6494
	"""will merge a .tbz2 file, returning a list of runtime dependencies
6509
	"""will merge a .tbz2 file, returning a list of runtime dependencies
6495
		that must be satisfied, or None if there was a merge error.	This
6510
		that must be satisfied, or None if there was a merge error.	This
6496
		code assumes the package exists."""
6511
		code assumes the package exists."""
Lines 6547-6553 Link Here
6547
	# auto-unmerge, virtual/provides updates, etc.
6562
	# auto-unmerge, virtual/provides updates, etc.
6548
	mysettings.load_infodir(infloc)
6563
	mysettings.load_infodir(infloc)
6549
	mylink = dblink(mycat, mypkg, myroot, mysettings, vartree=vartree,
6564
	mylink = dblink(mycat, mypkg, myroot, mysettings, vartree=vartree,
6550
		treetype="bintree")
6565
		treetype="bintree", logfile=logfile)
6551
	mylink.merge(pkgloc, infloc, myroot, myebuild, cleanup=1, mydbapi=mydbapi,
6566
	mylink.merge(pkgloc, infloc, myroot, myebuild, cleanup=1, mydbapi=mydbapi,
6552
		prev_mtimes=prev_mtimes)
6567
		prev_mtimes=prev_mtimes)
6553
6568
(-)portage-2.1.1.orig/pym/portage_exec.py (-5 / +13 lines)
Lines 100-106 Link Here
100
100
101
def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False,
101
def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False,
102
          uid=None, gid=None, groups=None, umask=None, logfile=None,
102
          uid=None, gid=None, groups=None, umask=None, logfile=None,
103
          path_lookup=True):
103
          path_lookup=True, quiet=True):
104
104
105
	# mycommand is either a str or a list
105
	# mycommand is either a str or a list
106
	if isinstance(mycommand, str):
106
	if isinstance(mycommand, str):
Lines 123-142 Link Here
123
	# mypids will hold the pids of all processes created.
123
	# mypids will hold the pids of all processes created.
124
	mypids = []
124
	mypids = []
125
125
126
	if logfile:
126
	if logfile and not quiet:
127
		# Using a log file requires that stdout and stderr
127
		# Using a log file requires that stdout and stderr
128
		# are assigned to the process we're running.
128
		# are assigned to the process we're running.
129
		if 1 not in fd_pipes or 2 not in fd_pipes:
129
		if 1 not in fd_pipes or 2 not in fd_pipes:
130
			raise ValueError(fd_pipes)
130
			raise ValueError(fd_pipes)
131
131
132
132
		# Create a pipe
133
		# Create a pipe
133
		(pr, pw) = os.pipe()
134
		(pr, pw) = os.pipe()
134
135
135
		# Create a tee process, giving it our stdout and stderr
136
		# Create a tee process, giving it our stdout and stderr
136
		# as well as the read end of the pipe.
137
		# as well as the read end of the pipe.
137
		mypids.extend(spawn(('tee', '-i', '-a', logfile),
138
		mypids.extend(spawn(('tee', '-i', '-a', logfile),
138
		              returnpid=True, fd_pipes={0:pr,
139
				returnpid=True, fd_pipes={0:pr,
139
		              1:fd_pipes[1], 2:fd_pipes[2]}))
140
				1:fd_pipes[1], 2:fd_pipes[2]}))
140
141
141
		# We don't need the read end of the pipe, so close it.
142
		# We don't need the read end of the pipe, so close it.
142
		os.close(pr)
143
		os.close(pr)
Lines 148-153 Link Here
148
	pid = os.fork()
149
	pid = os.fork()
149
150
150
	if not pid:
151
	if not pid:
152
		if quiet and logfile:
153
			sys.stdout.close()
154
			sys.stderr.close()
155
			sys.stdout = open(logfile, "a")
156
			sys.stderr = sys.stdout
157
			os.dup2(sys.stdout.fileno(), fd_pipes[1])
158
			os.dup2(sys.stderr.fileno(), fd_pipes[2])
151
		try:
159
		try:
152
			_exec(binary, mycommand, opt_name, fd_pipes,
160
			_exec(binary, mycommand, opt_name, fd_pipes,
153
			      env, gid, groups, uid, umask)
161
			      env, gid, groups, uid, umask)
Lines 164-170 Link Here
164
172
165
	# If we started a tee process the write side of the pipe is no
173
	# If we started a tee process the write side of the pipe is no
166
	# longer needed, so close it.
174
	# longer needed, so close it.
167
	if logfile:
175
	if logfile and not quiet:
168
		os.close(pw)
176
		os.close(pw)
169
177
170
	# If the caller wants to handle cleaning up the processes, we tell
178
	# If the caller wants to handle cleaning up the processes, we tell

Return to bug 147516