diff options
Diffstat (limited to 'meta/classes/license_image.bbclass')
-rw-r--r-- | meta/classes/license_image.bbclass | 269 |
1 files changed, 0 insertions, 269 deletions
diff --git a/meta/classes/license_image.bbclass b/meta/classes/license_image.bbclass deleted file mode 100644 index c96b032ebd..0000000000 --- a/meta/classes/license_image.bbclass +++ /dev/null | |||
@@ -1,269 +0,0 @@ | |||
1 | python write_package_manifest() { | ||
2 | # Get list of installed packages | ||
3 | license_image_dir = d.expand('${LICENSE_DIRECTORY}/${IMAGE_NAME}') | ||
4 | bb.utils.mkdirhier(license_image_dir) | ||
5 | from oe.rootfs import image_list_installed_packages | ||
6 | from oe.utils import format_pkg_list | ||
7 | |||
8 | pkgs = image_list_installed_packages(d) | ||
9 | output = format_pkg_list(pkgs) | ||
10 | open(os.path.join(license_image_dir, 'package.manifest'), | ||
11 | 'w+').write(output) | ||
12 | } | ||
13 | |||
14 | python license_create_manifest() { | ||
15 | import oe.packagedata | ||
16 | from oe.rootfs import image_list_installed_packages | ||
17 | |||
18 | build_images_from_feeds = d.getVar('BUILD_IMAGES_FROM_FEEDS') | ||
19 | if build_images_from_feeds == "1": | ||
20 | return 0 | ||
21 | |||
22 | pkg_dic = {} | ||
23 | for pkg in sorted(image_list_installed_packages(d)): | ||
24 | pkg_info = os.path.join(d.getVar('PKGDATA_DIR'), | ||
25 | 'runtime-reverse', pkg) | ||
26 | pkg_name = os.path.basename(os.readlink(pkg_info)) | ||
27 | |||
28 | pkg_dic[pkg_name] = oe.packagedata.read_pkgdatafile(pkg_info) | ||
29 | if not "LICENSE" in pkg_dic[pkg_name].keys(): | ||
30 | pkg_lic_name = "LICENSE_" + pkg_name | ||
31 | pkg_dic[pkg_name]["LICENSE"] = pkg_dic[pkg_name][pkg_lic_name] | ||
32 | |||
33 | rootfs_license_manifest = os.path.join(d.getVar('LICENSE_DIRECTORY'), | ||
34 | d.getVar('IMAGE_NAME'), 'license.manifest') | ||
35 | write_license_files(d, rootfs_license_manifest, pkg_dic, rootfs=True) | ||
36 | } | ||
37 | |||
38 | def write_license_files(d, license_manifest, pkg_dic, rootfs=True): | ||
39 | import re | ||
40 | import stat | ||
41 | |||
42 | bad_licenses = (d.getVar("INCOMPATIBLE_LICENSE") or "").split() | ||
43 | bad_licenses = expand_wildcard_licenses(d, bad_licenses) | ||
44 | |||
45 | whitelist = [] | ||
46 | for lic in bad_licenses: | ||
47 | whitelist.extend((d.getVar("WHITELIST_" + lic) or "").split()) | ||
48 | |||
49 | with open(license_manifest, "w") as license_file: | ||
50 | for pkg in sorted(pkg_dic): | ||
51 | if bad_licenses and pkg not in whitelist: | ||
52 | try: | ||
53 | licenses = incompatible_pkg_license(d, bad_licenses, pkg_dic[pkg]["LICENSE"]) | ||
54 | if licenses: | ||
55 | bb.fatal("Package %s cannot be installed into the image because it has incompatible license(s): %s" %(pkg, ' '.join(licenses))) | ||
56 | (pkg_dic[pkg]["LICENSE"], pkg_dic[pkg]["LICENSES"]) = \ | ||
57 | oe.license.manifest_licenses(pkg_dic[pkg]["LICENSE"], | ||
58 | bad_licenses, canonical_license, d) | ||
59 | except oe.license.LicenseError as exc: | ||
60 | bb.fatal('%s: %s' % (d.getVar('P'), exc)) | ||
61 | else: | ||
62 | pkg_dic[pkg]["LICENSES"] = re.sub(r'[|&()*]', ' ', pkg_dic[pkg]["LICENSE"]) | ||
63 | pkg_dic[pkg]["LICENSES"] = re.sub(r' *', ' ', pkg_dic[pkg]["LICENSES"]) | ||
64 | pkg_dic[pkg]["LICENSES"] = pkg_dic[pkg]["LICENSES"].split() | ||
65 | if pkg in whitelist: | ||
66 | bb.warn("Including %s with an incompatible license %s into the image, because it has been whitelisted." %(pkg, pkg_dic[pkg]["LICENSE"])) | ||
67 | |||
68 | if not "IMAGE_MANIFEST" in pkg_dic[pkg]: | ||
69 | # Rootfs manifest | ||
70 | license_file.write("PACKAGE NAME: %s\n" % pkg) | ||
71 | license_file.write("PACKAGE VERSION: %s\n" % pkg_dic[pkg]["PV"]) | ||
72 | license_file.write("RECIPE NAME: %s\n" % pkg_dic[pkg]["PN"]) | ||
73 | license_file.write("LICENSE: %s\n\n" % pkg_dic[pkg]["LICENSE"]) | ||
74 | |||
75 | # If the package doesn't contain any file, that is, its size is 0, the license | ||
76 | # isn't relevant as far as the final image is concerned. So doing license check | ||
77 | # doesn't make much sense, skip it. | ||
78 | if pkg_dic[pkg]["PKGSIZE_%s" % pkg] == "0": | ||
79 | continue | ||
80 | else: | ||
81 | # Image manifest | ||
82 | license_file.write("RECIPE NAME: %s\n" % pkg_dic[pkg]["PN"]) | ||
83 | license_file.write("VERSION: %s\n" % pkg_dic[pkg]["PV"]) | ||
84 | license_file.write("LICENSE: %s\n" % pkg_dic[pkg]["LICENSE"]) | ||
85 | license_file.write("FILES: %s\n\n" % pkg_dic[pkg]["FILES"]) | ||
86 | |||
87 | for lic in pkg_dic[pkg]["LICENSES"]: | ||
88 | lic_file = os.path.join(d.getVar('LICENSE_DIRECTORY'), | ||
89 | pkg_dic[pkg]["PN"], "generic_%s" % | ||
90 | re.sub(r'\+', '', lic)) | ||
91 | # add explicity avoid of CLOSED license because isn't generic | ||
92 | if lic == "CLOSED": | ||
93 | continue | ||
94 | |||
95 | if not os.path.exists(lic_file): | ||
96 | bb.warn("The license listed %s was not in the "\ | ||
97 | "licenses collected for recipe %s" | ||
98 | % (lic, pkg_dic[pkg]["PN"])) | ||
99 | |||
100 | # Two options here: | ||
101 | # - Just copy the manifest | ||
102 | # - Copy the manifest and the license directories | ||
103 | # With both options set we see a .5 M increase in core-image-minimal | ||
104 | copy_lic_manifest = d.getVar('COPY_LIC_MANIFEST') | ||
105 | copy_lic_dirs = d.getVar('COPY_LIC_DIRS') | ||
106 | if rootfs and copy_lic_manifest == "1": | ||
107 | rootfs_license_dir = os.path.join(d.getVar('IMAGE_ROOTFS'), | ||
108 | 'usr', 'share', 'common-licenses') | ||
109 | bb.utils.mkdirhier(rootfs_license_dir) | ||
110 | rootfs_license_manifest = os.path.join(rootfs_license_dir, | ||
111 | os.path.split(license_manifest)[1]) | ||
112 | if not os.path.exists(rootfs_license_manifest): | ||
113 | oe.path.copyhardlink(license_manifest, rootfs_license_manifest) | ||
114 | |||
115 | if copy_lic_dirs == "1": | ||
116 | for pkg in sorted(pkg_dic): | ||
117 | pkg_rootfs_license_dir = os.path.join(rootfs_license_dir, pkg) | ||
118 | bb.utils.mkdirhier(pkg_rootfs_license_dir) | ||
119 | pkg_license_dir = os.path.join(d.getVar('LICENSE_DIRECTORY'), | ||
120 | pkg_dic[pkg]["PN"]) | ||
121 | |||
122 | pkg_manifest_licenses = [canonical_license(d, lic) \ | ||
123 | for lic in pkg_dic[pkg]["LICENSES"]] | ||
124 | |||
125 | licenses = os.listdir(pkg_license_dir) | ||
126 | for lic in licenses: | ||
127 | pkg_license = os.path.join(pkg_license_dir, lic) | ||
128 | pkg_rootfs_license = os.path.join(pkg_rootfs_license_dir, lic) | ||
129 | |||
130 | if re.match(r"^generic_.*$", lic): | ||
131 | generic_lic = canonical_license(d, | ||
132 | re.search(r"^generic_(.*)$", lic).group(1)) | ||
133 | |||
134 | # Do not copy generic license into package if isn't | ||
135 | # declared into LICENSES of the package. | ||
136 | if not re.sub(r'\+$', '', generic_lic) in \ | ||
137 | [re.sub(r'\+', '', lic) for lic in \ | ||
138 | pkg_manifest_licenses]: | ||
139 | continue | ||
140 | |||
141 | if oe.license.license_ok(generic_lic, | ||
142 | bad_licenses) == False: | ||
143 | continue | ||
144 | |||
145 | # Make sure we use only canonical name for the license file | ||
146 | rootfs_license = os.path.join(rootfs_license_dir, "generic_%s" % generic_lic) | ||
147 | if not os.path.exists(rootfs_license): | ||
148 | oe.path.copyhardlink(pkg_license, rootfs_license) | ||
149 | |||
150 | if not os.path.exists(pkg_rootfs_license): | ||
151 | os.symlink(os.path.join('..', lic), pkg_rootfs_license) | ||
152 | else: | ||
153 | if (oe.license.license_ok(canonical_license(d, | ||
154 | lic), bad_licenses) == False or | ||
155 | os.path.exists(pkg_rootfs_license)): | ||
156 | continue | ||
157 | |||
158 | oe.path.copyhardlink(pkg_license, pkg_rootfs_license) | ||
159 | # Fixup file ownership and permissions | ||
160 | for walkroot, dirs, files in os.walk(rootfs_license_dir): | ||
161 | for f in files: | ||
162 | p = os.path.join(walkroot, f) | ||
163 | os.lchown(p, 0, 0) | ||
164 | if not os.path.islink(p): | ||
165 | os.chmod(p, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) | ||
166 | for dir in dirs: | ||
167 | p = os.path.join(walkroot, dir) | ||
168 | os.lchown(p, 0, 0) | ||
169 | os.chmod(p, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) | ||
170 | |||
171 | |||
172 | |||
173 | def license_deployed_manifest(d): | ||
174 | """ | ||
175 | Write the license manifest for the deployed recipes. | ||
176 | The deployed recipes usually includes the bootloader | ||
177 | and extra files to boot the target. | ||
178 | """ | ||
179 | |||
180 | dep_dic = {} | ||
181 | man_dic = {} | ||
182 | lic_dir = d.getVar("LICENSE_DIRECTORY") | ||
183 | |||
184 | dep_dic = get_deployed_dependencies(d) | ||
185 | for dep in dep_dic.keys(): | ||
186 | man_dic[dep] = {} | ||
187 | # It is necessary to mark this will be used for image manifest | ||
188 | man_dic[dep]["IMAGE_MANIFEST"] = True | ||
189 | man_dic[dep]["PN"] = dep | ||
190 | man_dic[dep]["FILES"] = \ | ||
191 | " ".join(get_deployed_files(dep_dic[dep])) | ||
192 | with open(os.path.join(lic_dir, dep, "recipeinfo"), "r") as f: | ||
193 | for line in f.readlines(): | ||
194 | key,val = line.split(": ", 1) | ||
195 | man_dic[dep][key] = val[:-1] | ||
196 | |||
197 | lic_manifest_dir = os.path.join(d.getVar('LICENSE_DIRECTORY'), | ||
198 | d.getVar('IMAGE_NAME')) | ||
199 | bb.utils.mkdirhier(lic_manifest_dir) | ||
200 | image_license_manifest = os.path.join(lic_manifest_dir, 'image_license.manifest') | ||
201 | write_license_files(d, image_license_manifest, man_dic, rootfs=False) | ||
202 | |||
203 | link_name = d.getVar('IMAGE_LINK_NAME') | ||
204 | if link_name: | ||
205 | lic_manifest_symlink_dir = os.path.join(d.getVar('LICENSE_DIRECTORY'), | ||
206 | link_name) | ||
207 | # remove old symlink | ||
208 | if os.path.islink(lic_manifest_symlink_dir): | ||
209 | os.unlink(lic_manifest_symlink_dir) | ||
210 | |||
211 | # create the image dir symlink | ||
212 | if lic_manifest_dir != lic_manifest_symlink_dir: | ||
213 | os.symlink(lic_manifest_dir, lic_manifest_symlink_dir) | ||
214 | |||
215 | def get_deployed_dependencies(d): | ||
216 | """ | ||
217 | Get all the deployed dependencies of an image | ||
218 | """ | ||
219 | |||
220 | deploy = {} | ||
221 | # Get all the dependencies for the current task (rootfs). | ||
222 | taskdata = d.getVar("BB_TASKDEPDATA", False) | ||
223 | pn = d.getVar("PN", True) | ||
224 | depends = list(set([dep[0] for dep | ||
225 | in list(taskdata.values()) | ||
226 | if not dep[0].endswith("-native") and not dep[0] == pn])) | ||
227 | |||
228 | # To verify what was deployed it checks the rootfs dependencies against | ||
229 | # the SSTATE_MANIFESTS for "deploy" task. | ||
230 | # The manifest file name contains the arch. Because we are not running | ||
231 | # in the recipe context it is necessary to check every arch used. | ||
232 | sstate_manifest_dir = d.getVar("SSTATE_MANIFESTS") | ||
233 | archs = list(set(d.getVar("SSTATE_ARCHS").split())) | ||
234 | for dep in depends: | ||
235 | for arch in archs: | ||
236 | sstate_manifest_file = os.path.join(sstate_manifest_dir, | ||
237 | "manifest-%s-%s.deploy" % (arch, dep)) | ||
238 | if os.path.exists(sstate_manifest_file): | ||
239 | deploy[dep] = sstate_manifest_file | ||
240 | break | ||
241 | |||
242 | return deploy | ||
243 | get_deployed_dependencies[vardepsexclude] = "BB_TASKDEPDATA" | ||
244 | |||
245 | def get_deployed_files(man_file): | ||
246 | """ | ||
247 | Get the files deployed from the sstate manifest | ||
248 | """ | ||
249 | |||
250 | dep_files = [] | ||
251 | excluded_files = [] | ||
252 | with open(man_file, "r") as manifest: | ||
253 | all_files = manifest.read() | ||
254 | for f in all_files.splitlines(): | ||
255 | if ((not (os.path.islink(f) or os.path.isdir(f))) and | ||
256 | not os.path.basename(f) in excluded_files): | ||
257 | dep_files.append(os.path.basename(f)) | ||
258 | return dep_files | ||
259 | |||
260 | ROOTFS_POSTPROCESS_COMMAND_prepend = "write_package_manifest; license_create_manifest; " | ||
261 | do_rootfs[recrdeptask] += "do_populate_lic" | ||
262 | |||
263 | python do_populate_lic_deploy() { | ||
264 | license_deployed_manifest(d) | ||
265 | } | ||
266 | |||
267 | addtask populate_lic_deploy before do_build after do_image_complete | ||
268 | do_populate_lic_deploy[recrdeptask] += "do_populate_lic do_deploy" | ||
269 | |||