diff options
Diffstat (limited to 'bitbake/lib')
-rw-r--r-- | bitbake/lib/toaster/orm/management/commands/lsupdates.py | 228 |
1 files changed, 97 insertions, 131 deletions
diff --git a/bitbake/lib/toaster/orm/management/commands/lsupdates.py b/bitbake/lib/toaster/orm/management/commands/lsupdates.py index efc6b3a946..66114ff89e 100644 --- a/bitbake/lib/toaster/orm/management/commands/lsupdates.py +++ b/bitbake/lib/toaster/orm/management/commands/lsupdates.py | |||
@@ -29,7 +29,6 @@ from orm.models import ToasterSetting | |||
29 | import os | 29 | import os |
30 | import sys | 30 | import sys |
31 | 31 | ||
32 | import json | ||
33 | import logging | 32 | import logging |
34 | import threading | 33 | import threading |
35 | import time | 34 | import time |
@@ -37,6 +36,18 @@ logger = logging.getLogger("toaster") | |||
37 | 36 | ||
38 | DEFAULT_LAYERINDEX_SERVER = "http://layers.openembedded.org/layerindex/api/" | 37 | DEFAULT_LAYERINDEX_SERVER = "http://layers.openembedded.org/layerindex/api/" |
39 | 38 | ||
39 | # Add path to bitbake modules for layerindexlib | ||
40 | # lib/toaster/orm/management/commands/lsupdates.py (abspath) | ||
41 | # lib/toaster/orm/management/commands (dirname) | ||
42 | # lib/toaster/orm/management (dirname) | ||
43 | # lib/toaster/orm (dirname) | ||
44 | # lib/toaster/ (dirname) | ||
45 | # lib/ (dirname) | ||
46 | path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))) | ||
47 | sys.path.insert(0, path) | ||
48 | |||
49 | import layerindexlib | ||
50 | |||
40 | 51 | ||
41 | class Spinner(threading.Thread): | 52 | class Spinner(threading.Thread): |
42 | """ A simple progress spinner to indicate download/parsing is happening""" | 53 | """ A simple progress spinner to indicate download/parsing is happening""" |
@@ -86,45 +97,6 @@ class Command(BaseCommand): | |||
86 | self.apiurl = ToasterSetting.objects.get(name = 'CUSTOM_LAYERINDEX_SERVER').value | 97 | self.apiurl = ToasterSetting.objects.get(name = 'CUSTOM_LAYERINDEX_SERVER').value |
87 | 98 | ||
88 | assert self.apiurl is not None | 99 | assert self.apiurl is not None |
89 | try: | ||
90 | from urllib.request import urlopen, URLError | ||
91 | from urllib.parse import urlparse | ||
92 | except ImportError: | ||
93 | from urllib2 import urlopen, URLError | ||
94 | from urlparse import urlparse | ||
95 | |||
96 | proxy_settings = os.environ.get("http_proxy", None) | ||
97 | |||
98 | def _get_json_response(apiurl=None): | ||
99 | if None == apiurl: | ||
100 | apiurl=self.apiurl | ||
101 | http_progress = Spinner() | ||
102 | http_progress.start() | ||
103 | |||
104 | _parsedurl = urlparse(apiurl) | ||
105 | path = _parsedurl.path | ||
106 | |||
107 | # logger.debug("Fetching %s", apiurl) | ||
108 | try: | ||
109 | res = urlopen(apiurl) | ||
110 | except URLError as e: | ||
111 | raise Exception("Failed to read %s: %s" % (path, e.reason)) | ||
112 | |||
113 | parsed = json.loads(res.read().decode('utf-8')) | ||
114 | |||
115 | http_progress.stop() | ||
116 | return parsed | ||
117 | |||
118 | # verify we can get the basic api | ||
119 | try: | ||
120 | apilinks = _get_json_response() | ||
121 | except Exception as e: | ||
122 | import traceback | ||
123 | if proxy_settings is not None: | ||
124 | logger.info("EE: Using proxy %s" % proxy_settings) | ||
125 | logger.warning("EE: could not connect to %s, skipping update:" | ||
126 | "%s\n%s" % (self.apiurl, e, traceback.format_exc())) | ||
127 | return | ||
128 | 100 | ||
129 | # update branches; only those that we already have names listed in the | 101 | # update branches; only those that we already have names listed in the |
130 | # Releases table | 102 | # Releases table |
@@ -133,112 +105,118 @@ class Command(BaseCommand): | |||
133 | if len(whitelist_branch_names) == 0: | 105 | if len(whitelist_branch_names) == 0: |
134 | raise Exception("Failed to make list of branches to fetch") | 106 | raise Exception("Failed to make list of branches to fetch") |
135 | 107 | ||
136 | logger.info("Fetching metadata releases for %s", | 108 | logger.info("Fetching metadata for %s", |
137 | " ".join(whitelist_branch_names)) | 109 | " ".join(whitelist_branch_names)) |
138 | 110 | ||
139 | branches_info = _get_json_response(apilinks['branches'] + | 111 | # We require a non-empty bb.data, but we can fake it with a dictionary |
140 | "?filter=name:%s" | 112 | layerindex = layerindexlib.LayerIndex({"DUMMY" : "VALUE"}) |
141 | % "OR".join(whitelist_branch_names)) | 113 | |
114 | http_progress = Spinner() | ||
115 | http_progress.start() | ||
116 | |||
117 | if whitelist_branch_names: | ||
118 | url_branches = ";branch=%s" % ','.join(whitelist_branch_names) | ||
119 | else: | ||
120 | url_branches = "" | ||
121 | layerindex.load_layerindex("%s%s" % (self.apiurl, url_branches)) | ||
122 | |||
123 | http_progress.stop() | ||
124 | |||
125 | # We know we're only processing one entry, so we reference it here | ||
126 | # (this is cheating...) | ||
127 | index = layerindex.indexes[0] | ||
142 | 128 | ||
143 | # Map the layer index branches to toaster releases | 129 | # Map the layer index branches to toaster releases |
144 | li_branch_id_to_toaster_release = {} | 130 | li_branch_id_to_toaster_release = {} |
145 | 131 | ||
146 | total = len(branches_info) | 132 | logger.info("Processing releases") |
147 | for i, branch in enumerate(branches_info): | 133 | |
148 | li_branch_id_to_toaster_release[branch['id']] = \ | 134 | total = len(index.branches) |
149 | Release.objects.get(name=branch['name']) | 135 | for i, id in enumerate(index.branches): |
136 | li_branch_id_to_toaster_release[id] = \ | ||
137 | Release.objects.get(name=index.branches[id].name) | ||
150 | self.mini_progress("Releases", i, total) | 138 | self.mini_progress("Releases", i, total) |
151 | 139 | ||
152 | # keep a track of the layerindex (li) id mappings so that | 140 | # keep a track of the layerindex (li) id mappings so that |
153 | # layer_versions can be created for these layers later on | 141 | # layer_versions can be created for these layers later on |
154 | li_layer_id_to_toaster_layer_id = {} | 142 | li_layer_id_to_toaster_layer_id = {} |
155 | 143 | ||
156 | logger.info("Fetching layers") | 144 | logger.info("Processing layers") |
157 | |||
158 | layers_info = _get_json_response(apilinks['layerItems']) | ||
159 | 145 | ||
160 | total = len(layers_info) | 146 | total = len(index.layerItems) |
161 | for i, li in enumerate(layers_info): | 147 | for i, id in enumerate(index.layerItems): |
162 | try: | 148 | try: |
163 | l, created = Layer.objects.get_or_create(name=li['name']) | 149 | l, created = Layer.objects.get_or_create(name=index.layerItems[id].name) |
164 | l.up_date = li['updated'] | 150 | l.up_date = index.layerItems[id].updated |
165 | l.summary = li['summary'] | 151 | l.summary = index.layerItems[id].summary |
166 | l.description = li['description'] | 152 | l.description = index.layerItems[id].description |
167 | 153 | ||
168 | if created: | 154 | if created: |
169 | # predefined layers in the fixtures (for example poky.xml) | 155 | # predefined layers in the fixtures (for example poky.xml) |
170 | # always preempt the Layer Index for these values | 156 | # always preempt the Layer Index for these values |
171 | l.vcs_url = li['vcs_url'] | 157 | l.vcs_url = index.layerItems[id].vcs_url |
172 | l.vcs_web_url = li['vcs_web_url'] | 158 | l.vcs_web_url = index.layerItems[id].vcs_web_url |
173 | l.vcs_web_tree_base_url = li['vcs_web_tree_base_url'] | 159 | l.vcs_web_tree_base_url = index.layerItems[id].vcs_web_tree_base_url |
174 | l.vcs_web_file_base_url = li['vcs_web_file_base_url'] | 160 | l.vcs_web_file_base_url = index.layerItems[id].vcs_web_file_base_url |
175 | l.save() | 161 | l.save() |
176 | except Layer.MultipleObjectsReturned: | 162 | except Layer.MultipleObjectsReturned: |
177 | logger.info("Skipped %s as we found multiple layers and " | 163 | logger.info("Skipped %s as we found multiple layers and " |
178 | "don't know which to update" % | 164 | "don't know which to update" % |
179 | li['name']) | 165 | index.layerItems[id].name) |
180 | 166 | ||
181 | li_layer_id_to_toaster_layer_id[li['id']] = l.pk | 167 | li_layer_id_to_toaster_layer_id[id] = l.pk |
182 | 168 | ||
183 | self.mini_progress("layers", i, total) | 169 | self.mini_progress("layers", i, total) |
184 | 170 | ||
185 | # update layer_versions | 171 | # update layer_versions |
186 | logger.info("Fetching layer versions") | 172 | logger.info("Processing layer versions") |
187 | layerbranches_info = _get_json_response( | ||
188 | apilinks['layerBranches'] + "?filter=branch__name:%s" % | ||
189 | "OR".join(whitelist_branch_names)) | ||
190 | 173 | ||
191 | # Map Layer index layer_branch object id to | 174 | # Map Layer index layer_branch object id to |
192 | # layer_version toaster object id | 175 | # layer_version toaster object id |
193 | li_layer_branch_id_to_toaster_lv_id = {} | 176 | li_layer_branch_id_to_toaster_lv_id = {} |
194 | 177 | ||
195 | total = len(layerbranches_info) | 178 | total = len(index.layerBranches) |
196 | for i, lbi in enumerate(layerbranches_info): | 179 | for i, id in enumerate(index.layerBranches): |
197 | # release as defined by toaster map to layerindex branch | 180 | # release as defined by toaster map to layerindex branch |
198 | release = li_branch_id_to_toaster_release[lbi['branch']] | 181 | release = li_branch_id_to_toaster_release[index.layerBranches[id].branch_id] |
199 | 182 | ||
200 | try: | 183 | try: |
201 | lv, created = Layer_Version.objects.get_or_create( | 184 | lv, created = Layer_Version.objects.get_or_create( |
202 | layer=Layer.objects.get( | 185 | layer=Layer.objects.get( |
203 | pk=li_layer_id_to_toaster_layer_id[lbi['layer']]), | 186 | pk=li_layer_id_to_toaster_layer_id[index.layerBranches[id].layer_id]), |
204 | release=release | 187 | release=release |
205 | ) | 188 | ) |
206 | except KeyError: | 189 | except KeyError: |
207 | logger.warning( | 190 | logger.warning( |
208 | "No such layerindex layer referenced by layerbranch %d" % | 191 | "No such layerindex layer referenced by layerbranch %d" % |
209 | lbi['layer']) | 192 | index.layerBranches[id].layer_id) |
210 | continue | 193 | continue |
211 | 194 | ||
212 | if created: | 195 | if created: |
213 | lv.release = li_branch_id_to_toaster_release[lbi['branch']] | 196 | lv.release = li_branch_id_to_toaster_release[index.layerBranches[id].branch_id] |
214 | lv.up_date = lbi['updated'] | 197 | lv.up_date = index.layerBranches[id].updated |
215 | lv.commit = lbi['actual_branch'] | 198 | lv.commit = index.layerBranches[id].actual_branch |
216 | lv.dirpath = lbi['vcs_subdir'] | 199 | lv.dirpath = index.layerBranches[id].vcs_subdir |
217 | lv.save() | 200 | lv.save() |
218 | 201 | ||
219 | li_layer_branch_id_to_toaster_lv_id[lbi['id']] =\ | 202 | li_layer_branch_id_to_toaster_lv_id[index.layerBranches[id].id] =\ |
220 | lv.pk | 203 | lv.pk |
221 | self.mini_progress("layer versions", i, total) | 204 | self.mini_progress("layer versions", i, total) |
222 | 205 | ||
223 | logger.info("Fetching layer version dependencies") | 206 | logger.info("Processing layer version dependencies") |
224 | # update layer dependencies | ||
225 | layerdependencies_info = _get_json_response( | ||
226 | apilinks['layerDependencies'] + | ||
227 | "?filter=layerbranch__branch__name:%s" % | ||
228 | "OR".join(whitelist_branch_names)) | ||
229 | 207 | ||
230 | dependlist = {} | 208 | dependlist = {} |
231 | for ldi in layerdependencies_info: | 209 | for id in index.layerDependencies: |
232 | try: | 210 | try: |
233 | lv = Layer_Version.objects.get( | 211 | lv = Layer_Version.objects.get( |
234 | pk=li_layer_branch_id_to_toaster_lv_id[ldi['layerbranch']]) | 212 | pk=li_layer_branch_id_to_toaster_lv_id[index.layerDependencies[id].layerbranch_id]) |
235 | except Layer_Version.DoesNotExist as e: | 213 | except Layer_Version.DoesNotExist as e: |
236 | continue | 214 | continue |
237 | 215 | ||
238 | if lv not in dependlist: | 216 | if lv not in dependlist: |
239 | dependlist[lv] = [] | 217 | dependlist[lv] = [] |
240 | try: | 218 | try: |
241 | layer_id = li_layer_id_to_toaster_layer_id[ldi['dependency']] | 219 | layer_id = li_layer_id_to_toaster_layer_id[index.layerDependencies[id].dependency_id] |
242 | 220 | ||
243 | dependlist[lv].append( | 221 | dependlist[lv].append( |
244 | Layer_Version.objects.get(layer__pk=layer_id, | 222 | Layer_Version.objects.get(layer__pk=layer_id, |
@@ -247,7 +225,7 @@ class Command(BaseCommand): | |||
247 | except Layer_Version.DoesNotExist: | 225 | except Layer_Version.DoesNotExist: |
248 | logger.warning("Cannot find layer version (ls:%s)," | 226 | logger.warning("Cannot find layer version (ls:%s)," |
249 | "up_id:%s lv:%s" % | 227 | "up_id:%s lv:%s" % |
250 | (self, ldi['dependency'], lv)) | 228 | (self, index.layerDependencies[id].dependency_id, lv)) |
251 | 229 | ||
252 | total = len(dependlist) | 230 | total = len(dependlist) |
253 | for i, lv in enumerate(dependlist): | 231 | for i, lv in enumerate(dependlist): |
@@ -258,73 +236,61 @@ class Command(BaseCommand): | |||
258 | self.mini_progress("Layer version dependencies", i, total) | 236 | self.mini_progress("Layer version dependencies", i, total) |
259 | 237 | ||
260 | # update Distros | 238 | # update Distros |
261 | logger.info("Fetching distro information") | 239 | logger.info("Processing distro information") |
262 | distros_info = _get_json_response( | ||
263 | apilinks['distros'] + "?filter=layerbranch__branch__name:%s" % | ||
264 | "OR".join(whitelist_branch_names)) | ||
265 | 240 | ||
266 | total = len(distros_info) | 241 | total = len(index.distros) |
267 | for i, di in enumerate(distros_info): | 242 | for i, id in enumerate(index.distros): |
268 | distro, created = Distro.objects.get_or_create( | 243 | distro, created = Distro.objects.get_or_create( |
269 | name=di['name'], | 244 | name=index.distros[id].name, |
270 | layer_version=Layer_Version.objects.get( | 245 | layer_version=Layer_Version.objects.get( |
271 | pk=li_layer_branch_id_to_toaster_lv_id[di['layerbranch']])) | 246 | pk=li_layer_branch_id_to_toaster_lv_id[index.distros[id].layerbranch_id])) |
272 | distro.up_date = di['updated'] | 247 | distro.up_date = index.distros[id].updated |
273 | distro.name = di['name'] | 248 | distro.name = index.distros[id].name |
274 | distro.description = di['description'] | 249 | distro.description = index.distros[id].description |
275 | distro.save() | 250 | distro.save() |
276 | self.mini_progress("distros", i, total) | 251 | self.mini_progress("distros", i, total) |
277 | 252 | ||
278 | # update machines | 253 | # update machines |
279 | logger.info("Fetching machine information") | 254 | logger.info("Processing machine information") |
280 | machines_info = _get_json_response( | ||
281 | apilinks['machines'] + "?filter=layerbranch__branch__name:%s" % | ||
282 | "OR".join(whitelist_branch_names)) | ||
283 | 255 | ||
284 | total = len(machines_info) | 256 | total = len(index.machines) |
285 | for i, mi in enumerate(machines_info): | 257 | for i, id in enumerate(index.machines): |
286 | mo, created = Machine.objects.get_or_create( | 258 | mo, created = Machine.objects.get_or_create( |
287 | name=mi['name'], | 259 | name=index.machines[id].name, |
288 | layer_version=Layer_Version.objects.get( | 260 | layer_version=Layer_Version.objects.get( |
289 | pk=li_layer_branch_id_to_toaster_lv_id[mi['layerbranch']])) | 261 | pk=li_layer_branch_id_to_toaster_lv_id[index.machines[id].layerbranch_id])) |
290 | mo.up_date = mi['updated'] | 262 | mo.up_date = index.machines[id].updated |
291 | mo.name = mi['name'] | 263 | mo.name = index.machines[id].name |
292 | mo.description = mi['description'] | 264 | mo.description = index.machines[id].description |
293 | mo.save() | 265 | mo.save() |
294 | self.mini_progress("machines", i, total) | 266 | self.mini_progress("machines", i, total) |
295 | 267 | ||
296 | # update recipes; paginate by layer version / layer branch | 268 | # update recipes; paginate by layer version / layer branch |
297 | logger.info("Fetching recipe information") | 269 | logger.info("Processing recipe information") |
298 | recipes_info = _get_json_response( | ||
299 | apilinks['recipes'] + "?filter=layerbranch__branch__name:%s" % | ||
300 | "OR".join(whitelist_branch_names)) | ||
301 | 270 | ||
302 | total = len(recipes_info) | 271 | total = len(index.recipes) |
303 | for i, ri in enumerate(recipes_info): | 272 | for i, id in enumerate(index.recipes): |
304 | try: | 273 | try: |
305 | lv_id = li_layer_branch_id_to_toaster_lv_id[ri['layerbranch']] | 274 | lv_id = li_layer_branch_id_to_toaster_lv_id[index.recipes[id].layerbranch_id] |
306 | lv = Layer_Version.objects.get(pk=lv_id) | 275 | lv = Layer_Version.objects.get(pk=lv_id) |
307 | 276 | ||
308 | ro, created = Recipe.objects.get_or_create( | 277 | ro, created = Recipe.objects.get_or_create( |
309 | layer_version=lv, | 278 | layer_version=lv, |
310 | name=ri['pn'] | 279 | name=index.recipes[id].pn |
311 | ) | 280 | ) |
312 | 281 | ||
313 | ro.layer_version = lv | 282 | ro.layer_version = lv |
314 | ro.up_date = ri['updated'] | 283 | ro.up_date = index.recipes[id].updated |
315 | ro.name = ri['pn'] | 284 | ro.name = index.recipes[id].pn |
316 | ro.version = ri['pv'] | 285 | ro.version = index.recipes[id].pv |
317 | ro.summary = ri['summary'] | 286 | ro.summary = index.recipes[id].summary |
318 | ro.description = ri['description'] | 287 | ro.description = index.recipes[id].description |
319 | ro.section = ri['section'] | 288 | ro.section = index.recipes[id].section |
320 | ro.license = ri['license'] | 289 | ro.license = index.recipes[id].license |
321 | ro.homepage = ri['homepage'] | 290 | ro.homepage = index.recipes[id].homepage |
322 | ro.bugtracker = ri['bugtracker'] | 291 | ro.bugtracker = index.recipes[id].bugtracker |
323 | ro.file_path = ri['filepath'] + "/" + ri['filename'] | 292 | ro.file_path = index.recipes[id].fullpath |
324 | if 'inherits' in ri: | 293 | ro.is_image = 'image' in index.recipes[id].inherits.split() |
325 | ro.is_image = 'image' in ri['inherits'].split() | ||
326 | else: # workaround for old style layer index | ||
327 | ro.is_image = "-image-" in ri['pn'] | ||
328 | ro.save() | 294 | ro.save() |
329 | except Exception as e: | 295 | except Exception as e: |
330 | logger.warning("Failed saving recipe %s", e) | 296 | logger.warning("Failed saving recipe %s", e) |