2 # ex: set syntax=python:
9 from buildbot import locks
11 # This is a sample buildmaster config file. It must be installed as
12 # 'master.cfg' in your buildmaster's base directory.
14 ini = ConfigParser.ConfigParser()
15 ini.read("./config.ini")
17 # This is the dictionary that the buildmaster pays attention to. We also use
18 # a shorter alias to save typing.
19 c = BuildmasterConfig = {}
21 ####### PROJECT IDENTITY
23 # the 'title' string will appear at the top of this buildbot
24 # installation's html.WebStatus home page (linked to the
25 # 'titleURL') and is embedded in the title of the waterfall HTML page.
27 c['title'] = ini.get("general", "title")
28 c['titleURL'] = ini.get("general", "title_url")
30 # the 'buildbotURL' string should point to the location where the buildbot's
31 # internal web server (usually the html.WebStatus page) is visible. This
32 # typically uses the port number set in the Waterfall 'status' entry, but
33 # with an externally-visible host name which the buildbot cannot figure out
36 c['buildbotURL'] = ini.get("general", "buildbot_url")
40 # The 'slaves' list defines the set of recognized buildslaves. Each element is
41 # a BuildSlave object, specifying a unique slave name and password. The same
42 # slave name and password must be configured on the slave.
43 from buildbot.buildslave import BuildSlave
47 if ini.has_option("general", "port"):
48 slave_port = ini.getint("general", "port")
55 for section in ini.sections():
56 if section.startswith("slave "):
57 if ini.has_option(section, "name") and ini.has_option(section, "password"):
58 sl_props = { 'dl_lock':None, 'ul_lock':None, }
59 name = ini.get(section, "name")
60 password = ini.get(section, "password")
62 do_cleanup[name] = False
63 if ini.has_option(section, "builds"):
64 max_builds[name] = ini.getint(section, "builds")
65 if ini.has_option(section, "cleanup"):
66 do_cleanup[name] = ini.getboolean(section, "cleanup")
67 if ini.has_option(section, "dl_lock"):
68 lockname = ini.get(section, "dl_lock")
69 sl_props['dl_lock'] = lockname
70 if lockname not in NetLocks:
71 NetLocks[lockname] = locks.MasterLock(lockname)
72 if ini.has_option(section, "ul_lock"):
73 lockname = ini.get(section, "dl_lock")
74 sl_props['ul_lock'] = lockname
75 if lockname not in NetLocks:
76 NetLocks[lockname] = locks.MasterLock(lockname)
77 c['slaves'].append(BuildSlave(name, password, max_builds = max_builds[name], properties = sl_props))
79 # 'slavePortnum' defines the TCP port to listen on for connections from slaves.
80 # This must match the value configured into the buildslaves (with their
82 c['slavePortnum'] = slave_port
85 c['mergeRequests'] = True
87 # Reduce amount of backlog data
88 c['buildHorizon'] = 30
93 home_dir = os.path.abspath(ini.get("general", "homedir"))
101 if ini.has_option("general", "expire"):
102 tree_expire = ini.getint("general", "expire")
104 if ini.has_option("general", "other_builds"):
105 other_builds = ini.getint("general", "other_builds")
107 if ini.has_option("general", "cc_version"):
108 cc_version = ini.get("general", "cc_version").split()
109 if len(cc_version) == 1:
110 cc_version = ["eq", cc_version[0]]
112 repo_url = ini.get("repo", "url")
113 repo_branch = "master"
115 if ini.has_option("repo", "branch"):
116 repo_branch = ini.get("repo", "branch")
118 rsync_bin_url = ini.get("rsync", "binary_url")
119 rsync_bin_key = ini.get("rsync", "binary_password")
124 if ini.has_option("rsync", "source_url"):
125 rsync_src_url = ini.get("rsync", "source_url")
126 rsync_src_key = ini.get("rsync", "source_password")
128 gpg_home = "~/.gnupg"
130 gpg_comment = "Unattended build signature"
131 gpg_passfile = "/dev/null"
133 if ini.has_option("gpg", "home"):
134 gpg_home = ini.get("gpg", "home")
136 if ini.has_option("gpg", "keyid"):
137 gpg_keyid = ini.get("gpg", "keyid")
139 if ini.has_option("gpg", "comment"):
140 gpg_comment = ini.get("gpg", "comment")
142 if ini.has_option("gpg", "passfile"):
143 gpg_passfile = ini.get("gpg", "passfile")
145 enable_kmod_archive = True
151 if not os.path.isdir(home_dir+'/source.git'):
152 subprocess.call(["git", "clone", "--depth=1", "--branch="+repo_branch, repo_url, home_dir+'/source.git'])
154 subprocess.call(["git", "pull"], cwd = home_dir+'/source.git')
156 findtargets = subprocess.Popen([home_dir+'/dumpinfo.pl', 'targets'],
157 stdout = subprocess.PIPE, cwd = home_dir+'/source.git')
160 line = findtargets.stdout.readline()
163 ta = line.strip().split(' ')
164 targets.append(ta[0])
167 # the 'change_source' setting tells the buildmaster how it should find out
168 # about source code changes. Here we point to the buildbot clone of pyflakes.
170 from buildbot.changes.gitpoller import GitPoller
171 c['change_source'] = []
172 c['change_source'].append(GitPoller(
174 workdir=home_dir+'/work.git', branch=repo_branch,
179 # Configure the Schedulers, which decide how to react to incoming changes. In this
180 # case, just kick off a 'basebuild' build
182 from buildbot.schedulers.basic import SingleBranchScheduler
183 from buildbot.schedulers.forcesched import ForceScheduler
184 from buildbot.changes import filter
186 c['schedulers'].append(SingleBranchScheduler(
188 change_filter=filter.ChangeFilter(branch=repo_branch),
190 builderNames=targets))
192 c['schedulers'].append(ForceScheduler(
194 builderNames=targets))
198 # The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
199 # what steps, and which slaves can execute them. Note that any particular build will
200 # only take place on one slave.
202 from buildbot.process.factory import BuildFactory
203 from buildbot.steps.source.git import Git
204 from buildbot.steps.shell import ShellCommand
205 from buildbot.steps.shell import SetProperty
206 from buildbot.steps.transfer import FileUpload
207 from buildbot.steps.transfer import FileDownload
208 from buildbot.steps.master import MasterShellCommand
209 from buildbot.process.properties import WithProperties
210 from buildbot.process import properties
214 [ "tools", "tools/clean" ],
215 [ "chain", "toolchain/clean" ],
216 [ "linux", "target/linux/clean" ],
217 [ "dir", "dirclean" ],
218 [ "dist", "distclean" ]
221 def IsMakeCleanRequested(pattern):
222 def CheckCleanProperty(step):
223 val = step.getProperty("clean")
224 if val and re.match(pattern, val):
229 return CheckCleanProperty
231 def IsCleanupRequested(step):
232 val = step.getProperty("slavename")
233 if val and do_cleanup[val]:
238 def IsExpireRequested(step):
239 return not IsCleanupRequested(step)
241 def IsTaggingRequested(step):
242 val = step.getProperty("tag")
243 if val and re.match("^[0-9]+\.[0-9]+\.[0-9]+(?:-rc[0-9]+)?$", val):
248 def IsNoTaggingRequested(step):
249 return not IsTaggingRequested(step)
251 def IsNoMasterBuild(step):
252 return repo_branch != "master"
254 def IsCleanupConfigured(step):
255 slave = step.getProperty("slavename")
256 if slave and slave in do_cleanup:
257 return do_cleanup[slave] > 0
261 def GetBaseVersion(props):
262 if re.match("^[^-]+-[0-9]+\.[0-9]+$", repo_branch):
263 return repo_branch.split('-')[1]
267 def GetVersionPrefix(props):
268 basever = GetBaseVersion(props)
269 if props.hasProperty("tag") and re.match("^[0-9]+\.[0-9]+\.[0-9]+(?:-rc[0-9]+)?$", props["tag"]):
270 return "%s/" % props["tag"]
271 elif basever != "master":
272 return "%s-SNAPSHOT/" % basever
276 def GetNumJobs(props):
277 if props.hasProperty("slavename") and props.hasProperty("nproc"):
278 return (int(props["nproc"]) / (max_builds[props["slavename"]] + other_builds))
283 if props.hasProperty("cc_command"):
284 return props["cc_command"]
289 if props.hasProperty("cxx_command"):
290 return props["cxx_command"]
295 if props.hasProperty("builddir"):
296 return props["builddir"]
297 elif props.hasProperty("workdir"):
298 return props["workdir"]
302 def GetNextBuild(builder, requests):
304 if r.properties and r.properties.hasProperty("tag"):
308 def MakeEnv(overrides=None):
310 'CC': WithProperties("%(cc)s", cc=GetCC),
311 'CXX': WithProperties("%(cxx)s", cxx=GetCXX),
312 'CCACHE_BASEDIR': WithProperties("%(cwd)s", cwd=GetCwd)
314 if overrides is not None:
315 env.update(overrides)
319 def NetLockDl(props):
321 if props.hasProperty("dl_lock"):
322 lock = NetLocks[props["dl_lock"]]
324 return [lock.access('exclusive')]
329 def NetLockUl(props):
331 if props.hasProperty("ul_lock"):
332 lock = NetLocks[props["ul_lock"]]
334 return [lock.access('exclusive')]
340 dlLock = locks.SlaveLock("slave_dl")
342 checkBuiltin = re.sub('[\t\n ]+', ' ', """
344 local symbol op path file;
345 for file in $CHANGED_FILES; do
351 while read symbol op path; do
352 case "$symbol" in package-*)
353 symbol="${symbol##*(}";
354 symbol="${symbol%)}";
355 for file in $CHANGED_FILES; do
356 case "$file" in "package/$path/"*)
357 grep -qsx "$symbol=y" .config && return 0
361 done < tmp/.packagedeps;
367 class IfBuiltinShellCommand(ShellCommand):
368 def _quote(self, str):
369 if re.search("[^a-zA-Z0-9/_.-]", str):
370 return "'%s'" %(re.sub("'", "'\"'\"'", str))
373 def setCommand(self, command):
374 if not isinstance(command, (str, unicode)):
375 command = ' '.join(map(self._quote, command))
378 '%s; if checkBuiltin; then %s; else exit 0; fi' %(checkBuiltin, command)
381 def setupEnvironment(self, cmd):
382 slaveEnv = self.slaveEnvironment
386 for request in self.build.requests:
387 for source in request.sources:
388 for change in source.changes:
389 for file in change.files:
390 changedFiles[file] = True
391 fullSlaveEnv = slaveEnv.copy()
392 fullSlaveEnv['CHANGED_FILES'] = ' '.join(changedFiles.keys())
393 cmd.args['env'] = fullSlaveEnv
397 for slave in c['slaves']:
398 slaveNames.append(slave.slavename)
400 for target in targets:
401 ts = target.split('/')
403 factory = BuildFactory()
405 # find number of cores
406 factory.addStep(SetProperty(
409 description = "Finding number of CPUs",
410 command = ["nproc"]))
412 # find gcc and g++ compilers
413 if cc_version is not None:
414 factory.addStep(FileDownload(
415 mastersrc = "findbin.pl",
416 slavedest = "../findbin.pl",
419 factory.addStep(SetProperty(
421 property = "cc_command",
422 description = "Finding gcc command",
423 command = ["../findbin.pl", "gcc", cc_version[0], cc_version[1]],
424 haltOnFailure = True))
426 factory.addStep(SetProperty(
428 property = "cxx_command",
429 description = "Finding g++ command",
430 command = ["../findbin.pl", "g++", cc_version[0], cc_version[1]],
431 haltOnFailure = True))
433 # expire tree if needed
435 factory.addStep(FileDownload(
436 doStepIf = IsExpireRequested,
437 mastersrc = "expire.sh",
438 slavedest = "../expire.sh",
441 factory.addStep(ShellCommand(
443 description = "Checking for build tree expiry",
444 command = ["./expire.sh", str(tree_expire)],
446 haltOnFailure = True,
447 doStepIf = IsExpireRequested,
450 # cleanup.sh if needed
451 factory.addStep(FileDownload(
452 mastersrc = "cleanup.sh",
453 slavedest = "../cleanup.sh",
455 doStepIf = IsCleanupRequested))
457 factory.addStep(ShellCommand(
459 description = "Cleaning previous builds",
460 command = ["./cleanup.sh", c['buildbotURL'], WithProperties("%(slavename)s"), WithProperties("%(buildername)s"), "full"],
462 haltOnFailure = True,
463 doStepIf = IsCleanupRequested,
466 factory.addStep(ShellCommand(
468 description = "Cleaning work area",
469 command = ["./cleanup.sh", c['buildbotURL'], WithProperties("%(slavename)s"), WithProperties("%(buildername)s"), "single"],
471 haltOnFailure = True,
472 doStepIf = IsCleanupRequested,
475 # user-requested clean targets
476 for tuple in CleanTargetMap:
477 factory.addStep(ShellCommand(
479 description = 'User-requested "make %s"' % tuple[1],
480 command = ["make", tuple[1], "V=s"],
482 doStepIf = IsMakeCleanRequested(tuple[0])
485 # check out the source
487 # if repo doesn't exist: 'git clone repourl'
488 # method 'clean' runs 'git clean -d -f', method fresh runs 'git clean -d -f x'. Only works with mode='full'
489 # 'git fetch -t repourl branch; git reset --hard revision'
492 branch = repo_branch,
496 haltOnFailure = True,
500 factory.addStep(ShellCommand(
502 description = "Fetching Git remote refs",
503 command = ["git", "fetch", "origin", "+refs/heads/%s:refs/remotes/origin/%s" %(repo_branch, repo_branch)],
508 factory.addStep(ShellCommand(
510 description = "Checking out Git tag",
511 command = ["git", "checkout", WithProperties("tags/v%(tag:-)s")],
512 haltOnFailure = True,
513 doStepIf = IsTaggingRequested
516 factory.addStep(ShellCommand(
518 description = "Remove tmp folder",
519 command=["rm", "-rf", "tmp/"]))
522 # factory.addStep(ShellCommand(
523 # name = "feedsconf",
524 # description = "Copy the feeds.conf",
525 # command='''cp ~/feeds.conf ./feeds.conf''' ))
528 factory.addStep(ShellCommand(
529 name = "rmfeedlinks",
530 description = "Remove feed symlinks",
531 command=["rm", "-rf", "package/feeds/"]))
534 factory.addStep(ShellCommand(
535 name = "updatefeeds",
536 description = "Updating feeds",
537 command=["./scripts/feeds", "update"],
543 factory.addStep(ShellCommand(
544 name = "installfeeds",
545 description = "Installing feeds",
546 command=["./scripts/feeds", "install", "-a"],
550 factory.addStep(FileDownload(
551 mastersrc = "config.seed",
552 slavedest = ".config",
557 factory.addStep(ShellCommand(
559 description = "Seeding .config",
560 command = "printf 'CONFIG_TARGET_%s=y\\nCONFIG_TARGET_%s_%s=y\\n' >> .config" %(ts[0], ts[0], ts[1])
563 factory.addStep(ShellCommand(
565 description = "Removing output directory",
566 command = ["rm", "-rf", "bin/"]
569 factory.addStep(ShellCommand(
571 description = "Populating .config",
572 command = ["make", "defconfig"],
577 factory.addStep(ShellCommand(
579 description = "Checking architecture",
580 command = ["grep", "-sq", "CONFIG_TARGET_%s=y" %(ts[0]), ".config"],
588 factory.addStep(SetProperty(
591 description = "Finding libc suffix",
592 command = ["sed", "-ne", '/^CONFIG_LIBC=/ { s!^CONFIG_LIBC="\\(.*\\)"!\\1!; s!^musl$!!; s!.\\+!-&!p }', ".config"]))
595 factory.addStep(FileDownload(
596 mastersrc = "ccache.sh",
597 slavedest = "ccache.sh",
602 factory.addStep(ShellCommand(
604 description = "Preparing ccache",
605 command = ["./ccache.sh"]
609 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build', slavedest="key-build", mode=0600))
610 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build.pub', slavedest="key-build.pub", mode=0600))
613 factory.addStep(ShellCommand(
615 description = "Preparing dl/",
616 command = "mkdir -p $HOME/dl && rm -rf ./dl && ln -sf $HOME/dl ./dl",
622 factory.addStep(ShellCommand(
624 description = "Building and installing GNU tar",
625 command = ["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "tools/tar/compile", "V=s"],
631 factory.addStep(ShellCommand(
633 description = "Populating dl/",
634 command = ["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "download", "V=s"],
637 locks = properties.FlattenList(NetLockDl, [dlLock.access('exclusive')]),
640 factory.addStep(ShellCommand(
642 description = "Cleaning base-files",
643 command=["make", "package/base-files/clean", "V=s"]
647 factory.addStep(ShellCommand(
649 description = "Building and installing tools",
650 command = ["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "tools/install", "V=s"],
655 factory.addStep(ShellCommand(
657 description = "Building and installing toolchain",
658 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "toolchain/install", "V=s"],
663 factory.addStep(ShellCommand(
665 description = "Building kmods",
666 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "target/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
668 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
672 # find kernel version
673 factory.addStep(SetProperty(
674 name = "kernelversion",
675 property = "kernelversion",
676 description = "Finding the effective Kernel version",
677 command = "make --no-print-directory -C target/linux/ val.LINUX_VERSION val.LINUX_RELEASE val.LINUX_VERMAGIC | xargs printf '%s-%s-%s\\n'",
678 env = { 'TOPDIR': WithProperties("%(cwd)s/build", cwd=GetCwd) }
681 factory.addStep(ShellCommand(
683 description = "Cleaning up package build",
684 command=["make", "package/cleanup", "V=s"]
687 factory.addStep(ShellCommand(
689 description = "Building packages",
690 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
692 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
696 # factory.addStep(IfBuiltinShellCommand(
697 factory.addStep(ShellCommand(
699 description = "Installing packages",
700 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/install", "V=s"],
705 factory.addStep(ShellCommand(
707 description = "Indexing packages",
708 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/index", "V=s"],
713 if enable_kmod_archive:
714 factory.addStep(ShellCommand(
716 description = "Creating kmod directory",
717 command=["mkdir", "-p", WithProperties("bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s" %(ts[0], ts[1]))],
721 factory.addStep(ShellCommand(
722 name = "kmodprepare",
723 description = "Preparing kmod archive",
724 command=["rsync", "--include=/kmod-*.ipk", "--exclude=*", "-va",
725 WithProperties("bin/targets/%s/%s%%(libc)s/packages/" %(ts[0], ts[1])),
726 WithProperties("bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s/" %(ts[0], ts[1]))],
730 factory.addStep(ShellCommand(
732 description = "Indexing kmod archive",
733 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/index", "V=s",
734 WithProperties("PACKAGE_SUBDIRS=bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s/" %(ts[0], ts[1]))],
739 # find rootfs staging directory
740 factory.addStep(SetProperty(
742 property = "stageroot",
743 description = "Finding the rootfs staging directory",
744 command=["make", "--no-print-directory", "val.STAGING_DIR_ROOT"],
745 env = { 'TOPDIR': WithProperties("%(cwd)s/build", cwd=GetCwd) }
748 factory.addStep(ShellCommand(
750 description = "Creating file overlay directory",
751 command=["mkdir", "-p", "files/etc/opkg"],
755 factory.addStep(ShellCommand(
757 description = "Embedding kmod repository configuration",
758 command=WithProperties("sed -e 's#^\\(src/gz .*\\)_core \\(.*\\)/packages$#&\\n\\1_kmods \\2/kmods/%(kernelversion)s#' " +
759 "%(stageroot)s/etc/opkg/distfeeds.conf > files/etc/opkg/distfeeds.conf"),
763 #factory.addStep(IfBuiltinShellCommand(
764 factory.addStep(ShellCommand(
766 description = "Building and installing images",
767 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "target/install", "V=s"],
772 factory.addStep(ShellCommand(
774 description = "Generating config.seed",
775 command=["make", "-j1", "diffconfig", "V=s"],
780 factory.addStep(ShellCommand(
782 description = "Calculating checksums",
783 command=["make", "-j1", "checksum", "V=s"],
789 if gpg_keyid is not None:
790 factory.addStep(MasterShellCommand(
791 name = "signprepare",
792 description = "Preparing temporary signing directory",
793 command = ["mkdir", "-p", "%s/signing" %(home_dir)],
797 factory.addStep(ShellCommand(
799 description = "Packing files to sign",
800 command = WithProperties("find bin/targets/%s/%s%%(libc)s/ bin/targets/%s/%s%%(libc)s/kmods/ -mindepth 1 -maxdepth 2 -type f -name sha256sums -print0 -or -name Packages -print0 | xargs -0 tar -czf sign.tar.gz" %(ts[0], ts[1], ts[0], ts[1])),
804 factory.addStep(FileUpload(
805 slavesrc = "sign.tar.gz",
806 masterdest = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
810 factory.addStep(MasterShellCommand(
812 description = "Signing files",
813 command = ["%s/signall.sh" %(home_dir), "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]), gpg_keyid, gpg_comment],
814 env = {'GNUPGHOME': gpg_home, 'PASSFILE': gpg_passfile},
818 factory.addStep(FileDownload(
819 mastersrc = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
820 slavedest = "sign.tar.gz",
824 factory.addStep(ShellCommand(
826 description = "Unpacking signed files",
827 command = ["tar", "-xzf", "sign.tar.gz"],
832 factory.addStep(ShellCommand(
834 description = "Preparing upload directory structure",
835 command = ["mkdir", "-p", WithProperties("tmp/upload/%%(prefix)stargets/%s/%s" %(ts[0], ts[1]), prefix=GetVersionPrefix)],
839 factory.addStep(ShellCommand(
840 name = "linkprepare",
841 description = "Preparing repository symlink",
842 command = ["ln", "-s", "-f", WithProperties("../packages-%(basever)s", basever=GetBaseVersion), WithProperties("tmp/upload/%(prefix)spackages", prefix=GetVersionPrefix)],
843 doStepIf = IsNoMasterBuild,
847 if enable_kmod_archive:
848 factory.addStep(ShellCommand(
849 name = "kmoddirprepare",
850 description = "Preparing kmod archive upload directory",
851 command = ["mkdir", "-p", WithProperties("tmp/upload/%%(prefix)stargets/%s/%s/kmods/%%(kernelversion)s" %(ts[0], ts[1]), prefix=GetVersionPrefix)],
855 factory.addStep(ShellCommand(
857 description = "Uploading directory structure",
858 command = ["rsync", "-4", "--info=name", "-az", "tmp/upload/", "%s/" %(rsync_bin_url)],
859 env={'RSYNC_PASSWORD': rsync_bin_key},
860 haltOnFailure = True,
865 factory.addStep(FileDownload(
866 mastersrc = "rsync.sh",
867 slavedest = "../rsync.sh",
870 factory.addStep(ShellCommand(
871 name = "targetupload",
872 description = "Uploading target files",
873 command=["../rsync.sh", "-4", "--info=name", "--exclude=/kmods/", "--delete", "--size-only", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]),
874 "-a", WithProperties("bin/targets/%s/%s%%(libc)s/" %(ts[0], ts[1])),
875 WithProperties("%s/%%(prefix)stargets/%s/%s/" %(rsync_bin_url, ts[0], ts[1]), prefix=GetVersionPrefix)],
876 env={'RSYNC_PASSWORD': rsync_bin_key},
877 haltOnFailure = True,
882 if enable_kmod_archive:
883 factory.addStep(ShellCommand(
885 description = "Uploading kmod archive",
886 command=["../rsync.sh", "-4", "--info=name", "--delete", "--size-only", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]),
887 "-a", WithProperties("bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s/" %(ts[0], ts[1])),
888 WithProperties("%s/%%(prefix)stargets/%s/%s/kmods/%%(kernelversion)s/" %(rsync_bin_url, ts[0], ts[1]), prefix=GetVersionPrefix)],
889 env={'RSYNC_PASSWORD': rsync_bin_key},
890 haltOnFailure = True,
895 if rsync_src_url is not None:
896 factory.addStep(ShellCommand(
897 name = "sourceupload",
898 description = "Uploading source archives",
899 command=["../rsync.sh", "-4", "--info=name", "--size-only", "--delay-updates",
900 WithProperties("--partial-dir=.~tmp~%s~%s~%%(slavename)s" %(ts[0], ts[1])), "-a", "dl/", "%s/" %(rsync_src_url)],
901 env={'RSYNC_PASSWORD': rsync_src_key},
902 haltOnFailure = True,
908 factory.addStep(ShellCommand(
909 name = "packageupload",
910 description = "Uploading package files",
911 command=["../rsync.sh", "-4", "--info=name", "--delete", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]), "-a", "bin/packages/", "%s/packages/" %(rsync_bin_url)],
912 env={'RSYNC_PASSWORD': rsync_bin_key},
913 haltOnFailure = False,
920 factory.addStep(ShellCommand(
922 description = "Uploading logs",
923 command=["../rsync.sh", "-4", "-info=name", "--delete", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]), "-az", "logs/", "%s/logs/%s/%s/" %(rsync_bin_url, ts[0], ts[1])],
924 env={'RSYNC_PASSWORD': rsync_bin_key},
925 haltOnFailure = False,
931 factory.addStep(ShellCommand(
933 description = "Reporting disk usage",
934 command=["df", "-h", "."],
936 haltOnFailure = False,
940 from buildbot.config import BuilderConfig
942 c['builders'].append(BuilderConfig(name=target, slavenames=slaveNames, factory=factory, nextBuild=GetNextBuild))
945 ####### STATUS TARGETS
947 # 'status' is a list of Status Targets. The results of each build will be
948 # pushed to these targets. buildbot/status/*.py has a variety to choose from,
949 # including web pages, email senders, and IRC bots.
953 from buildbot.status import html
954 from buildbot.status.web import authz, auth
956 if ini.has_option("status", "bind"):
957 if ini.has_option("status", "user") and ini.has_option("status", "password"):
958 authz_cfg=authz.Authz(
959 # change any of these to True to enable; see the manual for more
961 auth=auth.BasicAuth([(ini.get("status", "user"), ini.get("status", "password"))]),
962 gracefulShutdown = 'auth',
963 forceBuild = 'auth', # use this to test your slave once it is set up
964 forceAllBuilds = 'auth',
967 stopAllBuilds = 'auth',
968 cancelPendingBuild = 'auth',
970 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind"), authz=authz_cfg))
972 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind")))
975 from buildbot.status import words
977 if ini.has_option("irc", "host") and ini.has_option("irc", "nickname") and ini.has_option("irc", "channel"):
978 irc_host = ini.get("irc", "host")
980 irc_chan = ini.get("irc", "channel")
981 irc_nick = ini.get("irc", "nickname")
984 if ini.has_option("irc", "port"):
985 irc_port = ini.getint("irc", "port")
987 if ini.has_option("irc", "password"):
988 irc_pass = ini.get("irc", "password")
990 irc = words.IRC(irc_host, irc_nick, port = irc_port, password = irc_pass,
991 channels = [{ "channel": irc_chan }],
994 'successToFailure': 1,
995 'failureToSuccess': 1
999 c['status'].append(irc)
1004 # This specifies what database buildbot uses to store its state. You can leave
1005 # this at its default for all but the largest installations.
1006 'db_url' : "sqlite:///state.sqlite",