|
2 | 2 | import logging
|
3 | 3 | import os
|
4 | 4 | import re
|
| 5 | +import docker |
5 | 6 | from odoo import api, fields, models
|
6 | 7 | from odoo.addons.base.models.ir_qweb import QWebException
|
7 | 8 |
|
@@ -155,8 +156,15 @@ def copy(self, default=None):
|
155 | 156 | return copied_record
|
156 | 157 |
|
157 | 158 | def _compute_last_successful_result(self):
|
| 159 | + rg = self.env['runbot.docker_build_result']._read_group( |
| 160 | + [('result', '=', 'success'), ('dockerfile_id', 'in', self.ids)], |
| 161 | + ['dockerfile_id'], |
| 162 | + ['id:max'], |
| 163 | + ) |
| 164 | + result_ids = dict(rg) |
| 165 | + |
158 | 166 | for record in self:
|
159 |
| - record.last_successful_result = next((result for result in record.build_results if result.result == 'success'), record.build_results.browse()) |
| 167 | + record.last_successful_result = result_ids.get(record) |
160 | 168 |
|
161 | 169 | @api.depends('bundle_ids', 'referencing_dockerlayer_ids', 'project_ids', 'version_ids')
|
162 | 170 | def _compute_use_count(self):
|
@@ -287,6 +295,35 @@ def clean_comments(text):
|
287 | 295 | 'content': 'USER {USERNAME}',
|
288 | 296 | })
|
289 | 297 |
|
| 298 | + def _get_docker_metadata(self, image_id): |
| 299 | + _logger.info(f'Fetching metadata for image {image_id}') |
| 300 | + metadata = {} |
| 301 | + commands = { |
| 302 | + 'release': 'lsb_release -ds', |
| 303 | + 'python': 'python3 --version', |
| 304 | + 'chrome': 'google-chrome --version', |
| 305 | + 'psql': 'psql --version', |
| 306 | + 'pip_packages': 'python3 -m pip freeze', |
| 307 | + 'debian_packages': "dpkg-query -W -f '${Package}==${Version}\n'", |
| 308 | + } |
| 309 | + if image_id: |
| 310 | + try: |
| 311 | + docker_client = docker.from_env() |
| 312 | + for key, command in commands.items(): |
| 313 | + name = f"GetDockerInfos_{image_id}_{key}" |
| 314 | + try: |
| 315 | + result = docker_client.containers.run(image_id, name=name,command=['/bin/bash', '-c', command], detach=False, remove=True) |
| 316 | + result = result.decode('utf-8').strip() |
| 317 | + if 'packages' in key: |
| 318 | + result = result.split('\n') |
| 319 | + except docker.errors.ContainerError: |
| 320 | + result = None |
| 321 | + metadata[key] = result |
| 322 | + except Exception as e: |
| 323 | + _logger.exception(f'Error while fetching metadata for image {image_id}') |
| 324 | + return {'error': str(e)} |
| 325 | + return metadata |
| 326 | + |
290 | 327 | def _build(self, host=None):
|
291 | 328 | docker_build_path = self.env['runbot.runbot']._path('docker', self.image_tag)
|
292 | 329 | os.makedirs(docker_build_path, exist_ok=True)
|
@@ -322,7 +359,10 @@ def _build(self, host=None):
|
322 | 359 | if previous_result.content != docker_build_result_values['content']: # docker image changed
|
323 | 360 | should_save_result = True
|
324 | 361 |
|
| 362 | + |
325 | 363 | if should_save_result:
|
| 364 | + if success: |
| 365 | + docker_build_result_values['metadata'] = self._get_docker_metadata(docker_build_result_values['identifier']) |
326 | 366 | result = self.env['runbot.docker_build_result'].create(docker_build_result_values)
|
327 | 367 | if not success:
|
328 | 368 | message = f'Build failure, check results for more info ({result.summary})'
|
|
0 commit comments