~ubuntu-branches/ubuntu/oneiric/dell-recovery/oneiric-proposed

« back to all changes in this revision

Viewing changes to ubiquity/dell-bootstrap.py

  • Committer: Package Import Robot
  • Author(s): Mario Limonciello
  • Date: 2011-09-08 17:55:42 UTC
  • Revision ID: package-import@ubuntu.com-20110908175542-jy7hy4x9l48et3bi
Tags: 1.03
* Move all the "code" from dell-recovery-bootloader to it's own script
  so that it can be invoked from other places too.
* Store all GRUB configs in /factory from now.  Don't use /boot/grub
  as that's where the on disk bootloaders will land for EFI as well
  as later MBR installs.
* Don't use grub-install at all.  Always build bootloader binaries
  ourselves that rely items in /factory.
* Set up the FAIL and SUCCESS scripts to work out of /factory for grubenv.
* Reinstall GRUB to the MBR on fail if fist isn't around and not EFI.
* Add missing RP declaration in FAIL-SCRIPT.
* Lookup the recovery partition on demand during oem-config early
  command in case the devices were different during install.
* Depending on when FAIL_COMMAND happened, we might have mountpoints.
  Clean them up.
* Delay the write of the new MBR until the last step in the set active
  partition command.

Show diffs side-by-side

added added

removed removed

Lines of Context:
782
782
            location = ISO_MOUNT
783
783
        else:
784
784
            location = CDROM_MOUNT
785
 
        early = '/usr/share/dell/scripts/oem_config.sh early %s %s' % (rec_part['device'], location)
 
785
        early = '/usr/share/dell/scripts/oem_config.sh early %s' % location
786
786
        self.db.set('oem-config/early_command', early)
787
787
        self.db.set('partman-auto/disk', self.device)
788
788
 
1449
1449
                os.makedirs(os.path.join('/mnt', 'preseed'))
1450
1450
            magic.write_seed(seed, keys)
1451
1451
 
1452
 
        #files and grub go in /mnt/efi if we're EFI and include EFI specifics
1453
 
        #Check for a grub.cfg - replace as necessary
1454
 
        if self.efi:
1455
 
            pivot = '/mnt/efi'
1456
 
            if not os.path.exists(pivot):
1457
 
                with misc.raised_privileges():
1458
 
                    os.makedirs(pivot)
1459
 
            mount = misc.execute_root('mount', self.device + EFI_ESP_PARTITION, pivot)
1460
 
            if mount is False:
1461
 
                raise RuntimeError, ("Error mounting %s%s" % (self.device, EFI_ESP_PARTITION))
1462
 
        else:
1463
 
            pivot = '/mnt'
1464
 
 
1465
1452
        #Check for a grub.cfg - replace as necessary
1466
1453
        files = {'recovery_partition.cfg': 'grub.cfg',
1467
1454
                 'common.cfg' : 'common.cfg'} 
1468
1455
        for item in files:
1469
 
            if os.path.exists(os.path.join(pivot, 'boot', 'grub', files[item])):
 
1456
            full_path = os.path.join('/mnt', 'factory', files[item])
 
1457
            if os.path.exists(full_path):
1470
1458
                with misc.raised_privileges():
1471
 
                    shutil.move(os.path.join(pivot, 'boot', 'grub', files[item]),
1472
 
                                os.path.join(pivot, 'boot', 'grub', files[item]) + '.old')
 
1459
                    shutil.move(full_path, full_path + '.old')
1473
1460
 
1474
1461
            with misc.raised_privileges():
1475
 
                
1476
1462
                magic.process_conf_file('/usr/share/dell/grub/' + item, \
1477
 
                                   os.path.join(pivot, 'boot', 'grub', files[item]),\
1478
 
                                   uuid, rp_part)
 
1463
                                        full_path, uuid, rp_part)
1479
1464
                #Allow these to be invoked from a recovery solution launched by the BCD.
1480
1465
                if self.dual:
1481
 
                    shutil.copy(os.path.join(pivot, 'boot', 'grub', files[item]), \
1482
 
                                os.path.join('/tmp', files[item]))
 
1466
                    shutil.copy(full_path, os.path.join('/tmp', files[item]))
 
1467
 
 
1468
        #If we don't have grub binaries, build them
 
1469
        if self.efi:
 
1470
            grub_files = [ '/mnt/factory/grubx64.efi']
 
1471
        else:
 
1472
            grub_files = [ '/mnt/factory/core.img',
 
1473
                           '/mnt/factory/boot.img']
 
1474
        for item in grub_files:
 
1475
            if not os.path.exists(item):
 
1476
                build = misc.execute_root('/usr/share/dell/grub/build-binaries.sh')
 
1477
                if build is False:
 
1478
                    raise RuntimeError, ("Error building grub binaries.")
 
1479
                with misc.raised_privileges():
 
1480
                    magic.white_tree("copy", re.compile('.'), '/var/lib/dell-recovery', '/mnt/factory')
 
1481
                break
1483
1482
 
1484
1483
        #Install grub
1485
1484
        self.status("Installing GRUB", 88)
1486
1485
        if self.efi:
1487
 
            #if we have a pre-built EFI binary, use that.
1488
 
            if os.path.exists('/cdrom/factory/grubx64.efi') and \
1489
 
               os.path.exists('/cdrom/factory/grub.cfg'):
1490
 
                direct_path = pivot + '/efi/ubuntu'
 
1486
            #Mount ESP
 
1487
            if not os.path.exists('/mnt/efi'):
1491
1488
                with misc.raised_privileges():
1492
 
                    os.makedirs(direct_path)
1493
 
                    #copy our pre-built loader
1494
 
                    shutil.copy('/cdrom/factory/grubx64.efi', direct_path)
1495
 
                    #find old entries
1496
 
                    bootmgr_output = magic.fetch_output(['efibootmgr']).split('\n')
1497
 
                #delete old entries
1498
 
                for line in bootmgr_output:
1499
 
                    if line.startswith('Boot') and 'ubuntu' in line:
1500
 
                        bootnum = line.split('Boot')[1].replace('*', '').split()[0]
1501
 
                        bootmgr = misc.execute_root('efibootmgr', '-q', '-b', bootnum, '-B')
1502
 
                        if bootmgr is False:
1503
 
                            raise RuntimeError, ("Error removing old EFI boot manager entries")
1504
 
                bootmgr = misc.execute_root('efibootmgr', '-q', '-c', '-d',
1505
 
                                            self.device, '-p', EFI_ESP_PARTITION, '-w',
1506
 
                                            '-L', 'ubuntu', '-l', '\\EFI\ubuntu\\grubx64.efi')
1507
 
                if bootmgr is False:
1508
 
                    raise RuntimeError, ("Error creating EFI boot manager entry.")
1509
 
            #otherwise build one and install it
1510
 
            else:
1511
 
                grub = misc.execute_root('grub-install', '--root-directory=%s' % pivot)
1512
 
                if grub is False:
1513
 
                    raise RuntimeError, ("Error installing grub to ESP")
1514
 
            misc.execute_root('umount', pivot)
 
1489
                    os.makedirs('/mnt/efi')
 
1490
            mount = misc.execute_root('mount', self.device + EFI_ESP_PARTITION, '/mnt/efi')
 
1491
            if mount is False:
 
1492
                raise RuntimeError, ("Error mounting %s%s" % (self.device, EFI_ESP_PARTITION))
 
1493
 
 
1494
            #find old entries and prep directory
 
1495
            direct_path = '/mnt/efi' + '/efi/ubuntu'
 
1496
            with misc.raised_privileges():
 
1497
                os.makedirs(direct_path)
 
1498
                #copy our pre-built loader
 
1499
                shutil.copy('/mnt/factory/grubx64.efi', direct_path)
 
1500
                #find old entries
 
1501
                bootmgr_output = magic.fetch_output(['efibootmgr']).split('\n')
 
1502
 
 
1503
            #delete old entries
 
1504
            for line in bootmgr_output:
 
1505
                if line.startswith('Boot') and 'ubuntu' in line:
 
1506
                    bootnum = line.split('Boot')[1].replace('*', '').split()[0]
 
1507
                    bootmgr = misc.execute_root('efibootmgr', '-q', '-b', bootnum, '-B')
 
1508
                    if bootmgr is False:
 
1509
                        raise RuntimeError, ("Error removing old EFI boot manager entries")
 
1510
            #create new boot entry
 
1511
            bootmgr = misc.execute_root('efibootmgr', '-q', '-c', '-d',
 
1512
                                        self.device, '-p', EFI_ESP_PARTITION, '-w',
 
1513
                                        '-L', 'ubuntu', '-l', '\\EFI\ubuntu\\grubx64.efi')
 
1514
            if bootmgr is False:
 
1515
                raise RuntimeError, ("Error creating EFI boot manager entry.")
 
1516
 
 
1517
            #clean up ESP mount
 
1518
            misc.execute_root('umount', '/mnt/efi')
1515
1519
        else:
1516
 
            #allow red screening after MBR is replaced
1517
 
            grub = misc.execute_root('grub-install', '--root-directory=%s' % pivot, '--force', self.device + grub_part)
 
1520
            grub = misc.execute_root('grub-setup', '-d', '/mnt/factory', self.device)
1518
1521
            if grub is False:
1519
 
                raise RuntimeError, ("Error installing grub to %s%s" % (self.device, grub_part))
1520
 
 
1521
 
            #emulate factory process.  place pre-built GRUB in the MBR
1522
 
            if os.path.exists('%s/factory/core.img' % pivot) and \
1523
 
               os.path.exists('%s/factory/boot.img' % pivot) and \
1524
 
               os.path.exists('%s/factory/grub.cfg' % pivot):
1525
 
                grub = misc.execute_root('grub-setup', '-d', '%s/factory' % pivot, self.device)
1526
 
                if grub is False:
1527
 
                    raise RuntimeError, ("Error installing grub to %s" % (self.device))
1528
 
 
 
1522
                raise RuntimeError, ("Error installing grub to %s" % (self.device))
1529
1523
 
1530
1524
        #dual boot needs primary #4 unmounted
1531
1525
        if self.dual:
1533
1527
            self.status("Building G2LDR", 90)
1534
1528
            #build g2ldr
1535
1529
            magic.create_g2ldr('/', '/mnt', '')
1536
 
            if not os.path.isdir(os.path.join('/mnt', 'boot', 'grub')):
1537
 
                os.makedirs(os.path.join('/mnt', 'boot', 'grub'))
 
1530
            if not os.path.isdir(os.path.join('/mnt', 'factory')):
 
1531
                os.makedirs(os.path.join('/mnt', 'factory'))
1538
1532
            for item in files:
1539
1533
                shutil.copy(os.path.join('/tmp', files[item]), \
1540
 
                            os.path.join('/mnt', 'boot', 'grub', files[item]))
 
1534
                            os.path.join('/mnt', 'factory', files[item]))
1541
1535
 
1542
1536
 
1543
1537
        #Build new UUID
1821
1815
 
1822
1816
        if active.isdigit():
1823
1817
            disk = progress.get('partman-auto/disk')
1824
 
            with open('/tmp/set_active_partition', 'w') as wfd:
 
1818
            with open('/tmp/set_bootable', 'w') as wfd:
1825
1819
                #If we have an MBR, 
1826
1820
                if layout == 'msdos':
1827
1821
                    #we use the active partition bit in it
1830
1824
                    #in factory process if we backed up an MBR, that would have already
1831
1825
                    #been restored.
1832
1826
                    if not os.path.exists(os.path.join(CDROM_MOUNT, 'factory', 'mbr.bin')):
1833
 
                        #we don't necessarily know how we booted
1834
1827
                        #test the md5 of the MBR to match DRMK or syslinux
1835
1828
                        #if they don't match, rewrite MBR
1836
1829
                        with misc.raised_privileges():
1839
1832
                        path = '/usr/share/dell/up/mbr.bin'
1840
1833
                        if not os.path.exists(path):
1841
1834
                            path = '/usr/lib/syslinux/mbr.bin'
1842
 
                        if not os.path.exists(path):
1843
 
                            raise RuntimeError, ("Missing DRMK and syslinux MBR")
1844
1835
                        with open(path, 'rb') as rfd:
1845
 
                            file_mbr = rfd.read(440)
 
1836
                            file_mbr = rfd.read(440)        
1846
1837
                        if hashlib.md5(file_mbr).hexdigest() != hashlib.md5(disk_mbr).hexdigest():
1847
 
                            self.debug("%s: MBR of disk is invalid, rewriting" % NAME)
1848
 
                            with misc.raised_privileges():
1849
 
                                with open(disk, 'wb') as wfd:
1850
 
                                    wfd.write(file_mbr)
 
1838
                            if not os.path.exists(path):
 
1839
                                raise RuntimeError, ("Missing DRMK and syslinux MBR")
 
1840
                            wfd.write('dd if=%s of=%s bs=440 count=1\n' % (path, disk))
1851
1841
 
1852
1842
                #If we have GPT, we need to go down other paths
1853
1843
                elif layout == 'gpt':
1864
1854
                            raise RuntimeError, ("Error working around bug 592813.")
1865
1855
                        
1866
1856
                        wfd.write('grub-install --no-floppy %s\n' % disk)
1867
 
            os.chmod('/tmp/set_active_partition', 0755)
 
1857
            os.chmod('/tmp/set_bootable', 0755)
1868
1858
 
1869
1859
        #if we are loop mounted, make sure the chroot knows it too
1870
1860
        if os.path.isdir(ISO_MOUNT):