phase1: manually fetch remote Git refs
[buildbot.git] / phase1 / master.cfg
1 # -*- python -*-
2 # ex: set syntax=python:
3
4 import os
5 import re
6 import subprocess
7 import ConfigParser
8
9 from buildbot import locks
10
11 # This is a sample buildmaster config file. It must be installed as
12 # 'master.cfg' in your buildmaster's base directory.
13
14 ini = ConfigParser.ConfigParser()
15 ini.read("./config.ini")
16
17 # This is the dictionary that the buildmaster pays attention to. We also use
18 # a shorter alias to save typing.
19 c = BuildmasterConfig = {}
20
21 ####### BUILDSLAVES
22
23 # The 'slaves' list defines the set of recognized buildslaves. Each element is
24 # a BuildSlave object, specifying a unique slave name and password. The same
25 # slave name and password must be configured on the slave.
26 from buildbot.buildslave import BuildSlave
27
28 slave_port = 9989
29
30 if ini.has_option("general", "port"):
31 slave_port = ini.getint("general", "port")
32
33 c['slaves'] = []
34
35 for section in ini.sections():
36 if section.startswith("slave "):
37 if ini.has_option(section, "name") and ini.has_option(section, "password"):
38 name = ini.get(section, "name")
39 password = ini.get(section, "password")
40 max_builds = 1
41 if ini.has_option(section, "builds"):
42 max_builds = ini.getint(section, "builds")
43 c['slaves'].append(BuildSlave(name, password, max_builds = max_builds))
44
45 # 'slavePortnum' defines the TCP port to listen on for connections from slaves.
46 # This must match the value configured into the buildslaves (with their
47 # --master option)
48 c['slavePortnum'] = slave_port
49
50 # coalesce builds
51 c['mergeRequests'] = True
52
53 ####### CHANGESOURCES
54
55 home_dir = os.path.abspath(ini.get("general", "homedir"))
56 tree_expire = 0
57
58 if ini.has_option("general", "expire"):
59 tree_expire = ini.getint("general", "expire")
60
61 repo_url = ini.get("repo", "url")
62 repo_branch = "master"
63
64 if ini.has_option("repo", "branch"):
65 repo_branch = ini.get("repo", "branch")
66
67 rsync_bin_url = ini.get("rsync", "binary_url")
68 rsync_bin_key = ini.get("rsync", "binary_password")
69
70 rsync_src_url = None
71 rsync_src_key = None
72
73 if ini.has_option("rsync", "source_url"):
74 rsync_src_url = ini.get("rsync", "source_url")
75 rsync_src_key = ini.get("rsync", "source_password")
76
77 gpg_home = "~/.gnupg"
78 gpg_keyid = None
79 gpg_comment = "Unattended build signature"
80 gpg_passfile = "/dev/null"
81
82 if ini.has_option("gpg", "home"):
83 gpg_home = ini.get("gpg", "home")
84
85 if ini.has_option("gpg", "keyid"):
86 gpg_keyid = ini.get("gpg", "keyid")
87
88 if ini.has_option("gpg", "comment"):
89 gpg_comment = ini.get("gpg", "comment")
90
91 if ini.has_option("gpg", "passfile"):
92 gpg_passfile = ini.get("gpg", "passfile")
93
94
95 # find targets
96 targets = [ ]
97
98 if not os.path.isdir(home_dir+'/source.git'):
99 subprocess.call(["git", "clone", "--depth=1", "--branch="+repo_branch, repo_url, home_dir+'/source.git'])
100 else:
101 subprocess.call(["git", "pull"], cwd = home_dir+'/source.git')
102
103 findtargets = subprocess.Popen([home_dir+'/dumpinfo.pl', 'targets'],
104 stdout = subprocess.PIPE, cwd = home_dir+'/source.git')
105
106 while True:
107 line = findtargets.stdout.readline()
108 if not line:
109 break
110 ta = line.strip().split(' ')
111 targets.append(ta[0])
112
113
114 # the 'change_source' setting tells the buildmaster how it should find out
115 # about source code changes. Here we point to the buildbot clone of pyflakes.
116
117 from buildbot.changes.gitpoller import GitPoller
118 c['change_source'] = []
119 c['change_source'].append(GitPoller(
120 repo_url,
121 workdir=home_dir+'/work.git', branch=repo_branch,
122 pollinterval=300))
123
124 ####### SCHEDULERS
125
126 # Configure the Schedulers, which decide how to react to incoming changes. In this
127 # case, just kick off a 'basebuild' build
128
129 from buildbot.schedulers.basic import SingleBranchScheduler
130 from buildbot.schedulers.forcesched import ForceScheduler
131 from buildbot.changes import filter
132 c['schedulers'] = []
133 c['schedulers'].append(SingleBranchScheduler(
134 name="all",
135 change_filter=filter.ChangeFilter(branch=repo_branch),
136 treeStableTimer=60,
137 builderNames=targets))
138
139 c['schedulers'].append(ForceScheduler(
140 name="force",
141 builderNames=targets))
142
143 ####### BUILDERS
144
145 # The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
146 # what steps, and which slaves can execute them. Note that any particular build will
147 # only take place on one slave.
148
149 from buildbot.process.factory import BuildFactory
150 from buildbot.steps.source.git import Git
151 from buildbot.steps.shell import ShellCommand
152 from buildbot.steps.shell import SetProperty
153 from buildbot.steps.transfer import FileUpload
154 from buildbot.steps.transfer import FileDownload
155 from buildbot.steps.master import MasterShellCommand
156 from buildbot.process.properties import WithProperties
157
158
159 CleanTargetMap = [
160 [ "tools", "tools/clean" ],
161 [ "chain", "toolchain/clean" ],
162 [ "linux", "target/linux/clean" ],
163 [ "dir", "dirclean" ],
164 [ "dist", "distclean" ]
165 ]
166
167 def IsCleanRequested(pattern):
168 def CheckCleanProperty(step):
169 val = step.getProperty("clean")
170 if val and re.match(pattern, val):
171 return True
172 else:
173 return False
174
175 return CheckCleanProperty
176
177 def IsTaggingRequested(step):
178 val = step.getProperty("tag")
179 if val and re.match("^[0-9]+\.[0-9]+\.[0-9]+$", val):
180 return True
181 else:
182 return False
183
184 def IsNoTaggingRequested(step):
185 return not IsTaggingRequested(step)
186
187 def IsNoMasterBuild(step):
188 return repo_branch != "master"
189
190 def GetBaseVersion(props):
191 if re.match("^[^-]+-[0-9]+\.[0-9]+$", repo_branch):
192 return repo_branch.split('-')[1]
193 else:
194 return "master"
195
196 def GetVersionPrefix(props):
197 basever = GetBaseVersion(props)
198 if props.hasProperty("tag") and re.match("^[0-9]+\.[0-9]+\.[0-9]+$", props["tag"]):
199 return "%s/" % props["tag"]
200 elif basever != "master":
201 return "%s-SNAPSHOT/" % basever
202 else:
203 return ""
204
205
206 c['builders'] = []
207
208 dlLock = locks.SlaveLock("slave_dl")
209 tagLock = locks.MasterLock("make_tag")
210
211 checkBuiltin = re.sub('[\t\n ]+', ' ', """
212 checkBuiltin() {
213 local symbol op path file;
214 for file in $CHANGED_FILES; do
215 case "$file" in
216 package/*/*) : ;;
217 *) return 0 ;;
218 esac;
219 done;
220 while read symbol op path; do
221 case "$symbol" in package-*)
222 symbol="${symbol##*(}";
223 symbol="${symbol%)}";
224 for file in $CHANGED_FILES; do
225 case "$file" in "package/$path/"*)
226 grep -qsx "$symbol=y" .config && return 0
227 ;; esac;
228 done;
229 esac;
230 done < tmp/.packagedeps;
231 return 1;
232 }
233 """).strip()
234
235
236 class IfBuiltinShellCommand(ShellCommand):
237 def _quote(self, str):
238 if re.search("[^a-zA-Z0-9/_.-]", str):
239 return "'%s'" %(re.sub("'", "'\"'\"'", str))
240 return str
241
242 def setCommand(self, command):
243 if not isinstance(command, (str, unicode)):
244 command = ' '.join(map(self._quote, command))
245 self.command = [
246 '/bin/sh', '-c',
247 '%s; if checkBuiltin; then %s; else exit 0; fi' %(checkBuiltin, command)
248 ]
249
250 def setupEnvironment(self, cmd):
251 slaveEnv = self.slaveEnvironment
252 if slaveEnv is None:
253 slaveEnv = { }
254 changedFiles = { }
255 for request in self.build.requests:
256 for source in request.sources:
257 for change in source.changes:
258 for file in change.files:
259 changedFiles[file] = True
260 fullSlaveEnv = slaveEnv.copy()
261 fullSlaveEnv['CHANGED_FILES'] = ' '.join(changedFiles.keys())
262 cmd.args['env'] = fullSlaveEnv
263
264 slaveNames = [ ]
265
266 for slave in c['slaves']:
267 slaveNames.append(slave.slavename)
268
269 for target in targets:
270 ts = target.split('/')
271
272 factory = BuildFactory()
273
274 # find number of cores
275 factory.addStep(SetProperty(
276 name = "nproc",
277 property = "nproc",
278 description = "Finding number of CPUs",
279 command = ["nproc"]))
280
281 # expire tree if needed
282 if tree_expire > 0:
283 factory.addStep(FileDownload(
284 mastersrc = "expire.sh",
285 slavedest = "../expire.sh",
286 mode = 0755))
287
288 factory.addStep(ShellCommand(
289 name = "expire",
290 description = "Checking for build tree expiry",
291 command = ["./expire.sh", str(tree_expire)],
292 workdir = ".",
293 haltOnFailure = True,
294 timeout = 2400))
295
296 # user-requested clean targets
297 for tuple in CleanTargetMap:
298 factory.addStep(ShellCommand(
299 name = tuple[1],
300 description = 'User-requested "make %s"' % tuple[1],
301 command = ["make", tuple[1], "V=s"],
302 doStepIf = IsCleanRequested(tuple[0])
303 ))
304
305 factory.addStep(MasterShellCommand(
306 name = "maketag",
307 description = "Tagging Git repository",
308 command = [home_dir+'/maketag.sh', '-i', '-k', str(gpg_keyid or ''),
309 '-p', str(gpg_passfile or ''), '-v', WithProperties("%(tag:-)s")],
310 path = home_dir+'/source.git',
311 env = {'GNUPGHOME': gpg_home},
312 haltOnFailure = True,
313 doStepIf = IsTaggingRequested,
314 locks = [tagLock.access('exclusive')]
315 ))
316
317 # switch to branch
318 factory.addStep(ShellCommand(
319 name = "switchbranch",
320 description = "Checking out Git branch",
321 command = "if [ -d .git ]; then git checkout '%s'; else exit 0; fi" % repo_branch,
322 haltOnFailure = True,
323 doStepIf = IsNoTaggingRequested
324 ))
325
326 # check out the source
327 factory.addStep(Git(
328 repourl = repo_url,
329 branch = repo_branch,
330 mode = 'incremental',
331 method = 'clean'))
332
333 # update remote refs
334 factory.addStep(ShellCommand(
335 name = "fetchrefs",
336 description = "Fetching Git remote refs",
337 command = ["git", "fetch", "origin", "+refs/heads/%s:refs/remotes/origin/%s" %(repo_branch, repo_branch)],
338 haltOnFailure = True
339 ))
340
341 # fetch tags
342 factory.addStep(ShellCommand(
343 name = "fetchtag",
344 description = "Fetching Git tags",
345 command = ["git", "fetch", "--tags", "--", repo_url],
346 haltOnFailure = True,
347 doStepIf = IsTaggingRequested
348 ))
349
350 # switch to tag
351 factory.addStep(ShellCommand(
352 name = "switchtag",
353 description = "Checking out Git tag",
354 command = ["git", "checkout", WithProperties("tags/v%(tag:-)s")],
355 haltOnFailure = True,
356 doStepIf = IsTaggingRequested
357 ))
358
359 factory.addStep(ShellCommand(
360 name = "rmtmp",
361 description = "Remove tmp folder",
362 command=["rm", "-rf", "tmp/"]))
363
364 # feed
365 # factory.addStep(ShellCommand(
366 # name = "feedsconf",
367 # description = "Copy the feeds.conf",
368 # command='''cp ~/feeds.conf ./feeds.conf''' ))
369
370 # feed
371 factory.addStep(ShellCommand(
372 name = "rmfeedlinks",
373 description = "Remove feed symlinks",
374 command=["rm", "-rf", "package/feeds/"]))
375
376 # feed
377 factory.addStep(ShellCommand(
378 name = "updatefeeds",
379 description = "Updating feeds",
380 command=["./scripts/feeds", "update"]))
381
382 # feed
383 factory.addStep(ShellCommand(
384 name = "installfeeds",
385 description = "Installing feeds",
386 command=["./scripts/feeds", "install", "-a"]))
387
388 # seed config
389 factory.addStep(FileDownload(
390 mastersrc = "config.seed",
391 slavedest = ".config",
392 mode = 0644
393 ))
394
395 # configure
396 factory.addStep(ShellCommand(
397 name = "newconfig",
398 description = "Seeding .config",
399 command = "printf 'CONFIG_TARGET_%s=y\\nCONFIG_TARGET_%s_%s=y\\n' >> .config" %(ts[0], ts[0], ts[1])
400 ))
401
402 factory.addStep(ShellCommand(
403 name = "delbin",
404 description = "Removing output directory",
405 command = ["rm", "-rf", "bin/"]
406 ))
407
408 factory.addStep(ShellCommand(
409 name = "defconfig",
410 description = "Populating .config",
411 command = ["make", "defconfig"]
412 ))
413
414 # check arch
415 factory.addStep(ShellCommand(
416 name = "checkarch",
417 description = "Checking architecture",
418 command = ["grep", "-sq", "CONFIG_TARGET_%s=y" %(ts[0]), ".config"],
419 logEnviron = False,
420 want_stdout = False,
421 want_stderr = False,
422 haltOnFailure = True
423 ))
424
425 # find libc suffix
426 factory.addStep(SetProperty(
427 name = "libc",
428 property = "libc",
429 description = "Finding libc suffix",
430 command = ["sed", "-ne", '/^CONFIG_LIBC=/ { s!^CONFIG_LIBC="\\(.*\\)"!\\1!; s!^musl$!!; s!.\\+!-&!p }', ".config"]))
431
432 # install build key
433 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build', slavedest="key-build", mode=0600))
434 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build.pub', slavedest="key-build.pub", mode=0600))
435
436 # prepare dl
437 factory.addStep(ShellCommand(
438 name = "dldir",
439 description = "Preparing dl/",
440 command = "mkdir -p $HOME/dl && rm -rf ./dl && ln -sf $HOME/dl ./dl",
441 logEnviron = False,
442 want_stdout = False
443 ))
444
445 # prepare tar
446 factory.addStep(ShellCommand(
447 name = "dltar",
448 description = "Building GNU tar",
449 command = ["make", WithProperties("-j%(nproc:~4)s"), "tools/tar/install", "V=s"],
450 haltOnFailure = True
451 ))
452
453 # populate dl
454 factory.addStep(ShellCommand(
455 name = "dlrun",
456 description = "Populating dl/",
457 command = ["make", WithProperties("-j%(nproc:~4)s"), "download", "V=s"],
458 logEnviron = False,
459 locks = [dlLock.access('exclusive')]
460 ))
461
462 factory.addStep(ShellCommand(
463 name = "cleanbase",
464 description = "Cleaning base-files",
465 command=["make", "package/base-files/clean", "V=s"]
466 ))
467
468 # build
469 factory.addStep(ShellCommand(
470 name = "tools",
471 description = "Building tools",
472 command = ["make", WithProperties("-j%(nproc:~4)s"), "tools/install", "V=s"],
473 haltOnFailure = True
474 ))
475
476 factory.addStep(ShellCommand(
477 name = "toolchain",
478 description = "Building toolchain",
479 command=["make", WithProperties("-j%(nproc:~4)s"), "toolchain/install", "V=s"],
480 haltOnFailure = True
481 ))
482
483 factory.addStep(ShellCommand(
484 name = "kmods",
485 description = "Building kmods",
486 command=["make", WithProperties("-j%(nproc:~4)s"), "target/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
487 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
488 haltOnFailure = True
489 ))
490
491 factory.addStep(ShellCommand(
492 name = "pkgbuild",
493 description = "Building packages",
494 command=["make", WithProperties("-j%(nproc:~4)s"), "package/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
495 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
496 haltOnFailure = True
497 ))
498
499 # factory.addStep(IfBuiltinShellCommand(
500 factory.addStep(ShellCommand(
501 name = "pkginstall",
502 description = "Installing packages",
503 command=["make", WithProperties("-j%(nproc:~4)s"), "package/install", "V=s"],
504 haltOnFailure = True
505 ))
506
507 factory.addStep(ShellCommand(
508 name = "pkgindex",
509 description = "Indexing packages",
510 command=["make", WithProperties("-j%(nproc:~4)s"), "package/index", "V=s"],
511 haltOnFailure = True
512 ))
513
514 #factory.addStep(IfBuiltinShellCommand(
515 factory.addStep(ShellCommand(
516 name = "images",
517 description = "Building images",
518 command=["make", WithProperties("-j%(nproc:~4)s"), "target/install", "V=s"],
519 haltOnFailure = True
520 ))
521
522 factory.addStep(ShellCommand(
523 name = "checksums",
524 description = "Calculating checksums",
525 command=["make", "-j1", "checksum", "V=s"],
526 haltOnFailure = True
527 ))
528
529 # sign
530 if gpg_keyid is not None:
531 factory.addStep(MasterShellCommand(
532 name = "signprepare",
533 description = "Preparing temporary signing directory",
534 command = ["mkdir", "-p", "%s/signing" %(home_dir)],
535 haltOnFailure = True
536 ))
537
538 factory.addStep(ShellCommand(
539 name = "signpack",
540 description = "Packing files to sign",
541 command = WithProperties("find bin/targets/%s/%s%%(libc)s/ -mindepth 1 -maxdepth 2 -type f -name sha256sums -print0 -or -name Packages -print0 | xargs -0 tar -czf sign.tar.gz" %(ts[0], ts[1])),
542 haltOnFailure = True
543 ))
544
545 factory.addStep(FileUpload(
546 slavesrc = "sign.tar.gz",
547 masterdest = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
548 haltOnFailure = True
549 ))
550
551 factory.addStep(MasterShellCommand(
552 name = "signfiles",
553 description = "Signing files",
554 command = ["%s/signall.sh" %(home_dir), "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]), gpg_keyid, gpg_comment],
555 env = {'GNUPGHOME': gpg_home, 'PASSFILE': gpg_passfile},
556 haltOnFailure = True
557 ))
558
559 factory.addStep(FileDownload(
560 mastersrc = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
561 slavedest = "sign.tar.gz",
562 haltOnFailure = True
563 ))
564
565 factory.addStep(ShellCommand(
566 name = "signunpack",
567 description = "Unpacking signed files",
568 command = ["tar", "-xzf", "sign.tar.gz"],
569 haltOnFailure = True
570 ))
571
572 # upload
573 factory.addStep(ShellCommand(
574 name = "dirprepare",
575 description = "Preparing upload directory structure",
576 command = ["mkdir", "-p", WithProperties("tmp/upload/%%(prefix)stargets/%s/%s" %(ts[0], ts[1]), prefix=GetVersionPrefix)],
577 haltOnFailure = True
578 ))
579
580 factory.addStep(ShellCommand(
581 name = "linkprepare",
582 description = "Preparing repository symlink",
583 command = ["ln", "-s", "-f", WithProperties("../packages-%(basever)s", basever=GetBaseVersion), WithProperties("tmp/upload/%(prefix)spackages", prefix=GetVersionPrefix)],
584 doStepIf = IsNoMasterBuild,
585 haltOnFailure = True
586 ))
587
588 factory.addStep(ShellCommand(
589 name = "dirupload",
590 description = "Uploading directory structure",
591 command = ["rsync", "-avz", "tmp/upload/", "%s/" %(rsync_bin_url)],
592 env={'RSYNC_PASSWORD': rsync_bin_key},
593 haltOnFailure = True,
594 logEnviron = False
595 ))
596
597 factory.addStep(ShellCommand(
598 name = "targetupload",
599 description = "Uploading target files",
600 command=["rsync", "--delete", "--checksum", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]),
601 "-avz", WithProperties("bin/targets/%s/%s%%(libc)s/" %(ts[0], ts[1])),
602 WithProperties("%s/%%(prefix)stargets/%s/%s/" %(rsync_bin_url, ts[0], ts[1]), prefix=GetVersionPrefix)],
603 env={'RSYNC_PASSWORD': rsync_bin_key},
604 haltOnFailure = True,
605 logEnviron = False
606 ))
607
608 if rsync_src_url is not None:
609 factory.addStep(ShellCommand(
610 name = "sourceupload",
611 description = "Uploading source archives",
612 command=["rsync", "--checksum", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]), "-avz", "dl/", "%s/" %(rsync_src_url)],
613 env={'RSYNC_PASSWORD': rsync_src_key},
614 haltOnFailure = True,
615 logEnviron = False
616 ))
617
618 if False:
619 factory.addStep(ShellCommand(
620 name = "packageupload",
621 description = "Uploading package files",
622 command=["rsync", "--delete", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]), "-avz", "bin/packages/", "%s/packages/" %(rsync_bin_url)],
623 env={'RSYNC_PASSWORD': rsync_bin_key},
624 haltOnFailure = False,
625 logEnviron = False
626 ))
627
628 # logs
629 if False:
630 factory.addStep(ShellCommand(
631 name = "upload",
632 description = "Uploading logs",
633 command=["rsync", "--delete", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]), "-avz", "logs/", "%s/logs/%s/%s/" %(rsync_bin_url, ts[0], ts[1])],
634 env={'RSYNC_PASSWORD': rsync_bin_key},
635 haltOnFailure = False,
636 alwaysRun = True,
637 logEnviron = False
638 ))
639
640 from buildbot.config import BuilderConfig
641
642 c['builders'].append(BuilderConfig(name=target, slavenames=slaveNames, factory=factory))
643
644
645 ####### STATUS TARGETS
646
647 # 'status' is a list of Status Targets. The results of each build will be
648 # pushed to these targets. buildbot/status/*.py has a variety to choose from,
649 # including web pages, email senders, and IRC bots.
650
651 c['status'] = []
652
653 from buildbot.status import html
654 from buildbot.status.web import authz, auth
655
656 if ini.has_option("status", "bind"):
657 if ini.has_option("status", "user") and ini.has_option("status", "password"):
658 authz_cfg=authz.Authz(
659 # change any of these to True to enable; see the manual for more
660 # options
661 auth=auth.BasicAuth([(ini.get("status", "user"), ini.get("status", "password"))]),
662 gracefulShutdown = 'auth',
663 forceBuild = 'auth', # use this to test your slave once it is set up
664 forceAllBuilds = 'auth',
665 pingBuilder = False,
666 stopBuild = 'auth',
667 stopAllBuilds = 'auth',
668 cancelPendingBuild = 'auth',
669 )
670 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind"), authz=authz_cfg))
671 else:
672 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind")))
673
674
675 from buildbot.status import words
676
677 if ini.has_option("irc", "host") and ini.has_option("irc", "nickname") and ini.has_option("irc", "channel"):
678 irc_host = ini.get("irc", "host")
679 irc_port = 6667
680 irc_chan = ini.get("irc", "channel")
681 irc_nick = ini.get("irc", "nickname")
682 irc_pass = None
683
684 if ini.has_option("irc", "port"):
685 irc_port = ini.getint("irc", "port")
686
687 if ini.has_option("irc", "password"):
688 irc_pass = ini.get("irc", "password")
689
690 irc = words.IRC(irc_host, irc_nick, port = irc_port, password = irc_pass,
691 channels = [{ "channel": irc_chan }],
692 notify_events = {
693 'exception': 1,
694 'successToFailure': 1,
695 'failureToSuccess': 1
696 }
697 )
698
699 c['status'].append(irc)
700
701
702 ####### PROJECT IDENTITY
703
704 # the 'title' string will appear at the top of this buildbot
705 # installation's html.WebStatus home page (linked to the
706 # 'titleURL') and is embedded in the title of the waterfall HTML page.
707
708 c['title'] = ini.get("general", "title")
709 c['titleURL'] = ini.get("general", "title_url")
710
711 # the 'buildbotURL' string should point to the location where the buildbot's
712 # internal web server (usually the html.WebStatus page) is visible. This
713 # typically uses the port number set in the Waterfall 'status' entry, but
714 # with an externally-visible host name which the buildbot cannot figure out
715 # without some help.
716
717 c['buildbotURL'] = ini.get("general", "buildbot_url")
718
719 ####### DB URL
720
721 c['db'] = {
722 # This specifies what database buildbot uses to store its state. You can leave
723 # this at its default for all but the largest installations.
724 'db_url' : "sqlite:///state.sqlite",
725 }