diff options
Diffstat (limited to 'bitbake/lib/toaster/bldcontrol/bbcontroller.py')
| -rw-r--r-- | bitbake/lib/toaster/bldcontrol/bbcontroller.py | 108 |
1 files changed, 93 insertions, 15 deletions
diff --git a/bitbake/lib/toaster/bldcontrol/bbcontroller.py b/bitbake/lib/toaster/bldcontrol/bbcontroller.py index c3beba96f0..1e58c67fcd 100644 --- a/bitbake/lib/toaster/bldcontrol/bbcontroller.py +++ b/bitbake/lib/toaster/bldcontrol/bbcontroller.py | |||
| @@ -126,6 +126,8 @@ class BuildEnvironmentController(object): | |||
| 126 | def setLayers(self,ls): | 126 | def setLayers(self,ls): |
| 127 | """ Sets the layer variables in the config file, after validating local layer paths. | 127 | """ Sets the layer variables in the config file, after validating local layer paths. |
| 128 | The layer paths must be in a list of BRLayer object | 128 | The layer paths must be in a list of BRLayer object |
| 129 | |||
| 130 | a word of attention: by convention, the first layer for any build will be poky! | ||
| 129 | """ | 131 | """ |
| 130 | raise Exception("Must override setLayers") | 132 | raise Exception("Must override setLayers") |
| 131 | 133 | ||
| @@ -165,25 +167,31 @@ class BuildEnvironmentController(object): | |||
| 165 | class ShellCmdException(Exception): | 167 | class ShellCmdException(Exception): |
| 166 | pass | 168 | pass |
| 167 | 169 | ||
| 170 | |||
| 171 | class BuildSetupException(Exception): | ||
| 172 | pass | ||
| 173 | |||
| 168 | class LocalhostBEController(BuildEnvironmentController): | 174 | class LocalhostBEController(BuildEnvironmentController): |
| 169 | """ Implementation of the BuildEnvironmentController for the localhost; | 175 | """ Implementation of the BuildEnvironmentController for the localhost; |
| 170 | this controller manages the default build directory, | 176 | this controller manages the default build directory, |
| 171 | the server setup and system start and stop for the localhost-type build environment | 177 | the server setup and system start and stop for the localhost-type build environment |
| 172 | 178 | ||
| 173 | """ | 179 | """ |
| 174 | from os.path import dirname as DN | ||
| 175 | 180 | ||
| 176 | def __init__(self, be): | 181 | def __init__(self, be): |
| 177 | super(LocalhostBEController, self).__init__(be) | 182 | super(LocalhostBEController, self).__init__(be) |
| 178 | from os.path import dirname as DN | ||
| 179 | self.dburl = settings.getDATABASE_URL() | 183 | self.dburl = settings.getDATABASE_URL() |
| 184 | self.pokydirname = None | ||
| 185 | |||
| 186 | def _shellcmd(self, command, cwd = None): | ||
| 187 | if cwd is None: | ||
| 188 | cwd = self.be.sourcedir | ||
| 180 | 189 | ||
| 181 | def _shellcmd(self, command): | 190 | p = subprocess.Popen(command, cwd = cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 182 | p = subprocess.Popen(command, cwd=self.be.sourcedir, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
| 183 | (out,err) = p.communicate() | 191 | (out,err) = p.communicate() |
| 184 | if p.returncode: | 192 | if p.returncode: |
| 185 | if len(err) == 0: | 193 | if len(err) == 0: |
| 186 | err = "command: %s" % command | 194 | err = "command: %s \n%s" % (command, out) |
| 187 | else: | 195 | else: |
| 188 | err = "command: %s \n%s" % (command, err) | 196 | err = "command: %s \n%s" % (command, err) |
| 189 | raise ShellCmdException(err) | 197 | raise ShellCmdException(err) |
| @@ -191,22 +199,20 @@ class LocalhostBEController(BuildEnvironmentController): | |||
| 191 | return out | 199 | return out |
| 192 | 200 | ||
| 193 | def _createdirpath(self, path): | 201 | def _createdirpath(self, path): |
| 202 | from os.path import dirname as DN | ||
| 194 | if not os.path.exists(DN(path)): | 203 | if not os.path.exists(DN(path)): |
| 195 | self._createdirpath(DN(path)) | 204 | self._createdirpath(DN(path)) |
| 196 | if not os.path.exists(path): | 205 | if not os.path.exists(path): |
| 197 | os.mkdir(path, 0755) | 206 | os.mkdir(path, 0755) |
| 198 | 207 | ||
| 199 | def _startBE(self): | 208 | def _startBE(self): |
| 200 | assert self.be.sourcedir and os.path.exists(self.be.sourcedir) | 209 | assert self.pokydirname and os.path.exists(self.pokydirname) |
| 201 | self._createdirpath(self.be.builddir) | 210 | self._createdirpath(self.be.builddir) |
| 202 | self._shellcmd("bash -c \"source %s/oe-init-build-env %s\"" % (self.be.sourcedir, self.be.builddir)) | 211 | self._shellcmd("bash -c \"source %s/oe-init-build-env %s\"" % (self.pokydirname, self.be.builddir)) |
| 203 | 212 | ||
| 204 | def startBBServer(self): | 213 | def startBBServer(self): |
| 205 | assert self.be.sourcedir and os.path.exists(self.be.sourcedir) | 214 | assert self.pokydirname and os.path.exists(self.pokydirname) |
| 206 | 215 | 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)) | |
| 207 | self._startBE() | ||
| 208 | |||
| 209 | 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)) | ||
| 210 | # FIXME unfortunate sleep 1 - we need to make sure that bbserver is started and the toaster ui is connected | 216 | # FIXME unfortunate sleep 1 - we need to make sure that bbserver is started and the toaster ui is connected |
| 211 | # but since they start async without any return, we just wait a bit | 217 | # but since they start async without any return, we just wait a bit |
| 212 | print "Started server" | 218 | print "Started server" |
| @@ -225,10 +231,82 @@ class LocalhostBEController(BuildEnvironmentController): | |||
| 225 | print "Stopped server" | 231 | print "Stopped server" |
| 226 | 232 | ||
| 227 | def setLayers(self, layers): | 233 | def setLayers(self, layers): |
| 234 | """ a word of attention: by convention, the first layer for any build will be poky! """ | ||
| 235 | |||
| 228 | assert self.be.sourcedir is not None | 236 | assert self.be.sourcedir is not None |
| 229 | layerconf = os.path.join(self.be.builddir, "conf/bblayers.conf") | 237 | # set layers in the layersource |
| 230 | if not os.path.exists(layerconf): | 238 | |
| 231 | raise Exception("BE is not consistent: bblayers.conf file missing at ", layerconf) | 239 | # 1. get a list of repos, and map dirpaths for each layer |
| 240 | gitrepos = {} | ||
| 241 | for layer in layers: | ||
| 242 | if not layer.giturl in gitrepos: | ||
| 243 | gitrepos[layer.giturl] = [] | ||
| 244 | gitrepos[layer.giturl].append( (layer.name, layer.dirpath, layer.commit)) | ||
| 245 | for giturl in gitrepos.keys(): | ||
| 246 | commitid = gitrepos[giturl][0][2] | ||
| 247 | for e in gitrepos[giturl]: | ||
| 248 | if commitid != e[2]: | ||
| 249 | raise BuildSetupException("More than one commit per git url, unsupported configuration") | ||
| 250 | |||
| 251 | def _getgitdirectoryname(url): | ||
| 252 | import re | ||
| 253 | components = re.split(r'[\.\/]', url) | ||
| 254 | return components[-2] if components[-1] == "git" else components[-1] | ||
| 255 | |||
| 256 | layerlist = [] | ||
| 257 | |||
| 258 | # 2. checkout the repositories | ||
| 259 | for giturl in gitrepos.keys(): | ||
| 260 | localdirname = os.path.join(self.be.sourcedir, _getgitdirectoryname(giturl)) | ||
| 261 | print "DEBUG: giturl checking out in current directory", localdirname | ||
| 262 | |||
| 263 | # make sure our directory is a git repository | ||
| 264 | if os.path.exists(localdirname): | ||
| 265 | if not giturl in self._shellcmd("git remote -v", localdirname): | ||
| 266 | raise BuildSetupException("Existing git repository at %s, but with different remotes (not '%s'). Aborting." % (localdirname, giturl)) | ||
| 267 | else: | ||
| 268 | self._shellcmd("git clone \"%s\" \"%s\"" % (giturl, localdirname)) | ||
| 269 | # checkout the needed commit | ||
| 270 | commit = gitrepos[giturl][0][2] | ||
| 271 | self._shellcmd("git fetch --all && git checkout \"%s\"" % commit , localdirname) | ||
| 272 | print "DEBUG: checked out commit ", commit, "to", localdirname | ||
| 273 | |||
| 274 | # if this is the first checkout, take the localdirname as poky dir | ||
| 275 | if self.pokydirname is None: | ||
| 276 | print "DEBUG: selected poky dir name", localdirname | ||
| 277 | self.pokydirname = localdirname | ||
| 278 | |||
| 279 | # verify our repositories | ||
| 280 | for name, dirpath, commit in gitrepos[giturl]: | ||
| 281 | localdirpath = os.path.join(localdirname, dirpath) | ||
| 282 | if not os.path.exists(localdirpath): | ||
| 283 | raise BuildSetupException("Cannot find layer git path '%s' in checked out repository '%s:%s'. Aborting." % (localdirpath, giturl, commit)) | ||
| 284 | |||
| 285 | layerlist.append(localdirpath) | ||
| 286 | |||
| 287 | print "DEBUG: current layer list ", layerlist | ||
| 288 | |||
| 289 | # 3. configure the build environment, so we have a conf/bblayers.conf | ||
| 290 | assert self.pokydirname is not None | ||
| 291 | self._startBE() | ||
| 292 | |||
| 293 | # 4. update the bblayers.conf | ||
| 294 | bblayerconf = os.path.join(self.be.builddir, "conf/bblayers.conf") | ||
| 295 | if not os.path.exists(bblayerconf): | ||
| 296 | raise BuildSetupException("BE is not consistent: bblayers.conf file missing at %s" % bblayerconf) | ||
| 297 | |||
| 298 | conflines = open(bblayerconf, "r").readlines() | ||
| 299 | |||
| 300 | bblayerconffile = open(bblayerconf, "w") | ||
| 301 | for i in xrange(len(conflines)): | ||
| 302 | if conflines[i].startswith("# line added by toaster"): | ||
| 303 | i += 2 | ||
| 304 | else: | ||
| 305 | bblayerconffile.write(conflines[i]) | ||
| 306 | |||
| 307 | bblayerconffile.write("\n# line added by toaster build control\nBBLAYERS = \"" + " ".join(layerlist) + "\"") | ||
| 308 | bblayerconffile.close() | ||
| 309 | |||
| 232 | return True | 310 | return True |
| 233 | 311 | ||
| 234 | def release(self): | 312 | def release(self): |
