summaryrefslogtreecommitdiffstats
path: root/lib/toaster/bldcontrol/bbcontroller.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/toaster/bldcontrol/bbcontroller.py')
-rw-r--r--lib/toaster/bldcontrol/bbcontroller.py108
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):