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 IsGitFreshRequested(step):
241 do_cleanup = step.getProperty("do_cleanup")
247 def IsGitCleanRequested(step):
248 return not IsGitFreshRequested(step)
250 def IsTaggingRequested(step):
251 val = step.getProperty("tag")
252 if val and re.match("^[0-9]+\.[0-9]+\.[0-9]+(?:-rc[0-9]+)?$", val):
257 def IsNoTaggingRequested(step):
258 return not IsTaggingRequested(step)
260 def IsNoMasterBuild(step):
261 return repo_branch != "master"
263 def IsCleanupConfigured(step):
264 do_cleanup = step.getProperty("do_cleanup")
266 return do_cleanup > 0
270 def GetBaseVersion(props):
271 if re.match("^[^-]+-[0-9]+\.[0-9]+$", repo_branch):
272 return repo_branch.split('-')[1]
276 def GetVersionPrefix(props):
277 basever = GetBaseVersion(props)
278 if props.hasProperty("tag") and re.match("^[0-9]+\.[0-9]+\.[0-9]+(?:-rc[0-9]+)?$", props["tag"]):
279 return "%s/" % props["tag"]
280 elif basever != "master":
281 return "%s-SNAPSHOT/" % basever
285 def GetNumJobs(props):
286 if props.hasProperty("slavename") and props.hasProperty("nproc"):
287 return (int(props["nproc"]) / (max_builds[props["slavename"]] + other_builds))
292 if props.hasProperty("cc_command"):
293 return props["cc_command"]
298 if props.hasProperty("cxx_command"):
299 return props["cxx_command"]
304 if props.hasProperty("builddir"):
305 return props["builddir"]
306 elif props.hasProperty("workdir"):
307 return props["workdir"]
311 def GetCCache(props):
312 if props.hasProperty("ccache_command") and "ccache" in props["ccache_command"]:
313 return props["ccache_command"] + " "
317 def GetNextBuild(builder, requests):
319 if r.properties and r.properties.hasProperty("tag"):
323 def MakeEnv(overrides=None, tryccache=False):
325 envcc = Interpolate("%(kw:ccache)s%(kw:cc)s", ccache=GetCCache, cc=GetCC)
326 envcxx = Interpolate("%(kw:ccache)s%(kw:cxx)s", ccache=GetCCache, cxx=GetCXX)
328 envcc = Interpolate("%(kw:cc)s", cc=GetCC)
329 envcxx = Interpolate("%(kw:cxx)s", cxx=GetCXX)
333 'CCACHE_BASEDIR': Interpolate("%(kw:cwd)s", cwd=GetCwd)
335 if overrides is not None:
336 env.update(overrides)
340 def NetLockDl(props):
342 if props.hasProperty("dl_lock"):
343 lock = NetLocks[props["dl_lock"]]
345 return [lock.access('exclusive')]
350 def NetLockUl(props):
352 if props.hasProperty("ul_lock"):
353 lock = NetLocks[props["ul_lock"]]
355 return [lock.access('exclusive')]
361 dlLock = locks.SlaveLock("slave_dl")
363 checkBuiltin = re.sub('[\t\n ]+', ' ', """
365 local symbol op path file;
366 for file in $CHANGED_FILES; do
372 while read symbol op path; do
373 case "$symbol" in package-*)
374 symbol="${symbol##*(}";
375 symbol="${symbol%)}";
376 for file in $CHANGED_FILES; do
377 case "$file" in "package/$path/"*)
378 grep -qsx "$symbol=y" .config && return 0
382 done < tmp/.packagedeps;
388 class IfBuiltinShellCommand(ShellCommand):
389 def _quote(self, str):
390 if re.search("[^a-zA-Z0-9/_.-]", str):
391 return "'%s'" %(re.sub("'", "'\"'\"'", str))
394 def setCommand(self, command):
395 if not isinstance(command, (str, unicode)):
396 command = ' '.join(map(self._quote, command))
399 '%s; if checkBuiltin; then %s; else exit 0; fi' %(checkBuiltin, command)
402 def setupEnvironment(self, cmd):
403 slaveEnv = self.slaveEnvironment
407 for request in self.build.requests:
408 for source in request.sources:
409 for change in source.changes:
410 for file in change.files:
411 changedFiles[file] = True
412 fullSlaveEnv = slaveEnv.copy()
413 fullSlaveEnv['CHANGED_FILES'] = ' '.join(changedFiles.keys())
414 cmd.args['env'] = fullSlaveEnv
418 for slave in c['slaves']:
419 slaveNames.append(slave.slavename)
421 for target in targets:
422 ts = target.split('/')
424 factory = BuildFactory()
426 # find number of cores
427 factory.addStep(SetProperty(
430 description = "Finding number of CPUs",
431 command = ["nproc"]))
433 # find gcc and g++ compilers
434 if cc_version is not None:
435 factory.addStep(FileDownload(
436 mastersrc = "findbin.pl",
437 slavedest = "../findbin.pl",
440 factory.addStep(SetProperty(
442 property = "cc_command",
443 description = "Finding gcc command",
444 command = ["../findbin.pl", "gcc", cc_version[0], cc_version[1]],
445 haltOnFailure = True))
447 factory.addStep(SetProperty(
449 property = "cxx_command",
450 description = "Finding g++ command",
451 command = ["../findbin.pl", "g++", cc_version[0], cc_version[1]],
452 haltOnFailure = True))
454 # see if ccache is available
455 factory.addStep(SetPropertyFromCommand(
456 property = "ccache_command",
457 command = ["which", "ccache"],
458 description = "Testing for ccache command",
459 haltOnFailure = False,
460 flunkOnFailure = False,
461 warnOnFailure = False,
464 # expire tree if needed
466 factory.addStep(FileDownload(
467 doStepIf = IsExpireRequested,
468 mastersrc = "expire.sh",
469 slavedest = "../expire.sh",
472 factory.addStep(ShellCommand(
474 description = "Checking for build tree expiry",
475 command = ["./expire.sh", str(tree_expire)],
477 haltOnFailure = True,
478 doStepIf = IsExpireRequested,
481 # cleanup.sh if needed
482 factory.addStep(FileDownload(
483 mastersrc = "cleanup.sh",
484 slavedest = "../cleanup.sh",
486 doStepIf = IsCleanupRequested))
488 factory.addStep(ShellCommand(
490 description = "Cleaning previous builds",
491 command = ["./cleanup.sh", c['buildbotURL'], WithProperties("%(slavename)s"), WithProperties("%(buildername)s"), "full"],
493 haltOnFailure = True,
494 doStepIf = IsCleanupRequested,
497 factory.addStep(ShellCommand(
499 description = "Cleaning work area",
500 command = ["./cleanup.sh", c['buildbotURL'], WithProperties("%(slavename)s"), WithProperties("%(buildername)s"), "single"],
502 haltOnFailure = True,
503 doStepIf = IsCleanupRequested,
506 # user-requested clean targets
507 for tuple in CleanTargetMap:
508 factory.addStep(ShellCommand(
510 description = 'User-requested "make %s"' % tuple[1],
511 command = ["make", tuple[1], "V=s"],
513 doStepIf = IsMakeCleanRequested(tuple[0])
516 # check out the source
518 # if repo doesn't exist: 'git clone repourl'
519 # method 'clean' runs 'git clean -d -f', method fresh runs 'git clean -d -f x'. Only works with mode='full'
520 # 'git fetch -t repourl branch; git reset --hard revision'
521 # Git() parameters can't take a renderer until buildbot 0.8.10, so we have to split the fresh and clean cases
522 # if buildbot is updated, one can use: method = Interpolate('%(prop:do_cleanup:#?|fresh|clean)s')
525 branch = repo_branch,
529 haltOnFailure = True,
530 doStepIf = IsGitCleanRequested,
535 branch = repo_branch,
539 haltOnFailure = True,
540 doStepIf = IsGitFreshRequested,
544 factory.addStep(ShellCommand(
546 description = "Fetching Git remote refs",
547 command = ["git", "fetch", "origin", "+refs/heads/%s:refs/remotes/origin/%s" %(repo_branch, repo_branch)],
552 factory.addStep(ShellCommand(
554 description = "Checking out Git tag",
555 command = ["git", "checkout", WithProperties("tags/v%(tag:-)s")],
556 haltOnFailure = True,
557 doStepIf = IsTaggingRequested
560 factory.addStep(ShellCommand(
562 description = "Remove tmp folder",
563 command=["rm", "-rf", "tmp/"]))
566 # factory.addStep(ShellCommand(
567 # name = "feedsconf",
568 # description = "Copy the feeds.conf",
569 # command='''cp ~/feeds.conf ./feeds.conf''' ))
572 factory.addStep(ShellCommand(
573 name = "rmfeedlinks",
574 description = "Remove feed symlinks",
575 command=["rm", "-rf", "package/feeds/"]))
578 factory.addStep(ShellCommand(
579 name = "updatefeeds",
580 description = "Updating feeds",
581 command=["./scripts/feeds", "update"],
587 factory.addStep(ShellCommand(
588 name = "installfeeds",
589 description = "Installing feeds",
590 command=["./scripts/feeds", "install", "-a"],
594 factory.addStep(FileDownload(
595 mastersrc = "config.seed",
596 slavedest = ".config",
601 factory.addStep(ShellCommand(
603 description = "Seeding .config",
604 command = "printf 'CONFIG_TARGET_%s=y\\nCONFIG_TARGET_%s_%s=y\\n' >> .config" %(ts[0], ts[0], ts[1])
607 factory.addStep(ShellCommand(
609 description = "Removing output directory",
610 command = ["rm", "-rf", "bin/"]
613 factory.addStep(ShellCommand(
615 description = "Populating .config",
616 command = ["make", "defconfig"],
621 factory.addStep(ShellCommand(
623 description = "Checking architecture",
624 command = ["grep", "-sq", "CONFIG_TARGET_%s=y" %(ts[0]), ".config"],
632 factory.addStep(SetProperty(
635 description = "Finding libc suffix",
636 command = ["sed", "-ne", '/^CONFIG_LIBC=/ { s!^CONFIG_LIBC="\\(.*\\)"!\\1!; s!^musl$!!; s!.\\+!-&!p }', ".config"]))
639 factory.addStep(FileDownload(
640 mastersrc = "ccache.sh",
641 slavedest = "../ccache.sh",
646 factory.addStep(ShellCommand(
648 description = "Preparing ccache",
649 command = ["../ccache.sh"]
653 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build', slavedest="key-build", mode=0600))
654 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build.pub', slavedest="key-build.pub", mode=0600))
657 factory.addStep(ShellCommand(
659 description = "Preparing dl/",
660 command = "mkdir -p $HOME/dl && rm -rf ./dl && ln -sf $HOME/dl ./dl",
666 factory.addStep(ShellCommand(
668 description = "Building and installing GNU tar",
669 command = ["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "tools/tar/compile", "V=s"],
670 env = MakeEnv(tryccache=True),
675 factory.addStep(ShellCommand(
677 description = "Populating dl/",
678 command = ["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "download", "V=s"],
681 locks = properties.FlattenList(NetLockDl, [dlLock.access('exclusive')]),
684 factory.addStep(ShellCommand(
686 description = "Cleaning base-files",
687 command=["make", "package/base-files/clean", "V=s"]
691 factory.addStep(ShellCommand(
693 description = "Building and installing tools",
694 command = ["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "tools/install", "V=s"],
695 env = MakeEnv(tryccache=True),
699 factory.addStep(ShellCommand(
701 description = "Building and installing toolchain",
702 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "toolchain/install", "V=s"],
707 factory.addStep(ShellCommand(
709 description = "Building kmods",
710 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "target/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
712 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
716 # find kernel version
717 factory.addStep(SetProperty(
718 name = "kernelversion",
719 property = "kernelversion",
720 description = "Finding the effective Kernel version",
721 command = "make --no-print-directory -C target/linux/ val.LINUX_VERSION val.LINUX_RELEASE val.LINUX_VERMAGIC | xargs printf '%s-%s-%s\\n'",
722 env = { 'TOPDIR': WithProperties("%(cwd)s/build", cwd=GetCwd) }
725 factory.addStep(ShellCommand(
727 description = "Cleaning up package build",
728 command=["make", "package/cleanup", "V=s"]
731 factory.addStep(ShellCommand(
733 description = "Building packages",
734 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
736 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
740 # factory.addStep(IfBuiltinShellCommand(
741 factory.addStep(ShellCommand(
743 description = "Installing packages",
744 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/install", "V=s"],
749 factory.addStep(ShellCommand(
751 description = "Indexing packages",
752 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/index", "V=s"],
757 if enable_kmod_archive:
758 factory.addStep(ShellCommand(
760 description = "Creating kmod directory",
761 command=["mkdir", "-p", WithProperties("bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s" %(ts[0], ts[1]))],
765 factory.addStep(ShellCommand(
766 name = "kmodprepare",
767 description = "Preparing kmod archive",
768 command=["rsync", "--include=/kmod-*.ipk", "--exclude=*", "-va",
769 WithProperties("bin/targets/%s/%s%%(libc)s/packages/" %(ts[0], ts[1])),
770 WithProperties("bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s/" %(ts[0], ts[1]))],
774 factory.addStep(ShellCommand(
776 description = "Indexing kmod archive",
777 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "package/index", "V=s",
778 WithProperties("PACKAGE_SUBDIRS=bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s/" %(ts[0], ts[1]))],
783 # find rootfs staging directory
784 factory.addStep(SetProperty(
786 property = "stageroot",
787 description = "Finding the rootfs staging directory",
788 command=["make", "--no-print-directory", "val.STAGING_DIR_ROOT"],
789 env = { 'TOPDIR': WithProperties("%(cwd)s/build", cwd=GetCwd) }
792 factory.addStep(ShellCommand(
794 description = "Creating file overlay directory",
795 command=["mkdir", "-p", "files/etc/opkg"],
799 factory.addStep(ShellCommand(
801 description = "Embedding kmod repository configuration",
802 command=WithProperties("sed -e 's#^\\(src/gz .*\\)_core \\(.*\\)/packages$#&\\n\\1_kmods \\2/kmods/%(kernelversion)s#' " +
803 "%(stageroot)s/etc/opkg/distfeeds.conf > files/etc/opkg/distfeeds.conf"),
807 #factory.addStep(IfBuiltinShellCommand(
808 factory.addStep(ShellCommand(
810 description = "Building and installing images",
811 command=["make", WithProperties("-j%(jobs)d", jobs=GetNumJobs), "target/install", "V=s"],
816 factory.addStep(ShellCommand(
818 description = "Generating config.seed",
819 command=["make", "-j1", "diffconfig", "V=s"],
824 factory.addStep(ShellCommand(
826 description = "Calculating checksums",
827 command=["make", "-j1", "checksum", "V=s"],
833 if gpg_keyid is not None:
834 factory.addStep(MasterShellCommand(
835 name = "signprepare",
836 description = "Preparing temporary signing directory",
837 command = ["mkdir", "-p", "%s/signing" %(home_dir)],
841 factory.addStep(ShellCommand(
843 description = "Packing files to sign",
844 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])),
848 factory.addStep(FileUpload(
849 slavesrc = "sign.tar.gz",
850 masterdest = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
854 factory.addStep(MasterShellCommand(
856 description = "Signing files",
857 command = ["%s/signall.sh" %(home_dir), "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]), gpg_keyid, gpg_comment],
858 env = {'GNUPGHOME': gpg_home, 'PASSFILE': gpg_passfile},
862 factory.addStep(FileDownload(
863 mastersrc = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
864 slavedest = "sign.tar.gz",
868 factory.addStep(ShellCommand(
870 description = "Unpacking signed files",
871 command = ["tar", "-xzf", "sign.tar.gz"],
876 factory.addStep(ShellCommand(
878 description = "Preparing upload directory structure",
879 command = ["mkdir", "-p", WithProperties("tmp/upload/%%(prefix)stargets/%s/%s" %(ts[0], ts[1]), prefix=GetVersionPrefix)],
883 factory.addStep(ShellCommand(
884 name = "linkprepare",
885 description = "Preparing repository symlink",
886 command = ["ln", "-s", "-f", WithProperties("../packages-%(basever)s", basever=GetBaseVersion), WithProperties("tmp/upload/%(prefix)spackages", prefix=GetVersionPrefix)],
887 doStepIf = IsNoMasterBuild,
891 if enable_kmod_archive:
892 factory.addStep(ShellCommand(
893 name = "kmoddirprepare",
894 description = "Preparing kmod archive upload directory",
895 command = ["mkdir", "-p", WithProperties("tmp/upload/%%(prefix)stargets/%s/%s/kmods/%%(kernelversion)s" %(ts[0], ts[1]), prefix=GetVersionPrefix)],
899 factory.addStep(ShellCommand(
901 description = "Uploading directory structure",
902 command = ["rsync", "-4", "--info=name", "-az", "tmp/upload/", "%s/" %(rsync_bin_url)],
903 env={'RSYNC_PASSWORD': rsync_bin_key},
904 haltOnFailure = True,
909 factory.addStep(FileDownload(
910 mastersrc = "rsync.sh",
911 slavedest = "../rsync.sh",
914 factory.addStep(ShellCommand(
915 name = "targetupload",
916 description = "Uploading target files",
917 command=["../rsync.sh", "-4", "--info=name", "--exclude=/kmods/", "--delete", "--size-only", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]),
918 "-a", WithProperties("bin/targets/%s/%s%%(libc)s/" %(ts[0], ts[1])),
919 WithProperties("%s/%%(prefix)stargets/%s/%s/" %(rsync_bin_url, ts[0], ts[1]), prefix=GetVersionPrefix)],
920 env={'RSYNC_PASSWORD': rsync_bin_key},
921 haltOnFailure = True,
926 if enable_kmod_archive:
927 factory.addStep(ShellCommand(
929 description = "Uploading kmod archive",
930 command=["../rsync.sh", "-4", "--info=name", "--delete", "--size-only", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]),
931 "-a", WithProperties("bin/targets/%s/%s%%(libc)s/kmods/%%(kernelversion)s/" %(ts[0], ts[1])),
932 WithProperties("%s/%%(prefix)stargets/%s/%s/kmods/%%(kernelversion)s/" %(rsync_bin_url, ts[0], ts[1]), prefix=GetVersionPrefix)],
933 env={'RSYNC_PASSWORD': rsync_bin_key},
934 haltOnFailure = True,
939 if rsync_src_url is not None:
940 factory.addStep(ShellCommand(
941 name = "sourceupload",
942 description = "Uploading source archives",
943 command=["../rsync.sh", "-4", "--info=name", "--size-only", "--delay-updates",
944 WithProperties("--partial-dir=.~tmp~%s~%s~%%(slavename)s" %(ts[0], ts[1])), "-a", "dl/", "%s/" %(rsync_src_url)],
945 env={'RSYNC_PASSWORD': rsync_src_key},
946 haltOnFailure = True,
952 factory.addStep(ShellCommand(
953 name = "packageupload",
954 description = "Uploading package files",
955 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)],
956 env={'RSYNC_PASSWORD': rsync_bin_key},
957 haltOnFailure = False,
964 factory.addStep(ShellCommand(
966 description = "Uploading logs",
967 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])],
968 env={'RSYNC_PASSWORD': rsync_bin_key},
969 haltOnFailure = False,
975 factory.addStep(ShellCommand(
977 description = "Reporting disk usage",
978 command=["df", "-h", "."],
980 haltOnFailure = False,
984 factory.addStep(ShellCommand(
986 description = "Reporting ccache stats",
987 command=["ccache", "-s"],
988 env = MakeEnv(overrides={ 'PATH': ["./staging_dir/host/bin", "${PATH}"] }),
990 haltOnFailure = False,
991 flunkOnFailure = False,
992 warnOnFailure = False,
996 from buildbot.config import BuilderConfig
998 c['builders'].append(BuilderConfig(name=target, slavenames=slaveNames, factory=factory, nextBuild=GetNextBuild))
1001 ####### STATUS TARGETS
1003 # 'status' is a list of Status Targets. The results of each build will be
1004 # pushed to these targets. buildbot/status/*.py has a variety to choose from,
1005 # including web pages, email senders, and IRC bots.
1009 from buildbot.status import html
1010 from buildbot.status.web import authz, auth
1012 if ini.has_option("status", "bind"):
1013 if ini.has_option("status", "user") and ini.has_option("status", "password"):
1014 authz_cfg=authz.Authz(
1015 # change any of these to True to enable; see the manual for more
1017 auth=auth.BasicAuth([(ini.get("status", "user"), ini.get("status", "password"))]),
1018 gracefulShutdown = 'auth',
1019 forceBuild = 'auth', # use this to test your slave once it is set up
1020 forceAllBuilds = 'auth',
1021 pingBuilder = False,
1023 stopAllBuilds = 'auth',
1024 cancelPendingBuild = 'auth',
1026 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind"), authz=authz_cfg))
1028 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind")))
1031 from buildbot.status import words
1033 if ini.has_option("irc", "host") and ini.has_option("irc", "nickname") and ini.has_option("irc", "channel"):
1034 irc_host = ini.get("irc", "host")
1036 irc_chan = ini.get("irc", "channel")
1037 irc_nick = ini.get("irc", "nickname")
1040 if ini.has_option("irc", "port"):
1041 irc_port = ini.getint("irc", "port")
1043 if ini.has_option("irc", "password"):
1044 irc_pass = ini.get("irc", "password")
1046 irc = words.IRC(irc_host, irc_nick, port = irc_port, password = irc_pass,
1047 channels = [{ "channel": irc_chan }],
1050 'successToFailure': 1,
1051 'failureToSuccess': 1
1055 c['status'].append(irc)
1060 # This specifies what database buildbot uses to store its state. You can leave
1061 # this at its default for all but the largest installations.
1062 'db_url' : "sqlite:///state.sqlite",