summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2014-11-06 12:57:58 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-11-12 17:04:49 +0000
commitabf7551f60cd56129b9abc22730f45e336ece582 (patch)
tree2a234cb109366ad8a16951f05078d919e1970c13 /bitbake/lib/toaster
parent6f0496ef557cddda8fc8d71b414aa70e72e91aa8 (diff)
downloadpoky-abf7551f60cd56129b9abc22730f45e336ece582.tar.gz
bitbake: toaster: separate the load configuration file command
We separate the load configuration command as to allow system administrators load toasterconf.json file as part of the setup process. [YOCTO #6895] (Bitbake rev: 3ed596ac4e21a4494fd7f6cd8739d460fd98512f) Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster')
-rw-r--r--bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py139
-rw-r--r--bitbake/lib/toaster/bldcontrol/management/commands/loadconf.py157
2 files changed, 162 insertions, 134 deletions
diff --git a/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py b/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
index 08eebceaab..56e4e1bf0c 100644
--- a/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
+++ b/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
@@ -1,9 +1,8 @@
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 LayerSource, ToasterSetting, Branch, Layer, Layer_Version
4from orm.models import BitbakeVersion, Release, ReleaseDefaultLayer
5from bldcontrol.bbcontroller import getBuildEnvironmentController, ShellCmdException 3from bldcontrol.bbcontroller import getBuildEnvironmentController, ShellCmdException
6from bldcontrol.models import BuildRequest, BuildEnvironment 4from bldcontrol.models import BuildRequest, BuildEnvironment
5from orm.models import ToasterSetting
7import os 6import os
8 7
9def DN(path): 8def DN(path):
@@ -17,16 +16,6 @@ class Command(NoArgsCommand):
17 args = "" 16 args = ""
18 help = "Verifies that the configured settings are valid and usable, or prompts the user to fix the settings." 17 help = "Verifies that the configured settings are valid and usable, or prompts the user to fix the settings."
19 18
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 19
31 def _find_first_path_for_file(self, startdirectory, filename, level = 0): 20 def _find_first_path_for_file(self, startdirectory, filename, level = 0):
32 if level < 0: 21 if level < 0:
@@ -55,125 +44,6 @@ class Command(NoArgsCommand):
55 return "" 44 return ""
56 return DN(self._find_first_path_for_file(DN(self.guesspath), "bblayers.conf", 4)) 45 return DN(self._find_first_path_for_file(DN(self.guesspath), "bblayers.conf", 4))
57 46
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(DN(DN(filepath))), layerinfo['local_path']))
111
112 if not os.path.exists(lo.local_path):
113 raise Exception("Local layer path %s must exists." % lo.local_path)
114
115 if layerinfo['vcs_url'].startswith("remote:"):
116 lo.vcs_url = None
117 # we detect the remote name at runtime
118 import subprocess
119 (remote, remote_name) = layerinfo['vcs_url'].split(":", 1)
120 cmd = subprocess.Popen("git remote -v", shell=True, cwd = lo.local_path, stdout=subprocess.PIPE, stderr = subprocess.PIPE)
121 (out,err) = cmd.communicate()
122 if cmd.returncode != 0:
123 raise Exception("Error while importing layer vcs_url: git error: %s" % err)
124 for line in out.split("\n"):
125 try:
126 (name, path) = line.split("\t", 1)
127 if name == remote_name:
128 lo.vcs_url = path.split(" ")[0]
129 break
130 except ValueError:
131 pass
132 if lo.vcs_url == None:
133 raise Exception("Error while looking for remote \"%s\" in \"s\"" % (remote_name, lo.local_path))
134 else:
135 lo.vcs_url = layerinfo['vcs_url']
136
137 if 'layer_index_url' in layerinfo:
138 lo.layer_index_url = layerinfo['layer_index_url']
139 lo.save()
140
141 for branch in layerbranches:
142 lvo, created = Layer_Version.objects.get_or_create(layer_source = ls,
143 up_branch = branch,
144 commit = branch.name,
145 layer = lo)
146 lvo.dirpath = layerinfo['dirpath']
147 lvo.save()
148 # set releases
149 for ri in data['releases']:
150 bvo = BitbakeVersion.objects.get(name = ri['bitbake'])
151 assert bvo is not None
152
153 ro, created = Release.objects.get_or_create(name = ri['name'], bitbake_version = bvo, branch = Branch.objects.get( layer_source__name = ri['layersource'], name=ri['branch']))
154 ro.description = ri['description']
155 ro.helptext = ri['helptext']
156 ro.save()
157
158 for dli in ri['defaultlayers']:
159 layer, created = Layer.objects.get_or_create(
160 layer_source = LayerSource.objects.get(name = ri['layersource']),
161 name = dli
162 )
163 ReleaseDefaultLayer.objects.get_or_create( release = ro, layer = layer)
164
165 # set default release
166 if ToasterSetting.objects.filter(name = "DEFAULT_RELEASE").count() > 0:
167 ToasterSetting.objects.filter(name = "DEFAULT_RELEASE").update(value = data['defaultrelease'])
168 else:
169 ToasterSetting.objects.create(name = "DEFAULT_RELEASE", value = data['defaultrelease'])
170
171 # set default config variables
172 for configname in data['config']:
173 if ToasterSetting.objects.filter(name = "DEFCONF_" + configname).count() > 0:
174 ToasterSetting.objects.filter(name = "DEFCONF_" + configname).update(value = data['config'][configname])
175 else:
176 ToasterSetting.objects.create(name = "DEFCONF_" + configname, value = data['config'][configname])
177 47
178 def handle(self, **options): 48 def handle(self, **options):
179 self.guesspath = DN(DN(DN(DN(DN(DN(DN(__file__))))))) 49 self.guesspath = DN(DN(DN(DN(DN(DN(DN(__file__)))))))
@@ -197,6 +67,7 @@ class Command(NoArgsCommand):
197 print("Verifying the Build Environment type %s id %d." % (be.get_betype_display(), be.pk)) 67 print("Verifying the Build Environment type %s id %d." % (be.get_betype_display(), be.pk))
198 if len(be.sourcedir) == 0: 68 if len(be.sourcedir) == 0:
199 suggesteddir = self._get_suggested_sourcedir(be) 69 suggesteddir = self._get_suggested_sourcedir(be)
70 homesourcedir = suggesteddir
200 be.sourcedir = raw_input(" -- Layer sources checkout directory may not be empty [guessed \"%s\"]:" % suggesteddir) 71 be.sourcedir = raw_input(" -- Layer sources checkout directory may not be empty [guessed \"%s\"]:" % suggesteddir)
201 if len(be.sourcedir) == 0 and len(suggesteddir) > 0: 72 if len(be.sourcedir) == 0 and len(suggesteddir) > 0:
202 be.sourcedir = suggesteddir 73 be.sourcedir = suggesteddir
@@ -218,17 +89,17 @@ class Command(NoArgsCommand):
218 is_changed = True 89 is_changed = True
219 90
220 91
221
222 if is_changed: 92 if is_changed:
223 print "Build configuration saved" 93 print "Build configuration saved"
224 be.save() 94 be.save()
225 95
226 if is_changed and be.betype == BuildEnvironment.TYPE_LOCAL: 96 if is_changed and be.betype == BuildEnvironment.TYPE_LOCAL:
227 baselayerdir = DN(DN(self._find_first_path_for_file(be.sourcedir, "toasterconf.json", 3))) 97 baselayerdir = DN(DN(self._find_first_path_for_file(homesourcedir, "toasterconf.json", 3)))
228 if baselayerdir: 98 if baselayerdir:
229 i = raw_input(" -- Do you want to import basic layer configuration from \"%s\" ? (y/N):" % baselayerdir) 99 i = raw_input(" -- Do you want to import basic layer configuration from \"%s\" ? (y/N):" % baselayerdir)
230 if len(i) and i.upper()[0] == 'Y': 100 if len(i) and i.upper()[0] == 'Y':
231 self._import_layer_config(baselayerdir) 101 from loadconf import Command as LoadConfigCommand
102 LoadConfigCommand()._import_layer_config(os.path.join(baselayerdir, "meta/conf/toasterconf.json"))
232 # we run lsupdates after config update 103 # we run lsupdates after config update
233 print "Updating information from the layer source, please wait." 104 print "Updating information from the layer source, please wait."
234 from django.core.management import call_command 105 from django.core.management import call_command
diff --git a/bitbake/lib/toaster/bldcontrol/management/commands/loadconf.py b/bitbake/lib/toaster/bldcontrol/management/commands/loadconf.py
new file mode 100644
index 0000000000..c9af487d9d
--- /dev/null
+++ b/bitbake/lib/toaster/bldcontrol/management/commands/loadconf.py
@@ -0,0 +1,157 @@
1from django.core.management.base import BaseCommand, CommandError
2from orm.models import LayerSource, ToasterSetting, Branch, Layer, Layer_Version
3from orm.models import BitbakeVersion, Release, ReleaseDefaultLayer
4import os
5
6from checksettings import DN
7
8class Command(BaseCommand):
9 help = "Loads a toasterconf.json file in the database"
10 args = "filepath"
11
12 def _reduce_canon_path(self, path):
13 components = []
14 for c in path.split("/"):
15 if c == "..":
16 del components[-1]
17 elif c == ".":
18 pass
19 else:
20 components.append(c)
21 return "/".join(components)
22
23
24 def _import_layer_config(self, filepath):
25 if not os.path.exists(filepath) or not os.path.isfile(filepath):
26 raise Exception("Failed to find toaster config file %s ." % filepath)
27
28 import json, pprint
29 data = json.loads(open(filepath, "r").read())
30
31 # verify config file validity before updating settings
32 for i in ['bitbake', 'releases', 'defaultrelease', 'config', 'layersources']:
33 assert i in data
34
35 def _read_git_url_from_local_repository(address):
36 url = None
37 # we detect the remote name at runtime
38 import subprocess
39 (remote, remote_name) = address.split(":", 1)
40 cmd = subprocess.Popen("git remote -v", shell=True, cwd = os.path.dirname(filepath), stdout=subprocess.PIPE, stderr = subprocess.PIPE)
41 (out,err) = cmd.communicate()
42 if cmd.returncode != 0:
43 raise Exception("Error while importing layer vcs_url: git error: %s" % err)
44 for line in out.split("\n"):
45 try:
46 (name, path) = line.split("\t", 1)
47 if name == remote_name:
48 url = path.split(" ")[0]
49 break
50 except ValueError:
51 pass
52 if url == None:
53 raise Exception("Error while looking for remote \"%s\" in \"s\"" % (remote_name, lo.local_path))
54 return url
55
56
57 # import bitbake data
58 for bvi in data['bitbake']:
59 bvo, created = BitbakeVersion.objects.get_or_create(name=bvi['name'])
60 bvo.giturl = bvi['giturl']
61 if bvi['giturl'].startswith("remote:"):
62 bvo.giturl = _read_git_url_from_local_repository(bvi['giturl'])
63 bvo.branch = bvi['branch']
64 bvo.dirpath = bvi['dirpath']
65 bvo.save()
66
67 # set the layer sources
68 for lsi in data['layersources']:
69 assert 'sourcetype' in lsi
70 assert 'apiurl' in lsi
71 assert 'name' in lsi
72 assert 'branches' in lsi
73
74 if lsi['sourcetype'] == LayerSource.TYPE_LAYERINDEX or lsi['apiurl'].startswith("/"):
75 apiurl = lsi['apiurl']
76 else:
77 apiurl = self._reduce_canon_path(os.path.join(DN(filepath), lsi['apiurl']))
78
79 try:
80 ls = LayerSource.objects.get(sourcetype = lsi['sourcetype'], apiurl = apiurl)
81 except LayerSource.DoesNotExist:
82 ls = LayerSource.objects.create(
83 name = lsi['name'],
84 sourcetype = lsi['sourcetype'],
85 apiurl = apiurl
86 )
87
88 layerbranches = []
89 for branchname in lsi['branches']:
90 bo, created = Branch.objects.get_or_create(layer_source = ls, name = branchname)
91 layerbranches.append(bo)
92
93 if 'layers' in lsi:
94 for layerinfo in lsi['layers']:
95 lo, created = Layer.objects.get_or_create(layer_source = ls, name = layerinfo['name'])
96 if layerinfo['local_path'].startswith("/"):
97 lo.local_path = layerinfo['local_path']
98 else:
99 lo.local_path = self._reduce_canon_path(os.path.join(DN(DN(DN(filepath))), layerinfo['local_path']))
100
101 if not os.path.exists(lo.local_path):
102 raise Exception("Local layer path %s must exists." % lo.local_path)
103
104 lo.vcs_url = layerinfo['vcs_url']
105 if layerinfo['vcs_url'].startswith("remote:"):
106 lo.vcs_url = _read_git_url_from_local_repository(layerinfo['vcs_url'])
107
108 if 'layer_index_url' in layerinfo:
109 lo.layer_index_url = layerinfo['layer_index_url']
110 lo.save()
111
112 for branch in layerbranches:
113 lvo, created = Layer_Version.objects.get_or_create(layer_source = ls,
114 up_branch = branch,
115 commit = branch.name,
116 layer = lo)
117 lvo.dirpath = layerinfo['dirpath']
118 lvo.save()
119 # set releases
120 for ri in data['releases']:
121 bvo = BitbakeVersion.objects.get(name = ri['bitbake'])
122 assert bvo is not None
123
124 ro, created = Release.objects.get_or_create(name = ri['name'], bitbake_version = bvo, branch = Branch.objects.get( layer_source__name = ri['layersource'], name=ri['branch']))
125 ro.description = ri['description']
126 ro.helptext = ri['helptext']
127 ro.save()
128
129 for dli in ri['defaultlayers']:
130 layer, created = Layer.objects.get_or_create(
131 layer_source = LayerSource.objects.get(name = ri['layersource']),
132 name = dli
133 )
134 ReleaseDefaultLayer.objects.get_or_create( release = ro, layer = layer)
135
136 # set default release
137 if ToasterSetting.objects.filter(name = "DEFAULT_RELEASE").count() > 0:
138 ToasterSetting.objects.filter(name = "DEFAULT_RELEASE").update(value = data['defaultrelease'])
139 else:
140 ToasterSetting.objects.create(name = "DEFAULT_RELEASE", value = data['defaultrelease'])
141
142 # set default config variables
143 for configname in data['config']:
144 if ToasterSetting.objects.filter(name = "DEFCONF_" + configname).count() > 0:
145 ToasterSetting.objects.filter(name = "DEFCONF_" + configname).update(value = data['config'][configname])
146 else:
147 ToasterSetting.objects.create(name = "DEFCONF_" + configname, value = data['config'][configname])
148
149
150 def handle(self, *args, **options):
151 if len(args) == 0:
152 raise CommandError("Need a path to the toasterconf.json file")
153 filepath = args[0]
154 self._import_layer_config(filepath)
155
156
157