Пример #1
0
    def test_grub2_cfg(self, mock_def, mock_exec, mock_mkconfig, mock_conf):
        mock_def.return_value = '/etc/default/grub'
        mock_mkconfig.return_value = '/sbin/grub-mkconfig'
        mock_conf.return_value = '/boot/grub/grub.cfg'

        orig_content = """foo
GRUB_CMDLINE_LINUX="kernel-params-orig"
bar"""

        with mock.patch('bareon.utils.grub.open',
                        new=mock.mock_open(read_data=orig_content),
                        create=True) as mock_open:
            mock_open.return_value = mock.MagicMock(spec=io.IOBase)
            handle = mock_open.return_value.__enter__.return_value
            handle.__iter__.return_value = StringIO(orig_content)
            gu.grub2_cfg(kernel_params='kernel-params-new',
                         chroot='/target',
                         grub_timeout=10)

            self.assertEqual(mock_open.call_args_list, [
                mock.call('/target/etc/default/grub'),
                mock.call('/target/etc/default/grub', 'wt', encoding='utf-8')
            ])

        gu.grub2_cfg(kernel_params='kernel-params-new',
                     chroot='/target',
                     grub_timeout=10)

        mock_exec.assert_called_once_with('chroot',
                                          '/target',
                                          '/sbin/grub-mkconfig',
                                          '-o',
                                          '/boot/grub/grub.cfg',
                                          run_as_root=True)
Пример #2
0
    def test_grub2_cfg(self, mock_def, mock_exec, mock_mkconfig, mock_conf):
        mock_def.return_value = '/etc/default/grub'
        mock_mkconfig.return_value = '/sbin/grub-mkconfig'
        mock_conf.return_value = '/boot/grub/grub.cfg'

        orig_content = """foo
GRUB_CMDLINE_LINUX="kernel-params-orig"
bar"""

        with mock.patch('bareon.utils.grub.open',
                        new=mock.mock_open(read_data=orig_content),
                        create=True) as mock_open:
            mock_open.return_value = mock.MagicMock(spec=io.IOBase)
            handle = mock_open.return_value.__enter__.return_value
            handle.__iter__.return_value = StringIO(orig_content)
            gu.grub2_cfg(kernel_params='kernel-params-new', chroot='/target',
                         grub_timeout=10)

            self.assertEqual(
                mock_open.call_args_list,
                [mock.call('/target/etc/default/grub'),
                 mock.call('/target/etc/default/grub', 'wt', encoding='utf-8')]
            )

        gu.grub2_cfg(kernel_params='kernel-params-new', chroot='/target',
                     grub_timeout=10)

        mock_exec.assert_called_once_with('chroot', '/target',
                                          '/sbin/grub-mkconfig',
                                          '-o', '/boot/grub/grub.cfg',
                                          run_as_root=True)
Пример #3
0
 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)
Пример #4
0
    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))
Пример #5
0
    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))