Compare commits

44 Commits

Author SHA1 Message Date
a8c8e97946 Remove 291
Explicit setting of nighlty build usage
Disable most nightly jobs
2021-03-11 18:26:06 +01:00
f8ad6d9ef0 Add .arcconfig for easier code review. 2021-02-11 14:17:19 +01:00
ed11a51021 Add Blender 2.92 builder 2021-01-13 17:38:56 +01:00
5cc2ed5709 Disable 2.91 form nightly builds 2020-12-01 18:17:16 +01:00
7cf6ebf419 Remove 2.90 builder 2020-10-21 18:20:41 +02:00
03ded369b1 Add Blender 2.91 builder 2020-10-21 17:59:43 +02:00
e95d6accf5 Disable 2.90 builds from nightly scheduler 2020-09-21 10:42:47 +02:00
1ff732897d Buildbot: automatically build for all branches, not just master 2020-08-05 15:45:23 +02:00
dcbd1347c9 Buildbot: build automatically when git commits are made
But don't package and upload them, that only happens nightly still.
There will be one build per set of commits that arrives within 120s
of each other.

The idea behind this is that it will help us more easily find which
commits break the build or tests.

Differential Revision: https://developer.blender.org/D8438
2020-08-04 16:49:07 +02:00
f3436ff838 Buildbot: pass --codesign parameter required by latest worker scripts 2020-08-04 16:40:38 +02:00
Nathan Letwory
50ceaffaf8 Name builder 290 instead of beta. 2020-07-22 16:29:08 +03:00
Nathan Letwory
b6fc3c7f18 Add beta builder for 2.90 release branch. 2020-07-22 16:04:21 +03:00
fabedf6bfa Cleanup: Naming, use convention from buildbot upstream 2020-06-17 17:38:35 +02:00
67c034e3a0 Use more correct macOS builder name for 2.83 LTS
The deployment target is 10.9, but the host is running macOS 10.13
2020-06-16 16:56:21 +02:00
13e9f19ce3 Cleanup: Remove dead codepath related on rsync step
It was not used for a while, and it's not possible to rsync to the
server.

The reason why rsync step existed is because of upload performance.
But if FileUpload step is really not so much performant it is to be
fixed on Buildbot project side (or re-configured on our side to give
more suitable blocksize).
2020-06-16 10:13:23 +02:00
ee68c15433 Cleanup: Really make pep-8 complaint, fix terminology 2020-06-16 10:09:55 +02:00
5817ddd56a Use platform name as prefix
Allows to re-use existing logic on blender side, namely the
buildbot_util.py expects platform to be a prefix.
2020-06-16 09:45:38 +02:00
aeb56c6d3f Restrict single build per worker
Avoids too much of CPU burn and allows to more easily do codesign.
2020-06-16 09:43:59 +02:00
935a6f460f Buildbot: support force building master and lts branches again
But without the option to specify the branch name.
2020-06-15 18:05:08 +02:00
487b6f28e4 Fix syntax error in master private template 2020-06-15 18:03:57 +02:00
3cd1ea8005 Buildbot: add separate builders for master, lts and custom branches
This avoids too much rebuilding, and makes it easier to see which branches
are failing.
2020-06-15 17:38:34 +02:00
Nathan Letwory
ce6e2526d2 Enable nightly builds for 2.83 2020-04-15 16:33:41 +03:00
d4822bd0c3 Update Linux builder name in master_private_template.py
The template was still referencing `linux_glibc219_x86_64_cmake`,
while `master.cfg` is using `linux_glibc217_x86_64_cmake`. This caused
the slave to be silently ignored.
2020-04-14 12:34:40 +01:00
fc76dbf535 Revert "re-enable 2.82 branch for building for 2.82a release"
The website is not handling 'a' releases well, and the code is missing updates
needed for codesign.

This reverts commit 5c4f885e29.
2020-03-09 23:37:05 +01:00
5c4f885e29 re-enable 2.82 branch for building for 2.82a release 2020-03-09 23:14:07 +01:00
fdde89201e Disable 2.82 nightly scheduler 2020-02-12 19:14:16 +01:00
f653ad7ae7 Remove exception for experimental-build branch
It was replaced with using feature branches, which are easier
to keep track of.
2020-02-11 15:32:23 +01:00
e406a1118e Update python to 3.7 2020-02-05 17:29:29 +01:00
a910a05caa Don't replace daily build with release build of the same version
And simplify filename parsing for new conventions.
2020-02-04 13:32:32 +01:00
e7a7944965 Enable Blender-2.82 release branch builder 2020-01-10 10:19:41 +01:00
1ff1d2f2de Bump maximum upload size
For Windows releases we need to be able to push both ZIP and MSI
files which is more than old 200 MiB.
2019-11-20 17:20:52 +01:00
6baa608419 Disable 2.81 from nightly schedule 2019-11-20 16:45:44 +01:00
adbc6ebcea Commit local changes from server made by Brecht
Never, ever, ever such situation should happen.

From reading the change it seems it's related on making
it possible to build releases from the buildbot.
2019-11-08 09:24:53 +01:00
e0cd4f6d15 Make unpacker aware of XZ archives 2019-11-08 09:18:40 +01:00
72071394ff Bump max allowed upload size
macOS bundle became bigger than 180 megabytes.
2019-09-12 14:23:00 +02:00
d49aacbeae Stop build on update and package failures 2019-09-03 17:46:32 +02:00
21828fb997 Fix wrong permissions for branch download directory 2019-09-03 16:50:56 +02:00
14f01e9486 Auto remove branch builds older than 100 days 2019-09-03 16:21:06 +02:00
ab5646a13e Require sane branch names for force builds 2019-09-03 15:58:28 +02:00
98b1ab21a9 Support multiple packages in single upload, refactor unpack script 2019-09-03 14:12:53 +02:00
21d8fa089a Support building arbitrary branches 2019-09-03 14:12:53 +02:00
42b23d1c93 Pass branch name to all build slave scripts 2019-09-03 14:12:51 +02:00
ea470dc761 Move updating submodules and libraries to script in Blender repository
Ref D5545
2019-09-03 14:12:33 +02:00
6249edce8d Fix missing python3 command on Windows 2019-09-03 14:09:36 +02:00
4 changed files with 457 additions and 366 deletions

8
.arcconfig Normal file
View File

@@ -0,0 +1,8 @@
{
"project_id" : "Infrastructure: Blender Buildbot",
"conduit_uri" : "https://developer.blender.org/",
"phabricator.uri" : "https://developer.blender.org/",
"git.default-relative-commit" : "origin/master",
"arc.land.update.default" : "rebase",
"arc.land.onto.default" : "master"
}

View File

@@ -1,59 +1,92 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# -*- python -*-
# ex: set syntax=python:
# <pep8 compliant>
# List of the branches being built automatically overnight
NIGHT_SCHEDULE_BRANCHES = ["master"]
# List of the branches available for force build
FORCE_SCHEDULE_BRANCHES = ["master", "experimental-build"]
from buildbot.www.authz.roles import RolesFromBase
from buildbot.www.authz.roles import RolesFromOwner
from buildbot.steps.master import MasterShellCommand
from buildbot.steps.transfer import FileUpload
from buildbot.steps.shell import Test
from buildbot.steps.shell import Compile
from buildbot.steps.shell import ShellCommand
from buildbot.process.properties import Interpolate
from buildbot.process.factory import BuildFactory
from buildbot.plugins import steps, util
from buildbot.config import BuilderConfig
from buildbot.schedulers import timed, forcesched
from buildbot.schedulers.basic import SingleBranchScheduler
from buildbot.schedulers.filter import ChangeFilter
from buildbot.changes.gitpoller import GitPoller
from buildbot.changes.svnpoller import SVNPoller
from buildbot.worker import Worker
# List of branches availble for addons branch selection.
ADDONS_BRANCHES = ["master"]
from datetime import timedelta
# List of branches availble for libraries branch selection.
LIB_BRANCHES = ["trunk"]
# NOTE: We load the workers and their passwords from a separator file, so we can
# have # this one in Git.
import master_private
# Dictionary that the buildmaster pays attention to.
c = BuildmasterConfig = {}
# BUILD WORKERS
#
# We load the slaves and their passwords from a separator file, so we can have
# this one in SVN.
# Project identity.
c['projectName'] = 'Blender'
c['projectURL'] = 'https://www.blender.org/'
c['title'] = 'Blender'
c['titleURL'] = 'https://builder.blender.org/'
from buildbot.worker import Worker
import master_private
# Buildbot information.
c['buildbotURL'] = 'https://builder.blender.org/admin/'
c['buildbotNetUsageData'] = 'basic'
# Various.
c['db_url'] = 'sqlite:///state.sqlite'
# Disable sending of 'buildbotNetUsageData' for now, to improve startup time.
c['buildbotNetUsageData'] = None
################################################################################
# BUILD WORKERS
c['workers'] = []
for slave in master_private.slaves:
c['workers'].append(Worker(slave['name'], slave['password']))
for worker in master_private.workers:
c['workers'].append(
Worker(worker['name'], worker['password'], max_builds=1))
# TCP port through which slaves connect
# TCP port through which workers connect
c['protocols'] = {
"pb": {
"port": "tcp:{}".format(9989)
'pb': {
'port': 'tcp:{}'.format(9989)
}
}
# CHANGE SOURCES
from buildbot.changes.svnpoller import SVNPoller
from buildbot.changes.gitpoller import GitPoller
c['change_source'] = GitPoller('git://git.blender.org/blender.git',
pollinterval=1200)
################################################################################
# CODEBASES
#
# Allow to control separately things like branches for each repo and submodules.
all_repositories = {
r'git://git.blender.org/blender.git': 'blender',
r'git://git.blender.org/blender-translations.git': 'blender-translations',
r'git://git.blender.org/blender-addons.git': 'blender-addons',
r'git://git.blender.org/blender-addons-contrib.git': 'blender-addons-contrib',
r'git://git.blender.org/blender-dev-tools.git': 'blender-dev-tools',
r'https://svn.blender.org/svnroot/bf-blender/': 'lib svn',
}
@@ -65,179 +98,130 @@ def codebaseGenerator(chdict):
c['codebaseGenerator'] = codebaseGenerator
################################################################################
# SCHEDULERS
#
# Decide how to react to incoming changes.
from buildbot.schedulers import timed, forcesched
c['schedulers'] = []
def schedule_force_build(name):
def schedule_force_build(name, branch):
"""
Makes it possible to have "Force Build" for the given builder.
Makes sure only reasonabel subset of properties are exposed.
Makes sure only reasonable subset of properties are exposed.
"""
if branch != '':
branch_parameter = forcesched.FixedParameter(
name='branch',
default=branch,
hide=True)
else:
branch_parameter = forcesched.StringParameter(
name='branch',
label='Branch:',
default='custom-branch-name-here',
regex=r'^[a-zA-Z0-9][A-Za-z0-9\._-]*$')
c['schedulers'].append(forcesched.ForceScheduler(
name='force_' + name,
buttonName="Force Build",
buttonName='Force Build',
builderNames=[name],
codebases=[forcesched.CodebaseParameter(
codebase="blender",
branch=forcesched.ChoiceStringParameter(
name="branch",
choices=FORCE_SCHEDULE_BRANCHES,
default="master"),
# Do not hide revision, can be handy!
codebase='blender',
branch=branch_parameter,
# Hide revision. We don't want to allow anyone to overwrite the
# master build with an older version. Could be added back once we
# have authentication.
revision=forcesched.FixedParameter(
name='revision',
default='',
hide=True),
repository=forcesched.FixedParameter(
name="repository",
default="",
name='repository',
default='',
hide=True),
project=forcesched.FixedParameter(
name="project",
default="",
name='project',
default='',
hide=True)),
# For now, hide other codebases.
forcesched.CodebaseParameter(
hide=True,
codebase="blender-translations"),
forcesched.CodebaseParameter(
codebase="blender-addons",
branch=forcesched.ChoiceStringParameter(
name="branch",
choices=ADDONS_BRANCHES,
default="master"),
repository=forcesched.FixedParameter(name="repository",
default="",
hide=True),
project=forcesched.FixedParameter(name="project",
default="",
hide=True),
revision=forcesched.FixedParameter(name="revision",
default="",
hide=True),
),
forcesched.CodebaseParameter(
codebase="blender-addons-contrib",
branch=forcesched.ChoiceStringParameter(
name="branch",
choices=ADDONS_BRANCHES,
default="master"),
repository=forcesched.FixedParameter(name="repository",
default="",
hide=True),
project=forcesched.FixedParameter(name="project",
default="",
hide=True),
revision=forcesched.FixedParameter(name="revision",
default="",
hide=True),
),
forcesched.CodebaseParameter(
hide=True,
codebase="blender-dev-tools"),
forcesched.CodebaseParameter(
codebase="lib svn",
branch=forcesched.ChoiceStringParameter(
name="branch",
choices=LIB_BRANCHES,
default="trunk"),
repository=forcesched.FixedParameter(name="repository",
default="",
hide=True),
project=forcesched.FixedParameter(name="project",
default="",
hide=True),
revision=forcesched.FixedParameter(name="revision",
default="",
hide=True),
),
],
properties=[]))
]))
def schedule_nightly_build(name, hour, minute=0):
def schedule_nightly_build(name, branch, hour, minute=0):
"""
Creates scheduler for nightly builds for a given builder.
"""
for current_branch in NIGHT_SCHEDULE_BRANCHES:
scheduler_name = "nightly_" + name
if current_branch:
scheduler_name += ' ' + current_branch
addons_branch = "master"
scheduler_name = f'nightly_{name} {branch}'
c['schedulers'].append(timed.Nightly(
name=scheduler_name,
codebases={
"blender": {"repository": "",
"branch": current_branch},
"blender-translations": {"repository": "",
"branch": "master"},
"blender-addons": {"repository": "",
"branch": addons_branch},
"blender-addons-contrib": {"repository": "",
"branch": addons_branch},
"blender-dev-tools": {"repository": "",
"branch": "master"},
"lib svn": {"repository": "",
"branch": "trunk"}},
branch=current_branch,
'blender': {'repository': '',
'branch': branch}},
branch=branch,
builderNames=[name],
hour=hour,
minute=minute))
def schedule_change_build(name, branch):
"""
Creates scheduler for building on changes.
This will not package and upload the build.
"""
scheduler_name = f'change_{name} {branch}'
c['schedulers'].append(SingleBranchScheduler(
name=scheduler_name,
codebases={
'blender': {'repository': '',
'branch': branch}},
builderNames=[name],
treeStableTimer=120,
change_filter=ChangeFilter(project=['blender'], branch=branch),
properties={'skip_upload': True, 'skip_codesign': True}))
################################################################################
# BUILDERS
#
# The 'builders' list defines the Builders, which tell Buildbot how to
# perform a build: what steps, and which slaves can execute them.
# Note that any particular build will only take place on one slave.
from buildbot.config import BuilderConfig
from buildbot.plugins import steps, util
from buildbot.process.factory import BuildFactory
from buildbot.process.properties import Interpolate
from buildbot.steps.shell import ShellCommand
from buildbot.steps.shell import Compile
from buildbot.steps.shell import Test
from buildbot.steps.transfer import FileUpload
from buildbot.steps.master import MasterShellCommand
# add builder utility
# perform a build: what steps, and which workers can execute them.
# Note that any particular build will only take place on one worker.
c['builders'] = []
buildernames = []
builders_all_branches = set()
def add_builder(c, name, libdir, factory, branch='',
rsync=False, hour=3, minute=0):
# Add builder utility.
def add_builder(c, name, platforms, factory, branch='', hour=3, minute=0, use_nightly_builder=True):
if branch != '':
builders_all_branches.add(branch)
for platform in platforms:
workernames = []
builder_name = f'{name}_{platform}'
for slave in master_private.slaves:
if name in slave['builders']:
workernames.append(slave['name'])
for worker in master_private.workers:
if platform == worker['platform']:
workernames.append(worker['name'])
builder_name = f"{worker['platform_short']}_{name}"
if workernames:
f = factory(name, libdir, branch, rsync)
c['builders'].append(BuilderConfig(name=name,
f = factory(builder_name, branch)
c['builders'].append(BuilderConfig(name=builder_name,
workernames=workernames,
factory=f,
tags=['blender']))
buildernames.append(name)
schedule_nightly_build(name, hour, minute)
schedule_force_build(name)
if use_nightly_builder:
schedule_nightly_build(builder_name, branch, hour, minute)
schedule_change_build(builder_name, branch)
schedule_force_build(builder_name, branch)
# common steps
def git_submodule_step(submodule):
return steps.Git(name=submodule + '.git',
repourl='git://git.blender.org/' + submodule + '.git',
mode='incremental',
codebase=submodule,
workdir=submodule + '.git')
# Common steps.
def git_step(branch=''):
if branch:
@@ -257,96 +241,118 @@ def git_step(branch=''):
submodules=True)
def git_submodules_update():
command = ['git', 'submodule', 'update', '--remote']
return ShellCommand(name='Submodules Update',
command=command,
description='updating',
descriptionDone='up to date',
workdir='blender.git')
# Generic builder.
def do_upload(step):
return not step.hasProperty('skip_upload')
def lib_svn_step(dir):
# TODO(sergey): For some reason interpolation is always giving empty branch.
# lib_repo = 'https://svn.blender.org/svnroot/bf-blender/%(src::branch)s/lib/'
lib_repo = 'https://svn.blender.org/svnroot/bf-blender/trunk/lib/'
return steps.SVN(name='lib svn ' + dir,
repourl=util.Interpolate(lib_repo + dir),
codebase='lib svn',
mode='incremental',
workdir='lib/' + dir)
@util.renderer
def script_command(props, script, id, branch):
# NOTE: On Windows never includes major version in the executable name,
# so Python 3 will have be 'python.exe'.
if id.startswith('win'):
python_command = 'python'
else:
python_command = 'python3'
git_branch = branch or Interpolate('%(src:blender:branch)s')
args = [python_command, script, id, git_branch]
def rsync_step(id, branch, rsync_script):
return ShellCommand(name='rsync',
command=['python3', rsync_script, id, branch],
description='uploading',
descriptionDone='uploaded',
workdir='install')
if not props.hasProperty('skip_codesign'):
args += ['--codesign']
return args
# generic builder
def generic_builder(id, libdir='', branch='', rsync=False):
filename = 'uploaded/buildbot_upload_' + id + '.zip'
compile_script = '../blender.git/build_files/buildbot/slave_compile.py'
test_script = '../blender.git/build_files/buildbot/slave_test.py'
pack_script = '../blender.git/build_files/buildbot/slave_pack.py'
rsync_script = '../blender.git/build_files/buildbot/slave_rsync.py'
def generic_builder(id, branch=''):
# TODO(sergey): Consider using pathlib.
filename = f'uploaded/buildbot_upload_{id}.zip'
update_script = '../blender.git/build_files/buildbot/worker_update.py'
compile_script = '../blender.git/build_files/buildbot/worker_compile.py'
test_script = '../blender.git/build_files/buildbot/worker_test.py'
pack_script = '../blender.git/build_files/buildbot/worker_pack.py'
unpack_script = 'master_unpack.py'
f = BuildFactory()
if libdir != '':
f.addStep(lib_svn_step(libdir))
f.addStep(lib_svn_step('tests'))
for submodule in ('blender-translations',
'blender-addons',
'blender-addons-contrib',
'blender-dev-tools'):
f.addStep(git_submodule_step(submodule))
f.addStep(git_step(branch))
f.addStep(git_submodules_update())
f.addStep(Compile(command=['python3', compile_script, id], timeout=3600))
f.addStep(Test(command=['python3', test_script, id]))
f.addStep(ShellCommand(
name='submodules and libraries update',
command=script_command.withArgs(update_script, id, branch),
description='updating',
descriptionDone='updated',
haltOnFailure=True))
f.addStep(Compile(
command=script_command.withArgs(compile_script, id, branch),
timeout=3600))
f.addStep(Test(
command=script_command.withArgs(test_script, id, branch)))
f.addStep(ShellCommand(
name='package',
command=['python3',
pack_script,
id,
branch or Interpolate('%(src:blender:branch)s')],
command=script_command.withArgs(pack_script, id, branch),
description='packaging',
descriptionDone='packaged'))
if rsync:
f.addStep(rsync_step(id, branch, rsync_script))
else:
descriptionDone='packaged',
haltOnFailure=True,
doStepIf=do_upload))
f.addStep(FileUpload(name='upload',
workersrc='buildbot_upload.zip',
masterdest=filename,
maxsize=180 * 1024 * 1024,
workdir='install'))
maxsize=500 * 1024 * 1024,
workdir='install',
doStepIf=do_upload))
f.addStep(MasterShellCommand(name='unpack',
command=['python3.6',
command=['python3.7',
unpack_script,
filename],
description='unpacking',
descriptionDone='unpacked'))
descriptionDone='unpacked',
doStepIf=do_upload))
return f
################################################################################
# Builders
add_builder(c, 'mac_x86_64_10_9_cmake', 'darwin', generic_builder, hour=1)
add_builder(c, 'linux_glibc217_x86_64_cmake', '', generic_builder, hour=1)
# NOTE: Visual Studio 2017 (vc15) is using libraries folder from
# Visual Studio 2015 (vc14)
add_builder(c, 'win64_cmake_vs2017', 'win64_vc14', generic_builder, hour=1)
add_builder(c,
'master',
['windows', 'macOS_10_15', 'linux_centos7'],
generic_builder,
branch='master',
hour=1,
use_nightly_builder=True)
add_builder(c,
'292',
['windows', 'macOS_10_15', 'linux_centos7'],
generic_builder,
branch='blender-v2.92-release',
hour=1,
use_nightly_builder=False)
add_builder(c,
'lts_283',
['windows', 'macOS_10_13', 'linux_centos7'],
generic_builder,
branch='blender-v2.83-release',
hour=1,
use_nightly_builder=False)
add_builder(c,
'custom_branch',
['windows', 'macOS_10_15', 'linux_centos7'],
generic_builder,
branch='',
hour=1,
use_nightly_builder=False)
################################################################################
# CHANGE SOURCES
c['change_source'] = GitPoller(repourl='git://git.blender.org/blender.git',
pollinterval=120,
project='blender',
branches=list(builders_all_branches))
################################################################################
# HORIZONS
from datetime import timedelta
c['changeHorizon'] = 300
@@ -358,15 +364,17 @@ c['configurators'] = [util.JanitorConfigurator(
dayOfWeek=6)]
################################################################################
# WWW
c['www'] = dict(port=8010,
plugins={'console_view': {},
'grid_view': {},
'waterfall_view': {}})
################################################################################
# Access
from buildbot.www.authz.roles import RolesFromOwner
from buildbot.www.authz.roles import RolesFromBase
class StrangerRoles(RolesFromBase):
def getRolesFromUser(self, userDetails):
@@ -374,42 +382,31 @@ class StrangerRoles(RolesFromBase):
authz = util.Authz(
stringsMatcher=util.fnmatchStrMatcher, # simple matcher with '*' glob character
# stringsMatcher = util.reStrMatcher, # if you prefer regular expressions
# Simple matcher with '*' glob character.
# Could be util.reStrMatcher if regular expressions are preferred.
stringsMatcher=util.fnmatchStrMatcher,
allowRules=[
# admins can do anything,
# defaultDeny=False: if user does not have the admin role, we continue parsing rules
util.AnyEndpointMatcher(role="admins", defaultDeny=False),
# Admins can do anything,
#
# defaultDeny=False: if user does not have the admin role, we continue
# parsing rules
util.AnyEndpointMatcher(role='admins', defaultDeny=False),
# Defaulting old config, everyone can stop build.
util.StopBuildEndpointMatcher(role="stranger"),
util.ForceBuildEndpointMatcher(role="stranger"),
util.RebuildBuildEndpointMatcher(role="stranger"),
util.EnableSchedulerEndpointMatcher(role="admins"),
util.StopBuildEndpointMatcher(role='stranger'),
util.ForceBuildEndpointMatcher(role='stranger'),
util.RebuildBuildEndpointMatcher(role='stranger'),
util.EnableSchedulerEndpointMatcher(role='admins'),
# if future Buildbot implement new control, we are safe with this last rule
# If future Buildbot implement new control, we are safe with this last
# rule.
#
# NOTE: This prevents us from cancelling queue, so disabled for now.
# util.AnyControlEndpointMatcher(role="admins")
# util.AnyControlEndpointMatcher(role='admins')
],
roleMatchers=[
RolesFromOwner(role="owner"),
RolesFromOwner(role='owner'),
StrangerRoles(),
])
c['www']['authz'] = authz
# PROJECT IDENTITY
c['projectName'] = "Blender"
c['projectURL'] = "https://www.blender.org"
# Buildbot information
c['buildbotURL'] = "https://builder.blender.org/admin/"
c['buildbotNetUsageData'] = 'basic'
# Various
c['db_url'] = "sqlite:///state.sqlite"
c['title'] = "Blender"
c['titleURL'] = "https://builder.blender.org/"
# Disable sending of 'buildbotNetUsageData' for now, to improve startup time.
c['buildbotNetUsageData'] = None

View File

@@ -1,5 +1,18 @@
slaves = [
{'name': 'linux_glibc219_x86_64_chroot',
'password': 'barbarianna',
'builders': ['linux_glibc219_x86_64_cmake']}
workers = [
{'name': 'linux_something_something',
'password': 'something',
'platform': 'linux_centos7',
'platform_short': 'linux'},
{'name': 'macOS_10_15_something_something',
'password': 'something',
'platform': 'macOS_10_15',
'platform_short': 'macos'},
{'name': 'macOS_10_13_something_something',
'password': 'something',
'platform': 'macOS_10_13',
'platform_short': 'macos'},
{'name': 'windows_something_something',
'password': 'something',
'platform': 'windows',
'platform_short': 'windows'}
]

View File

@@ -21,129 +21,202 @@
# <pep8 compliant>
import argparse
import os
import shutil
import sys
import time
import zipfile
DOWNLOAD_DIR = "/data/www/vhosts/builder.blender.org/webroot/download/"
# Parse package filename to extract branch and platform
class Package:
def __init__(self, zipname):
self.zipname = zipname
self.filename = os.path.basename(zipname)
self.version = ""
self.branch = ""
self.platform = ""
self.parsed = False
self.parse_filename()
# extension stripping
def strip_extension(filename):
extensions = '.zip', '.tar', '.bz2', '.gz', '.tgz', '.tbz', '.exe'
for ext in extensions:
if filename.endswith(ext):
filename = filename[:-len(ext)]
def _strip_extension(self, filename):
filename, _ = os.path.splitext(filename)
if filename.endswith('.tar'):
filename, _ = os.path.splitext(filename)
return filename
# extract platform from package name
def get_platform(filename):
# name is blender-version-platform.extension. we want to get the
# platform out, but there may be some variations, so we fiddle a
# bit to handle current and hopefully future names
filename = strip_extension(filename)
filename = strip_extension(filename)
def parse_filename(self):
# Name is one one of:
# blender-version-platform: official release
# blender-version-hash-platform: daily build
# branch-blender-version-hash-platform: branch build
filename = self._strip_extension(self.filename)
tokens = filename.split("-")
if len(tokens) < 3:
return
if "blender" not in tokens:
return
blender_index = tokens.index("blender")
if not (blender_index + 2 < len(tokens)):
return
# Detect branch.
branch = "-".join(tokens[:blender_index])
# Detect version.
if branch == "":
version = tokens[blender_index + 1]
if len(tokens) == 3:
version += " release"
else:
version = ""
# Detect platform.
platform = tokens[-1]
platforms = ('osx', 'mac', 'bsd',
'win', 'linux', 'source',
'irix', 'solaris', 'mingw')
platform_tokens = []
found = False
platform_found = False
for name in platforms:
if platform.lower().startswith(name):
platform_found = True
if not platform_found:
return
for i, token in enumerate(tokens):
if not found:
for platform in platforms:
if platform in token.lower():
found = True
break
self.version = version
self.platform = platform
self.branch = branch
self.parsed = True
if found:
platform_tokens += [token]
return '-'.join(platform_tokens)
def get_branch(filename):
tokens = filename.split("-")
branch = ""
for token in tokens:
if token == "blender":
return branch
if branch == "":
branch = token
def get_download_dir(branch):
if not branch or branch == 'master':
directory = DOWNLOAD_DIR
else:
branch = branch + "-" + token
directory = os.path.join(DOWNLOAD_DIR, branch)
os.makedirs(directory, exist_ok=True)
os.chmod(directory, 0o755)
return ""
return directory
# get filename
if len(sys.argv) < 2:
sys.stderr.write("Not enough arguments, expecting file to unpack\n")
sys.exit(1)
filename = sys.argv[1]
# open zip file
def open_zipfile(filename):
# Open zip file
if not os.path.exists(filename):
sys.stderr.write("File %r not found.\n" % filename)
sys.exit(1)
try:
z = zipfile.ZipFile(filename, "r")
return zipfile.ZipFile(filename, "r")
except Exception as ex:
sys.stderr.write('Failed to open zip file: %s\n' % str(ex))
sys.exit(1)
if len(z.namelist()) != 1:
sys.stderr.write("Expected one file in %r." % filename)
def get_zipfile_packages(zipfile):
# List packages in zip file
packages = [Package(zipname) for zipname in zipfile.namelist()]
for package in packages:
if not package.parsed:
sys.stderr.write("Failed to parse package filename: %s\n" % str(package.filename))
sys.exit(1)
if len(packages) == 0:
sys.stderr.write('Empty zip file\n')
sys.exit(1)
return packages
package = z.namelist()[0]
packagename = os.path.basename(package)
# detect platform and branch
platform = get_platform(packagename)
branch = get_branch(packagename)
def get_branch_platform(packages):
# Extract branch and platform names
branch = packages[0].branch
platform = packages[0].platform
version = packages[0].version
if platform == '':
sys.stderr.write('Failed to detect platform ' +
'from package: %r\n' % packagename)
'from package: %r\n' % packages[0].filename)
sys.exit(1)
# extract
download_prefix = "/data/www/vhosts/builder.blender.org/webroot/download/"
if not branch or branch == 'master':
directory = download_prefix
elif branch == 'experimental-build':
directory = os.path.join(download_prefix, "experimental")
else:
directory = download_prefix
for package in packages:
if package.branch != branch or package.platform != platform or package.version != version:
sys.stderr.write('All packages in the zip file must have the same branch and platform\n')
sys.exit(1)
return branch, platform, version
def extract_zipfile_packages(zipfile, packages, branch):
# Extract packages from zip file
directory = get_download_dir(branch)
for package in packages:
filepath = os.path.join(directory, package.filename)
try:
filename = os.path.join(directory, packagename)
zf = z.open(package)
f = open(filename, "wb")
zf = zipfile.open(package.zipname)
f = open(filepath, "wb")
shutil.copyfileobj(zf, f)
os.chmod(filename, 0o644)
os.chmod(filepath, 0o644)
zf.close()
z.close()
except Exception as ex:
sys.stderr.write('Failed to unzip package: %s\n' % str(ex))
sys.exit(1)
# remove other files from the same platform and branch
def remove_replaced_packages(branch, platform, version, new_packages):
# Remove other files from the same platform and branch that are replaced
# by the new packages.
directory = get_download_dir(branch)
for filename in os.listdir(directory):
package = Package(filename)
if package.platform == platform and package.branch == branch and package.version == version:
is_new_package = False
for new_package in new_packages:
if package.filename == new_package.filename:
is_new_package = True
if not is_new_package:
try:
for f in os.listdir(directory):
if get_platform(f) == platform and get_branch(f) == branch:
if f != packagename:
os.remove(os.path.join(directory, f))
print("Removing older package version", filename)
os.remove(os.path.join(directory, filename))
except Exception as ex:
sys.stderr.write('Failed to remove old packages: %s\n' % str(ex))
sys.exit(1)
sys.stderr.write('Failed to remove replaced package: %s\n' % str(ex))
def remove_old_packages():
# Remove any branch packages that are 100 days or older.
cutoff_time = time.time() - 100 * 86400
for dirname in os.listdir(DOWNLOAD_DIR):
dirpath = os.path.join(DOWNLOAD_DIR, dirname)
if not os.path.isdir(dirpath):
continue
for filename in os.listdir(dirpath):
filepath = os.path.join(dirpath, filename)
if not os.path.isfile(filepath):
continue
file_mtime = os.stat(filepath).st_mtime
if file_mtime < cutoff_time:
try:
print("Removing old branch build", filename)
os.remove(filepath)
except Exception as ex:
sys.stderr.write('Failed to remove old package: %s\n' % str(ex))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('filename')
args = parser.parse_args()
with open_zipfile(args.filename) as zipfile:
packages = get_zipfile_packages(zipfile)
branch, platform, version = get_branch_platform(packages)
extract_zipfile_packages(zipfile, packages, branch)
remove_replaced_packages(branch, platform, version, packages)
remove_old_packages()