diff options
Diffstat (limited to 'scripts/lib/mic/imager')
-rw-r--r-- | scripts/lib/mic/imager/direct.py | 194 |
1 files changed, 39 insertions, 155 deletions
diff --git a/scripts/lib/mic/imager/direct.py b/scripts/lib/mic/imager/direct.py index 3827eb8e94..f8c300c787 100644 --- a/scripts/lib/mic/imager/direct.py +++ b/scripts/lib/mic/imager/direct.py | |||
@@ -35,6 +35,11 @@ from mic.utils.partitionedfs import PartitionedMount | |||
35 | from mic.utils.errors import CreatorError, MountError | 35 | from mic.utils.errors import CreatorError, MountError |
36 | from mic.imager.baseimager import BaseImageCreator | 36 | from mic.imager.baseimager import BaseImageCreator |
37 | from mic.utils.oe.misc import * | 37 | from mic.utils.oe.misc import * |
38 | from mic.plugin import pluginmgr | ||
39 | |||
40 | disk_methods = { | ||
41 | "do_install_disk":None, | ||
42 | } | ||
38 | 43 | ||
39 | class DirectImageCreator(BaseImageCreator): | 44 | class DirectImageCreator(BaseImageCreator): |
40 | """ | 45 | """ |
@@ -78,7 +83,6 @@ class DirectImageCreator(BaseImageCreator): | |||
78 | self.native_sysroot = native_sysroot | 83 | self.native_sysroot = native_sysroot |
79 | self.hdddir = hdddir | 84 | self.hdddir = hdddir |
80 | self.staging_data_dir = staging_data_dir | 85 | self.staging_data_dir = staging_data_dir |
81 | self.boot_type = "" | ||
82 | 86 | ||
83 | def __write_fstab(self): | 87 | def __write_fstab(self): |
84 | """overriden to generate fstab (temporarily) in rootfs. This | 88 | """overriden to generate fstab (temporarily) in rootfs. This |
@@ -101,7 +105,7 @@ class DirectImageCreator(BaseImageCreator): | |||
101 | def _update_fstab(self, fstab_lines, parts): | 105 | def _update_fstab(self, fstab_lines, parts): |
102 | """Assume partition order same as in wks""" | 106 | """Assume partition order same as in wks""" |
103 | for num, p in enumerate(parts, 1): | 107 | for num, p in enumerate(parts, 1): |
104 | if p.mountpoint == "/" or p.mountpoint == "/boot": | 108 | if not p.mountpoint or p.mountpoint == "/" or p.mountpoint == "/boot": |
105 | continue | 109 | continue |
106 | if self._ptable_format == 'msdos' and num > 3: | 110 | if self._ptable_format == 'msdos' and num > 3: |
107 | device_name = "/dev/" + p.disk + str(num + 1) | 111 | device_name = "/dev/" + p.disk + str(num + 1) |
@@ -132,6 +136,15 @@ class DirectImageCreator(BaseImageCreator): | |||
132 | 136 | ||
133 | return fstab_contents | 137 | return fstab_contents |
134 | 138 | ||
139 | def set_bootimg_dir(self, bootimg_dir): | ||
140 | """ | ||
141 | Accessor for bootimg_dir, the actual location used for the source | ||
142 | of the bootimg. Should be set by source plugins (only if they | ||
143 | change the default bootimg source) so the correct info gets | ||
144 | displayed for print_outimage_info(). | ||
145 | """ | ||
146 | self.bootimg_dir = bootimg_dir | ||
147 | |||
135 | def _get_parts(self): | 148 | def _get_parts(self): |
136 | if not self.ks: | 149 | if not self.ks: |
137 | raise CreatorError("Failed to get partition info, " | 150 | raise CreatorError("Failed to get partition info, " |
@@ -182,19 +195,18 @@ class DirectImageCreator(BaseImageCreator): | |||
182 | """ Construct full file path to a file we generate. """ | 195 | """ Construct full file path to a file we generate. """ |
183 | return os.path.join(path, self._full_name(name, extention)) | 196 | return os.path.join(path, self._full_name(name, extention)) |
184 | 197 | ||
185 | def get_boot_type(self): | 198 | def get_default_source_plugin(self): |
186 | """ Determine the boot type from fstype and mountpoint. """ | 199 | """ |
187 | parts = self._get_parts() | 200 | The default source plugin i.e. the plugin that's consulted for |
188 | 201 | overall image generation tasks outside of any particular | |
189 | boot_type = "" | 202 | partition. For convenience, we just hang it off the |
190 | 203 | bootloader handler since it's the one non-partition object in | |
191 | for p in parts: | 204 | any setup. By default the default plugin is set to the same |
192 | if p.mountpoint == "/boot": | 205 | plugin as the /boot partition; since we hang it off the |
193 | if p.fstype == "msdos": | 206 | bootloader object, the default can be explicitly set using the |
194 | boot_type = "pcbios" | 207 | --source bootloader param. |
195 | else: | 208 | """ |
196 | boot_type = p.fstype | 209 | return self.ks.handler.bootloader.source |
197 | return boot_type | ||
198 | 210 | ||
199 | # | 211 | # |
200 | # Actual implemention | 212 | # Actual implemention |
@@ -231,25 +243,7 @@ class DirectImageCreator(BaseImageCreator): | |||
231 | if not self.ks.handler.bootloader.source and p.mountpoint == "/boot": | 243 | if not self.ks.handler.bootloader.source and p.mountpoint == "/boot": |
232 | self.ks.handler.bootloader.source = p.source | 244 | self.ks.handler.bootloader.source = p.source |
233 | 245 | ||
234 | self.boot_type = self.get_boot_type() | ||
235 | |||
236 | if not self.bootimg_dir: | ||
237 | if self.boot_type == "pcbios": | ||
238 | self.bootimg_dir = self.staging_data_dir | ||
239 | elif self.boot_type == "efi": | ||
240 | self.bootimg_dir = self.hdddir | ||
241 | |||
242 | if self.boot_type == "pcbios": | ||
243 | self._create_syslinux_config() | ||
244 | elif self.boot_type == "efi": | ||
245 | self._create_grubefi_config() | ||
246 | else: | ||
247 | raise CreatorError("Failed to detect boot type (no /boot partition?), " | ||
248 | "please check your kickstart setting.") | ||
249 | |||
250 | for p in parts: | 246 | for p in parts: |
251 | if p.fstype == "efi": | ||
252 | p.fstype = "msdos" | ||
253 | # need to create the filesystems in order to get their | 247 | # need to create the filesystems in order to get their |
254 | # sizes before we can add them and do the layout. | 248 | # sizes before we can add them and do the layout. |
255 | # PartitionedMount.mount() actually calls __format_disks() | 249 | # PartitionedMount.mount() actually calls __format_disks() |
@@ -266,9 +260,8 @@ class DirectImageCreator(BaseImageCreator): | |||
266 | # when/if we need to actually do package selection we | 260 | # when/if we need to actually do package selection we |
267 | # should modify things to use those objects, but for now | 261 | # should modify things to use those objects, but for now |
268 | # we can avoid that. | 262 | # we can avoid that. |
269 | p.prepare(self.workdir, self.oe_builddir, self.boot_type, | 263 | p.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir, |
270 | self.rootfs_dir, self.bootimg_dir, self.kernel_dir, | 264 | self.bootimg_dir, self.kernel_dir, self.native_sysroot) |
271 | self.native_sysroot) | ||
272 | 265 | ||
273 | self.__instimage.add_partition(int(p.size), | 266 | self.__instimage.add_partition(int(p.size), |
274 | p.disk, | 267 | p.disk, |
@@ -311,8 +304,16 @@ class DirectImageCreator(BaseImageCreator): | |||
311 | For now, it just prepares the image to be bootable by e.g. | 304 | For now, it just prepares the image to be bootable by e.g. |
312 | creating and installing a bootloader configuration. | 305 | creating and installing a bootloader configuration. |
313 | """ | 306 | """ |
314 | if self.boot_type == "pcbios": | 307 | source_plugin = self.get_default_source_plugin() |
315 | self._install_syslinux() | 308 | if source_plugin: |
309 | self._source_methods = pluginmgr.get_source_plugin_methods(source_plugin, disk_methods) | ||
310 | for disk_name, disk in self.__instimage.disks.items(): | ||
311 | self._source_methods["do_install_disk"](disk, disk_name, self, | ||
312 | self.workdir, | ||
313 | self.oe_builddir, | ||
314 | self.bootimg_dir, | ||
315 | self.kernel_dir, | ||
316 | self.native_sysroot) | ||
316 | 317 | ||
317 | def print_outimage_info(self): | 318 | def print_outimage_info(self): |
318 | """ | 319 | """ |
@@ -352,123 +353,6 @@ class DirectImageCreator(BaseImageCreator): | |||
352 | 353 | ||
353 | return (rootdev, root_part_uuid) | 354 | return (rootdev, root_part_uuid) |
354 | 355 | ||
355 | def _create_syslinux_config(self): | ||
356 | hdddir = "%s/hdd/boot" % self.workdir | ||
357 | rm_cmd = "rm -rf " + self.workdir | ||
358 | exec_cmd(rm_cmd) | ||
359 | |||
360 | install_cmd = "install -d %s" % hdddir | ||
361 | tmp = exec_cmd(install_cmd) | ||
362 | |||
363 | splash = os.path.join(self.workdir, "/hdd/boot/splash.jpg") | ||
364 | if os.path.exists(splash): | ||
365 | splashline = "menu background splash.jpg" | ||
366 | else: | ||
367 | splashline = "" | ||
368 | |||
369 | (rootdev, root_part_uuid) = self._get_boot_config() | ||
370 | options = self.ks.handler.bootloader.appendLine | ||
371 | |||
372 | syslinux_conf = "" | ||
373 | syslinux_conf += "PROMPT 0\n" | ||
374 | timeout = kickstart.get_timeout(self.ks) | ||
375 | if not timeout: | ||
376 | timeout = 0 | ||
377 | syslinux_conf += "TIMEOUT " + str(timeout) + "\n" | ||
378 | syslinux_conf += "\n" | ||
379 | syslinux_conf += "ALLOWOPTIONS 1\n" | ||
380 | syslinux_conf += "SERIAL 0 115200\n" | ||
381 | syslinux_conf += "\n" | ||
382 | if splashline: | ||
383 | syslinux_conf += "%s\n" % splashline | ||
384 | syslinux_conf += "DEFAULT boot\n" | ||
385 | syslinux_conf += "LABEL boot\n" | ||
386 | |||
387 | kernel = "/vmlinuz" | ||
388 | syslinux_conf += "KERNEL " + kernel + "\n" | ||
389 | |||
390 | if self._ptable_format == 'msdos': | ||
391 | rootstr = rootdev | ||
392 | else: | ||
393 | if not root_part_uuid: | ||
394 | raise MountError("Cannot find the root GPT partition UUID") | ||
395 | rootstr = "PARTUUID=%s" % root_part_uuid | ||
396 | |||
397 | syslinux_conf += "APPEND label=boot root=%s %s\n" % (rootstr, options) | ||
398 | |||
399 | msger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg" \ | ||
400 | % self.workdir) | ||
401 | cfg = open("%s/hdd/boot/syslinux.cfg" % self.workdir, "w") | ||
402 | cfg.write(syslinux_conf) | ||
403 | cfg.close() | ||
404 | |||
405 | def _create_grubefi_config(self): | ||
406 | hdddir = "%s/hdd/boot" % self.workdir | ||
407 | rm_cmd = "rm -rf %s" % self.workdir | ||
408 | exec_cmd(rm_cmd) | ||
409 | |||
410 | install_cmd = "install -d %s/EFI/BOOT" % hdddir | ||
411 | tmp = exec_cmd(install_cmd) | ||
412 | |||
413 | splash = os.path.join(self.workdir, "/EFI/boot/splash.jpg") | ||
414 | if os.path.exists(splash): | ||
415 | splashline = "menu background splash.jpg" | ||
416 | else: | ||
417 | splashline = "" | ||
418 | |||
419 | (rootdev, root_part_uuid) = self._get_boot_config() | ||
420 | options = self.ks.handler.bootloader.appendLine | ||
421 | |||
422 | grubefi_conf = "" | ||
423 | grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n" | ||
424 | grubefi_conf += "default=boot\n" | ||
425 | timeout = kickstart.get_timeout(self.ks) | ||
426 | if not timeout: | ||
427 | timeout = 0 | ||
428 | grubefi_conf += "timeout=%s\n" % timeout | ||
429 | grubefi_conf += "menuentry 'boot'{\n" | ||
430 | |||
431 | kernel = "/vmlinuz" | ||
432 | |||
433 | if self._ptable_format == 'msdos': | ||
434 | rootstr = rootdev | ||
435 | else: | ||
436 | if not root_part_uuid: | ||
437 | raise MountError("Cannot find the root GPT partition UUID") | ||
438 | rootstr = "PARTUUID=%s" % root_part_uuid | ||
439 | |||
440 | grubefi_conf += "linux %s root=%s rootwait %s\n" \ | ||
441 | % (kernel, rootstr, options) | ||
442 | grubefi_conf += "}\n" | ||
443 | if splashline: | ||
444 | syslinux_conf += "%s\n" % splashline | ||
445 | |||
446 | msger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg" \ | ||
447 | % self.workdir) | ||
448 | cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % self.workdir, "w") | ||
449 | cfg.write(grubefi_conf) | ||
450 | cfg.close() | ||
451 | |||
452 | def _install_syslinux(self): | ||
453 | mbrfile = "%s/syslinux/" % self.bootimg_dir | ||
454 | if self._ptable_format == 'gpt': | ||
455 | mbrfile += "gptmbr.bin" | ||
456 | else: | ||
457 | mbrfile += "mbr.bin" | ||
458 | |||
459 | if not os.path.exists(mbrfile): | ||
460 | msger.error("Couldn't find %s. If using the -e option, do you have the right MACHINE set in local.conf? If not, is the bootimg_dir path correct?" % mbrfile) | ||
461 | |||
462 | for disk_name, disk in self.__instimage.disks.items(): | ||
463 | full_path = self._full_path(self.__imgdir, disk_name, "direct") | ||
464 | msger.debug("Installing MBR on disk %s as %s with size %s bytes" \ | ||
465 | % (disk_name, full_path, disk['min_size'])) | ||
466 | |||
467 | rc = runner.show(['dd', 'if=%s' % mbrfile, | ||
468 | 'of=%s' % full_path, 'conv=notrunc']) | ||
469 | if rc != 0: | ||
470 | raise MountError("Unable to set MBR to %s" % full_path) | ||
471 | |||
472 | def _unmount_instroot(self): | 356 | def _unmount_instroot(self): |
473 | if not self.__instimage is None: | 357 | if not self.__instimage is None: |
474 | try: | 358 | try: |