def do_multiboot_bootloader(self): install_devices = [d.name for d in self.driver.partition_scheme.parteds if d.install_bootloader] mount_dir = '/tmp/target' with self._mount_bootloader(mount_dir) as uuid: gu.grub2_install(install_devices, boot_root=mount_dir) self._generate_boot_info(mount_dir, uuid)
def test_grub2_install(self, mock_guess_grub, mock_exec): mock_guess_grub.return_value = '/sbin/grub' expected_calls = [ mock.call('chroot', '/target', '/sbin/grub', '/dev/foo', run_as_root=True, check_exit_code=[0]), mock.call('chroot', '/target', '/sbin/grub', '/dev/bar', run_as_root=True, check_exit_code=[0]) ] gu.grub2_install(['/dev/foo', '/dev/bar'], chroot='/target') self.assertEqual(mock_exec.call_args_list, expected_calls)
def _do_bootloader_grub2(self, grub, chroot, install_devices, lvm_boot=False): try: gu.grub2_cfg(kernel_params=grub.kernel_params, chroot=chroot, grub_timeout=CONF.grub_timeout, lvm_boot=lvm_boot) gu.grub2_install(install_devices, chroot=chroot, lvm_boot=lvm_boot) except errors.ProcessExecutionError as ex: LOG.warning('Tenant grub2 install failed. Error: {}'.format(ex)) LOG.warning('Trying to install using bundled grub2') self._do_bootloader_grub2_bundled(grub, chroot, install_devices, lvm_boot=lvm_boot)
def do_bootloader(self): LOG.debug('--- Installing bootloader (do_bootloader) ---') chroot = '/tmp/target' partition_scheme = self.driver.partition_scheme with self.mount_target(chroot): mount2uuid = {} for fs in partition_scheme.fss: mount2uuid[fs.mount] = utils.execute( 'blkid', '-c', '/dev/null', '-o', 'value', '-s', 'UUID', fs.device, check_exit_code=[0])[0].strip() if '/' not in mount2uuid: raise errors.WrongPartitionSchemeError( 'Error: device with / mountpoint has not been found') self._override_lvm_config(chroot) grub = self.driver.grub guessed_version = gu.guess_grub_version(chroot=chroot) if guessed_version != grub.version: grub.version = guessed_version LOG.warning('Grub version differs from which the operating ' 'system should have by default. Found version in ' 'image: %s', guessed_version) boot_device = partition_scheme.boot_device(grub.version) install_devices = [d.name for d in partition_scheme.parteds if d.install_bootloader] grub.append_kernel_params('root=UUID=%s ' % mount2uuid['/']) kernel = grub.kernel_name or \ gu.guess_kernel(chroot=chroot, regexp=grub.kernel_regexp) initrd = grub.initrd_name or \ gu.guess_initrd(chroot=chroot, regexp=grub.initrd_regexp) if grub.version == 1: gu.grub1_cfg(kernel=kernel, initrd=initrd, kernel_params=grub.kernel_params, chroot=chroot, grub_timeout=CONF.timeout) gu.grub1_install(install_devices, boot_device, chroot=chroot) else: # TODO(kozhukalov): implement which kernel to use by default # Currently only grub1_cfg accepts kernel and initrd # parameters. gu.grub2_cfg(kernel_params=grub.kernel_params, chroot=chroot, grub_timeout=CONF.timeout) gu.grub2_install(install_devices, chroot=chroot) # TODO(agordeev): move to separate actions? if CONF.fix_udev_net_rules: # FIXME(agordeev) There's no convenient way to perfrom NIC # remapping in Ubuntu, so injecting files prior the first boot # should work with open(chroot + '/etc/udev/rules.d/70-persistent-net.rules', 'wt', encoding='utf-8') as f: f.write(u'# Generated by bareon during provisioning: ' u'BEGIN\n') # pattern is aa:bb:cc:dd:ee:ff_eth0,aa:bb:cc:dd:ee:ff_eth1 for mapping in self.driver.configdrive_scheme. \ common.udevrules.split(','): mac_addr, nic_name = mapping.split('_') f.write(u'SUBSYSTEM=="net", ACTION=="add", ' u'DRIVERS=="?*", ATTR{address}=="%s", ' u'ATTR{type}=="1", KERNEL=="eth*", ' u'NAME="%s"\n' % (mac_addr, nic_name)) f.write( u'# Generated by bareon during provisioning: END\n') # FIXME(agordeev): Disable net-generator that adds new entries # to 70-persistent-net.rules with open(chroot + '/etc/udev/rules.d/' '75-persistent-net-generator.rules', 'wt', encoding='utf-8') as f: f.write(u'# Generated by bareon during provisioning:\n' u'# DO NOT DELETE. It is needed to disable ' u'net-generator\n') # FIXME(kozhukalov): Prevent nailgun-agent from doing anything. # This ugly hack is to be used together with the command removing # this lock file not earlier than /etc/rc.local # The reason for this hack to appear is to prevent nailgun-agent # from changing mcollective config at the same time when cloud-init # does the same. Otherwise, we can end up with corrupted # mcollective config. # For details see https://bugs.launchpad.net/fuel/+bug/1449186 LOG.debug('Preventing nailgun-agent from doing ' 'anything until it is unlocked') utils.makedirs_if_not_exists(os.path.join(chroot, 'etc/nailgun-agent')) with open(os.path.join(chroot, 'etc/nailgun-agent/nodiscover'), 'w'): pass with open(chroot + '/etc/fstab', 'wt', encoding='utf-8') as f: for fs in self.driver.partition_scheme.fss: # TODO(kozhukalov): Think of improving the logic so as to # insert a meaningful fsck order value which is last zero # at fstab line. Currently we set it into 0 which means # a corresponding file system will never be checked. We # assume puppet or other configuration tool will care of # it. if fs.mount == '/': f.write(u'UUID=%s %s %s defaults,errors=panic 0 0\n' % (mount2uuid[fs.mount], fs.mount, fs.type)) else: f.write(u'UUID=%s %s %s defaults 0 0\n' % (mount2uuid[fs.mount], fs.mount, fs.type))
def _do_bootloader_grub2_bundled(self, grub, chroot, install_devices, lvm_boot=False): gu.grub2_install(install_devices, boot_root=chroot, lvm_boot=lvm_boot) gu.grub2_cfg_bundled(kernel_params=grub.kernel_params, chroot=chroot, grub_timeout=CONF.grub_timeout, lvm_boot=lvm_boot)
def do_bootloader(self): LOG.debug('--- Installing bootloader (do_bootloader) ---') chroot = '/tmp/target' partition_scheme = self.driver.partition_scheme with self.mount_target(chroot): mount2uuid = {} for fs in partition_scheme.fss: mount2uuid[fs.mount] = utils.execute( 'blkid', '-o', 'value', '-s', 'UUID', fs.device, check_exit_code=[0])[0].strip() if '/' not in mount2uuid: raise errors.WrongPartitionSchemeError( 'Error: device with / mountpoint has not been found') grub = self.driver.grub guessed_version = gu.guess_grub_version(chroot=chroot) if guessed_version != grub.version: grub.version = guessed_version LOG.warning('Grub version differs from which the operating ' 'system should have by default. Found version in ' 'image: %s', guessed_version) boot_device = partition_scheme.boot_device(grub.version) install_devices = [d.name for d in partition_scheme.parteds if d.install_bootloader] grub.append_kernel_params('root=UUID=%s ' % mount2uuid['/']) kernel = grub.kernel_name or \ gu.guess_kernel(chroot=chroot, regexp=grub.kernel_regexp) initrd = grub.initrd_name or \ gu.guess_initrd(chroot=chroot, regexp=grub.initrd_regexp) if grub.version == 1: gu.grub1_cfg(kernel=kernel, initrd=initrd, kernel_params=grub.kernel_params, chroot=chroot, grub_timeout=CONF.timeout) gu.grub1_install(install_devices, boot_device, chroot=chroot) else: # TODO(kozhukalov): implement which kernel to use by default # Currently only grub1_cfg accepts kernel and initrd # parameters. gu.grub2_cfg(kernel_params=grub.kernel_params, chroot=chroot, grub_timeout=CONF.timeout) gu.grub2_install(install_devices, chroot=chroot) # TODO(agordeev): move to separate actions? if CONF.fix_udev_net_rules: # FIXME(agordeev) There's no convenient way to perfrom NIC # remapping in Ubuntu, so injecting files prior the first boot # should work with open(chroot + '/etc/udev/rules.d/70-persistent-net.rules', 'wt', encoding='utf-8') as f: f.write(u'# Generated by bareon during provisioning: ' u'BEGIN\n') # pattern is aa:bb:cc:dd:ee:ff_eth0,aa:bb:cc:dd:ee:ff_eth1 for mapping in self.driver.configdrive_scheme. \ common.udevrules.split(','): mac_addr, nic_name = mapping.split('_') f.write(u'SUBSYSTEM=="net", ACTION=="add", ' u'DRIVERS=="?*", ATTR{address}=="%s", ' u'ATTR{type}=="1", KERNEL=="eth*", ' u'NAME="%s"\n' % (mac_addr, nic_name)) f.write( u'# Generated by bareon during provisioning: END\n') # FIXME(agordeev): Disable net-generator that adds new entries # to 70-persistent-net.rules with open(chroot + '/etc/udev/rules.d/' '75-persistent-net-generator.rules', 'wt', encoding='utf-8') as f: f.write(u'# Generated by bareon during provisioning:\n' u'# DO NOT DELETE. It is needed to disable ' u'net-generator\n') # FIXME(kozhukalov): Prevent nailgun-agent from doing anything. # This ugly hack is to be used together with the command removing # this lock file not earlier than /etc/rc.local # The reason for this hack to appear is to prevent nailgun-agent # from changing mcollective config at the same time when cloud-init # does the same. Otherwise, we can end up with corrupted # mcollective config. # For details see https://bugs.launchpad.net/fuel/+bug/1449186 LOG.debug('Preventing nailgun-agent from doing ' 'anything until it is unlocked') utils.makedirs_if_not_exists(os.path.join(chroot, 'etc/nailgun-agent')) with open(os.path.join(chroot, 'etc/nailgun-agent/nodiscover'), 'w'): pass # FIXME(kozhukalov): When we have just os-root fs image and don't # have os-var-log fs image while / and /var/log are supposed to be # separate file systems and os-var-log is mounted into # non-empty directory on the / file system, those files in /var/log # directory become unavailable. # The thing is that among those file there is /var/log/upstart # where upstart daemon writes its logs. We have specific upstart # job which is to flush open files once all file systems are # mounted. # This job needs upstart directory to be available on os-var-log # file system. # This is just a temporary fix and correct fix will be available # soon via updates. utils.execute('mkdir', '-p', chroot + '/var/log/upstart') with open(chroot + '/etc/fstab', 'wt', encoding='utf-8') as f: for fs in self.driver.partition_scheme.fss: # TODO(kozhukalov): Think of improving the logic so as to # insert a meaningful fsck order value which is last zero # at fstab line. Currently we set it into 0 which means # a corresponding file system will never be checked. We # assume puppet or other configuration tool will care of # it. if fs.mount == '/': f.write(u'UUID=%s %s %s defaults,errors=panic 0 0\n' % (mount2uuid[fs.mount], fs.mount, fs.type)) else: f.write(u'UUID=%s %s %s defaults 0 0\n' % (mount2uuid[fs.mount], fs.mount, fs.type))