1 |
On Fri, Mar 14, 2014 at 10:35 PM, Pavel Kazakov <nullishzero@g.o>wrote: |
2 |
|
3 |
> On 03/13/14 15:09, Alec Warner wrote: |
4 |
> > |
5 |
> > |
6 |
> > |
7 |
> > On Wed, Mar 12, 2014 at 11:10 PM, Pavel Kazakov |
8 |
> > <nullishzero@g.o <mailto:nullishzero@g.o>> wrote: |
9 |
> > |
10 |
> > --- |
11 |
> > pym/portage/emaint/main.py | 6 +- |
12 |
> > |
13 |
> |
14 |
> ... |
15 |
> |
16 |
> > Perhaps add an __iter__ function to TrackingFile, that implicitly |
17 |
> > calls load? |
18 |
> > |
19 |
> > Then this can be: |
20 |
> > for pkg, mtime in self._tracking_file: |
21 |
> > |
22 |
> > ? |
23 |
> > |
24 |
> > Just a thought. |
25 |
> |
26 |
> That's actually a neat idea. Going to do it. |
27 |
> |
28 |
> > |
29 |
> > |
30 |
> > + for pkg, mtime in self._tracking_file.load().items(): |
31 |
> > + if pkg not in failed_pkgs: |
32 |
> > + failed_pkgs[pkg] = mtime |
33 |
> > + return failed_pkgs |
34 |
> > + |
35 |
> > + |
36 |
> > + def _remove_failed_dirs(self, failed_pkgs): |
37 |
> > + """ |
38 |
> > + Remove the directories of packages that failed to |
39 |
> > merge. |
40 |
> > + |
41 |
> > + @param failed_pkgs: failed packages whose |
42 |
> > directories to remove |
43 |
> > + @type failed_pkg: dict |
44 |
> > + """ |
45 |
> > + for failed_pkg in failed_pkgs: |
46 |
> > + pkg_path = os.path.join(self._vardb_path, |
47 |
> > failed_pkg) |
48 |
> > + # delete failed merge directory if it |
49 |
> > exists (it might not exist |
50 |
> > + # if loaded from tracking file) |
51 |
> > + if os.path.exists(pkg_path): |
52 |
> > + shutil.rmtree(pkg_path) |
53 |
> > + # TODO: try removing package contents to |
54 |
> > prevent orphaned |
55 |
> > + # files |
56 |
> > |
57 |
> > |
58 |
> > I don't get this TODO, can you elaborate? |
59 |
> |
60 |
> Right now the current code deletes only the failed merge directory (e.g. |
61 |
> /var/db/pkg/app-misc/-MERGING-lsx-0.1/). |
62 |
> |
63 |
> In /var/db/pkg/app-misc/-MERGING-lsx-0.1/, there should be a file called |
64 |
> CONTENTS that records the package contents (e.g. obj |
65 |
> /usr/bin/lsx-suckless 478333aa1cb7761bc8e3a400cbd976ab 1394688298). |
66 |
> However, during a failed merge, the CONTENTS file may not be there or |
67 |
> may be corrupt, so my code doesn't handle removing the contents right |
68 |
> now, only the failed merge directory. |
69 |
> |
70 |
> Any suggestions for better wording? |
71 |
> |
72 |
> |
73 |
an upcase CONTENTS, or just talk about vdb or metadata specifically. |
74 |
|
75 |
|
76 |
|
77 |
> > |
78 |
> > |
79 |
> > + |
80 |
> > + |
81 |
> > + def _get_pkg_atoms(self, failed_pkgs, pkg_atoms, pkg_dne): |
82 |
> > + """ |
83 |
> > + Get the package atoms for the specified failed |
84 |
> > packages. |
85 |
> > + |
86 |
> > + @param failed_pkgs: failed packages to iterate |
87 |
> > + @type failed_pkgs: dict |
88 |
> > + @param pkg_atoms: append package atoms to this set |
89 |
> > + @type pkg_atoms: set |
90 |
> > + @param pkg_dne: append any packages atoms that are |
91 |
> > invalid to this set |
92 |
> > + @type pkg_dne: set |
93 |
> > |
94 |
> > |
95 |
> > Not following what dne means. |
96 |
> |
97 |
> How about pkg_invalid_entries? And I can change the comment to '@param |
98 |
> pkg_invalid_entries: append any packages that are invalid to this set' |
99 |
> |
100 |
> After looking at the function more, I think it might make sense to |
101 |
> instead return pkg_atoms and pkg_invalid_entries as a tuple, instead of |
102 |
> having the calling code pass them in. |
103 |
> |
104 |
|
105 |
sgtm |
106 |
|
107 |
> |
108 |
> > |
109 |
> > |
110 |
> > + """ |
111 |
> > + |
112 |
> > + emerge_config = load_emerge_config() |
113 |
> > + portdb = |
114 |
> > emerge_config.target_config.trees['porttree'].dbapi |
115 |
> > + for failed_pkg in failed_pkgs: |
116 |
> > + # validate pkg name |
117 |
> > + pkg_name = '%s' % |
118 |
> > failed_pkg.replace(MERGING_IDENTIFIER, '') |
119 |
> > + pkg_atom = '=%s' % pkg_name |
120 |
> > + |
121 |
> > + if not isvalidatom(pkg_atom): |
122 |
> > + pkg_dne.append( "'%s' is an |
123 |
> > invalid package atom." % pkg_atom) |
124 |
> > + if not portdb.cpv_exists(pkg_name): |
125 |
> > + pkg_dne.append( "'%s' does not |
126 |
> > exist in the portage tree." |
127 |
> > + % pkg_name) |
128 |
> > + pkg_atoms.add(pkg_atom) |
129 |
> > + |
130 |
> > + |
131 |
> > + def _emerge_pkg_atoms(self, module_output, pkg_atoms): |
132 |
> > + """ |
133 |
> > + Emerge the specified packages atoms. |
134 |
> > + |
135 |
> > + @param module_output: output will be written to |
136 |
> > + @type module_output: Class |
137 |
> > + @param pkg_atoms: packages atoms to emerge |
138 |
> > + @type pkg_atoms: set |
139 |
> > + @rtype: list |
140 |
> > + @return: List of results |
141 |
> > + """ |
142 |
> > + # TODO: rewrite code to use portage's APIs instead |
143 |
> > of a subprocess |
144 |
> > + env = { |
145 |
> > + "FEATURES" : "-collision-detect |
146 |
> > -protect-owned", |
147 |
> > + "PATH" : os.environ["PATH"] |
148 |
> > + } |
149 |
> > + emerge_cmd = ( |
150 |
> > + portage._python_interpreter, |
151 |
> > + '-b', |
152 |
> > + os.path.join(PORTAGE_BIN_PATH, 'emerge'), |
153 |
> > + '--quiet', |
154 |
> > + '--oneshot', |
155 |
> > + '--complete-graph=y' |
156 |
> > + ) |
157 |
> > + results = [] |
158 |
> > + msg = 'Re-Emerging packages that failed to |
159 |
> merge...\n' |
160 |
> > + if module_output: |
161 |
> > + module_output.write(msg) |
162 |
> > + else: |
163 |
> > + module_output = subprocess.PIPE |
164 |
> > + results.append(msg) |
165 |
> > + proc = subprocess.Popen(emerge_cmd + |
166 |
> > tuple(pkg_atoms), env=env, |
167 |
> > + stdout=module_output, stderr=sys.stderr) |
168 |
> > + output = proc.communicate()[0] |
169 |
> > |
170 |
> > |
171 |
> > This seems sort of weird, perhaps: |
172 |
> > |
173 |
> > output, _ = proc.communicate() |
174 |
> |
175 |
> I'll change it, but in fairness 'proc.communicate()[0]' is how both the |
176 |
> official python documentation and other areas of portage do it ;) |
177 |
> |
178 |
|
179 |
Prefer the existing (foo[0]) style then. I've been writing too much go ;) |
180 |
|
181 |
> |
182 |
> > |
183 |
> > |
184 |
> > + if output: |
185 |
> > + results.append(output) |
186 |
> > + if proc.returncode != os.EX_OK: |
187 |
> > + emerge_status = "Failed to emerge '%s'" % |
188 |
> > (' '.join(pkg_atoms)) |
189 |
> > + else: |
190 |
> > |
191 |
> ... |
192 |
> |
193 |
> I'll incorporate your other changes. |
194 |
> |
195 |
> Regards, |
196 |
> Pavel |
197 |
> |
198 |
> |