diff --git a/playbooks/groups/taskotron-dev.yml b/playbooks/groups/taskotron-dev.yml index 5907caf9ee..d5da19389b 100644 --- a/playbooks/groups/taskotron-dev.yml +++ b/playbooks/groups/taskotron-dev.yml @@ -66,6 +66,7 @@ - { role: taskotron/grokmirror, tags: ['grokmirror'] } # - { role: taskotron/cgit, tags: ['cgit'] } - { role: taskotron/buildmaster, tags: ['buildmaster'] } + - { role: taskotron/buildmaster-configure, tags: ['buildmasterconfig'] } # - { role: taskotron/taskotron-trigger, tags: ['trigger'] } # - { role: taskotron/taskotron-frontend, tags: ['frontend'] } diff --git a/roles/taskotron/buildmaster-configure/defaults/main.yml b/roles/taskotron/buildmaster-configure/defaults/main.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/roles/taskotron/buildmaster-configure/tasks/main.yml b/roles/taskotron/buildmaster-configure/tasks/main.yml new file mode 100644 index 0000000000..1b525e3881 --- /dev/null +++ b/roles/taskotron/buildmaster-configure/tasks/main.yml @@ -0,0 +1,22 @@ +- name: create master + command: creates={{ buildmaster_dir }} buildbot create-master -r {{ buildmaster_dir }} + +- name: upload master config + template: src={{ templates }}/buildmaster/{{ buildmaster_template }} dest={{ buildmaster_dir }}/master.cfg owner={{ master_user }} group={{ master_user }} + +- name: check master config + command: buildbot checkconfig {{ buildmaster_dir }} + +#- name: upgrade master +# command: buildbot upgrade-master {{ buildmaster_dir }} + +- name: generate buildmaster service file + template: src={{ templates }}/buildmaster/buildmaster.service.j2 dest=/lib/systemd/system/buildmaster.service owner=root group=root mode=0744 + sudo_user: root + +- name: start and enable buildmaster service + service: name=buildmaster enabled=yes state=started + sudo_user: root + +- name: reconfig master + command: buildbot reconfig {{ buildmaster_dir }} diff --git a/roles/taskotron/buildmaster-configure/templates/buildmaster.service.j2 b/roles/taskotron/buildmaster-configure/templates/buildmaster.service.j2 new file mode 100644 index 0000000000..980c00473b --- /dev/null +++ b/roles/taskotron/buildmaster-configure/templates/buildmaster.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=Buildmaster for taskbot +After=network.target + +[Service] +Type=forking +PIDFile={{ buildmaster_dir }}/twistd.pid +ExecStart=/bin/buildbot start {{ buildmaster_dir }} +ExecStop=/bin/buildbot stop {{ buildmaster_dir }} +ExecReload=/bin/buildbot reconfig {{ buildmaster_dir }} +User={{ master_user }} +Group={{ master_user }} + +[Install] +WantedBy=multi-user.target diff --git a/roles/taskotron/buildmaster-configure/templates/taskotron.master.cfg.j2 b/roles/taskotron/buildmaster-configure/templates/taskotron.master.cfg.j2 new file mode 100644 index 0000000000..5074b77600 --- /dev/null +++ b/roles/taskotron/buildmaster-configure/templates/taskotron.master.cfg.j2 @@ -0,0 +1,235 @@ +# -*- python -*- +# ex: set syntax=python: + +# This is a sample buildmaster config file. It must be installed as +# 'master.cfg' in your buildmaster's base directory. + +# This is the dictionary that the buildmaster pays attention to. We also use +# a shorter alias to save typing. +c = BuildmasterConfig = {} + +####### BUILDSLAVES + +# The 'slaves' list defines the set of recognized buildslaves. Each element is +# a BuildSlave object, specifying a unique slave name and password. The same +# slave name and password must be configured on the slave. +from buildbot.buildslave import BuildSlave +c['slaves'] = [ + {% for buildslave in buildslaves %} + BuildSlave("{{ buildslave }}", "{{ buildslave_pw }}"), + {% endfor %} + ] + +# 'slavePortnum' defines the TCP port to listen on for connections from slaves. +# This must match the value configured into the buildslaves (with their +# --master option) +c['slavePortnum'] = {{ buildslave_port }} + +####### CHANGESOURCES + +# the 'change_source' setting tells the buildmaster how it should find out +# about source code changes. Here we point to the buildbot clone of pyflakes. + +#from buildbot.changes.gitpoller import GitPoller +#c['change_source'] = [] +#c['change_source'].append(GitPoller( +# 'gitolite3@localhost:exampletrigger', +# workdir='gitpoller-workdir', branch='master', +# pollinterval=300)) + +#c['change_source'].append(GitPoller( +# 'git://github.com/buildbot/pyflakes.git', +# workdir='gitpoller-workdir', branch='master', +# pollinterval=300)) +####### SCHEDULERS + +# Configure the Schedulers, which decide how to react to incoming changes. In this +# case, just kick off a 'runtests' build + +from buildbot.schedulers.basic import SingleBranchScheduler +from buildbot.schedulers.forcesched import ForceScheduler, StringParameter +from buildbot.changes import filter +from buildbot.schedulers.basic import BaseBasicScheduler + +class JobScheduler(BaseBasicScheduler): + + def __init__(self, name, **kwargs): + BaseBasicScheduler.__init__(self, name, **kwargs) + + def getChangeFilter(self, branch, branches, change_filter, categories): + return filter.ChangeFilter.fromSchedulerConstructorArgs( + change_filter=change_filter, categories=categories) + + def getTimerNameForChange(self, changes): + return "only" + + def getChangeClassificationsForTimer(self, objectid, timer_name): + return self.master.db.schedulers.getChangeClassifications( + self.objectid) + +c['schedulers'] = [] +c['schedulers'].append(JobScheduler( + name="jobsched-noarch", + builderNames=["all"], + change_filter=filter.ChangeFilter(project='rpmcheck', + category='noarch'))) + +c['schedulers'].append(JobScheduler( + name="jobsched-i386", + builderNames=['i386'], + change_filter=filter.ChangeFilter(project='rpmcheck', + category='i386'))) + +c['schedulers'].append(JobScheduler( + name="jobsched-x86_64", + builderNames=['x86_64'], + change_filter=filter.ChangeFilter(project='rpmcheck', + category='x86_64'))) + +#c['schedulers'].append(SingleBranchScheduler( +# name="all", +# change_filter=filter.ChangeFilter(branch='master'), +# treeStableTimer=None, +# builderNames=["all", 'x86_64', 'i386'])) +c['schedulers'].append(ForceScheduler( + name="force", + builderNames=["all", 'x86_64', 'i386'])) +c['schedulers'].append(ForceScheduler( + name="rpmcheck", + builderNames=["all", 'x86_64', 'i386'], + properties=[ + StringParameter(name='taskname', + label='name of check to run', + default='', + size=256), + StringParameter(name='item', + label='object to use', + default='', + size=256), + StringParameter(name='item_type', + label='type of object to use', + default='', + size=256), + StringParameter(name='arch', + label='arch of rpm to test', + default='x86_64', + size=128)])) + +####### 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.process.factory import BuildFactory +from buildbot.steps.source.git import Git +from buildbot.steps.shell import ShellCommand +from buildbot.process.properties import Property, Interpolate +from buildbot.steps.slave import RemoveDirectory + +factory = BuildFactory() + +# clean out /var/tmp/taskotron (see T253) +factory.addStep(RemoveDirectory(dir="/var/tmp/taskotron/")) + +# clean the log (see T230) +factory.addStep(ShellCommand(command=["rm", "-f", "/var/log/taskotron/taskotron.log"], name="rm_log")) + +# check out the source +factory.addStep(Git(repourl=Interpolate('{{ grokmirror_user }}@{{ buildmaster }}:/var/lib/git/mirror/fedoraqa/%(prop:taskname)s/'), + mode='full', method='clobber')) + +# run the runner +factory.addStep(ShellCommand(command=["runtask", '-i', + Interpolate('%(prop:item)s'), '-t', + Interpolate('%(prop:item_type)s'), + '-a', Interpolate('%(prop:arch)s'), + '-j', Interpolate('%(prop:buildername)s/%(prop:buildnumber)s'), + Interpolate('%(prop:taskname)s.yml')], + name='runtask')) + +# disabling this for now until all the logging changes are pushed +# print the log (see T230) +#factory.addStep(ShellCommand(command=["cat", "/var/log/taskotron/taskotron.log"], name="cat_log")) + +from buildbot.config import BuilderConfig + +c['builders'] = [] +c['builders'].append( + BuilderConfig(name="x86_64", + slavenames=[{% for buildslave in x86_64_buildslaves %}"{{ buildslave }}",{% endfor %}], + factory=factory)) + +c['builders'].append( + BuilderConfig(name="i386", + slavenames=[{% for buildslave in i386_buildslaves %}"{{ buildslave }}",{% endfor %}], + factory=factory)) + +c['builders'].append( + BuilderConfig(name="all", + slavenames=[{% for buildslave in buildslaves %}"{{ buildslave }}",{% endfor %}], + factory=factory)) + +####### STATUS TARGETS + +# 'status' is a list of Status Targets. The results of each build will be +# pushed to these targets. buildbot/status/*.py has a variety to choose from, +# including web pages, email senders, and IRC bots. + +c['status'] = [] + +from buildbot.status import html +from buildbot.status.web import authz, auth + +authz_cfg=authz.Authz( + # change any of these to True to enable; see the manual for more + # options + auth=auth.BasicAuth([("{{ buildbot_user }}","{{ buildbot_pw }}")]), + gracefulShutdown = False, + forceBuild = 'auth', # use this to test your slave once it is set up + forceAllBuilds = False, + pingBuilder = False, + stopBuild = False, + stopAllBuilds = False, + cancelPendingBuild = False, +) +c['status'].append(html.WebStatus(http_port=8080, authz=authz_cfg, + change_hook_dialects={'base':True})) +c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg)) + +#from buildbot.status.mail import MailNotifier +# +#mn = MailNotifier(fromaddr="yagisama@gmail.com", +# sendToInterestedUsers=False, +# extraRecipients=["goat@tirfa.com"], +# useTls=True, relayhost="smtp.gmail.com", smtpPort=587, +# smtpUser="yagisama", smtpPassword="Somehw3r", +# mode='all') +# +#c['status'].append(mn) + +####### PROJECT IDENTITY + +# the 'title' string will appear at the top of this buildbot +# installation's html.WebStatus home page (linked to the +# 'titleURL') and is embedded in the title of the waterfall HTML page. + +c['title'] = "Taskotron" +c['titleURL'] = "http://{{ hostname }}/{{buildmaster_endpoint}}" + +# the 'buildbotURL' string should point to the location where the buildbot's +# internal web server (usually the html.WebStatus page) is visible. This +# typically uses the port number set in the Waterfall 'status' entry, but +# with an externally-visible host name which the buildbot cannot figure out +# without some help. + +c['buildbotURL'] = "http://{{ hostname }}/{{buildmaster_endpoint}}" + +####### DB URL + +c['db'] = { + # This specifies what database buildbot uses to store its state. You can leave + # this at its default for all but the largest installations. + #'db_url' : "sqlite:///state.sqlite", + 'db_url' : "postgresql://{{ buildmaster_db_user }}:{{ buildmaster_db_pw }}@{{ buildmaster_db_host }}/{{ buildmaster_db }}", +}