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): |