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")
54 for section in ini.sections():
55 if section.startswith("slave "):
56 if ini.has_option(section, "name") and ini.has_option(section, "password"):
57 sl_props = { 'dl_lock':None, 'ul_lock':None, 'do_cleanup':False }
58 name = ini.get(section, "name")
59 password = ini.get(section, "password")
61 if ini.has_option(section, "builds"):
62 max_builds[name] = ini.getint(section, "builds")
63 if ini.has_option(section, "cleanup"):
64 sl_props['do_cleanup'] = ini.getboolean(section, "cleanup")
65 if ini.has_option(section, "dl_lock"):
66 lockname = ini.get(section, "dl_lock")
67 sl_props['dl_lock'] = lockname
68 if lockname not in NetLocks:
69 NetLocks[lockname] = locks.MasterLock(lockname)
70 if ini.has_option(section, "ul_lock"):
71 lockname = ini.get(section, "dl_lock")
72 sl_props['ul_lock'] = lockname
73 if lockname not in NetLocks:
74 NetLocks[lockname] = locks.MasterLock(lockname)
75 c['slaves'].append(BuildSlave(name, password, max_builds = max_builds[name], properties = sl_props))
77 # 'slavePortnum' defines the TCP port to listen on for connections from slaves.
78 # This must match the value configured into the buildslaves (with their
80 c['slavePortnum'] = slave_port
83 c['mergeRequests'] = True
85 # Reduce amount of backlog data
86 c['buildHorizon'] = 30
91 home_dir = os.path.abspath(ini.get("general", "homedir"))
99 if ini.has_option("general", "expire"):
100 tree_expire = ini.getint("general", "expire")
102 if ini.has_option("general", "other_builds"):
103 other_builds = ini.getint("general", "other_builds")
105 if ini.has_option("general", "cc_version"):
106 cc_version = ini.get("general", "cc_version").split()
107 if len(cc_version) == 1:
108 cc_version = ["eq", cc_version[0]]
110 repo_url = ini.get("repo", "url")
111 repo_branch = "master"
113 if ini.has_option("repo", "branch"):
114 repo_branch = ini.get("repo", "branch")
116 rsync_bin_url = ini.get("rsync", "binary_url")
117 rsync_bin_key = ini.get("rsync", "binary_password")
122 if ini.has_option("rsync", "source_url"):
123 rsync_src_url = ini.get("rsync", "source_url")
124 rsync_src_key = ini.get("rsync", "source_password")
126 gpg_home = "~/.gnupg"
128 gpg_comment = "Unattended build signature"
129 gpg_passfile = "/dev/null"
131 if ini.has_option("gpg", "home"):
132 gpg_home = ini.get("gpg", "home")
134 if ini.has_option("gpg", "keyid"):
135 gpg_keyid = ini.get("gpg", "keyid")
137 if ini.has_option("gpg", "comment"):
138 gpg_comment = ini.get("gpg", "comment")
140 if ini.has_option("gpg", "passfile"):
141 gpg_passfile = ini.get("gpg", "passfile")
143 enable_kmod_archive = True
149 if not os.path.isdir(home_dir+'/source.git'):
150 subprocess.call(["git", "clone", "--depth=1", "--branch="+repo_branch, repo_url, home_dir+'/source.git'])
152 subprocess.call(["git", "pull"], cwd = home_dir+'/source.git')
154 findtargets = subprocess.Popen([home_dir+'/dumpinfo.pl', 'targets'],
155 stdout = subprocess.PIPE, cwd = home_dir+'/source.git')
158 line = findtargets.stdout.readline()
161 ta = line.strip().split(' ')
162 targets.append(ta[0])
165 # the 'change_source' setting tells the buildmaster how it should find out
166 # about source code changes. Here we point to the buildbot clone of pyflakes.
168 from buildbot.changes.gitpoller import GitPoller
169 c['change_source'] = []
170 c['change_source'].append(GitPoller(
172 workdir=home_dir+'/work.git', branch=repo_branch,
177 # Configure the Schedulers, which decide how to react to incoming changes. In this
178 # case, just kick off a 'basebuild' build
180 from buildbot.schedulers.basic import SingleBranchScheduler
181 from buildbot.schedulers.forcesched import ForceScheduler
182 from buildbot.changes import filter
184 c['schedulers'].append(SingleBranchScheduler(
186 change_filter=filter.ChangeFilter(branch=repo_branch),
188 builderNames=targets))
190 c['schedulers'].append(ForceScheduler(
192 builderNames=targets))
196 # The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
197 # what steps, and which slaves can execute them. Note that any particular build will
198 # only take place on one slave.
200 from buildbot.process.factory import BuildFactory
201 from buildbot.steps.source.git import Git
202 from buildbot.steps.shell import ShellCommand
203 from buildbot.steps.shell import SetProperty
204 from buildbot.steps.shell import SetPropertyFromCommand
205 from buildbot.steps.transfer import FileUpload
206 from buildbot.steps.transfer import FileDownload
207 from buildbot.steps.master import MasterShellCommand
208 from buildbot.process.properties import WithProperties
209 from buildbot.process import properties
213 [ "tools", "tools/clean" ],
214 [ "chain", "toolchain/clean" ],
215 [ "linux", "target/linux/clean" ],
216 [ "dir", "dirclean" ],
217 [ "dist", "distclean" ]
220 def IsMakeCleanRequested(pattern):
221 def CheckCleanProperty(step):
222 val = step.getProperty("clean")
223 if val and re.match(pattern, val):
228 return CheckCleanProperty
230 def IsCleanupRequested(step):
231 do_cleanup = step.getProperty("do_cleanup")
237 def IsExpireRequested(step):
238 return not IsCleanupRequested(step)
240 def IsTaggingRequested(step):
241 val = step.getProperty("tag")
242 if val and re.match("^[0-9]+\.[0-9]+\.[0-9]+(?:-rc[0-9]+)?$", val):
247 def IsNoTaggingRequested(step):
248 return not IsTaggingRequested(step)
250 def IsNoMasterBuild(step):
251 return repo_branch != "master"
253 def IsCleanupConfigured(step):
254 do_cleanup = step.getProperty("do_cleanup")
256 return do_cleanup > 0
260 def GetBaseVersion(props):
261 if re.match("^[^-]+-[0-9]+\.[0-9]+$", repo_branch):
262 return repo_branch.split('-')[1]
266 def GetVersionPrefix(props):
267 basever = GetBaseVersion(props)
268 if props.hasProperty("tag") and re.match("^[0-9]+\.[0-9]+\.[0-9]+(?:-rc[0-9]+)?$", props["tag"]):
269 return "%s/" % props["tag"]
270 elif basever != "master":
271 return "%s-SNAPSHOT/" % basever
275 def GetNumJobs(props):
276 if props.hasProperty("slavename") and props.hasProperty("nproc"):
277 return (int(props["nproc"]) / (max_builds[props["slavename"]] + other_builds))
282 if props.hasProperty("cc_command"):
283 return props["cc_command"]
288 if props.hasProperty("cxx_command"):
289 return props["cxx_command"]
294 if props.hasProperty("builddir"):
295 return props["builddir"]
296 elif props.hasProperty("workdir"):
297 return props["workdir"]
301 def GetCCache(props):
302 if props.hasProperty("ccache_command") and "ccache" in props["ccache_command"]:
303 return props["ccache_command"] + " "
307 def GetNextBuild(builder, requests):
309 if r.properties and r.properties.hasProperty("tag"):
313 def MakeEnv(overrides=None, tryccache=False):
315 envcc = Interpolate("%(kw:ccache)s%(kw:cc)s", ccache=GetCCache, cc=GetCC)
316 envcxx = Interpolate("%(kw:ccache)s%(kw:cxx)s", ccache=GetCCache, cxx=GetCXX)
318 envcc = Interpolate("%(kw:cc)s", cc=GetCC)
319 envcxx = Interpolate("%(kw:cxx)s", cxx=GetCXX)
323 'CCACHE_BASEDIR': Interpolate("%(kw:cwd)s", cwd=GetCwd)
325 if overrides is not None:
326 env.update(overrides)
330 def NetLockDl(props):
332 if props.hasProperty("dl_lock"):
333 lock = NetLocks[props["dl_lock"]]
335 return [lock.access('exclusive')]
340 def NetLockUl(props):
342 if props.hasProperty("ul_lock"):
343 lock = NetLocks[props["ul_lock"]]
345 return [lock.access('exclusive')]
351 dlLock = locks.SlaveLock("slave_dl")
353 checkBuiltin = re.sub('[\t\n ]+', ' ', """
355 local symbol op path file;
356 for file in $CHANGED_FILES; do
362 while read symbol op path; do
363 case "$symbol" in package-*)
364 symbol="${symbol##*(}";
365 symbol="${symbol%)}";
366 for file in $CHANGED_FILES; do
367 case "$file" in "package/$path/"*)
368 grep -qsx "$symbol=y" .config && return 0
372 done < tmp/.packagedeps;
378 class IfBuiltinShellCommand(ShellCommand):
379 def _quote(self, str):
380 if re.search("[^a-zA-Z0-9/_.-]", str):
381 return "'%s'" %(re.sub("'", "'\"'\"'", str))
384 def setCommand(self, command):
385 if not isinstance(command, (str, unicode)):
386 command = ' '.join(map(self._quote, command))
389 '%s; if checkBuiltin; then %s; else exit 0; fi' %(checkBuiltin, command)
392 def setupEnvironment(self, cmd):
393 slaveEnv = self.slaveEnvironment
397 for request in self.build.requests:
398 for source in request.sources:
399 for change in source.changes:
400 for file in change.files:
401 changedFiles[file] = True
402 fullSlaveEnv = slaveEnv.copy()
403 fullSlaveEnv['CHANGED_FILES'] = ' '.join(changedFiles.keys())
404 cmd.args['env'] = fullSlaveEnv
408 for slave in c['slaves']:
409 slaveNames.append(slave.slavename)
411 for target in targets:
412 ts = target.split('/')
414 factory = BuildFactory()
416 # find number of cores
417 factory.addStep(SetProperty(
420 description = "Finding number of CPUs",
421 command = ["nproc"]))
423 # find gcc and g++ compilers
424 if cc_version is not None:
425 factory.addStep(FileDownload(
426 mastersrc = "findbin.pl",
427 slavedest = "../findbin.pl",
430 factory.addStep(SetProperty(
432 property = "cc_command",
433 description = "Finding gcc command",
434 command = ["../findbin.pl", "gcc", cc_version[0], cc_version[1]],
435 haltOnFailure = True))
437 factory.addStep(SetProperty(
439 property = "cxx_command",
440 description = "Finding g++ command",
441 command = ["../findbin.pl", "g++", cc_version[0], cc_version[1]],
442 haltOnFailure = True))
444 # see if ccache is available
445 factory.addStep(SetPropertyFromCommand(
446 property = "ccache_command",
447 command = ["which", "ccache"],
448 description = "Testing for ccache command",
449 haltOnFailure = False,
450 flunkOnFailure = False,
451 warnOnFailure = False,
454 # expire tree if needed
456 factory.addStep(FileDownload(
457 doStepIf = IsExpireRequested,
458 mastersrc = "expire.sh",
459 slavedest = "../expire.sh",
462 factory.addStep(ShellCommand(
464 description = "Checking for build tree expiry",
465 command = ["./expire.sh", str(tree_expire)],
467 haltOnFailure = True,
468 doStepIf = IsExpireRequested,
471 # cleanup.sh if needed
472 factory.addStep(FileDownload(
473 mastersrc = "cleanup.sh",
474 slavedest = "../cleanup.sh",
476 doStepIf = IsCleanupRequested))
478 factory.addStep(ShellCommand(
480 description = "Cleaning previous builds",
481 command = ["./cleanup.sh", c['buildbotURL'], WithProperties("%(slavename)s"), WithProperties("%(buildername)s"), "full"],
483 haltOnFailure = True,
484 doStepIf = IsCleanupRequested,
487 factory.addStep(ShellCommand(
489 description = "Cleaning work area",
490 command = ["./cleanup.sh", c['buildbotURL'], WithProperties("%(slavename)s"), WithProperties("%(buildername)s"), "single"],
492 haltOnFailure = True,
493 doStepIf = IsCleanupRequested,
496 # user-requested clean targets
497 for tuple in CleanTargetMap:
498 factory.addStep(ShellCommand(
500 description = 'User-requested "make %s"' % tuple[1],
501 command = ["make", tuple[1], "V=s"],
503 doStepIf = IsMakeCleanRequested(tuple[0])
506 # check out the source
508 # if repo doesn't exist: 'git clone repourl'
509 # method 'clean' runs 'git clean -d -f', method fresh runs 'git clean -d -f x'. Only works with mode='full'
510 # 'git fetch -t repourl branch; git reset --hard revision'
513 branch = repo_branch,
517 haltOnFailure = True,
521 factory.addStep(ShellCommand(
523 description = "Fetching Git remote refs",
524 command = ["git", "fetch", "origin", "+refs/heads/%s:refs/remotes/origin/%s" %(repo_branch, repo_branch)],
529 factory.addStep(ShellCommand(
531 description = "Checking out Git tag",
532 command = ["git", "checkout", WithProperties("tags/v%(tag:-)s")],
533 haltOnFailure = True,
534 doStepIf = IsTaggingRequested
537 factory.addStep(ShellCommand(
539 description = "Remove tmp folder",
540 command=["rm", "-rf", "tmp/"]))
543 # factory.addStep(ShellCommand(
544 # name = "feedsconf",
545 # description = "Copy the feeds.conf",
546 # command='''cp ~/feeds.conf ./feeds.conf''' ))
549 factory.addStep(ShellCommand(
550 name = "rmfeedlinks",
551 description = "Remove feed symlinks",
552 command=["rm", "-rf", "package/feeds/"]))
555 factory.addStep(ShellCommand(
556 name = "updatefeeds",
557 description = "Updating feeds",
558 command=["./scripts/feeds", "update"],
564 factory.addStep(ShellCommand(
565 name = "installfeeds",
566 description = "Installing feeds",
567 command=["./scripts/feeds", "install", "-a"],
571 factory.addStep(FileDownload(
572 mastersrc = "config.seed",
573 slavedest = ".config",
578 factory.addStep(ShellCommand(
580 description = "Seeding .config",
581 command = "printf 'CONFIG_TARGET_%s=y\\nCONFIG_TARGET_%s_%s=y\\n' >> .config" %(ts[0], ts[0], ts[1])
584 factory.addStep(ShellCommand(
586 description = "Removing output directory",
587 command = ["rm", "-rf", "bin/"]
590 factory.addStep(ShellCommand(
592 description = "Populating .config",
593 command = ["make", "defconfig"],
598 factory.addStep(ShellCommand(
600 description = "Checking architecture",
601 command = ["grep", "-sq", "CONFIG_TARGET_%s=y" %(ts[0]), ".config"],
609 factory.addStep(SetProperty(
612 description = "Finding libc suffix",
613 command = ["sed", "-ne", '/^CONFIG_LIBC=/ { s!^CONFIG_LIBC="\\(.*\\)"!\\1!; s!^musl$!!; s!.\\+!-&!p }', ".config"]))
616 factory.addStep(FileDownload(
617 mastersrc = "ccache.sh",
618 slavedest = "../ccache.sh",
623 factory.addStep(ShellCommand(
625 description = "Preparing ccache",
626 command = ["../ccache.sh"]
630 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build', slavedest="key-build", mode=0600))
631 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build.pub', slavedest="key-build.pub", mode=0600))
634 factory.addStep(ShellCommand(
636 description = "Preparing dl/",
637 command = "mkdir -p $HOME/dl && rm -rf ./dl && ln -sf $HOME/dl ./dl",
643 factory.addStep(ShellCommand(
645 description = "Building and installing GNU tar",
646 command = ["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "tools/tar/compile", "V=s"],
647 env = MakeEnv(tryccache=True),
652 factory.addStep(ShellCommand(
654 description = "Populating dl/",
655 command = ["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "download", "V=s"],
658 locks = properties.FlattenList(NetLockDl, [dlLock.access('exclusive')]),
661 factory.addStep(ShellCommand(
663 description = "Cleaning base-files",
664 command=["make", "package/base-files/clean", "V=s"]
668 factory.addStep(ShellCommand(
670 description = "Building and installing tools",
671 command = ["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "tools/install", "V=s"],
672 env = MakeEnv(tryccache=True),
676 factory.addStep(ShellCommand(
678 description = "Building and installing toolchain",
679 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "toolchain/install", "V=s"],
684 factory.addStep(ShellCommand(
686 description = "Building kmods",
687 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "target/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
689 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
693 # find kernel version
694 factory.addStep(SetProperty(
695 name = "kernelversion",
696 property = "kernelversion",
697 description = "Finding the effective Kernel version",
698 command = "make --no-print-directory -C target/linux/ val.LINUX_VERSION val.LINUX_RELEASE val.LINUX_VERMAGIC | xargs printf '%s-%s-%s\\n'",
699 env = { 'TOPDIR': WithProperties("%(cwd)s/build", cwd=GetCwd) }
702 factory.addStep(ShellCommand(
704 description = "Cleaning up package build",
705 command=["make", "package/cleanup", "V=s"]
708 factory.addStep(ShellCommand(
710 description = "Building packages",
711 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
713 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
717 # factory.addStep(IfBuiltinShellCommand(
718 factory.addStep(ShellCommand(
720 description = "Installing packages",
721 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/install", "V=s"],
726 factory.addStep(ShellCommand(
728 description = "Indexing packages",
729 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/index", "V=s"],
734 if enable_kmod_archive:
735 factory.addStep(ShellCommand(
737 description = "Creating kmod directory",
738 command=["mkdir", "-p", WithProperties("bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s" %(ts[0], ts[1]))],
742 factory.addStep(ShellCommand(
743 name = "kmodprepare",
744 description = "Preparing kmod archive",
745 command=["rsync", "--include=/kmod-*.ipk", "--exclude=*", "-va",
746 WithProperties("bin/targets/%s/%s%%(libc)s/packages/" %(ts[0], ts[1])),
747 WithProperties("bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s/" %(ts[0], ts[1]))],
751 factory.addStep(ShellCommand(
753 description = "Indexing kmod archive",
754 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/index", "V=s",
755 WithProperties("PACKAGE_SUBDIRS=bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s/" %(ts[0], ts[1]))],
760 # find rootfs staging directory
761 factory.addStep(SetProperty(
763 property = "stageroot",
764 description = "Finding the rootfs staging directory",
765 command=["make", "--no-print-directory", "val.STAGING_DIR_ROOT"],
766 env = { 'TOPDIR': WithProperties("%(cwd)s/build", cwd=GetCwd) }
769 factory.addStep(ShellCommand(
771 description = "Creating file overlay directory",
772 command=["mkdir", "-p", "files/etc/opkg"],
776 factory.addStep(ShellCommand(
778 description = "Embedding kmod repository configuration",
779 command=WithProperties("sed -e 's#^\\(src/gz .*\\)_core \\(.*\\)/packages$#&\\n\\1_kmods \\2/kmods/%(kernelversion)s#' " +
780 "%(stageroot)s/etc/opkg/distfeeds.conf > files/etc/opkg/distfeeds.conf"),
784 #factory.addStep(IfBuiltinShellCommand(
785 factory.addStep(ShellCommand(
787 description = "Building and installing images",
788 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "target/install", "V=s"],
793 factory.addStep(ShellCommand(
795 description = "Generating config.seed",
796 command=["make", "-j1", "diffconfig", "V=s"],
801 factory.addStep(ShellCommand(
803 description = "Calculating checksums",
804 command=["make", "-j1", "checksum", "V=s"],
810 if gpg_keyid is not None:
811 factory.addStep(MasterShellCommand(
812 name = "signprepare",
813 description = "Preparing temporary signing directory",
814 command = ["mkdir", "-p", "%s/signing" %(home_dir)],
818 factory.addStep(ShellCommand(
820 description = "Packing files to sign",
821 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])),
825 factory.addStep(FileUpload(
826 slavesrc = "sign.tar.gz",
827 masterdest = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
831 factory.addStep(MasterShellCommand(
833 description = "Signing files",
834 command = ["%s/signall.sh" %(home_dir), "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]), gpg_keyid, gpg_comment],
835 env = {'GNUPGHOME': gpg_home, 'PASSFILE': gpg_passfile},
839 factory.addStep(FileDownload(
840 mastersrc = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
841 slavedest = "sign.tar.gz",
845 factory.addStep(ShellCommand(
847 description = "Unpacking signed files",
848 command = ["tar", "-xzf", "sign.tar.gz"],
853 factory.addStep(ShellCommand(
855 description = "Preparing upload directory structure",
856 command = ["mkdir", "-p", WithProperties("tmp/upload/%%(prefix)stargets/%s/%s" %(ts[0], ts[1]), prefix=GetVersionPrefix)],
860 factory.addStep(ShellCommand(
861 name = "linkprepare",
862 description = "Preparing repository symlink",
863 command = ["ln", "-s", "-f", WithProperties("../packages-%(basever)s", basever=GetBaseVersion), WithProperties("tmp/upload/%(prefix)spackages", prefix=GetVersionPrefix)],
864 doStepIf = IsNoMasterBuild,
868 if enable_kmod_archive:
869 factory.addStep(ShellCommand(
870 name = "kmoddirprepare",
871 description = "Preparing kmod archive upload directory",
872 command = ["mkdir", "-p", WithProperties("tmp/upload/%%(prefix)stargets/%s/%s/kmods/%%(kernelversion)s" %(ts[0], ts[1]), prefix=GetVersionPrefix)],
876 factory.addStep(ShellCommand(
878 description = "Uploading directory structure",
879 command = ["rsync", "-4", "--info=name", "-az", "tmp/upload/", "%s/" %(rsync_bin_url)],
880 env={'RSYNC_PASSWORD': rsync_bin_key},
881 haltOnFailure = True,
886 factory.addStep(FileDownload(
887 mastersrc = "rsync.sh",
888 slavedest = "../rsync.sh",
891 factory.addStep(ShellCommand(
892 name = "targetupload",
893 description = "Uploading target files",
894 command=["../rsync.sh", "-4", "--info=name", "--exclude=/kmods/", "--delete", "--size-only", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]),
895 "-a", WithProperties("bin/targets/%s/%s%%(libc)s/" %(ts[0], ts[1])),
896 WithProperties("%s/%%(prefix)stargets/%s/%s/" %(rsync_bin_url, ts[0], ts[1]), prefix=GetVersionPrefix)],
897 env={'RSYNC_PASSWORD': rsync_bin_key},
898 haltOnFailure = True,
903 if enable_kmod_archive:
904 factory.addStep(ShellCommand(
906 description = "Uploading kmod archive",
907 command=["../rsync.sh", "-4", "--info=name", "--delete", "--size-only", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]),
908 "-a", WithProperties("bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s/" %(ts[0], ts[1])),
909 WithProperties("%s/%%(prefix)stargets/%s/%s/kmods/%%(kernelversion)s/" %(rsync_bin_url, ts[0], ts[1]), prefix=GetVersionPrefix)],
910 env={'RSYNC_PASSWORD': rsync_bin_key},
911 haltOnFailure = True,
916 if rsync_src_url is not None:
917 factory.addStep(ShellCommand(
918 name = "sourceupload",
919 description = "Uploading source archives",
920 command=["../rsync.sh", "-4", "--info=name", "--size-only", "--delay-updates",
921 WithProperties("--partial-dir=.~tmp~%s~%s~%%(slavename)s" %(ts[0], ts[1])), "-a", "dl/", "%s/" %(rsync_src_url)],
922 env={'RSYNC_PASSWORD': rsync_src_key},
923 haltOnFailure = True,
929 factory.addStep(ShellCommand(
930 name = "packageupload",
931 description = "Uploading package files",
932 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)],
933 env={'RSYNC_PASSWORD': rsync_bin_key},
934 haltOnFailure = False,
941 factory.addStep(ShellCommand(
943 description = "Uploading logs",
944 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])],
945 env={'RSYNC_PASSWORD': rsync_bin_key},
946 haltOnFailure = False,
952 factory.addStep(ShellCommand(
954 description = "Reporting disk usage",
955 command=["df", "-h", "."],
957 haltOnFailure = False,
961 factory.addStep(ShellCommand(
963 description = "Reporting ccache stats",
964 command=["ccache", "-s"],
965 env = MakeEnv(overrides={ 'PATH': ["./staging_dir/host/bin", "${PATH}"] }),
967 haltOnFailure = False,
968 flunkOnFailure = False,
969 warnOnFailure = False,
973 from buildbot.config import BuilderConfig
975 c['builders'].append(BuilderConfig(name=target, slavenames=slaveNames, factory=factory, nextBuild=GetNextBuild))
978 ####### STATUS TARGETS
980 # 'status' is a list of Status Targets. The results of each build will be
981 # pushed to these targets. buildbot/status/*.py has a variety to choose from,
982 # including web pages, email senders, and IRC bots.
986 from buildbot.status import html
987 from buildbot.status.web import authz, auth
989 if ini.has_option("status", "bind"):
990 if ini.has_option("status", "user") and ini.has_option("status", "password"):
991 authz_cfg=authz.Authz(
992 # change any of these to True to enable; see the manual for more
994 auth=auth.BasicAuth([(ini.get("status", "user"), ini.get("status", "password"))]),
995 gracefulShutdown = 'auth',
996 forceBuild = 'auth', # use this to test your slave once it is set up
997 forceAllBuilds = 'auth',
1000 stopAllBuilds = 'auth',
1001 cancelPendingBuild = 'auth',
1003 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind"), authz=authz_cfg))
1005 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind")))
1008 from buildbot.status import words
1010 if ini.has_option("irc", "host") and ini.has_option("irc", "nickname") and ini.has_option("irc", "channel"):
1011 irc_host = ini.get("irc", "host")
1013 irc_chan = ini.get("irc", "channel")
1014 irc_nick = ini.get("irc", "nickname")
1017 if ini.has_option("irc", "port"):
1018 irc_port = ini.getint("irc", "port")
1020 if ini.has_option("irc", "password"):
1021 irc_pass = ini.get("irc", "password")
1023 irc = words.IRC(irc_host, irc_nick, port = irc_port, password = irc_pass,
1024 channels = [{ "channel": irc_chan }],
1027 'successToFailure': 1,
1028 'failureToSuccess': 1
1032 c['status'].append(irc)
1037 # This specifies what database buildbot uses to store its state. You can leave
1038 # this at its default for all but the largest installations.
1039 'db_url' : "sqlite:///state.sqlite",