1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
#!/usr/bin/python
from yum.transactioninfo import TransactionData, TransactionMember
from yum.Errors import YumBaseError
import urlparse
urlparse.uses_fragment.append('media')
WHITE = 0
GREY = 1
BLACK = 2
class SortableTransactionData(TransactionData):
def __init__(self):
self._sorted = []
self.path = []
self.loops = []
self.changed = True
TransactionData.__init__(self)
def _visit(self, txmbr):
self.path.append(txmbr.name)
txmbr.sortColour = GREY
for (relation, reltype) in txmbr.relatedto:
if reltype != 'dependson':
continue
vertex = self.getMembers(pkgtup=relation)[0]
if vertex.sortColour == GREY:
self._doLoop(vertex.name)
if vertex.sortColour == WHITE:
self._visit(vertex)
txmbr.sortColour = BLACK
self._sorted.insert(0, txmbr.pkgtup)
def _doLoop(self, name):
self.path.append(name)
loop = self.path[self.path.index(self.path[-1]):]
if len(loop) > 2:
self.loops.append(loop)
def add(self, txmember):
txmember.sortColour = WHITE
TransactionData.add(self, txmember)
self.changed = True
def remove(self, pkgtup):
TransactionData.remove(self, pkgtup)
self.changed = True
def sort(self):
if self._sorted and not self.changed:
return self._sorted
self._sorted = []
self.changed = False
# loop over all members
for txmbr in self.getMembers():
if txmbr.sortColour == WHITE:
self.path = [ ]
self._visit(txmbr)
self._sorted.reverse()
return self._sorted
class SplitMediaTransactionData(SortableTransactionData):
def __init__(self):
SortableTransactionData.__init__(self)
self.reqmedia = {}
self.curmedia = 0
def __getMedia(self, po):
try:
uri = po.returnSimple('basepath')
(scheme, netloc, path, query, fragid) = urlparse.urlsplit(uri)
if scheme != "media" or not fragid:
return 0
else:
return int(fragid)
except (KeyError, AttributeError):
return 0
def getMembers(self, pkgtup=None):
if not self.curmedia:
return TransactionData.getMembers(self, pkgtup)
if pkgtup is None:
returnlist = []
for key in self.reqmedia[self.curmedia]:
returnlist.extend(self.pkgdict[key])
return returnlist
if self.reqmedia[self.curmedia].has_key(pkgtup):
return self.pkgdict[pkgtup]
else:
return []
def add(self, txmember):
id = self.__getMedia(txmember.po)
if id:
if id not in self.reqmedia.keys():
self.reqmedia[id] = [ txmember.pkgtup ]
else:
self.reqmedia[id].append(txmember.pkgtup)
SortableTransactionData.add(self, txmember)
def remove(self, pkgtup):
if not self.pkgdict.has_key(pkgtup):
return
txmembers = self.pkgdict[pkgtup]
if len(txmembers) > 0:
for txmbr in txmembers:
id = self.__getMedia(txmbr.po)
if id:
self.reqmedia[id].remove(pktup)
del txmbr
SortableTransactionData.remove(self, pkgtup)
class TransactionConstraintMetError(YumBaseError):
def __init__(self, args=None):
YumBaseError.__init__(self)
self.args = args
class ConstrainedTransactionData(SortableTransactionData):
def __init__(self, constraint=lambda txmbr: False):
"""Arbitrary constraint on transaction member
@param constraint form:
function(self, TransactionMember)
constraint function returns True/False.
@type constraint function"""
self.constraint = constraint
SortableTransactionData.__init__(self)
def add(self, txmbr):
"""@param txmbr: TransactionMember
@raise TransactionConstraintMetError: if
constraint returns True when adding"""
if self.constraint and not self.constraint(txmbr):
SortableTransactionData.add(self, txmbr)
else:
raise TransactionConstraintMetError("Constraint met")
|