1*eb8dc403SDave Cobbley#
2*eb8dc403SDave Cobbley# ex:ts=4:sw=4:sts=4:et
3*eb8dc403SDave Cobbley# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4*eb8dc403SDave Cobbley#
5*eb8dc403SDave Cobbley# BitBake Toaster Implementation
6*eb8dc403SDave Cobbley#
7*eb8dc403SDave Cobbley# Copyright (C) 2014        Intel Corporation
8*eb8dc403SDave Cobbley#
9*eb8dc403SDave Cobbley# This program is free software; you can redistribute it and/or modify
10*eb8dc403SDave Cobbley# it under the terms of the GNU General Public License version 2 as
11*eb8dc403SDave Cobbley# published by the Free Software Foundation.
12*eb8dc403SDave Cobbley#
13*eb8dc403SDave Cobbley# This program is distributed in the hope that it will be useful,
14*eb8dc403SDave Cobbley# but WITHOUT ANY WARRANTY; without even the implied warranty of
15*eb8dc403SDave Cobbley# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*eb8dc403SDave Cobbley# GNU General Public License for more details.
17*eb8dc403SDave Cobbley#
18*eb8dc403SDave Cobbley# You should have received a copy of the GNU General Public License along
19*eb8dc403SDave Cobbley# with this program; if not, write to the Free Software Foundation, Inc.,
20*eb8dc403SDave Cobbley# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21*eb8dc403SDave Cobbley
22*eb8dc403SDave Cobbley
23*eb8dc403SDave Cobbleyimport os
24*eb8dc403SDave Cobbleyimport sys
25*eb8dc403SDave Cobbleyimport re
26*eb8dc403SDave Cobbleyfrom django.db import transaction
27*eb8dc403SDave Cobbleyfrom django.db.models import Q
28*eb8dc403SDave Cobbleyfrom bldcontrol.models import BuildEnvironment, BRLayer, BRVariable, BRTarget, BRBitbake
29*eb8dc403SDave Cobbley
30*eb8dc403SDave Cobbley# load Bitbake components
31*eb8dc403SDave Cobbleypath = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
32*eb8dc403SDave Cobbleysys.path.insert(0, path)
33*eb8dc403SDave Cobbley
34*eb8dc403SDave Cobbleyclass BitbakeController(object):
35*eb8dc403SDave Cobbley    """ This is the basic class that controlls a bitbake server.
36*eb8dc403SDave Cobbley        It is outside the scope of this class on how the server is started and aquired
37*eb8dc403SDave Cobbley    """
38*eb8dc403SDave Cobbley
39*eb8dc403SDave Cobbley    def __init__(self, be):
40*eb8dc403SDave Cobbley        import bb.server.xmlrpcclient
41*eb8dc403SDave Cobbley        self.connection = bb.server.xmlrpcclient._create_server(be.bbaddress,
42*eb8dc403SDave Cobbley                                                          int(be.bbport))[0]
43*eb8dc403SDave Cobbley
44*eb8dc403SDave Cobbley    def _runCommand(self, command):
45*eb8dc403SDave Cobbley        result, error = self.connection.runCommand(command)
46*eb8dc403SDave Cobbley        if error:
47*eb8dc403SDave Cobbley            raise Exception(error)
48*eb8dc403SDave Cobbley        return result
49*eb8dc403SDave Cobbley
50*eb8dc403SDave Cobbley    def disconnect(self):
51*eb8dc403SDave Cobbley        return self.connection.removeClient()
52*eb8dc403SDave Cobbley
53*eb8dc403SDave Cobbley    def setVariable(self, name, value):
54*eb8dc403SDave Cobbley        return self._runCommand(["setVariable", name, value])
55*eb8dc403SDave Cobbley
56*eb8dc403SDave Cobbley    def getVariable(self, name):
57*eb8dc403SDave Cobbley        return self._runCommand(["getVariable", name])
58*eb8dc403SDave Cobbley
59*eb8dc403SDave Cobbley    def triggerEvent(self, event):
60*eb8dc403SDave Cobbley        return self._runCommand(["triggerEvent", event])
61*eb8dc403SDave Cobbley
62*eb8dc403SDave Cobbley    def build(self, targets, task = None):
63*eb8dc403SDave Cobbley        if task is None:
64*eb8dc403SDave Cobbley            task = "build"
65*eb8dc403SDave Cobbley        return self._runCommand(["buildTargets", targets, task])
66*eb8dc403SDave Cobbley
67*eb8dc403SDave Cobbley    def forceShutDown(self):
68*eb8dc403SDave Cobbley        return self._runCommand(["stateForceShutdown"])
69*eb8dc403SDave Cobbley
70*eb8dc403SDave Cobbley
71*eb8dc403SDave Cobbley
72*eb8dc403SDave Cobbleydef getBuildEnvironmentController(**kwargs):
73*eb8dc403SDave Cobbley    """ Gets you a BuildEnvironmentController that encapsulates a build environment,
74*eb8dc403SDave Cobbley        based on the query dictionary sent in.
75*eb8dc403SDave Cobbley
76*eb8dc403SDave Cobbley        This is used to retrieve, for example, the currently running BE from inside
77*eb8dc403SDave Cobbley        the toaster UI, or find a new BE to start a new build in it.
78*eb8dc403SDave Cobbley
79*eb8dc403SDave Cobbley        The return object MUST always be a BuildEnvironmentController.
80*eb8dc403SDave Cobbley    """
81*eb8dc403SDave Cobbley
82*eb8dc403SDave Cobbley    from bldcontrol.localhostbecontroller import LocalhostBEController
83*eb8dc403SDave Cobbley
84*eb8dc403SDave Cobbley    be = BuildEnvironment.objects.filter(Q(**kwargs))[0]
85*eb8dc403SDave Cobbley    if be.betype == BuildEnvironment.TYPE_LOCAL:
86*eb8dc403SDave Cobbley        return LocalhostBEController(be)
87*eb8dc403SDave Cobbley    else:
88*eb8dc403SDave Cobbley        raise Exception("FIXME: Implement BEC for type %s" % str(be.betype))
89*eb8dc403SDave Cobbley
90*eb8dc403SDave Cobbley
91*eb8dc403SDave Cobbleyclass BuildEnvironmentController(object):
92*eb8dc403SDave Cobbley    """ BuildEnvironmentController (BEC) is the abstract class that defines the operations that MUST
93*eb8dc403SDave Cobbley        or SHOULD be supported by a Build Environment. It is used to establish the framework, and must
94*eb8dc403SDave Cobbley        not be instantiated directly by the user.
95*eb8dc403SDave Cobbley
96*eb8dc403SDave Cobbley        Use the "getBuildEnvironmentController()" function to get a working BEC for your remote.
97*eb8dc403SDave Cobbley
98*eb8dc403SDave Cobbley        How the BuildEnvironments are discovered is outside the scope of this class.
99*eb8dc403SDave Cobbley
100*eb8dc403SDave Cobbley        You must derive this class to teach Toaster how to operate in your own infrastructure.
101*eb8dc403SDave Cobbley        We provide some specific BuildEnvironmentController classes that can be used either to
102*eb8dc403SDave Cobbley        directly set-up Toaster infrastructure, or as a model for your own infrastructure set:
103*eb8dc403SDave Cobbley
104*eb8dc403SDave Cobbley            * Localhost controller will run the Toaster BE on the same account as the web server
105*eb8dc403SDave Cobbley        (current user if you are using the the Django development web server)
106*eb8dc403SDave Cobbley        on the local machine, with the "build/" directory under the "poky/" source checkout directory.
107*eb8dc403SDave Cobbley        Bash is expected to be available.
108*eb8dc403SDave Cobbley
109*eb8dc403SDave Cobbley    """
110*eb8dc403SDave Cobbley    def __init__(self, be):
111*eb8dc403SDave Cobbley        """ Takes a BuildEnvironment object as parameter that points to the settings of the BE.
112*eb8dc403SDave Cobbley        """
113*eb8dc403SDave Cobbley        self.be = be
114*eb8dc403SDave Cobbley        self.connection = None
115*eb8dc403SDave Cobbley
116*eb8dc403SDave Cobbley    def setLayers(self, bitbake, ls):
117*eb8dc403SDave Cobbley        """ Checks-out bitbake executor and layers from git repositories.
118*eb8dc403SDave Cobbley            Sets the layer variables in the config file, after validating local layer paths.
119*eb8dc403SDave Cobbley            bitbake must be a single BRBitbake instance
120*eb8dc403SDave Cobbley            The layer paths must be in a list of BRLayer object
121*eb8dc403SDave Cobbley
122*eb8dc403SDave Cobbley            a word of attention: by convention, the first layer for any build will be poky!
123*eb8dc403SDave Cobbley        """
124*eb8dc403SDave Cobbley        raise NotImplementedError("FIXME: Must override setLayers")
125*eb8dc403SDave Cobbley
126*eb8dc403SDave Cobbley    def getArtifact(self, path):
127*eb8dc403SDave Cobbley        """ This call returns an artifact identified by the 'path'. How 'path' is interpreted as
128*eb8dc403SDave Cobbley            up to the implementing BEC. The return MUST be a REST URL where a GET will actually return
129*eb8dc403SDave Cobbley            the content of the artifact, e.g. for use as a "download link" in a web UI.
130*eb8dc403SDave Cobbley        """
131*eb8dc403SDave Cobbley        raise NotImplementedError("Must return the REST URL of the artifact")
132*eb8dc403SDave Cobbley
133*eb8dc403SDave Cobbley    def triggerBuild(self, bitbake, layers, variables, targets):
134*eb8dc403SDave Cobbley        raise NotImplementedError("Must override BE release")
135*eb8dc403SDave Cobbley
136*eb8dc403SDave Cobbleyclass ShellCmdException(Exception):
137*eb8dc403SDave Cobbley    pass
138*eb8dc403SDave Cobbley
139*eb8dc403SDave Cobbley
140*eb8dc403SDave Cobbleyclass BuildSetupException(Exception):
141*eb8dc403SDave Cobbley    pass
142*eb8dc403SDave Cobbley
143