summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2014-08-12 15:45:48 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-08-29 13:56:50 +0100
commit95df54238b6013c374215905b1937fbac72cdd63 (patch)
tree42f1f2061f9583c3906bb3f8674534d496792210
parent565f69205f130644dee136c8296dd0dc979e492b (diff)
downloadpoky-95df54238b6013c374215905b1937fbac72cdd63.tar.gz
bitbake: toaster: update checksettings command for auto-detection
We enhance the checksettings command to try to automatically detect settings for running on localhost. The checksettings will look for a nearby poky layer source, for a nearby build directory, and will try to import settings from "toasterconf.json" files found in the local layer. On new configuration, it will also perform updates from the layer source. (Bitbake rev: 2aab77dfccb538e2b09829841ea6c464d40cafb1) Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rwxr-xr-xbitbake/bin/toaster9
-rw-r--r--bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py190
2 files changed, 188 insertions, 11 deletions
diff --git a/bitbake/bin/toaster b/bitbake/bin/toaster
index ce16de6c3b..2fabe5c8ec 100755
--- a/bitbake/bin/toaster
+++ b/bitbake/bin/toaster
@@ -65,10 +65,10 @@ function webserverStartAll()
65 fi 65 fi
66 if [ "x$TOASTER_MANAGED" == "x1" ]; then 66 if [ "x$TOASTER_MANAGED" == "x1" ]; then
67 python $BBBASEDIR/lib/toaster/manage.py migrate bldcontrol || retval=1 67 python $BBBASEDIR/lib/toaster/manage.py migrate bldcontrol || retval=1
68 python $BBBASEDIR/lib/toaster/manage.py checksettings || retval=1 68 python $BBBASEDIR/lib/toaster/manage.py checksettings --traceback || retval=1
69 fi 69 fi
70 echo "Starting webserver"
71 if [ $retval -eq 0 ]; then 70 if [ $retval -eq 0 ]; then
71 echo "Starting webserver"
72 python $BBBASEDIR/lib/toaster/manage.py runserver 0.0.0.0:8000 </dev/null >${BUILDDIR}/toaster_web.log 2>&1 & echo $! >${BUILDDIR}/.toastermain.pid 72 python $BBBASEDIR/lib/toaster/manage.py runserver 0.0.0.0:8000 </dev/null >${BUILDDIR}/toaster_web.log 2>&1 & echo $! >${BUILDDIR}/.toastermain.pid
73 sleep 1 73 sleep 1
74 if ! cat "${BUILDDIR}/.toastermain.pid" | xargs -I{} kill -0 {} ; then 74 if ! cat "${BUILDDIR}/.toastermain.pid" | xargs -I{} kill -0 {} ; then
@@ -144,7 +144,10 @@ if [ -z "$ZSH_NAME" ] && [ `basename \"$0\"` = `basename \"$BASH_SOURCE\"` ]; th
144 } 144 }
145 TOASTER_MANAGED=1 145 TOASTER_MANAGED=1
146 export TOASTER_MANAGED=1 146 export TOASTER_MANAGED=1
147 webserverStartAll || (echo "Fail to start the web server, stopping" 1>&2 && exit 1) 147 if ! webserverStartAll; then
148 echo "Failed to start the web server, stopping" 1>&2;
149 exit 1;
150 fi
148 xdg-open http://0.0.0.0:8000/ >/dev/null 2>&1 & 151 xdg-open http://0.0.0.0:8000/ >/dev/null 2>&1 &
149 trap trap_ctrlc SIGINT 152 trap trap_ctrlc SIGINT
150 echo "Running. Stop with Ctrl-C" 153 echo "Running. Stop with Ctrl-C"
diff --git a/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py b/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
index a91dd150ef..4f6a66e711 100644
--- a/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
+++ b/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
@@ -1,38 +1,212 @@
1from django.core.management.base import NoArgsCommand, CommandError 1from django.core.management.base import NoArgsCommand, CommandError
2from django.db import transaction 2from django.db import transaction
3from orm.models import Build 3from orm.models import LayerSource, ToasterSetting, Branch, Layer, Layer_Version
4from orm.models import BitbakeVersion, Release, ReleaseDefaultLayer
4from bldcontrol.bbcontroller import getBuildEnvironmentController, ShellCmdException 5from bldcontrol.bbcontroller import getBuildEnvironmentController, ShellCmdException
5from bldcontrol.models import BuildRequest, BuildEnvironment 6from bldcontrol.models import BuildRequest, BuildEnvironment
6import os 7import os
7 8
9def DN(path):
10 if path is None:
11 return ""
12 else:
13 return os.path.dirname(path)
14
15
8class Command(NoArgsCommand): 16class Command(NoArgsCommand):
9 args = "" 17 args = ""
10 help = "Verifies thid %dthe configured settings are valid and usable, or prompts the user to fix the settings." 18 help = "Verifies that the configured settings are valid and usable, or prompts the user to fix the settings."
19
20 def _reduce_canon_path(self, path):
21 components = []
22 for c in path.split("/"):
23 if c == "..":
24 del components[-1]
25 elif c == ".":
26 pass
27 else:
28 components.append(c)
29 return "/".join(components)
30
31 def _find_first_path_for_file(self, startdirectory, filename, level = 0):
32 if level < 0:
33 return None
34 dirs = []
35 for i in os.listdir(startdirectory):
36 j = os.path.join(startdirectory, i)
37 if os.path.isfile(j):
38 if i == filename:
39 return startdirectory
40 elif os.path.isdir(j):
41 dirs.append(j)
42 for j in dirs:
43 ret = self._find_first_path_for_file(j, filename, level - 1)
44 if ret is not None:
45 return ret
46 return None
47
48 def _get_suggested_sourcedir(self, be):
49 if be.betype != BuildEnvironment.TYPE_LOCAL:
50 return ""
51 return DN(DN(DN(self._find_first_path_for_file(self.guesspath, "toasterconf.json", 4))))
52
53 def _get_suggested_builddir(self, be):
54 if be.betype != BuildEnvironment.TYPE_LOCAL:
55 return ""
56 return DN(self._find_first_path_for_file(self.guesspath, "bblayers.conf", 3))
57
58 def _import_layer_config(self, baselayerdir):
59 filepath = os.path.join(baselayerdir, "meta/conf/toasterconf.json")
60 if not os.path.exists(filepath) or not os.path.isfile(filepath):
61 raise Exception("Failed to find toaster config file %s ." % filepath)
62
63 import json, pprint
64 data = json.loads(open(filepath, "r").read())
65
66 # verify config file validity before updating settings
67 for i in ['bitbake', 'releases', 'defaultrelease', 'config', 'layersources']:
68 assert i in data
69
70 # import bitbake data
71 for bvi in data['bitbake']:
72 bvo, created = BitbakeVersion.objects.get_or_create(name=bvi['name'])
73 bvo.giturl = bvi['giturl']
74 bvo.branch = bvi['branch']
75 bvo.dirpath = bvi['dirpath']
76 bvo.save()
77
78 # set the layer sources
79 for lsi in data['layersources']:
80 assert 'sourcetype' in lsi
81 assert 'apiurl' in lsi
82 assert 'name' in lsi
83 assert 'branches' in lsi
84
85 if lsi['sourcetype'] == LayerSource.TYPE_LAYERINDEX or lsi['apiurl'].startswith("/"):
86 apiurl = lsi['apiurl']
87 else:
88 apiurl = self._reduce_canon_path(os.path.join(DN(filepath), lsi['apiurl']))
89
90 try:
91 ls = LayerSource.objects.get(sourcetype = lsi['sourcetype'], apiurl = apiurl)
92 except LayerSource.DoesNotExist:
93 ls = LayerSource.objects.create(
94 name = lsi['name'],
95 sourcetype = lsi['sourcetype'],
96 apiurl = apiurl
97 )
98
99 layerbranches = []
100 for branchname in lsi['branches']:
101 bo, created = Branch.objects.get_or_create(layer_source = ls, name = branchname)
102 layerbranches.append(bo)
103
104 if 'layers' in lsi:
105 for layerinfo in lsi['layers']:
106 lo, created = Layer.objects.get_or_create(layer_source = ls, name = layerinfo['name'])
107 if layerinfo['local_path'].startswith("/"):
108 lo.local_path = layerinfo['local_path']
109 else:
110 lo.local_path = self._reduce_canon_path(os.path.join(DN(filepath), layerinfo['local_path']))
111 lo.layer_index_url = layerinfo['layer_index_url']
112 if 'vcs_url' in layerinfo:
113 lo.vcs_url = layerinfo['vcs_url']
114 lo.save()
115
116 for branch in layerbranches:
117 lvo, created = Layer_Version.objects.get_or_create(layer_source = ls,
118 up_branch = branch,
119 commit = branch.name,
120 layer = lo)
121 lvo.dirpath = layerinfo['dirpath']
122 lvo.save()
123 # set releases
124 for ri in data['releases']:
125 bvo = BitbakeVersion.objects.get(name = ri['bitbake'])
126 assert bvo is not None
127
128 ro, created = Release.objects.get_or_create(name = ri['name'], bitbake_version = bvo)
129 ro.description = ri['description']
130 ro.branch = ri['branch']
131 ro.save()
132
133 for dli in ri['defaultlayers']:
134 lsi, layername = dli.split(":")
135 layer, created = Layer.objects.get_or_create(
136 layer_source = LayerSource.objects.get(name = lsi),
137 name = layername
138 )
139 ReleaseDefaultLayer.objects.get_or_create( release = ro, layer = layer)
140
141 # set default release
142 if ToasterSetting.objects.filter(name = "DEFAULT_RELEASE").count() > 0:
143 ToasterSetting.objects.filter(name = "DEFAULT_RELEASE").update(value = data['defaultrelease'])
144 else:
145 ToasterSetting.objects.create(name = "DEFAULT_RELEASE", value = data['defaultrelease'])
146
147 # set default config variables
148 for configname in data['config']:
149 if ToasterSetting.objects.filter(name = "DEFCONF_" + configname).count() > 0:
150 ToasterSetting.objects.filter(name = "DEFCONF_" + configname).update(value = data['config'][configname])
151 else:
152 ToasterSetting.objects.create(name = "DEFCONF_" + configname, value = data['config'][configname])
11 153
12 def handle(self, **options): 154 def handle(self, **options):
155 self.guesspath = DN(DN(DN(DN(DN(DN(DN(__file__)))))))
156
13 # we make sure we have builddir and sourcedir for all defined build envionments 157 # we make sure we have builddir and sourcedir for all defined build envionments
14 for be in BuildEnvironment.objects.all(): 158 for be in BuildEnvironment.objects.all():
15 def _verify_be(): 159 def _verify_be():
16 is_changed = False 160 is_changed = False
17 print("Verifying the Build Environment type %s id %d." % (be.get_betype_display(), be.pk)) 161 print("Verifying the Build Environment type %s id %d." % (be.get_betype_display(), be.pk))
18 if len(be.sourcedir) == 0: 162 if len(be.sourcedir) == 0:
19 be.sourcedir = raw_input(" -- sourcedir may not be empty:") 163 suggesteddir = self._get_suggested_sourcedir(be)
164 be.sourcedir = raw_input(" -- Layer sources checkout directory may not be empty [guessed \"%s\"]:" % suggesteddir)
165 if len(be.sourcedir) == 0 and len(suggesteddir) > 0:
166 be.sourcedir = suggesteddir
20 is_changed = True 167 is_changed = True
168
21 if not be.sourcedir.startswith("/"): 169 if not be.sourcedir.startswith("/"):
22 be.sourcedir = raw_input(" -- sourcedir must be an absolute path:") 170 be.sourcedir = raw_input(" -- Layer sources checkout directory must be an absolute path:")
23 is_changed = True 171 is_changed = True
172
24 if len(be.builddir) == 0: 173 if len(be.builddir) == 0:
25 be.builddir = raw_input(" -- builddir may not be empty:") 174 suggesteddir = self._get_suggested_builddir(be)
175 be.builddir = raw_input(" -- Build directory may not be empty [guessed \"%s\"]:" % suggesteddir)
176 if len(be.builddir) == 0 and len(suggesteddir) > 0:
177 be.builddir = suggesteddir
26 is_changed = True 178 is_changed = True
179
27 if not be.builddir.startswith("/"): 180 if not be.builddir.startswith("/"):
28 be.builddir = raw_input(" -- builddir must be an absolute path:") 181 be.builddir = raw_input(" -- Build directory must be an absolute path:")
29 is_changed = True 182 is_changed = True
183
184
185
30 if is_changed: 186 if is_changed:
31 print "saved" 187 print "Build configuration saved"
32 be.save() 188 be.save()
189
190 if is_changed and be.betype == BuildEnvironment.TYPE_LOCAL:
191 baselayerdir = DN(DN(self._find_first_path_for_file(be.sourcedir, "toasterconf.json", 3)))
192 if baselayerdir:
193 i = raw_input(" -- Do you want to import basic layer configuration from \"%s\" ? (y/N):" % baselayerdir)
194 if len(i) and i.upper()[0] == 'Y':
195 self._import_layer_config(baselayerdir)
196 # we run lsupdates after config update
197 print "Updating information from the layer source, please wait."
198 from django.core.management import call_command
199 call_command("lsupdates")
200 pass
201
33 return is_changed 202 return is_changed
34 203
35 while (_verify_be()): 204 while (_verify_be()):
36 pass 205 pass
37 206
38 return 0 207 # verify that default settings are there
208 if ToasterSetting.objects.filter(name = 'DEFAULT_RELEASE').count() != 1:
209 ToasterSetting.objects.filter(name = 'DEFAULT_RELEASE').delete()
210 ToasterSetting.objects.get_or_create(name = 'DEFAULT_RELEASE', value = '')
211
212 return 0