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")
53 for section in ini.sections():
54 if section.startswith("slave "):
55 if ini.has_option(section, "name") and ini.has_option(section, "password"):
56 sl_props = { 'dl_lock':None, 'ul_lock':None, 'do_cleanup':False, 'max_builds':1, 'shared_wd':False }
57 name = ini.get(section, "name")
58 password = ini.get(section, "password")
60 if ini.has_option(section, "builds"):
61 max_builds = ini.getint(section, "builds")
62 sl_props['max_builds'] = max_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 if ini.has_option(section, "shared_wd"):
76 shared_wd = ini.getboolean(section, "shared_wd")
77 sl_props['shared_wd'] = shared_wd
78 if shared_wd and (max_builds != 1):
79 raise ValueError('max_builds must be 1 with shared workdir!')
80 c['slaves'].append(BuildSlave(name, password, max_builds = max_builds, properties = sl_props))
82 # 'slavePortnum' defines the TCP port to listen on for connections from slaves.
83 # This must match the value configured into the buildslaves (with their
85 c['slavePortnum'] = slave_port
88 c['mergeRequests'] = True
90 # Reduce amount of backlog data
91 c['buildHorizon'] = 30
96 home_dir = os.path.abspath(ini.get("general", "homedir"))
104 if ini.has_option("general", "expire"):
105 tree_expire = ini.getint("general", "expire")
107 if ini.has_option("general", "other_builds"):
108 other_builds = ini.getint("general", "other_builds")
110 if ini.has_option("general", "cc_version"):
111 cc_version = ini.get("general", "cc_version").split()
112 if len(cc_version) == 1:
113 cc_version = ["eq", cc_version[0]]
115 repo_url = ini.get("repo", "url")
116 repo_branch = "master"
118 if ini.has_option("repo", "branch"):
119 repo_branch = ini.get("repo", "branch")
121 rsync_bin_url = ini.get("rsync", "binary_url")
122 rsync_bin_key = ini.get("rsync", "binary_password")
127 if ini.has_option("rsync", "source_url"):
128 rsync_src_url = ini.get("rsync", "source_url")
129 rsync_src_key = ini.get("rsync", "source_password")
131 gpg_home = "~/.gnupg"
133 gpg_comment = "Unattended build signature"
134 gpg_passfile = "/dev/null"
136 if ini.has_option("gpg", "home"):
137 gpg_home = ini.get("gpg", "home")
139 if ini.has_option("gpg", "keyid"):
140 gpg_keyid = ini.get("gpg", "keyid")
142 if ini.has_option("gpg", "comment"):
143 gpg_comment = ini.get("gpg", "comment")
145 if ini.has_option("gpg", "passfile"):
146 gpg_passfile = ini.get("gpg", "passfile")
148 enable_kmod_archive = True
154 if not os.path.isdir(home_dir+'/source.git'):
155 subprocess.call(["git", "clone", "--depth=1", "--branch="+repo_branch, repo_url, home_dir+'/source.git'])
157 subprocess.call(["git", "pull"], cwd = home_dir+'/source.git')
159 findtargets = subprocess.Popen([home_dir+'/dumpinfo.pl', 'targets'],
160 stdout = subprocess.PIPE, cwd = home_dir+'/source.git')
163 line = findtargets.stdout.readline()
166 ta = line.strip().split(' ')
167 targets.append(ta[0])
170 # the 'change_source' setting tells the buildmaster how it should find out
171 # about source code changes. Here we point to the buildbot clone of pyflakes.
173 from buildbot.changes.gitpoller import GitPoller
174 c['change_source'] = []
175 c['change_source'].append(GitPoller(
177 workdir=home_dir+'/work.git', branch=repo_branch,
182 # Configure the Schedulers, which decide how to react to incoming changes. In this
183 # case, just kick off a 'basebuild' build
185 from buildbot.schedulers.basic import SingleBranchScheduler
186 from buildbot.schedulers.forcesched import ForceScheduler
187 from buildbot.changes import filter
189 c['schedulers'].append(SingleBranchScheduler(
191 change_filter=filter.ChangeFilter(branch=repo_branch),
193 builderNames=targets))
195 c['schedulers'].append(ForceScheduler(
197 builderNames=targets))
201 # The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
202 # what steps, and which slaves can execute them. Note that any particular build will
203 # only take place on one slave.
205 from buildbot.process.factory import BuildFactory
206 from buildbot.steps.source.git import Git
207 from buildbot.steps.shell import ShellCommand
208 from buildbot.steps.shell import SetPropertyFromCommand
209 from buildbot.steps.transfer import FileUpload
210 from buildbot.steps.transfer import FileDownload
211 from buildbot.steps.master import MasterShellCommand
212 from buildbot.process.properties import Interpolate
213 from buildbot.process import properties
217 [ "tools", "tools/clean" ],
218 [ "chain", "toolchain/clean" ],
219 [ "linux", "target/linux/clean" ],
220 [ "dir", "dirclean" ],
221 [ "dist", "distclean" ]
224 def IsMakeCleanRequested(pattern):
225 def CheckCleanProperty(step):
226 val = step.getProperty("clean")
227 if val and re.match(pattern, val):
232 return CheckCleanProperty
234 def IsCleanupRequested(step):
235 shared_wd = step.getProperty("shared_wd")
238 do_cleanup = step.getProperty("do_cleanup")
244 def IsExpireRequested(step):
245 shared_wd = step.getProperty("shared_wd")
249 return not IsCleanupRequested(step)
251 def IsGitFreshRequested(step):
252 do_cleanup = step.getProperty("do_cleanup")
258 def IsGitCleanRequested(step):
259 return not IsGitFreshRequested(step)
261 def IsTaggingRequested(step):
262 val = step.getProperty("tag")
263 if val and re.match("^[0-9]+\.[0-9]+\.[0-9]+(?:-rc[0-9]+)?$", val):
268 def IsNoTaggingRequested(step):
269 return not IsTaggingRequested(step)
271 def IsNoMasterBuild(step):
272 return repo_branch != "master"
274 def GetBaseVersion():
275 if re.match("^[^-]+-[0-9]+\.[0-9]+$", repo_branch):
276 return repo_branch.split('-')[1]
281 def GetVersionPrefix(props):
282 basever = GetBaseVersion()
283 if props.hasProperty("tag") and re.match("^[0-9]+\.[0-9]+\.[0-9]+(?:-rc[0-9]+)?$", props["tag"]):
284 return "%s/" % props["tag"]
285 elif basever != "master":
286 return "%s-SNAPSHOT/" % basever
291 def GetNumJobs(props):
292 if props.hasProperty("max_builds") and props.hasProperty("nproc"):
293 return str(int(props["nproc"]) / (props["max_builds"] + other_builds))
299 if props.hasProperty("cc_command"):
300 return props["cc_command"]
306 if props.hasProperty("cxx_command"):
307 return props["cxx_command"]
313 if props.hasProperty("builddir"):
314 return props["builddir"]
315 elif props.hasProperty("workdir"):
316 return props["workdir"]
321 def GetCCache(props):
322 if props.hasProperty("ccache_command") and "ccache" in props["ccache_command"]:
323 return props["ccache_command"] + " "
327 def GetNextBuild(builder, requests):
329 if r.properties and r.properties.hasProperty("tag"):
333 def MakeEnv(overrides=None, tryccache=False):
335 envcc = Interpolate("%(kw:ccache)s%(kw:cc)s", ccache=GetCCache, cc=GetCC)
336 envcxx = Interpolate("%(kw:ccache)s%(kw:cxx)s", ccache=GetCCache, cxx=GetCXX)
338 envcc = Interpolate("%(kw:cc)s", cc=GetCC)
339 envcxx = Interpolate("%(kw:cxx)s", cxx=GetCXX)
343 'CCACHE_BASEDIR': Interpolate("%(kw:cwd)s", cwd=GetCwd)
345 if overrides is not None:
346 env.update(overrides)
350 def NetLockDl(props):
352 if props.hasProperty("dl_lock"):
353 lock = NetLocks[props["dl_lock"]]
355 return [lock.access('exclusive')]
360 def NetLockUl(props):
362 if props.hasProperty("ul_lock"):
363 lock = NetLocks[props["ul_lock"]]
365 return [lock.access('exclusive')]
371 dlLock = locks.SlaveLock("slave_dl")
373 checkBuiltin = re.sub('[\t\n ]+', ' ', """
375 local symbol op path file;
376 for file in $CHANGED_FILES; do
382 while read symbol op path; do
383 case "$symbol" in package-*)
384 symbol="${symbol##*(}";
385 symbol="${symbol%)}";
386 for file in $CHANGED_FILES; do
387 case "$file" in "package/$path/"*)
388 grep -qsx "$symbol=y" .config && return 0
392 done < tmp/.packagedeps;
398 class IfBuiltinShellCommand(ShellCommand):
399 def _quote(self, str):
400 if re.search("[^a-zA-Z0-9/_.-]", str):
401 return "'%s'" %(re.sub("'", "'\"'\"'", str))
404 def setCommand(self, command):
405 if not isinstance(command, (str, unicode)):
406 command = ' '.join(map(self._quote, command))
409 '%s; if checkBuiltin; then %s; else exit 0; fi' %(checkBuiltin, command)
412 def setupEnvironment(self, cmd):
413 slaveEnv = self.slaveEnvironment
417 for request in self.build.requests:
418 for source in request.sources:
419 for change in source.changes:
420 for file in change.files:
421 changedFiles[file] = True
422 fullSlaveEnv = slaveEnv.copy()
423 fullSlaveEnv['CHANGED_FILES'] = ' '.join(changedFiles.keys())
424 cmd.args['env'] = fullSlaveEnv
428 for slave in c['slaves']:
429 slaveNames.append(slave.slavename)
431 for target in targets:
432 ts = target.split('/')
434 factory = BuildFactory()
436 # find number of cores
437 factory.addStep(SetPropertyFromCommand(
440 description = "Finding number of CPUs",
441 command = ["nproc"]))
443 # find gcc and g++ compilers
444 if cc_version is not None:
445 factory.addStep(FileDownload(
446 mastersrc = "findbin.pl",
447 slavedest = "../findbin.pl",
450 factory.addStep(SetPropertyFromCommand(
452 property = "cc_command",
453 description = "Finding gcc command",
454 command = ["../findbin.pl", "gcc", cc_version[0], cc_version[1]],
455 haltOnFailure = True))
457 factory.addStep(SetPropertyFromCommand(
459 property = "cxx_command",
460 description = "Finding g++ command",
461 command = ["../findbin.pl", "g++", cc_version[0], cc_version[1]],
462 haltOnFailure = True))
464 # see if ccache is available
465 factory.addStep(SetPropertyFromCommand(
466 property = "ccache_command",
467 command = ["which", "ccache"],
468 description = "Testing for ccache command",
469 haltOnFailure = False,
470 flunkOnFailure = False,
471 warnOnFailure = False,
474 # expire tree if needed
476 factory.addStep(FileDownload(
477 doStepIf = IsExpireRequested,
478 mastersrc = "expire.sh",
479 slavedest = "../expire.sh",
482 factory.addStep(ShellCommand(
484 description = "Checking for build tree expiry",
485 command = ["./expire.sh", str(tree_expire)],
487 haltOnFailure = True,
488 doStepIf = IsExpireRequested,
491 # cleanup.sh if needed
492 factory.addStep(FileDownload(
493 mastersrc = "cleanup.sh",
494 slavedest = "../cleanup.sh",
496 doStepIf = IsCleanupRequested))
498 factory.addStep(ShellCommand(
500 description = "Cleaning previous builds",
501 command = ["./cleanup.sh", c['buildbotURL'], Interpolate("%(prop:slavename)s"), Interpolate("%(prop:buildername)s"), "full"],
503 haltOnFailure = True,
504 doStepIf = IsCleanupRequested,
507 factory.addStep(ShellCommand(
509 description = "Cleaning work area",
510 command = ["./cleanup.sh", c['buildbotURL'], Interpolate("%(prop:slavename)s"), Interpolate("%(prop:buildername)s"), "single"],
512 haltOnFailure = True,
513 doStepIf = IsCleanupRequested,
516 # user-requested clean targets
517 for tuple in CleanTargetMap:
518 factory.addStep(ShellCommand(
520 description = 'User-requested "make %s"' % tuple[1],
521 command = ["make", tuple[1], "V=s"],
523 doStepIf = IsMakeCleanRequested(tuple[0])
526 # check out the source
528 # if repo doesn't exist: 'git clone repourl'
529 # method 'clean' runs 'git clean -d -f', method fresh runs 'git clean -d -f x'. Only works with mode='full'
530 # 'git fetch -t repourl branch; git reset --hard revision'
531 # Git() parameters can't take a renderer until buildbot 0.8.10, so we have to split the fresh and clean cases
532 # if buildbot is updated, one can use: method = Interpolate('%(prop:do_cleanup:#?|fresh|clean)s')
535 branch = repo_branch,
538 haltOnFailure = True,
539 doStepIf = IsGitCleanRequested,
544 branch = repo_branch,
547 haltOnFailure = True,
548 doStepIf = IsGitFreshRequested,
552 factory.addStep(ShellCommand(
554 description = "Fetching Git remote refs",
555 command = ["git", "fetch", "origin", "+refs/heads/%s:refs/remotes/origin/%s" %(repo_branch, repo_branch)],
560 factory.addStep(ShellCommand(
562 description = "Checking out Git tag",
563 command = ["git", "checkout", Interpolate("tags/v%(prop:tag:-)s")],
564 haltOnFailure = True,
565 doStepIf = IsTaggingRequested
568 factory.addStep(ShellCommand(
570 description = "Remove tmp folder",
571 command=["rm", "-rf", "tmp/"]))
574 # factory.addStep(ShellCommand(
575 # name = "feedsconf",
576 # description = "Copy the feeds.conf",
577 # command='''cp ~/feeds.conf ./feeds.conf''' ))
580 factory.addStep(ShellCommand(
581 name = "rmfeedlinks",
582 description = "Remove feed symlinks",
583 command=["rm", "-rf", "package/feeds/"]))
586 factory.addStep(ShellCommand(
587 name = "updatefeeds",
588 description = "Updating feeds",
589 command=["./scripts/feeds", "update"],
594 factory.addStep(ShellCommand(
595 name = "installfeeds",
596 description = "Installing feeds",
597 command=["./scripts/feeds", "install", "-a"],
601 factory.addStep(FileDownload(
602 mastersrc = "config.seed",
603 slavedest = ".config",
608 factory.addStep(ShellCommand(
610 description = "Seeding .config",
611 command = "printf 'CONFIG_TARGET_%s=y\\nCONFIG_TARGET_%s_%s=y\\n' >> .config" %(ts[0], ts[0], ts[1])
614 factory.addStep(ShellCommand(
616 description = "Removing output directory",
617 command = ["rm", "-rf", "bin/"]
620 factory.addStep(ShellCommand(
622 description = "Populating .config",
623 command = ["make", "defconfig"],
628 factory.addStep(ShellCommand(
630 description = "Checking architecture",
631 command = ["grep", "-sq", "CONFIG_TARGET_%s=y" %(ts[0]), ".config"],
639 factory.addStep(SetPropertyFromCommand(
642 description = "Finding libc suffix",
643 command = ["sed", "-ne", '/^CONFIG_LIBC=/ { s!^CONFIG_LIBC="\\(.*\\)"!\\1!; s!^musl$!!; s!.\\+!-&!p }', ".config"]))
646 factory.addStep(FileDownload(
647 mastersrc = "ccache.sh",
648 slavedest = "../ccache.sh",
653 factory.addStep(ShellCommand(
655 description = "Preparing ccache",
656 command = ["../ccache.sh"]
660 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build', slavedest="key-build", mode=0600))
661 factory.addStep(FileDownload(mastersrc=home_dir+'/key-build.pub', slavedest="key-build.pub", mode=0600))
664 factory.addStep(ShellCommand(
666 description = "Preparing dl/",
667 command = "mkdir -p $HOME/dl && rm -rf ./dl && ln -sf $HOME/dl ./dl",
673 factory.addStep(ShellCommand(
675 description = "Building and installing GNU tar",
676 command = ["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "tools/tar/compile", "V=s"],
677 env = MakeEnv(tryccache=True),
682 factory.addStep(ShellCommand(
684 description = "Populating dl/",
685 command = ["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "download", "V=s"],
688 locks = [dlLock.access('exclusive')],
691 factory.addStep(ShellCommand(
693 description = "Cleaning base-files",
694 command=["make", "package/base-files/clean", "V=s"]
698 factory.addStep(ShellCommand(
700 description = "Building and installing tools",
701 command = ["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "tools/install", "V=s"],
702 env = MakeEnv(tryccache=True),
706 factory.addStep(ShellCommand(
708 description = "Building and installing toolchain",
709 command=["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "toolchain/install", "V=s"],
714 factory.addStep(ShellCommand(
716 description = "Building kmods",
717 command=["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "target/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
719 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
723 # find kernel version
724 factory.addStep(SetPropertyFromCommand(
725 name = "kernelversion",
726 property = "kernelversion",
727 description = "Finding the effective Kernel version",
728 command = "make --no-print-directory -C target/linux/ val.LINUX_VERSION val.LINUX_RELEASE val.LINUX_VERMAGIC | xargs printf '%s-%s-%s\\n'",
729 env = { 'TOPDIR': Interpolate("%(kw:cwd)s/build", cwd=GetCwd) }
732 factory.addStep(ShellCommand(
734 description = "Cleaning up package build",
735 command=["make", "package/cleanup", "V=s"]
738 factory.addStep(ShellCommand(
740 description = "Building packages",
741 command=["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "package/compile", "V=s", "IGNORE_ERRORS=n m", "BUILD_LOG=1"],
743 #env={'BUILD_LOG_DIR': 'bin/%s' %(ts[0])},
747 # factory.addStep(IfBuiltinShellCommand(
748 factory.addStep(ShellCommand(
750 description = "Installing packages",
751 command=["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "package/install", "V=s"],
756 factory.addStep(ShellCommand(
758 description = "Indexing packages",
759 command=["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "package/index", "V=s"],
764 if enable_kmod_archive:
765 factory.addStep(ShellCommand(
767 description = "Creating kmod directory",
768 command=["mkdir", "-p", Interpolate("bin/targets/%(kw:target)s/%(kw:subtarget)s%(prop:libc)s/kmods/%(prop:kernelversion)s", target=ts[0], subtarget=ts[1])],
772 factory.addStep(ShellCommand(
773 name = "kmodprepare",
774 description = "Preparing kmod archive",
775 command=["rsync", "--include=/kmod-*.ipk", "--exclude=*", "-va",
776 Interpolate("bin/targets/%(kw:target)s/%(kw:subtarget)s%(prop:libc)s/packages/", target=ts[0], subtarget=ts[1]),
777 Interpolate("bin/targets/%(kw:target)s/%(kw:subtarget)s%(prop:libc)s/kmods/%(prop:kernelversion)s/", target=ts[0], subtarget=ts[1])],
781 factory.addStep(ShellCommand(
783 description = "Indexing kmod archive",
784 command=["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "package/index", "V=s",
785 Interpolate("PACKAGE_SUBDIRS=bin/targets/%(kw:target)s/%(kw:subtarget)s%(prop:libc)s/kmods/%(prop:kernelversion)s/", target=ts[0], subtarget=ts[1])],
790 # find rootfs staging directory
791 factory.addStep(SetPropertyFromCommand(
793 property = "stageroot",
794 description = "Finding the rootfs staging directory",
795 command=["make", "--no-print-directory", "val.STAGING_DIR_ROOT"],
796 env = { 'TOPDIR': Interpolate("%(kw:cwd)s/build", cwd=GetCwd) }
799 factory.addStep(ShellCommand(
801 description = "Creating file overlay directory",
802 command=["mkdir", "-p", "files/etc/opkg"],
806 factory.addStep(ShellCommand(
808 description = "Embedding kmod repository configuration",
809 command=Interpolate("sed -e 's#^\\(src/gz .*\\)_core \\(.*\\)/packages$#&\\n\\1_kmods \\2/kmods/%(prop:kernelversion)s#' " +
810 "%(prop:stageroot)s/etc/opkg/distfeeds.conf > files/etc/opkg/distfeeds.conf"),
814 #factory.addStep(IfBuiltinShellCommand(
815 factory.addStep(ShellCommand(
817 description = "Building and installing images",
818 command=["make", Interpolate("-j%(kw:jobs)s", jobs=GetNumJobs), "target/install", "V=s"],
823 factory.addStep(ShellCommand(
825 description = "Generating config.seed",
826 command=["make", "-j1", "diffconfig", "V=s"],
831 factory.addStep(ShellCommand(
833 description = "Calculating checksums",
834 command=["make", "-j1", "checksum", "V=s"],
840 if gpg_keyid is not None:
841 factory.addStep(MasterShellCommand(
842 name = "signprepare",
843 description = "Preparing temporary signing directory",
844 command = ["mkdir", "-p", "%s/signing" %(home_dir)],
848 factory.addStep(ShellCommand(
850 description = "Packing files to sign",
851 command = Interpolate("find bin/targets/%(kw:target)s/%(kw:subtarget)s%(prop:libc)s/ bin/targets/%(kw:target)s/%(kw:subtarget)s%(prop:libc)s/kmods/ -mindepth 1 -maxdepth 2 -type f -name sha256sums -print0 -or -name Packages -print0 | xargs -0 tar -czf sign.tar.gz", target=ts[0], subtarget=ts[1]),
855 factory.addStep(FileUpload(
856 slavesrc = "sign.tar.gz",
857 masterdest = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
861 factory.addStep(MasterShellCommand(
863 description = "Signing files",
864 command = ["%s/signall.sh" %(home_dir), "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]), gpg_keyid, gpg_comment],
865 env = {'GNUPGHOME': gpg_home, 'PASSFILE': gpg_passfile},
869 factory.addStep(FileDownload(
870 mastersrc = "%s/signing/%s.%s.tar.gz" %(home_dir, ts[0], ts[1]),
871 slavedest = "sign.tar.gz",
875 factory.addStep(ShellCommand(
877 description = "Unpacking signed files",
878 command = ["tar", "-xzf", "sign.tar.gz"],
883 factory.addStep(ShellCommand(
885 description = "Preparing upload directory structure",
886 command = ["mkdir", "-p", Interpolate("tmp/upload/%(kw:prefix)stargets/%(kw:target)s/%(kw:subtarget)s", target=ts[0], subtarget=ts[1], prefix=GetVersionPrefix)],
890 factory.addStep(ShellCommand(
891 name = "linkprepare",
892 description = "Preparing repository symlink",
893 command = ["ln", "-s", "-f", Interpolate("../packages-%(kw:basever)s", basever=GetBaseVersion()), Interpolate("tmp/upload/%(kw:prefix)spackages", prefix=GetVersionPrefix)],
894 doStepIf = IsNoMasterBuild,
898 if enable_kmod_archive:
899 factory.addStep(ShellCommand(
900 name = "kmoddirprepare",
901 description = "Preparing kmod archive upload directory",
902 command = ["mkdir", "-p", Interpolate("tmp/upload/%(kw:prefix)stargets/%(kw:target)s/%(kw:subtarget)s/kmods/%(prop:kernelversion)s", target=ts[0], subtarget=ts[1], prefix=GetVersionPrefix)],
906 factory.addStep(ShellCommand(
908 description = "Uploading directory structure",
909 command = ["rsync", "-4", "-az", "tmp/upload/", "%s/" %(rsync_bin_url)],
910 env={'RSYNC_PASSWORD': rsync_bin_key},
911 haltOnFailure = True,
915 factory.addStep(FileDownload(
916 mastersrc = "rsync.sh",
917 slavedest = "../rsync.sh",
920 factory.addStep(ShellCommand(
921 name = "targetupload",
922 description = "Uploading target files",
923 command=["../rsync.sh", "-4", "--exclude=/kmods/", "--delete", "--size-only", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]),
924 "-a", Interpolate("bin/targets/%(kw:target)s/%(kw:subtarget)s%(prop:libc)s/", target=ts[0], subtarget=ts[1]),
925 Interpolate("%(kw:rsyncbinurl)s/%(kw:prefix)stargets/%(kw:target)s/%(kw:subtarget)s/", rsyncbinurl=rsync_bin_url, target=ts[0], subtarget=ts[1], prefix=GetVersionPrefix)],
926 env={'RSYNC_PASSWORD': rsync_bin_key},
927 haltOnFailure = True,
931 if enable_kmod_archive:
932 factory.addStep(ShellCommand(
934 description = "Uploading kmod archive",
935 command=["../rsync.sh", "-4", "--delete", "--size-only", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]),
936 "-a", Interpolate("bin/targets/%(kw:target)s/%(kw:subtarget)s%(prop:libc)s/kmods/%(prop:kernelversion)s/", target=ts[0], subtarget=ts[1]),
937 Interpolate("%(kw:rsyncbinurl)s/%(kw:prefix)stargets/%(kw:target)s/%(kw:subtarget)s/kmods/%(prop:kernelversion)s/", rsyncbinurl=rsync_bin_url, target=ts[0], subtarget=ts[1], prefix=GetVersionPrefix)],
938 env={'RSYNC_PASSWORD': rsync_bin_key},
939 haltOnFailure = True,
943 if rsync_src_url is not None:
944 factory.addStep(ShellCommand(
945 name = "sourceupload",
946 description = "Uploading source archives",
947 command=["../rsync.sh", "-4", "--size-only", "--delay-updates",
948 Interpolate("--partial-dir=.~tmp~%(kw:target)s~%(kw:subtarget)s~%(prop:slavename)s", target=ts[0], subtarget=ts[1]), "-a", "dl/", "%s/" %(rsync_src_url)],
949 env={'RSYNC_PASSWORD': rsync_src_key},
950 haltOnFailure = True,
955 factory.addStep(ShellCommand(
956 name = "packageupload",
957 description = "Uploading package files",
958 command=["../rsync.sh", "-4", "--delete", "--delay-updates", "--partial-dir=.~tmp~%s~%s" %(ts[0], ts[1]), "-a", "bin/packages/", "%s/packages/" %(rsync_bin_url)],
959 env={'RSYNC_PASSWORD': rsync_bin_key},
960 haltOnFailure = False,
966 factory.addStep(ShellCommand(
968 description = "Uploading logs",
969 command=["../rsync.sh", "-4", "--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])],
970 env={'RSYNC_PASSWORD': rsync_bin_key},
971 haltOnFailure = False,
976 factory.addStep(ShellCommand(
978 description = "Reporting disk usage",
979 command=["df", "-h", "."],
981 haltOnFailure = False,
985 factory.addStep(ShellCommand(
987 description = "Reporting ccache stats",
988 command=["ccache", "-s"],
989 env = MakeEnv(overrides={ 'PATH': ["./staging_dir/host/bin", "${PATH}"] }),
991 haltOnFailure = False,
992 flunkOnFailure = False,
993 warnOnFailure = False,
997 from buildbot.config import BuilderConfig
999 c['builders'].append(BuilderConfig(name=target, slavenames=slaveNames, factory=factory, nextBuild=GetNextBuild))
1002 ####### STATUS TARGETS
1004 # 'status' is a list of Status Targets. The results of each build will be
1005 # pushed to these targets. buildbot/status/*.py has a variety to choose from,
1006 # including web pages, email senders, and IRC bots.
1010 from buildbot.status import html
1011 from buildbot.status.web import authz, auth
1013 if ini.has_option("status", "bind"):
1014 if ini.has_option("status", "user") and ini.has_option("status", "password"):
1015 authz_cfg=authz.Authz(
1016 # change any of these to True to enable; see the manual for more
1018 auth=auth.BasicAuth([(ini.get("status", "user"), ini.get("status", "password"))]),
1019 gracefulShutdown = 'auth',
1020 forceBuild = 'auth', # use this to test your slave once it is set up
1021 forceAllBuilds = 'auth',
1022 pingBuilder = False,
1024 stopAllBuilds = 'auth',
1025 cancelPendingBuild = 'auth',
1027 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind"), authz=authz_cfg))
1029 c['status'].append(html.WebStatus(http_port=ini.get("status", "bind")))
1032 from buildbot.status import words
1034 if ini.has_option("irc", "host") and ini.has_option("irc", "nickname") and ini.has_option("irc", "channel"):
1035 irc_host = ini.get("irc", "host")
1037 irc_chan = ini.get("irc", "channel")
1038 irc_nick = ini.get("irc", "nickname")
1041 if ini.has_option("irc", "port"):
1042 irc_port = ini.getint("irc", "port")
1044 if ini.has_option("irc", "password"):
1045 irc_pass = ini.get("irc", "password")
1047 irc = words.IRC(irc_host, irc_nick, port = irc_port, password = irc_pass,
1048 channels = [{ "channel": irc_chan }],
1051 'successToFailure': 1,
1052 'failureToSuccess': 1
1056 c['status'].append(irc)
1061 # This specifies what database buildbot uses to store its state. You can leave
1062 # this at its default for all but the largest installations.
1063 'db_url' : "sqlite:///state.sqlite",