diff options
Diffstat (limited to 'yocto-poky/bitbake/lib/toaster/bldcontrol/sshbecontroller.py')
-rw-r--r-- | yocto-poky/bitbake/lib/toaster/bldcontrol/sshbecontroller.py | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/yocto-poky/bitbake/lib/toaster/bldcontrol/sshbecontroller.py b/yocto-poky/bitbake/lib/toaster/bldcontrol/sshbecontroller.py new file mode 100644 index 0000000000..8ef434baf5 --- /dev/null +++ b/yocto-poky/bitbake/lib/toaster/bldcontrol/sshbecontroller.py @@ -0,0 +1,179 @@ +# +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +# +# BitBake Toaster Implementation +# +# Copyright (C) 2014 Intel Corporation +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +import sys +import re +from django.db import transaction +from django.db.models import Q +from bldcontrol.models import BuildEnvironment, BRLayer, BRVariable, BRTarget, BRBitbake +import subprocess + +from toastermain import settings + +from bbcontroller import BuildEnvironmentController, ShellCmdException, BuildSetupException + +class NotImplementedException(Exception): + pass + +def DN(path): + return "/".join(path.split("/")[0:-1]) + +class SSHBEController(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 + + """ + + def __init__(self, be): + super(SSHBEController, self).__init__(be) + self.dburl = settings.getDATABASE_URL() + self.pokydirname = None + self.islayerset = False + + def _shellcmd(self, command, cwd = None): + if cwd is None: + cwd = self.be.sourcedir + + p = subprocess.Popen("ssh %s 'cd %s && %s'" % (self.be.address, cwd, command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + (out,err) = p.communicate() + if p.returncode: + if len(err) == 0: + err = "command: %s \n%s" % (command, out) + else: + err = "command: %s \n%s" % (command, err) + raise ShellCmdException(err) + else: + return out.strip() + + def _pathexists(self, path): + try: + self._shellcmd("test -e \"%s\"" % path) + return True + except ShellCmdException as e: + return False + + def _pathcreate(self, path): + self._shellcmd("mkdir -p \"%s\"" % path) + + def _setupBE(self): + assert self.pokydirname and self._pathexists(self.pokydirname) + self._pathcreate(self.be.builddir) + self._shellcmd("bash -c \"source %s/oe-init-build-env %s\"" % (self.pokydirname, self.be.builddir)) + + def startBBServer(self, brbe): + assert self.pokydirname and self._pathexists(self.pokydirname) + assert self.islayerset + cmd = self._shellcmd("bash -c \"source %s/oe-init-build-env %s && DATABASE_URL=%s source toaster start noweb brbe=%s\"" % (self.pokydirname, self.be.builddir, self.dburl, brbe)) + + port = "-1" + for i in cmd.split("\n"): + if i.startswith("Bitbake server address"): + port = i.split(" ")[-1] + print "Found bitbake server port ", port + + + assert self.be.sourcedir and self._pathexists(self.be.builddir) + self.be.bbaddress = self.be.address.split("@")[-1] + self.be.bbport = port + self.be.bbstate = BuildEnvironment.SERVER_STARTED + self.be.save() + + def stopBBServer(self): + assert self.pokydirname and self._pathexists(self.pokydirname) + assert self.islayerset + print self._shellcmd("bash -c \"source %s/oe-init-build-env %s && %s source toaster stop\"" % + (self.pokydirname, self.be.builddir, (lambda: "" if self.be.bbtoken is None else "BBTOKEN=%s" % self.be.bbtoken)())) + self.be.bbstate = BuildEnvironment.SERVER_STOPPED + self.be.save() + print "Stopped server" + + + def _copyFile(self, filepath1, filepath2): + p = subprocess.Popen("scp '%s' '%s'" % (filepath1, filepath2), stdout=subprocess.PIPE, stderr = subprocess.PIPE, shell=True) + (out, err) = p.communicate() + if p.returncode: + raise ShellCmdException(err) + + def pullFile(self, local_filename, remote_filename): + _copyFile(local_filename, "%s:%s" % (self.be.address, remote_filename)) + + def pushFile(self, local_filename, remote_filename): + _copyFile("%s:%s" % (self.be.address, remote_filename), local_filename) + + def setLayers(self, bitbakes, layers): + """ a word of attention: by convention, the first layer for any build will be poky! """ + + assert self.be.sourcedir is not None + assert len(bitbakes) == 1 + # set layers in the layersource + + + raise NotImplementedException("Not implemented: SSH setLayers") + # 3. configure the build environment, so we have a conf/bblayers.conf + assert self.pokydirname is not None + self._setupBE() + + # 4. update the bblayers.conf + bblayerconf = os.path.join(self.be.builddir, "conf/bblayers.conf") + if not self._pathexists(bblayerconf): + raise BuildSetupException("BE is not consistent: bblayers.conf file missing at %s" % bblayerconf) + + import uuid + local_bblayerconf = "/tmp/" + uuid.uuid4() + "-bblayer.conf" + + self.pullFile(bblayerconf, local_bblayerconf) + + BuildEnvironmentController._updateBBLayers(local_bblayerconf, layerlist) + self.pushFile(local_bblayerconf, bblayerconf) + + os.unlink(local_bblayerconf) + + self.islayerset = True + return True + + def release(self): + assert self.be.sourcedir and self._pathexists(self.be.builddir) + import shutil + shutil.rmtree(os.path.join(self.be.sourcedir, "build")) + assert not self._pathexists(self.be.builddir) + + def triggerBuild(self, bitbake, layers, variables, targets): + # set up the buid environment with the needed layers + self.setLayers(bitbake, layers) + self.writeConfFile("conf/toaster-pre.conf", ) + self.writeConfFile("conf/toaster.conf", raw = "INHERIT+=\"toaster buildhistory\"") + + # get the bb server running with the build req id and build env id + bbctrl = self.getBBController() + + # trigger the build command + task = reduce(lambda x, y: x if len(y)== 0 else y, map(lambda y: y.task, targets)) + if len(task) == 0: + task = None + + bbctrl.build(list(map(lambda x:x.target, targets)), task) + + logger.debug("localhostbecontroller: Build launched, exiting. Follow build logs at %s/toaster_ui.log" % self.be.builddir) + + # disconnect from the server + bbctrl.disconnect() |