Patch for Bug #227013 - /boot not mounted
[moblin-image-creator.eeepc.git] / libs / InstallImage.py
blobd07d1ed7ffb862a143d6f376247840560c14c7fc
1 #!/usr/bin/python -tt
2 # vim: ai ts=4 sts=4 et sw=4
4 # Copyright (c) 2007 Intel Corporation
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the Free
8 # Software Foundation; version 2 of the License
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 # for more details.
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc., 59
17 # Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 import gettext
20 import os
21 import re
22 import shutil
23 import sys
24 import tempfile
25 import traceback
27 import Project
28 import SDK
29 import mic_cfg
30 import pdk_utils
32 debug = False
33 if mic_cfg.config.has_option('general', 'debug'):
34 debug = int(mic_cfg.config.get('general', 'debug'))
36 _ = gettext.lgettext
38 class SyslinuxCfg(object):
39 """Class to provide helper functions for doing the syslinux stuff.
40 Syslinux home page: http://syslinux.zytor.com/"""
41 def __init__(self, project, path, cfg_filename, message_color, message):
42 try:
43 self.project = project
44 self.path = path
45 self.cfg_filename = cfg_filename
46 self.cfg_path = os.path.join(self.path, cfg_filename)
47 self.msg_path = os.path.join(self.path, 'boot.msg')
48 self.index = 1
50 for section in [ "installimage.%s" % self.project.platform.name, "installimage" ]:
51 if mic_cfg.config.has_section(section):
52 # section is now set to the appropriate section
53 break
54 welcome_mesg = mic_cfg.config.get(section, "welcome_message")
55 # Create and initialize the syslinux config file
56 cfg_file = open(self.cfg_path, 'w')
57 print >> cfg_file, """\
58 prompt 1
59 display boot.msg
60 """
61 cfg_file.close()
62 # Create and initialize the syslinux boot message file
63 msg_file = open(self.msg_path, 'w')
64 msg_file.write("\f")
65 print >> msg_file, "\n" + welcome_mesg + "\n"
66 msg_file.close()
67 self.setMessage(message_color, message)
68 except:
69 if debug: print_exc_plus()
70 sys.exit(1)
72 def setMessage(self, message_color, message):
73 """message_color is the 2 bytes to set the background and foreground
74 color as documented in the syslinux documentation under DISPLAY file
75 format
77 <SI><bg><fg> <SI> = <Ctrl-O> = ASCII 15
78 Set the display colors to the specified background and
79 foreground colors, where <bg> and <fg> are hex digits,
80 corresponding to the standard PC display attributes:
82 0 = black 8 = dark grey
83 1 = dark blue 9 = bright blue
84 2 = dark green a = bright green
85 3 = dark cyan b = bright cyan
86 4 = dark red c = bright red
87 5 = dark purple d = bright purple
88 6 = brown e = yellow
89 7 = light grey f = white
91 Picking a bright color (8-f) for the background results in the
92 corresponding dark color (0-7), with the foreground flashing.
93 """
94 if len(message_color) != 2:
95 raise ValueError(_("message_color string must be 2 bytes long. Passed in string was: %s bytes long. String: %s") % (len(message_color), message(color)))
96 msg_file = open(self.msg_path, 'a ')
97 msg_file.write(chr(15) + message_color)
98 msg_file.write(message)
99 # Set it back to light gray on black
100 print >> msg_file, chr(15) + "07"
102 def __repr__(self):
103 return 'SyslinuxCfg(path = "%s", cfg_filename = "%s")' % (self.path,
104 self.cfg_filename)
106 def __str__(self):
107 return "<SyslinuxCfg: __dict__=%s>" % self.__dict__
109 def add_default(self, kernel, append = 'initrd=initrd.img'):
110 label = 'linux'
111 append = re.sub(r'initrd.img',"initrd0.img", append)
112 kernel_file = 'vmlinuz'
113 # Add the default entry to the syslinux config file
114 cfg_file = open(self.cfg_path, 'a ')
115 print >> cfg_file, "default " + label
116 print >> cfg_file, "label " + label
117 print >> cfg_file, " kernel " + kernel_file
118 print >> cfg_file, " append " + append
119 cfg_file.close()
120 # Add the default entry in the syslinux boot message file
121 msg_file = open(self.msg_path, 'a ')
122 msg_file.write("- To boot default " + kernel + " kernel, press " + \
123 chr(15) + "0f<ENTER>" + chr(15) + "07\n\n")
124 msg_file.close()
125 return kernel_file
127 def add_target(self, kernel, append = 'initrd=initrd.img'):
128 label = "linux%s" % self.index
129 kernel_file = "linux%s" % self.index
130 append = re.sub(r'initrd.img',"initrd%d.img" % self.index, append)
131 self.index += 1
132 # Add the target to the syslinux config file
133 cfg_file = open(self.cfg_path, 'a ')
134 print >> cfg_file, "label " + label
135 print >> cfg_file, " kernel " + kernel_file
136 print >> cfg_file, " append " + append
137 cfg_file.close()
138 # Add the target to the syslinux boot message file
139 msg_file = open(self.msg_path, 'a ')
140 msg_file.write("- To boot " + kernel + " kernel, type: " + chr(15) + \
141 "\x01" + label + " <ENTER>" + chr(15) + "\x07\n\n")
142 msg_file.close()
143 return kernel_file
145 class InstallImage(object):
147 This is the base class for any type of target image output.
149 This is used as the super-class for sub-classes that will generate
150 installation images for a specific target and for a specific class
151 of installation device/medium. Such as installation of a target system
152 on a LiveUSB Key, LiveCD/DVD's, Hard Disks, and Flash Parts.
154 def __init__(self, project, target, name, progress_callback = None):
155 self.project = project
156 self.target = target
157 self.name = name
158 self.progress_callback = progress_callback
159 self.path = os.path.join(self.target.image_path, self.name)
160 self.tmp_path = ''
161 self.rootfs = ''
162 self.rootfs_path = ''
163 self.kernels = []
164 self.default_kernel = ''
165 # Find the config section for whole class usage
166 for section in [ "installimage.%s" % self.project.platform.name, "installimage" ]:
167 if mic_cfg.config.has_section(section):
168 # section is now set to the appropriate section
169 break
170 self.section = section
171 for filename in os.listdir(os.path.join(self.target.fs_path, 'boot')):
172 if filename.find('vmlinuz') == 0:
173 if (not self.default_kernel) and (filename.find('default') > 0):
174 self.default_kernel = filename
175 else:
176 self.kernels.append(filename)
177 if (not self.kernels) and (not self.default_kernel):
178 raise ValueError(_("no kernels were found"))
179 self.kernels.sort()
180 if not self.default_kernel:
181 self.default_kernel = self.kernels.pop(0)
182 self.default_kernel_mod_path = os.path.join(self.target.fs_path, 'lib', 'modules', self.default_kernel.split('vmlinuz-').pop().strip())
183 self.exclude_file = os.path.join(self.project.platform.path, 'exclude')
185 def install_kernels(self, cfg_filename, message_color, message, imageType='USBImage'):
186 if not self.tmp_path:
187 raise ValueError, _("tmp_path doesn't exist")
189 s = SyslinuxCfg(self.project, self.tmp_path, cfg_filename, message_color, message)
190 # Copy the default kernel
191 if imageType == 'CDImage':
192 kernel_name = s.add_default(self.default_kernel, self.project.get_target_cd_kernel_cmdline(self.target.name))
193 else:
194 kernel_name = s.add_default(self.default_kernel, self.project.get_target_usb_kernel_cmdline(self.target.name))
195 src_path = os.path.join(self.target.fs_path, 'boot', self.default_kernel)
196 dst_path = os.path.join(self.tmp_path, kernel_name)
197 shutil.copyfile(src_path, dst_path)
198 # Copy the remaining kernels
199 for kernel in self.kernels:
200 if imageType == 'CDImage':
201 kernel_name = s.add_target(kernel, self.project.get_target_cd_kernel_cmdline(self.target.name))
202 else:
203 kernel_name = s.add_target(kernel, self.project.get_target_usb_kernel_cmdline(self.target.name))
204 src_path = os.path.join(self.target.fs_path, 'boot', kernel)
205 dst_path = os.path.join(self.tmp_path, kernel_name)
206 shutil.copyfile(src_path, dst_path)
208 def create_fstab(self, swap = True):
209 fstab_file = open(os.path.join(self.target.fs_path, 'etc/fstab'), 'w')
210 print >> fstab_file, "unionfs / unionfs defaults 0 0"
211 print >> fstab_file, "proc /proc proc defaults 0 0"
212 if swap:
213 print >> fstab_file, "/dev/sda3 none swap sw 0 0"
214 fstab_file.close()
216 def create_modules_dep(self):
217 base_dir = self.target.fs_path[len(self.project.path):]
218 boot_path = os.path.join(self.target.fs_path, 'boot')
220 for filename in os.listdir(boot_path):
221 if filename.find('System.map-') == 0:
222 kernel_version = filename[len('System.map-'):]
224 tmp_str = "lib/modules/%s/modules.dep" % kernel_version
225 moddep_file = os.path.join(self.target.fs_path, tmp_str)
227 symbol_file = os.path.join(base_dir, 'boot', filename)
229 cmd = "depmod -b %s -v %s -F %s" % (base_dir, kernel_version, symbol_file)
230 self.project.chroot(cmd)
232 def create_rootfs(self):
233 """Create the root file system, using mksquashfs. If we don't want to
234 use squashfs on the device then the content will be copied out of the
235 squashfs image during the install"""
236 print _("Creating root file system...")
237 # re-create fstab every time, since user could change fstab options on
238 # the fly (by editing image-creator.cfg)
239 fstab_path = os.path.join(self.target.fs_path, 'etc/fstab')
240 if int(mic_cfg.config.get(self.section, "swap_option")) == 2:
241 swap = True
242 else:
243 swap = False
244 self.create_fstab(swap)
245 self.create_modules_dep()
246 self.rootfs = 'rootfs.img'
247 self.rootfs_path = os.path.join(self.target.image_path, self.rootfs)
248 if os.path.isfile(self.rootfs_path):
249 os.remove(self.rootfs_path)
251 fs_path = self.target.fs_path[len(self.project.path):]
252 image_path = self.target.image_path[len(self.project.path):]
253 image_path = os.path.join(image_path,'rootfs.img')
254 cmd = "mksquashfs %s %s -no-progress -ef %s" % (fs_path, image_path, self.exclude_file)
255 self.write_manifest(self.path)
256 self.target.umount()
257 print _("Executing the mksquashfs program: %s") % cmd
258 self.project.chroot(cmd)
259 self.target.mount()
261 def delete_rootfs(self):
262 if self.rootfs and os.path.isfile(self.rootfs_path):
263 os.remove(self.rootfs_path)
264 self.rootfs = ''
265 self.rootfs_path = ''
267 def create_bootfs(self):
268 self.bootfs = 'bootfs.img'
269 self.bootfs_path = os.path.join(self.target.image_path, self.bootfs)
270 if os.path.isfile(self.bootfs_path):
271 os.remove(self.bootfs_path)
272 print _("Creating bootfs at: %s") % self.bootfs_path
273 # Remove old initrd images
274 for file in os.listdir(os.path.join(self.target.fs_path, 'boot')):
275 if file.find('initrd.img') == 0:
276 os.remove(os.path.join(self.target.fs_path, 'boot', file))
277 self.kernels.insert(0,self.default_kernel)
278 # copy pre-created initrd img (by create_all_initramfs) for each installed kernel
279 for count, kernel in enumerate(self.kernels):
280 version_str = kernel.split('vmlinuz-').pop().strip()
281 initrd_name = "initrd.img-" + version_str
282 shutil.copy("/tmp/.tmp.initrd%d" % count, os.path.join(self.target.fs_path, 'boot', initrd_name))
283 self.kernels.pop(0)
284 fs_path = self.target.fs_path[len(self.project.path):]
285 fs_path = os.path.join(fs_path, 'boot')
286 image_path = self.target.image_path[len(self.project.path):]
287 image_path = os.path.join(image_path,'bootfs.img')
288 cmd = "mksquashfs %s %s -no-progress" % (fs_path, image_path)
289 self.project.chroot(cmd)
291 def delete_bootfs(self):
292 if self.bootfs and os.path.isfile(self.bootfs_path):
293 os.remove(self.bootfs_path)
294 self.bootfs = ''
295 self.bootfs_path = ''
297 def create_install_script(self, output_dir):
298 shutil.copy(os.path.join(self.project.platform.path, 'install.sh'), output_dir)
299 self.create_install_cfg(output_dir)
301 def create_install_cfg(self, output_dir):
302 cfg_file = os.path.join(output_dir, "install.cfg")
303 self.writeShellConfigFile(cfg_file)
304 print _("install.cfg created")
306 def writeShellConfigFile(self, filename):
307 """Write all of the config file options that we care about to the
308 specified file"""
309 # How big to make the boot partition for the HD installation image
310 boot_partition_size = int(mic_cfg.config.get(self.section, "boot_partition_size"))
311 # Options for swap partition: 0. No swap 1. swap always off 2. swap always on
312 swap_option = int(mic_cfg.config.get(self.section, "swap_option"))
313 # How big to make the swap partition for the HD installation image
314 swap_partition_size = int(mic_cfg.config.get(self.section, "swap_partition_size"))
315 # How big to make the fat32 partition for the HD installation image
316 fat32_partition_size = int(mic_cfg.config.get(self.section, "fat32_partition_size"))
317 # Use squashfs or not
318 use_squashfs = int(mic_cfg.config.get(self.section, "use_squashfs"))
319 if swap_option == 0:
320 swap_partition_size = 0
321 cfg_dict = {
322 'boot_partition_size' : boot_partition_size,
323 'swap_option' : swap_option,
324 'swap_partition_size' : swap_partition_size,
325 'fat32_partition_size' : fat32_partition_size,
326 'use_squashfs' : use_squashfs,
328 output_file = open(filename, 'w')
329 print >> output_file, "#!/bin/bash"
330 print >> output_file, "# Dynamically generated config file"
331 for key, value in sorted(cfg_dict.iteritems()):
332 print >> output_file, "%s=%s" % (key, value)
333 output_file.close()
335 def create_all_initramfs(self):
336 self.kernels.insert(0, self.default_kernel)
337 for count, kernel in enumerate(self.kernels):
338 kernel_version = kernel.split('vmlinuz-').pop().strip()
339 self.create_initramfs("/tmp/.tmp.initrd%d" % count, kernel_version)
340 self.kernels.pop(0)
342 def create_initramfs(self, initrd_file, kernel_version):
343 print _("Creating initramfs for kernel version: %s") % kernel_version
344 # copy the platform initramfs stuff into /etc/initramfs-tools/ in the target
345 src_path = os.path.join('/usr/share/pdk/platforms', self.project.platform.name, 'initramfs')
346 dst_path = os.path.join(self.target.fs_path, 'etc', 'initramfs-tools', )
347 pdk_utils.rmtree(dst_path, True, callback = self.progress_callback)
348 shutil.copytree(src_path, dst_path, True)
349 # Create our config file that is used by our scripts during the running
350 # of initramfs. The initramfs/hooks/mobile script in each platform
351 # takes care of putting this file into place into the initramfs image.
352 cfg_filename = os.path.join(dst_path, "moblin-initramfs.cfg")
353 self.writeShellConfigFile(cfg_filename)
354 print _("moblin-initramfs.cfg file created")
355 kernel_mod_path = os.path.join('/lib/modules', kernel_version)
356 cmd = "mkinitramfs -o %s %s" % (initrd_file , kernel_mod_path)
357 print _("Executing: %s") % cmd
358 self.target.chroot(cmd)
360 def create_grub_menu(self):
361 print _("Creating the grub menu")
362 # remove previous menu.lst, since we are about to create one
363 menu_dir = os.path.join(self.target.path, "boot/grub")
364 menu_file = os.path.join(menu_dir, "menu.lst")
365 if os.path.exists(menu_file):
366 os.unlink(menu_file)
367 if not os.path.exists(menu_dir):
368 os.makedirs(menu_dir)
369 self.target.chroot("update-grub -y")
370 # FIXME: JLV: I really don't like all this sed usage, need to clean this up
371 self.target.chroot("/bin/sed s+/boot/+/+g -i /boot/grub/menu.lst")
372 menu=open(os.path.join(self.target.fs_path,"boot","grub","menu.lst"),'r')
373 for count, line in enumerate(menu):
374 if line.find('title') == 0:
375 print line
376 if line.find(self.default_kernel.split('vmlinuz-').pop().strip()) > 0:
377 # FIXME: JLV: I really don't like all this sed usage, need to clean this up
378 cmd="sed s/^default.*/default\\t\\t%d/g -i /boot/grub/menu.lst" % count
379 print cmd
380 self.target.chroot(cmd)
381 break;
382 menu.close()
384 def __str__(self):
385 return ("<InstallImage: project=%s, target=%s, name=%s>"
386 % (self.project, self.target, self.name))
388 def write_manifest(self, image_path):
389 all_packages = []
390 self.target.chroot("dpkg-query --show", output = all_packages)
391 manifest = open(image_path.rstrip('.img') + '.manifest', 'w')
392 print >>manifest, "\n".join(all_packages)
393 manifest.close()
396 class LiveIsoImage(InstallImage):
397 def install_kernels(self, message_color, message):
398 InstallImage.install_kernels(self, 'isolinux.cfg', message_color, message, 'CDImage')
400 def create_image(self, fs_type='RAMFS'):
401 print _("LiveCDImage: Creating Live CD Image(%s) Now...") % fs_type
402 image_type = _("Live CD Image (no persistent R/W)")
403 self.create_all_initramfs()
404 self.create_rootfs()
405 initrd_stat_result = os.stat('/tmp/.tmp.initrd0')
406 rootfs_stat_result = os.stat(self.rootfs_path)
408 self.tmp_path = tempfile.mkdtemp('','pdk-', '/tmp')
410 self.kernels.insert(0,self.default_kernel)
411 for count, kernel in enumerate(self.kernels):
412 initrd_path = os.path.join(self.tmp_path, "initrd%d.img" % count)
413 shutil.move("/tmp/.tmp.initrd%d" % count, initrd_path)
414 self.kernels.pop(0)
415 # Flashing yellow on a blue background
416 self.install_kernels("9e", image_type)
417 pdk_utils.copy(self.rootfs_path, self.tmp_path, callback = self.progress_callback)
418 pdk_utils.copy("/usr/lib/syslinux/isolinux.bin", self.tmp_path, callback = self.progress_callback)
420 print _("Creating CD image file at: %s") % self.path
421 cmd_line = "genisoimage -quiet -o %s -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -l -R -r %s" % (self.path, self.tmp_path)
422 result = pdk_utils.execCommand(cmd_line, callback = self.progress_callback)
423 if result:
424 print >> sys.stderr, _("Error running command: %s") % cmd_line
425 raise EnvironmentError, _("Error running command: %s") % cmd_line
427 shutil.rmtree(self.tmp_path)
428 self.tmp_path = ''
430 self.delete_rootfs()
431 print _("LiveIsoImage: Finished!")
433 def __str__(self):
434 return ("<LiveIsoImage: project=%s, target=%s, name=%s>"
435 % (self.project, self.target, self.name))
438 class InstallIsoImage(InstallImage):
439 def create_image(self):
440 raise ValueError(_("InstallIsoImage: Create Install ISO Image not implemented!"))
442 def __str__(self):
443 return ("<InstallIsoImage: project=%s, target=%s, name=%s>"
444 % (self.project, self.target, self.name))
447 class BaseUsbImage(InstallImage):
448 def install_kernels(self, message_color, message):
449 InstallImage.install_kernels(self, 'syslinux.cfg', message_color, message)
451 def create_usb_image(self, size):
452 print _("Creating USB flash drive image file at: %s") % self.path
453 out_file = open(self.path, 'w')
454 # Make a kibibyte length string of zeroes
455 out_string = chr(0) * 1024
456 # Write the string out to the file to create file of size * mibibyte in length
457 for count in range(0, size * 1024):
458 if self.progress_callback and count % 1024 == 0:
459 self.progress_callback(None)
460 out_file.write(out_string)
461 out_file.close()
463 cmd_line = "mkfs.vfat %s" % self.path
464 result = pdk_utils.execCommand(cmd_line, callback = self.progress_callback)
465 if result:
466 print >> sys.stderr, _("Error running command: %s") % cmd_line
467 raise EnvironmentError, _("Error running command: %s") % cmd_line
469 # NOTE: Running syslinux on the host development system
470 # means the host and target have compatible architectures.
471 # This runs syslinux inside the jailroot so the correct
472 # version of syslinux is used.
473 jail_path = self.path[len(self.project.path):]
474 self.project.chroot('syslinux %s' % jail_path)
476 def create_ext3fs_file(self, path, size):
477 """Create a ext3fs file. size is how big to make the file in megabytes"""
478 out_file = open(path, 'w')
479 out_string = chr(0) * 1024
480 for count in range(0, size * 1024):
481 out_file.write(out_string)
482 out_file.close()
484 cmd_line = "mkfs.ext3 %s -F" % path
485 result = pdk_utils.execCommand(cmd_line, callback = self.progress_callback)
486 if result:
487 print >> sys.stderr, _("Error running command: %s") % cmd_line
488 raise EnvironmentError, _("Error running command: %s") % cmd_line
490 def mount_container(self):
491 if not self.tmp_path:
492 self.tmp_path = tempfile.mkdtemp('','pdk-', '/tmp')
493 cmd_line = "mount -o loop -t vfat %s %s" % (self.path, self.tmp_path)
494 result = pdk_utils.execCommand(cmd_line, callback = self.progress_callback)
495 if result:
496 print >> sys.stderr, _("Error running command: %s") % cmd_line
497 raise EnvironmentError, _("Error running command: %s") % cmd_line
499 def umount_container(self):
500 if self.tmp_path:
501 result = pdk_utils.umount(self.tmp_path)
502 if not result:
503 print >> sys.stderr, _("Error unmounting: %s") % self.tmp_path
504 raise EnvironmentError, _("Error unmounting: %s") % self.tmp_path
505 os.rmdir(self.tmp_path)
506 self.tmp_path = ''
508 class LiveUsbImage(BaseUsbImage):
509 def create_image(self, fs_type='RAMFS'):
510 if fs_type == 'EXT3FS':
511 print _("LiveUsbImage: Creating Live R/W USB Image(%s) Now...") % fs_type
512 image_type = _("Live R/W USB Image")
513 else:
514 print _("LiveUsbImage: Creating Live USB Image(%s) Now...") % fs_type
515 image_type = _("Live USB Image (no persistent R/W)")
516 # How big to make the ext3 File System on the Live RW USB image, in megabytes
517 ext3fs_fs_size = int(mic_cfg.config.get(self.section, "ext3fs_size"))
518 self.create_all_initramfs()
519 self.create_rootfs()
520 initrd_stat_result = os.stat('/tmp/.tmp.initrd0')
521 rootfs_stat_result = os.stat(self.rootfs_path)
522 size = ((rootfs_stat_result.st_size + initrd_stat_result.st_size) / (1024 * 1024)) + 64
523 if fs_type == 'EXT3FS':
524 size = size + ext3fs_fs_size
525 self.create_usb_image(size)
526 self.mount_container()
527 self.kernels.insert(0,self.default_kernel)
528 for count, kernel in enumerate(self.kernels):
529 initrd_path = os.path.join(self.tmp_path, "initrd%d.img" % count)
530 shutil.move("/tmp/.tmp.initrd%d" % count, initrd_path)
531 self.kernels.pop(0)
532 # Flashing yellow on a blue background
533 self.install_kernels("9e", image_type)
534 pdk_utils.copy(self.rootfs_path, self.tmp_path, callback = self.progress_callback)
535 if fs_type == 'EXT3FS':
536 self.create_ext3fs_file(os.path.join(self.tmp_path, 'ext3fs.img'), ext3fs_fs_size)
537 self.umount_container()
538 self.delete_rootfs()
539 print _("LiveUsbImage: Finished!")
541 def __str__(self):
542 return ("<LiveUsbImage: project=%s, target=%s, name=%s>"
543 % (self.project, self.target, self.name))
546 class InstallUsbImage(BaseUsbImage):
547 def create_image(self):
548 print _("InstallUsbImage: Creating InstallUSB Image...")
549 image_type = _("Install USB Image. This will DESTROY all content on your hard drive!!")
550 self.create_all_initramfs()
551 self.create_grub_menu()
552 self.apply_hd_kernel_cmdline()
553 self.create_bootfs()
554 self.create_rootfs()
555 initrd_stat_result = os.stat('/tmp/.tmp.initrd0')
556 rootfs_stat_result = os.stat(self.rootfs_path)
557 bootfs_stat_result = os.stat(self.bootfs_path)
558 size = ((rootfs_stat_result.st_size + bootfs_stat_result.st_size + initrd_stat_result.st_size) / (1024 * 1024)) + 64
559 self.create_usb_image(size)
560 self.mount_container()
561 self.kernels.insert(0,self.default_kernel)
562 for count, kernel in enumerate(self.kernels):
563 initrd_path = os.path.join(self.tmp_path, "initrd%d.img" % count)
564 shutil.move("/tmp/.tmp.initrd%d" % count, initrd_path)
565 self.kernels.pop(0)
566 # Flashing yellow on a red background
567 self.install_kernels("ce", image_type)
568 pdk_utils.copy(self.rootfs_path, self.tmp_path, callback = self.progress_callback)
569 pdk_utils.copy(self.bootfs_path, self.tmp_path, callback = self.progress_callback)
570 self.create_install_script(self.tmp_path)
571 self.umount_container()
572 self.delete_rootfs()
573 self.delete_bootfs()
574 print _("InstallUsbImage: Finished!")
575 print _("\nYou can now use the image to boot and install the target file-system on the target device's HDD.\n")
576 print _("\nWARNING: Entire contents of the target devices's HDD will be erased prior to installation!")
577 print _(" This includes ALL partitions on the disk!\n")
578 print _("InstallUsbImage: Finished!")
580 def apply_hd_kernel_cmdline(self):
581 cmd = "sed -e 's:^\\s*kernel\\s*\\([/a-zA-Z0-9._-]*\\).*:kernel \\t\\t\\1 %s:g' -i %s" % (self.project.get_target_hd_kernel_cmdline(self.target.name), os.path.join(self.target.fs_path, 'boot', 'grub', 'menu.lst'))
582 print cmd
583 print os.popen(cmd).readlines()
584 print _("grub.conf kernel cmdline changed")
586 def __str__(self):
587 return ("<InstallUsbImage: project=%s, target=%s, name=%s>"
588 % (self.project, self.target, self.name))
591 class HddImage(InstallImage):
592 def create_image(self):
593 raise ValueError(_("HddImage: Create Hard Disk Image not implemented!"))
595 def __str__(self):
596 return ("<HddImage: project=%s, target=%s, name=%s>"
597 % (self.project, self.target, self.name))
599 def print_exc_plus():
600 # From Python Cookbook 2nd Edition. FIXME: Will need to remove this at
601 # some point, or give attribution.
602 """ Print the usual traceback information, followed by a listing of
603 all the local variables in each frame.
605 tb = sys.exc_info()[2]
606 while tb.tb_next:
607 tb = tb.tb_next
608 stack = []
609 f = tb.tb_frame
610 while f:
611 stack.append(f)
612 f = f.f_back
613 stack.reverse()
614 traceback.print_exc()
615 print _("Locals by frame, innermost last")
616 for frame in stack:
617 print
618 print _("Frame %s in %s at line %s") % (frame.f_code.co_name,
619 frame.f_code.co_filename,
620 frame.f_lineno)
621 for key, value in frame.f_locals.items():
622 print "\t%20s = " % key,
623 # we must _absolutely_ avoid propagating exceptions, and str(value)
624 # COULD cause any exception, so we MUST catch any...:
625 try:
626 print value
627 except:
628 print _("<ERROR WHILE PRINTING VALUE>")
629 traceback.print_exc()
631 class Callback:
632 def iteration(self, process):
633 return
635 if __name__ == '__main__':
636 cnt = len(sys.argv)
637 if (cnt != 4) and (cnt != 2):
638 print >> sys.stderr, _("USAGE: %s proj_path proj_name platform_name") % (sys.argv[0])
639 print >> sys.stderr, _(" %s proj_name") % (sys.argv[0])
640 sys.exit(1)
642 sdk = SDK.SDK(Callback())
644 if cnt == 4:
645 proj_path = sys.argv[1]
646 proj_name = sys.argv[2]
647 platform_name = sys.argv[3]
649 proj = sdk.create_project(proj_path, proj_name, 'test project', sdk.platforms[platform_name])
650 proj.install()
652 target = proj.create_target('mytest')
653 target.installFset(sdk.platforms[platform_name].fset['Core'])
655 else:
656 proj_name = sys.argv[1]
657 proj = sdk.projects[proj_name]
659 proj.mount()
661 imgLiveUsb = LiveUsbImage(proj, proj.targets['mytest'], "mytest_v3-Live-USB.bin")
662 print _("\nImage File Name: %s") % imgLiveUsb.name
663 imgLiveUsb.create_image()
665 imgInstallUsb = InstallUsbImage(proj, proj.targets['mytest'], "mytest_v4-Install-USB.bin")
666 print _("\nImage File Name: %s") % imgInstallUsb.name
667 imgInstallUsb.create_image()
669 imgHdd = HddImage(proj, proj.targets['mytest'], "mytest_v5-HDD.tar.bz2")
670 print _("\nImage File Name: %s") % imgHdd.name
671 imgHdd.create_image()
673 print _("\n\nFinish!\n")