Skip to contentSkip to conversation

Autobuilder patches

PATCH In review Elizabeth Flanagan 5 participants 33 messages Mar 5, 2014 – Mar 11, 2014

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

PATCH 1/27 buildsets: add a new buildset to run builds on target

From: 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
new file mode 100644
index 0000000..a95db78
@@ -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
#2 lore raw

PATCH 2/27 Add buildstep and buildset for oe-selftest script

In reply to Elizabeth Flanagan

From: 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
new file mode 100644
index 0000000..42bccde
@@ -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
index 116ee14..bec221a 100644
@@ -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
new file mode 100644
index 0000000..0efddd7
@@ -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
#3 lore raw

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
new file mode 100644
index 0000000..533bba6
@@ -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
#4 lore raw

Re: [AB PATCH 03/27] nightly-world-uclibc: uclibc target

Quoted 3 lines · Elizabeth Flanagan

This should add a uclibc world build (which will probably have some issues at first)

yay ! thanks

#5 lore raw

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

#6 lore raw

PATCH 4/27 PrepPkgIndex.py: ln instead of cp

In reply to Elizabeth Flanagan

From: 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
index 3b2591e..1b41927 100644
@@ -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
#7 lore raw

PATCH 5/27 Add mirror functionality to git fetcher

In reply to Elizabeth Flanagan

From: 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
index 4626e02..d73f278 100644
@@ -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
index 7d06d06..25c3b4d 100644
@@ -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
index 191dc3f..2ffb3b2 100644
@@ -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
index 7c95d2d..93ce805 100644
@@ -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
#8 lore raw

PATCH 6/27 Autobuilder.py/Buildset.py: More sane parser/UI

In reply to Elizabeth Flanagan

From: 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
index e2aec21..c6c4bc0 100644
@@ -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
#9 lore raw

Re: [AB PATCH 06/27] Autobuilder.py/Buildset.py: More sane parser/UI

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 6 lines

From: 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.

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

#10 lore raw

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.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.

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
#11 lore raw

PATCH 7/27 nightly.conf: Add additional parameters

In reply to Elizabeth Flanagan

From: 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
index 1ecd982..085c25f 100644
@@ -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
index bec221a..73cf4a6 100644
@@ -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
index 14b7deb..c73fd29 100644
@@ -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
#12 lore raw

PATCH 8/27 CheckOutLayers.py/ResolveLayerHead.py: support simplified git

In reply to Elizabeth Flanagan

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
index 2ffb3b2..d56143b 100644
@@ -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
index c1c6605..88b12bf 100644
@@ -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
#13 lore raw

PATCH 9/27 Autobuilder.py: remove DEBUG code

In reply to Elizabeth Flanagan

From: 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
index c6c4bc0..5d7ff7c 100644
@@ -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
#14 lore raw

PATCH 10/27 BuildSet.py: Remove more debug code.

In reply to Elizabeth Flanagan

From: 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
index c913e93..7973a23 100644
@@ -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
#15 lore raw

PATCH 11/27 trigger.py: Allow wait and nowait triggers

In reply to Elizabeth Flanagan

From: 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
index a375df6..f23f708 100644
@@ -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
#16 lore raw

PATCH 12/27 yoctogit: Don't use branch args for referenced clone

In reply to Elizabeth Flanagan

From: 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
index 93ce805..446631d 100644
@@ -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
#17 lore raw

PATCH 13/27 yocto-start/stop-autobuilder: start buildslave-janitor

In reply to Elizabeth Flanagan

From: 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
index 0998ee3..b34a60d 100755
@@ -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
#18 lore raw

PATCH 14/27 bin/buildslave-janitor: For fast-git checkouts

In reply to Elizabeth Flanagan

From: 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
new file mode 100755
index 0000000..153f18d
@@ -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
#19 lore raw

PATCH 15/27 forms.html/layout.html: support simplified UI

In reply to Elizabeth Flanagan

From: 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
index d006bab..32779ae 100644
@@ -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
index 178c809..01dfb80 100644
@@ -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
#20 lore raw

PATCH 16/27 SyncPersistDB.py: First run failure correction

In reply to Elizabeth Flanagan

persistdb 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
index 8fa7768..68e887f 100644
@@ -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
#21 lore raw

PATCH 17/27 BuildSet.py: Set workdir based on layer not order

In reply to Elizabeth Flanagan

workdir 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
index 7973a23..19fbb00 100644
@@ -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
#22 lore raw

PATCH 18/27 yoctogit: Remove use of oe.path.exists()

In reply to Elizabeth Flanagan

From: 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
index 446631d..64dfe06 100644
@@ -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
#23 lore raw

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
index 19fbb00..6d318eb 100644
@@ -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
#24 lore raw

PATCH 20/27 yoctogit.py: fix callbacks and instance attrs

In reply to Elizabeth Flanagan

The 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
index 64dfe06..26599e7 100644
@@ -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
#25 lore raw

PATCH 21/27 PublishArtifacts.py: Fix poky-tiny publish

In reply to Elizabeth Flanagan

There 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
index 38f1980..1967b42 100644
@@ -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
#26 lore raw

PATCH 22/27 PublishArtifacts.py: genericx86-64 publish

In reply to Elizabeth Flanagan

genericx86_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
index 1967b42..b7dc680 100644
@@ -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
#27 lore raw

PATCH 23/27 BuildEclipsePlugin.py: Change location of build.

In reply to Elizabeth Flanagan

Now 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
index bc5d9b3..c06f569 100644
@@ -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
#28 lore raw

PATCH 24/27 PublishArtifacts.py: Change where we find eclipse artifacts

In reply to Elizabeth Flanagan

Now 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
index b7dc680..00f6852 100644
@@ -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
#29 lore raw

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
index 227d5f6..69c1e83 100644
@@ -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
#30 lore raw

PATCH 26/27 fs.py: Bump default timeout

In reply to Elizabeth Flanagan

120 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
index 3e01568..ae720cd 100644
@@ -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
#31 lore raw

PATCH 27/27 autobuilder: whitespace removal

In reply to Elizabeth Flanagan

sed --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
index 5d7ff7c..4c33489 100644
@@ -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
index 6d318eb..e5a9d5d 100644
@@ -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
index c06f569..c437cd4 100644
@@ -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
index 02d9b28..9ffc320 100644
@@ -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
index d56143b..90b90c5 100644
@@ -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
index 73cf4a6..95180d4 100644
@@ -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
index 1ee5261..23b594b 100644
@@ -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
index ff9b9f5..fab1008 100644
@@ -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
index 40f5ce3..2b0e4e7 100644
@@ -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
index 8482090..3d4f314 100644
@@ -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
index 6c0161d..1e2070a 100644
@@ -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
index 9a025ff..32de5cb 100644
@@ -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
index 8975857..c52cec9 100644
@@ -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
index 1b41927..ce773d1 100644
@@ -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
index 00f6852..e23ecbf 100644
@@ -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
index c73fd29..b9484e7 100644
@@ -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
index 88b12bf..c9ca9ad 100644
@@ -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
index a7d1a03..c1dd13a 100644
@@ -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
index 3063bb2..cf901cb 100644
@@ -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
index d416f4b..50ac9ec 100644
@@ -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
index 68e887f..78c5abc 100644
@@ -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
index a57f6bb..f0134a9 100644
@@ -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
index 92e1f0b..1b8de27 100644
@@ -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
#32 lore raw
In reply to Elizabeth Flanagan
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 code BuildSet.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 publish PublishArtifacts.py: genericx86-64 publish BuildEclipsePlugin.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