summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster')
-rw-r--r--bitbake/lib/toaster/bldcontrol/bbcontroller.py6
-rw-r--r--bitbake/lib/toaster/bldcontrol/localhostbecontroller.py39
-rw-r--r--bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py19
-rw-r--r--bitbake/lib/toaster/bldcontrol/migrations/0007_auto__add_field_buildrequest_environment__chg_field_buildrequest_build.py145
-rw-r--r--bitbake/lib/toaster/bldcontrol/models.py3
-rw-r--r--bitbake/lib/toaster/bldcontrol/sshbecontroller.py4
-rw-r--r--bitbake/lib/toaster/bldcontrol/tests.py10
7 files changed, 198 insertions, 28 deletions
diff --git a/bitbake/lib/toaster/bldcontrol/bbcontroller.py b/bitbake/lib/toaster/bldcontrol/bbcontroller.py
index 6812ae3e6e..6bb45d6388 100644
--- a/bitbake/lib/toaster/bldcontrol/bbcontroller.py
+++ b/bitbake/lib/toaster/bldcontrol/bbcontroller.py
@@ -118,7 +118,7 @@ class BuildEnvironmentController(object):
118 self.connection = None 118 self.connection = None
119 119
120 120
121 def startBBServer(self): 121 def startBBServer(self, brbe):
122 """ Starts a BB server with Toaster toasterui set up to record the builds, an no controlling UI. 122 """ Starts a BB server with Toaster toasterui set up to record the builds, an no controlling UI.
123 After this method executes, self.be bbaddress/bbport MUST point to a running and free server, 123 After this method executes, self.be bbaddress/bbport MUST point to a running and free server,
124 and the bbstate MUST be updated to "started". 124 and the bbstate MUST be updated to "started".
@@ -142,12 +142,12 @@ class BuildEnvironmentController(object):
142 raise Exception("Must override setLayers") 142 raise Exception("Must override setLayers")
143 143
144 144
145 def getBBController(self): 145 def getBBController(self, brbe):
146 """ returns a BitbakeController to an already started server; this is the point where the server 146 """ returns a BitbakeController to an already started server; this is the point where the server
147 starts if needed; or reconnects to the server if we can 147 starts if needed; or reconnects to the server if we can
148 """ 148 """
149 if not self.connection: 149 if not self.connection:
150 self.startBBServer() 150 self.startBBServer(brbe)
151 self.be.lock = BuildEnvironment.LOCK_RUNNING 151 self.be.lock = BuildEnvironment.LOCK_RUNNING
152 self.be.save() 152 self.be.save()
153 153
diff --git a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
index fe7fd81fb9..a272860ec0 100644
--- a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
+++ b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
@@ -74,14 +74,35 @@ class LocalhostBEController(BuildEnvironmentController):
74 self._createdirpath(self.be.builddir) 74 self._createdirpath(self.be.builddir)
75 self._shellcmd("bash -c \"source %s/oe-init-build-env %s\"" % (self.pokydirname, self.be.builddir)) 75 self._shellcmd("bash -c \"source %s/oe-init-build-env %s\"" % (self.pokydirname, self.be.builddir))
76 76
77 def startBBServer(self): 77 def startBBServer(self, brbe):
78 assert self.pokydirname and os.path.exists(self.pokydirname) 78 assert self.pokydirname and os.path.exists(self.pokydirname)
79 assert self.islayerset 79 assert self.islayerset
80 print("DEBUG: executing ", "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)) 80
81 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)) 81 try:
82 # FIXME unfortunate sleep 1 - we need to make sure that bbserver is started and the toaster ui is connected 82 os.remove(os.path.join(self.be.builddir, "toaster_ui.log"))
83 # but since they start async without any return, we just wait a bit 83 except OSError as e:
84 print "Started server" 84 import errno
85 if e.errno != errno.ENOENT:
86 raise
87
88 cmd = "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)
89 print("DEBUG: executing ", cmd)
90 print self._shellcmd(cmd)
91 def _toaster_ui_started(filepath):
92 if not os.path.exists(filepath):
93 return False
94 with open(filepath, "r") as f:
95 for line in f:
96 if line.startswith("NOTE: ToasterUI waiting for events"):
97 return True
98 return False
99
100 while not _toaster_ui_started(os.path.join(self.be.builddir, "toaster_ui.log")):
101 import time
102 print "DEBUG: Waiting server to start"
103 time.sleep(0.5)
104
105 print("DEBUG: Started server")
85 assert self.be.sourcedir and os.path.exists(self.be.builddir) 106 assert self.be.sourcedir and os.path.exists(self.be.builddir)
86 self.be.bbaddress = "localhost" 107 self.be.bbaddress = "localhost"
87 self.be.bbport = "8200" 108 self.be.bbport = "8200"
@@ -172,9 +193,13 @@ class LocalhostBEController(BuildEnvironmentController):
172 conflines = open(bblayerconf, "r").readlines() 193 conflines = open(bblayerconf, "r").readlines()
173 194
174 bblayerconffile = open(bblayerconf, "w") 195 bblayerconffile = open(bblayerconf, "w")
196 skip = 0
175 for i in xrange(len(conflines)): 197 for i in xrange(len(conflines)):
198 if skip > 0:
199 skip =- 1
200 continue
176 if conflines[i].startswith("# line added by toaster"): 201 if conflines[i].startswith("# line added by toaster"):
177 i += 2 202 skip = 1
178 else: 203 else:
179 bblayerconffile.write(conflines[i]) 204 bblayerconffile.write(conflines[i])
180 205
diff --git a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
index 8efe8e62bc..5e253e0efc 100644
--- a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
+++ b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
@@ -39,24 +39,29 @@ class Command(NoArgsCommand):
39 # we could not find a BEC; postpone the BR 39 # we could not find a BEC; postpone the BR
40 br.state = BuildRequest.REQ_QUEUED 40 br.state = BuildRequest.REQ_QUEUED
41 br.save() 41 br.save()
42 print "No build env"
42 return 43 return
43 44
44 # set up the buid environment with the needed layers
45 print "Build %s, Environment %s" % (br, bec.be) 45 print "Build %s, Environment %s" % (br, bec.be)
46 bec.setLayers(br.brbitbake_set.all(), br.brlayer_set.all()) 46 # let the build request know where it is being executed
47 br.environment = bec.be
48 br.save()
47 49
48 # get the bb server running 50 # set up the buid environment with the needed layers
49 bbctrl = bec.getBBController() 51 bec.setLayers(br.brbitbake_set.all(), br.brlayer_set.all())
50 52
51 # let toasterui that this is a managed build 53 # get the bb server running with the build req id and build env id
52 bbctrl.setVariable("TOASTER_BRBE", "%d:%d" % (br.pk, bec.be.pk)) 54 bbctrl = bec.getBBController("%d:%d" % (br.pk, bec.be.pk))
53 55
54 # set the build configuration 56 # set the build configuration
55 for variable in br.brvariable_set.all(): 57 for variable in br.brvariable_set.all():
56 bbctrl.setVariable(variable.name, variable.value) 58 bbctrl.setVariable(variable.name, variable.value)
57 59
58 # trigger the build command 60 # trigger the build command
59 bbctrl.build(list(map(lambda x:x.target, br.brtarget_set.all()))) 61 task = reduce(lambda x, y: x if len(y)== 0 else y, map(lambda y: y.task, br.brtarget_set.all()))
62 if len(task) == 0:
63 task = None
64 bbctrl.build(list(map(lambda x:x.target, br.brtarget_set.all())), task)
60 65
61 print "Build launched, exiting" 66 print "Build launched, exiting"
62 # disconnect from the server 67 # disconnect from the server
diff --git a/bitbake/lib/toaster/bldcontrol/migrations/0007_auto__add_field_buildrequest_environment__chg_field_buildrequest_build.py b/bitbake/lib/toaster/bldcontrol/migrations/0007_auto__add_field_buildrequest_environment__chg_field_buildrequest_build.py
new file mode 100644
index 0000000000..70677a294e
--- /dev/null
+++ b/bitbake/lib/toaster/bldcontrol/migrations/0007_auto__add_field_buildrequest_environment__chg_field_buildrequest_build.py
@@ -0,0 +1,145 @@
1# -*- coding: utf-8 -*-
2from south.utils import datetime_utils as datetime
3from south.db import db
4from south.v2 import SchemaMigration
5from django.db import models
6
7
8class Migration(SchemaMigration):
9
10 def forwards(self, orm):
11 # Adding field 'BuildRequest.environment'
12 db.add_column(u'bldcontrol_buildrequest', 'environment',
13 self.gf('django.db.models.fields.related.ForeignKey')(to=orm['bldcontrol.BuildEnvironment'], null=True),
14 keep_default=False)
15
16
17 # Changing field 'BuildRequest.build'
18 db.alter_column(u'bldcontrol_buildrequest', 'build_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['orm.Build'], unique=True, null=True))
19 # Adding unique constraint on 'BuildRequest', fields ['build']
20 db.create_unique(u'bldcontrol_buildrequest', ['build_id'])
21
22
23 def backwards(self, orm):
24 # Removing unique constraint on 'BuildRequest', fields ['build']
25 db.delete_unique(u'bldcontrol_buildrequest', ['build_id'])
26
27 # Deleting field 'BuildRequest.environment'
28 db.delete_column(u'bldcontrol_buildrequest', 'environment_id')
29
30
31 # Changing field 'BuildRequest.build'
32 db.alter_column(u'bldcontrol_buildrequest', 'build_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['orm.Build'], null=True))
33
34 models = {
35 u'bldcontrol.brbitbake': {
36 'Meta': {'object_name': 'BRBitbake'},
37 'commit': ('django.db.models.fields.CharField', [], {'max_length': '254'}),
38 'dirpath': ('django.db.models.fields.CharField', [], {'max_length': '254'}),
39 'giturl': ('django.db.models.fields.CharField', [], {'max_length': '254'}),
40 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
41 'req': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['bldcontrol.BuildRequest']", 'unique': 'True'})
42 },
43 u'bldcontrol.brerror': {
44 'Meta': {'object_name': 'BRError'},
45 'errmsg': ('django.db.models.fields.TextField', [], {}),
46 'errtype': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
47 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
48 'req': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['bldcontrol.BuildRequest']"}),
49 'traceback': ('django.db.models.fields.TextField', [], {})
50 },
51 u'bldcontrol.brlayer': {
52 'Meta': {'object_name': 'BRLayer'},
53 'commit': ('django.db.models.fields.CharField', [], {'max_length': '254'}),
54 'dirpath': ('django.db.models.fields.CharField', [], {'max_length': '254'}),
55 'giturl': ('django.db.models.fields.CharField', [], {'max_length': '254'}),
56 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
57 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
58 'req': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['bldcontrol.BuildRequest']"})
59 },
60 u'bldcontrol.brtarget': {
61 'Meta': {'object_name': 'BRTarget'},
62 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
63 'req': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['bldcontrol.BuildRequest']"}),
64 'target': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
65 'task': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
66 },
67 u'bldcontrol.brvariable': {
68 'Meta': {'object_name': 'BRVariable'},
69 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
70 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
71 'req': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['bldcontrol.BuildRequest']"}),
72 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
73 },
74 u'bldcontrol.buildenvironment': {
75 'Meta': {'object_name': 'BuildEnvironment'},
76 'address': ('django.db.models.fields.CharField', [], {'max_length': '254'}),
77 'bbaddress': ('django.db.models.fields.CharField', [], {'max_length': '254', 'blank': 'True'}),
78 'bbport': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
79 'bbstate': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
80 'bbtoken': ('django.db.models.fields.CharField', [], {'max_length': '126', 'blank': 'True'}),
81 'betype': ('django.db.models.fields.IntegerField', [], {}),
82 'builddir': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
83 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
84 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
85 'lock': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
86 'sourcedir': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
87 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
88 },
89 u'bldcontrol.buildrequest': {
90 'Meta': {'object_name': 'BuildRequest'},
91 'build': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['orm.Build']", 'unique': 'True', 'null': 'True'}),
92 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
93 'environment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['bldcontrol.BuildEnvironment']", 'null': 'True'}),
94 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
95 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
96 'state': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
97 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
98 },
99 u'orm.bitbakeversion': {
100 'Meta': {'object_name': 'BitbakeVersion'},
101 'branch': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
102 'dirpath': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
103 'giturl': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
104 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
105 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
106 },
107 u'orm.build': {
108 'Meta': {'object_name': 'Build'},
109 'bitbake_version': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
110 'build_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
111 'completed_on': ('django.db.models.fields.DateTimeField', [], {}),
112 'cooker_log_path': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
113 'distro': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
114 'distro_version': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
115 'errors_no': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
116 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
117 'machine': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
118 'outcome': ('django.db.models.fields.IntegerField', [], {'default': '2'}),
119 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']", 'null': 'True'}),
120 'started_on': ('django.db.models.fields.DateTimeField', [], {}),
121 'timespent': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
122 'warnings_no': ('django.db.models.fields.IntegerField', [], {'default': '0'})
123 },
124 u'orm.project': {
125 'Meta': {'object_name': 'Project'},
126 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']"}),
127 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
128 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
129 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
130 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']"}),
131 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
132 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
133 'user_id': ('django.db.models.fields.IntegerField', [], {'null': 'True'})
134 },
135 u'orm.release': {
136 'Meta': {'object_name': 'Release'},
137 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']"}),
138 'branch': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
139 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
140 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
141 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
142 }
143 }
144
145 complete_apps = ['bldcontrol'] \ No newline at end of file
diff --git a/bitbake/lib/toaster/bldcontrol/models.py b/bitbake/lib/toaster/bldcontrol/models.py
index 4c54a59b1a..df3635b331 100644
--- a/bitbake/lib/toaster/bldcontrol/models.py
+++ b/bitbake/lib/toaster/bldcontrol/models.py
@@ -59,7 +59,8 @@ class BuildRequest(models.Model):
59 ) 59 )
60 60
61 project = models.ForeignKey(Project) 61 project = models.ForeignKey(Project)
62 build = models.ForeignKey(Build, null = True) # TODO: toasterui should set this when Build is created 62 build = models.OneToOneField(Build, null = True) # TODO: toasterui should set this when Build is created
63 environment = models.ForeignKey(BuildEnvironment, null = True)
63 state = models.IntegerField(choices = REQUEST_STATE, default = REQ_CREATED) 64 state = models.IntegerField(choices = REQUEST_STATE, default = REQ_CREATED)
64 created = models.DateTimeField(auto_now_add = True) 65 created = models.DateTimeField(auto_now_add = True)
65 updated = models.DateTimeField(auto_now = True) 66 updated = models.DateTimeField(auto_now = True)
diff --git a/bitbake/lib/toaster/bldcontrol/sshbecontroller.py b/bitbake/lib/toaster/bldcontrol/sshbecontroller.py
index 64674953dc..f9fd51e5f8 100644
--- a/bitbake/lib/toaster/bldcontrol/sshbecontroller.py
+++ b/bitbake/lib/toaster/bldcontrol/sshbecontroller.py
@@ -77,10 +77,10 @@ class SSHBEController(BuildEnvironmentController):
77 self._pathcreate(self.be.builddir) 77 self._pathcreate(self.be.builddir)
78 self._shellcmd("bash -c \"source %s/oe-init-build-env %s\"" % (self.pokydirname, self.be.builddir)) 78 self._shellcmd("bash -c \"source %s/oe-init-build-env %s\"" % (self.pokydirname, self.be.builddir))
79 79
80 def startBBServer(self): 80 def startBBServer(self, brbe):
81 assert self.pokydirname and self._pathexists(self.pokydirname) 81 assert self.pokydirname and self._pathexists(self.pokydirname)
82 assert self.islayerset 82 assert self.islayerset
83 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)) 83 print 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))
84 # FIXME unfortunate sleep 1 - we need to make sure that bbserver is started and the toaster ui is connected 84 # FIXME unfortunate sleep 1 - we need to make sure that bbserver is started and the toaster ui is connected
85 # but since they start async without any return, we just wait a bit 85 # but since they start async without any return, we just wait a bit
86 print "Started server" 86 print "Started server"
diff --git a/bitbake/lib/toaster/bldcontrol/tests.py b/bitbake/lib/toaster/bldcontrol/tests.py
index 4577c3f03b..65e337a31b 100644
--- a/bitbake/lib/toaster/bldcontrol/tests.py
+++ b/bitbake/lib/toaster/bldcontrol/tests.py
@@ -44,7 +44,7 @@ class BEControllerTests(object):
44 44
45 # test start server and stop 45 # test start server and stop
46 self.assertTrue(socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex((hostname, 8200)), "Port already occupied") 46 self.assertTrue(socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex((hostname, 8200)), "Port already occupied")
47 bc.startBBServer() 47 bc.startBBServer("0:0")
48 self.assertFalse(socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex((hostname, 8200)), "Server not answering") 48 self.assertFalse(socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex((hostname, 8200)), "Server not answering")
49 49
50 bc.stopBBServer() 50 bc.stopBBServer()
@@ -57,14 +57,8 @@ class BEControllerTests(object):
57 bc = self._getBEController(obe) 57 bc = self._getBEController(obe)
58 bc.setLayers(BITBAKE_LAYERS, POKY_LAYERS) # setting layers, skip any layer info 58 bc.setLayers(BITBAKE_LAYERS, POKY_LAYERS) # setting layers, skip any layer info
59 59
60 bbc = bc.getBBController() 60 bbc = bc.getBBController("%d:%d" % (-1, obe.pk))
61 self.assertTrue(isinstance(bbc, BitbakeController)) 61 self.assertTrue(isinstance(bbc, BitbakeController))
62 # test set variable, use no build marker -1 for BR value
63 try:
64 bbc.setVariable("TOASTER_BRBE", "%d:%d" % (-1, obe.pk))
65 except Exception as e :
66 self.fail("setVariable raised %s", e)
67
68 bc.stopBBServer() 62 bc.stopBBServer()
69 63
70 self._serverForceStop(bc) 64 self._serverForceStop(bc)