Autobuilder patches
PATCH 4/27 PrepPkgIndex.py: ln instead of cp
In reply to Elizabeth FlanaganFrom: Beth Flanagan <[email protected]>
Since pkgindex is no longer using flock() this should be safe now.
--- lib/python2.7/site-packages/autobuilder/buildsteps/PrepPkgIndex.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
lib/python2.7/site-packages/autobuilder/buildsteps/PrepPkgIndex.py +3 -3
@@ -37,9 +37,9 @@ class PrepPkgIndex(ShellCommand): RPM_PUBLISH_DIR = os.environ.get("RPM_PUBLISH_DIR") IPK_PUBLISH_DIR = os.environ.get("IPK_PUBLISH_DIR") # Work around for #4186 - command = "rm -rf ipk; cp -R " + DEST + "/" + IPK_PUBLISH_DIR + " ipk;" -# command = "rm -rf ipk; ln -s " + DEST + "/" + IPK_PUBLISH_DIR + " ipk;" -# command = command + "rm -rf rpm; ln -s " + DEST + "/" + RPM_PUBLISH_DIR + " rpm" + #command = "rm -rf ipk; cp -R " + DEST + "/" + IPK_PUBLISH_DIR + " ipk;" + command = "rm -rf ipk; ln -s " + DEST + "/" + IPK_PUBLISH_DIR + " ipk;" + #command = command + "rm -rf rpm; ln -s " + DEST + "/" + RPM_PUBLISH_DIR + " rpm" self.command = command ShellCommand.start(self)
Signature · 1 line
1.8.1.2
cover Autobuilder patches
This is a fairly large patchset and I'd like at least a second set of eyes on it.
There are a few things this does:
1. Updates the Autobuilder parser.
The autobuilder parser was fairly junky. It didn't dive too far into what it was parsing. This made it so people couldn't do triggers of triggers because the props wouldn't filter all the way up to the master trigger. This should be possible now.
2. Simplify the commit/repo/branch combos/remove mix and match.
A long time ago we needed the ability to mix and match repos/branches when we were building out nightly. This made it so that we could build everything but nightly-foo on master. That use case is no longer really needed.
It was also a major complaint that the UI was complicated. This trims the UI down and makes it much sparser
3. Git fetcher mirror.
The git fetcher with buildbot doesn't do a lot of what we need it to. This set of patches creates a mirror on each slave of the major repos. This allows us to clone from those repos. The git fetcher also has a movecopy method that allows us to instead of clobbering a build dir, move it off to a trash directory. This works well when your trash and slaves are on the same partition but is slowed when you move it across disk.
When the ab starts a service runs in the background that 1. Updates all of the repos every XX minutes 2. takes out the trash every XX minutes.
The following changes since commit ba57054aea5627b557327632ad3d6c2a1faa14f2:
4. Simplifies wait/no_wait triggers.
This needs to be revisited, as I know of a better way to do this now, but this allows us to more optimally utilize the ab resources by triggering all builds, but putting a few second sleep in for the no_wait builds to queue.
Bugs fixed:
https://bugzilla.yoctoproject.org/show_bug.cgi?id=5454
https://bugzilla.yoctoproject.org/show_bug.cgi?id=5433
https://bugzilla.yoctoproject.org/show_bug.cgi?id=5027
PublishLayerTarballs: Don't hang is PUBLISH_BUILDS isn't set (2014-02-18 10:37:36 +0000)
are available in the git repository at:
git://git.yoctoproject.org/yocto-autobuilder eflanagan/yocto-autobuilder-dev-rebase
http://git.yoctoproject.org/cgit.cgi/yocto-autobuilder/log/?h=eflanagan/yocto-autobuilder-dev-rebase
Beth Flanagan (8):
PrepPkgIndex.py: ln instead of cp Autobuilder.py/Buildset.py: More sane parser/UI nightly.conf: Add additional parameters CheckOutLayers.py/ResolveLayerHead.py: support simplified git Autobuilder.py: remove DEBUG code
BuildSet.py: Remove more debug code. yocto-start/stop-autobuilder: start buildslave-janitor forms.html/layout.html: support simplified UI
Elizabeth Flanagan (12):
nightly-world-uclibc: uclibc target SyncPersistDB.py: First run failure correction BuildSet.py: Set workdir based on layer not order BuildSet.py: remove trailing spaces
yoctogit.py: fix callbacks and instance attrs PublishArtifacts.py: Fix poky-tiny publish PublishArtifacts.py: genericx86-64 publish BuildEclipsePlugin.py: Change location of build. PublishArtifacts.py: Change where we find eclipse artifacts
yocto-autobuilder-setup: set the correct bb version fs.py: Bump default timeout
autobuilder: whitespace removal
Richard Purdie (5):
Add mirror functionality to git fetcher trigger.py: Allow wait and nowait triggers
yoctogit: Don't use branch args for referenced clone bin/buildslave-janitor: For fast-git checkouts
yoctogit: Remove use of oe.path.exists()
Stefan Stanacar (2):
buildsets: add a new buildset to run builds on target Add buildstep and buildset for oe-selftest script
bin/buildslave-janitor | 125 ++++++ buildset-config.master/nightly-oe-selftest.conf | 15 + .../nightly-qa-targetbuilds.conf | 26 ++ buildset-config.master/nightly-world-uclibc.conf | 18 + buildset-config.master/nightly.conf | 40 +- config/autobuilder.conf.example | 1 + .../site-packages/autobuilder/Autobuilder.py | 422 ++++++++++----------- .../site-packages/autobuilder/BuildSet.py | 67 ++-- .../autobuilder/buildsteps/BuildEclipsePlugin.py | 8 +- .../autobuilder/buildsteps/BuildToolchainImages.py | 6 +- .../autobuilder/buildsteps/CheckOutLayers.py | 32 +- .../autobuilder/buildsteps/CreateAutoConf.py | 17 +- .../autobuilder/buildsteps/CreateBBLayersConf.py | 10 +- .../autobuilder/buildsteps/CreateCurrentLink.py | 6 +- .../buildsteps/CreateIntelBSPPackage.py | 8 +- .../autobuilder/buildsteps/GetDistroVersion.py | 4 +- .../autobuilder/buildsteps/GetLayerVersion.py | 10 +- .../autobuilder/buildsteps/HelloWorld.py | 6 +- .../autobuilder/buildsteps/MaintainPersistDB.py | 12 +- .../autobuilder/buildsteps/PrepPkgIndex.py | 12 +- .../autobuilder/buildsteps/PublishArtifacts.py | 28 +- .../autobuilder/buildsteps/PublishLayerTarballs.py | 33 +- .../autobuilder/buildsteps/ResolveLayerHead.py | 32 +- .../autobuilder/buildsteps/RunOeSelftest.py | 26 ++ .../autobuilder/buildsteps/RunSanityTests.py | 6 +- .../autobuilder/buildsteps/SetDest.py | 12 +- .../site-packages/autobuilder/buildsteps/Sleep.py | 20 +- .../autobuilder/buildsteps/SyncPersistDB.py | 11 +- .../autobuilder/buildsteps/TestFailStep.py | 4 +- .../autobuilder/buildsteps/YoctoBlocker.py | 2 +- .../buildbot/status/web/templates/forms.html | 1 - .../buildbot/status/web/templates/layout.html | 185 +-------- .../buildbot/steps/source/yoctogit.py | 99 +++-- .../buildbot/steps/trigger.py | 15 +- .../buildslave/commands/fs.py | 4 +- yocto-autobuilder-setup | 4 +- yocto-start-autobuilder | 24 +- yocto-stop-autobuilder | 41 +- 38 files changed, 756 insertions(+), 636 deletions(-) create mode 100755 bin/buildslave-janitor create mode 100644 buildset-config.master/nightly-oe-selftest.conf create mode 100644 buildset-config.master/nightly-qa-targetbuilds.conf create mode 100644 buildset-config.master/nightly-world-uclibc.conf create mode 100644 lib/python2.7/site-packages/autobuilder/buildsteps/RunOeSelftest.py
Signature · 1 line
1.8.1.2
PATCH 8/27 CheckOutLayers.py/ResolveLayerHead.py: support simplified git
From: Beth Flanagan <[email protected]>
As the parser now no longer has complex git information properties this simplifies the code needed to resolve FETCH_HEAD's git hash and checkout layers.
--- .../autobuilder/buildsteps/CheckOutLayers.py | 21 +++++------------ .../autobuilder/buildsteps/ResolveLayerHead.py | 26 +++++----------------- 2 files changed, 11 insertions(+), 36 deletions(-)
lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutLayers.py +6 -15
@@ -58,7 +58,7 @@ class CheckOutLayers(YoctoGit): self.timeout = 100000 self.getDescription = getDescription self.layername = layername - self.name="Git checkout of " + layername + " " + self.repourl + " " + self.workdir + self.name="Git checkout of " + layername kwargs['timeout']=self.timeout for k, v in argdict.iteritems(): setattr(self, k, v)
@@ -69,25 +69,16 @@ class CheckOutLayers(YoctoGit): getDescription=self.getDescription, layername=self.layername, **kwargs) def startVC(self, branch, revision, patch): - if self.getProperty('branch_trigger_'+self.layername+"_"+self.scheduler): - self.branch = self.getProperty('branch_trigger_'+self.layername+"_"+self.scheduler) - elif self.getProperty('branch_triggerer_'+self.layername+"_"+self.scheduler) : - self.branch = self.getProperty('branch_triggerer_'+self.layername+"_"+self.scheduler) - elif self.getProperty('branch_'+self.layername): + if self.getProperty('branch_'+self.layername): self.branch = self.getProperty('branch_'+self.layername) else: self.branch = "master" - if self.getProperty('repo_trigger_'+self.layername+"_"+self.scheduler): - self.repourl = self.getProperty('repo_trigger_'+self.layername+"_"+self.scheduler) - elif self.getProperty('repo_triggerer_'+self.layername+"_"+self.scheduler) : - self.repourl = self.getProperty('repo_triggerer_'+self.layername+"_"+self.scheduler) - elif self.getProperty('repo_'+self.layername): + if self.getProperty('repo_'+self.layername): self.repourl = self.getProperty('repo_'+self.layername) - else:self.repourl = "git://git.yoctoproject.org/poky" + else: + self.repourl = "git://git.yoctoproject.org/poky" - if self.getProperty('commit_trigger_'+self.layername+"_"+self.scheduler) == "HEAD" and \ - self.getProperty('repo_trigger_'+self.layername+"_"+self.scheduler) == self.getProperty('triggers_repo_'+self.layername) and \ - self.getProperty('branch_trigger_'+self.layername+"_"+self.scheduler) == self.getProperty('triggers_branch_'+self.layername) and \ + if self.getProperty('commit_'+self.layername) == "HEAD" and \ self.getProperty('commit_resolvedhead_'+self.layername) is not None: log.msg("Using Resolved HEAD") self.commit = self.getProperty('commit_resolvedhead_'+self.layername)
lib/python2.7/site-packages/autobuilder/buildsteps/ResolveLayerHead.py +5 -21
@@ -31,34 +31,18 @@ class ResolveLayerHead(ShellCommand): ShellCommand.__init__(self, **kwargs) def start(self): - if self.getProperty('branch_trigger_'+self.layername+"_"+self.scheduler): - self.branch = self.getProperty('branch_trigger_'+self.layername+"_"+self.scheduler) - elif self.getProperty('branch_triggerer_'+self.layername+"_"+self.scheduler) : - self.branch = self.getProperty('branch_triggerer_'+self.layername+"_"+self.scheduler) - elif self.getProperty('branch_'+self.layername): + if self.getProperty('branch_'+self.layername): self.branch = self.getProperty('branch_'+self.layername) else: self.branch = "master" - if self.getProperty('repo_trigger_'+self.layername+"_"+self.scheduler): - self.repourl = self.getProperty('repo_trigger_'+self.layername+"_"+self.scheduler) - elif self.getProperty('repo_triggerer_'+self.layername+"_"+self.scheduler) : - self.repourl = self.getProperty('repo_triggerer_'+self.layername+"_"+self.scheduler) - elif self.getProperty('repo_'+self.layername): + if self.getProperty('repo_'+self.layername): self.repourl = self.getProperty('repo_'+self.layername) - else:self.repourl = "git://git.yoctoproject.org/poky" + else: + self.repourl = "git://git.yoctoproject.org/poky" - if self.getProperty('commit_trigger_'+self.layername+"_"+self.scheduler) == "HEAD" and \ - self.getProperty('repo_trigger_'+self.layername+"_"+self.scheduler) == self.getProperty('repo_'+self.layername) and \ - self.getProperty('branch_trigger_'+self.layername+"_"+self.scheduler) == self.getProperty('branch_'+self.layername) and \ - self.getProperty('commit_resolvedhead_'+self.layername) is not None: + if self.getProperty('commit_resolvedhead_'+self.layername) is not None: self.commit = self.getProperty('commit_resolvedhead_'+self.layername) - elif self.getProperty('commit_trigger_'+self.layername+"_"+self.scheduler): - self.commit = self.getProperty('commit_trigger_'+self.layername+"_"+self.scheduler) - elif self.getProperty('commit_triggerer_'+self.layername+"_"+self.scheduler) : - self.commit = self.getProperty('commit_triggerer_'+self.layername+"_"+self.scheduler) - elif self.getProperty('commit_'+self.layername): - self.commit = self.getProperty('commit_'+self.layername) else: self.commit = "HEAD" if self.commit == "HEAD":
Signature · 1 line
1.8.1.2
PATCH 10/27 BuildSet.py: Remove more debug code.
In reply to Elizabeth FlanaganFrom: Beth Flanagan <[email protected]>
Removed some log.msg code.
--- lib/python2.7/site-packages/autobuilder/BuildSet.py | 2 -- 1 file changed, 2 deletions(-)
lib/python2.7/site-packages/autobuilder/BuildSet.py +0 -2
@@ -59,11 +59,9 @@ class BuildSet(): for layer in layers: kwargs=stepOrder[step] layername=layer.iterkeys().next() - log.msg(type(Property('commit_resolvedhead_'+layername))) if os.environ.get("RESOLVE_TRIGGERED_HEAD") == "True": m = __import__ ("ResolveLayerHead") func = getattr(m, "ResolveLayerHead") - log.msg(layer[layer.iterkeys().next()]) factoryFN(func(locals()['f'+name], layername=layername, scheduler=name,
Signature · 1 line
1.8.1.2
PATCH 12/27 yoctogit: Don't use branch args for referenced clone
In reply to Elizabeth FlanaganFrom: Richard Purdie <[email protected]>
--- .../buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py +2 -2
@@ -470,8 +470,8 @@ class YoctoGit(Source): mirror = None if self.mirrordir: mirror = self.mirrordir + "/" + self.repourl.replace("git://", "") + "/" - if os.path.exists(mirror): - command = ['clone'] + args + ["-s", "-n"] + [mirror, '.'] + if self.pathExists(mirror): + command = ['clone'] + ["-s", "-n"] + [mirror, '.'] #Fix references if self.prog:
Signature · 1 line
1.8.1.2
PATCH 20/27 yoctogit.py: fix callbacks and instance attrs
In reply to Elizabeth FlanaganThe callbacks in barecopy and movecopy were wrong. The big issue this fixes is adding a correct resetWorkdir to each of these methods.
This ensures we are in the right place, doing the right things depending on the name of the layer. For example, we need to be in build for poky, but build/meta-qt3 for meta-qt3.
Also, this stops us from changing instance attrs.
Setting instance attributes (like self.todir self.workdir) when you have a bunch of callbacks creates uglyness beyond belief.
Don't use them. Use local vars.
--- .../buildbot/steps/source/yoctogit.py | 80 +++++++++++++++------- 1 file changed, 55 insertions(+), 25 deletions(-)
lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py +55 -25
@@ -177,7 +177,7 @@ class YoctoGit(Source): @defer.inlineCallbacks def full(self): updatable = yield self._sourcedirIsUpdatable() - + if self.method == 'clobber': yield self.clobber() return
@@ -201,7 +201,7 @@ class YoctoGit(Source): @defer.inlineCallbacks def incremental(self): updatable = yield self._sourcedirIsUpdatable() - + # if not updateable, do a full checkout if not updatable: yield self._fullCloneOrFallback()
@@ -249,19 +249,24 @@ class YoctoGit(Source): if self.mirrordir: mirror = self.mirrordir + "/" + self.repourl.replace("git://", "") + "/" if self.pathExists(mirror): - self.srcdir=mirror + srcdir=mirror else: - self.srcdir='source/'+self.repourl - if self.layername == "poky" or self.layername == "oecore" or "eclipse" in self.layername: - self.todir = "build/" + srcdir='source/'+self.repourl + if "poky" in self.layername or \ + "oecore" in self.layername or \ + "eclipse" in self.layername: + todir = "." + self.workdir = "build" else: - self.todir = "build/" + self.layername + todir = "./" + self.layername + self.workdir = "build/" + self.layername + d.addCallback(lambda _: self.incremental()) def copy(_): cmd = buildstep.RemoteCommand('cpdir', - {'fromdir': self.srcdir, - 'todir':self.todir, + {'fromdir': srcdir, + 'todir': todir, 'logEnviron': self.logEnviron, 'timeout': self.timeout,}) cmd.useLog(self.stdio_log, False)
@@ -273,8 +278,14 @@ class YoctoGit(Source): d.addCallback(lambda _: evaluateCommand(cmd)) return d d.addCallback(copy) + def resetWorkdir(_): - self.workdir = 'build' + if "poky" in self.layername or \ + "oecore" in self.layername or \ + "eclipse" in self.layername: + self.workdir = 'build' + else: + self.workdir = "build/" + self.layername return 0 d.addCallback(resetWorkdir)
@@ -289,13 +300,15 @@ class YoctoGit(Source): # Let's make the todir difficult to have duplicate dir names. This # method probably won't work correctly crossing filesystems, so utilize # movecopy with caution. - + + srcdir='source/'+self.repourl + cmd = buildstep.RemoteCommand('mv', {'fromdir': self.workdir, - 'todir': self.storedir + '/' + self.getProperty("DEST") + '/' + - str(int(time.time())) + '-' + - str(random.randrange(100, 100000, 2)) + - self.layername, - 'logEnviron':self.logEnviron,}) + 'todir': self.storedir + '/' + self.getProperty("DEST") + '/' + + str(int(time.time())) + '-' + + str(random.randrange(100, 100000, 2)) + + self.layername, + 'logEnviron':self.logEnviron,}) cmd.useLog(self.stdio_log, False) d = self.runCommand(cmd) def evaluateCommand(cmd):
@@ -304,18 +317,29 @@ class YoctoGit(Source): raise buildstep.BuildStepFailed() d.addCallback(lambda _: evaluateCommand(cmd)) - todir = None - self.workdir = 'source/'+self.repourl - self.srcdir='source/'+self.repourl - d.addCallback(lambda _: self.incremental()) if self.layername == "poky" or self.layername == "oecore": - self.todir = "build" + todir = "build" else: - self.todir = "build/" + self.layername + todir = "build/" + self.layername + + def mkdir(_): + cmd = buildstep.RemoteCommand('mkdir', {'dir': 'build', + 'logEnviron': self.logEnviron, + 'timeout': self.timeout,}) + cmd.useLog(self.stdio_log, False) + d = self.runCommand(cmd) + def evaluateCommand(cmd): + if cmd.didFail(): + log.msg("Source step failed while running command %s" % cmd) + raise buildstep.BuildStepFailed() + d.addCallback(lambda _: evaluateCommand(cmd)) + return d + d.addCallback(mkdir) + d.addCallback(lambda _: self.incremental()) def copy(_): cmd = buildstep.RemoteCommand('cpdir', - {'fromdir': self.srcdir, - 'todir':self.todir, + {'fromdir': srcdir, + 'todir': todir, 'logEnviron': self.logEnviron, 'timeout': self.timeout,}) cmd.useLog(self.stdio_log, False)
@@ -327,8 +351,14 @@ class YoctoGit(Source): d.addCallback(lambda _: evaluateCommand(cmd)) return d d.addCallback(copy) + def resetWorkdir(_): - self.workdir = 'build' + if "poky" in self.layername or \ + "oecore" in self.layername or \ + "eclipse" in self.layername: + self.workdir = 'build.' + else: + self.workdir = "build/" + self.layername return 0 d.addCallback(resetWorkdir) return d
Signature · 1 line
1.8.1.2
PATCH 21/27 PublishArtifacts.py: Fix poky-tiny publish
In reply to Elizabeth FlanaganThere is a missing space between origin and dest for the cp.
--- lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py +1 -1
@@ -152,7 +152,7 @@ class PublishArtifacts(ShellCommand): command=command+"mkdir -p " + DEST + "/" + QEMU_PUBLISH_DIR + "/qemu-tiny;" if self.layerversion_core is not None and int(self.layerversion_core) > 2: command=command+"cp -R --no-dereference --preserve=links " + \ - os.path.join(self.basedir, "tmp/deploy/images/qemux86/*") + \ + os.path.join(self.basedir, "tmp/deploy/images/qemux86/* ") + \ " " + DEST + "/" + QEMU_PUBLISH_DIR + "/qemu-tiny;" else: command=command+"cp -R --no-dereference --preserve=links " + \
Signature · 1 line
1.8.1.2
PATCH 22/27 PublishArtifacts.py: genericx86-64 publish
In reply to Elizabeth Flanagangenericx86_64 is not the artifact name.
--- lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py +1 -1
@@ -54,7 +54,7 @@ class PublishArtifacts(ShellCommand): artifact = "genericx86" elif self.layerversion_yoctobsp is not None and int(self.layerversion_yoctobsp) < 2 and artifact == "genericx86": artifact = "atom-pc" - elif self.layerversion_yoctobsp is not None and int(self.layerversion_yoctobsp) < 2 and artifact == "genericx86_64": + elif self.layerversion_yoctobsp is not None and int(self.layerversion_yoctobsp) < 2 and artifact == "genericx86-64": artifact = "None" if artifact == "adt-installer": command=command+"mkdir -p " + os.path.join(DEST, ADT_INST_PUBLISH_DIR) + ";"
Signature · 1 line
1.8.1.2
PATCH 5/27 Add mirror functionality to git fetcher
In reply to Elizabeth FlanaganFrom: Richard Purdie <[email protected]>
--- config/autobuilder.conf.example | 1 + lib/python2.7/site-packages/autobuilder/BuildSet.py | 4 ++++ .../autobuilder/buildsteps/CheckOutLayers.py | 5 +++-- .../buildbot/steps/source/yoctogit.py | 20 +++++++++++++++++--- 4 files changed, 25 insertions(+), 5 deletions(-)
config/autobuilder.conf.example +1 -0
@@ -1,6 +1,7 @@ [GitSettings] OPTIMIZED_GIT_CLONE = True OGIT_TRASH_DIR = /tmp/yocto-autobuilder/git/trash +OGIT_MIRROR_DIR = /tmp/yocto-autobuilder/git/mirror OGIT_TRASH_CRON_TIME = "0 0 * * *" OGIT_TRASH_NICE_LEVEL = "19"
lib/python2.7/site-packages/autobuilder/BuildSet.py +4 -0
@@ -72,6 +72,7 @@ class BuildSet(): pass else: storedir=None + mirrordir=None method = 'clobber' mode='full' srcdir = 'source'
@@ -79,10 +80,12 @@ class BuildSet(): if passed==0: method='movecopy' storedir=os.environ.get('OGIT_TRASH_DIR') + mirrordir=os.environ.get('OGIT_MIRROR_DIR') passed=1 else: method='barecopy' storedir=os.environ.get('OGIT_TRASH_DIR') + mirrordir=os.environ.get('OGIT_MIRROR_DIR') passed=1 if layername == "poky" or layername == 'oecore': workdir = 'build'
@@ -99,6 +102,7 @@ class BuildSet(): scheduler=name, method=method, storedir=storedir, + mirrordir=mirrordir, workdir=workdir, argdict=layer[layer.iterkeys().next()])) if 'layerversion' in layer[layer.iterkeys().next()]:
lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutLayers.py +3 -2
@@ -34,7 +34,7 @@ from buildbot.status import build from buildbot.process import buildstep class CheckOutLayers(YoctoGit): - def __init__(self, factory, scheduler=None, layername=None, mode='full', storedir=None, + def __init__(self, factory, scheduler=None, layername=None, mode='full', storedir=None, mirrordir=None, method='clobber', submodules=False, shallow=False, srcdir='source', workdir='build', timeout=100000, progress=True, retryFetch=True, clobberOnFailure=False, getDescription=True, argdict=None,
@@ -51,6 +51,7 @@ class CheckOutLayers(YoctoGit): self.submodules = submodules self.shallow = shallow self.storedir=storedir + self.mirrordir=mirrordir self.fetchcount = 0 self.clobberOnFailure = clobberOnFailure self.mode = mode
@@ -62,7 +63,7 @@ class CheckOutLayers(YoctoGit): for k, v in argdict.iteritems(): setattr(self, k, v) YoctoGit.__init__(self, repourl=self.repourl, branch=self.branch, mode=self.mode, - method=self.method, storedir=self.storedir, submodules=self.submodules, srcdir=self.srcdir+"/"+self.repourl, + method=self.method, storedir=self.storedir, mirrordir=mirrordir, submodules=self.submodules, srcdir=self.srcdir+"/"+self.repourl, workdir=self.workdir, shallow=self.shallow, progress=self.progress, retryFetch=self.retryFetch, clobberOnFailure=self.clobberOnFailure, getDescription=self.getDescription, layername=self.layername, **kwargs)
lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py +17 -3
@@ -63,7 +63,7 @@ class YoctoGit(Source): def __init__(self, repourl=None, branch='HEAD', mode='incremental', method=None, submodules=False, shallow=False, progress=False, retryFetch=False, clobberOnFailure=False, getDescription=False, - workdir='build', layername=None, srcdir='sources', storedir="/tmp/junk", + workdir='build', layername=None, srcdir='sources', storedir="/tmp/junk", mirrordir=None, config=None, **kwargs): """ @type repourl: string
@@ -128,6 +128,7 @@ class YoctoGit(Source): self.srcdir = srcdir self.workdir = workdir self.storedir = storedir + self.mirrordir = mirrordir self.layername = layername self.fetchcount = 0 self.clobberOnFailure = clobberOnFailure
@@ -175,17 +176,18 @@ class YoctoGit(Source): @defer.inlineCallbacks def full(self): + updatable = yield self._sourcedirIsUpdatable() + if self.method == 'clobber': yield self.clobber() return elif self.method == 'barecopy': yield self.barecopy() return - elif self.method == 'movecopy': + elif updatable and self.method == 'movecopy': yield self.movecopy() return - updatable = yield self._sourcedirIsUpdatable() if not updatable: log.msg("No git repo present, making full clone") yield self._fullCloneOrFallback()
@@ -463,12 +465,24 @@ class YoctoGit(Source): args += ['--depth', '1'] command = ['clone'] + args + [self.repourl, '.'] + import os + + mirror = None + if self.mirrordir: + mirror = self.mirrordir + "/" + self.repourl.replace("git://", "") + "/" + if os.path.exists(mirror): + command = ['clone'] + args + ["-s", "-n"] + [mirror, '.'] + #Fix references if self.prog: command.append('--progress') # If it's a shallow clone abort build step d = self._dovccmd(command, shallowClone) + + if mirror: + d.addCallback(lambda _: self._fetch(None)) + # If revision specified checkout that revision if self.revision: d.addCallback(lambda _: self._dovccmd(['reset', '--hard',
Signature · 1 line
1.8.1.2
PATCH 6/27 Autobuilder.py/Buildset.py: More sane parser/UI
In reply to Elizabeth FlanaganFrom: Beth Flanagan <[email protected]>
The parser for Autobuilder.py didn't dive very deep on triggered builds. If it found one, it just grabbed it's properties and then displayed them on the UI. This allowed us to mix and match repos/branches/commits.
The utility of mix and match was needed, but at this point, we don't really need it. So, this commit removes mix and match, makes Autobuilder's parser recursive, simplifies commit data and makes it so we can have trigger of triggers and that the properties are inherited all the way to the top.
--- .../site-packages/autobuilder/Autobuilder.py | 414 ++++++++++----------- .../site-packages/autobuilder/BuildSet.py | 46 ++- 2 files changed, 232 insertions(+), 228 deletions(-)
lib/python2.7/site-packages/autobuilder/Autobuilder.py +203 -211
@@ -19,6 +19,8 @@ from buildbot.schedulers.basic import SingleBranchScheduler from buildbot.changes import filter from buildbot.changes.pb import PBChangeSource from lib.ABTools import capitalize +import ast +import BuildSet class Autobuilder: def __init__(self, cfile=None):
@@ -35,6 +37,154 @@ class Autobuilder: except: self.cfile = "./buildset-config/yoctoAB.conf" + def createBuildsets(self): + beenHere=[] + sort = True + if self.config.has_option('BuildSets', 'order'): + sort = False + for set in ast.literal_eval(self.config.get('BuildSets', 'order')): + beenHere.append(set) + for key in self.configdict: + if key not in beenHere and key != "BuildSets": + beenHere.append(key) + if sort: + beenHere.sort() + # REALLY crappy way to do this, but better than setting globals. + os.environ["YOCTO_SORTED_BUILDERS"]= str(beenHere) + for buildset in beenHere: + self.schedprops = [] + self.checkoutprops={} + self.set_props = {} + self.repos = [] + self.properties = [] + self.builders = None + self.schedprops.append(NestedParameter(name='ss_' + buildset, label="<h3><div class='trigger_heading' id='"+buildset+"'>" + buildset + " defaults:</div></h3>", fields=[FixedParameter(name="dummy", default="dummy")])) + self.parseBuildSet(buildset) + locals()['buildset_%s' % buildset]=BuildSet.BuildSet(name=buildset, + steps=ast.literal_eval(self.configdict[buildset]['steps']), + builders=self.builders, + layers=ast.literal_eval(self.configdict[buildset]['repos']), + set_props=self.set_props) + self.yocto_sched.append(ForceScheduler( + name=str(buildset), + branch=FixedParameter(name="branch", + default=""), + reason=StringParameter(name="reason", + label="Reason:<br>", + required=False, + size=120), + revision=FixedParameter(name="revision", + default=""), + repository=FixedParameter(name="repository", + default=""), + project=FixedParameter(name="repository", + default=""), + builderNames=['%s' % buildset], + properties=self.schedprops)) + self.createExtraSchedulers(key=buildset, checkoutprops=self.checkoutprops) + + def parseBuildSet(self, buildset): + if buildset is not "BuildSets": + self.builders=self.parseBuilders(buildset) + self.parseProps(buildset) + self.parseRepos(buildset) + self.parseSteps(buildset) + self.set_props.update(self.checkoutprops) + + def parseSteps(self, buildset): + buildset=buildset + for step in ast.literal_eval(self.configdict[buildset]['steps']): + if step.has_key('TriggerBuilds'): + master_trigger_name = step['TriggerBuilds']['schedulerName'] + for b in ["", "_nowait"]: + buildername=[] + if 'schedulerNames' + b in step['TriggerBuilds' ]: + for scheduler in step['TriggerBuilds']['schedulerNames' + b].iterkeys(): + if scheduler not in buildername: + self.parseBuildSet(scheduler) + buildername.append(scheduler) + self.yocto_sched.append(Triggerable(name="trigger_" + master_trigger_name + b, builderNames=buildername)) + + def parseRepos(self, buildset=None): + buildset=buildset + if DEBUG is True: + log.msg(buildset + " uses these repos:") + for layer in ast.literal_eval(self.configdict[buildset]['repos']): + if layer.iterkeys().next() not in self.repos: + schedpropstoextend, newcheckoutprops = self.CreateLayerSchedulerParams(layer=layer, trigger=buildset, triggerer=True) + self.schedprops.extend(schedpropstoextend) + self.checkoutprops.update(newcheckoutprops) + self.repos.append(layer.iterkeys().next()) + return + + def parseProps(self, buildset): + buildset=buildset + if self.configdict[buildset].has_key('props'): + for props in ast.literal_eval(self.configdict[buildset]['props']): + for prop in dict(props): + self.prop_name="" + self.prop_prop_type="" + self.prop_default="" + self.prop_choices="" + self.prop_label="" + self.prop_required="" + self.prop_size="" + setattr(self, "prop_name", prop) + for k, v in props[prop].iteritems(): + setattr(self, "prop_"+str(k), v) + if self.prop_name not in self.properties: + schedpropstoextend = self.CreateExtraSchedulerParams(name=self.prop_name, + prop_type=self.prop_prop_type, + default=self.prop_default, + choices=self.prop_choices, + label=self.prop_label, + required=self.prop_required, + scheduler=buildset, + size=self.prop_size) + self.schedprops.extend(schedpropstoextend) + self.properties.append(self.prop_name) + + def parseBuilders(self, buildset): + buildset=buildset + builders=ast.literal_eval(self.configdict[buildset]['builders']) + if DEBUG is True: + log.msg(buildset + " is built on " + str(builders)) + return builders + + def parseConfig(self): + import ConfigParser + from os import listdir + from os.path import dirname, isfile, join + print "LOADING CONFIG FILE" + self.config = ConfigParser.ConfigParser() + self.configdir=os.path.dirname(self.cfile) + self.configfiles = [ join(self.configdir,f) for f in listdir(self.configdir) if isfile(join(self.configdir,f)) and (f != 'autobuilder.conf') ] + try: + self.config.read(self.configfiles) + except: + print "Can't seem to find the Config file. Is YOCTO_AB_CONFIG set?" + self.buildsets=self.config.sections() + self.configdict = {} + for section in self.buildsets: + self.configdict[section]= dict(self.config.items(section)) + return self.configdict + + def GetLayerCommitId(self, layer): + if 'hash' in layer[layer.iterkeys().next()] : + layercommitid=layer[layer.iterkeys().next()]['hash'] + elif 'tag' in layer[layer.iterkeys().next()]: + layercommitid=layer[layer.iterkeys().next()]['tag'] + else: + layercommitid="HEAD" + return layercommitid + + def GetLayerBranch(self, layer): + if 'branch' in layer[layer.iterkeys().next()]: + layerbranch=layer[layer.iterkeys().next()]['branch'] + else: + layerbranch="master" + return layerbranch + # Create extra schedulers requested for the given buildset using 'scheduler:' def createExtraSchedulers(self, key, checkoutprops): import ast
@@ -109,156 +259,6 @@ class Autobuilder: dayOfWeek=builddayOfWeek)) - def createBuildsets(self): - import BuildSet - import ast - beenHere=[] - sort = True - if self.config.has_option('BuildSets', 'order'): - sort = False - for set in ast.literal_eval(self.config.get('BuildSets', 'order')): - beenHere.append(set) - for key in self.configdict: - if key not in beenHere and key != "BuildSets": - beenHere.append(key) - if sort: - beenHere.sort() - # REALLY crappy way to do this, but better than setting globals. - os.environ["YOCTO_SORTED_BUILDERS"]= str(beenHere) - for key in beenHere: - log.msg(key) - builders=ast.literal_eval(self.configdict[key]['builders']), - if key is not "BuildSets": - schedprops = [] - checkoutprops={} - set_props = {} - schedprops.append(NestedParameter(name='ss_' + key, label="<h3><div class='trigger_heading' id='"+key+"'>" + key + " defaults:</div></h3>", fields=[FixedParameter(name="dummy", default="dummy")])) - if self.configdict[key].has_key('props'): - for props in ast.literal_eval(self.configdict[key]['props']): - for prop in dict(props): - self.prop_name="" - self.prop_prop_type="" - self.prop_default="" - self.prop_choices="" - self.prop_label="" - self.prop_required="" - self.prop_size="" - setattr(self, "prop_name", prop) - for k, v in props[prop].iteritems(): - setattr(self, "prop_"+str(k), v) - schedpropstoextend = self.CreateExtraSchedulerParams(name=self.prop_name, - prop_type=self.prop_prop_type, - default=self.prop_default, - choices=self.prop_choices, - label=self.prop_label, - required=self.prop_required, - scheduler=key, - size=self.prop_size) - schedprops.extend(schedpropstoextend) - for layer in ast.literal_eval(self.configdict[key]['repos']): - schedpropstoextend, newcheckoutprops = self.CreateLayerSchedulerParams(layer=layer, trigger=key, triggerer=True) - schedprops.extend(schedpropstoextend) - checkoutprops.update(newcheckoutprops) - - for step in ast.literal_eval(self.configdict[key]['steps']): - if step.has_key('TriggerBuilds'): - layername=layer.iterkeys().next() - master_trigger_name = step['TriggerBuilds']['schedulerName'] - schedprops.append(NestedParameter(name='blank_triggered_builds', - label="<h3> Layers within triggered builds. These will not inherit the main repo/branch.<hr></h3>", - fields=[FixedParameter(name="dummy", default="dummy")])) - buildername=[] - for scheduler in step['TriggerBuilds']['schedulerNames'].iterkeys(): - schedprops.append(NestedParameter(name='ss_' + scheduler, label="<h3><div class='trigger_heading' id='"+scheduler+"'>" + key + " " + scheduler + " defaults:</div></h3>", fields=[FixedParameter(name="dummy", default="dummy")])) - - for triggered_layer in ast.literal_eval(self.configdict[scheduler]['repos']): - schedpropstoextend, newcheckoutprops = self.CreateLayerSchedulerParams(layer=triggered_layer, trigger=scheduler, triggerer=False) - schedprops.extend(schedpropstoextend) - checkoutprops.update(newcheckoutprops) - if self.configdict[scheduler].has_key('props'): - for sched_props in ast.literal_eval(self.configdict[scheduler]['props']): - for prop in dict(sched_props): - self.prop_name="" - self.prop_prop_type="" - self.prop_default="" - self.prop_choices="" - self.prop_label="" - self.prop_required="" - self.prop_size="" - setattr(self, "prop_name", prop) - for k, v in sched_props[prop].iteritems(): - setattr(self, "prop_"+str(k), v) - schedpropstoextend = self.CreateExtraSchedulerParams(name=self.prop_name, - prop_type=self.prop_prop_type, - default=self.prop_default, - choices=self.prop_choices, - label=self.prop_label, - required=self.prop_required, - size=self.prop_size, - scheduler=scheduler) - schedprops.extend(schedpropstoextend) - buildername.append(scheduler) - self.yocto_sched.append(Triggerable(name="trigger_" + master_trigger_name, builderNames=buildername)) - set_props.update(checkoutprops) - - locals()['buildset_%s' % key]=BuildSet.BuildSet(name=key, - steps=ast.literal_eval(self.configdict[key]['steps']), - builders=ast.literal_eval(self.configdict[key]['builders']), - layers=ast.literal_eval(self.configdict[key]['repos']), - set_props=set_props) - - self.yocto_sched.append(ForceScheduler( - name=str(key), - branch=FixedParameter(name="branch", - default=""), - reason=StringParameter(name="reason", - label="Reason:<br>", - required=False, - size=120), - revision=FixedParameter(name="revision", - default=""), - repository=FixedParameter(name="repository", - default=""), - project=FixedParameter(name="repository", - default=""), - builderNames=['%s' % key], - properties=schedprops)) - self.createExtraSchedulers(key=key, checkoutprops=checkoutprops) - - def parseConfig(self): - import ConfigParser - from os import listdir - from os.path import dirname, isfile, join - print "LOADING CONFIG FILE" - self.config = ConfigParser.ConfigParser() - self.configdir=os.path.dirname(self.cfile) - self.configfiles = [ join(self.configdir,f) for f in listdir(self.configdir) if isfile(join(self.configdir,f)) and (f != 'autobuilder.conf') ] - try: - self.config.read(self.configfiles) - except: - print "Can't seem to find the Config file. Is YOCTO_AB_CONFIG set?" - self.buildsets=self.config.sections() - self.configdict = {} - for section in self.buildsets: - self.configdict[section]= dict(self.config.items(section)) - return self.configdict - - def GetLayerCommitId(self, layer): - if 'hash' in layer[layer.iterkeys().next()] : - layercommitid=layer[layer.iterkeys().next()]['hash'] - elif 'tag' in layer[layer.iterkeys().next()]: - layercommitid=layer[layer.iterkeys().next()]['tag'] - else: - layercommitid="HEAD" - return layercommitid - - def GetLayerBranch(self, layer): - if 'branch' in layer[layer.iterkeys().next()]: - layerbranch=layer[layer.iterkeys().next()]['branch'] - else: - layerbranch="master" - return layerbranch - def CreateExtraSchedulerParams(self, name=None, prop_type=None, default=None,
@@ -267,98 +267,90 @@ class Autobuilder: required=None, size=None, scheduler=""): - self.supported_prop_types = ["ChoiceStringParameter", + supported_prop_types = ["ChoiceStringParameter", "StringParameter", "FixedParameter", "BooleanParameter"] - self.schedprops = [] - self.prop_type=prop_type - self.name=name - self.choices=choices - self.prop_type=prop_type - self.label=label - self.required=required - self.size=size - self.default=default - self.scheduler=scheduler - self.id="custom_"+self.name+"_"+self.scheduler - if self.label is None: - self.label=self.name + schedprops = [] + prop_type=prop_type + name=name + choices=choices + prop_type=prop_type + label=label + required=required + size=size + default=default + scheduler=scheduler + propid="custom_"+name + if label is None: + label=self.name - if self.default is None: + if default is None: if prop_type == "FixedParameter": try: raise ABConfigError("your config file has a fixed type property declaration that has no default") except ABConfigError, (instance): log.msg("Caught: " + instance.parameter) else: - self.default = "" + default = "" - if self.prop_type == "ChoiceStringParameter": - if self.choices is None: + if prop_type == "ChoiceStringParameter": + if choices is None: try: raise ABConfigError("your config file has a ChoiceStringParameter declaration that has no choices") except ABConfigError, (instance): log.msg("Caught: " + instance.parameter) - if self.required is None: - self.required=True + if required is None: + required=True - if self.size is None: - self.size=80 + if size is None: + size=80 - if self.prop_type is None: - self.prop_type = "StringParameter" + if prop_type is None: + prop_type = "StringParameter" - if self.prop_type=="ChoiceStringParameter": - self.schedprops.append(ChoiceStringParameter(name=self.id, - label=self.label, - required=self.required, - choices=self.choices)) - elif self.prop_type=="StringParameter": - self.schedprops.append(StringParameter(name=self.id, - label=self.label, - required=self.required, - default=self.default, - size=self.size)) - elif self.prop_type=="FixedParameter": - self.schedprops.append(FixedParameter(name=self.id, - label=self.label, - required=self.required, - default=self.default)) - elif self.prop_type=="BooleanParameter": - self.schedprops.append(BooleanParameter(name=self.id, - label=self.label, - required=self.required, - default=self.default)) + if prop_type=="ChoiceStringParameter": + schedprops.append(ChoiceStringParameter(name=propid, + label=label, + required=required, + choices=choices)) + elif prop_type=="StringParameter": + schedprops.append(StringParameter(name=propid, + label=label, + required=required, + default=default, + size=size)) + elif prop_type=="FixedParameter": + schedprops.append(FixedParameter(name=propid, + label=label, + required=required, + default=default)) + elif prop_type=="BooleanParameter": + schedprops.append(BooleanParameter(name=propid, + label=label, + required=required, + default=default)) else: try: raise ABConfigError("your config file has a prop declaration that is not valid") except ABConfigError, (instance): log.msg("Caught: " + instance.parameter) - return self.schedprops + return schedprops def CreateLayerSchedulerParams(self, layer=None, trigger=None, triggerer=None): schedprops = [] set_checkoutprops = {} layerrepo=layer[layer.iterkeys().next()]['repourl'] - log.msg(layerrepo) layerbranch=self.GetLayerBranch(layer) layercommitid=self.GetLayerCommitId(layer) - if triggerer is True: - layername="triggerer_" + layer.iterkeys().next() + "_" + trigger - layerlabel=capitalize(trigger) + " " + capitalize(layer.iterkeys().next()) - - set_checkoutprops['repo_' + layername] = layerrepo - set_checkoutprops['branch_' + layername] = layerbranch - else: - layername="trigger_" + layer.iterkeys().next() + "_" + trigger - layerlabel=capitalize(trigger) + " " + capitalize(layer.iterkeys().next()) - set_checkoutprops['repo_' + layername] = layerrepo - set_checkoutprops['branch_' + layername] = layerbranch - schedprops.append(StringParameter(name="repo_"+ layername, label="Repository:<br>", required=True, default=layerrepo, size=80)) - schedprops.append(StringParameter(name="branch_" + layername, label="Branch:<br>", required=True, default=layerbranch, size=80)) - schedprops.append(StringParameter(name="commit_" + layername, label="Tag/Commit Hash:<br>", required=True, default=layercommitid, size=80)) + layername=layer.iterkeys().next() + set_checkoutprops['repo_' + layername] = layerrepo + set_checkoutprops['branch_' + layername] = layerbranch + set_checkoutprops['commit_' + layername] = layercommitid + schedprops.append(StringParameter(name="repo_"+ layername, label="<hr><b>" + layername + "</b> Repository:<br>", required=True, default=layerrepo, size=50)) + schedprops.append(StringParameter(name="branch_" + layername, label="Branch:<br>", required=True, default=layerbranch, size=18)) + schedprops.append(StringParameter(name="commit_" + layername, label="Tag/Commit Hash:<br>", required=True, default=layercommitid, size=20)) return schedprops, set_checkoutprops class ABConfigError(Exception):
lib/python2.7/site-packages/autobuilder/BuildSet.py +29 -17
68 lines not on this page · raw message
Signature · 1 line
1.8.1.2
PATCH 9/27 Autobuilder.py: remove DEBUG code
In reply to Elizabeth FlanaganFrom: Beth Flanagan <[email protected]>
No need for a global DEBUG hanging about.
--- lib/python2.7/site-packages/autobuilder/Autobuilder.py | 4 ---- 1 file changed, 4 deletions(-)
lib/python2.7/site-packages/autobuilder/Autobuilder.py +0 -4
@@ -107,8 +107,6 @@ class Autobuilder: def parseRepos(self, buildset=None): buildset=buildset - if DEBUG is True: - log.msg(buildset + " uses these repos:") for layer in ast.literal_eval(self.configdict[buildset]['repos']): if layer.iterkeys().next() not in self.repos: schedpropstoextend, newcheckoutprops = self.CreateLayerSchedulerParams(layer=layer, trigger=buildset, triggerer=True)
@@ -147,8 +145,6 @@ class Autobuilder: def parseBuilders(self, buildset): buildset=buildset builders=ast.literal_eval(self.configdict[buildset]['builders']) - if DEBUG is True: - log.msg(buildset + " is built on " + str(builders)) return builders def parseConfig(self):
Signature · 1 line
1.8.1.2
PATCH 15/27 forms.html/layout.html: support simplified UI
In reply to Elizabeth FlanaganFrom: Beth Flanagan <[email protected]>
With the parser changes that simplify the UI we also need to change forms.html and layout.html to remove old code.
--- .../buildbot/status/web/templates/forms.html | 1 - .../buildbot/status/web/templates/layout.html | 185 +-------------------- 2 files changed, 8 insertions(+), 178 deletions(-)
lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/forms.html +0 -1
@@ -173,7 +173,6 @@ push the 'Force Build' button</p> {% endif %} <input type='hidden' name='forcescheduler' value='{{sch.name}}' /> - <input type="button" value="Set all triggered builders to same repo/branch combo" onClick="setRepoBranch('{{sch.name}}');"> <p> <hr /> {% for f in sch.all_fields %}
lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/layout.html +1 -14
@@ -1,6 +1,6 @@ {%- block doctype -%} <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> {% endblock %} <html xmlns="http://www.w3.org/1999/xhtml"> <head>
@@ -17,182 +17,12 @@ <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ path_to_root }}rss"> <link rel="shortcut icon" href="{{ path_to_root }}favicon.ico"> {% endblock %} - <script type="text/javascript"> -/* - * jQuery JavaScript Library v1.3.2 - * http://jquery.com/ - * - * Copyright (c) 2009 John Resig - * Dual licensed under the MIT and GPL licenses. - * http://docs.jquery.com/License - * - * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) - * Revision: 6246 - */ -(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.sele ctor=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this ;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G ){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="st ring"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o .inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(t his[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Obje ct.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!= =false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="m argin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDoc
ument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[ 2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J .parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return
J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webk
it/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K =0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache [H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx" }if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
-/*
- * Sizzle CSS Selector Engine - v0.9.3
- * Copyright 2009, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/
- */
-(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.cal
l(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab]. exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)(( ?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:functi on(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[ 1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file" ===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U =U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)= ==U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){va r V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagNa me(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElem entsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:f unction(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U= =T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeT ype==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G. indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.tes t(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY =H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.is DefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F|
|H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.sel
ector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatecha
nge",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML=' <link/><table></table><a href="/a" style="color:red;float:left;o
pacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var
L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:func
tion(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.ext
end(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"
="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);
return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.
httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try
{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.conca
t.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?
this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return tr
ue})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.pr
ototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop==
"height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J
,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.
offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElem
ent("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();va
r G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxMod
el&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
- </script>
- <script type="text/javascript">
- if (typeof String.prototype.endsWith != 'function') {
- String.prototype.endsWith = function(suffix) {
- return this.indexOf(suffix, this.length - suffix.length) !== -1;
- };
- }
- if (typeof String.prototype.startsWith != 'function') {
- String.prototype.startsWith = function (str){
- return this.indexOf(str) == 0;
- };
- }
- function setRepoBranch(schname) {
- console.log(schname);
- var repodict = new Object();
- $("input").each(function (i) {
- if (($(this).attr('name').startsWith("repo_triggerer")))
- {
- var name=$(this).attr('name').replace("repo_triggerer_", "").replace("_"+schname, "");
- repodict[name+"_repo"]=$(this).val();
- };
- if (($(this).attr('name').startsWith("branch_triggerer")))
- {
- var name=$(this).attr('name').replace("branch_triggerer_", "").replace("_"+schname, "");
- repodict[name+"_branch"]=$(this).val();
- };
- if (($(this).attr('name').startsWith("commit_triggerer")))
- {
- var name=$(this).attr('name').replace("commit_triggerer_", "").replace("_"+schname, "");
- repodict[name+"_commit"]=$(this).val();
- };-
- if (($(this).attr('name').startsWith("bb_triggerer")))
- {
- var name=$(this).attr('name').replace("bb_triggerer_", "").replace("_"+schname, "");
- repodict[name+"_bb"]=$(this).val();
- };
- });
- console.log(repodict)
- $("input").each(function (i) {- if (($(this).attr('name').startsWith("repo_trigger_")))
- {
-
- for (var val in repodict) {
- if (val.endsWith("_repo")) {
- console.log(repodict)
- if ($(this).attr('name').indexOf(val.replace("_repo", "")) != -1 )
- {- $(this).attr("value",repodict[val])
- };
- };
- };
- };
- if (($(this).attr('name').startsWith("branch_trigger_")))
- {
- for (var val in repodict) {
- if (val.endsWith("_branch")) {
- console.log(repodict)
- if ($(this).attr('name').indexOf(val.replace("_branch", "")) != -1 )
- {- $(this).attr("value",repodict[val])
- };
- };
- };
- };
- if (($(this).attr('name').startsWith("commit_trigger_")))
- {
- for (var val in repodict) {
- if (val.endsWith("_commit")) {
- console.log(repodict)
- if ($(this).attr('name').indexOf(val.replace("_commit", "")) != -1 )
- {- $(this).attr("value",repodict[val])
- };
- };
- };
- };
- if (($(this).attr('name').startsWith("bb_trigger_")))
- {
- for (var val in repodict) {
- if (val.endsWith("_bb")) {
- console.log(repodict)
- if ($(this).attr('name').indexOf(val.replace("_bb", "")) != -1 )
- {- $(this).attr("value",repodict[val])
- };
- };
- };
- };
- });
- };
-
- $(document).ready(function() {
- $(".force-text").hide();
- $(".force-list").hide();
- $(".force-textarea").hide();
- $(".force-any").hide();
- $(".trigger_heading").click(
- function()
- {- var x = $(this).attr('id')
- $(".force-text").each(function (i) {
- if (($(this).attr('id').endsWith(x)))
- {
- $(this).toggle()
- };
- });
- $(".force-textarea").each(function (i) {
- if (($(this).attr('id').endsWith(x)))
- {
- $(this).toggle()
- };
- });
- $(".force-any").each(function (i) {
- if (($(this).attr('id').endsWith(x)))
- {
- $(this).toggle()
- };
- });
- $(".force-list").each(function (i) {
- if (($(this).attr('id').endsWith(x)))
- {
- $(this).toggle()
- };
- });
-
- });
- });
- </script>
- <style type="text/css">
- .trigger_heading {
- margin: 1px;
- color: #fff;
- padding: 3px 10px;
- cursor: pointer;
- background-color:#c30;
- }
- .force-text {
- background-color:#fafafa;
- display: none
- }
- .force-textarea {
- background-color:#fafafa;
- display: none
- }
- .force-any {
- background-color:#fafafa;
- display: none
- }
- p { padding: 5px 0; }
- </style>
</head>
<body class="interface">
{% block header -%}
- <div class="header">
+ <div class="header">
<a href="{{ path_to_root or '.' }}">Home</a>
+ {% if authz.advertiseAction('view', request) %}
- <a href="{{ path_to_root }}waterfall">Waterfall</a>
<a href="{{ path_to_root }}grid">Grid</a>
<a href="{{ path_to_root }}tgrid">T-Grid</a>@@ -206,7 +36,8 @@
{% endif %}
- <a href="{{ path_to_root }}json/help">JSON API</a>
- <a href="{{ path_to_root }}about">About</a>
- <div class="auth">
+ {% endif %}
+ <div class="auth">
{% if authz.authenticated(request) %}
{{ authz.getUsernameHTML(request) }}
|<a href="{{ path_to_root }}logout">Logout</a>
@@ -227,18 +58,18 @@
<hr/>
{% if alert_msg != "" %}
- <div class="alert">
+ <div class="alert">
{{ alert_msg }}
</div>
{% endif %}
<div class="content">
- {%- block content -%}
+ {%- block content -%}
{%- endblock -%}
</div>
{%- endblock -%}- {%- block footer -%}
+ {%- block footer -%}
<div class="footer" style="clear:both">
<hr/>
<a href="http://buildbot.net/">BuildBot</a> ({{version}})Signature · 1 line
1.8.1.2
PATCH 24/27 PublishArtifacts.py: Change where we find eclipse artifacts
In reply to Elizabeth FlanaganNow that we're checking things out correctly, set where we find eclipse artifacts.
--- .../site-packages/autobuilder/buildsteps/PublishArtifacts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py +2 -2
@@ -79,13 +79,13 @@ class PublishArtifacts(ShellCommand): command=command+"mkdir -p " + DEST + "/eclipse-plugin/juno;" command=command+"cp -R --no-dereference --preserve=links " + \ os.path.join(os.path.join(self.slavedir, buildername), - "build/eclipse-poky-juno/scripts/org.*.zip") + \ + "build/scripts/org.*.zip") + \ " " + DEST + "/eclipse-plugin/juno;" elif artifact == "eclipse-plugin-kepler": command=command+"mkdir -p " + DEST + "/eclipse-plugin/kepler;" command=command+"cp -R --no-dereference --preserve=links " + \ os.path.join(os.path.join(self.slavedir, buildername), - "build/eclipse-poky-kepler/scripts/org.*.zip") + \ + "build/scripts/org.*.zip") + \ " " + DEST + "/eclipse-plugin/kepler;" elif artifact == "build-appliance": command=command+"mkdir -p " + DEST + "/" + BA_PUBLISH_DIR + ";"
Signature · 1 line
1.8.1.2
PATCH 25/27 yocto-autobuilder-setup: set the correct bb version
In reply to Elizabeth Flanagan--- yocto-autobuilder-setup | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
yocto-autobuilder-setup +2 -2
@@ -137,8 +137,8 @@ if [ -n "${config_check:+x}" ]; then echo "" echo " Ready to start the yocto autobuilder." echo "" - echo " The yocto-autobuilder runs buildbot 0.8.7p1 with some modifications to " - echo " layout.py and buildbot/status/master.py. " + echo " The yocto-autobuilder runs buildbot 0.8.8 with some modifications and" + echo " a different git fetcher (yoctogit.py)" echo "" echo "#########################################################################" buildbot upgrade-master ${PWD}/yocto-master
Signature · 1 line
1.8.1.2
PATCH 27/27 autobuilder: whitespace removal
In reply to Elizabeth Flanagansed --in-place 's/[[:space:]]\+$//' * for the autobuilder dir
--- .../site-packages/autobuilder/Autobuilder.py | 64 +++++++++++----------- .../site-packages/autobuilder/BuildSet.py | 10 ++-- .../autobuilder/buildsteps/BuildEclipsePlugin.py | 6 +- .../autobuilder/buildsteps/BuildToolchainImages.py | 6 +- .../autobuilder/buildsteps/CheckOutLayers.py | 6 +- .../autobuilder/buildsteps/CreateAutoConf.py | 8 +-- .../autobuilder/buildsteps/CreateBBLayersConf.py | 10 ++-- .../autobuilder/buildsteps/CreateCurrentLink.py | 6 +- .../buildsteps/CreateIntelBSPPackage.py | 8 +-- .../autobuilder/buildsteps/GetDistroVersion.py | 4 +- .../autobuilder/buildsteps/GetLayerVersion.py | 10 ++-- .../autobuilder/buildsteps/HelloWorld.py | 6 +- .../autobuilder/buildsteps/MaintainPersistDB.py | 12 ++-- .../autobuilder/buildsteps/PrepPkgIndex.py | 6 +- .../autobuilder/buildsteps/PublishArtifacts.py | 20 +++---- .../autobuilder/buildsteps/PublishLayerTarballs.py | 8 +-- .../autobuilder/buildsteps/ResolveLayerHead.py | 6 +- .../autobuilder/buildsteps/RunSanityTests.py | 6 +- .../autobuilder/buildsteps/SetDest.py | 12 ++-- .../site-packages/autobuilder/buildsteps/Sleep.py | 20 +++---- .../autobuilder/buildsteps/SyncPersistDB.py | 6 +- .../autobuilder/buildsteps/TestFailStep.py | 4 +- .../autobuilder/buildsteps/YoctoBlocker.py | 2 +- 23 files changed, 123 insertions(+), 123 deletions(-)
lib/python2.7/site-packages/autobuilder/Autobuilder.py +32 -32
@@ -49,7 +49,7 @@ class Autobuilder: beenHere.append(key) if sort: beenHere.sort() - # REALLY crappy way to do this, but better than setting globals. + # REALLY crappy way to do this, but better than setting globals. os.environ["YOCTO_SORTED_BUILDERS"]= str(beenHere) for buildset in beenHere: self.schedprops = []
@@ -61,19 +61,19 @@ class Autobuilder: self.schedprops.append(NestedParameter(name='ss_' + buildset, label="<h3><div class='trigger_heading' id='"+buildset+"'>" + buildset + " defaults:</div></h3>", fields=[FixedParameter(name="dummy", default="dummy")])) self.parseBuildSet(buildset) locals()['buildset_%s' % buildset]=BuildSet.BuildSet(name=buildset, - steps=ast.literal_eval(self.configdict[buildset]['steps']), + steps=ast.literal_eval(self.configdict[buildset]['steps']), builders=self.builders, layers=ast.literal_eval(self.configdict[buildset]['repos']), set_props=self.set_props) self.yocto_sched.append(ForceScheduler( name=str(buildset), - branch=FixedParameter(name="branch", + branch=FixedParameter(name="branch", default=""), reason=StringParameter(name="reason", label="Reason:<br>", - required=False, + required=False, size=120), - revision=FixedParameter(name="revision", + revision=FixedParameter(name="revision", default=""), repository=FixedParameter(name="repository", default=""),
@@ -122,8 +122,8 @@ class Autobuilder: for prop in dict(props): self.prop_name="" self.prop_prop_type="" - self.prop_default="" - self.prop_choices="" + self.prop_default="" + self.prop_choices="" self.prop_label="" self.prop_required="" self.prop_size=""
@@ -131,12 +131,12 @@ class Autobuilder: for k, v in props[prop].iteritems(): setattr(self, "prop_"+str(k), v) if self.prop_name not in self.properties: - schedpropstoextend = self.CreateExtraSchedulerParams(name=self.prop_name, + schedpropstoextend = self.CreateExtraSchedulerParams(name=self.prop_name, prop_type=self.prop_prop_type, - default=self.prop_default, - choices=self.prop_choices, - label=self.prop_label, - required=self.prop_required, + default=self.prop_default, + choices=self.prop_choices, + label=self.prop_label, + required=self.prop_required, scheduler=buildset, size=self.prop_size) self.schedprops.extend(schedpropstoextend)
@@ -145,7 +145,7 @@ class Autobuilder: def parseBuilders(self, buildset): buildset=buildset builders=ast.literal_eval(self.configdict[buildset]['builders']) - return builders + return builders def parseConfig(self): import ConfigParser
@@ -255,15 +255,15 @@ class Autobuilder: dayOfWeek=builddayOfWeek)) - def CreateExtraSchedulerParams(self, name=None, - prop_type=None, - default=None, - choices=None, - label=None, - required=None, + def CreateExtraSchedulerParams(self, name=None, + prop_type=None, + default=None, + choices=None, + label=None, + required=None, size=None, scheduler=""): - supported_prop_types = ["ChoiceStringParameter", + supported_prop_types = ["ChoiceStringParameter", "StringParameter", "FixedParameter", "BooleanParameter"]
@@ -291,7 +291,7 @@ class Autobuilder: default = "" if prop_type == "ChoiceStringParameter": - if choices is None: + if choices is None: try: raise ABConfigError("your config file has a ChoiceStringParameter declaration that has no choices") except ABConfigError, (instance):
@@ -307,25 +307,25 @@ class Autobuilder: prop_type = "StringParameter" if prop_type=="ChoiceStringParameter": - schedprops.append(ChoiceStringParameter(name=propid, - label=label, - required=required, + schedprops.append(ChoiceStringParameter(name=propid, + label=label, + required=required, choices=choices)) elif prop_type=="StringParameter": schedprops.append(StringParameter(name=propid, - label=label, - required=required, + label=label, + required=required, default=default, size=size)) elif prop_type=="FixedParameter": - schedprops.append(FixedParameter(name=propid, - label=label, - required=required, + schedprops.append(FixedParameter(name=propid, + label=label, + required=required, default=default)) elif prop_type=="BooleanParameter": - schedprops.append(BooleanParameter(name=propid, - label=label, - required=required, + schedprops.append(BooleanParameter(name=propid, + label=label, + required=required, default=default)) else: try:
lib/python2.7/site-packages/autobuilder/BuildSet.py +5 -5
@@ -38,12 +38,12 @@ class BuildSet(): for layer in layers: kwargs=stepOrder[step] layername=layer.iterkeys().next() - if layer[layer.iterkeys().next()].has_key('checkout') and layer[layer.iterkeys().next()]['checkout'] == False: + if layer[layer.iterkeys().next()].has_key('checkout') and layer[layer.iterkeys().next()]['checkout'] == False: pass else: if layername == "poky" or layername == 'oecore': workdir = 'build' - elif "eclipse" in layername: + elif "eclipse" in layername: workdir="build" else: workdir="build/" + layername
@@ -66,7 +66,7 @@ class BuildSet(): scheduler=name, argdict=layer[layer.iterkeys().next()])) if 'checkout' in layer[layer.iterkeys().next()]: - if layer[layer.iterkeys().next()]['checkout'] == False: + if layer[layer.iterkeys().next()]['checkout'] == False: pass else: storedir=None
@@ -114,7 +114,7 @@ class BuildSet(): kwargs=stepOrder[step] m = __import__ (step) func = getattr(m, step) - factoryFN(func(locals()['f'+name], + factoryFN(func(locals()['f'+name], layers, argdict=stepOrder[step])) elif step=="TriggerBuilds":
@@ -124,7 +124,7 @@ class BuildSet(): trigger_name = "" waitForFinish = False if 'schedulerName' in stepOrder[step]: - trigger_name = 'trigger_' + stepOrder[step]['schedulerName'] + trigger_name = 'trigger_' + stepOrder[step]['schedulerName'] if 'set_properties' in stepOrder[step]: for p in stepOrder[step]['set_properties'].iterkeys(): set_properties[p]=stepOrder[step]['set_properties'][p]
lib/python2.7/site-packages/autobuilder/buildsteps/BuildEclipsePlugin.py +3 -3
@@ -18,9 +18,9 @@ import os from twisted.python import log class BuildEclipsePlugin(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "Building Eclipse Plugin" + haltOnFailure = False + flunkOnFailure = True + name = "Building Eclipse Plugin" def __init__(self, factory, argdict=None, **kwargs): self._pendingLogObservers = [] self.factory = factory
lib/python2.7/site-packages/autobuilder/buildsteps/BuildToolchainImages.py +3 -3
@@ -16,9 +16,9 @@ from buildbot.process.buildstep import LogLineObserver import os class BuildToolchainImages(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "Building Toolchain Images" + haltOnFailure = False + flunkOnFailure = True + name = "Building Toolchain Images" def __init__(self, factory, argdict=None, **kwargs): self.images="" self._pendingLogObservers = []
lib/python2.7/site-packages/autobuilder/buildsteps/CheckOutLayers.py +3 -3
@@ -36,7 +36,7 @@ from buildbot.process import buildstep class CheckOutLayers(YoctoGit): def __init__(self, factory, scheduler=None, layername=None, mode='full', storedir=None, mirrordir=None, method='clobber', submodules=False, shallow=False, srcdir='source', workdir='build', - timeout=100000, progress=True, retryFetch=True, clobberOnFailure=False, + timeout=100000, progress=True, retryFetch=True, clobberOnFailure=False, getDescription=True, argdict=None, **kwargs): self.scheduler = scheduler
@@ -64,8 +64,8 @@ class CheckOutLayers(YoctoGit): setattr(self, k, v) YoctoGit.__init__(self, repourl=self.repourl, branch=self.branch, mode=self.mode, method=self.method, storedir=self.storedir, mirrordir=mirrordir, submodules=self.submodules, srcdir=self.srcdir+"/"+self.repourl, - workdir=self.workdir, shallow=self.shallow, progress=self.progress, - retryFetch=self.retryFetch, clobberOnFailure=self.clobberOnFailure, + workdir=self.workdir, shallow=self.shallow, progress=self.progress, + retryFetch=self.retryFetch, clobberOnFailure=self.clobberOnFailure, getDescription=self.getDescription, layername=self.layername, **kwargs) def startVC(self, branch, revision, patch):
lib/python2.7/site-packages/autobuilder/buildsteps/CreateAutoConf.py +4 -4
@@ -15,9 +15,9 @@ import os from twisted.python import log class CreateAutoConf(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "CreateAutoConf" + haltOnFailure = False + flunkOnFailure = True + name = "CreateAutoConf" def __init__(self, factory, argdict=None, **kwargs): self.machine="" self.buildapp=""
@@ -159,7 +159,7 @@ class CreateAutoConf(ShellCommand): if self.atextappend: fout = fout + self.atextappend - # We have to pass command in as a list due to some weird issue where + # We have to pass command in as a list due to some weird issue where # build progress will throw an assert error in stepFinished. This does # not happen all the time but when it does happen, just break command # up into a list.
lib/python2.7/site-packages/autobuilder/buildsteps/CreateBBLayersConf.py +5 -5
@@ -14,9 +14,9 @@ from buildbot.steps.shell import ShellCommand from twisted.python import log class CreateBBLayersConf(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "Create BBLayers Configuration" + haltOnFailure = False + flunkOnFailure = True + name = "Create BBLayers Configuration" def __init__(self, factory, layers, argdict=None, **kwargs): self.factory = factory self.layers=layers
@@ -45,7 +45,7 @@ class CreateBBLayersConf(ShellCommand): #check to see if we have text override if self.bbtext != "": fout = fout+self.bbtext - fout = fout + 'LCONF_VERSION = <LCONF> \n' + fout = fout + 'LCONF_VERSION = <LCONF> \n' fout = fout + 'BBPATH = "${TOPDIR}" \n' fout = fout + 'BBFILES ?="" \n' fout = fout + 'BBLAYERS += " \ \n'
@@ -57,7 +57,7 @@ class CreateBBLayersConf(ShellCommand): fout = fout + workdir + '/build/meta-x32 \ \n' elif self.buildprovider == "oe": fout = fout + workdir + "/build/meta \ \n" - if self.bsplayer == True: + if self.bsplayer == True: if self.bspprovider == "intel": if list(self.layerdirs): for layer in self.layerdirs:
lib/python2.7/site-packages/autobuilder/buildsteps/CreateCurrentLink.py +3 -3
@@ -14,9 +14,9 @@ from buildbot.steps.shell import ShellCommand from twisted.python import log class CreateCurrentLink(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "CreateCurrentLink" + haltOnFailure = False + flunkOnFailure = True + name = "CreateCurrentLink" def __init__(self, factory, argdict=None, **kwargs): for k, v in argdict.iteritems(): setattr(self, k, v)
lib/python2.7/site-packages/autobuilder/buildsteps/CreateIntelBSPPackage.py +4 -4
@@ -12,13 +12,13 @@ __email__ = "[email protected]" from buildbot.steps.shell import ShellCommand from twisted.python import log -import os, datetime +import os, datetime from autobuilder.config import * class CreateIntelBSPPackage(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "Creating BSP Packages" + haltOnFailure = False + flunkOnFailure = True + name = "Creating BSP Packages" def __init__(self, factory, argdict=None, **kwargs): self.factory = factory self.machine = ""
lib/python2.7/site-packages/autobuilder/buildsteps/GetDistroVersion.py +2 -2
@@ -17,8 +17,8 @@ from twisted.python import log from autobuilder.config import * class GetDistroVersion(ShellCommand): - haltOnFailure = False - flunkOnFailure = True + haltOnFailure = False + flunkOnFailure = True name = "GetDistroVersion" def __init__(self, factory, argdict=None, **kwargs): for k, v in argdict.iteritems():
lib/python2.7/site-packages/autobuilder/buildsteps/GetLayerVersion.py +5 -5
@@ -17,8 +17,8 @@ from twisted.python import log from autobuilder.config import * class GetLayerVersion(ShellCommand): - haltOnFailure = False - flunkOnFailure = False + haltOnFailure = False + flunkOnFailure = False name = "GetLayerVersion" def __init__(self, factory, layerversion=None, workdir='build', argdict=None, **kwargs): for k, v in argdict.iteritems():
@@ -35,9 +35,9 @@ class GetLayerVersion(ShellCommand): buildername=self.getProperty("buildername") log.msg(self.workdir) log.msg(self.layerversion) - - layerconf=self.slaveworkdir + "/" + buildername + "/build/" + self.workdir + "/conf/layer.conf|grep LAYERVERSION_" + self.layerversion - cmd = 'cat ' + layerconf + + layerconf=self.slaveworkdir + "/" + buildername + "/build/" + self.workdir + "/conf/layer.conf|grep LAYERVERSION_" + self.layerversion + cmd = 'cat ' + layerconf self.command = cmd ShellCommand.start(self)
lib/python2.7/site-packages/autobuilder/buildsteps/HelloWorld.py +3 -3
@@ -14,9 +14,9 @@ __email__ = "[email protected]" from buildbot.steps.shell import ShellCommand class HelloWorld(ShellCommand): - haltOnFailure = True - flunkOnFailure = True - name = "Hello World" + haltOnFailure = True + flunkOnFailure = True + name = "Hello World" def __init__(self, factory, argdict=None, **kwargs): self.firstname="" self.lastname=""
lib/python2.7/site-packages/autobuilder/buildsteps/MaintainPersistDB.py +6 -6
@@ -14,9 +14,9 @@ from buildbot.steps.shell import ShellCommand from twisted.python import log class CreateCurrentLink(ShellCommand): - haltOnFailure = False - flunkOnFailure = False - name = "CreateCurrentLink" + haltOnFailure = False + flunkOnFailure = False + name = "CreateCurrentLink" def __init__(self, factory, argdict=None, **kwargs): for k, v in argdict.iteritems(): setattr(self, k, v)
@@ -26,8 +26,8 @@ class CreateCurrentLink(ShellCommand): kwargs['timeout']=self.timeout buildername = self.getProperty("buildername") branch = self.getProperty("branch_poky") - persistdbdir = str(os.environ.get('PERSISTDB_DIR')) - buildhistory = str(os.environ.get('BUILD_HISTORY_COLLECT'')) + persistdbdir = str(os.environ.get('PERSISTDB_DIR')) + buildhistory = str(os.environ.get('BUILD_HISTORY_COLLECT'')) nightly_arch = [] nightly_arch.append("x86") nightly_arch.append("x86-64")
@@ -46,7 +46,7 @@ class CreateCurrentLink(ShellCommand): elif "nightly-" + arch in buildername and branch == "master" and buildhistory == "True" and self.sync == "checkin": command=command+"cp -R tmp/cache/bb_persist_data.sqlite3 " \ + persistdbdir + "/" + buildername \ - + "/" + branch + "/" + self.distro + + "/" + branch + "/" + self.distro ShellCommand.start(self, **kwargs) def describe(self, done=False):
lib/python2.7/site-packages/autobuilder/buildsteps/PrepPkgIndex.py +3 -3
@@ -15,9 +15,9 @@ from twisted.python import log from autobuilder.config import * class PrepPkgIndex(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "PrepPkgIndex" + haltOnFailure = False + flunkOnFailure = True + name = "PrepPkgIndex" def __init__(self, factory, argdict=None, **kwargs): for k, v in argdict.iteritems(): setattr(self, k, v)
lib/python2.7/site-packages/autobuilder/buildsteps/PublishArtifacts.py +10 -10
@@ -12,14 +12,14 @@ __email__ = "[email protected]" from buildbot.steps.shell import ShellCommand from twisted.python import log -import os, datetime +import os, datetime from autobuilder.config import * class PublishArtifacts(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "Publishing Artifacts" + haltOnFailure = False + flunkOnFailure = True + name = "Publishing Artifacts" def __init__(self, factory, argdict=None, **kwargs): self.factory = factory self.description = "Publishing Artifacts"
@@ -44,7 +44,7 @@ class PublishArtifacts(ShellCommand): self.layerversion_core = self.getProperty("layerversion_core") log.msg(layerversion_yoctobsp) self.basedir=os.path.join(os.path.join( - self.slavedir, buildername), + self.slavedir, buildername), "build/build/") command="" DATESTAMP=datetime.datetime.now().strftime("%Y%m%d")
@@ -71,20 +71,20 @@ class PublishArtifacts(ShellCommand): command=command+"mkdir -p " + adt_dev_dest + "/adt-ipk;" command=command+"cp -R " + os.path.join(self.basedir, "tmp/deploy/ipk/*") + " " + adt_dev_dest + "/adt-ipk;" command=command+"rsync -av " + os.path.join(self.basedir, "tmp/deploy/ipk/") + " " + DEST + "/ipk;" - command=command+"mkdir -p " + adt_dev_dest + "/rootfs;" + command=command+"mkdir -p " + adt_dev_dest + "/rootfs;" command=command+"for x in `ls " + DEST + "/machines/qemu/|grep -v tiny`; do ln -s " + DEST + "/machines/qemu/$x " + adt_dev_dest + "/rootfs/$x; done;" if self.layerversion_yocto is not None and int(self.layerversion_yocto) < 2: - command=command+"mv " + adt_dev_dest + "/rootfs/qemux86-64 " + adt_dev_dest + "/rootfs/qemux86_64;" + command=command+"mv " + adt_dev_dest + "/rootfs/qemux86-64 " + adt_dev_dest + "/rootfs/qemux86_64;" elif artifact == "eclipse-plugin-juno": command=command+"mkdir -p " + DEST + "/eclipse-plugin/juno;" command=command+"cp -R --no-dereference --preserve=links " + \ - os.path.join(os.path.join(self.slavedir, buildername), + os.path.join(os.path.join(self.slavedir, buildername), "build/scripts/org.*.zip") + \ " " + DEST + "/eclipse-plugin/juno;" elif artifact == "eclipse-plugin-kepler": command=command+"mkdir -p " + DEST + "/eclipse-plugin/kepler;" command=command+"cp -R --no-dereference --preserve=links " + \ - os.path.join(os.path.join(self.slavedir, buildername), + os.path.join(os.path.join(self.slavedir, buildername), "build/scripts/org.*.zip") + \ " " + DEST + "/eclipse-plugin/kepler;" elif artifact == "build-appliance":
@@ -169,7 +169,7 @@ class PublishArtifacts(ShellCommand): command=command+"echo 'Skipping copy of " + artifact + ".'" else: artifact_name, deploy_image_dir = self.getDeployNames(artifact, buildername) - + command=command+"mkdir -p " + DEST + "/"+ MACHINE_PUBLISH_DIR +"/" + artifact_name + ";" command=command+"cp -R --no-dereference --preserve=links " + \ deploy_image_dir + \
lib/python2.7/site-packages/autobuilder/buildsteps/PublishLayerTarballs.py +4 -4
@@ -12,13 +12,13 @@ __email__ = "[email protected]" from buildbot.steps.shell import ShellCommand from twisted.python import log -import os, datetime +import os, datetime from autobuilder.config import * class PublishLayerTarballs(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "Publishing Layer Tarballs" + haltOnFailure = False + flunkOnFailure = True + name = "Publishing Layer Tarballs" def __init__(self, factory, layername, workdir, argdict=None, **kwargs): self.factory = factory self.layername = layername
lib/python2.7/site-packages/autobuilder/buildsteps/ResolveLayerHead.py +3 -3
@@ -16,8 +16,8 @@ from twisted.python import log from autobuilder.config import * class ResolveLayerHead(ShellCommand): - haltOnFailure = False - flunkOnFailure = False + haltOnFailure = False + flunkOnFailure = False name = "ResolveLayerHead" def __init__(self, factory, layername=None, scheduler=None, argdict=None, **kwargs): self.branch = ""
@@ -46,7 +46,7 @@ class ResolveLayerHead(ShellCommand): else: self.commit = "HEAD" if self.commit == "HEAD": - cmd = 'git ls-remote ' + self.repourl + ' refs/heads/' + self.branch + '|cut -f1' + cmd = 'git ls-remote ' + self.repourl + ' refs/heads/' + self.branch + '|cut -f1' else: cmd = 'echo ' + self.commit self.command = cmd
lib/python2.7/site-packages/autobuilder/buildsteps/RunSanityTests.py +3 -3
@@ -18,9 +18,9 @@ import os, re class RunSanityTests(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "Running Sanity Tests" + haltOnFailure = False + flunkOnFailure = True + name = "Running Sanity Tests" def __init__(self, factory, argdict=None, **kwargs): self.factory = factory self.testsfailed = 0
lib/python2.7/site-packages/autobuilder/buildsteps/SetDest.py +6 -6
@@ -12,15 +12,15 @@ __email__ = "[email protected]" from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, SKIPPED, \ EXCEPTION, RETRY, worst_status -import os, datetime +import os, datetime import cPickle as pickle from autobuilder.config import * from twisted.python import log from buildbot.steps.shell import ShellCommand class SetDest(ShellCommand): - name = "SetDest" - haltOnFailure = True + name = "SetDest" + haltOnFailure = True flunkOnFailure = True name = "Destination" description = ["Setting %s" % name]
@@ -49,7 +49,7 @@ class SetDest(ShellCommand): else: buildername=self.getProperty("buildername") self.workdir=os.path.join(self.slaveworkdir, buildername) - if str(self.getProperty("custom_release_me_" + buildername)) == "True": + if str(self.getProperty("custom_release_me_" + buildername)) == "True": rel_name = self.getProperty("custom_release_name_" + buildername) if not rel_name or rel_name == "": rel_name == self.getProperty(commit-description)
@@ -75,7 +75,7 @@ class SetDest(ShellCommand): pickle.dump(data, pfile) pfile.close() # we can't os.path.exists here as we don't neccessarily have - # access to the slave dest from master. So we keep a cpickle of + # access to the slave dest from master. So we keep a cpickle of # the dests. try: # if the dictionary entry exists, we increment value by one, then repickle
@@ -87,7 +87,7 @@ class SetDest(ShellCommand): pfile = open(DATA_FILE, 'wb') pickle.dump(data, pfile) pfile.close() - + DEST = os.path.join(DEST, DEST_DATE + "-" + str(REV)) self.setProperty("DEST", DEST) self.finished(SUCCESS)
lib/python2.7/site-packages/autobuilder/buildsteps/Sleep.py +10 -10
@@ -14,9 +14,9 @@ __email__ = "[email protected]" from buildbot.steps.shell import ShellCommand class Sleep(ShellCommand): - haltOnFailure = True - flunkOnFailure = True - name = "Sleep" + haltOnFailure = True + flunkOnFailure = True + name = "Sleep" def __init__(self, factory, argdict=None, **kwargs): self.time="0" self.funny="False"
@@ -28,13 +28,13 @@ class Sleep(ShellCommand): setattr(self, k, v) sleep_quotes = ["Sleep, those little slices of death, how I loathe them.", "No day is so bad it can't be fixed with a nap.", - "People who say they sleep like a baby usually don't have one.", - "Life is too short to sleep on low thread-count sheets", - "Sleep is a symptom of caffeine deprivation.", - "Without enough sleep, we all become tall two-year-olds.", - "I'm not asleep... but that doesn't mean I'm awake.", - "When you have insomnia, you're never really asleep, and you're never really awake.", - "Life is something that happens when you can't get to sleep.", + "People who say they sleep like a baby usually don't have one.", + "Life is too short to sleep on low thread-count sheets", + "Sleep is a symptom of caffeine deprivation.", + "Without enough sleep, we all become tall two-year-olds.", + "I'm not asleep... but that doesn't mean I'm awake.", + "When you have insomnia, you're never really asleep, and you're never really awake.", + "Life is something that happens when you can't get to sleep.", "Sleeping is no mean art: for its sake one must stay awake all day.", "I count it as a certainty that in paradise, everyone naps.", "Early to rise and early to bed, makes a man healthy and wealthy and dead.",
lib/python2.7/site-packages/autobuilder/buildsteps/SyncPersistDB.py +3 -3
@@ -17,9 +17,9 @@ from autobuilder.config import * import os class SyncPersistDB(ShellCommand): - haltOnFailure = False - flunkOnFailure = True - name = "syncing persistdb" + haltOnFailure = False + flunkOnFailure = True + name = "syncing persistdb" def __init__(self, factory, argdict=None, **kwargs): self._pendingLogObservers = [] self.factory = factory
lib/python2.7/site-packages/autobuilder/buildsteps/TestFailStep.py +2 -2
@@ -13,8 +13,8 @@ from buildbot.steps.shell import ShellCommand from buildbot.status.results import FAILURE class TestFailStep(ShellCommand): - haltOnFailure = False - flunkOnFailure = True + haltOnFailure = False + flunkOnFailure = True name = "TestFailStep" def __init__(self, factory, argdict=None, **kwargs): for k, v in argdict.iteritems():
lib/python2.7/site-packages/autobuilder/buildsteps/YoctoBlocker.py +1 -1
@@ -17,7 +17,7 @@ class YoctoBlocker(Blocker): builderStatus = builder.builder_status matchingBuild = None - all_builds = builderStatus.getCurrentBuilds() + all_builds = builderStatus.getCurrentBuilds() for buildStatus in all_builds: if self.buildsMatch(myBuildStatus, buildStatus):
Signature · 1 line
1.8.1.2
PATCH 3/27 nightly-world-uclibc: uclibc target
In reply to Elizabeth Flanagan[Yocto #5433]
This should add a uclibc world build (which will probably have some issues at first)
--- buildset-config.master/nightly-world-uclibc.conf | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 buildset-config.master/nightly-world-uclibc.conf
buildset-config.master/nightly-world-uclibc.conf new file +18 -0
@@ -0,0 +1,18 @@ +[nightly-world-uclibc] +builders: 'builder1' +repos: [{'poky': + {'repourl':'git://git.yoctoproject.org/poky', + 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp'}, + 'branch':'master'}}, + {'meta-qt3': + {'repourl':'git://git.yoctoproject.org/meta-qt3', + 'branch':'master'}}] +steps: [{'SetDest':{}}, + {'CheckOutLayers': {}}, + {'RunPreamble': {}}, + {'GetDistroVersion' : {'distro': 'poky'}}, + {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64', 'multilib': True, 'distro': 'poky', 'atextappend' : '\nTCLIBC="uclibc"\n' }}, + {'CreateBBLayersConf': {'buildprovider' : 'yocto'}}, + {'BuildImages': {'images': 'world'}}, + {'PublishArtifacts': {'artifacts': ['ipk', 'rpm', 'deb']}}] +
Signature · 1 line
1.8.1.2
PATCH 14/27 bin/buildslave-janitor: For fast-git checkouts
In reply to Elizabeth FlanaganFrom: Richard Purdie <[email protected]>
This cleans up OGIT_TRASH_DIR and OGIT_MIRROR_DIR. Next few commits bring it into the infrastructure.
--- bin/buildslave-janitor | 125 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100755 bin/buildslave-janitor
bin/buildslave-janitor new file +125 -0
@@ -0,0 +1,125 @@ +#!/usr/bin/python +''' +Created on Feb 19, 2014 + +__author__ = "Richard Purdie" +__copyright__ = "Copyright 2014, Linux Foundation" +__credits__ = ["Richard Purdie"] +__license__ = "GPL" +__version__ = "2.0" +__maintainer__ = "Richard Purdie" +__email__ = "[email protected]" +''' + +from __future__ import print_function +import signal +import os +import sys +import ConfigParser +import threading +import time + +if len(sys.argv) < 2: + print("Please specify the path to the config file on the commandline as the first argument") + sys.exit(1) + +config = ConfigParser.ConfigParser() +config.read(sys.argv[1]) + +sections = {} +for section in config.sections(): + sections[section] = dict(config.items(section)) + +if "GitSettings" not in sections: + print("There is no GitSettings section in the configuration file?") + sys.exit(1) + +gitsettings = sections["GitSettings"] + +if "ogit_trash_dir" not in gitsettings: + print("Please set OGIT_TRASH_DIR in the configuration file") + sys.exit(1) + +if "ogit_mirror_dir" not in gitsettings: + print("Please set OGIT_MIRROR_DIR in the configuration file") + sys.exit(1) + +trashdir = gitsettings["ogit_trash_dir"].replace('"','').replace("'",'') +mirrordir = gitsettings["ogit_mirror_dir"].replace('"','').replace("'",'') + +mirrorlist = [ + "git://git.yoctoproject.org/meta-fsl-arm", + "git://git.yoctoproject.org/meta-fsl-ppc", + "git://git.yoctoproject.org/meta-intel", + "git://git.yoctoproject.org/meta-minnow", + "git://git.yoctoproject.org/meta-qt3", + "git://git.yoctoproject.org/poky", + "git://git.yoctoproject.org/eclipse-poky-kepler", + "git://git.yoctoproject.org/eclipse-poky-juno" +] + +def trash_processor(trashdir): + print("Monitoring trashdir %s" % trashdir) + if not os.path.exists(trashdir): + os.makedirs(trashdir) + if trashdir == "/": + print("Not prepared to use a trashdir of /") + return + while True: + files = os.listdir(trashdir) + if files: + os.system("ionice -c 3 rm %s -rf" % trashdir) + else: + time.sleep(30*60) # 30 minutes + return + +def mirror_processor(mirrordir): + print("Updating mirrors in %s" % mirrordir) + mirrorpaths = [] + for mirror in mirrorlist: + mirrorpaths.append(os.path.join(mirrordir, mirror.split("/")[2], mirror.split("/", 3)[3])) + if not os.path.exists(mirrorpaths[-1] + "/.git/"): + os.system("git clone %s %s" % (mirror, mirrorpaths[-1])) + while True: + for path in mirrorpaths: + os.chdir(path) + os.system("git fetch --all") + time.sleep(30*60) # 30 minutes + return + +#Check to see if this is running already. If so, kill it and rerun +if os.path.exists('/tmp/.buildslave-janitor') and os.path.isfile('/tmp/.buildslave-janitor'): + print("A prior PID file exists. Attempting to kill.") + with open('/tmp/.buildslave-janitor', 'r') as f: + pid=f.readline() + try: + os.kill(int(pid), signal.SIGKILL) + # We need to sleep for a second or two just to give the SIGKILL time + time.sleep(2) + except OSError as ex: + print("""We weren't able to kill the prior buildslave-janitor. Trying again.""") + pass + # Check if the process that we killed is alive. + try: + os.kill(int(pid), 0) + except OSError as ex: + pass +elif os.path.exists('/tmp/.buildslave-janitor') and not os.path.isfile('/tmp/.buildslave-janitor'): + raise Exception("""/tmp/.buildslave-janitor is a director. remove it to continue.""") +try: + os.unlink('/tmp/.buildslave-janitor') +except: + pass +with open('/tmp/.buildslave-janitor', 'w') as f: + print(os.getpid(), file=f) + +threads = [] +threads.append(threading.Thread(target=trash_processor, args=(trashdir,))) +threads[-1].start() +threads.append(threading.Thread(target=mirror_processor, args=(mirrordir,))) +threads[-1].start() + +# wait for all threads to finish +for t in threads: + t.join() +sys.exit(0)
Signature · 1 line
1.8.1.2
PATCH 16/27 SyncPersistDB.py: First run failure correction
In reply to Elizabeth Flanaganpersistdb does not exist on first run. Allow pass if it does not exist.
--- lib/python2.7/site-packages/autobuilder/buildsteps/SyncPersistDB.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
lib/python2.7/site-packages/autobuilder/buildsteps/SyncPersistDB.py +3 -2
@@ -41,9 +41,10 @@ class SyncPersistDB(ShellCommand): self.buildername=self.getProperty("buildername") self.branch=self.getProperty("branch_poky") if self.getProperty("repourl_poky") == "git://git.yoctoproject.org/poky" and os.environ.get('MAINTAIN_PERSISTDB') == "True" and self.branch=="master": - self.command = "mkdir -p ./build/tmp/cache/; cp -R " + os.environ.get('PERSISTDB_DIR') + "/" + self.buildername + \ + self.command = "mkdir -p ./build/tmp/cache/; if [ -b '/tmp/yocto-autobuilder/persistdb/nightly-arm/master/poky/bb_persist_data.sqlite3' ]; " \ + "then cp -R " + os.environ.get('PERSISTDB_DIR') + "/" + self.buildername + \ "/" + self.branch + "/" + self.distro + \ - "/bb_persist_data.sqlite3 ./build/tmp/cache/bb_persist_data.sqlite3 " + "/bb_persist_data.sqlite3 ./build/tmp/cache/bb_persist_data.sqlite3; fi " if str(self.commit) == 'True': self.command = "cp -R ./build/tmp/cache/bb_persist_data.sqlite3 " + os.environ.get('PERSISTDB_DIR') + \ "/" + self.buildername + "/" + self.branch + "/" + self.distro + "/bb_persist_data.sqlite3"
Signature · 1 line
1.8.1.2
PATCH 17/27 BuildSet.py: Set workdir based on layer not order
In reply to Elizabeth Flanaganworkdir needs to be build/ for poky,oecore and build/layername for everything else. doing if via location in list is bad.
--- lib/python2.7/site-packages/autobuilder/BuildSet.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
lib/python2.7/site-packages/autobuilder/BuildSet.py +2 -5
@@ -55,7 +55,6 @@ class BuildSet(): argdict=layer[layer.iterkeys().next()])) elif step=="CheckOutLayers": # All steps need the factory passed as the first param - passed=0 for layer in layers: kwargs=stepOrder[step] layername=layer.iterkeys().next()
@@ -76,17 +75,15 @@ class BuildSet(): mode='full' srcdir = 'source' if str(os.environ.get('OPTIMIZED_GIT_CLONE')) == "True": - if passed==0: + if 'poky' in layername or 'oecore' in layername or 'eclipse' in layername: method='movecopy' storedir=os.environ.get('OGIT_TRASH_DIR') mirrordir=os.environ.get('OGIT_MIRROR_DIR') - passed=1 else: method='barecopy' storedir=os.environ.get('OGIT_TRASH_DIR') mirrordir=os.environ.get('OGIT_MIRROR_DIR') - passed=1 - if layername == "poky" or layername == 'oecore': + if 'poky' in layername or 'oecore' in layername: workdir = 'build' elif "eclipse-poky" in layername: workdir="build/" + layername
Signature · 1 line
1.8.1.2
PATCH 1/27 buildsets: add a new buildset to run builds on target
In reply to Elizabeth FlanaganFrom: Stefan Stanacar <[email protected]>
Builds core-image-sato-sdk for each qemu arch and runs tests building sudoku/cvs/iptables.
These do take a while, so they shouldn't be added to nightly!
--- .../nightly-qa-targetbuilds.conf | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 buildset-config.master/nightly-qa-targetbuilds.conf
buildset-config.master/nightly-qa-targetbuilds.conf new file +26 -0
@@ -0,0 +1,26 @@ +[nightly-qa-targetbuilds] +builders: 'builder1' +repos: [{'poky': + {'repourl':'git://git.yoctoproject.org/poky', + 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp'}, + 'branch':'master'}}] +steps: [{'SetDest':{}}, + {'CheckOutLayers': {}}, + {'RunPreamble': {}}, + {'GetDistroVersion' : {'distro': 'poky'}}, + {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}}, + {'CreateBBLayersConf': {'buildprovider' : 'yocto'}}, + {'BuildImages': {'images': 'core-image-sato-sdk'}}, + {'RunSanityTests': {'images': 'core-image-sato-sdk', 'suites' : 'ping ssh buildsudoku buildcvs buildiptables'}}, + {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}}, + {'BuildImages': {'images': 'core-image-sato-sdk'}}, + {'RunSanityTests': {'images': 'core-image-sato-sdk', 'suites' : 'ping ssh buildsudoku buildcvs buildiptables'}}, + {'CreateAutoConf': {'machine': 'qemuarm', 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}}, + {'BuildImages': {'images': 'core-image-sato-sdk'}}, + {'RunSanityTests': {'images': 'core-image-sato-sdk', 'suites' : 'ping ssh buildsudoku buildcvs buildiptables'}}, + {'CreateAutoConf': {'machine': 'qemuppc', 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}}, + {'BuildImages': {'images': 'core-image-sato-sdk'}}, + {'RunSanityTests': {'images': 'core-image-sato-sdk', 'suites' : 'ping ssh buildsudoku buildcvs buildiptables'}}, + {'CreateAutoConf': {'machine': 'qemumips', 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}}, + {'BuildImages': {'images': 'core-image-sato-sdk'}}, + {'RunSanityTests': {'images': 'core-image-sato-sdk', 'suites' : 'ping ssh buildsudoku buildcvs buildiptables'}}]
Signature · 1 line
1.8.1.2
PATCH 2/27 Add buildstep and buildset for oe-selftest script
In reply to Elizabeth FlanaganFrom: Stefan Stanacar <[email protected]>
This will run the oe-selftest script which has been available in master for a while. The scripts run a series of bitbake tests and takes care of it's own config. Because some of the tests mess up with sstate we want to use the default sstate dir, so a nosstate option was added to CreateAutoConf.
--- buildset-config.master/nightly-oe-selftest.conf | 15 +++++++++++++ .../autobuilder/buildsteps/CreateAutoConf.py | 7 ++++-- .../autobuilder/buildsteps/RunOeSelftest.py | 26 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 buildset-config.master/nightly-oe-selftest.conf create mode 100644 lib/python2.7/site-packages/autobuilder/buildsteps/RunOeSelftest.py
buildset-config.master/nightly-oe-selftest.conf new file +15 -0
@@ -0,0 +1,15 @@ +[nightly-oe-selftest] +builders: 'builder1' +repos: [{'poky': + {'repourl':'git://git.yoctoproject.org/poky', + 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp'}, + 'branch':'master'}}] +steps: [{'SetDest':{}}, + {'CheckOutLayers': {}}, + {'RunPreamble': {}}, + {'GetDistroVersion' : {'distro': 'poky'}}, + {'CreateAutoConf': {'machine': 'qemux86-64', 'SDKMACHINE' : 'x86_64', 'distro': 'poky', 'nosstate': True, 'packages': 'rpm'}}, + {'CreateBBLayersConf': {'buildprovider' : 'yocto'}}, + {'BuildImages': {'images': 'core-image-minimal'}}, + {'CreateBBLayersConf': {'buildprovider' : 'yocto', 'layerdirs': ['meta-selftest']}}, + {'RunOeSelftest': {}}]
lib/python2.7/site-packages/autobuilder/buildsteps/CreateAutoConf.py +5 -2
@@ -38,6 +38,7 @@ class CreateAutoConf(ShellCommand): self.factory = factory self.buildappsrcrev = "${AUTOREV}" self.initmgr=None + self.nosstate=False self.kwargs = kwargs for k, v in argdict.iteritems(): if type(v) is bool:
@@ -100,9 +101,11 @@ class CreateAutoConf(ShellCommand): elif self.multilib == "lib64": fout = fout + 'MULTILIBS = "multilib:lib64" \n' fout = fout + 'DEFAULTTUNE_virtclass-multilib-lib64 = "x86-64" \n' - fout = fout + 'SSTATE_DIR ?= "' + os.environ.get("SSTATE_DIR") + '/multilib" \n' + if not self.nosstate: + fout = fout + 'SSTATE_DIR ?= "' + os.environ.get("SSTATE_DIR") + '/multilib" \n' else: - fout = fout + 'SSTATE_DIR ?= "' + os.environ.get("SSTATE_DIR") + '/" \n' + if not self.nosstate: + fout = fout + 'SSTATE_DIR ?= "' + os.environ.get("SSTATE_DIR") + '/" \n' if self.gplv3 == "False": fout = fout + 'INCOMPATIBLE_LICENSE = "GPLv3" \n' if self.x32 == "True":
lib/python2.7/site-packages/autobuilder/buildsteps/RunOeSelftest.py new file +26 -0
@@ -0,0 +1,26 @@ +''' +__author__ = "Stefan Stanacar" +__copyright__ = "Copyright 2014 Intel Corporation" +__credits__ = ["Stefan Stanacar"] +__license__ = "GPL" +__version__ = "2.0" +__maintainer__ = "Stefan Stanacar" +__email__ = "[email protected]" +''' + + +from buildbot.steps.shell import ShellCommand + +class RunOeSelftest(ShellCommand): + haltOnFailure = False + flunkOnFailure = True + name = "Running oe-selftest" + def __init__(self, factory, argdict=None, **kwargs): + self.factory = factory + for k, v in argdict.iteritems(): + setattr(self, k, v) + self.description = "Running oe-selftest" + self.timeout = 100000 + kwargs['timeout']=self.timeout + self.command = "if [ -d meta-selftest ]; then . ./oe-init-build-env; oe-selftest; else echo 'Skipping step - no meta-selftest layer here'; fi" + ShellCommand.__init__(self, **kwargs)
Signature · 1 line
1.8.1.2
PATCH 18/27 yoctogit: Remove use of oe.path.exists()
In reply to Elizabeth FlanaganFrom: Richard Purdie <[email protected]>
--- .../buildbot/steps/source/yoctogit.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py +10 -5
@@ -246,10 +246,17 @@ class YoctoGit(Source): log.msg("Source step failed while running command %s" % cmd) raise buildstep.BuildStepFailed() d.addCallback(lambda _: evaluateCommand(cmd)) + if self.mirrordir: + mirror = self.mirrordir + "/" + self.repourl.replace("git://", "") + "/" + if self.pathExists(mirror): + self.srcdir=mirror + else: + self.srcdir='source/'+self.repourl + if self.layername == "poky" or self.layername == "oecore" or "eclipse" in self.layername: + self.todir = "build/" + else: + self.todir = "build/" + self.layername - self.workdir = 'source/'+self.repourl - self.srcdir='source/'+self.repourl - self.todir = "build/" + self.layername d.addCallback(lambda _: self.incremental()) def copy(_): cmd = buildstep.RemoteCommand('cpdir',
@@ -465,8 +472,6 @@ class YoctoGit(Source): args += ['--depth', '1'] command = ['clone'] + args + [self.repourl, '.'] - import os - mirror = None if self.mirrordir: mirror = self.mirrordir + "/" + self.repourl.replace("git://", "") + "/"
Signature · 1 line
1.8.1.2
PATCH 19/27 BuildSet.py: remove trailing spaces
In reply to Elizabeth Flanagan--- lib/python2.7/site-packages/autobuilder/BuildSet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/python2.7/site-packages/autobuilder/BuildSet.py +1 -1
@@ -73,7 +73,7 @@ class BuildSet(): mirrordir=None method = 'clobber' mode='full' - srcdir = 'source' + srcdir = 'source' if str(os.environ.get('OPTIMIZED_GIT_CLONE')) == "True": if 'poky' in layername or 'oecore' in layername or 'eclipse' in layername: method='movecopy'
Signature · 1 line
1.8.1.2
PATCH 23/27 BuildEclipsePlugin.py: Change location of build.
In reply to Elizabeth FlanaganNow that yoctogit is checking this out in the right place, change where we look for setup.sh
--- .../site-packages/autobuilder/buildsteps/BuildEclipsePlugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/python2.7/site-packages/autobuilder/buildsteps/BuildEclipsePlugin.py +1 -1
@@ -40,7 +40,7 @@ class BuildEclipsePlugin(ShellCommand): buildername=self.getProperty("buildername") oldbuildername=buildername.replace("plugin", "poky") branch=self.getProperty("branch") - eclipsehome=self.slaveworkdir + "/" + buildername + '/build/' + oldbuildername + eclipsehome=self.slaveworkdir + "/" + buildername + '/build' self.command='cd ' + eclipsehome + '/scripts/; ./setup.sh; ECLIPSE_HOME="' + eclipsehome + '/scripts/eclipse" ./build.sh ' + branch + ' development' ShellCommand.start(self)
Signature · 1 line
1.8.1.2
PATCH 7/27 nightly.conf: Add additional parameters
In reply to Elizabeth FlanaganFrom: Beth Flanagan <[email protected]>
This allows us to set the prefered kernel via the UI as well as supports additional release related parameters that are not currently supported by PublishArtifacts/SetDest.
This also supports TriggerBuilds schedulerNames_nowait. This allows us to delay the schedulers of certain buildsets a few seconds before pushing them out to be built.
--- buildset-config.master/nightly.conf | 40 +++++++++++++--------- .../autobuilder/buildsteps/CreateAutoConf.py | 2 ++ .../autobuilder/buildsteps/PublishLayerTarballs.py | 25 ++++++++------ 3 files changed, 41 insertions(+), 26 deletions(-)
buildset-config.master/nightly.conf +24 -16
@@ -2,7 +2,7 @@ builders: 'builder1' repos: [{'poky': {'repourl':'git://git.yoctoproject.org/poky', - 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp'}, + 'layerversion':{'core':'meta', 'yoctobsp':'meta-yocto-bsp'}, 'branch':'master'}}, {'meta-intel': {'repourl':'git://git.yoctoproject.org/meta-intel',
@@ -55,7 +55,12 @@ props: [{'release_me':{'prop_type':'ChoiceStringParameter', {'send_email':{'prop_type':'ChoiceStringParameter', 'choices': ['False', 'True'], 'name': 'send_email', - 'label':'<h3> Send QA alert emails?:</h3>'}}] + 'label':'<h3> Send QA alert emails?:</h3>'}}, + {'prefered_kernel':{'prop_type':'StringParameter', + 'size': 15, + 'name': 'prefered_kernel', + 'default': 'linux-yocto', + 'label':'<hr><h3> PREFERRED_PROVIDER_virtual/kernel (default is "linux-yocto"):</h3>'}}] steps: [{'SetDest':{}}, {'CheckOutLayers': {}}, {'RunPreamble': {}},
@@ -63,22 +68,25 @@ steps: [{'SetDest':{}}, {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'x86_64', 'distro': 'poky'}}, {'CreateBBLayersConf': {'buildprovider' : 'yocto'}}, - {'RunBitbakeSelftest': {}}, {'BuildImages': {'images': 'universe -c fetch'}}, {'TriggerBuilds': {'schedulerName': 'main-build', 'waitForFinish': 'True', - 'schedulerNames': {'minnow': {}, 'minnow-lsb': {}, - 'nightly-arm': {}, 'nightly-arm-lsb': {}, - 'nightly-fsl-arm': {}, 'nightly-fsl-arm-lsb': {}, - 'nightly-fsl-ppc': {}, 'nightly-fsl-ppc-lsb': {}, - 'nightly-intel-gpl': {}, 'nightly-mips': {}, - 'nightly-mips-lsb': {}, 'nightly-multilib': {}, - 'nightly-ppc': {}, 'nightly-ppc-lsb': {}, - 'nightly-x86-64': {}, 'nightly-x86-64-lsb': {}, - 'nightly-x86': {}, 'nightly-x86-lsb': {}, - 'nightly-x32': {}, 'poky-tiny': {}, 'buildtools': {}, - 'nightly-qa-systemd': {}, 'nightly-qa-extras': {}, - 'nightly-qa-logrotate': {}, 'nightly-qa-pam': {}, - 'nightly-qa-skeleton': {}, 'nightly-extras': {}}}}, + 'schedulerNames': {'minnow': {}, 'minnow-lsb': {}, + 'nightly-arm': {}, 'nightly-arm-lsb': {}, + 'nightly-fsl-arm': {}, 'nightly-fsl-arm-lsb': {}, + 'nightly-fsl-ppc': {}, 'nightly-fsl-ppc-lsb': {}, + 'nightly-mips': {}, 'nightly-mips-lsb': {}, + 'nightly-multilib': {}, 'nightly-x32': {}, + 'nightly-ppc': {}, 'nightly-ppc-lsb': {}, + 'nightly-x86-64': {}, 'nightly-x86-64-lsb': {}, + 'nightly-x86': {}, 'nightly-x86-lsb': {}}, + 'schedulerNames_nowait' : {'build-appliance': {}, + 'eclipse-plugin-kepler': {}, 'eclipse-plugin-juno': {}, + 'nightly-non-gpl3': {}, 'nightly-oecore': {}, + 'nightly-world':{}, 'nightly-intel-gpl': {}, + 'poky-tiny': {}, 'buildtools': {}, + 'nightly-qa-systemd': {}, 'nightly-qa-extras': {}, + 'nightly-qa-logrotate': {}, 'nightly-qa-pam': {}, + 'nightly-qa-skeleton': {}}}}, {'PrepPkgIndex' : {}}, {'BuildImages': {'images': 'package-index'}}, {'CreateAutoConf': {'machine': 'atom-pc', 'SDKMACHINE' : 'x86_64',
lib/python2.7/site-packages/autobuilder/buildsteps/CreateAutoConf.py +2 -0
@@ -67,6 +67,8 @@ class CreateAutoConf(ShellCommand): fout = fout + 'PACKAGE_CLASSES = "' + " ".join(self.classes) + '"\n' else: fout = fout + 'PACKAGE_CLASSES = "package_rpm package_deb package_ipk"\n' + if self.getProperty("custom_prefered_kernel") is not None: + fout = fout + 'PREFERRED_PROVIDER_virtual/kernel = "' + self.getProperty("custom_prefered_kernel") +'"\n' fout = fout + 'BB_NUMBER_THREADS = "' + os.environ.get('BB_NUMBER_THREADS') + '"\n' fout = fout + 'PARALLEL_MAKE = "-j ' + os.environ.get('PARALLEL_MAKE') + '"\n' fout = fout + 'SDKMACHINE ?= "' + self.SDKMACHINE + '"\n'
lib/python2.7/site-packages/autobuilder/buildsteps/PublishLayerTarballs.py +15 -10
@@ -35,26 +35,31 @@ class PublishLayerTarballs(ShellCommand): DEST=self.getProperty("DEST") buildername=self.getProperty("buildername") revision = "" + self.basedir=os.path.join(os.path.join(os.path.join( + self.slavedir, buildername), self.workdir)) if str(os.environ.get('PUBLISH_BUILDS')) == "True": if self.getProperty("custom_release_me_"+buildername): - revision=self.getProperty("custom_release_name_"+buildername) + poky_name = self.getProperty("poky_name") + poky_number = self.getProperty("poky_number") + yocto_number = self.getProperty("yocto_number") + archive_name = self.layername + "-" + poky_name + "-" + poky_number + command = " git archive --format=tar HEAD " + command = command + "--prefix=" + archive_name + "/" + command = command + " | bzip2 -c > " + archive_name + ".tar.bz2; " + command = command + "md5sum " + archive_name + ".tar.bz2 >> " + command = command + self.layername + "-" + revision + ".tar.bz2.md5sum; " + command = command + "mkdir -p " + DEST + "; rsync -av " + command = command + archive_name +".tar.bz2* " + DEST elif self.getProperty("got_revision_"+self.layername): revision=self.getProperty("got_revision_"+self.layername) - if revision is not "": - self.basedir=os.path.join(os.path.join(os.path.join( - self.slavedir, buildername), self.workdir)) + archive_name = self.layername + "-" + revision command = " git archive --format=tar HEAD " command = command + "--prefix=" + self.layername + "-" + revision + "/" - command = command + " | gzip > " + self.layername + "-" + revision + ".tar.gz; " - command = command + " git archive --format=tar HEAD " - command = command + "--prefix=" + self.layername + "-" + revision + "/" command = command + " | bzip2 -c > " + self.layername + "-" + revision + ".tar.bz2; " command = command + "md5sum " + self.layername + "-" + revision + ".tar.bz2 >> " command = command + self.layername + "-" + revision + ".tar.bz2.md5sum; " - command = command + "md5sum " + self.layername + "-" + revision + ".tar.gz >> " - command = command + self.layername + "-" + revision + ".tar.gz.md5sum; " command = command + "mkdir -p " + DEST + "; rsync -av " - command = command + self.layername + "-" + revision +".tar.* " + DEST + command = command + archive_name +".tar.bz2* " + DEST self.command=command else: self.command="echo 'No revision found. Skipping tarball'"
Signature · 1 line
1.8.1.2
PATCH 11/27 trigger.py: Allow wait and nowait triggers
In reply to Elizabeth FlanaganFrom: Richard Purdie <[email protected]>
This is from RP. It's a little hacky, but gets around our broken parser.
Author: Richard Purdie <[email protected]>
--- .../buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py +13 -2
@@ -31,7 +31,7 @@ class Trigger(LoggingBuildStep): def __init__(self, schedulerNames=[], sourceStamp = None, sourceStamps = None, updateSourceStamp=None, alwaysUseLatest=False, waitForFinish=False, set_properties={}, - copy_properties=[], **kwargs): + copy_properties=[], noWait=[], **kwargs): if not schedulerNames: config.error( "You must specify a scheduler to trigger")
@@ -46,6 +46,7 @@ class Trigger(LoggingBuildStep): "You can't specify both alwaysUseLatest and updateSourceStamp" ) self.schedulerNames = schedulerNames + self.noWait = noWait self.sourceStamps = sourceStamps or [] if sourceStamp: self.sourceStamps.append(sourceStamp)
@@ -146,12 +147,22 @@ class Trigger(LoggingBuildStep): ss_for_trigger = self.prepareSourcestampListForTrigger() dl = [] + nowait = [] triggered_names = [] for sch in triggered_schedulers: - dl.append(sch.trigger(ss_for_trigger, set_props=props_to_set)) + if sch.name in self.noWait: + import time + time.sleep(5) + nowait.append(sch.trigger(ss_for_trigger, set_props=props_to_set)) + else: + dl.append(sch.trigger(ss_for_trigger, set_props=props_to_set)) triggered_names.append(sch.name) self.step_status.setText(['triggered'] + triggered_names) + for d in nowait: + d.addErrback(log.err, + '(ignored) while invoking Triggerable schedulers:') + if self.waitForFinish: rclist = yield defer.DeferredList(dl, consumeErrors=1) else:
Signature · 1 line
1.8.1.2
PATCH 13/27 yocto-start/stop-autobuilder: start buildslave-janitor
In reply to Elizabeth FlanaganFrom: Beth Flanagan <[email protected]>
This adds starting and stopping the buildslave janitor automatically.
--- yocto-start-autobuilder | 24 ++++++++++++++---------- yocto-stop-autobuilder | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 20 deletions(-)
yocto-start-autobuilder +14 -10
@@ -51,14 +51,14 @@ if os.path.isfile(os.path.join(AB_BASE, ".setupdone")): parser = SafeConfigParser() parser.read('config/autobuilder.conf') print - print "Reading " + os.path.join(AB_BASE, "conf/autobuilder.conf") + print "Reading " + os.path.join(AB_BASE, "config/autobuilder.conf") print os.environ["SLAVEBASEDIR"] = AB_BASE.strip('"') + "/yocto-slave" print ' Setting %s to %s' % ("SLAVEBASEDIR", AB_BASE + "/yocto-slave") for section_name in parser.sections(): for name, value in parser.items(section_name): print ' Setting %s to %s' % (name.upper(), value) - os.environ[name.upper()] = value.strip('"') + os.environ[name.upper()] = value.strip('"').strip("'") if os.environ[name.upper()].endswith("_DIR"): if not os.path.exists(value): try:
@@ -69,16 +69,20 @@ if os.path.isfile(os.path.join(AB_BASE, ".setupdone")): print if sys.argv[1] == "master" or sys.argv[1] == "both": - - os.chdir(os.path.join(AB_BASE, "yocto-master")) - subprocess.call(["make", "start"]) - os.chdir(AB_BASE) + os.chdir(os.path.join(AB_BASE, "yocto-master")) + subprocess.call(["make", "start"]) + os.chdir(AB_BASE) if sys.argv[1] == "slave" or sys.argv[1] == "both": - - os.chdir(os.path.join(AB_BASE, "yocto-slave")) - subprocess.call(["make", "start"]) - os.chdir(AB_BASE) + os.chdir(os.path.join(AB_BASE, "yocto-slave")) + subprocess.call(["make", "start"]) + os.chdir(AB_BASE) + if os.environ["OPTIMIZED_GIT_CLONE"] == "True": + os.chdir(AB_BASE) + subprocess.Popen("python bin/buildslave-janitor " + os.path.join(AB_BASE, "config/autobuilder.conf"), + shell=True, stdin=None, + stdout=None, stderr=None, + close_fds=True) else: print "You have not sourced ./yocto-autobuilder-setup. Please do so first!" print ""
yocto-stop-autobuilder +31 -10
53 lines not on this page · raw message
Signature · 1 line
1.8.1.2
PATCH 26/27 fs.py: Bump default timeout
In reply to Elizabeth Flanagan120 seconds is too little if we're doing a mv across filesystems.
--- .../buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/fs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/python2.7/site-packages/buildbot_slave-0.8.8-py2.7.egg/buildslave/commands/fs.py +2 -2
@@ -148,7 +148,7 @@ class CopyDirectory(base.Command): fromdir = os.path.join(self.builder.basedir, args['fromdir']) todir = os.path.join(self.builder.basedir, args['todir']) - self.timeout = args.get('timeout', 120) + self.timeout = args.get('timeout', 1200) self.maxTime = args.get('maxTime', None) if runtime.platformType != "posix":
@@ -197,7 +197,7 @@ class Move(base.Command): fromdir = os.path.join(self.builder.basedir, args['fromdir']) todir = args['todir'] - self.timeout = args.get('timeout', 120) + self.timeout = args.get('timeout', 1200) self.maxTime = args.get('maxTime', None) if runtime.platformType != "posix":
Signature · 1 line
1.8.1.2
Re: [AB PATCH 03/27] nightly-world-uclibc: uclibc target
In reply to Elizabeth FlanaganQuoted 3 lines · Elizabeth Flanagan
This should add a uclibc world build (which will probably have some issues at first)
yay ! thanks
Re: [AB PATCH 03/27] nightly-world-uclibc: uclibc target
Quoted 7 lines · Khem Raj
Quoted 3 lines · Elizabeth Flanagan
This should add a uclibc world build (which will probably have some issues at first)
yay ! thanks
Yes, it will have issues, I ran a world build a while ago for this bug:
https://bugzilla.yoctoproject.org/show_bug.cgi?id=5431
So we currently have some idea, we should add any new bugs to block this one.
Will this run nightly or as requested?
Sau!
Quoted 6 lines
_______________________________________________
yocto mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/yocto
Re: [AB PATCH 06/27] Autobuilder.py/Buildset.py: More sane parser/UI
In reply to Elizabeth FlanaganBeth,
Quoted 8 lines
-----Original Message-----
From: [email protected] [mailto:yocto- [email protected]] On Behalf Of Elizabeth Flanagan
Sent: Wednesday, March 05, 2014 1:23 PM
To: [email protected]
Subject: [yocto] [AB PATCH 06/27]Autobuilder.py/Buildset.py: More sane parser/UI
Quoted 6 lines
From: Beth Flanagan <[email protected]>
The parser for
Autobuilder.pydidn't dive very deep on triggered builds. If it found one, it just grabbed it's properties and then displayed them on the UI. This allowed us to mix and match repos/branches/commits.
I'm a little unclear what functionality is being removed. After this commit, are we still able to specify a different repo/branch/commit for each layer? Or was the previous functionality to mix and match repo/branch/commits within a layer? For example, would a buildset still be able to specify the repos as follows:
repos: [{'poky':
{'repourl':'git://git.yoctoproject.org/poky',
'branch':'dora'}},
{'meta-openembedded':
{'repourl':'git://git.openembedded.org/meta-openembedded',
'branch':'dora'}}]which have a different repository for each layer? Or do something like:
repos: [{'poky':
{'repourl':'git://git.yoctoproject.org/poky',
'branch':'dora'}},
{'meta-openembedded':
{'repourl':'git://git.openembedded.org/meta-openembedded',
'branch':'master'}}]to specify different branches for each layer? Granted, probably not a good idea for poky and meta-openembedded, but would be necessary for private layers that don't follow the same branch naming scheme.
And as you had stated this is a fairly large patchset with some interface changes. What are the plans (short-term and long-term) for the Autobuilder documentation? Is the plan just to update the README files, or are there plans to move toward an HTML document under http://www.yoctoproject.org/documentation? Either way, the Autobuilder documentation is pretty sparse and as an Autobuilder user I'm willing to extend the documentation. If there are specific sections you are looking to document first, let us know.
Thanks,
Bryan
Re: [AB PATCH 06/27] Autobuilder.py/Buildset.py: More sane parser/UI
Quoted 10 lines · Bryan Evenson
Beth,
Quoted 8 lines
-----Original Message-----
From: [email protected] [mailto:yocto- [email protected]] On Behalf Of Elizabeth Flanagan
Sent: Wednesday, March 05, 2014 1:23 PM
To: [email protected]
Subject: [yocto] [AB PATCH 06/27]Autobuilder.py/Buildset.py: More sane parser/UI
Quoted 8 lines
Quoted 6 lines
From: Beth Flanagan <[email protected]>
The parser for
Autobuilder.pydidn't dive very deep on triggered builds. If it found one, it just grabbed it's properties and then displayed them on the UI. This allowed us to mix and match repos/branches/commits.I'm a little unclear what functionality is being removed. After this commit, are we still able to specify a different repo/branch/commit for each layer?
Hi Bryan,
Yes, this doesn't effect that ability. What I call "mix and match" is what you'd see if you had a build that triggers other builds (like nightly.conf in buildsets.master). Prior to this patch, you would be able to set via the UI each individual repo/git hash/branch/tag that each of the triggered builds used. So, for example, your nightly could normally run master poky and trigger a build called nightly-next which would default to master-next. What mix and match allowed you to do is to override via the UI any of those repo source stamp attributes.
While that was an interesting thing, I wasn't really using it, it made the UI clunky and tbh, the parser was garbage to begin with. I had no ability to inherit the props of triggers of triggers, it was hard to read, hard to grok, and really needed a rewrite. So, during that rewrite, I ditched the "mix and match" bit, simplified the source variables (no more triggerer_nightly_triggered_commit_foo variables ;) ) and tried to make it a bit easier to understand.
Quoted 11 lines
Or was the previous functionality to mix and match repo/branch/commits within a layer? For example, would a buildset still be able to specify the repos as follows:
repos: [{'poky':
{'repourl':'git://git.yoctoproject.org/poky', 'branch':'dora'}}, {'meta-openembedded': {'repourl':'git://git.openembedded.org/meta-openembedded', 'branch':'dora'}}]which have a different repository for each layer? Or do something like:
repos: [{'poky':
Quoted 8 lines
{'repourl':'git://git.yoctoproject.org/poky', 'branch':'dora'}}, {'meta-openembedded': {'repourl':'git://git.openembedded.org/meta-openembedded', 'branch':'master'}}]to specify different branches for each layer? Granted, probably not a good idea for poky and meta-openembedded, but would be necessary for private layers that don't follow the same branch naming scheme.
Both are perfectly legitimate and these changes don't effect that ability at all.
Quoted 1 line
And as you had stated this is a fairly large patchset with some interface changes. What are the plans (short-term and long-term) for the Autobuilder documentation?
It's been on the list for a while, but, to be honest, it was only a year ago that the autobuilder refactor occurred and I wanted to see how we'd end up using it and what changes we'd need to make before we set things in stone. As it stands, we've made very few and minor changes over the past 6 months to the conf format, so I feel confident that we won't make many more major changes. The one place I see possibly making some changes is within TriggerBuilds (which we've already changed once). I'm not thrilled with how we're setting builder priority and I know there is a better way to do it (prioritizeBuilders or something?), I just haven't sat down and drawn it out yet.
Quoted 1 line
Is the plan just to update the README files, or are there plans to move toward an HTML document under http://www.yoctoproject.org/documentation? Either way, the Autobuilder documentation is pretty sparse and as an Autobuilder user I'm willing to extend the documentation. If there are specific sections you are looking to document first, let us know.
YES! I would love help documenting this, especially from an end user perspective. I know how *I* use the AB but how others do is somewhat of a black hole sometimes.
Generally, I think the most bang for the buck here is to documention:
- Quick start (how to get up and running and do basic config changes)
- buildset/*.conf documentation and config/autobuilder.conf documentation
- Buildstep class documentation
- Custom buildstep creation
With 1.6 fast approaching, I'd like to get this on the radar for 1.7.
Quoted 3 lines
Thanks,
Bryan
Signature · 3 lines
Elizabeth Flanagan Yocto Project Build and Release
Quoted 2 lines · Elizabeth Flanagan
Beth Flanagan (8):
PrepPkgIndex.py: ln instead of cp
This leaves several alternative lines that are commented out, why not just have the one working line?
Quoted 1 line
Autobuilder.py/Buildset.py: More sane parser/UI
Erm, yeah, sure. I'll take your word for that :)
Quoted 1 line
nightly.conf: Add additional parameters
This removes RunBitbakeSelfTest and needlessly reindents a large block.
Isn't the change to PublishLayerTarballs unrelated and therefore should be in a separate commit?
Quoted 1 line
CheckOutLayers.py/ResolveLayerHead.py: support simplified git
Ack.
Quoted 3 lines
Autobuilder.py: remove DEBUG codeBuildSet.py: Remove more debug code. yocto-start/stop-autobuilder: start buildslave-janitor
Ack x 3.
Quoted 1 line
forms.html/layout.html: support simplified UI
Ack.
Quoted 2 lines
Elizabeth Flanagan (12):
nightly-world-uclibc: uclibc target
Ack.
Quoted 1 line
SyncPersistDB.py: First run failure correction
Pretty sure you didn't mean -b there (block device).
Quoted 1 line
BuildSet.py: Set workdir based on layer not order
I'm not massively keen on special-casing poky/oe-core like this because it breaks when you use something that is almost but not quite poky (such as iot-devkit). Can this be an option that the buildset can set (and defaulting to something that mostly works)?
Also a better idiom is:
if layername in ('poky', 'oe-core', 'eclipse'):
pass
Quoted 1 line
yoctogit.py: fix callbacks and instance attrs
More hardcoding of repo names and behaviour. Again, does this mean that iot-devkit (a fork of poky) won't build in the autobuilder?
Quoted 4 lines
PublishArtifacts.py: Fix poky-tiny publishPublishArtifacts.py: genericx86-64 publishBuildEclipsePlugin.py: Change location of build.PublishArtifacts.py: Change where we find eclipse artifacts
Ack x 4
Quoted 1 line
yocto-autobuilder-setup: set the correct bb version
Might be useful to stop using bb (bitbake? buildbot?) and use the full name :)
Ack.
Quoted 1 line
fs.py: Bump default timeout
Ack.
Quoted 2 lines
autobuilder: whitespace removal
BuildSet.py: remove trailing spaces
Should be squashed.
Quoted 2 lines
Richard Purdie (5):
Add mirror functionality to git fetcher
Ack.
Quoted 1 line
trigger.py: Allow wait and nowait triggers
Ack.
Quoted 1 line
yoctogit: Don't use branch args for referenced clone
This also changes os.path.exists to self.pathExists which AFAICT have different uses (local vs remote). The commit should clarify this.
Quoted 1 line
bin/buildslave-janitor: For fast-git checkouts
Truncated commit message.
Quoted 1 line
yoctogit: Remove use of
oe.path.exists()
This commit doesn't actually remove a use of os.path.exists, so either the patch is incomplete or the message is misleading.
Quoted 2 lines
Stefan Stanacar (2):
buildsets: add a new buildset to run builds on target
Ack.
Quoted 1 line
Add buildstep and buildset for oe-selftest script
I'm a big fan of logically independent sequential patches as they make things a lot easier to review, so I'd say the change to CreateAutoConf should be split out as a separate commit. It's unrelated to the commit short message and only mentioned in passing in the long message.
Ross