runbot/runbot/container.py

314 lines
12 KiB
Python
Raw Normal View History

[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
# -*- coding: utf-8 -*-
"""Containerize builds
The docker image used for the build is always tagged like this:
odoo:runbot_tests
This file contains helpers to containerize builds with Docker.
When testing this file:
the first parameter should be a directory containing Odoo.
The second parameter is the exposed port
"""
import argparse
import configparser
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
import datetime
import io
import json
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
import logging
import os
import re
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
import shutil
import subprocess
import time
_logger = logging.getLogger(__name__)
DOCKERUSER = """
RUN groupadd -g %(group_id)s odoo \\
&& useradd -u %(user_id)s -g odoo -G audio,video odoo \\
&& mkdir /home/odoo \\
&& chown -R odoo:odoo /home/odoo \\
&& echo "odoo ALL= NOPASSWD: /usr/bin/pip" > /etc/sudoers.d/pip \\
&& echo "odoo ALL= NOPASSWD: /usr/bin/pip3" >> /etc/sudoers.d/pip
USER odoo
ENV COVERAGE_FILE /data/build/.coverage
""" % {'group_id': os.getgid(), 'user_id': os.getuid()}
class Command():
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
def __init__(self, pres, cmd, posts, finals=None, config_tuples=None, cmd_checker=None):
""" Command object that represent commands to run in Docker container
:param pres: list of pre-commands
:param cmd: list of main command only run if the pres commands succeed (&&)
:param posts: list of post commands posts only run if the cmd command succedd (&&)
:param finals: list of finals commands always executed
:param config_tuples: list of key,value tuples to write in config file
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
:param cmd_checker: a checker object that must have a `_cmd_check` method that will be called at build
returns a string of the full command line to run
"""
self.pres = pres or []
self.cmd = cmd
self.posts = posts or []
self.finals = finals or []
self.config_tuples = config_tuples or []
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
self.cmd_checker = cmd_checker
def __getattr__(self, name):
return getattr(self.cmd, name)
def __getitem__(self, key):
return self.cmd[key]
def __add__(self, l):
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
return Command(self.pres, self.cmd + l, self.posts, self.finals, self.config_tuples, self.cmd_checker)
def __str__(self):
return ' '.join(self)
def __repr__(self):
return self.build().replace('&& ', '&&\n').replace('|| ', '||\n\t').replace(';', ';\n')
def build(self):
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
if self.cmd_checker:
self.cmd_checker._cmd_check(self)
cmd_chain = []
cmd_chain += [' '.join(pre) for pre in self.pres if pre]
cmd_chain.append(' '.join(self))
cmd_chain += [' '.join(post) for post in self.posts if post]
cmd_chain = [' && '.join(cmd_chain)]
cmd_chain += [' '.join(final) for final in self.finals if final]
return ' ; '.join(cmd_chain)
def add_config_tuple(self, option, value):
assert '-' not in option
self.config_tuples.append((option, value))
def get_config(self, starting_config=''):
""" returns a config file content based on config tuples and
and eventually update the starting config
"""
config = configparser.ConfigParser()
config.read_string(starting_config)
if self.config_tuples and not config.has_section('options'):
config.add_section('options')
for option, value in self.config_tuples:
config.set('options', option, value)
res = io.StringIO()
config.write(res)
res.seek(0)
return res.read()
def docker_build(build_dir, image_tag):
return _docker_build(build_dir, image_tag)
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
def _docker_build(build_dir, image_tag):
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
"""Build the docker image
:param build_dir: the build directory that contains Dockerfile.
:param image_tag: name used to tag the resulting docker image
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
"""
# synchronise the current user with the odoo user inside the Dockerfile
with open(os.path.join(build_dir, 'Dockerfile'), 'a') as df:
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
df.write(DOCKERUSER)
log_path = os.path.join(build_dir, 'docker_build.txt')
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
logs = open(log_path, 'w')
dbuild = subprocess.Popen(['docker', 'build', '--tag', image_tag, '.'], stdout=logs, stderr=logs, cwd=build_dir)
return dbuild.wait()
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
def docker_run(*args, **kwargs):
return _docker_run(*args, **kwargs)
def _docker_run(cmd=False, log_path=False, build_dir=False, container_name=False, image_tag=False, exposed_ports=None, cpu_limit=None, preexec_fn=None, ro_volumes=None, env_variables=None):
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
"""Run tests in a docker container
:param run_cmd: command string to run in container
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
:param log_path: path to the logfile that will contain odoo stdout and stderr
:param build_dir: the build directory that contains the Odoo sources to build.
This directory is shared as a volume with the container
:param container_name: used to give a name to the container for later reference
:param image_tag: Docker image tag name to select which docker image to use
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
:param exposed_ports: if not None, starting at 8069, ports will be exposed as exposed_ports numbers
:params ro_volumes: dict of dest:source volumes to mount readonly in builddir
:params env_variables: list of environment variables
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
"""
assert cmd and log_path and build_dir and container_name
run_cmd = cmd
image_tag = image_tag or 'odoo:DockerDefault'
container_name = sanitize_container_name(container_name)
if isinstance(run_cmd, Command):
cmd_object = run_cmd
run_cmd = cmd_object.build()
else:
cmd_object = Command([], run_cmd.split(' '), [])
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
_logger.debug('Docker run command: %s', run_cmd)
logs = open(log_path, 'w')
run_cmd = 'cd /data/build;touch start-%s;%s;cd /data/build;touch end-%s' % (container_name, run_cmd, container_name)
docker_clear_state(container_name, build_dir) # ensure that no state are remaining
open(os.path.join(build_dir, 'exist-%s' % container_name), 'w+').close()
logs.write("Docker command:\n%s\n=================================================\n" % cmd_object)
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
# create start script
docker_command = [
'docker', 'run', '--rm',
'--name', container_name,
'--volume=/var/run/postgresql:/var/run/postgresql',
'--volume=%s:/data/build' % build_dir,
'--shm-size=128m',
'--init',
]
if ro_volumes:
for dest, source in ro_volumes.items():
logs.write("Adding readonly volume '%s' pointing to %s \n" % (dest, source))
docker_command.append('--volume=%s:/data/build/%s:ro' % (source, dest))
if env_variables:
for var in env_variables:
docker_command.append('-e=%s' % var)
serverrc_path = os.path.expanduser('~/.openerp_serverrc')
odoorc_path = os.path.expanduser('~/.odoorc')
final_rc = odoorc_path if os.path.exists(odoorc_path) else serverrc_path if os.path.exists(serverrc_path) else None
rc_content = cmd_object.get_config(starting_config=open(final_rc, 'r').read() if final_rc else '')
rc_path = os.path.join(build_dir, '.odoorc')
with open(rc_path, 'w') as rc_file:
rc_file.write(rc_content)
docker_command.extend(['--volume=%s:/home/odoo/.odoorc:ro' % rc_path])
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
if exposed_ports:
for dp, hp in enumerate(exposed_ports, start=8069):
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
docker_command.extend(['-p', '127.0.0.1:%s:%s' % (hp, dp)])
if cpu_limit:
docker_command.extend(['--ulimit', 'cpu=%s' % int(cpu_limit)])
docker_command.extend([image_tag, '/bin/bash', '-c', "%s" % run_cmd])
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
subprocess.Popen(docker_command, stdout=logs, stderr=logs, preexec_fn=preexec_fn, close_fds=False, cwd=build_dir)
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
_logger.info('Started Docker container %s', container_name)
2019-12-17 17:27:11 +07:00
return
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
def docker_stop(container_name, build_dir=None):
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
return _docker_stop(container_name, build_dir)
def _docker_stop(container_name, build_dir):
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
"""Stops the container named container_name"""
container_name = sanitize_container_name(container_name)
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
_logger.info('Stopping container %s', container_name)
if build_dir:
end_file = os.path.join(build_dir, 'end-%s' % container_name)
subprocess.run(['touch', end_file])
else:
_logger.info('Stopping docker without defined build_dir')
subprocess.run(['docker', 'stop', container_name])
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
def docker_is_running(container_name):
container_name = sanitize_container_name(container_name)
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
dinspect = subprocess.run(['docker', 'container', 'inspect', container_name], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
return True if dinspect.returncode == 0 else False
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
def docker_state(container_name, build_dir):
container_name = sanitize_container_name(container_name)
exist = os.path.exists(os.path.join(build_dir, 'exist-%s' % container_name))
started = os.path.exists(os.path.join(build_dir, 'start-%s' % container_name))
ended = os.path.exists(os.path.join(build_dir, 'end-%s' % container_name))
if not exist:
return 'VOID'
if ended:
return 'END'
if started:
if docker_is_running(container_name):
return 'RUNNING'
else:
return 'GHOST'
return 'UNKNOWN'
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
def docker_clear_state(container_name, build_dir):
"""Return True if container is still running"""
container_name = sanitize_container_name(container_name)
if os.path.exists(os.path.join(build_dir, 'start-%s' % container_name)):
os.remove(os.path.join(build_dir, 'start-%s' % container_name))
if os.path.exists(os.path.join(build_dir, 'end-%s' % container_name)):
os.remove(os.path.join(build_dir, 'end-%s' % container_name))
if os.path.exists(os.path.join(build_dir, 'exist-%s' % container_name)):
os.remove(os.path.join(build_dir, 'exist-%s' % container_name))
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
def docker_get_gateway_ip():
"""Return the host ip of the docker default bridge gateway"""
docker_net_inspect = subprocess.run(['docker', 'network', 'inspect', 'bridge'], stdout=subprocess.PIPE)
if docker_net_inspect.returncode != 0:
return None
if docker_net_inspect.stdout:
try:
return json.loads(docker_net_inspect.stdout)[0]['IPAM']['Config'][0]['Gateway']
except KeyError:
return None
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
def docker_ps():
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
return _docker_ps()
def _docker_ps():
"""Return a list of running containers names"""
try:
docker_ps = subprocess.run(['docker', 'ps', '--format', '{{.Names}}'], stderr=subprocess.DEVNULL, stdout=subprocess.PIPE)
except FileNotFoundError:
_logger.warning('Docker not found, returning an empty list.')
return []
if docker_ps.returncode != 0:
return []
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
output = docker_ps.stdout.decode()
if not output:
return []
return output.strip().split('\n')
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
def build(args):
"""Build container from CLI"""
_logger.info('Building the base image container')
logdir = os.path.join(args.build_dir, 'logs')
os.makedirs(logdir, exist_ok=True)
logfile = os.path.join(logdir, 'logs-build.txt')
_logger.info('Logfile is in %s', logfile)
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
docker_build(logfile, args.build_dir)
_logger.info('Finished building the base image container')
def sanitize_container_name(name):
"""Returns a container name with unallowed characters removed"""
name = re.sub('^[^a-zA-Z0-9]+', '', name)
return re.sub('[^a-zA-Z0-9_.-]', '', name)
[REF] runbot: use Docker containers for builds When building Odoo, the instance is started on the same host as the runbot. It means that all the required python packages have to be installed on each runbot hosts with the same versions. Also there is no real separation between builds. Finally, from a security point of view, arbitrary code could be executed on the runbot host. With this commit, the runbot uses Docker containers to build Odoo. During the tests, Odoo http ports are not exposed to the outside, meaning that nobody could interact with that instance. The Docker image used for containers is valid for Odoo branches 10.0, 11.0, 12.0 and master. When building, right before starting the Odoo tests, the tested branch's requirements.txt is now taken into account to adapt the container. On a runbot host, the "docker ps -a" command can be used to have the list of the current builds. The containers are named using the build dest field and the current running job. For example: 123456-12-0-123456_job_30_run Prerequisites: Docker have to be installed on the runbot hosts and the user that runs the runbot should be able to use Docker. Typically, the runbot user have to be added to the docker unix group. On the first build, the Docker image will be built from scratch. It can last several minutes locking the runbot cron during this time. It means that on a multi-runbot configuration, this process will be repeated for each runbot and during this time there will be no builds. To avoid such a situation, the Docker image can be built from the command line. The container.py file can be started like this: python3 container.py build /tmp/build_dir The /tmp/build_dir directory will be created to store the Dockerfile. When the process is done, the "docker images" command should show an image tagged runbot_tests in the odoo repository. At that time, the runbot instance can be started, it will use this image for the builds. Api change: The 'job_*' methods signature has changed, the lock_path is not needed anymore. Docker image informations: Currently, the Docker image is built based on Ubuntu bionic to benefit of the python 3.6 version. Chrome and phantomjs are both installed. The latest wkhtmltopdf (0.12.5) is installed as recommended on our wiki: https://github.com/odoo/odoo/wiki/Wkhtmltopdf
2018-10-29 22:16:12 +07:00
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
##############################################################################
# Ugly monkey patch to set runbot in set runbot in testing mode
# No Docker will be started, instead a fake docker_run function will be used
##############################################################################
if os.environ.get('RUNBOT_MODE') == 'test':
_logger.warning('Using Fake Docker')
def fake_docker_run(run_cmd, log_path, build_dir, container_name, exposed_ports=None, cpu_limit=None, preexec_fn=None, ro_volumes=None, env_variables=None, *args, **kwargs):
_logger.info('Docker Fake Run: %s', run_cmd)
open(os.path.join(build_dir, 'exist-%s' % container_name), 'w').write('fake end')
[IMP] runbot: runbot 5.0 Runbot initial architechture was working for a single odoo repo, and was adapted to build enterprise. Addition of upgrade repo and test began to make result less intuitive revealing more weakness of the system. Adding to the oddities of duplicate detection and branch matching, there was some room for improvement in the runbot models. This (small) commit introduce the runbot v5.0, designed for a closer match of odoo's development flows, and hopefully improving devs experience and making runbot configuration more flexible. **Remotes:** remote intoduction helps to detect duplicate between odoo and odoo-dev repos: a commit is now on a repo, a repo having multiple remote. If a hash is in odoo-dev, we consider that it is the same in odoo. Note: github seems to manage commit kind of the same way. It is possible to send a status on a commit on odoo when the commit only exists in odoo-dev. This change also allows to remove some repo duplicate configuration between a repo and his dev corresponding repo. (modules, server files, manifests, ...) **Trigger:** before v5.0, only one build per repo was created, making it difficult to tweak what test to execute in what case. The example use case was for upgrade. We want to test upgrade to master when pushing on odoo. But we also want to test upgrade the same way when pushing on upgrade. We introduce a build that should be ran on pushing on either repo when each repo already have specific tests. The trigger allows to specify a build to create with a specific config. The trigger is executed when any repo of the trigger repo is pushed. The trigger can define depedencies: only build enterprise when pushing enterprise, but enterprise needs odoo. Test upgrade to master when pushing either odoo or upgrade. Trigger will also allows to extract some build like cla that where executed on both enterprise and odoo, and hidden in a subbuild. **Bundle:** Cross repo branches/pr branches matching was hidden in build creation and can be confusing. A build can be detected as a duplicate of a pr, but not always if naming is wrong or traget is invalid/changes. This was mainly because of how a community ref will be found. This was making ci on pr undeterministic if duplicate matching fails. This was also creating two build, with one pointing to the other when duplicate detection was working, but the visual result can be confusing. Associtaions of remotes and bundles fix this by adding all pr and related branches from all repo in a bundle. First of all this helps to visualise what the runbot consider has branch matching and that should be considered as part of the same task, giving a place where to warn devs of some possible inconsistencies. Associate whith repo/remote, we can consider branches in the same repo in a bundle as expected to have the same head. Only one build is created since trigger considers repo, not remotes. **Batch:** A batch is a group of build, a batch on a bundle can be compared to a build on a branch in previous version. When a branch is pushed, the corresponding bundle creates a new batch, and wait for new commit. Once no new update are detected in the batch for 60 seconds, All the trigger are executed if elligible. The created build are added to the batch in a batch_slot. It is also possible that an corresponding build exists (duplicate) and is added to the slot instead of creating a new build. Co-authored-by d-fence <moc@odoo.com>
2020-06-03 21:17:42 +07:00
open(os.path.join(build_dir, 'start-%s' % container_name), 'w').write('fake start\n')
open(os.path.join(build_dir, 'end-%s' % container_name), 'w').write('fake end')
with open(log_path, 'w') as log_file:
log_file.write('Fake docker_run started\n')
log_file.write('run_cmd: %s\n' % run_cmd)
log_file.write('build_dir: %s\n' % container_name)
log_file.write('container_name: %s\n' % container_name)
log_file.write('.modules.loading: Modules loaded.\n')
log_file.write('Initiating shutdown\n')
docker_run = fake_docker_run