blob: 301df1880af300d2b5f2def981cecc22787faa3b [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002# BitBake Toaster Implementation
3#
4# Copyright (C) 2014 Intel Corporation
5#
Brad Bishopc342db32019-05-15 21:57:59 -04006# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -05007#
Patrick Williamsc124f4f2015-09-15 14:41:29 -05008
9import os
10import sys
11import re
12from django.db import transaction
13from django.db.models import Q
14from bldcontrol.models import BuildEnvironment, BRLayer, BRVariable, BRTarget, BRBitbake
15
16# load Bitbake components
17path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
18sys.path.insert(0, path)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050019
20class BitbakeController(object):
21 """ This is the basic class that controlls a bitbake server.
22 It is outside the scope of this class on how the server is started and aquired
23 """
24
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050025 def __init__(self, be):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050026 import bb.server.xmlrpcclient
27 self.connection = bb.server.xmlrpcclient._create_server(be.bbaddress,
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050028 int(be.bbport))[0]
Patrick Williamsc124f4f2015-09-15 14:41:29 -050029
30 def _runCommand(self, command):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050031 result, error = self.connection.runCommand(command)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050032 if error:
33 raise Exception(error)
34 return result
35
36 def disconnect(self):
37 return self.connection.removeClient()
38
39 def setVariable(self, name, value):
40 return self._runCommand(["setVariable", name, value])
41
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050042 def getVariable(self, name):
43 return self._runCommand(["getVariable", name])
44
45 def triggerEvent(self, event):
46 return self._runCommand(["triggerEvent", event])
47
Patrick Williamsc124f4f2015-09-15 14:41:29 -050048 def build(self, targets, task = None):
49 if task is None:
50 task = "build"
51 return self._runCommand(["buildTargets", targets, task])
52
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050053 def forceShutDown(self):
54 return self._runCommand(["stateForceShutdown"])
55
Patrick Williamsc124f4f2015-09-15 14:41:29 -050056
57
58def getBuildEnvironmentController(**kwargs):
59 """ Gets you a BuildEnvironmentController that encapsulates a build environment,
60 based on the query dictionary sent in.
61
62 This is used to retrieve, for example, the currently running BE from inside
63 the toaster UI, or find a new BE to start a new build in it.
64
65 The return object MUST always be a BuildEnvironmentController.
66 """
67
Patrick Williamsc0f7c042017-02-23 20:41:17 -060068 from bldcontrol.localhostbecontroller import LocalhostBEController
Patrick Williamsc124f4f2015-09-15 14:41:29 -050069
70 be = BuildEnvironment.objects.filter(Q(**kwargs))[0]
71 if be.betype == BuildEnvironment.TYPE_LOCAL:
72 return LocalhostBEController(be)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050073 else:
74 raise Exception("FIXME: Implement BEC for type %s" % str(be.betype))
75
76
77class BuildEnvironmentController(object):
78 """ BuildEnvironmentController (BEC) is the abstract class that defines the operations that MUST
79 or SHOULD be supported by a Build Environment. It is used to establish the framework, and must
80 not be instantiated directly by the user.
81
82 Use the "getBuildEnvironmentController()" function to get a working BEC for your remote.
83
84 How the BuildEnvironments are discovered is outside the scope of this class.
85
86 You must derive this class to teach Toaster how to operate in your own infrastructure.
87 We provide some specific BuildEnvironmentController classes that can be used either to
88 directly set-up Toaster infrastructure, or as a model for your own infrastructure set:
89
90 * Localhost controller will run the Toaster BE on the same account as the web server
91 (current user if you are using the the Django development web server)
92 on the local machine, with the "build/" directory under the "poky/" source checkout directory.
93 Bash is expected to be available.
94
Patrick Williamsc124f4f2015-09-15 14:41:29 -050095 """
96 def __init__(self, be):
97 """ Takes a BuildEnvironment object as parameter that points to the settings of the BE.
98 """
99 self.be = be
100 self.connection = None
101
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500102 def setLayers(self, bitbake, ls):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500103 """ Checks-out bitbake executor and layers from git repositories.
104 Sets the layer variables in the config file, after validating local layer paths.
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500105 bitbake must be a single BRBitbake instance
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500106 The layer paths must be in a list of BRLayer object
107
108 a word of attention: by convention, the first layer for any build will be poky!
109 """
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500110 raise NotImplementedError("FIXME: Must override setLayers")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500111
112 def getArtifact(self, path):
113 """ This call returns an artifact identified by the 'path'. How 'path' is interpreted as
114 up to the implementing BEC. The return MUST be a REST URL where a GET will actually return
115 the content of the artifact, e.g. for use as a "download link" in a web UI.
116 """
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500117 raise NotImplementedError("Must return the REST URL of the artifact")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500118
119 def triggerBuild(self, bitbake, layers, variables, targets):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500120 raise NotImplementedError("Must override BE release")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500121
122class ShellCmdException(Exception):
123 pass
124
125
126class BuildSetupException(Exception):
127 pass
128