summaryrefslogtreecommitdiffstats
path: root/scripts/lib/mic/imager/direct.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/mic/imager/direct.py')
-rw-r--r--scripts/lib/mic/imager/direct.py194
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
35from mic.utils.errors import CreatorError, MountError 35from mic.utils.errors import CreatorError, MountError
36from mic.imager.baseimager import BaseImageCreator 36from mic.imager.baseimager import BaseImageCreator
37from mic.utils.oe.misc import * 37from mic.utils.oe.misc import *
38from mic.plugin import pluginmgr
39
40disk_methods = {
41 "do_install_disk":None,
42}
38 43
39class DirectImageCreator(BaseImageCreator): 44class 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: