diff options
Diffstat (limited to 'lib/toaster/bldcontrol/bbcontroller.py')
-rw-r--r-- | lib/toaster/bldcontrol/bbcontroller.py | 108 |
1 files changed, 93 insertions, 15 deletions
diff --git a/lib/toaster/bldcontrol/bbcontroller.py b/lib/toaster/bldcontrol/bbcontroller.py index c3beba96f..1e58c67fc 100644 --- a/lib/toaster/bldcontrol/bbcontroller.py +++ b/lib/toaster/bldcontrol/bbcontroller.py @@ -126,6 +126,8 @@ class BuildEnvironmentController(object): def setLayers(self,ls): """ Sets the layer variables in the config file, after validating local layer paths. The layer paths must be in a list of BRLayer object + + a word of attention: by convention, the first layer for any build will be poky! """ raise Exception("Must override setLayers") @@ -165,25 +167,31 @@ class BuildEnvironmentController(object): class ShellCmdException(Exception): pass + +class BuildSetupException(Exception): + pass + class LocalhostBEController(BuildEnvironmentController): """ Implementation of the BuildEnvironmentController for the localhost; this controller manages the default build directory, the server setup and system start and stop for the localhost-type build environment """ - from os.path import dirname as DN def __init__(self, be): super(LocalhostBEController, self).__init__(be) - from os.path import dirname as DN self.dburl = settings.getDATABASE_URL() + self.pokydirname = None + + def _shellcmd(self, command, cwd = None): + if cwd is None: + cwd = self.be.sourcedir - def _shellcmd(self, command): - p = subprocess.Popen(command, cwd=self.be.sourcedir, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p = subprocess.Popen(command, cwd = cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out,err) = p.communicate() if p.returncode: if len(err) == 0: - err = "command: %s" % command + err = "command: %s \n%s" % (command, out) else: err = "command: %s \n%s" % (command, err) raise ShellCmdException(err) @@ -191,22 +199,20 @@ class LocalhostBEController(BuildEnvironmentController): return out def _createdirpath(self, path): + from os.path import dirname as DN if not os.path.exists(DN(path)): self._createdirpath(DN(path)) if not os.path.exists(path): os.mkdir(path, 0755) def _startBE(self): - assert self.be.sourcedir and os.path.exists(self.be.sourcedir) + assert self.pokydirname and os.path.exists(self.pokydirname) self._createdirpath(self.be.builddir) - self._shellcmd("bash -c \"source %s/oe-init-build-env %s\"" % (self.be.sourcedir, self.be.builddir)) + self._shellcmd("bash -c \"source %s/oe-init-build-env %s\"" % (self.pokydirname, self.be.builddir)) def startBBServer(self): - assert self.be.sourcedir and os.path.exists(self.be.sourcedir) - - self._startBE() - - print self._shellcmd("bash -c \"source %s/oe-init-build-env %s && DATABASE_URL=%s source toaster start noweb && sleep 1\"" % (self.be.sourcedir, self.be.builddir, self.dburl)) + assert self.pokydirname and os.path.exists(self.pokydirname) + print self._shellcmd("bash -c \"source %s/oe-init-build-env %s && DATABASE_URL=%s source toaster start noweb && sleep 1\"" % (self.pokydirname, self.be.builddir, self.dburl)) # FIXME unfortunate sleep 1 - we need to make sure that bbserver is started and the toaster ui is connected # but since they start async without any return, we just wait a bit print "Started server" @@ -225,10 +231,82 @@ class LocalhostBEController(BuildEnvironmentController): print "Stopped server" def setLayers(self, layers): + """ a word of attention: by convention, the first layer for any build will be poky! """ + assert self.be.sourcedir is not None - layerconf = os.path.join(self.be.builddir, "conf/bblayers.conf") - if not os.path.exists(layerconf): - raise Exception("BE is not consistent: bblayers.conf file missing at ", layerconf) + # set layers in the layersource + + # 1. get a list of repos, and map dirpaths for each layer + gitrepos = {} + for layer in layers: + if not layer.giturl in gitrepos: + gitrepos[layer.giturl] = [] + gitrepos[layer.giturl].append( (layer.name, layer.dirpath, layer.commit)) + for giturl in gitrepos.keys(): + commitid = gitrepos[giturl][0][2] + for e in gitrepos[giturl]: + if commitid != e[2]: + raise BuildSetupException("More than one commit per git url, unsupported configuration") + + def _getgitdirectoryname(url): + import re + components = re.split(r'[\.\/]', url) + return components[-2] if components[-1] == "git" else components[-1] + + layerlist = [] + + # 2. checkout the repositories + for giturl in gitrepos.keys(): + localdirname = os.path.join(self.be.sourcedir, _getgitdirectoryname(giturl)) + print "DEBUG: giturl checking out in current directory", localdirname + + # make sure our directory is a git repository + if os.path.exists(localdirname): + if not giturl in self._shellcmd("git remote -v", localdirname): + raise BuildSetupException("Existing git repository at %s, but with different remotes (not '%s'). Aborting." % (localdirname, giturl)) + else: + self._shellcmd("git clone \"%s\" \"%s\"" % (giturl, localdirname)) + # checkout the needed commit + commit = gitrepos[giturl][0][2] + self._shellcmd("git fetch --all && git checkout \"%s\"" % commit , localdirname) + print "DEBUG: checked out commit ", commit, "to", localdirname + + # if this is the first checkout, take the localdirname as poky dir + if self.pokydirname is None: + print "DEBUG: selected poky dir name", localdirname + self.pokydirname = localdirname + + # verify our repositories + for name, dirpath, commit in gitrepos[giturl]: + localdirpath = os.path.join(localdirname, dirpath) + if not os.path.exists(localdirpath): + raise BuildSetupException("Cannot find layer git path '%s' in checked out repository '%s:%s'. Aborting." % (localdirpath, giturl, commit)) + + layerlist.append(localdirpath) + + print "DEBUG: current layer list ", layerlist + + # 3. configure the build environment, so we have a conf/bblayers.conf + assert self.pokydirname is not None + self._startBE() + + # 4. update the bblayers.conf + bblayerconf = os.path.join(self.be.builddir, "conf/bblayers.conf") + if not os.path.exists(bblayerconf): + raise BuildSetupException("BE is not consistent: bblayers.conf file missing at %s" % bblayerconf) + + conflines = open(bblayerconf, "r").readlines() + + bblayerconffile = open(bblayerconf, "w") + for i in xrange(len(conflines)): + if conflines[i].startswith("# line added by toaster"): + i += 2 + else: + bblayerconffile.write(conflines[i]) + + bblayerconffile.write("\n# line added by toaster build control\nBBLAYERS = \"" + " ".join(layerlist) + "\"") + bblayerconffile.close() + return True def release(self): |