diff options
author | Tudor Florea <tudor.florea@enea.com> | 2014-10-16 03:05:19 +0200 |
---|---|---|
committer | Tudor Florea <tudor.florea@enea.com> | 2014-10-16 03:05:19 +0200 |
commit | c527fd1f14c27855a37f2e8ac5346ce8d940ced2 (patch) | |
tree | bb002c1fdf011c41dbd2f0927bed23ecb5f83c97 /meta/lib/oe/manifest.py | |
download | poky-c527fd1f14c27855a37f2e8ac5346ce8d940ced2.tar.gz |
initial commit for Enea Linux 4.0-140929daisy-140929
Migrated from the internal git server on the daisy-enea-point-release branch
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Diffstat (limited to 'meta/lib/oe/manifest.py')
-rw-r--r-- | meta/lib/oe/manifest.py | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/meta/lib/oe/manifest.py b/meta/lib/oe/manifest.py new file mode 100644 index 0000000000..afda76be66 --- /dev/null +++ b/meta/lib/oe/manifest.py | |||
@@ -0,0 +1,345 @@ | |||
1 | from abc import ABCMeta, abstractmethod | ||
2 | import os | ||
3 | import re | ||
4 | import bb | ||
5 | |||
6 | |||
7 | class Manifest(object): | ||
8 | """ | ||
9 | This is an abstract class. Do not instantiate this directly. | ||
10 | """ | ||
11 | __metaclass__ = ABCMeta | ||
12 | |||
13 | PKG_TYPE_MUST_INSTALL = "mip" | ||
14 | PKG_TYPE_MULTILIB = "mlp" | ||
15 | PKG_TYPE_LANGUAGE = "lgp" | ||
16 | PKG_TYPE_ATTEMPT_ONLY = "aop" | ||
17 | |||
18 | MANIFEST_TYPE_IMAGE = "image" | ||
19 | MANIFEST_TYPE_SDK_HOST = "sdk_host" | ||
20 | MANIFEST_TYPE_SDK_TARGET = "sdk_target" | ||
21 | |||
22 | var_maps = { | ||
23 | MANIFEST_TYPE_IMAGE: { | ||
24 | "PACKAGE_INSTALL": PKG_TYPE_MUST_INSTALL, | ||
25 | "PACKAGE_INSTALL_ATTEMPTONLY": PKG_TYPE_ATTEMPT_ONLY, | ||
26 | "LINGUAS_INSTALL": PKG_TYPE_LANGUAGE | ||
27 | }, | ||
28 | MANIFEST_TYPE_SDK_HOST: { | ||
29 | "TOOLCHAIN_HOST_TASK": PKG_TYPE_MUST_INSTALL, | ||
30 | "TOOLCHAIN_HOST_TASK_ATTEMPTONLY": PKG_TYPE_ATTEMPT_ONLY | ||
31 | }, | ||
32 | MANIFEST_TYPE_SDK_TARGET: { | ||
33 | "TOOLCHAIN_TARGET_TASK": PKG_TYPE_MUST_INSTALL, | ||
34 | "TOOLCHAIN_TARGET_ATTEMPTONLY": PKG_TYPE_ATTEMPT_ONLY | ||
35 | } | ||
36 | } | ||
37 | |||
38 | INSTALL_ORDER = [ | ||
39 | PKG_TYPE_LANGUAGE, | ||
40 | PKG_TYPE_MUST_INSTALL, | ||
41 | PKG_TYPE_ATTEMPT_ONLY, | ||
42 | PKG_TYPE_MULTILIB | ||
43 | ] | ||
44 | |||
45 | initial_manifest_file_header = \ | ||
46 | "# This file was generated automatically and contains the packages\n" \ | ||
47 | "# passed on to the package manager in order to create the rootfs.\n\n" \ | ||
48 | "# Format:\n" \ | ||
49 | "# <package_type>,<package_name>\n" \ | ||
50 | "# where:\n" \ | ||
51 | "# <package_type> can be:\n" \ | ||
52 | "# 'mip' = must install package\n" \ | ||
53 | "# 'aop' = attempt only package\n" \ | ||
54 | "# 'mlp' = multilib package\n" \ | ||
55 | "# 'lgp' = language package\n\n" | ||
56 | |||
57 | def __init__(self, d, manifest_dir=None, manifest_type=MANIFEST_TYPE_IMAGE): | ||
58 | self.d = d | ||
59 | self.manifest_type = manifest_type | ||
60 | |||
61 | if manifest_dir is None: | ||
62 | if manifest_type != self.MANIFEST_TYPE_IMAGE: | ||
63 | self.manifest_dir = self.d.getVar('SDK_DIR', True) | ||
64 | else: | ||
65 | self.manifest_dir = self.d.getVar('WORKDIR', True) | ||
66 | else: | ||
67 | self.manifest_dir = manifest_dir | ||
68 | |||
69 | bb.utils.mkdirhier(self.manifest_dir) | ||
70 | |||
71 | self.initial_manifest = os.path.join(self.manifest_dir, "%s_initial_manifest" % manifest_type) | ||
72 | self.final_manifest = os.path.join(self.manifest_dir, "%s_final_manifest" % manifest_type) | ||
73 | self.full_manifest = os.path.join(self.manifest_dir, "%s_full_manifest" % manifest_type) | ||
74 | |||
75 | # packages in the following vars will be split in 'must install' and | ||
76 | # 'multilib' | ||
77 | self.vars_to_split = ["PACKAGE_INSTALL", | ||
78 | "TOOLCHAIN_HOST_TASK", | ||
79 | "TOOLCHAIN_TARGET_TASK"] | ||
80 | |||
81 | """ | ||
82 | This creates a standard initial manifest for core-image-(minimal|sato|sato-sdk). | ||
83 | This will be used for testing until the class is implemented properly! | ||
84 | """ | ||
85 | def _create_dummy_initial(self): | ||
86 | image_rootfs = self.d.getVar('IMAGE_ROOTFS', True) | ||
87 | pkg_list = dict() | ||
88 | if image_rootfs.find("core-image-sato-sdk") > 0: | ||
89 | pkg_list[self.PKG_TYPE_MUST_INSTALL] = \ | ||
90 | "packagegroup-core-x11-sato-games packagegroup-base-extended " \ | ||
91 | "packagegroup-core-x11-sato packagegroup-core-x11-base " \ | ||
92 | "packagegroup-core-sdk packagegroup-core-tools-debug " \ | ||
93 | "packagegroup-core-boot packagegroup-core-tools-testapps " \ | ||
94 | "packagegroup-core-eclipse-debug packagegroup-core-qt-demoapps " \ | ||
95 | "apt packagegroup-core-tools-profile psplash " \ | ||
96 | "packagegroup-core-standalone-sdk-target " \ | ||
97 | "packagegroup-core-ssh-openssh dpkg kernel-dev" | ||
98 | pkg_list[self.PKG_TYPE_LANGUAGE] = \ | ||
99 | "locale-base-en-us locale-base-en-gb" | ||
100 | elif image_rootfs.find("core-image-sato") > 0: | ||
101 | pkg_list[self.PKG_TYPE_MUST_INSTALL] = \ | ||
102 | "packagegroup-core-ssh-dropbear packagegroup-core-x11-sato-games " \ | ||
103 | "packagegroup-core-x11-base psplash apt dpkg packagegroup-base-extended " \ | ||
104 | "packagegroup-core-x11-sato packagegroup-core-boot" | ||
105 | pkg_list['lgp'] = \ | ||
106 | "locale-base-en-us locale-base-en-gb" | ||
107 | elif image_rootfs.find("core-image-minimal") > 0: | ||
108 | pkg_list[self.PKG_TYPE_MUST_INSTALL] = "run-postinsts packagegroup-core-boot" | ||
109 | |||
110 | with open(self.initial_manifest, "w+") as manifest: | ||
111 | manifest.write(self.initial_manifest_file_header) | ||
112 | |||
113 | for pkg_type in pkg_list: | ||
114 | for pkg in pkg_list[pkg_type].split(): | ||
115 | manifest.write("%s,%s\n" % (pkg_type, pkg)) | ||
116 | |||
117 | """ | ||
118 | This will create the initial manifest which will be used by Rootfs class to | ||
119 | generate the rootfs | ||
120 | """ | ||
121 | @abstractmethod | ||
122 | def create_initial(self): | ||
123 | pass | ||
124 | |||
125 | """ | ||
126 | This creates the manifest after everything has been installed. | ||
127 | """ | ||
128 | @abstractmethod | ||
129 | def create_final(self): | ||
130 | pass | ||
131 | |||
132 | """ | ||
133 | This creates the manifest after the package in initial manifest has been | ||
134 | dummy installed. It lists all *to be installed* packages. There is no real | ||
135 | installation, just a test. | ||
136 | """ | ||
137 | @abstractmethod | ||
138 | def create_full(self, pm): | ||
139 | pass | ||
140 | |||
141 | """ | ||
142 | The following function parses an initial manifest and returns a dictionary | ||
143 | object with the must install, attempt only, multilib and language packages. | ||
144 | """ | ||
145 | def parse_initial_manifest(self): | ||
146 | pkgs = dict() | ||
147 | |||
148 | with open(self.initial_manifest) as manifest: | ||
149 | for line in manifest.read().split('\n'): | ||
150 | comment = re.match("^#.*", line) | ||
151 | pattern = "^(%s|%s|%s|%s),(.*)$" % \ | ||
152 | (self.PKG_TYPE_MUST_INSTALL, | ||
153 | self.PKG_TYPE_ATTEMPT_ONLY, | ||
154 | self.PKG_TYPE_MULTILIB, | ||
155 | self.PKG_TYPE_LANGUAGE) | ||
156 | pkg = re.match(pattern, line) | ||
157 | |||
158 | if comment is not None: | ||
159 | continue | ||
160 | |||
161 | if pkg is not None: | ||
162 | pkg_type = pkg.group(1) | ||
163 | pkg_name = pkg.group(2) | ||
164 | |||
165 | if not pkg_type in pkgs: | ||
166 | pkgs[pkg_type] = [pkg_name] | ||
167 | else: | ||
168 | pkgs[pkg_type].append(pkg_name) | ||
169 | |||
170 | return pkgs | ||
171 | |||
172 | ''' | ||
173 | This following function parses a full manifest and return a list | ||
174 | object with packages. | ||
175 | ''' | ||
176 | def parse_full_manifest(self): | ||
177 | installed_pkgs = list() | ||
178 | if not os.path.exists(self.full_manifest): | ||
179 | bb.note('full manifest not exist') | ||
180 | return installed_pkgs | ||
181 | |||
182 | with open(self.full_manifest, 'r') as manifest: | ||
183 | for pkg in manifest.read().split('\n'): | ||
184 | installed_pkgs.append(pkg.strip()) | ||
185 | |||
186 | return installed_pkgs | ||
187 | |||
188 | |||
189 | class RpmManifest(Manifest): | ||
190 | """ | ||
191 | Returns a dictionary object with mip and mlp packages. | ||
192 | """ | ||
193 | def _split_multilib(self, pkg_list): | ||
194 | pkgs = dict() | ||
195 | |||
196 | for pkg in pkg_list.split(): | ||
197 | pkg_type = self.PKG_TYPE_MUST_INSTALL | ||
198 | |||
199 | ml_variants = self.d.getVar('MULTILIB_VARIANTS', True).split() | ||
200 | |||
201 | for ml_variant in ml_variants: | ||
202 | if pkg.startswith(ml_variant + '-'): | ||
203 | pkg_type = self.PKG_TYPE_MULTILIB | ||
204 | |||
205 | if not pkg_type in pkgs: | ||
206 | pkgs[pkg_type] = pkg | ||
207 | else: | ||
208 | pkgs[pkg_type] += " " + pkg | ||
209 | |||
210 | return pkgs | ||
211 | |||
212 | def create_initial(self): | ||
213 | pkgs = dict() | ||
214 | |||
215 | with open(self.initial_manifest, "w+") as manifest: | ||
216 | manifest.write(self.initial_manifest_file_header) | ||
217 | |||
218 | for var in self.var_maps[self.manifest_type]: | ||
219 | if var in self.vars_to_split: | ||
220 | split_pkgs = self._split_multilib(self.d.getVar(var, True)) | ||
221 | if split_pkgs is not None: | ||
222 | pkgs = dict(pkgs.items() + split_pkgs.items()) | ||
223 | else: | ||
224 | pkg_list = self.d.getVar(var, True) | ||
225 | if pkg_list is not None: | ||
226 | pkgs[self.var_maps[self.manifest_type][var]] = self.d.getVar(var, True) | ||
227 | |||
228 | for pkg_type in pkgs: | ||
229 | for pkg in pkgs[pkg_type].split(): | ||
230 | manifest.write("%s,%s\n" % (pkg_type, pkg)) | ||
231 | |||
232 | def create_final(self): | ||
233 | pass | ||
234 | |||
235 | def create_full(self, pm): | ||
236 | pass | ||
237 | |||
238 | |||
239 | class OpkgManifest(Manifest): | ||
240 | """ | ||
241 | Returns a dictionary object with mip and mlp packages. | ||
242 | """ | ||
243 | def _split_multilib(self, pkg_list): | ||
244 | pkgs = dict() | ||
245 | |||
246 | for pkg in pkg_list.split(): | ||
247 | pkg_type = self.PKG_TYPE_MUST_INSTALL | ||
248 | |||
249 | ml_variants = self.d.getVar('MULTILIB_VARIANTS', True).split() | ||
250 | |||
251 | for ml_variant in ml_variants: | ||
252 | if pkg.startswith(ml_variant + '-'): | ||
253 | pkg_type = self.PKG_TYPE_MULTILIB | ||
254 | |||
255 | if not pkg_type in pkgs: | ||
256 | pkgs[pkg_type] = pkg | ||
257 | else: | ||
258 | pkgs[pkg_type] += " " + pkg | ||
259 | |||
260 | return pkgs | ||
261 | |||
262 | def create_initial(self): | ||
263 | pkgs = dict() | ||
264 | |||
265 | with open(self.initial_manifest, "w+") as manifest: | ||
266 | manifest.write(self.initial_manifest_file_header) | ||
267 | |||
268 | for var in self.var_maps[self.manifest_type]: | ||
269 | if var in self.vars_to_split: | ||
270 | split_pkgs = self._split_multilib(self.d.getVar(var, True)) | ||
271 | if split_pkgs is not None: | ||
272 | pkgs = dict(pkgs.items() + split_pkgs.items()) | ||
273 | else: | ||
274 | pkg_list = self.d.getVar(var, True) | ||
275 | if pkg_list is not None: | ||
276 | pkgs[self.var_maps[self.manifest_type][var]] = self.d.getVar(var, True) | ||
277 | |||
278 | for pkg_type in pkgs: | ||
279 | for pkg in pkgs[pkg_type].split(): | ||
280 | manifest.write("%s,%s\n" % (pkg_type, pkg)) | ||
281 | |||
282 | def create_final(self): | ||
283 | pass | ||
284 | |||
285 | def create_full(self, pm): | ||
286 | if not os.path.exists(self.initial_manifest): | ||
287 | self.create_initial() | ||
288 | |||
289 | initial_manifest = self.parse_initial_manifest() | ||
290 | pkgs_to_install = list() | ||
291 | for pkg_type in initial_manifest: | ||
292 | pkgs_to_install += initial_manifest[pkg_type] | ||
293 | if len(pkgs_to_install) == 0: | ||
294 | return | ||
295 | |||
296 | output = pm.dummy_install(pkgs_to_install) | ||
297 | |||
298 | with open(self.full_manifest, 'w+') as manifest: | ||
299 | pkg_re = re.compile('^Installing ([^ ]+) [^ ].*') | ||
300 | for line in set(output.split('\n')): | ||
301 | m = pkg_re.match(line) | ||
302 | if m: | ||
303 | manifest.write(m.group(1) + '\n') | ||
304 | |||
305 | return | ||
306 | |||
307 | |||
308 | class DpkgManifest(Manifest): | ||
309 | def create_initial(self): | ||
310 | with open(self.initial_manifest, "w+") as manifest: | ||
311 | manifest.write(self.initial_manifest_file_header) | ||
312 | |||
313 | for var in self.var_maps[self.manifest_type]: | ||
314 | pkg_list = self.d.getVar(var, True) | ||
315 | |||
316 | if pkg_list is None: | ||
317 | continue | ||
318 | |||
319 | for pkg in pkg_list.split(): | ||
320 | manifest.write("%s,%s\n" % | ||
321 | (self.var_maps[self.manifest_type][var], pkg)) | ||
322 | |||
323 | def create_final(self): | ||
324 | pass | ||
325 | |||
326 | def create_full(self, pm): | ||
327 | pass | ||
328 | |||
329 | |||
330 | def create_manifest(d, final_manifest=False, manifest_dir=None, | ||
331 | manifest_type=Manifest.MANIFEST_TYPE_IMAGE): | ||
332 | manifest_map = {'rpm': RpmManifest, | ||
333 | 'ipk': OpkgManifest, | ||
334 | 'deb': DpkgManifest} | ||
335 | |||
336 | manifest = manifest_map[d.getVar('IMAGE_PKGTYPE', True)](d, manifest_dir, manifest_type) | ||
337 | |||
338 | if final_manifest: | ||
339 | manifest.create_final() | ||
340 | else: | ||
341 | manifest.create_initial() | ||
342 | |||
343 | |||
344 | if __name__ == "__main__": | ||
345 | pass | ||