1 |
On Wed, Feb 19, 2014 at 12:31 PM, Pavel Kazakov <nullishzero@g.o>wrote: |
2 |
|
3 |
> --- |
4 |
> pym/portage/emaint/modules/merges/__init__.py | 20 ++++++++ |
5 |
> pym/portage/emaint/modules/merges/merges.py | 70 |
6 |
> +++++++++++++++++++++++++++ |
7 |
> 2 files changed, 90 insertions(+) |
8 |
> create mode 100644 pym/portage/emaint/modules/merges/__init__.py |
9 |
> create mode 100644 pym/portage/emaint/modules/merges/merges.py |
10 |
> |
11 |
> diff --git a/pym/portage/emaint/modules/merges/__init__.py |
12 |
> b/pym/portage/emaint/modules/merges/__init__.py |
13 |
> new file mode 100644 |
14 |
> index 0000000..2cd79af |
15 |
> --- /dev/null |
16 |
> +++ b/pym/portage/emaint/modules/merges/__init__.py |
17 |
> @@ -0,0 +1,20 @@ |
18 |
> +# Copyright 2005-2014 Gentoo Foundation |
19 |
> +# Distributed under the terms of the GNU General Public License v2 |
20 |
> + |
21 |
> +"""Scan for failed merges and fix them. |
22 |
> +""" |
23 |
> |
24 |
|
25 |
"""Scan for failed merges fix them.""" |
26 |
|
27 |
|
28 |
> + |
29 |
> + |
30 |
> +module_spec = { |
31 |
> + 'name': 'merges', |
32 |
> + 'description': __doc__, |
33 |
> + 'provides':{ |
34 |
> |
35 |
|
36 |
'module1' ? |
37 |
|
38 |
|
39 |
> + 'module1': { |
40 |
> + 'name': "merges", |
41 |
> + 'class': "MergesHandler", |
42 |
> + 'description': __doc__, |
43 |
> + 'functions': ['check', 'fix',], |
44 |
> + 'func_desc': {} |
45 |
> + } |
46 |
> + } |
47 |
> + } |
48 |
> diff --git a/pym/portage/emaint/modules/merges/merges.py |
49 |
> b/pym/portage/emaint/modules/merges/merges.py |
50 |
> new file mode 100644 |
51 |
> index 0000000..b243082 |
52 |
> --- /dev/null |
53 |
> +++ b/pym/portage/emaint/modules/merges/merges.py |
54 |
> @@ -0,0 +1,70 @@ |
55 |
> +# Copyright 2005-2014 Gentoo Foundation |
56 |
> +# Distributed under the terms of the GNU General Public License v2 |
57 |
> + |
58 |
> +import portage |
59 |
> +from portage import os |
60 |
> +from portage.const import PRIVATE_PATH, VDB_PATH |
61 |
> +from portage.util import writemsg |
62 |
> + |
63 |
> +import shutil |
64 |
> +import sys |
65 |
> + |
66 |
> +if sys.hexversion >= 0x3000000: |
67 |
> + # pylint: disable=W0622 |
68 |
> + long = int |
69 |
> |
70 |
|
71 |
What is this little guy? Can we just do this in a library someplace? |
72 |
|
73 |
|
74 |
> + |
75 |
> +class MergesHandler(object): |
76 |
> + |
77 |
> + short_desc = "Remove failed merges" |
78 |
> + |
79 |
> |
80 |
|
81 |
@staticmethod decorator? |
82 |
|
83 |
> + def name(): |
84 |
> + return "merges" |
85 |
> + name = staticmethod(name) |
86 |
> + |
87 |
> + def __init__(self): |
88 |
> |
89 |
|
90 |
Generally you want to be able to change these later, so you might do |
91 |
something like: |
92 |
|
93 |
def __init__(self, eroot=None, vardb=None, vardb_path=None): |
94 |
self._eroot = error or portage.settings['EROOT'] |
95 |
... and so forth. |
96 |
|
97 |
Also..why can't self._vardb_path be queried from the vardb? |
98 |
|
99 |
|
100 |
> + self._eroot = portage.settings['EROOT'] |
101 |
> + self._vardb = portage.db[self._eroot]["vartree"].dbapi |
102 |
> + self._vardb_path = os.path.join(self._eroot, VDB_PATH) + |
103 |
> os.path.sep |
104 |
> + |
105 |
> + def can_progressbar(self, func): |
106 |
> + return True |
107 |
> + |
108 |
> + def _failed_packages(self, onProgress): |
109 |
> + for cat in os.listdir(self._vardb_path): |
110 |
> |
111 |
os.listdir(os.path.join(...)) ? |
112 |
|
113 |
> + pkgs = os.listdir(self._vardb_path + cat) |
114 |
> + maxval = len(pkgs) |
115 |
> + for i, pkg in enumerate(pkgs): |
116 |
> + if onProgress: |
117 |
> + onProgress(maxval, i+1) |
118 |
> + |
119 |
> + if '-MERGING-' in pkg: |
120 |
> + yield cat + os.path.sep + pkg |
121 |
> + |
122 |
> + def check(self, **kwargs): |
123 |
> + onProgress = kwargs.get('onProgress', None) |
124 |
> + failed_pkgs = [] |
125 |
> + for pkg in self._failed_packages(onProgress): |
126 |
> + failed_pkgs.append(pkg) |
127 |
> + |
128 |
> + errors = ["'%s' failed to merge." % x for x in failed_pkgs] |
129 |
> + return errors |
130 |
> + |
131 |
> + def fix(self, **kwargs): |
132 |
> + onProgress = kwargs.get('onProgress', None) |
133 |
> + tracking_path = os.path.join(self._eroot, PRIVATE_PATH, |
134 |
> 'failed-merges'); |
135 |
> + try: |
136 |
> + with open(tracking_path, 'w') as tracking_file: |
137 |
> |
138 |
|
139 |
is this unicode safe? |
140 |
|
141 |
|
142 |
> + for failed_pkg in |
143 |
> self._failed_packages(onProgress): |
144 |
> + |
145 |
> tracking_file.write(failed_pkg + '\n') |
146 |
> + pkg_path = |
147 |
> self._vardb_path + failed_pkg |
148 |
> |
149 |
|
150 |
os.path.join(...) |
151 |
|
152 |
|
153 |
> + # Delete failed merge |
154 |
> directory |
155 |
> + # XXX: Would be a good |
156 |
> idea to attempt try removing |
157 |
> + # package contents to |
158 |
> prevent orphaned files |
159 |
> |
160 |
|
161 |
# XXX is terrible style. I realize a bunch of code does that, and it is |
162 |
stupid. |
163 |
# use |
164 |
# TODO: foo |
165 |
|
166 |
|
167 |
|
168 |
|
169 |
> + shutil.rmtree(pkg_path) |
170 |
> + # Re-emerge package |
171 |
> |
172 |
+ pkg_name = '=' + |
173 |
> failed_pkg.replace('-MERGING-', '') |
174 |
> + |
175 |
> features='FEATURES="-collision-detect -protect-owned"' |
176 |
> + emerge_cmd="emerge |
177 |
> --verbose --oneshot --complete-graph=y" |
178 |
> + os.system('%s %s %s' % |
179 |
> (features, emerge_cmd, pkg_name)) |
180 |
> |
181 |
|
182 |
This is a security vulnerability :) |
183 |
|
184 |
-A |
185 |
|
186 |
|
187 |
> + except Exception as ex: |
188 |
> + writemsg('Unable to fix failed package: %s' % |
189 |
> str(ex)) |
190 |
> -- |
191 |
> 1.8.3.2 |
192 |
> |
193 |
> |
194 |
> |