diff options
Diffstat (limited to 'scripts/lib')
-rw-r--r-- | scripts/lib/devtool/standard.py | 43 | ||||
-rw-r--r-- | scripts/lib/devtool/upgrade.py | 4 | ||||
-rw-r--r-- | scripts/lib/recipetool/create_npm.py | 6 | ||||
-rw-r--r-- | scripts/lib/wic/canned-wks/common.wks.inc | 2 | ||||
-rw-r--r-- | scripts/lib/wic/canned-wks/directdisk-gpt.wks | 2 | ||||
-rw-r--r-- | scripts/lib/wic/canned-wks/mkefidisk.wks | 2 | ||||
-rw-r--r-- | scripts/lib/wic/ksparser.py | 17 | ||||
-rw-r--r-- | scripts/lib/wic/misc.py | 8 | ||||
-rw-r--r-- | scripts/lib/wic/partition.py | 82 | ||||
-rw-r--r-- | scripts/lib/wic/plugins/imager/direct.py | 61 | ||||
-rw-r--r-- | scripts/lib/wic/plugins/source/rootfs.py | 33 |
11 files changed, 203 insertions, 57 deletions
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py index 261d642d4a..f364a45283 100644 --- a/scripts/lib/devtool/standard.py +++ b/scripts/lib/devtool/standard.py | |||
@@ -474,7 +474,11 @@ def symlink_oelocal_files_srctree(rd,srctree): | |||
474 | destpth = os.path.join(srctree, relpth, fn) | 474 | destpth = os.path.join(srctree, relpth, fn) |
475 | if os.path.exists(destpth): | 475 | if os.path.exists(destpth): |
476 | os.unlink(destpth) | 476 | os.unlink(destpth) |
477 | os.symlink('oe-local-files/%s' % fn, destpth) | 477 | if relpth != '.': |
478 | back_relpth = os.path.relpath(local_files_dir, root) | ||
479 | os.symlink('%s/oe-local-files/%s/%s' % (back_relpth, relpth, fn), destpth) | ||
480 | else: | ||
481 | os.symlink('oe-local-files/%s' % fn, destpth) | ||
478 | addfiles.append(os.path.join(relpth, fn)) | 482 | addfiles.append(os.path.join(relpth, fn)) |
479 | if addfiles: | 483 | if addfiles: |
480 | bb.process.run('git add %s' % ' '.join(addfiles), cwd=srctree) | 484 | bb.process.run('git add %s' % ' '.join(addfiles), cwd=srctree) |
@@ -589,6 +593,16 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
589 | else: | 593 | else: |
590 | task = 'do_patch' | 594 | task = 'do_patch' |
591 | 595 | ||
596 | if 'noexec' in (d.getVarFlags(task, False) or []) or 'task' not in (d.getVarFlags(task, False) or []): | ||
597 | logger.info('The %s recipe has %s disabled. Running only ' | ||
598 | 'do_configure task dependencies' % (pn, task)) | ||
599 | |||
600 | if 'depends' in d.getVarFlags('do_configure', False): | ||
601 | pn = d.getVarFlags('do_configure', False)['depends'] | ||
602 | pn = pn.replace('${PV}', d.getVar('PV')) | ||
603 | pn = pn.replace('${COMPILERDEP}', d.getVar('COMPILERDEP')) | ||
604 | task = None | ||
605 | |||
592 | # Run the fetch + unpack tasks | 606 | # Run the fetch + unpack tasks |
593 | res = tinfoil.build_targets(pn, | 607 | res = tinfoil.build_targets(pn, |
594 | task, | 608 | task, |
@@ -600,6 +614,17 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works | |||
600 | if not res: | 614 | if not res: |
601 | raise DevtoolError('Extracting source for %s failed' % pn) | 615 | raise DevtoolError('Extracting source for %s failed' % pn) |
602 | 616 | ||
617 | if not is_kernel_yocto and ('noexec' in (d.getVarFlags('do_patch', False) or []) or 'task' not in (d.getVarFlags('do_patch', False) or [])): | ||
618 | workshareddir = d.getVar('S') | ||
619 | if os.path.islink(srctree): | ||
620 | os.unlink(srctree) | ||
621 | |||
622 | os.symlink(workshareddir, srctree) | ||
623 | |||
624 | # The initial_rev file is created in devtool_post_unpack function that will not be executed if | ||
625 | # do_unpack/do_patch tasks are disabled so we have to directly say that source extraction was successful | ||
626 | return True, True | ||
627 | |||
603 | try: | 628 | try: |
604 | with open(os.path.join(tempdir, 'initial_rev'), 'r') as f: | 629 | with open(os.path.join(tempdir, 'initial_rev'), 'r') as f: |
605 | initial_rev = f.read() | 630 | initial_rev = f.read() |
@@ -847,10 +872,11 @@ def modify(args, config, basepath, workspace): | |||
847 | if not initial_rev: | 872 | if not initial_rev: |
848 | return 1 | 873 | return 1 |
849 | logger.info('Source tree extracted to %s' % srctree) | 874 | logger.info('Source tree extracted to %s' % srctree) |
850 | # Get list of commits since this revision | 875 | if os.path.exists(os.path.join(srctree, '.git')): |
851 | (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree) | 876 | # Get list of commits since this revision |
852 | commits = stdout.split() | 877 | (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree) |
853 | check_commits = True | 878 | commits = stdout.split() |
879 | check_commits = True | ||
854 | else: | 880 | else: |
855 | if os.path.exists(os.path.join(srctree, '.git')): | 881 | if os.path.exists(os.path.join(srctree, '.git')): |
856 | # Check if it's a tree previously extracted by us. This is done | 882 | # Check if it's a tree previously extracted by us. This is done |
@@ -927,12 +953,17 @@ def modify(args, config, basepath, workspace): | |||
927 | 953 | ||
928 | if bb.data.inherits_class('kernel', rd): | 954 | if bb.data.inherits_class('kernel', rd): |
929 | f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout ' | 955 | f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout ' |
930 | 'do_fetch do_unpack do_kernel_configme do_kernel_configcheck"\n') | 956 | 'do_fetch do_unpack do_kernel_configcheck"\n') |
931 | f.write('\ndo_patch[noexec] = "1"\n') | 957 | f.write('\ndo_patch[noexec] = "1"\n') |
932 | f.write('\ndo_configure_append() {\n' | 958 | f.write('\ndo_configure_append() {\n' |
933 | ' cp ${B}/.config ${S}/.config.baseline\n' | 959 | ' cp ${B}/.config ${S}/.config.baseline\n' |
934 | ' ln -sfT ${B}/.config ${S}/.config.new\n' | 960 | ' ln -sfT ${B}/.config ${S}/.config.new\n' |
935 | '}\n') | 961 | '}\n') |
962 | f.write('\ndo_kernel_configme_prepend() {\n' | ||
963 | ' if [ -e ${S}/.config ]; then\n' | ||
964 | ' mv ${S}/.config ${S}/.config.old\n' | ||
965 | ' fi\n' | ||
966 | '}\n') | ||
936 | if rd.getVarFlag('do_menuconfig','task'): | 967 | if rd.getVarFlag('do_menuconfig','task'): |
937 | f.write('\ndo_configure_append() {\n' | 968 | f.write('\ndo_configure_append() {\n' |
938 | ' if [ ! ${DEVTOOL_DISABLE_MENUCONFIG} ]; then\n' | 969 | ' if [ ! ${DEVTOOL_DISABLE_MENUCONFIG} ]; then\n' |
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py index 0c1de8cdc7..5a057e95f5 100644 --- a/scripts/lib/devtool/upgrade.py +++ b/scripts/lib/devtool/upgrade.py | |||
@@ -178,7 +178,7 @@ def _extract_new_source(newpv, srctree, no_patch, srcrev, srcbranch, branch, kee | |||
178 | uri, rev = _get_uri(crd) | 178 | uri, rev = _get_uri(crd) |
179 | if srcrev: | 179 | if srcrev: |
180 | rev = srcrev | 180 | rev = srcrev |
181 | if uri.startswith('git://'): | 181 | if uri.startswith('git://') or uri.startswith('gitsm://'): |
182 | __run('git fetch') | 182 | __run('git fetch') |
183 | __run('git checkout %s' % rev) | 183 | __run('git checkout %s' % rev) |
184 | __run('git tag -f devtool-base-new') | 184 | __run('git tag -f devtool-base-new') |
@@ -270,7 +270,7 @@ def _extract_new_source(newpv, srctree, no_patch, srcrev, srcbranch, branch, kee | |||
270 | else: | 270 | else: |
271 | logger.warning('Command \'%s\' failed:\n%s' % (e.command, e.stdout)) | 271 | logger.warning('Command \'%s\' failed:\n%s' % (e.command, e.stdout)) |
272 | if not skiptag: | 272 | if not skiptag: |
273 | if uri.startswith('git://'): | 273 | if uri.startswith('git://') or uri.startswith('gitsm://'): |
274 | suffix = 'new' | 274 | suffix = 'new' |
275 | else: | 275 | else: |
276 | suffix = newpv | 276 | suffix = newpv |
diff --git a/scripts/lib/recipetool/create_npm.py b/scripts/lib/recipetool/create_npm.py index 579b7ae48a..2bcae91dfa 100644 --- a/scripts/lib/recipetool/create_npm.py +++ b/scripts/lib/recipetool/create_npm.py | |||
@@ -204,6 +204,9 @@ class NpmRecipeHandler(RecipeHandler): | |||
204 | self._run_npm_install(d, srctree, registry, dev) | 204 | self._run_npm_install(d, srctree, registry, dev) |
205 | shrinkwrap_file = self._generate_shrinkwrap(d, srctree, dev) | 205 | shrinkwrap_file = self._generate_shrinkwrap(d, srctree, dev) |
206 | 206 | ||
207 | with open(shrinkwrap_file, "r") as f: | ||
208 | shrinkwrap = json.load(f) | ||
209 | |||
207 | if os.path.exists(lock_copy): | 210 | if os.path.exists(lock_copy): |
208 | bb.utils.movefile(lock_copy, lock_file) | 211 | bb.utils.movefile(lock_copy, lock_file) |
209 | 212 | ||
@@ -226,7 +229,8 @@ class NpmRecipeHandler(RecipeHandler): | |||
226 | value = origvalue.replace("version=" + data["version"], "version=${PV}") | 229 | value = origvalue.replace("version=" + data["version"], "version=${PV}") |
227 | value = value.replace("version=latest", "version=${PV}") | 230 | value = value.replace("version=latest", "version=${PV}") |
228 | values = [line.strip() for line in value.strip('\n').splitlines()] | 231 | values = [line.strip() for line in value.strip('\n').splitlines()] |
229 | values.append(url_recipe) | 232 | if "dependencies" in shrinkwrap: |
233 | values.append(url_recipe) | ||
230 | return values, None, 4, False | 234 | return values, None, 4, False |
231 | 235 | ||
232 | (_, newlines) = bb.utils.edit_metadata(lines_before, ["SRC_URI"], _handle_srcuri) | 236 | (_, newlines) = bb.utils.edit_metadata(lines_before, ["SRC_URI"], _handle_srcuri) |
diff --git a/scripts/lib/wic/canned-wks/common.wks.inc b/scripts/lib/wic/canned-wks/common.wks.inc index 89880b417b..4fd29fa8c1 100644 --- a/scripts/lib/wic/canned-wks/common.wks.inc +++ b/scripts/lib/wic/canned-wks/common.wks.inc | |||
@@ -1,3 +1,3 @@ | |||
1 | # This file is included into 3 canned wks files from this directory | 1 | # This file is included into 3 canned wks files from this directory |
2 | part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024 | 2 | part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024 |
3 | part / --source rootfs --use-uuid --fstype=ext4 --label platform --align 1024 | 3 | part / --source rootfs --use-uuid --fstype=ext4 --mkfs-extraopts "-T default" --label platform --align 1024 |
diff --git a/scripts/lib/wic/canned-wks/directdisk-gpt.wks b/scripts/lib/wic/canned-wks/directdisk-gpt.wks index 8d7d8de6ea..cf16c0c30b 100644 --- a/scripts/lib/wic/canned-wks/directdisk-gpt.wks +++ b/scripts/lib/wic/canned-wks/directdisk-gpt.wks | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | 5 | ||
6 | part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024 | 6 | part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024 |
7 | part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid | 7 | part / --source rootfs --ondisk sda --fstype=ext4 --mkfs-extraopts "-T default" --label platform --align 1024 --use-uuid |
8 | 8 | ||
9 | bootloader --ptable gpt --timeout=0 --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8" | 9 | bootloader --ptable gpt --timeout=0 --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8" |
10 | 10 | ||
diff --git a/scripts/lib/wic/canned-wks/mkefidisk.wks b/scripts/lib/wic/canned-wks/mkefidisk.wks index 9f534fe184..d1878e23e5 100644 --- a/scripts/lib/wic/canned-wks/mkefidisk.wks +++ b/scripts/lib/wic/canned-wks/mkefidisk.wks | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | part /boot --source bootimg-efi --sourceparams="loader=grub-efi" --ondisk sda --label msdos --active --align 1024 | 5 | part /boot --source bootimg-efi --sourceparams="loader=grub-efi" --ondisk sda --label msdos --active --align 1024 |
6 | 6 | ||
7 | part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid | 7 | part / --source rootfs --ondisk sda --fstype=ext4 --mkfs-extraopts "-T default" --label platform --align 1024 --use-uuid |
8 | 8 | ||
9 | part swap --ondisk sda --size 44 --label swap1 --fstype=swap | 9 | part swap --ondisk sda --size 44 --label swap1 --fstype=swap |
10 | 10 | ||
diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py index 913e3283dc..3eb669da39 100644 --- a/scripts/lib/wic/ksparser.py +++ b/scripts/lib/wic/ksparser.py | |||
@@ -229,6 +229,23 @@ class KickStart(): | |||
229 | err = "%s:%d: SquashFS does not support LABEL" \ | 229 | err = "%s:%d: SquashFS does not support LABEL" \ |
230 | % (confpath, lineno) | 230 | % (confpath, lineno) |
231 | raise KickStartError(err) | 231 | raise KickStartError(err) |
232 | if parsed.fstype == 'msdos' or parsed.fstype == 'vfat': | ||
233 | if parsed.fsuuid: | ||
234 | if parsed.fsuuid.upper().startswith('0X'): | ||
235 | if len(parsed.fsuuid) > 10: | ||
236 | err = "%s:%d: fsuuid %s given in wks kickstart file " \ | ||
237 | "exceeds the length limit for %s filesystem. " \ | ||
238 | "It should be in the form of a 32 bit hexadecimal" \ | ||
239 | "number (for example, 0xABCD1234)." \ | ||
240 | % (confpath, lineno, parsed.fsuuid, parsed.fstype) | ||
241 | raise KickStartError(err) | ||
242 | elif len(parsed.fsuuid) > 8: | ||
243 | err = "%s:%d: fsuuid %s given in wks kickstart file " \ | ||
244 | "exceeds the length limit for %s filesystem. " \ | ||
245 | "It should be in the form of a 32 bit hexadecimal" \ | ||
246 | "number (for example, 0xABCD1234)." \ | ||
247 | % (confpath, lineno, parsed.fsuuid, parsed.fstype) | ||
248 | raise KickStartError(err) | ||
232 | if parsed.use_label and not parsed.label: | 249 | if parsed.use_label and not parsed.label: |
233 | err = "%s:%d: Must set the label with --label" \ | 250 | err = "%s:%d: Must set the label with --label" \ |
234 | % (confpath, lineno) | 251 | % (confpath, lineno) |
diff --git a/scripts/lib/wic/misc.py b/scripts/lib/wic/misc.py index 4b08d649c6..57c042c503 100644 --- a/scripts/lib/wic/misc.py +++ b/scripts/lib/wic/misc.py | |||
@@ -26,6 +26,7 @@ logger = logging.getLogger('wic') | |||
26 | 26 | ||
27 | # executable -> recipe pairs for exec_native_cmd | 27 | # executable -> recipe pairs for exec_native_cmd |
28 | NATIVE_RECIPES = {"bmaptool": "bmap-tools", | 28 | NATIVE_RECIPES = {"bmaptool": "bmap-tools", |
29 | "dumpe2fs": "e2fsprogs", | ||
29 | "grub-mkimage": "grub-efi", | 30 | "grub-mkimage": "grub-efi", |
30 | "isohybrid": "syslinux", | 31 | "isohybrid": "syslinux", |
31 | "mcopy": "mtools", | 32 | "mcopy": "mtools", |
@@ -138,9 +139,12 @@ def exec_native_cmd(cmd_and_args, native_sysroot, pseudo=""): | |||
138 | if pseudo: | 139 | if pseudo: |
139 | cmd_and_args = pseudo + cmd_and_args | 140 | cmd_and_args = pseudo + cmd_and_args |
140 | 141 | ||
141 | native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin:%s/bin" % \ | 142 | hosttools_dir = get_bitbake_var("HOSTTOOLS_DIR") |
143 | |||
144 | native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin:%s/bin:%s" % \ | ||
142 | (native_sysroot, native_sysroot, | 145 | (native_sysroot, native_sysroot, |
143 | native_sysroot, native_sysroot) | 146 | native_sysroot, native_sysroot, |
147 | hosttools_dir) | ||
144 | 148 | ||
145 | native_cmd_and_args = "export PATH=%s:$PATH;%s" % \ | 149 | native_cmd_and_args = "export PATH=%s:$PATH;%s" % \ |
146 | (native_paths, cmd_and_args) | 150 | (native_paths, cmd_and_args) |
diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py index ebe250b00d..85f9847047 100644 --- a/scripts/lib/wic/partition.py +++ b/scripts/lib/wic/partition.py | |||
@@ -54,6 +54,9 @@ class Partition(): | |||
54 | self.uuid = args.uuid | 54 | self.uuid = args.uuid |
55 | self.fsuuid = args.fsuuid | 55 | self.fsuuid = args.fsuuid |
56 | self.type = args.type | 56 | self.type = args.type |
57 | self.updated_fstab_path = None | ||
58 | self.has_fstab = False | ||
59 | self.update_fstab_in_rootfs = False | ||
57 | 60 | ||
58 | self.lineno = lineno | 61 | self.lineno = lineno |
59 | self.source_file = "" | 62 | self.source_file = "" |
@@ -118,11 +121,15 @@ class Partition(): | |||
118 | return self.fixed_size if self.fixed_size else self.size | 121 | return self.fixed_size if self.fixed_size else self.size |
119 | 122 | ||
120 | def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir, | 123 | def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir, |
121 | bootimg_dir, kernel_dir, native_sysroot): | 124 | bootimg_dir, kernel_dir, native_sysroot, updated_fstab_path): |
122 | """ | 125 | """ |
123 | Prepare content for individual partitions, depending on | 126 | Prepare content for individual partitions, depending on |
124 | partition command parameters. | 127 | partition command parameters. |
125 | """ | 128 | """ |
129 | self.updated_fstab_path = updated_fstab_path | ||
130 | if self.updated_fstab_path and not (self.fstype.startswith("ext") or self.fstype == "msdos"): | ||
131 | self.update_fstab_in_rootfs = True | ||
132 | |||
126 | if not self.source: | 133 | if not self.source: |
127 | if not self.size and not self.fixed_size: | 134 | if not self.size and not self.fixed_size: |
128 | raise WicError("The %s partition has a size of zero. Please " | 135 | raise WicError("The %s partition has a size of zero. Please " |
@@ -207,11 +214,21 @@ class Partition(): | |||
207 | 214 | ||
208 | p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) | 215 | p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) |
209 | if (pseudo_dir): | 216 | if (pseudo_dir): |
217 | # Canonicalize the ignore paths. This corresponds to | ||
218 | # calling oe.path.canonicalize(), which is used in bitbake.conf. | ||
219 | ignore_paths = [rootfs] + (get_bitbake_var("PSEUDO_IGNORE_PATHS") or "").split(",") | ||
220 | canonical_paths = [] | ||
221 | for path in ignore_paths: | ||
222 | if "$" not in path: | ||
223 | trailing_slash = path.endswith("/") and "/" or "" | ||
224 | canonical_paths.append(os.path.realpath(path) + trailing_slash) | ||
225 | ignore_paths = ",".join(canonical_paths) | ||
226 | |||
210 | pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix | 227 | pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix |
211 | pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir | 228 | pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir |
212 | pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir | 229 | pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir |
213 | pseudo += "export PSEUDO_NOSYMLINKEXP=1;" | 230 | pseudo += "export PSEUDO_NOSYMLINKEXP=1;" |
214 | pseudo += "export PSEUDO_IGNORE_PATHS=%s;" % (rootfs + "," + (get_bitbake_var("PSEUDO_IGNORE_PATHS") or "")) | 231 | pseudo += "export PSEUDO_IGNORE_PATHS=%s;" % ignore_paths |
215 | pseudo += "%s " % get_bitbake_var("FAKEROOTCMD") | 232 | pseudo += "%s " % get_bitbake_var("FAKEROOTCMD") |
216 | else: | 233 | else: |
217 | pseudo = None | 234 | pseudo = None |
@@ -237,7 +254,7 @@ class Partition(): | |||
237 | 254 | ||
238 | prefix = "ext" if self.fstype.startswith("ext") else self.fstype | 255 | prefix = "ext" if self.fstype.startswith("ext") else self.fstype |
239 | method = getattr(self, "prepare_rootfs_" + prefix) | 256 | method = getattr(self, "prepare_rootfs_" + prefix) |
240 | method(rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo) | 257 | method(rootfs, cr_workdir, oe_builddir, rootfs_dir, native_sysroot, pseudo) |
241 | self.source_file = rootfs | 258 | self.source_file = rootfs |
242 | 259 | ||
243 | # get the rootfs size in the right units for kickstart (kB) | 260 | # get the rootfs size in the right units for kickstart (kB) |
@@ -245,7 +262,7 @@ class Partition(): | |||
245 | out = exec_cmd(du_cmd) | 262 | out = exec_cmd(du_cmd) |
246 | self.size = int(out.split()[0]) | 263 | self.size = int(out.split()[0]) |
247 | 264 | ||
248 | def prepare_rootfs_ext(self, rootfs, oe_builddir, rootfs_dir, | 265 | def prepare_rootfs_ext(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, |
249 | native_sysroot, pseudo): | 266 | native_sysroot, pseudo): |
250 | """ | 267 | """ |
251 | Prepare content for an ext2/3/4 rootfs partition. | 268 | Prepare content for an ext2/3/4 rootfs partition. |
@@ -269,10 +286,21 @@ class Partition(): | |||
269 | (self.fstype, extraopts, rootfs, label_str, self.fsuuid, rootfs_dir) | 286 | (self.fstype, extraopts, rootfs, label_str, self.fsuuid, rootfs_dir) |
270 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) | 287 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) |
271 | 288 | ||
289 | if self.updated_fstab_path and self.has_fstab: | ||
290 | debugfs_script_path = os.path.join(cr_workdir, "debugfs_script") | ||
291 | with open(debugfs_script_path, "w") as f: | ||
292 | f.write("cd etc\n") | ||
293 | f.write("rm fstab\n") | ||
294 | f.write("write %s fstab\n" % (self.updated_fstab_path)) | ||
295 | debugfs_cmd = "debugfs -w -f %s %s" % (debugfs_script_path, rootfs) | ||
296 | exec_native_cmd(debugfs_cmd, native_sysroot) | ||
297 | |||
272 | mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs) | 298 | mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs) |
273 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) | 299 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) |
274 | 300 | ||
275 | def prepare_rootfs_btrfs(self, rootfs, oe_builddir, rootfs_dir, | 301 | self.check_for_Y2038_problem(rootfs, native_sysroot) |
302 | |||
303 | def prepare_rootfs_btrfs(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, | ||
276 | native_sysroot, pseudo): | 304 | native_sysroot, pseudo): |
277 | """ | 305 | """ |
278 | Prepare content for a btrfs rootfs partition. | 306 | Prepare content for a btrfs rootfs partition. |
@@ -295,7 +323,7 @@ class Partition(): | |||
295 | self.mkfs_extraopts, self.fsuuid, rootfs) | 323 | self.mkfs_extraopts, self.fsuuid, rootfs) |
296 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) | 324 | exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) |
297 | 325 | ||
298 | def prepare_rootfs_msdos(self, rootfs, oe_builddir, rootfs_dir, | 326 | def prepare_rootfs_msdos(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, |
299 | native_sysroot, pseudo): | 327 | native_sysroot, pseudo): |
300 | """ | 328 | """ |
301 | Prepare content for a msdos/vfat rootfs partition. | 329 | Prepare content for a msdos/vfat rootfs partition. |
@@ -324,12 +352,16 @@ class Partition(): | |||
324 | mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir) | 352 | mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir) |
325 | exec_native_cmd(mcopy_cmd, native_sysroot) | 353 | exec_native_cmd(mcopy_cmd, native_sysroot) |
326 | 354 | ||
355 | if self.updated_fstab_path and self.has_fstab: | ||
356 | mcopy_cmd = "mcopy -i %s %s ::/etc/fstab" % (rootfs, self.updated_fstab_path) | ||
357 | exec_native_cmd(mcopy_cmd, native_sysroot) | ||
358 | |||
327 | chmod_cmd = "chmod 644 %s" % rootfs | 359 | chmod_cmd = "chmod 644 %s" % rootfs |
328 | exec_cmd(chmod_cmd) | 360 | exec_cmd(chmod_cmd) |
329 | 361 | ||
330 | prepare_rootfs_vfat = prepare_rootfs_msdos | 362 | prepare_rootfs_vfat = prepare_rootfs_msdos |
331 | 363 | ||
332 | def prepare_rootfs_squashfs(self, rootfs, oe_builddir, rootfs_dir, | 364 | def prepare_rootfs_squashfs(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, |
333 | native_sysroot, pseudo): | 365 | native_sysroot, pseudo): |
334 | """ | 366 | """ |
335 | Prepare content for a squashfs rootfs partition. | 367 | Prepare content for a squashfs rootfs partition. |
@@ -358,6 +390,8 @@ class Partition(): | |||
358 | (self.fstype, extraopts, label_str, self.fsuuid, rootfs) | 390 | (self.fstype, extraopts, label_str, self.fsuuid, rootfs) |
359 | exec_native_cmd(mkfs_cmd, native_sysroot) | 391 | exec_native_cmd(mkfs_cmd, native_sysroot) |
360 | 392 | ||
393 | self.check_for_Y2038_problem(rootfs, native_sysroot) | ||
394 | |||
361 | def prepare_empty_partition_btrfs(self, rootfs, oe_builddir, | 395 | def prepare_empty_partition_btrfs(self, rootfs, oe_builddir, |
362 | native_sysroot): | 396 | native_sysroot): |
363 | """ | 397 | """ |
@@ -419,3 +453,37 @@ class Partition(): | |||
419 | 453 | ||
420 | mkswap_cmd = "mkswap %s -U %s %s" % (label_str, self.fsuuid, path) | 454 | mkswap_cmd = "mkswap %s -U %s %s" % (label_str, self.fsuuid, path) |
421 | exec_native_cmd(mkswap_cmd, native_sysroot) | 455 | exec_native_cmd(mkswap_cmd, native_sysroot) |
456 | |||
457 | def check_for_Y2038_problem(self, rootfs, native_sysroot): | ||
458 | """ | ||
459 | Check if the filesystem is affected by the Y2038 problem | ||
460 | (Y2038 problem = 32 bit time_t overflow in January 2038) | ||
461 | """ | ||
462 | def get_err_str(part): | ||
463 | err = "The {} filesystem {} has no Y2038 support." | ||
464 | if part.mountpoint: | ||
465 | args = [part.fstype, "mounted at %s" % part.mountpoint] | ||
466 | elif part.label: | ||
467 | args = [part.fstype, "labeled '%s'" % part.label] | ||
468 | elif part.part_name: | ||
469 | args = [part.fstype, "in partition '%s'" % part.part_name] | ||
470 | else: | ||
471 | args = [part.fstype, "in partition %s" % part.num] | ||
472 | return err.format(*args) | ||
473 | |||
474 | # ext2 and ext3 are always affected by the Y2038 problem | ||
475 | if self.fstype in ["ext2", "ext3"]: | ||
476 | logger.warn(get_err_str(self)) | ||
477 | return | ||
478 | |||
479 | ret, out = exec_native_cmd("dumpe2fs %s" % rootfs, native_sysroot) | ||
480 | |||
481 | # if ext4 is affected by the Y2038 problem depends on the inode size | ||
482 | for line in out.splitlines(): | ||
483 | if line.startswith("Inode size:"): | ||
484 | size = int(line.split(":")[1].strip()) | ||
485 | if size < 256: | ||
486 | logger.warn("%s Inodes (of size %d) are too small." % | ||
487 | (get_err_str(self), size)) | ||
488 | break | ||
489 | |||
diff --git a/scripts/lib/wic/plugins/imager/direct.py b/scripts/lib/wic/plugins/imager/direct.py index 55db826e93..ea709e8c54 100644 --- a/scripts/lib/wic/plugins/imager/direct.py +++ b/scripts/lib/wic/plugins/imager/direct.py | |||
@@ -54,15 +54,16 @@ class DirectPlugin(ImagerPlugin): | |||
54 | self.native_sysroot = native_sysroot | 54 | self.native_sysroot = native_sysroot |
55 | self.oe_builddir = oe_builddir | 55 | self.oe_builddir = oe_builddir |
56 | 56 | ||
57 | self.debug = options.debug | ||
57 | self.outdir = options.outdir | 58 | self.outdir = options.outdir |
58 | self.compressor = options.compressor | 59 | self.compressor = options.compressor |
59 | self.bmap = options.bmap | 60 | self.bmap = options.bmap |
60 | self.no_fstab_update = options.no_fstab_update | 61 | self.no_fstab_update = options.no_fstab_update |
61 | self.original_fstab = None | 62 | self.updated_fstab_path = None |
62 | 63 | ||
63 | self.name = "%s-%s" % (os.path.splitext(os.path.basename(wks_file))[0], | 64 | self.name = "%s-%s" % (os.path.splitext(os.path.basename(wks_file))[0], |
64 | strftime("%Y%m%d%H%M")) | 65 | strftime("%Y%m%d%H%M")) |
65 | self.workdir = tempfile.mkdtemp(dir=self.outdir, prefix='tmp.wic.') | 66 | self.workdir = self.setup_workdir(options.workdir) |
66 | self._image = None | 67 | self._image = None |
67 | self.ptable_format = self.ks.bootloader.ptable | 68 | self.ptable_format = self.ks.bootloader.ptable |
68 | self.parts = self.ks.partitions | 69 | self.parts = self.ks.partitions |
@@ -78,6 +79,16 @@ class DirectPlugin(ImagerPlugin): | |||
78 | self._image = PartitionedImage(image_path, self.ptable_format, | 79 | self._image = PartitionedImage(image_path, self.ptable_format, |
79 | self.parts, self.native_sysroot) | 80 | self.parts, self.native_sysroot) |
80 | 81 | ||
82 | def setup_workdir(self, workdir): | ||
83 | if workdir: | ||
84 | if os.path.exists(workdir): | ||
85 | raise WicError("Internal workdir '%s' specified in wic arguments already exists!" % (workdir)) | ||
86 | |||
87 | os.makedirs(workdir) | ||
88 | return workdir | ||
89 | else: | ||
90 | return tempfile.mkdtemp(dir=self.outdir, prefix='tmp.wic.') | ||
91 | |||
81 | def do_create(self): | 92 | def do_create(self): |
82 | """ | 93 | """ |
83 | Plugin entry point. | 94 | Plugin entry point. |
@@ -90,11 +101,8 @@ class DirectPlugin(ImagerPlugin): | |||
90 | finally: | 101 | finally: |
91 | self.cleanup() | 102 | self.cleanup() |
92 | 103 | ||
93 | def _write_fstab(self, image_rootfs): | 104 | def update_fstab(self, image_rootfs): |
94 | """overriden to generate fstab (temporarily) in rootfs. This is called | 105 | """Assume partition order same as in wks""" |
95 | from _create, make sure it doesn't get called from | ||
96 | BaseImage.create() | ||
97 | """ | ||
98 | if not image_rootfs: | 106 | if not image_rootfs: |
99 | return | 107 | return |
100 | 108 | ||
@@ -104,18 +112,9 @@ class DirectPlugin(ImagerPlugin): | |||
104 | 112 | ||
105 | with open(fstab_path) as fstab: | 113 | with open(fstab_path) as fstab: |
106 | fstab_lines = fstab.readlines() | 114 | fstab_lines = fstab.readlines() |
107 | self.original_fstab = fstab_lines.copy() | ||
108 | |||
109 | if self._update_fstab(fstab_lines, self.parts): | ||
110 | with open(fstab_path, "w") as fstab: | ||
111 | fstab.writelines(fstab_lines) | ||
112 | else: | ||
113 | self.original_fstab = None | ||
114 | 115 | ||
115 | def _update_fstab(self, fstab_lines, parts): | ||
116 | """Assume partition order same as in wks""" | ||
117 | updated = False | 116 | updated = False |
118 | for part in parts: | 117 | for part in self.parts: |
119 | if not part.realnum or not part.mountpoint \ | 118 | if not part.realnum or not part.mountpoint \ |
120 | or part.mountpoint == "/": | 119 | or part.mountpoint == "/": |
121 | continue | 120 | continue |
@@ -144,7 +143,10 @@ class DirectPlugin(ImagerPlugin): | |||
144 | fstab_lines.append(line) | 143 | fstab_lines.append(line) |
145 | updated = True | 144 | updated = True |
146 | 145 | ||
147 | return updated | 146 | if updated: |
147 | self.updated_fstab_path = os.path.join(self.workdir, "fstab") | ||
148 | with open(self.updated_fstab_path, "w") as f: | ||
149 | f.writelines(fstab_lines) | ||
148 | 150 | ||
149 | def _full_path(self, path, name, extention): | 151 | def _full_path(self, path, name, extention): |
150 | """ Construct full file path to a file we generate. """ | 152 | """ Construct full file path to a file we generate. """ |
@@ -160,7 +162,7 @@ class DirectPlugin(ImagerPlugin): | |||
160 | a partitioned image. | 162 | a partitioned image. |
161 | """ | 163 | """ |
162 | if not self.no_fstab_update: | 164 | if not self.no_fstab_update: |
163 | self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR")) | 165 | self.update_fstab(self.rootfs_dir.get("ROOTFS_DIR")) |
164 | 166 | ||
165 | for part in self.parts: | 167 | for part in self.parts: |
166 | # get rootfs size from bitbake variable if it's not set in .ks file | 168 | # get rootfs size from bitbake variable if it's not set in .ks file |
@@ -273,14 +275,9 @@ class DirectPlugin(ImagerPlugin): | |||
273 | if os.path.isfile(path): | 275 | if os.path.isfile(path): |
274 | shutil.move(path, os.path.join(self.outdir, fname)) | 276 | shutil.move(path, os.path.join(self.outdir, fname)) |
275 | 277 | ||
276 | #Restore original fstab | 278 | # remove work directory when it is not in debugging mode |
277 | if self.original_fstab: | 279 | if not self.debug: |
278 | fstab_path = self.rootfs_dir.get("ROOTFS_DIR") + "/etc/fstab" | 280 | shutil.rmtree(self.workdir, ignore_errors=True) |
279 | with open(fstab_path, "w") as fstab: | ||
280 | fstab.writelines(self.original_fstab) | ||
281 | |||
282 | # remove work directory | ||
283 | shutil.rmtree(self.workdir, ignore_errors=True) | ||
284 | 281 | ||
285 | # Overhead of the MBR partitioning scheme (just one sector) | 282 | # Overhead of the MBR partitioning scheme (just one sector) |
286 | MBR_OVERHEAD = 1 | 283 | MBR_OVERHEAD = 1 |
@@ -343,6 +340,13 @@ class PartitionedImage(): | |||
343 | part.fsuuid = '0x' + str(uuid.uuid4())[:8].upper() | 340 | part.fsuuid = '0x' + str(uuid.uuid4())[:8].upper() |
344 | else: | 341 | else: |
345 | part.fsuuid = str(uuid.uuid4()) | 342 | part.fsuuid = str(uuid.uuid4()) |
343 | else: | ||
344 | #make sure the fsuuid for vfat/msdos align with format 0xYYYYYYYY | ||
345 | if part.fstype == 'vfat' or part.fstype == 'msdos': | ||
346 | if part.fsuuid.upper().startswith("0X"): | ||
347 | part.fsuuid = '0x' + part.fsuuid.upper()[2:].rjust(8,"0") | ||
348 | else: | ||
349 | part.fsuuid = '0x' + part.fsuuid.upper().rjust(8,"0") | ||
346 | 350 | ||
347 | def prepare(self, imager): | 351 | def prepare(self, imager): |
348 | """Prepare an image. Call prepare method of all image partitions.""" | 352 | """Prepare an image. Call prepare method of all image partitions.""" |
@@ -351,7 +355,8 @@ class PartitionedImage(): | |||
351 | # sizes before we can add them and do the layout. | 355 | # sizes before we can add them and do the layout. |
352 | part.prepare(imager, imager.workdir, imager.oe_builddir, | 356 | part.prepare(imager, imager.workdir, imager.oe_builddir, |
353 | imager.rootfs_dir, imager.bootimg_dir, | 357 | imager.rootfs_dir, imager.bootimg_dir, |
354 | imager.kernel_dir, imager.native_sysroot) | 358 | imager.kernel_dir, imager.native_sysroot, |
359 | imager.updated_fstab_path) | ||
355 | 360 | ||
356 | # Converting kB to sectors for parted | 361 | # Converting kB to sectors for parted |
357 | part.size_sec = part.disk_size * 1024 // self.sector_size | 362 | part.size_sec = part.disk_size * 1024 // self.sector_size |
diff --git a/scripts/lib/wic/plugins/source/rootfs.py b/scripts/lib/wic/plugins/source/rootfs.py index f1db83f8a1..96d940a91d 100644 --- a/scripts/lib/wic/plugins/source/rootfs.py +++ b/scripts/lib/wic/plugins/source/rootfs.py | |||
@@ -94,6 +94,7 @@ class RootfsPlugin(SourcePlugin): | |||
94 | "it is not a valid path, exiting" % part.rootfs_dir) | 94 | "it is not a valid path, exiting" % part.rootfs_dir) |
95 | 95 | ||
96 | part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir) | 96 | part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir) |
97 | part.has_fstab = os.path.exists(os.path.join(part.rootfs_dir, "etc/fstab")) | ||
97 | pseudo_dir = os.path.join(part.rootfs_dir, "../pseudo") | 98 | pseudo_dir = os.path.join(part.rootfs_dir, "../pseudo") |
98 | if not os.path.lexists(pseudo_dir): | 99 | if not os.path.lexists(pseudo_dir): |
99 | logger.warn("%s folder does not exist. " | 100 | logger.warn("%s folder does not exist. " |
@@ -103,9 +104,9 @@ class RootfsPlugin(SourcePlugin): | |||
103 | new_rootfs = None | 104 | new_rootfs = None |
104 | new_pseudo = None | 105 | new_pseudo = None |
105 | # Handle excluded paths. | 106 | # Handle excluded paths. |
106 | if part.exclude_path or part.include_path or part.change_directory: | 107 | if part.exclude_path or part.include_path or part.change_directory or part.update_fstab_in_rootfs: |
107 | # We need a new rootfs directory we can delete files from. Copy to | 108 | # We need a new rootfs directory we can safely modify without |
108 | # workdir. | 109 | # interfering with other tasks. Copy to workdir. |
109 | new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs%d" % part.lineno)) | 110 | new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs%d" % part.lineno)) |
110 | 111 | ||
111 | if os.path.lexists(new_rootfs): | 112 | if os.path.lexists(new_rootfs): |
@@ -199,17 +200,33 @@ class RootfsPlugin(SourcePlugin): | |||
199 | if not os.path.lexists(full_path): | 200 | if not os.path.lexists(full_path): |
200 | continue | 201 | continue |
201 | 202 | ||
203 | if new_pseudo: | ||
204 | pseudo = cls.__get_pseudo(native_sysroot, new_rootfs, new_pseudo) | ||
205 | else: | ||
206 | pseudo = None | ||
202 | if path.endswith(os.sep): | 207 | if path.endswith(os.sep): |
203 | # Delete content only. | 208 | # Delete content only. |
204 | for entry in os.listdir(full_path): | 209 | for entry in os.listdir(full_path): |
205 | full_entry = os.path.join(full_path, entry) | 210 | full_entry = os.path.join(full_path, entry) |
206 | if os.path.isdir(full_entry) and not os.path.islink(full_entry): | 211 | rm_cmd = "rm -rf %s" % (full_entry) |
207 | shutil.rmtree(full_entry) | 212 | exec_native_cmd(rm_cmd, native_sysroot, pseudo) |
208 | else: | ||
209 | os.remove(full_entry) | ||
210 | else: | 213 | else: |
211 | # Delete whole directory. | 214 | # Delete whole directory. |
212 | shutil.rmtree(full_path) | 215 | rm_cmd = "rm -rf %s" % (full_path) |
216 | exec_native_cmd(rm_cmd, native_sysroot, pseudo) | ||
217 | |||
218 | # Update part.has_fstab here as fstab may have been added or | ||
219 | # removed by the above modifications. | ||
220 | part.has_fstab = os.path.exists(os.path.join(new_rootfs, "etc/fstab")) | ||
221 | if part.update_fstab_in_rootfs and part.has_fstab: | ||
222 | fstab_path = os.path.join(new_rootfs, "etc/fstab") | ||
223 | # Assume that fstab should always be owned by root with fixed permissions | ||
224 | install_cmd = "install -m 0644 %s %s" % (part.updated_fstab_path, fstab_path) | ||
225 | if new_pseudo: | ||
226 | pseudo = cls.__get_pseudo(native_sysroot, new_rootfs, new_pseudo) | ||
227 | else: | ||
228 | pseudo = None | ||
229 | exec_native_cmd(install_cmd, native_sysroot, pseudo) | ||
213 | 230 | ||
214 | part.prepare_rootfs(cr_workdir, oe_builddir, | 231 | part.prepare_rootfs(cr_workdir, oe_builddir, |
215 | new_rootfs or part.rootfs_dir, native_sysroot, | 232 | new_rootfs or part.rootfs_dir, native_sysroot, |