mirror of
https://github.com/odoo/runbot.git
synced 2025-03-27 13:25:47 +07:00
Merge pull request #12 from odoo/master-improvements-ged
[IMP] improvements to runbot scheduler
This commit is contained in:
commit
0ce2bb3485
@ -212,6 +212,9 @@ class runbot_repo(osv.osv):
|
|||||||
|
|
||||||
def update_git(self, cr, uid, repo, context=None):
|
def update_git(self, cr, uid, repo, context=None):
|
||||||
_logger.debug('repo %s updating branches', repo.name)
|
_logger.debug('repo %s updating branches', repo.name)
|
||||||
|
|
||||||
|
Build = self.pool['runbot.build']
|
||||||
|
|
||||||
if not os.path.isdir(os.path.join(repo.path)):
|
if not os.path.isdir(os.path.join(repo.path)):
|
||||||
os.makedirs(repo.path)
|
os.makedirs(repo.path)
|
||||||
if not os.path.isdir(os.path.join(repo.path, 'refs')):
|
if not os.path.isdir(os.path.join(repo.path, 'refs')):
|
||||||
@ -245,9 +248,13 @@ class runbot_repo(osv.osv):
|
|||||||
# skip build for old branches
|
# skip build for old branches
|
||||||
if dateutil.parser.parse(date[:19]) + datetime.timedelta(30) < datetime.datetime.now():
|
if dateutil.parser.parse(date[:19]) + datetime.timedelta(30) < datetime.datetime.now():
|
||||||
continue
|
continue
|
||||||
# create build if not found
|
# create build (and mark previous builds as skipped) if not found
|
||||||
build_ids = self.pool['runbot.build'].search(cr, uid, [('branch_id', '=', branch.id), ('name', '=', sha)])
|
build_ids = self.pool['runbot.build'].search(cr, uid, [('branch_id', '=', branch.id), ('name', '=', sha)])
|
||||||
if not build_ids:
|
if not build_ids:
|
||||||
|
if not branch.sticky:
|
||||||
|
to_be_skipped_ids = Build.search(cr, uid, [('branch_id', '=', branch.id), ('state', '=', 'pending')])
|
||||||
|
Build.write(cr, uid, to_be_skipped_ids, {'state': 'done', 'result': 'skipped'})
|
||||||
|
|
||||||
_logger.debug('repo %s branch %s new build found revno %s', branch.repo_id.name, branch.name, sha)
|
_logger.debug('repo %s branch %s new build found revno %s', branch.repo_id.name, branch.name, sha)
|
||||||
v = {
|
v = {
|
||||||
'branch_id': branch.id,
|
'branch_id': branch.id,
|
||||||
@ -255,7 +262,12 @@ class runbot_repo(osv.osv):
|
|||||||
'author': author,
|
'author': author,
|
||||||
'subject': subject,
|
'subject': subject,
|
||||||
}
|
}
|
||||||
self.pool['runbot.build'].create(cr, uid, v)
|
Build.create(cr, uid, v)
|
||||||
|
|
||||||
|
# skip old builds (if their sequence number is too low, they will not ever be built)
|
||||||
|
skippable_domain = [('repo_id', '=', repo.id), ('state', '=', 'pending')]
|
||||||
|
to_be_skipped_ids = Build.search(cr, uid, skippable_domain, order='sequence', offset=repo.running)
|
||||||
|
Build.write(cr, uid, to_be_skipped_ids, {'state': 'done', 'result': 'skipped'})
|
||||||
|
|
||||||
def scheduler(self, cr, uid, ids=None, context=None):
|
def scheduler(self, cr, uid, ids=None, context=None):
|
||||||
for repo in self.browse(cr, uid, ids, context=context):
|
for repo in self.browse(cr, uid, ids, context=context):
|
||||||
@ -267,30 +279,22 @@ class runbot_repo(osv.osv):
|
|||||||
bo.schedule(cr, uid, build_ids)
|
bo.schedule(cr, uid, build_ids)
|
||||||
|
|
||||||
# launch new tests
|
# launch new tests
|
||||||
testing = bo.search(cr, uid, dom + [('state', '=', 'testing')], count=True)
|
testing = bo.search_count(cr, uid, dom + [('state', '=', 'testing')])
|
||||||
while testing < repo.testing:
|
pending = bo.search_count(cr, uid, dom + [('state', '=', 'pending')])
|
||||||
# select the next build to process
|
|
||||||
pending_ids = bo.search(cr, uid, dom + [('state', '=', 'pending')])
|
|
||||||
if pending_ids:
|
|
||||||
pending = bo.browse(cr, uid, pending_ids[0])
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
# gather information about currently running builds
|
while testing < repo.testing and pending > 0:
|
||||||
running_ids = bo.search(cr, uid, dom + [('state', '=', 'running')])
|
|
||||||
running_len = len(running_ids)
|
|
||||||
running_max = 0
|
|
||||||
if running_ids:
|
|
||||||
running_max = bo.browse(cr, uid, running_ids[0]).sequence
|
|
||||||
|
|
||||||
# determine if pending one should be launched
|
# find sticky pending build if any, otherwise, last pending (by id, not by sequence) will do the job
|
||||||
if running_len < repo.running or pending.sequence >= running_max:
|
pending_ids = bo.search(cr, uid, dom + [('state', '=', 'pending'), ('branch_id.sticky', '=', True)], limit=1)
|
||||||
pending.schedule()
|
if not pending_ids:
|
||||||
else:
|
pending_ids = bo.search(cr, uid, dom + [('state', '=', 'pending')], order="id desc")
|
||||||
break
|
|
||||||
|
|
||||||
# compute the number of testing job again
|
pending = bo.browse(cr, uid, pending_ids[0])
|
||||||
testing = bo.search(cr, uid, dom + [('state', '=', 'testing')], count=True)
|
pending.schedule()
|
||||||
|
|
||||||
|
# compute the number of testing and pending jobs again
|
||||||
|
testing = bo.search_count(cr, uid, dom + [('state', '=', 'testing')])
|
||||||
|
pending = bo.search_count(cr, uid, dom + [('state', '=', 'pending')])
|
||||||
|
|
||||||
# terminate and reap doomed build
|
# terminate and reap doomed build
|
||||||
build_ids = bo.search(cr, uid, dom + [('state', '=', 'running')])
|
build_ids = bo.search(cr, uid, dom + [('state', '=', 'running')])
|
||||||
@ -373,7 +377,7 @@ class runbot_branch(osv.osv):
|
|||||||
|
|
||||||
class runbot_build(osv.osv):
|
class runbot_build(osv.osv):
|
||||||
_name = "runbot.build"
|
_name = "runbot.build"
|
||||||
_order = 'sequence desc'
|
_order = 'id desc'
|
||||||
|
|
||||||
def _get_dest(self, cr, uid, ids, field_name, arg, context=None):
|
def _get_dest(self, cr, uid, ids, field_name, arg, context=None):
|
||||||
r = {}
|
r = {}
|
||||||
@ -690,8 +694,8 @@ class runbot_build(osv.osv):
|
|||||||
for build in self.browse(cr, uid, ids, context=context):
|
for build in self.browse(cr, uid, ids, context=context):
|
||||||
max_id = self.search(cr, uid, [('repo_id','=',build.repo_id.id)], order='id desc', limit=1)[0]
|
max_id = self.search(cr, uid, [('repo_id','=',build.repo_id.id)], order='id desc', limit=1)[0]
|
||||||
# Force it now
|
# Force it now
|
||||||
if build.state in ['pending']:
|
if build.state == 'done' and build.result == 'skipped':
|
||||||
build.write({ 'sequence':max_id })
|
build.write({'state': 'pending', 'sequence':max_id, 'result': '' })
|
||||||
# or duplicate it
|
# or duplicate it
|
||||||
elif build.state in ['running','done']:
|
elif build.state in ['running','done']:
|
||||||
d = {
|
d = {
|
||||||
|
@ -222,8 +222,8 @@
|
|||||||
<a t-attf-href="https://#{bu.repo_id.base}/commit/#{bu.name}" class="btn btn-default"><i class="fa fa-github"/></a>
|
<a t-attf-href="https://#{bu.repo_id.base}/commit/#{bu.name}" class="btn btn-default"><i class="fa fa-github"/></a>
|
||||||
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown"><i class="fa fa-cog"/><span class="caret"></span></button>
|
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown"><i class="fa fa-cog"/><span class="caret"></span></button>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li t-if="bu.state=='pending'">
|
<li t-if="bu.result=='skipped'">
|
||||||
<a t-attf-href="/runbot/build/{{bu.id}}/force">Build now <i class="fa fa-level-up"> </i></a>
|
<a t-attf-href="/runbot/build/{{bu.id}}/force">Force Build<i class="fa fa-level-up"> </i></a>
|
||||||
</li>
|
</li>
|
||||||
<t t-if="bu.state=='running'">
|
<t t-if="bu.state=='running'">
|
||||||
<li><a t-attf-href="http://{{bu.domain}}/?db={{bu.dest}}-all">Connect all <i class="fa fa-sign-in"></i></a></li>
|
<li><a t-attf-href="http://{{bu.domain}}/?db={{bu.dest}}-all">Connect all <i class="fa fa-sign-in"></i></a></li>
|
||||||
@ -233,11 +233,11 @@
|
|||||||
<li t-if="bu.state in ['done','running'] and bu_index==0">
|
<li t-if="bu.state in ['done','running'] and bu_index==0">
|
||||||
<a t-attf-href="/runbot/build/#{bu.id}/force">Rebuild <i class="fa fa-refresh"/></a>
|
<a t-attf-href="/runbot/build/#{bu.id}/force">Rebuild <i class="fa fa-refresh"/></a>
|
||||||
</li>
|
</li>
|
||||||
<li t-if="bu.state!='testing'" class="divider"></li>
|
<li t-if="bu.state!='testing' and bu.state!='pending'" class="divider"></li>
|
||||||
<li><a t-attf-href="/runbot/build/{{bu.id}}">Logs <i class="fa fa-file-text-o"/></a></li>
|
<li><a t-attf-href="/runbot/build/{{bu.id}}">Logs <i class="fa fa-file-text-o"/></a></li>
|
||||||
<li><a t-attf-href="/runbot/static/build/#{bu.dest}/logs/job_10_test_base.txt">Full base logs <i class="fa fa-file-text-o"/></a></li>
|
<li><a t-attf-href="/runbot/static/build/#{bu.dest}/logs/job_10_test_base.txt">Full base logs <i class="fa fa-file-text-o"/></a></li>
|
||||||
<li><a t-attf-href="/runbot/static/build/#{bu.dest}/logs/job_20_test_all.txt">Full all logs <i class="fa fa-file-text-o"/></a></li>
|
<li><a t-attf-href="/runbot/static/build/#{bu.dest}/logs/job_20_test_all.txt">Full all logs <i class="fa fa-file-text-o"/></a></li>
|
||||||
<li class="divider"></li>
|
<li t-if="bu.state!='pending'" class="divider"></li>
|
||||||
<li><a t-attf-href="{{bu.branch_id.branch_url}}">Branch or pull <i class="fa fa-github"/></a></li>
|
<li><a t-attf-href="{{bu.branch_id.branch_url}}">Branch or pull <i class="fa fa-github"/></a></li>
|
||||||
<li><a t-attf-href="https://{{bu.repo_id.base}}/commit/{{bu.name}}">Commit <i class="fa fa-github"/></a></li>
|
<li><a t-attf-href="https://{{bu.repo_id.base}}/commit/{{bu.name}}">Commit <i class="fa fa-github"/></a></li>
|
||||||
<li><a t-attf-href="https://{{bu.repo_id.base}}/compare/{{bu.branch_id.branch_name}}">Compare <i class="fa fa-github"/></a></li>
|
<li><a t-attf-href="https://{{bu.repo_id.base}}/compare/{{bu.branch_id.branch_name}}">Compare <i class="fa fa-github"/></a></li>
|
||||||
|
Loading…
Reference in New Issue
Block a user