]>
Commit | Line | Data |
---|---|---|
9137135a MT |
1 | #!/usr/bin/python |
2 | ||
f6e6ff79 MT |
3 | import os.path |
4 | ||
2c909128 MT |
5 | from . import base |
6 | from . import logs | |
9137135a | 7 | |
e459cbba MT |
8 | from .decorators import * |
9 | ||
9137135a | 10 | class Repositories(base.Object): |
e459cbba MT |
11 | def _get_repository(self, query, *args): |
12 | res = self.db.get(query, *args) | |
9137135a | 13 | |
e459cbba MT |
14 | if res: |
15 | return Repository(self.backend, res.id, data=res) | |
9137135a | 16 | |
e459cbba MT |
17 | def _get_repositories(self, query, *args): |
18 | res = self.db.query(query, *args) | |
19 | ||
20 | for row in res: | |
21 | yield Repository(self.backend, row.id, data=row) | |
22 | ||
23 | def __iter__(self): | |
24 | repositories = self._get_repositories("SELECT * FROM repositories \ | |
25 | ORDER BY distro_id, name") | |
9137135a | 26 | |
e459cbba MT |
27 | return iter(repositories) |
28 | ||
29 | def get_by_id(self, repo_id): | |
30 | return self._get_repository("SELECT * FROM repositories \ | |
31 | WHERE id = %s", repo_id) | |
9137135a MT |
32 | |
33 | def get_needs_update(self, limit=None): | |
34 | query = "SELECT id FROM repositories WHERE needs_update = 'Y'" | |
35 | query += " ORDER BY last_update ASC" | |
36 | ||
37 | # Append limit if any | |
38 | if limit: | |
39 | query += " LIMIT %d" % limit | |
40 | ||
41 | repos = self.db.query(query) | |
42 | ||
43 | return [Repository(self.pakfire, r.id) for r in repos] | |
44 | ||
f6e6ff79 MT |
45 | def get_history(self, limit=None, offset=None, build=None, repo=None, user=None): |
46 | query = "SELECT * FROM repositories_history" | |
47 | args = [] | |
9137135a | 48 | |
f6e6ff79 | 49 | query += " ORDER BY time DESC" |
9137135a | 50 | |
f6e6ff79 MT |
51 | if limit: |
52 | if offset: | |
53 | query += " LIMIT %s,%s" | |
54 | args += [offset, limit,] | |
55 | else: | |
56 | query += " LIMIT %s" | |
57 | args += [limit,] | |
9137135a | 58 | |
f6e6ff79 MT |
59 | entries = [] |
60 | for entry in self.db.query(query, *args): | |
61 | entry = logs.RepositoryLogEntry(self.pakfire, entry) | |
62 | entries.append(entry) | |
9137135a | 63 | |
f6e6ff79 | 64 | return entries |
9137135a MT |
65 | |
66 | ||
67 | class Repository(base.Object): | |
9fa1787c | 68 | def __init__(self, pakfire, id, data=None): |
9137135a MT |
69 | base.Object.__init__(self, pakfire) |
70 | self.id = id | |
71 | ||
f6e6ff79 | 72 | # Cache. |
9fa1787c | 73 | self._data = data |
f6e6ff79 MT |
74 | self._next = None |
75 | self._prev = None | |
76 | self._key = None | |
77 | self._distro = None | |
78 | ||
79 | @property | |
80 | def data(self): | |
81 | if self._data is None: | |
9fa1787c | 82 | self._data = self.db.get("SELECT * FROM repositories WHERE id = %s", self.id) |
f6e6ff79 MT |
83 | |
84 | return self._data | |
9137135a MT |
85 | |
86 | def __cmp__(self, other): | |
f6e6ff79 MT |
87 | if other is None: |
88 | return 1 | |
89 | ||
90 | if self.id == other.id: | |
9137135a MT |
91 | return 0 |
92 | ||
f6e6ff79 MT |
93 | elif self.id == other.parent_id: |
94 | return 1 | |
95 | ||
96 | elif self.parent_id == other.id: | |
9137135a MT |
97 | return -1 |
98 | ||
f6e6ff79 | 99 | return 1 |
9137135a MT |
100 | |
101 | def next(self): | |
f6e6ff79 MT |
102 | if self._next is None: |
103 | repo = self.db.get("SELECT id FROM repositories \ | |
104 | WHERE parent_id = %s LIMIT 1", self.id) | |
9137135a | 105 | |
f6e6ff79 MT |
106 | if not repo: |
107 | return | |
9137135a | 108 | |
f6e6ff79 | 109 | self._next = Repository(self.pakfire, repo.id) |
9137135a | 110 | |
f6e6ff79 MT |
111 | return self._next |
112 | ||
113 | def prev(self): | |
114 | if not self.parent_id: | |
115 | return | |
116 | ||
117 | if self._prev is None: | |
118 | self._prev = Repository(self.pakfire, self.parent_id) | |
119 | ||
120 | return self._prev | |
9137135a MT |
121 | |
122 | @property | |
f6e6ff79 MT |
123 | def parent(self): |
124 | return self.prev() | |
9137135a MT |
125 | |
126 | @classmethod | |
f6e6ff79 | 127 | def create(cls, pakfire, distro, name, description): |
9137135a MT |
128 | id = pakfire.db.execute("INSERT INTO repositories(distro_id, name, description)" |
129 | " VALUES(%s, %s, %s)", distro.id, name, description) | |
130 | ||
131 | return cls(pakfire, id) | |
132 | ||
e459cbba | 133 | @lazy_property |
9137135a | 134 | def distro(self): |
e459cbba | 135 | return self.backend.distros.get_by_id(self.data.distro_id) |
9137135a MT |
136 | |
137 | @property | |
138 | def info(self): | |
139 | return { | |
140 | "id" : self.id, | |
141 | "distro" : self.distro.info, | |
142 | "name" : self.name, | |
143 | "arches" : self.arches, | |
144 | } | |
145 | ||
146 | @property | |
f6e6ff79 MT |
147 | def url(self): |
148 | url = os.path.join( | |
149 | self.settings.get("repository_baseurl", "http://pakfire.ipfire.org/repositories/"), | |
150 | self.distro.identifier, | |
151 | self.identifier, | |
152 | "%{arch}" | |
153 | ) | |
154 | ||
155 | return url | |
156 | ||
157 | @property | |
158 | def mirrorlist(self): | |
159 | url = os.path.join( | |
160 | self.settings.get("mirrorlist_baseurl", "https://pakfire.ipfire.org/"), | |
161 | "distro", self.distro.identifier, | |
162 | "repo", self.identifier, | |
163 | "mirrorlist?arch=%{arch}" | |
164 | ) | |
165 | ||
166 | return url | |
167 | ||
168 | def get_conf(self): | |
169 | prioritymap = { | |
170 | "stable" : 500, | |
171 | "unstable" : 200, | |
172 | "testing" : 100, | |
173 | } | |
174 | ||
175 | try: | |
176 | priority = prioritymap[self.type] | |
177 | except KeyError: | |
178 | priority = None | |
179 | ||
180 | lines = [ | |
181 | "[repo:%s]" % self.identifier, | |
182 | "description = %s - %s" % (self.distro.name, self.summary), | |
183 | "enabled = 1", | |
184 | "baseurl = %s" % self.url, | |
185 | "mirrors = %s" % self.mirrorlist, | |
186 | ] | |
187 | ||
188 | if priority: | |
189 | lines.append("priority = %s" % priority) | |
190 | ||
191 | return "\n".join(lines) | |
9137135a MT |
192 | |
193 | @property | |
194 | def name(self): | |
195 | return self.data.name | |
196 | ||
197 | @property | |
f6e6ff79 MT |
198 | def identifier(self): |
199 | return self.name.lower() | |
9137135a MT |
200 | |
201 | @property | |
f6e6ff79 MT |
202 | def type(self): |
203 | return self.data.type | |
9137135a MT |
204 | |
205 | @property | |
f6e6ff79 MT |
206 | def summary(self): |
207 | lines = self.description.splitlines() | |
9137135a | 208 | |
f6e6ff79 MT |
209 | if lines: |
210 | return lines[0] | |
9137135a | 211 | |
f6e6ff79 | 212 | return "N/A" |
9137135a | 213 | |
f6e6ff79 MT |
214 | @property |
215 | def description(self): | |
216 | return self.data.description or "" | |
9137135a | 217 | |
f6e6ff79 MT |
218 | @property |
219 | def parent_id(self): | |
220 | return self.data.parent_id | |
9137135a MT |
221 | |
222 | @property | |
f6e6ff79 MT |
223 | def key(self): |
224 | if not self.data.key_id: | |
225 | return | |
9137135a | 226 | |
f6e6ff79 MT |
227 | if self._key is None: |
228 | self._key = self.pakfire.keys.get_by_id(self.data.key_id) | |
229 | assert self._key | |
9137135a | 230 | |
f6e6ff79 | 231 | return self._key |
9137135a | 232 | |
f6e6ff79 MT |
233 | @property |
234 | def arches(self): | |
235 | return self.distro.arches | |
236 | ||
237 | @property | |
238 | def mirrored(self): | |
239 | return self.data.mirrored == "Y" | |
9137135a | 240 | |
f6e6ff79 MT |
241 | def get_enabled_for_builds(self): |
242 | return self.data.enabled_for_builds == "Y" | |
9137135a | 243 | |
f6e6ff79 MT |
244 | def set_enabled_for_builds(self, state): |
245 | if state: | |
246 | state = "Y" | |
247 | else: | |
248 | state = "N" | |
9137135a | 249 | |
f6e6ff79 MT |
250 | self.db.execute("UPDATE repositories SET enabled_for_builds = %s WHERE id = %s", |
251 | state, self.id) | |
9137135a | 252 | |
f6e6ff79 MT |
253 | if self._data: |
254 | self._data["enabled_for_builds"] = state | |
255 | ||
256 | enabled_for_builds = property(get_enabled_for_builds, set_enabled_for_builds) | |
9137135a MT |
257 | |
258 | @property | |
f6e6ff79 MT |
259 | def score_needed(self): |
260 | return self.data.score_needed | |
9137135a MT |
261 | |
262 | @property | |
f6e6ff79 MT |
263 | def time_min(self): |
264 | return self.data.time_min | |
9137135a MT |
265 | |
266 | @property | |
f6e6ff79 MT |
267 | def time_max(self): |
268 | return self.data.time_max | |
9137135a | 269 | |
f6e6ff79 MT |
270 | def _log_build(self, action, build, from_repo=None, to_repo=None, user=None): |
271 | user_id = None | |
272 | if user: | |
273 | user_id = user.id | |
9137135a | 274 | |
f6e6ff79 MT |
275 | from_repo_id = None |
276 | if from_repo: | |
277 | from_repo_id = from_repo.id | |
9137135a | 278 | |
f6e6ff79 MT |
279 | to_repo_id = None |
280 | if to_repo: | |
281 | to_repo_id = to_repo.id | |
9137135a | 282 | |
f6e6ff79 MT |
283 | self.db.execute("INSERT INTO repositories_history(action, build_id, from_repo_id, to_repo_id, user_id, time) \ |
284 | VALUES(%s, %s, %s, %s, %s, NOW())", action, build.id, from_repo_id, to_repo_id, user_id) | |
9137135a | 285 | |
f6e6ff79 MT |
286 | def add_build(self, build, user=None, log=True): |
287 | self.db.execute("INSERT INTO repositories_builds(repo_id, build_id, time_added)" | |
288 | " VALUES(%s, %s, NOW())", self.id, build.id) | |
9137135a | 289 | |
f6e6ff79 MT |
290 | # Update bug status. |
291 | build._update_bugs_helper(self) | |
9137135a | 292 | |
f6e6ff79 MT |
293 | if log: |
294 | self._log_build("added", build, to_repo=self, user=user) | |
9137135a | 295 | |
f6e6ff79 MT |
296 | def rem_build(self, build, user=None, log=True): |
297 | self.db.execute("DELETE FROM repositories_builds \ | |
298 | WHERE repo_id = %s AND build_id = %s", self.id, build.id) | |
9137135a | 299 | |
f6e6ff79 MT |
300 | if log: |
301 | self._log_build("removed", build, from_repo=self, user=user) | |
9137135a | 302 | |
f6e6ff79 MT |
303 | def move_build(self, build, to_repo, user=None, log=True): |
304 | self.db.execute("UPDATE repositories_builds SET repo_id = %s, time_added = NOW() \ | |
305 | WHERE repo_id = %s AND build_id = %s", to_repo.id, self.id, build.id) | |
9137135a | 306 | |
f6e6ff79 MT |
307 | # Update bug status. |
308 | build._update_bugs_helper(to_repo) | |
9137135a | 309 | |
f6e6ff79 MT |
310 | if log: |
311 | self._log_build("moved", build, from_repo=self, to_repo=to_repo, | |
312 | user=user) | |
9137135a | 313 | |
f6e6ff79 MT |
314 | def build_count(self): |
315 | query = self.db.get("SELECT COUNT(*) AS count FROM repositories_builds \ | |
316 | WHERE repo_id = %s", self.id) | |
9137135a | 317 | |
f6e6ff79 MT |
318 | if query: |
319 | return query.count | |
9137135a | 320 | |
f6e6ff79 MT |
321 | def get_builds(self, limit=None, offset=None): |
322 | query = "SELECT build_id AS id FROM repositories_builds \ | |
323 | WHERE repo_id = %s ORDER BY time_added DESC" | |
324 | args = [self.id,] | |
9137135a | 325 | |
f6e6ff79 MT |
326 | if limit: |
327 | if offset: | |
328 | query += " LIMIT %s,%s" | |
329 | args += [offset, limit,] | |
330 | else: | |
331 | query += " LIMIT %s" | |
332 | args += [limit,] | |
333 | ||
334 | _builds = [] | |
335 | for build in self.db.query(query, *args): | |
2c909128 | 336 | build = self.pakfire.builds.get_by_id(build.id) |
f6e6ff79 MT |
337 | build._repo = self |
338 | ||
339 | _builds.append(build) | |
340 | ||
341 | return _builds | |
342 | ||
83be3106 | 343 | def _get_packages(self, arch): |
f6e6ff79 | 344 | if arch.name == "src": |
83be3106 | 345 | pkgs = self.db.query("SELECT packages.id AS id, packages.path AS path FROM packages \ |
f6e6ff79 MT |
346 | JOIN builds ON builds.pkg_id = packages.id \ |
347 | JOIN repositories_builds ON builds.id = repositories_builds.build_id \ | |
348 | WHERE packages.arch = %s AND repositories_builds.repo_id = %s", | |
22b715d7 | 349 | arch.name, self.id) |
9137135a | 350 | |
f6e6ff79 MT |
351 | else: |
352 | noarch = self.pakfire.arches.get_by_name("noarch") | |
353 | assert noarch | |
9137135a | 354 | |
83be3106 | 355 | pkgs = self.db.query("SELECT packages.id AS id, packages.path AS path FROM packages \ |
f6e6ff79 MT |
356 | JOIN jobs_packages ON jobs_packages.pkg_id = packages.id \ |
357 | JOIN jobs ON jobs_packages.job_id = jobs.id \ | |
358 | JOIN builds ON builds.id = jobs.build_id \ | |
359 | JOIN repositories_builds ON builds.id = repositories_builds.build_id \ | |
22b715d7 | 360 | WHERE (jobs.arch = %s OR jobs.arch = %s) AND \ |
f6e6ff79 | 361 | repositories_builds.repo_id = %s", |
22b715d7 | 362 | arch.name, noarch.name, self.id) |
9137135a | 363 | |
83be3106 MT |
364 | return pkgs |
365 | ||
366 | def get_packages(self, arch): | |
2c909128 | 367 | pkgs = [self.pakfire.packages.get_by_id(p.id) for p in self._get_packages(arch)] |
83be3106 MT |
368 | pkgs.sort() |
369 | ||
370 | return pkgs | |
371 | ||
372 | def get_paths(self, arch): | |
373 | paths = [p.path for p in self._get_packages(arch)] | |
374 | paths.sort() | |
375 | ||
376 | return paths | |
f6e6ff79 MT |
377 | |
378 | @property | |
379 | def packages(self): | |
380 | return self.get_packages() | |
9137135a | 381 | |
f6e6ff79 MT |
382 | def get_unpushed_builds(self): |
383 | query = self.db.query("SELECT build_id FROM repositories_builds \ | |
384 | WHERE repo_id = %s AND \ | |
385 | time_added > (SELECT last_update FROM repositories WHERE id = %s)", | |
386 | self.id, self.id) | |
387 | ||
388 | ret = [] | |
389 | for row in query: | |
2c909128 | 390 | b = self.pakfire.builds.get_by_id(row.build_id) |
f6e6ff79 MT |
391 | ret.append(b) |
392 | ||
393 | return ret | |
394 | ||
395 | def get_obsolete_builds(self): | |
396 | #query = self.db.query("SELECT build_id AS id FROM repositories_builds \ | |
397 | # JOIN builds ON repositories.build_id = builds.id \ | |
398 | # WHERE repositories_builds.repo_id = %s AND builds.state = 'obsolete'", | |
399 | # self.id) | |
400 | # | |
401 | #ret = [] | |
402 | #for row in query: | |
403 | # b = builds.Build(self.pakfire, row.id) | |
404 | # ret.append(b) | |
405 | # | |
406 | #return ret | |
407 | return self.pakfire.builds.get_obsolete(self) | |
408 | ||
409 | def needs_update(self): | |
410 | if self.get_unpushed_builds: | |
9137135a MT |
411 | return True |
412 | ||
9137135a MT |
413 | return False |
414 | ||
f6e6ff79 MT |
415 | def updated(self): |
416 | self.db.execute("UPDATE repositories SET last_update = NOW() \ | |
417 | WHERE id = %s", self.id) | |
9137135a | 418 | |
f6e6ff79 MT |
419 | def get_history(self, **kwargs): |
420 | kwargs.update({ | |
421 | "repo" : self, | |
422 | }) | |
9137135a | 423 | |
f6e6ff79 | 424 | return self.pakfire.repos.get_history(**kwargs) |
9137135a | 425 | |
f6e6ff79 | 426 | def get_build_times(self): |
f6e6ff79 | 427 | times = [] |
e459cbba MT |
428 | for arch in self.arches: |
429 | time = self.db.get("SELECT SUM(jobs.time_finished - jobs.time_started) AS time FROM jobs \ | |
f6e6ff79 MT |
430 | JOIN builds ON builds.id = jobs.build_id \ |
431 | JOIN repositories_builds ON builds.id = repositories_builds.build_id \ | |
e459cbba | 432 | WHERE (jobs.arch = %s OR jobs.arch = %s) AND \ |
a577f40c | 433 | jobs.type = 'build' AND \ |
e459cbba | 434 | repositories_builds.repo_id = %s", arch, "noarch", self.id) |
f6e6ff79 | 435 | |
e459cbba | 436 | times.append((arch, time.time.total_seconds())) |
f6e6ff79 MT |
437 | |
438 | return times | |
9137135a | 439 | |
9137135a | 440 | |
f6e6ff79 MT |
441 | class RepositoryAux(base.Object): |
442 | def __init__(self, pakfire, id): | |
443 | base.Object.__init__(self, pakfire) | |
444 | ||
445 | self.id = id | |
446 | ||
447 | # Cache. | |
448 | self._data = None | |
449 | self._distro = None | |
9137135a | 450 | |
f6e6ff79 MT |
451 | @property |
452 | def data(self): | |
453 | if self._data is None: | |
454 | self._data = self.db.get("SELECT * FROM repositories_aux WHERE id = %s", self.id) | |
455 | assert self._data | |
456 | ||
457 | return self._data | |
458 | ||
459 | @property | |
460 | def name(self): | |
461 | return self.data.name | |
462 | ||
463 | @property | |
464 | def description(self): | |
465 | return self.data.description or "" | |
466 | ||
467 | @property | |
468 | def url(self): | |
469 | return self.data.url | |
470 | ||
471 | @property | |
472 | def identifier(self): | |
473 | return self.name.lower() | |
474 | ||
475 | @property | |
476 | def distro(self): | |
477 | if self._distro is None: | |
478 | self._distro = self.pakfire.distros.get_by_id(self.data.distro_id) | |
479 | assert self._distro | |
480 | ||
481 | return self._distro | |
482 | ||
483 | def get_conf(self): | |
484 | lines = [ | |
485 | "[repo:%s]" % self.identifier, | |
486 | "description = %s - %s" % (self.distro.name, self.name), | |
487 | "enabled = 1", | |
488 | "baseurl = %s" % self.url, | |
489 | "priority = 0", | |
490 | ] | |
491 | ||
492 | return "\n".join(lines) |