Skip to content

Commit

Permalink
[IMP] runbot: get docker metadata after build
Browse files Browse the repository at this point in the history
The docker metadata are currently computed only on
some images durring the nightly.

This aims to get metadata after each docker image build in order to be
able to rely on them when needed.
  • Loading branch information
Xavier-Do committed Nov 20, 2024
1 parent 36b35b6 commit 20392d4
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
52 changes: 51 additions & 1 deletion runbot/models/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import os
import re
import docker
from odoo import api, fields, models
from odoo.addons.base.models.ir_qweb import QWebException

Expand Down Expand Up @@ -155,8 +156,25 @@ def copy(self, default=None):
return copied_record

def _compute_last_successful_result(self):
result_ids = {}
if self.ids:
self.env.cr.execute("""
SELECT
max(id)
FROM
runbot_docker_build_result
WHERE
result = 'success'
AND dockerfile_id IN %s
GROUP BY dockerfile_id
""", [tuple(self.ids)]
)
results = self.env['runbot.docker_build_result'].browse([r[0] for r in self.env.cr.fetchall()])
for result in results:
result_ids[result.dockerfile_id.id] = result

for record in self:
record.last_successful_result = next((result for result in record.build_results if result.result == 'success'), record.build_results.browse())
record.last_successful_result = result_ids.get(record.id)

@api.depends('bundle_ids', 'referencing_dockerlayer_ids', 'project_ids', 'version_ids')
def _compute_use_count(self):
Expand Down Expand Up @@ -287,6 +305,35 @@ def clean_comments(text):
'content': 'USER {USERNAME}',
})

def _get_docker_metadata(self, image_id):
_logger.info(f'Fetching metadata for image {image_id}')
metadata = {}
commands = {
'release': 'lsb_release -ds',
'python': 'python3 --version',
'chrome': 'google-chrome --version',
'psql': 'psql --version',
'pip_packages': 'python3 -m pip freeze',
'debian_packages': "dpkg-query -W -f '${Package}==${Version}\n'",
}
if image_id:
try:
docker_client = docker.from_env()
for key, command in commands.items():
name = f"GetDockerInfos_{image_id}_{key}"
try:
result = docker_client.containers.run(image_id, name=name,command=['/bin/bash', '-c', command], detach=False, remove=True)
result = result.decode('utf-8').strip()
if 'packages' in key:
result = result.split('\n')
except docker.errors.ContainerError:
result = None
metadata[key] = result
except Exception as e:
_logger.exception(f'Error while fetching metadata for image {image_id}')
return {'error': str(e)}
return metadata

def _build(self, host=None):
docker_build_path = self.env['runbot.runbot']._path('docker', self.image_tag)
os.makedirs(docker_build_path, exist_ok=True)
Expand Down Expand Up @@ -322,7 +369,10 @@ def _build(self, host=None):
if previous_result.content != docker_build_result_values['content']: # docker image changed
should_save_result = True


if should_save_result:
if success:
docker_build_result_values['metadata'] = self._get_docker_metadata(docker_build_result_values['identifier'])
result = self.env['runbot.docker_build_result'].create(docker_build_result_values)
if not success:
message = f'Build failure, check results for more info ({result.summary})'
Expand Down
4 changes: 4 additions & 0 deletions runbot/static/src/js/fields/fields.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.o_field_widget.o_field_runbotjsonb {
width: 100%;
white-space: pre-wrap;
}
3 changes: 3 additions & 0 deletions runbot/views/dockerfile_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@
<page string="Content">
<field name="content"/>
</page>
<page string="Metadata">
<field name="metadata"/>
</page>
</notebook>
</sheet>
</form>
Expand Down

0 comments on commit 20392d4

Please sign in to comment.