diff options
Diffstat (limited to 'meta/classes/image.bbclass')
-rw-r--r-- | meta/classes/image.bbclass | 661 |
1 files changed, 661 insertions, 0 deletions
diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass new file mode 100644 index 0000000000..7650594f8c --- /dev/null +++ b/meta/classes/image.bbclass | |||
@@ -0,0 +1,661 @@ | |||
1 | inherit rootfs_${IMAGE_PKGTYPE} | ||
2 | |||
3 | inherit populate_sdk_base | ||
4 | |||
5 | TOOLCHAIN_TARGET_TASK += "${PACKAGE_INSTALL}" | ||
6 | TOOLCHAIN_TARGET_TASK_ATTEMPTONLY += "${PACKAGE_INSTALL_ATTEMPTONLY}" | ||
7 | POPULATE_SDK_POST_TARGET_COMMAND += "rootfs_install_complementary populate_sdk; rootfs_sysroot_relativelinks; " | ||
8 | |||
9 | inherit gzipnative | ||
10 | |||
11 | LICENSE = "MIT" | ||
12 | PACKAGES = "" | ||
13 | DEPENDS += "${MLPREFIX}qemuwrapper-cross ${MLPREFIX}depmodwrapper-cross" | ||
14 | RDEPENDS += "${PACKAGE_INSTALL} ${LINGUAS_INSTALL}" | ||
15 | RRECOMMENDS += "${PACKAGE_INSTALL_ATTEMPTONLY}" | ||
16 | |||
17 | INHIBIT_DEFAULT_DEPS = "1" | ||
18 | |||
19 | TESTIMAGECLASS = "${@base_conditional('TEST_IMAGE', '1', 'testimage-auto', '', d)}" | ||
20 | inherit ${TESTIMAGECLASS} | ||
21 | |||
22 | # IMAGE_FEATURES may contain any available package group | ||
23 | IMAGE_FEATURES ?= "" | ||
24 | IMAGE_FEATURES[type] = "list" | ||
25 | IMAGE_FEATURES[validitems] += "debug-tweaks read-only-rootfs package-management" | ||
26 | |||
27 | # rootfs bootstrap install | ||
28 | ROOTFS_BOOTSTRAP_INSTALL = "${@base_contains("IMAGE_FEATURES", "package-management", "", "${ROOTFS_PKGMANAGE_BOOTSTRAP}",d)}" | ||
29 | |||
30 | # packages to install from features | ||
31 | FEATURE_INSTALL = "${@' '.join(oe.packagegroup.required_packages(oe.data.typed_value('IMAGE_FEATURES', d), d))}" | ||
32 | FEATURE_INSTALL_OPTIONAL = "${@' '.join(oe.packagegroup.optional_packages(oe.data.typed_value('IMAGE_FEATURES', d), d))}" | ||
33 | |||
34 | # Define some very basic feature package groups | ||
35 | SPLASH ?= "psplash" | ||
36 | PACKAGE_GROUP_splash = "${SPLASH}" | ||
37 | |||
38 | # Wildcards specifying complementary packages to install for every package that has been explicitly | ||
39 | # installed into the rootfs | ||
40 | COMPLEMENTARY_GLOB[dev-pkgs] = '*-dev' | ||
41 | COMPLEMENTARY_GLOB[staticdev-pkgs] = '*-staticdev' | ||
42 | COMPLEMENTARY_GLOB[doc-pkgs] = '*-doc' | ||
43 | COMPLEMENTARY_GLOB[dbg-pkgs] = '*-dbg' | ||
44 | COMPLEMENTARY_GLOB[ptest-pkgs] = '*-ptest' | ||
45 | |||
46 | def complementary_globs(featurevar, d): | ||
47 | all_globs = d.getVarFlags('COMPLEMENTARY_GLOB') | ||
48 | globs = [] | ||
49 | features = set((d.getVar(featurevar, True) or '').split()) | ||
50 | for name, glob in all_globs.items(): | ||
51 | if name in features: | ||
52 | globs.append(glob) | ||
53 | return ' '.join(globs) | ||
54 | |||
55 | IMAGE_INSTALL_COMPLEMENTARY = '${@complementary_globs("IMAGE_FEATURES", d)}' | ||
56 | SDKIMAGE_FEATURES ??= "dev-pkgs dbg-pkgs" | ||
57 | SDKIMAGE_INSTALL_COMPLEMENTARY = '${@complementary_globs("SDKIMAGE_FEATURES", d)}' | ||
58 | |||
59 | def check_image_features(d): | ||
60 | valid_features = (d.getVarFlag('IMAGE_FEATURES', 'validitems', True) or "").split() | ||
61 | valid_features += d.getVarFlags('COMPLEMENTARY_GLOB').keys() | ||
62 | for var in d: | ||
63 | if var.startswith("PACKAGE_GROUP_"): | ||
64 | valid_features.append(var[14:]) | ||
65 | valid_features.sort() | ||
66 | |||
67 | features = set(oe.data.typed_value('IMAGE_FEATURES', d)) | ||
68 | for feature in features: | ||
69 | if feature not in valid_features: | ||
70 | bb.fatal("'%s' in IMAGE_FEATURES is not a valid image feature. Valid features: %s" % (feature, ' '.join(valid_features))) | ||
71 | |||
72 | IMAGE_INSTALL ?= "" | ||
73 | IMAGE_INSTALL[type] = "list" | ||
74 | export PACKAGE_INSTALL ?= "${IMAGE_INSTALL} ${ROOTFS_BOOTSTRAP_INSTALL} ${FEATURE_INSTALL}" | ||
75 | PACKAGE_INSTALL_ATTEMPTONLY ?= "${FEATURE_INSTALL_OPTIONAL}" | ||
76 | |||
77 | # Images are generally built explicitly, do not need to be part of world. | ||
78 | EXCLUDE_FROM_WORLD = "1" | ||
79 | |||
80 | USE_DEVFS ?= "0" | ||
81 | |||
82 | PID = "${@os.getpid()}" | ||
83 | |||
84 | PACKAGE_ARCH = "${MACHINE_ARCH}" | ||
85 | |||
86 | LDCONFIGDEPEND ?= "ldconfig-native:do_populate_sysroot" | ||
87 | LDCONFIGDEPEND_libc-uclibc = "" | ||
88 | |||
89 | do_rootfs[depends] += "makedevs-native:do_populate_sysroot virtual/fakeroot-native:do_populate_sysroot ${LDCONFIGDEPEND}" | ||
90 | do_rootfs[depends] += "virtual/update-alternatives-native:do_populate_sysroot update-rc.d-native:do_populate_sysroot" | ||
91 | do_rootfs[recrdeptask] += "do_packagedata" | ||
92 | |||
93 | IMAGE_TYPE_live = '${@base_contains("IMAGE_FSTYPES", "live", "live", "empty", d)}' | ||
94 | inherit image-${IMAGE_TYPE_live} | ||
95 | IMAGE_TYPE_vmdk = '${@base_contains("IMAGE_FSTYPES", "vmdk", "vmdk", "empty", d)}' | ||
96 | inherit image-${IMAGE_TYPE_vmdk} | ||
97 | |||
98 | python () { | ||
99 | deps = " " + imagetypes_getdepends(d) | ||
100 | d.appendVarFlag('do_rootfs', 'depends', deps) | ||
101 | |||
102 | deps = "" | ||
103 | for dep in (d.getVar('EXTRA_IMAGEDEPENDS', True) or "").split(): | ||
104 | deps += " %s:do_populate_sysroot" % dep | ||
105 | d.appendVarFlag('do_build', 'depends', deps) | ||
106 | |||
107 | #process IMAGE_FEATURES, we must do this before runtime_mapping_rename | ||
108 | #Check for replaces image features | ||
109 | features = set(oe.data.typed_value('IMAGE_FEATURES', d)) | ||
110 | remain_features = features.copy() | ||
111 | for feature in features: | ||
112 | replaces = set((d.getVar("IMAGE_FEATURES_REPLACES_%s" % feature, True) or "").split()) | ||
113 | remain_features -= replaces | ||
114 | |||
115 | #Check for conflict image features | ||
116 | for feature in remain_features: | ||
117 | conflicts = set((d.getVar("IMAGE_FEATURES_CONFLICTS_%s" % feature, True) or "").split()) | ||
118 | temp = conflicts & remain_features | ||
119 | if temp: | ||
120 | bb.fatal("%s contains conflicting IMAGE_FEATURES %s %s" % (d.getVar('PN', True), feature, ' '.join(list(temp)))) | ||
121 | |||
122 | d.setVar('IMAGE_FEATURES', ' '.join(list(remain_features))) | ||
123 | |||
124 | # Ensure we have the vendor list for complementary package handling | ||
125 | ml_vendor_list = "" | ||
126 | multilibs = d.getVar('MULTILIBS', True) or "" | ||
127 | for ext in multilibs.split(): | ||
128 | eext = ext.split(':') | ||
129 | if len(eext) > 1 and eext[0] == 'multilib': | ||
130 | localdata = bb.data.createCopy(d) | ||
131 | vendor = localdata.getVar("TARGET_VENDOR_virtclass-multilib-" + eext[1], False) | ||
132 | ml_vendor_list += " " + vendor | ||
133 | d.setVar('MULTILIB_VENDORS', ml_vendor_list) | ||
134 | |||
135 | check_image_features(d) | ||
136 | initramfs_image = d.getVar('INITRAMFS_IMAGE', True) or "" | ||
137 | if initramfs_image != "": | ||
138 | d.appendVarFlag('do_build', 'depends', " %s:do_bundle_initramfs" % d.getVar('PN', True)) | ||
139 | d.appendVarFlag('do_bundle_initramfs', 'depends', " %s:do_rootfs" % initramfs_image) | ||
140 | } | ||
141 | |||
142 | # | ||
143 | # Get a list of files containing device tables to create. | ||
144 | # * IMAGE_DEVICE_TABLE is the old name to an absolute path to a device table file | ||
145 | # * IMAGE_DEVICE_TABLES is a new name for a file, or list of files, seached | ||
146 | # for in the BBPATH | ||
147 | # If neither are specified then the default name of files/device_table-minimal.txt | ||
148 | # is searched for in the BBPATH (same as the old version.) | ||
149 | # | ||
150 | def get_devtable_list(d): | ||
151 | devtable = d.getVar('IMAGE_DEVICE_TABLE', True) | ||
152 | if devtable != None: | ||
153 | return devtable | ||
154 | str = "" | ||
155 | devtables = d.getVar('IMAGE_DEVICE_TABLES', True) | ||
156 | if devtables == None: | ||
157 | devtables = 'files/device_table-minimal.txt' | ||
158 | for devtable in devtables.split(): | ||
159 | str += " %s" % bb.utils.which(d.getVar('BBPATH', True), devtable) | ||
160 | return str | ||
161 | |||
162 | IMAGE_CLASSES ?= "image_types" | ||
163 | inherit ${IMAGE_CLASSES} | ||
164 | |||
165 | IMAGE_POSTPROCESS_COMMAND ?= "" | ||
166 | MACHINE_POSTPROCESS_COMMAND ?= "" | ||
167 | ROOTFS_POSTPROCESS_COMMAND_prepend = "run_intercept_scriptlets; " | ||
168 | # Allow dropbear/openssh to accept logins from accounts with an empty password string if debug-tweaks is enabled | ||
169 | ROOTFS_POSTPROCESS_COMMAND += '${@base_contains("IMAGE_FEATURES", "debug-tweaks", "ssh_allow_empty_password; ", "",d)}' | ||
170 | # Enable postinst logging if debug-tweaks is enabled | ||
171 | ROOTFS_POSTPROCESS_COMMAND += '${@base_contains("IMAGE_FEATURES", "debug-tweaks", "postinst_enable_logging; ", "",d)}' | ||
172 | # Set default postinst log file | ||
173 | POSTINST_LOGFILE ?= "${localstatedir}/log/postinstall.log" | ||
174 | |||
175 | # some default locales | ||
176 | IMAGE_LINGUAS ?= "de-de fr-fr en-gb" | ||
177 | |||
178 | LINGUAS_INSTALL ?= "${@" ".join(map(lambda s: "locale-base-%s" % s, d.getVar('IMAGE_LINGUAS', True).split()))}" | ||
179 | |||
180 | PSEUDO_PASSWD = "${IMAGE_ROOTFS}" | ||
181 | |||
182 | do_rootfs[dirs] = "${TOPDIR} ${WORKDIR}/intercept_scripts" | ||
183 | do_rootfs[lockfiles] += "${IMAGE_ROOTFS}.lock" | ||
184 | do_rootfs[cleandirs] += "${S} ${WORKDIR}/intercept_scripts" | ||
185 | |||
186 | # Must call real_do_rootfs() from inside here, rather than as a separate | ||
187 | # task, so that we have a single fakeroot context for the whole process. | ||
188 | do_rootfs[umask] = "022" | ||
189 | |||
190 | |||
191 | run_intercept_scriptlets () { | ||
192 | if [ -d ${WORKDIR}/intercept_scripts ]; then | ||
193 | cd ${WORKDIR}/intercept_scripts | ||
194 | echo "Running intercept scripts:" | ||
195 | for script in *; do | ||
196 | [ "$script" = "*" ] && break | ||
197 | [ "$script" = "postinst_intercept" ] || [ ! -x "$script" ] && continue | ||
198 | echo "> Executing $script" | ||
199 | ./$script && continue | ||
200 | echo "WARNING: intercept script \"$script\" failed, falling back to running postinstalls at first boot" | ||
201 | # | ||
202 | # If we got here, than the intercept has failed. Next, we must | ||
203 | # mark the postinstalls as "unpacked". For rpm is a little bit | ||
204 | # different, we just have to save the package postinstalls in | ||
205 | # /etc/rpm-postinsts | ||
206 | # | ||
207 | pkgs="$(cat ./$script|grep "^##PKGS"|cut -d':' -f2)" || continue | ||
208 | case ${IMAGE_PKGTYPE} in | ||
209 | "rpm") | ||
210 | [ -d ${IMAGE_ROOTFS}${sysconfdir}/rpm-postinsts/ ] || mkdir ${IMAGE_ROOTFS}${sysconfdir}/rpm-postinsts/ | ||
211 | v_expr=$(echo ${MULTILIB_GLOBAL_VARIANTS}|tr ' ' '|') | ||
212 | for p in $pkgs; do | ||
213 | # remove any multilib prefix from the package name (RPM | ||
214 | # does not use it like this) | ||
215 | new_p=$(echo $p | sed -r "s/^($v_expr)-//") | ||
216 | |||
217 | # extract the postinstall scriptlet from rpm package and | ||
218 | # save it in /etc/rpm-postinsts | ||
219 | echo " * postponing $new_p" | ||
220 | rpm -q --scripts --root=${IMAGE_ROOTFS} --dbpath=/var/lib/rpm $new_p |\ | ||
221 | sed -n -e '/^postinstall scriptlet (using .*):$/,/^.* scriptlet (using .*):$/ {/.*/p}' |\ | ||
222 | sed -e 's/postinstall scriptlet (using \(.*\)):$/#!\1/' -e '/^.* scriptlet (using .*):$/d'\ | ||
223 | > ${IMAGE_ROOTFS}${sysconfdir}/rpm-postinsts/$new_p | ||
224 | chmod +x ${IMAGE_ROOTFS}${sysconfdir}/rpm-postinsts/$new_p | ||
225 | done | ||
226 | # move to the next intercept script | ||
227 | continue | ||
228 | ;; | ||
229 | "ipk") | ||
230 | status_file="${IMAGE_ROOTFS}${OPKGLIBDIR}/opkg/status" | ||
231 | ;; | ||
232 | "deb") | ||
233 | status_file="${IMAGE_ROOTFS}/var/lib/dpkg/status" | ||
234 | ;; | ||
235 | esac | ||
236 | # the next piece of code is run only for ipk/dpkg | ||
237 | sed_expr="" | ||
238 | for p in $pkgs; do | ||
239 | echo " * postponing $p" | ||
240 | sed_expr="$sed_expr -e \"/^Package: ${p}$/,/^Status: install.* installed$/ {s/installed/unpacked/}\"" | ||
241 | done | ||
242 | eval sed -i $sed_expr $status_file | ||
243 | done | ||
244 | fi | ||
245 | } | ||
246 | |||
247 | # A hook function to support read-only-rootfs IMAGE_FEATURES | ||
248 | # Currently, it only supports sysvinit system. | ||
249 | read_only_rootfs_hook () { | ||
250 | if ${@base_contains("DISTRO_FEATURES", "sysvinit", "true", "false", d)}; then | ||
251 | # Tweak the mount option and fs_passno for rootfs in fstab | ||
252 | sed -i -e '/^[#[:space:]]*rootfs/{s/defaults/ro/;s/\([[:space:]]*[[:digit:]]\)\([[:space:]]*\)[[:digit:]]$/\1\20/}' ${IMAGE_ROOTFS}/etc/fstab | ||
253 | # Change the value of ROOTFS_READ_ONLY in /etc/default/rcS to yes | ||
254 | if [ -e ${IMAGE_ROOTFS}/etc/default/rcS ]; then | ||
255 | sed -i 's/ROOTFS_READ_ONLY=no/ROOTFS_READ_ONLY=yes/' ${IMAGE_ROOTFS}/etc/default/rcS | ||
256 | fi | ||
257 | # Run populate-volatile.sh at rootfs time to set up basic files | ||
258 | # and directories to support read-only rootfs. | ||
259 | if [ -x ${IMAGE_ROOTFS}/etc/init.d/populate-volatile.sh ]; then | ||
260 | ${IMAGE_ROOTFS}/etc/init.d/populate-volatile.sh | ||
261 | fi | ||
262 | # If we're using openssh and the /etc/ssh directory has no pre-generated keys, | ||
263 | # we should configure openssh to use the configuration file /etc/ssh/sshd_config_readonly | ||
264 | # and the keys under /var/run/ssh. | ||
265 | if [ -d ${IMAGE_ROOTFS}/etc/ssh ]; then | ||
266 | if [ -e ${IMAGE_ROOTFS}/etc/ssh/ssh_host_rsa_key ]; then | ||
267 | echo "SYSCONFDIR=/etc/ssh" >> ${IMAGE_ROOTFS}/etc/default/ssh | ||
268 | echo "SSHD_OPTS=" >> ${IMAGE_ROOTFS}/etc/default/ssh | ||
269 | else | ||
270 | echo "SYSCONFDIR=/var/run/ssh" >> ${IMAGE_ROOTFS}/etc/default/ssh | ||
271 | echo "SSHD_OPTS='-f /etc/ssh/sshd_config_readonly'" >> ${IMAGE_ROOTFS}/etc/default/ssh | ||
272 | fi | ||
273 | fi | ||
274 | fi | ||
275 | } | ||
276 | |||
277 | PACKAGE_EXCLUDE ??= "" | ||
278 | PACKAGE_EXCLUDE[type] = "list" | ||
279 | |||
280 | python rootfs_process_ignore() { | ||
281 | excl_pkgs = d.getVar("PACKAGE_EXCLUDE", True).split() | ||
282 | inst_pkgs = d.getVar("PACKAGE_INSTALL", True).split() | ||
283 | inst_attempt_pkgs = d.getVar("PACKAGE_INSTALL_ATTEMPTONLY", True).split() | ||
284 | |||
285 | d.setVar('PACKAGE_INSTALL_ORIG', ' '.join(inst_pkgs)) | ||
286 | d.setVar('PACKAGE_INSTALL_ATTEMPTONLY', ' '.join(inst_attempt_pkgs)) | ||
287 | |||
288 | for pkg in excl_pkgs: | ||
289 | if pkg in inst_pkgs: | ||
290 | bb.warn("Package %s, set to be excluded, is in %s PACKAGE_INSTALL (%s). It will be removed from the list." % (pkg, d.getVar('PN', True), inst_pkgs)) | ||
291 | inst_pkgs.remove(pkg) | ||
292 | |||
293 | if pkg in inst_attempt_pkgs: | ||
294 | bb.warn("Package %s, set to be excluded, is in %s PACKAGE_INSTALL_ATTEMPTONLY (%s). It will be removed from the list." % (pkg, d.getVar('PN', True), inst_pkgs)) | ||
295 | inst_attempt_pkgs.remove(pkg) | ||
296 | |||
297 | d.setVar("PACKAGE_INSTALL", ' '.join(inst_pkgs)) | ||
298 | d.setVar("PACKAGE_INSTALL_ATTEMPTONLY", ' '.join(inst_attempt_pkgs)) | ||
299 | } | ||
300 | do_rootfs[prefuncs] += "rootfs_process_ignore" | ||
301 | |||
302 | # We have to delay the runtime_mapping_rename until just before rootfs runs | ||
303 | # otherwise, the multilib renaming could step in and squash any fixups that | ||
304 | # may have occurred. | ||
305 | python rootfs_runtime_mapping() { | ||
306 | pn = d.getVar('PN', True) | ||
307 | runtime_mapping_rename("PACKAGE_INSTALL", pn, d) | ||
308 | runtime_mapping_rename("PACKAGE_INSTALL_ATTEMPTONLY", pn, d) | ||
309 | runtime_mapping_rename("BAD_RECOMMENDATIONS", pn, d) | ||
310 | } | ||
311 | do_rootfs[prefuncs] += "rootfs_runtime_mapping" | ||
312 | |||
313 | fakeroot do_rootfs () { | ||
314 | #set -x | ||
315 | # When use the rpm incremental image generation, don't remove the rootfs | ||
316 | if [ "${INC_RPM_IMAGE_GEN}" != "1" -o "${IMAGE_PKGTYPE}" != "rpm" ]; then | ||
317 | rm -rf ${IMAGE_ROOTFS} | ||
318 | elif [ -d ${T}/saved_rpmlib/var/lib/rpm ]; then | ||
319 | # Move the rpmlib back | ||
320 | if [ ! -d ${IMAGE_ROOTFS}/var/lib/rpm ]; then | ||
321 | mkdir -p ${IMAGE_ROOTFS}/var/lib/ | ||
322 | mv ${T}/saved_rpmlib/var/lib/rpm ${IMAGE_ROOTFS}/var/lib/ | ||
323 | fi | ||
324 | fi | ||
325 | rm -rf ${MULTILIB_TEMP_ROOTFS} | ||
326 | mkdir -p ${IMAGE_ROOTFS} | ||
327 | mkdir -p ${DEPLOY_DIR_IMAGE} | ||
328 | |||
329 | cp ${COREBASE}/meta/files/deploydir_readme.txt ${DEPLOY_DIR_IMAGE}/README_-_DO_NOT_DELETE_FILES_IN_THIS_DIRECTORY.txt || true | ||
330 | |||
331 | # copy the intercept scripts | ||
332 | cp ${COREBASE}/scripts/postinst-intercepts/* ${WORKDIR}/intercept_scripts/ | ||
333 | |||
334 | rootfs_${IMAGE_PKGTYPE}_do_rootfs | ||
335 | |||
336 | if [ "${USE_DEVFS}" != "1" ]; then | ||
337 | for devtable in ${@get_devtable_list(d)}; do | ||
338 | # Always return ture since there maybe already one when use the | ||
339 | # incremental image generation | ||
340 | makedevs -r ${IMAGE_ROOTFS} -D $devtable | ||
341 | done | ||
342 | fi | ||
343 | |||
344 | # remove unneeded packages/files from the final image | ||
345 | rootfs_uninstall_unneeded | ||
346 | |||
347 | insert_feed_uris | ||
348 | |||
349 | if [ "x${LDCONFIGDEPEND}" != "x" ]; then | ||
350 | # Run ldconfig on the image to create a valid cache | ||
351 | # (new format for cross arch compatibility) | ||
352 | echo executing: ldconfig -r ${IMAGE_ROOTFS} -c new -v | ||
353 | ldconfig -r ${IMAGE_ROOTFS} -c new -v | ||
354 | fi | ||
355 | |||
356 | # (re)create kernel modules dependencies | ||
357 | # This part is done by kernel-module-* postinstall scripts but if image do | ||
358 | # not contains modules at all there are few moments in boot sequence with | ||
359 | # "unable to open modules.dep" message. | ||
360 | if [ -e ${STAGING_KERNEL_DIR}/kernel-abiversion ]; then | ||
361 | KERNEL_VERSION=`cat ${STAGING_KERNEL_DIR}/kernel-abiversion` | ||
362 | |||
363 | mkdir -p ${IMAGE_ROOTFS}/lib/modules/$KERNEL_VERSION | ||
364 | depmodwrapper -a -b ${IMAGE_ROOTFS} $KERNEL_VERSION | ||
365 | fi | ||
366 | |||
367 | ${IMAGE_PREPROCESS_COMMAND} | ||
368 | |||
369 | ${@get_imagecmds(d)} | ||
370 | |||
371 | ${IMAGE_POSTPROCESS_COMMAND} | ||
372 | |||
373 | ${MACHINE_POSTPROCESS_COMMAND} | ||
374 | } | ||
375 | |||
376 | insert_feed_uris () { | ||
377 | |||
378 | echo "Building feeds for [${DISTRO}].." | ||
379 | |||
380 | for line in ${FEED_URIS} | ||
381 | do | ||
382 | # strip leading and trailing spaces/tabs, then split into name and uri | ||
383 | line_clean="`echo "$line"|sed 's/^[ \t]*//;s/[ \t]*$//'`" | ||
384 | feed_name="`echo "$line_clean" | sed -n 's/\(.*\)##\(.*\)/\1/p'`" | ||
385 | feed_uri="`echo "$line_clean" | sed -n 's/\(.*\)##\(.*\)/\2/p'`" | ||
386 | |||
387 | echo "Added $feed_name feed with URL $feed_uri" | ||
388 | |||
389 | # insert new feed-sources | ||
390 | echo "src/gz $feed_name $feed_uri" >> ${IMAGE_ROOTFS}/etc/opkg/${feed_name}-feed.conf | ||
391 | done | ||
392 | } | ||
393 | |||
394 | log_check() { | ||
395 | for target in $* | ||
396 | do | ||
397 | lf_path="`dirname ${BB_LOGFILE}`/log.do_$target.${PID}" | ||
398 | |||
399 | echo "log_check: Using $lf_path as logfile" | ||
400 | |||
401 | if test -e "$lf_path" | ||
402 | then | ||
403 | ${IMAGE_PKGTYPE}_log_check $target $lf_path | ||
404 | else | ||
405 | echo "Cannot find logfile [$lf_path]" | ||
406 | fi | ||
407 | echo "Logfile is clean" | ||
408 | done | ||
409 | } | ||
410 | |||
411 | MULTILIBRE_ALLOW_REP =. "${base_bindir}|${base_sbindir}|${bindir}|${sbindir}|${libexecdir}|" | ||
412 | MULTILIB_CHECK_FILE = "${WORKDIR}/multilib_check.py" | ||
413 | MULTILIB_TEMP_ROOTFS = "${WORKDIR}/multilib" | ||
414 | |||
415 | multilib_generate_python_file() { | ||
416 | cat >${MULTILIB_CHECK_FILE} <<EOF | ||
417 | import sys, os, os.path | ||
418 | import re,filecmp | ||
419 | |||
420 | allow_rep=re.compile(re.sub("\|$","","${MULTILIBRE_ALLOW_REP}")) | ||
421 | error_prompt="Multilib check error:" | ||
422 | |||
423 | files={} | ||
424 | dirs=raw_input() | ||
425 | for dir in dirs.split(): | ||
426 | for root, subfolders, subfiles in os.walk(dir): | ||
427 | for file in subfiles: | ||
428 | item=os.path.join(root,file) | ||
429 | key=str(os.path.join("/",os.path.relpath(item,dir))) | ||
430 | |||
431 | valid=True; | ||
432 | if key in files: | ||
433 | #check whether the file is allow to replace | ||
434 | if allow_rep.match(key): | ||
435 | valid=True | ||
436 | else: | ||
437 | if not filecmp.cmp(files[key],item): | ||
438 | valid=False | ||
439 | print("%s duplicate files %s %s is not the same\n" % (error_prompt, item, files[key])) | ||
440 | sys.exit(1) | ||
441 | |||
442 | #pass the check, add to list | ||
443 | if valid: | ||
444 | files[key]=item | ||
445 | EOF | ||
446 | } | ||
447 | |||
448 | multilib_sanity_check() { | ||
449 | multilib_generate_python_file | ||
450 | echo $@ | python ${MULTILIB_CHECK_FILE} | ||
451 | } | ||
452 | |||
453 | get_split_linguas() { | ||
454 | for translation in ${IMAGE_LINGUAS}; do | ||
455 | translation_split=$(echo ${translation} | awk -F '-' '{print $1}') | ||
456 | echo ${translation} | ||
457 | echo ${translation_split} | ||
458 | done | sort | uniq | ||
459 | } | ||
460 | |||
461 | rootfs_install_complementary() { | ||
462 | # Install complementary packages based upon the list of currently installed packages | ||
463 | # e.g. locales, *-dev, *-dbg, etc. This will only attempt to install these packages, | ||
464 | # if they don't exist then no error will occur. | ||
465 | # Note: every backend needs to call this function explicitly after the normal | ||
466 | # package installation | ||
467 | |||
468 | # Get list of installed packages | ||
469 | list_installed_packages arch > ${WORKDIR}/installed_pkgs.txt | ||
470 | |||
471 | # Apply the globs to all the packages currently installed | ||
472 | if [ -n "$1" -a "$1" = "populate_sdk" ] ; then | ||
473 | GLOBS="${SDKIMAGE_INSTALL_COMPLEMENTARY}" | ||
474 | elif [ -n "$1" ]; then | ||
475 | GLOBS="$@" | ||
476 | else | ||
477 | GLOBS="${IMAGE_INSTALL_COMPLEMENTARY}" | ||
478 | # Add locales | ||
479 | SPLIT_LINGUAS=`get_split_linguas` | ||
480 | PACKAGES_TO_INSTALL="" | ||
481 | for lang in $SPLIT_LINGUAS ; do | ||
482 | GLOBS="$GLOBS *-locale-$lang" | ||
483 | done | ||
484 | fi | ||
485 | |||
486 | if [ "$GLOBS" != "" ] ; then | ||
487 | # Use the magic script to do all the work for us :) | ||
488 | : > ${WORKDIR}/complementary_pkgs.txt | ||
489 | for vendor in '${TARGET_VENDOR}' ${MULTILIB_VENDORS} ; do | ||
490 | oe-pkgdata-util glob ${PKGDATA_DIR} ${WORKDIR}/installed_pkgs.txt "$GLOBS" >> ${WORKDIR}/complementary_pkgs.txt | ||
491 | done | ||
492 | |||
493 | # Install the packages, if any | ||
494 | sed -i '/^$/d' ${WORKDIR}/complementary_pkgs.txt | ||
495 | if [ -s ${WORKDIR}/complementary_pkgs.txt ]; then | ||
496 | echo "Installing complementary packages" | ||
497 | rootfs_install_packages ${WORKDIR}/complementary_pkgs.txt | ||
498 | fi | ||
499 | fi | ||
500 | |||
501 | # Workaround for broken shell function dependencies | ||
502 | if false ; then | ||
503 | get_split_linguas | ||
504 | fi | ||
505 | } | ||
506 | |||
507 | rootfs_uninstall_unneeded () { | ||
508 | if ${@base_contains("IMAGE_FEATURES", "package-management", "false", "true", d)}; then | ||
509 | if [ -z "$(delayed_postinsts)" ]; then | ||
510 | # All packages were successfully configured. | ||
511 | # update-rc.d, base-passwd, run-postinsts are no further use, remove them now | ||
512 | remove_run_postinsts=false | ||
513 | if [ -e ${IMAGE_ROOTFS}${sysconfdir}/init.d/run-postinsts ]; then | ||
514 | remove_run_postinsts=true | ||
515 | fi | ||
516 | |||
517 | # Remove package only if it's installed | ||
518 | pkgs_to_remove="update-rc.d base-passwd ${ROOTFS_BOOTSTRAP_INSTALL}" | ||
519 | for pkg in $pkgs_to_remove; do | ||
520 | # regexp for pkg, to be used in grep and sed | ||
521 | pkg_regexp="^`echo $pkg | sed 's/\./\\\./'` " | ||
522 | if grep -q "$pkg_regexp" ${WORKDIR}/installed_pkgs.txt; then | ||
523 | rootfs_uninstall_packages $pkg | ||
524 | sed -i "/$pkg_regexp/d" ${WORKDIR}/installed_pkgs.txt | ||
525 | fi | ||
526 | done | ||
527 | |||
528 | # Need to remove rc.d files for run-postinsts by hand since opkg won't | ||
529 | # call postrm scripts in offline root mode. | ||
530 | if $remove_run_postinsts; then | ||
531 | update-rc.d -f -r ${IMAGE_ROOTFS} run-postinsts remove | ||
532 | fi | ||
533 | else | ||
534 | # Some packages were not successfully configured, save them only | ||
535 | # if we have run-postinsts script present. Otherwise, they're | ||
536 | # useless | ||
537 | if [ -e ${IMAGE_ROOTFS}${sysconfdir}/init.d/run-postinsts ]; then | ||
538 | save_postinsts | ||
539 | fi | ||
540 | fi | ||
541 | |||
542 | # Since no package manager is present in the image the metadata is not needed | ||
543 | remove_packaging_data_files | ||
544 | fi | ||
545 | } | ||
546 | |||
547 | # set '*' as the root password so the images | ||
548 | # can decide if they want it or not | ||
549 | zap_root_password () { | ||
550 | sed 's%^root:[^:]*:%root:*:%' < ${IMAGE_ROOTFS}/etc/passwd >${IMAGE_ROOTFS}/etc/passwd.new | ||
551 | mv ${IMAGE_ROOTFS}/etc/passwd.new ${IMAGE_ROOTFS}/etc/passwd | ||
552 | } | ||
553 | |||
554 | # allow dropbear/openssh to accept root logins and logins from accounts with an empty password string | ||
555 | ssh_allow_empty_password () { | ||
556 | if [ -e ${IMAGE_ROOTFS}${sysconfdir}/ssh/sshd_config ]; then | ||
557 | sed -i 's#.*PermitRootLogin.*#PermitRootLogin yes#' ${IMAGE_ROOTFS}${sysconfdir}/ssh/sshd_config | ||
558 | sed -i 's#.*PermitEmptyPasswords.*#PermitEmptyPasswords yes#' ${IMAGE_ROOTFS}${sysconfdir}/ssh/sshd_config | ||
559 | fi | ||
560 | |||
561 | if [ -e ${IMAGE_ROOTFS}${sbindir}/dropbear ] ; then | ||
562 | if grep -q DROPBEAR_EXTRA_ARGS ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear 2>/dev/null ; then | ||
563 | if ! grep -q "DROPBEAR_EXTRA_ARGS=.*-B" ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear ; then | ||
564 | sed -i 's/^DROPBEAR_EXTRA_ARGS="*\([^"]*\)"*/DROPBEAR_EXTRA_ARGS="\1 -B"/' ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear | ||
565 | fi | ||
566 | else | ||
567 | printf '\nDROPBEAR_EXTRA_ARGS="-B"\n' >> ${IMAGE_ROOTFS}${sysconfdir}/default/dropbear | ||
568 | fi | ||
569 | fi | ||
570 | } | ||
571 | |||
572 | # Enable postinst logging if debug-tweaks is enabled | ||
573 | postinst_enable_logging () { | ||
574 | mkdir -p ${IMAGE_ROOTFS}${sysconfdir}/default | ||
575 | echo "POSTINST_LOGGING=1" >> ${IMAGE_ROOTFS}${sysconfdir}/default/postinst | ||
576 | echo "LOGFILE=${POSTINST_LOGFILE}" >> ${IMAGE_ROOTFS}${sysconfdir}/default/postinst | ||
577 | } | ||
578 | |||
579 | # Turn any symbolic /sbin/init link into a file | ||
580 | remove_init_link () { | ||
581 | if [ -h ${IMAGE_ROOTFS}/sbin/init ]; then | ||
582 | LINKFILE=${IMAGE_ROOTFS}`readlink ${IMAGE_ROOTFS}/sbin/init` | ||
583 | rm ${IMAGE_ROOTFS}/sbin/init | ||
584 | cp $LINKFILE ${IMAGE_ROOTFS}/sbin/init | ||
585 | fi | ||
586 | } | ||
587 | |||
588 | make_zimage_symlink_relative () { | ||
589 | if [ -L ${IMAGE_ROOTFS}/boot/zImage ]; then | ||
590 | (cd ${IMAGE_ROOTFS}/boot/ && for i in `ls zImage-* | sort`; do ln -sf $i zImage; done) | ||
591 | fi | ||
592 | } | ||
593 | |||
594 | write_image_manifest () { | ||
595 | rootfs_${IMAGE_PKGTYPE}_write_manifest | ||
596 | |||
597 | if [ -n "${IMAGE_LINK_NAME}" ]; then | ||
598 | rm -f ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.manifest | ||
599 | ln -s ${IMAGE_NAME}.rootfs.manifest ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.manifest | ||
600 | fi | ||
601 | } | ||
602 | |||
603 | # Make login manager(s) enable automatic login. | ||
604 | # Useful for devices where we do not want to log in at all (e.g. phones) | ||
605 | set_image_autologin () { | ||
606 | sed -i 's%^AUTOLOGIN=\"false"%AUTOLOGIN="true"%g' ${IMAGE_ROOTFS}/etc/sysconfig/gpelogin | ||
607 | } | ||
608 | |||
609 | # Can be use to create /etc/timestamp during image construction to give a reasonably | ||
610 | # sane default time setting | ||
611 | rootfs_update_timestamp () { | ||
612 | date -u +%4Y%2m%2d%2H%2M >${IMAGE_ROOTFS}/etc/timestamp | ||
613 | } | ||
614 | |||
615 | # Prevent X from being started | ||
616 | rootfs_no_x_startup () { | ||
617 | if [ -f ${IMAGE_ROOTFS}/etc/init.d/xserver-nodm ]; then | ||
618 | chmod a-x ${IMAGE_ROOTFS}/etc/init.d/xserver-nodm | ||
619 | fi | ||
620 | } | ||
621 | |||
622 | rootfs_trim_schemas () { | ||
623 | for schema in ${IMAGE_ROOTFS}/etc/gconf/schemas/*.schemas | ||
624 | do | ||
625 | # Need this in case no files exist | ||
626 | if [ -e $schema ]; then | ||
627 | oe-trim-schemas $schema > $schema.new | ||
628 | mv $schema.new $schema | ||
629 | fi | ||
630 | done | ||
631 | } | ||
632 | |||
633 | # Make any absolute links in a sysroot relative | ||
634 | rootfs_sysroot_relativelinks () { | ||
635 | sysroot-relativelinks.py ${SDK_OUTPUT}/${SDKTARGETSYSROOT} | ||
636 | } | ||
637 | |||
638 | EXPORT_FUNCTIONS zap_root_password remove_init_link do_rootfs make_zimage_symlink_relative set_image_autologin rootfs_update_timestamp rootfs_no_x_startup | ||
639 | |||
640 | do_fetch[noexec] = "1" | ||
641 | do_unpack[noexec] = "1" | ||
642 | do_patch[noexec] = "1" | ||
643 | do_configure[noexec] = "1" | ||
644 | do_compile[noexec] = "1" | ||
645 | do_install[noexec] = "1" | ||
646 | do_populate_sysroot[noexec] = "1" | ||
647 | do_package[noexec] = "1" | ||
648 | do_packagedata[noexec] = "1" | ||
649 | do_package_write_ipk[noexec] = "1" | ||
650 | do_package_write_deb[noexec] = "1" | ||
651 | do_package_write_rpm[noexec] = "1" | ||
652 | |||
653 | addtask rootfs before do_build | ||
654 | # Allow the kernel to be repacked with the initramfs and boot image file as a single file | ||
655 | do_bundle_initramfs[depends] += "virtual/kernel:do_bundle_initramfs" | ||
656 | do_bundle_initramfs[nostamp] = "1" | ||
657 | do_bundle_initramfs[noexec] = "1" | ||
658 | do_bundle_initramfs () { | ||
659 | : | ||
660 | } | ||
661 | addtask bundle_initramfs after do_rootfs | ||