When a build is running, the stmp is the localhost.
Since Docker builds, the localhost is the container which does not catch
port 25 smtp. Mails are lost in the limbo.
With this commit, the default gateway of the Docker network is used as
smtp host for the builds. It's the responsability of the runbot host to
catch smtp traffic from the container.
This bridge interface exists by default on a system where Docker is
running. However, Docker is affected by this issue:
https://github.com/moby/moby/issues/26799
The first time the Docker daemon is installed, the Gateway is not
defined on the bridge interface. When the Docker daemon is restarted,
the gateway is correctly defined. Pay attention that restarting the
Docker daemon will kill all the running/testing builds.
When starting a container, the .odoorc|.openerp_serverrc file is not
used by the build.
With this commit, if a .odoorc or .openerp_serverrc file is found in the
home directory of the runbot user, this file is mounted read-only in the
container, allowing some customization.
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
When a PR is a duplicate of a branch, only the branch CLA status are
update. The same issue for build status was fixed in commit 4f1a55da9.
With this commit, there is new method than can be used in runbot_cla.
This method updates commit given status in each repo.
When commit is built serveral times, each time the status is updated, a
request is sent to github for each build.
As a side effect, if the first build is a failure and the last one a
success, github is wrongly updated to failure.
This bug is particulary annoying on PR in conjunction with the
runbot_merge, preventing a the PR to be merged even after several
rebuild.
With this commit, only the latest build per repository is used to update
the github status. The amount of github status updates is also reduced.
In the case of PR, the name contains 'refs/pull/3175', the branch_name
contains '3175' and because of the previous fix e095170f8c, the
pull_head_name sontains something like 'blah:12.0-something'.
In that case, the _get_closest_branch_name reaches the fallback.
With this commit, the target_branch_name is stored in a new field and is
used as the fallback.
When searching for a matching PR in a target repo, the match was made on
the 'base ref' which is the base branch that the PR targets.
This means that the second case of the _get_closest_branch method was
never reached.
Example:
An enterprise PR is created that targets Odoo branch 12.0 but with a
matching community PR with a branch with the same name.
The corresponding PR is never found by the runbot because the first
rule match: '12.0' is the base ref of the PR.
This could have been fixed by using the branch pull_head_name field to
build the domain but that leads to a problem with the second rule:
If a PR branch is named 'patch-1', the domain will match each PR with
the same pull_head_name.
With this commit, the pull_head_name field will store the pull head
label. It's not a problem with older PR as a newly created PR in
enterprise will not accidentally match with older ones.
Another issue appeared with github branch naming like 'patch-'.
If someone creates a PR with a branch auto-named 'patch-1',
targeting the community repo and later creates an unrelated PR,
targetting another repo depending of the community, they will be
matched.
To avoid that, the pull head names that ends with 'patch-n' are not
stored. Those pull requests will be built against the target branch
head.
The actual behavior, before this commit, is a blocking point for the
runbot_merge which is based on PR's only. It means that when a community
PR is wrongly matched with with an enterprise PR runbot_merge will not
merge the PR's.
When examining a particular build with the build view, one can be
frustrated being forced to navigate the frontend page to ask for a
rebuild.
With this commit, the rebuild menu entry is also visible on the build
page when the build is the last one of the branch.
Also the build host is now visible on the build page for the same
usability reason.
This commit permits to prioritize a branch when scheduling builds.
It's main purpose is for the runbot_merge module. It avoids to have
staging branches as sticky and pollutes the main repo view.
Also, that branch can benefit of the autokill feature when a newer build
is found, freeing ressources for other builds.
Closes#43
The frontend view shows only the four last builds by branch, which is a
little bit small to explore builds and search for failed builds.
With this commit, a new frontend template displays a paged list of
builds for a specified branch.
Closes#39
In a near future, Odoo will use Chrome Headless instead of phantomjs.
Chrome needs a port to listen to and it was decided that it will be
http_port + 2.
With this commit, we ensure that this port is not used by another build.
Closes#30
Avoids overly generic vhost declaration, and makes config easier to
understand.
We only want to allow such hosts:
<build_dest>.runbotX.odoo.com
<build_dest>-<db_name_extension>.runbotX.odoo.com
Where <db_name_extension> is usually "all" or "base".
The unicode icon added in the build subject is not clear for the users.
In that state, it's not easy to add a title on the icon or the subject.
With this commit, a build type field is added to differentiate the
builds and add the appropriate icon and title.
Closes: #24
When a build with coverage is killed during the tests, the coverage
result is set to 100%.
With this commit, coverage result is verbosely skipped if the coverage
file does not exists.
Also, the coverage module is no longer user to retrieve the coverage
value as it was already calculated. It's faster to grep the html file
than to recompute the value.
As the coverage builds takes a longer time than normal builds, the
timeout is increased for those kind of builds (as it was already done for the
CPU limit).
Finally, the omitted patterns were wrong and are now fixed with this
commit.
Closes#25
When the Odoo instances are spawned for tests, they have a time limit
set on their CPU usage. This limit is hard-coded in the _spawn method
calls.
As the number of tests are increasing, their duration increases too.
As this limit is inherited by subprocesses, if a phantomjs test
last too long, the test is killed alone.
Finally, when the coverage is enabled, the tests duration is
approximately increased of 1.5 times.
With this commit, the cpu_limit of the two main tests jobs are
increased. When the coverage is used, the cpu_limit is increased.
Closes: #23
When a new commit is found and a new build is created, if a user
pushes more commits in the same branch a few minutes later, it causes
more builds in testing phase, resulting in a CPU waste.
With this commit, previous builds in testing phase in non sticky
branches are killed when a new build is created.
Closes: #20
When someone tries to log in an old runbot build that is not running
anymore, he lands on the runbot instance that was running the build.
Also, all the running builds are allowed on all runbot instances,
leading to the same behavior.
With this commit, only the builds that are running on the runbot
instance can be reached, others are defaulted to a 404.
closes#21
Actually, the "Other builds" button can increase the page size and
increase the page loading time.
With this commit, the number of other builds visible in the button is limited to 100.
When the coverage is activated on a branch, the coverage result is not
stored.
With this commit, the coverage result will be stored on a build.
The last result will be shown on the frontend for sticky branches.
Also, an extra_parameter field is added on the build model.
When a reverse dependency is in testing, pending or deathrow state, there is no
icon in the depending build box.
This commit adds icons for testing, pending and deathrow states.
Also, icons are now displayed in the repository name order.
closes: #19
When a build fails in a repo that depends on another repo, it's difficult
to figure out from which commit it comes in the depending repo.
If this commit is applied, when a new commit is found in a repo's sticky
branch, the latest build from the same branch name, in the depending
repo will be forced to rebuild.
The refresh method is deprecated and invalidate_cache should be used
instead. Also, since the new API, the cache is automatically
invalidated, hence this removal.
Actually, when a build is a duplicate of another build, its github status is not updated.
e.g. a pull request may not have a github status but its corresponding
branch have a gtihub status.
With this commit, all builds will have their github status updated based
on the corresponding build status.
Thanks for your help @xmo-odoo
closes: #3
When a build was a duplicate, the link to the running build instance was
leading to the duplicate instance with the db filter of the current
build. Because of that, the user was then redirected to the database selector.
With this commit, the link button gives the proper database argument.
Thanks @RomainLibert for reporting this issue.
When code coverage was processed the 'coverage' utility was called the
same way regardless of the Odoo version. That was the cause of two
problems:
1) In some OS packages, the 'coverage' executable was renamed to
'python-coverage' and 'python3-coverage'
2) Since version 11.0, Odoo needs python3
With this commit, the coverage module is called from python '-m'
argument and the python version is chosen from the Odoo executable
shebang.
closes: #12
When a server is built based on dependency_ids, only the branch refs was
logged. In this situation, it's difficult to reproduce a build locally
in the exact same conditions.
With this commit, the latest commit hash and message of this
branch is also logged.
When searching for the closest branch name in a target repo, if the PR
head names are equals, a branch method is called on a dictionary, causing
a traceback.
With this commit, the method is called on a branch object instance.
closes#11
Before this commit, when a clean instance of the runbot is installed,
there was a KeyError on the frontend because there was not builds for
the sticky branches.
When installing a clean runbot instance a bad query is made because
there is not any build yet.
With this commmit, the query is not made when there are no builds
directories found on the filesystem.
Some HTML attributes were missing, and are required to ensure good
compatibility with screen readers.
The following attributes are included:
- `aria-expanded`: this should be present in all dropdown menus
- `aria-label`: this should be present in all links and buttons which
don't show text, but icons or images.
Instead of marking most fields as `copy=False` to be able to use the
copy method for rebuilds, we create the build explicitly. We also
forbid to copy builds as it doesn't make much sense to begin with.
As for duplicates, it wasn't always possible to rebuild them. The
rebuild now injects a specific context key (force_rebuild). This allows
duplicates to undergo a rebuild. The side-effect of writing on previous
builds is also removed[1].
[1]: it's not obvious from the diff but the porting to the V8 API
should have yielded
duplicate.write({'duplicate_id': build_id.id})
instead of
build_id.write({'duplicate_id': build_id.id})
Before this commit, the job_end was always None because of a time2str
function with no return. So the job_time was the same as the job age.
Also, the result and times were copied from the prvious build. Displayed
time and results were wrong.
The previous code of runbot and runbot_cla was made for Odoo API version
8.0. This commit makes it work with Odoo API 11.0 and Python 3.
Also, the present refactoring splits the code into multiple files to
make it easier to read (I hope).
The main change due to Python 3 is the job locking mechanism:
Since PEP-446 file descriptors are non-inheritable by default.
A new method (os.set_inheritable) was introduced to explicitely make
fd inheritable. Also, the close_fds parameter of the subprocess.Popen
method is now True by default.
Finally, PEP-3151 changed the exception raised by fcntl.flock from IOError to OSError
(and IOError became an alias of OSError).
As a consequence of all that, the runbot locking mechanism to check if a
job is finished was not working in python3.
The linked build is extracted from dbname via a trigger on new row
creation.
This improve rendering of build page.
A migration script is added to link existing logging entries to
corresponding build and remove invalid ones.
Note that this migration script can take a long time.
Allow logged users to kill builds that are pending or testing.
The kill button solves the following problem:
When you have a community and enterprise branch with pull request.
The enterprise PR gets fetched before the branch by runbot, so it
builds with the community master branch instead of the corresponding
community branch. As the branch shares the same HEAD as the PR,
so no other build is done for the branch.
Previously you had to wait the build to finish building, then rebuild it
from the branch, taking twice the time necessary. Now you'll be able to
kill & rebuild it just after pushing the branch.
Also having a kill button is globally a nice to have feature.
In a repository with dependencies
e.g. `odoo-dev/enterprise` depending on `odoo-dev/odoo`
consider a build as a duplicate of another if
- The HEAD is identical (as before)
- AND the branches used for the depending repositories are the same
e.g.
- pushing `master-staging-dle` to `odoo-dev/enterprise`,
- with as HEAD the same HEAD than `master`,
- but for which a branch `master-staging-dle` exists in `odoo-dev/odoo`
- a duplicate would be a build having as HEAD the HEAD of master
AND the `odoo-dev` branch `master-staging-dle`
Before, it would have used the latest build of the `master` branch,
as the HEAD was the same, despite the fact it didn't use the branch
`master-staging-dle` of `odoo-dev/odoo`
The `git gc --auto` command often fails and requires an explicit
execution of `git gc --prune=all`. When it happens, it crashes the
update, failing the cron execution.
Executing `git gc prune` every time would be very slow and dispruptive
during the cron's critical sections.
As the initial goal was to avoid triggering the automatic GC during the
next update/pull command, we prefer to adopt the global strategy of
disabling the auto GC globally with:
git config --global gc.auto 0
And to configure a system cron job to periodically GC/prune all
repositories, to get the performance benefit.
Due to locking issues, that cronjob should be scheduled outside peak
build hours.
Example bash script for the system cron:
```
#!/bin/bash
set -e
base_repo_dir='/path/to/runbot/static/repo'
for repo in $base_repo_dir/*
do
if [[ -d $repo ]];then
git --git-dir="$repo" gc --prune=all
fi
done
```
Catch exceptions occurring within job methods, to avoid
stalling the runbot by repeatedly trying to call it -
and crashing every time.
Mark the build as failed immediately and skip it.
Most of the non-CRUD methods of runbot models should be private, as
there is no need to access them via RPC.
WARNING: This change is backwards compatible with existing
installations and existing runbot databases, but will most
likely BREAK all third-party extensions, due to the renamed
methods.
Fortunately the runbot module is not ruled by Odoo's "stable policy" ;-)
Reported by @nilshamerlinck - thanks!
When doing a `git archive`, all the files in the tar archive are set to
the commit date. Ignore this date during extraction.
Having the files with dates in future will make some tests about assets
to fail. These tests force the asset regeneration by `touch`ing one
js/css file. If other bundle files are still older that the one we touch,
the asset is not regenerated and the test fail.
This commit() is the root cause of the famous false-positive error
`_check_module_names invalid module names, ignored: False`.
The first step (pull code) is a long one. if a push-hook request
happen during this step, the current transaction wont be able to be
commited (the list of module to test is written on the build). Due to
this early commit(), the build is left in an intermediate state with
the module list unpopulated (=False).
To find out the list of manually created dbs,
rev. 4d94f45 used the cursor that is connected to the
master `runbot` database, which may reside on a different
cluster/host.
- Add a helper to run commands on the local PG cluster
instead ("postgres" database).
- Modify other commands for local cluster (create/drop db)
to use the same cursor. Rename those methods to _local_*
to better indicate their local effect.
- pos_blackbox_be: because it makes the POS unuseable without a blackbox
- pos_cache: because it's too confusing for runbot users, everytime they
update a product they have to also update the cache, but
most people don't realise that.
As of Odoo 9 the first l10n module installed will automatically
install its chart of account on the main company, so installing
the first one (l10n_ae) is surprising/strange.
Branches that want to build l10n_* modules should list
them explicitly in the "modules to install" field (modules).
In addition, having demo data to set the country of the
main company will automatically installe the relevant
l10n module if it exists. This is the default in Odoo 9
with l10n_us.
This allows configuring an explicit list of modules to install
on a repository without having orange builds (with warnings)
whenever a branch does not have one of these modules for some
reason.
This lets us use them in README files
on GitHub, which uses an image proxy
that does not have access to private
repositories.
This is an acceptable disclosure of
information about private repos.
The web addon is supposed to be duplicate, and needs to be installed
(in the enterprise version) over the community edition.
A better fix would be to keep the folder and use the --addons-path key
to start the server with the correct addon, but this is an urgent
change.
closes#69
pushing new commits on your branch should not make you loose rank in schuler
build order is based on sequence which is the id of the build, take lowest
When a build is skipped, `build.host` is `False`.
The proposed link is then just `http://rubot/static/build/...` which is invalid.
As there is no logs anyway, hide the buttons.
The base field is used to compose URL (e.g. "https://%s/pulls" % repo.base).
The URL given by github can contains trailing '.git' so this should be removed.
This module should be simply deleted in a futur version.
The implementation are not more supported with Odoo.
Architecture need to be reviewed to allow the support of this library
c6ce286 moved cla check as first job (`05_check_cla`), but as the
checkout of the working directory was done in `10_test_base`, the check
was actually a no-op.
Do the build environment init in `job_00_init`.
Jobs that does not returning a pid to wait for are automatically
rescheduled.
/b/ :
Use smallest repo_id by default if repo is not specified
Allow to force the repo in quick_url /b/<branch_name> -> /<repo>/<branch_name>
Duplicated:
If state is duplicated, the main build in not always running
There was an uncaught exception raised by one of the git command in certain cases when searching for the right branch in the dependencies repositories. Because of this error, the dependencies process never finished, and in some case there was no server to run because the server was located on a dependency repo. With no server to run, the build would fail instantly at the start of the testing phase.
revert commit dea869273a9a03f6f58993c3fa558a916cb8e4a5
phantomjs stderr is now discarded since odoo commit
5a642a802e
no need to discard odoo stderr from logfile.
Close#49
A Community addon can depend on more than just an odoo server, but other
addon repos
Bump version
Add migration script
Signed-off-by: Sandy Carter <sandy.carter@savoirfairelinux.com>
OCA addon repos will only want to test modules at root
Glob before retrieving dependencies and store in build object
Signed-off-by: Sandy Carter <sandy.carter@savoirfairelinux.com>