]>
Commit | Line | Data |
---|---|---|
83be3106 MT |
1 | #!/usr/bin/python |
2 | ||
3 | import datetime | |
4 | import logging | |
e6fa8404 MT |
5 | import pakfire |
6 | import pakfire.config | |
7 | import shutil | |
8 | import tempfile | |
9 | ||
2c909128 MT |
10 | from .. import builds |
11 | from .. import git | |
83be3106 | 12 | |
2c909128 | 13 | from . import base |
83be3106 | 14 | |
2c909128 | 15 | from ..constants import * |
e6fa8404 | 16 | |
83be3106 MT |
17 | class CheckBuildDependenciesEvent(base.Event): |
18 | # Process them as quickly as possible, but there may be more important events. | |
19 | priority = 3 | |
20 | ||
21 | @property | |
22 | def interval(self): | |
23 | return self.pakfire.settings.get_int("dependency_checker_interval", 30) | |
24 | ||
25 | def run(self): | |
26 | query = self.db.query("SELECT id FROM jobs \ | |
27 | WHERE state = 'new' OR \ | |
28 | (state = 'dependency_error' AND \ | |
9779008c | 29 | time_finished < NOW() - '5 minutes'::interval) \ |
83be3106 MT |
30 | ORDER BY time_finished LIMIT 50") |
31 | ||
32 | for row in query: | |
33 | e = CheckBuildDependencyEvent(self.pakfire, row.id) | |
34 | self.scheduler.add_event(e) | |
35 | ||
36 | ||
37 | class CheckBuildDependencyEvent(base.Event): | |
38 | # Process them as quickly as possible, but there may be more important events. | |
39 | priority = 3 | |
40 | ||
41 | def run(self, job_id): | |
e6fa8404 MT |
42 | self.run_subprocess(self._run, job_id) |
43 | ||
44 | @staticmethod | |
45 | def _run(_pakfire, job_id): | |
83be3106 | 46 | # Get the build job we are working on. |
e6fa8404 | 47 | job = _pakfire.jobs.get_by_id(job_id) |
83be3106 MT |
48 | if not job: |
49 | logging.debug("Job %s does not exist." % job_id) | |
50 | return | |
51 | ||
52 | # Check if the job status has changed in the meanwhile. | |
53 | if not job.state in ("new", "dependency_error", "failed"): | |
54 | logging.warning("Job status has already changed: %s - %s" % (job.name, job.state)) | |
55 | return | |
56 | ||
57 | # Resolve the dependencies. | |
58 | job.resolvdep() | |
59 | ||
60 | ||
e6fa8404 MT |
61 | class DistEvent(base.Event): |
62 | interval = 60 | |
83be3106 MT |
63 | |
64 | first_run = True | |
65 | ||
e6fa8404 | 66 | def run(self): |
83be3106 MT |
67 | if self.first_run: |
68 | self.first_run = False | |
69 | ||
70 | self.process = self.init_repos() | |
71 | ||
e6fa8404 MT |
72 | for commit in self.pakfire.sources.get_pending_commits(): |
73 | commit.state = "running" | |
83be3106 | 74 | |
e6fa8404 | 75 | logging.debug("Processing commit %s: %s" % (commit.revision, commit.subject)) |
83be3106 | 76 | |
e6fa8404 | 77 | # Get the repository of this commit. |
78366294 | 78 | repo = git.Repo(self.pakfire, commit.source) |
83be3106 | 79 | |
e6fa8404 MT |
80 | # Make sure, it is checked out. |
81 | if not repo.cloned: | |
82 | repo.clone() | |
83be3106 | 83 | |
e6fa8404 MT |
84 | # Navigate to the right revision. |
85 | repo.checkout(commit.revision) | |
83be3106 | 86 | |
e6fa8404 MT |
87 | # Get all changed makefiles. |
88 | deleted_files = [] | |
89 | updated_files = [] | |
83be3106 | 90 | |
e6fa8404 MT |
91 | for file in repo.changed_files(commit.revision): |
92 | # Don't care about files that are not a makefile. | |
93 | if not file.endswith(".%s" % MAKEFILE_EXTENSION): | |
94 | continue | |
83be3106 | 95 | |
e6fa8404 MT |
96 | if os.path.exists(file): |
97 | updated_files.append(file) | |
98 | else: | |
99 | deleted_files.append(file) | |
83be3106 | 100 | |
e6fa8404 MT |
101 | e = DistFileEvent(self.pakfire, None, commit.id, updated_files, deleted_files) |
102 | self.scheduler.add_event(e) | |
83be3106 MT |
103 | |
104 | def init_repos(self): | |
e6fa8404 MT |
105 | """ |
106 | Initialize all repositories. | |
107 | """ | |
108 | for source in self.pakfire.sources.get_all(): | |
109 | # Skip those which already have a revision. | |
83be3106 MT |
110 | if source.revision: |
111 | continue | |
112 | ||
e6fa8404 | 113 | # Initialize the repository or and clone it if necessary. |
78366294 | 114 | repo = git.Repo(self.pakfire, source) |
83be3106 MT |
115 | if not repo.cloned: |
116 | repo.clone() | |
117 | ||
e6fa8404 | 118 | # Get a list of all files in the repository. |
83be3106 MT |
119 | files = repo.get_all_files() |
120 | ||
e6fa8404 MT |
121 | for file in [f for f in files if file.endswith(".%s" % MAKEFILE_EXTENSION)]: |
122 | e = DistFileEvent(self.pakfire, source.id, None, [file,], []) | |
123 | self.scheduler.add_event(e) | |
83be3106 | 124 | |
83be3106 | 125 | |
e6fa8404 MT |
126 | class DistFileEvent(base.Event): |
127 | def run(self, *args): | |
128 | self.run_subprocess(self._run, *args) | |
83be3106 MT |
129 | |
130 | @staticmethod | |
e6fa8404 | 131 | def _run(_pakfire, source_id, commit_id, updated_files, deleted_files): |
83be3106 MT |
132 | commit = None |
133 | source = None | |
134 | ||
135 | if commit_id: | |
136 | commit = _pakfire.sources.get_commit_by_id(commit_id) | |
137 | assert commit | |
138 | ||
139 | source = commit.source | |
140 | ||
141 | if source_id and not source: | |
142 | source = _pakfire.sources.get_by_id(source_id) | |
143 | ||
144 | assert source | |
145 | ||
146 | if updated_files: | |
147 | # Create a temporary directory where to put all the files | |
148 | # that are generated here. | |
149 | pkg_dir = tempfile.mkdtemp() | |
150 | ||
151 | try: | |
152 | config = pakfire.config.Config(["general.conf",]) | |
153 | config.parse(source.distro.get_config()) | |
154 | ||
e6fa8404 | 155 | p = pakfire.PakfireServer(config=config) |
83be3106 MT |
156 | |
157 | pkgs = [] | |
158 | for file in updated_files: | |
159 | try: | |
160 | pkg_file = p.dist(file, pkg_dir) | |
161 | pkgs.append(pkg_file) | |
162 | except: | |
163 | raise | |
164 | ||
165 | # Import all packages in one swoop. | |
166 | for pkg in pkgs: | |
167 | # Import the package file and create a build out of it. | |
2c909128 | 168 | builds.import_from_package(_pakfire, pkg, |
83be3106 MT |
169 | distro=source.distro, commit=commit, type="release") |
170 | ||
171 | except: | |
172 | if commit: | |
173 | commit.state = "failed" | |
174 | ||
175 | raise | |
176 | ||
177 | finally: | |
178 | if os.path.exists(pkg_dir): | |
179 | shutil.rmtree(pkg_dir) | |
180 | ||
e6fa8404 MT |
181 | for file in deleted_files: |
182 | # Determine the name of the package. | |
183 | name = os.path.basename(file) | |
184 | name = name[:len(MAKEFILE_EXTENSION) + 1] | |
83be3106 | 185 | |
e6fa8404 | 186 | source.distro.delete_package(name) |
83be3106 | 187 | |
e6fa8404 MT |
188 | if commit: |
189 | commit.state = "finished" |