def test_guess_grub_version_2(self, mock_exec, mock_ggi): mock_ggi.return_value = '/grub_install' mock_exec.return_value = ('foo bar', '') version = gu.guess_grub_version('/target') cmd = 'chroot /target /grub_install --version'.split() mock_exec.assert_called_once_with(*cmd) self.assertEqual(version, 2)
def do_singleboot_bootloader(self, chroot, os_id): grub = self.driver.grub try: guessed_version = gu.guess_grub_version(chroot=chroot) except errors.GrubUtilsError as ex: LOG.warning('Grub detection failed. Error: {}'.format(ex)) guessed_version = -1 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: ' '{0}'.format(guessed_version)) if grub.version == 1 and self.driver.is_multiboot: LOG.warning('Grub1 is being used in a multiboot deployment, ' 'thus it is not guaranteed that image name "{}" will ' 'be discovered by os-prober and appear in the common ' 'grub.cfg'.format(os_id)) install_devices = [d.name for d in self.driver.partition_scheme.parteds if d.install_bootloader] if grub.version == 1: mount2uuid = self._mount2uuid(os_id) grub.append_kernel_params('root=UUID=%s ' % mount2uuid['/']) GRUB_INSTALLERS = {1: self._do_bootloader_grub1, 2: self._do_bootloader_grub2, -1: self._do_bootloader_grub2_bundled} GRUB_INSTALLERS[grub.version](grub, chroot, install_devices, self.driver.boot_on_lvm)
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(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))