Add bootloader do_action
Partially implements blueprint: pluggable-do-actions Change-Id: I92c8864dc3021b04d0d0f898198007176a1e92fe
This commit is contained in:
parent
981a3e9023
commit
478e4c149d
182
bareon/actions/bootloader.py
Normal file
182
bareon/actions/bootloader.py
Normal file
@ -0,0 +1,182 @@
|
||||
# Copyright 2016 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
from io import open
|
||||
import os
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from bareon.actions import base
|
||||
from bareon.drivers.deploy import mixins
|
||||
from bareon import errors
|
||||
from bareon.openstack.common import log as logging
|
||||
from bareon.utils import grub as gu
|
||||
from bareon.utils import utils
|
||||
|
||||
opts = [
|
||||
cfg.IntOpt(
|
||||
'grub_timeout',
|
||||
default=5,
|
||||
help='Timeout in secs for GRUB'
|
||||
),
|
||||
cfg.BoolOpt(
|
||||
'fix_udev_net_rules',
|
||||
default=True,
|
||||
help='Add udev rules for NIC remapping'
|
||||
),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(opts)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# TODO(agordeev): rename to GrubBootLoaderAction ?
|
||||
class BootLoaderAction(base.BaseAction, mixins.MountableMixin):
|
||||
"""BootLoaderAction
|
||||
|
||||
installs and configures bootloader
|
||||
"""
|
||||
|
||||
def validate(self):
|
||||
# TODO(agordeev): implement validate for bootloader
|
||||
pass
|
||||
|
||||
def execute(self):
|
||||
self.do_bootloader()
|
||||
|
||||
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.grub_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.grub_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))
|
@ -28,7 +28,8 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
class MountableMixin(object):
|
||||
|
||||
def _mount_target(self, mount_dir, os_id, pseudo=True, treat_mtab=True):
|
||||
def _mount_target(self, mount_dir, os_id=None, pseudo=True,
|
||||
treat_mtab=True):
|
||||
LOG.debug('Mounting target file systems: %s', mount_dir)
|
||||
# Here we are going to mount all file systems in partition schema.
|
||||
for fs in self.driver.partition_scheme.fs_sorted_by_depth(os_id):
|
||||
@ -53,10 +54,11 @@ class MountableMixin(object):
|
||||
with open(mtab_path, 'wb') as f:
|
||||
f.write(mtab)
|
||||
|
||||
def _umount_target(self, mount_dir, os_id, pseudo=True):
|
||||
def _umount_target(self, mount_dir, os_id=None, pseudo=True):
|
||||
LOG.debug('Umounting target file systems: %s', mount_dir)
|
||||
if pseudo:
|
||||
for path in ('/proc', '/dev', '/sys'):
|
||||
# umount fusectl (typically mounted at /sys/fs/fuse/connections)
|
||||
for path in ('/proc', '/dev', '/sys/fs/fuse/connections', '/sys'):
|
||||
fu.umount_fs(os.path.join(mount_dir, path.strip(os.sep)),
|
||||
try_lazy_umount=True)
|
||||
for fs in self.driver.partition_scheme.fs_sorted_by_depth(os_id,
|
||||
@ -66,13 +68,14 @@ class MountableMixin(object):
|
||||
fu.umount_fs(os.path.join(mount_dir, fs.mount.strip(os.sep)))
|
||||
|
||||
@contextmanager
|
||||
def mount_target(self, mount_dir, os_id, pseudo=True, treat_mtab=True):
|
||||
self._mount_target(mount_dir, os_id, pseudo=pseudo,
|
||||
def mount_target(self, mount_dir, os_id=None, pseudo=True,
|
||||
treat_mtab=True):
|
||||
self._mount_target(mount_dir, os_id=os_id, pseudo=pseudo,
|
||||
treat_mtab=treat_mtab)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
self._umount_target(mount_dir, os_id, pseudo)
|
||||
self._umount_target(mount_dir, os_id=os_id, pseudo=pseudo)
|
||||
|
||||
@contextmanager
|
||||
def _mount_bootloader(self, mount_dir):
|
||||
|
@ -21,6 +21,7 @@ from oslo_config import cfg
|
||||
import six
|
||||
import yaml
|
||||
|
||||
from bareon.actions import bootloader
|
||||
from bareon.actions import configdrive
|
||||
from bareon.actions import copyimage
|
||||
from bareon.actions import partitioning
|
||||
@ -29,7 +30,6 @@ from bareon import errors
|
||||
from bareon.openstack.common import log as logging
|
||||
from bareon.utils import build as bu
|
||||
from bareon.utils import fs as fu
|
||||
from bareon.utils import grub as gu
|
||||
from bareon.utils import utils
|
||||
|
||||
opts = [
|
||||
@ -132,6 +132,9 @@ class Manager(BaseDeployDriver):
|
||||
def do_copyimage(self):
|
||||
copyimage.CopyImageAction(self.driver).execute()
|
||||
|
||||
def do_bootloader(self):
|
||||
bootloader.BootLoaderAction(self.driver).execute()
|
||||
|
||||
@staticmethod
|
||||
def _update_metadata_with_repos(metadata, repos):
|
||||
"""Update action metadata with information about repositories
|
||||
@ -394,123 +397,6 @@ class Manager(BaseDeployDriver):
|
||||
with open(meta_file, 'wt') as f:
|
||||
yaml.safe_dump(drop_data, stream=f, encoding='utf-8')
|
||||
|
||||
def do_bootloader(self):
|
||||
LOG.debug('--- Installing bootloader (do_bootloader) ---')
|
||||
chroot = '/tmp/target'
|
||||
self.mount_target(chroot)
|
||||
|
||||
mount2uuid = {}
|
||||
for fs in self.driver.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: '
|
||||
'{0}'.format(guessed_version))
|
||||
boot_device = self.driver.partition_scheme.boot_device(grub.version)
|
||||
install_devices = [d.name for d in self.driver.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.grub_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.grub_timeout)
|
||||
gu.grub2_install(install_devices, chroot=chroot)
|
||||
|
||||
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", DRIVERS=="?*", '
|
||||
u'ATTR{address}=="%s", ATTR{type}=="1", '
|
||||
u'KERNEL=="eth*", NAME="%s"\n' % (mac_addr,
|
||||
nic_name))
|
||||
f.write(
|
||||
u'# Generated by bareon during provisioning: END\n')
|
||||
# FIXME(agordeev): Disable net-generator that will add new etries
|
||||
# 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))
|
||||
|
||||
self.umount_target(chroot)
|
||||
|
||||
def do_reboot(self):
|
||||
LOG.debug('--- Rebooting node (do_reboot) ---')
|
||||
utils.execute('reboot')
|
||||
|
253
bareon/tests/test_do_bootloader.py
Normal file
253
bareon/tests/test_do_bootloader.py
Normal file
@ -0,0 +1,253 @@
|
||||
# Copyright 2016 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import six
|
||||
import unittest2
|
||||
|
||||
from bareon.actions import bootloader
|
||||
from bareon.drivers.data import nailgun
|
||||
from bareon import errors
|
||||
from bareon import objects
|
||||
|
||||
if six.PY2:
|
||||
import mock
|
||||
elif six.PY3:
|
||||
import unittest.mock as mock
|
||||
|
||||
|
||||
class TestBootLoaderAction(unittest2.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBootLoaderAction, self).setUp()
|
||||
self.drv = mock.MagicMock(spec=nailgun.Nailgun)
|
||||
self.action = bootloader.BootLoaderAction(self.drv)
|
||||
self.action._mount_target = mock.Mock()
|
||||
self.action._umount_target = mock.Mock()
|
||||
self.drv.grub = objects.Grub(
|
||||
kernel_params=' console=ttyS0,9600 console=tty0 '
|
||||
'rootdelay=90 nomodeset')
|
||||
root_fs = objects.FS('/dev/sda', mount='/')
|
||||
self.drv.partition_scheme.fss = [root_fs]
|
||||
self.drv.partition_scheme.boot_device.return_value = '/dev/sda3'
|
||||
parteds = [objects.Parted('/dev/sd%s' % x, 'gpt',
|
||||
install_bootloader=True)
|
||||
for x in ['a', 'b', 'c']]
|
||||
self.drv.partition_scheme.parteds = parteds
|
||||
|
||||
@mock.patch.object(bootloader, 'open', create=True,
|
||||
new_callable=mock.mock_open)
|
||||
@mock.patch.object(bootloader, 'gu', autospec=True)
|
||||
@mock.patch.object(bootloader, 'utils', autospec=True)
|
||||
def test_do_bootloader_grub1_kernel_initrd_guessed(self, mock_utils,
|
||||
mock_gu, mock_open):
|
||||
mock_utils.execute.return_value = ('fake_root_uuid', '')
|
||||
mock_gu.guess_grub_version.return_value = 1
|
||||
# grub has kernel_name and initrd_name both set to None
|
||||
self.drv.grub.kernel_name = None
|
||||
self.drv.grub.initrd_name = None
|
||||
self.drv.grub.kernel_params = 'fake_kernel_params'
|
||||
self.drv.grub.kernel_regexp = 'fake_kernel_regexp'
|
||||
self.drv.grub.initrd_regexp = 'fake_initrd_regexp'
|
||||
mock_gu.guess_kernel.return_value = 'guessed_kernel'
|
||||
mock_gu.guess_initrd.return_value = 'guessed_initrd'
|
||||
self.action.execute()
|
||||
self.assertFalse(mock_gu.grub2_cfg.called)
|
||||
self.assertFalse(mock_gu.grub2_install.called)
|
||||
mock_gu.grub1_cfg.assert_called_once_with(
|
||||
kernel_params='fake_kernel_params root=UUID=fake_root_uuid ',
|
||||
initrd='guessed_initrd', kernel='guessed_kernel',
|
||||
chroot='/tmp/target', grub_timeout=5)
|
||||
mock_gu.grub1_install.assert_called_once_with(
|
||||
['/dev/sda', '/dev/sdb', '/dev/sdc'],
|
||||
'/dev/sda3', chroot='/tmp/target')
|
||||
mock_gu.guess_initrd.assert_called_once_with(
|
||||
regexp='fake_initrd_regexp', chroot='/tmp/target')
|
||||
mock_gu.guess_kernel.assert_called_once_with(
|
||||
regexp='fake_kernel_regexp', chroot='/tmp/target')
|
||||
|
||||
@mock.patch.object(bootloader, 'open', create=True,
|
||||
new_callable=mock.mock_open)
|
||||
@mock.patch.object(bootloader, 'gu', autospec=True)
|
||||
@mock.patch.object(bootloader, 'utils', autospec=True)
|
||||
def test_do_bootloader_grub1_kernel_initrd_set(self, mock_utils,
|
||||
mock_gu, mock_open):
|
||||
mock_utils.execute.return_value = ('', '')
|
||||
mock_gu.guess_grub_version.return_value = 1
|
||||
self.drv.grub.kernel_params = 'fake_kernel_params'
|
||||
# grub has kernel_name and initrd_name set
|
||||
self.drv.grub.kernel_name = 'kernel_name'
|
||||
self.drv.grub.initrd_name = 'initrd_name'
|
||||
self.action.execute()
|
||||
self.assertFalse(mock_gu.grub2_cfg.called)
|
||||
self.assertFalse(mock_gu.grub2_install.called)
|
||||
mock_gu.grub1_cfg.assert_called_once_with(
|
||||
kernel_params='fake_kernel_params root=UUID= ',
|
||||
initrd='initrd_name', kernel='kernel_name', chroot='/tmp/target',
|
||||
grub_timeout=5)
|
||||
mock_gu.grub1_install.assert_called_once_with(
|
||||
['/dev/sda', '/dev/sdb', '/dev/sdc'],
|
||||
'/dev/sda3', chroot='/tmp/target')
|
||||
self.assertFalse(mock_gu.guess_initrd.called)
|
||||
self.assertFalse(mock_gu.guess_kernel.called)
|
||||
|
||||
@mock.patch.object(objects, 'Grub', autospec=True)
|
||||
@mock.patch.object(bootloader, 'open', create=True,
|
||||
new_callable=mock.mock_open)
|
||||
@mock.patch.object(bootloader, 'gu', autospec=True)
|
||||
@mock.patch.object(bootloader, 'utils', autospec=True)
|
||||
def test_do_bootloader_rootfs_uuid(self, mock_utils, mock_gu, mock_open,
|
||||
mock_grub):
|
||||
def _fake_uuid(*args, **kwargs):
|
||||
if len(args) >= 6 and args[5] == '/dev/sda':
|
||||
return ('FAKE_ROOTFS_UUID', None)
|
||||
else:
|
||||
return ('FAKE_UUID', None)
|
||||
mock_utils.execute.side_effect = _fake_uuid
|
||||
mock_grub.version = 2
|
||||
mock_gu.guess_grub_version.return_value = 2
|
||||
mock_grub.kernel_name = 'fake_kernel_name'
|
||||
mock_grub.initrd_name = 'fake_initrd_name'
|
||||
mock_grub.kernel_params = 'fake_kernel_params'
|
||||
self.drv.grub = mock_grub
|
||||
self.action.execute()
|
||||
mock_grub.append_kernel_params.assert_called_once_with(
|
||||
'root=UUID=FAKE_ROOTFS_UUID ')
|
||||
self.assertEqual(2, mock_grub.version)
|
||||
|
||||
@mock.patch.object(bootloader, 'utils', autospec=True)
|
||||
def test_do_bootloader_rootfs_not_found(self, mock_utils):
|
||||
mock_utils.execute.return_value = ('fake', 'fake')
|
||||
self.drv.partition_scheme.fss = [
|
||||
objects.FS(device='fake', mount='/boot', fs_type='ext2'),
|
||||
objects.FS(device='fake', mount='swap', fs_type='swap')]
|
||||
self.assertRaises(errors.WrongPartitionSchemeError,
|
||||
self.action.execute)
|
||||
|
||||
@mock.patch.object(bootloader, 'open', create=True,
|
||||
new_callable=mock.mock_open)
|
||||
@mock.patch.object(bootloader, 'gu', autospec=True)
|
||||
@mock.patch.object(bootloader, 'utils', autospec=True)
|
||||
def test_do_bootloader_grub_version_changes(
|
||||
self, mock_utils, mock_gu, mock_open):
|
||||
# actually covers only grub1 related logic
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
mock_gu.guess_grub_version.return_value = 'expected_version'
|
||||
self.action.execute()
|
||||
mock_gu.guess_grub_version.assert_called_once_with(
|
||||
chroot='/tmp/target')
|
||||
self.assertEqual('expected_version', self.drv.grub.version)
|
||||
|
||||
@mock.patch.object(bootloader, 'open', create=True,
|
||||
new_callable=mock.mock_open)
|
||||
@mock.patch.object(bootloader, 'gu', autospec=True)
|
||||
@mock.patch.object(bootloader, 'utils', autospec=True)
|
||||
def test_do_bootloader_grub1(self, mock_utils, mock_gu, mock_open):
|
||||
# actually covers only grub1 related logic
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
mock_gu.guess_initrd.return_value = 'guessed_initrd'
|
||||
mock_gu.guess_kernel.return_value = 'guessed_kernel'
|
||||
mock_gu.guess_grub_version.return_value = 1
|
||||
self.action.execute()
|
||||
mock_gu.guess_grub_version.assert_called_once_with(
|
||||
chroot='/tmp/target')
|
||||
mock_gu.grub1_cfg.assert_called_once_with(
|
||||
kernel_params=' console=ttyS0,9600 console=tty0 rootdelay=90 '
|
||||
'nomodeset root=UUID=fake_UUID ',
|
||||
initrd='guessed_initrd',
|
||||
chroot='/tmp/target',
|
||||
kernel='guessed_kernel',
|
||||
grub_timeout=5)
|
||||
mock_gu.grub1_install.assert_called_once_with(
|
||||
['/dev/sda', '/dev/sdb', '/dev/sdc'],
|
||||
'/dev/sda3', chroot='/tmp/target')
|
||||
self.assertFalse(mock_gu.grub2_cfg.called)
|
||||
self.assertFalse(mock_gu.grub2_install.called)
|
||||
|
||||
@mock.patch.object(bootloader, 'open', create=True,
|
||||
new_callable=mock.mock_open)
|
||||
@mock.patch.object(bootloader, 'gu', autospec=True)
|
||||
@mock.patch.object(bootloader, 'utils', autospec=True)
|
||||
def test_do_bootloader_grub2(self, mock_utils, mock_gu, mock_open):
|
||||
# actually covers only grub2 related logic
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
mock_gu.guess_grub_version.return_value = 2
|
||||
self.action.execute()
|
||||
mock_gu.guess_grub_version.assert_called_once_with(
|
||||
chroot='/tmp/target')
|
||||
mock_gu.grub2_cfg.assert_called_once_with(
|
||||
kernel_params=' console=ttyS0,9600 console=tty0 rootdelay=90 '
|
||||
'nomodeset root=UUID=fake_UUID ',
|
||||
chroot='/tmp/target', grub_timeout=5)
|
||||
mock_gu.grub2_install.assert_called_once_with(
|
||||
['/dev/sda', '/dev/sdb', '/dev/sdc'],
|
||||
chroot='/tmp/target')
|
||||
self.assertFalse(mock_gu.grub1_cfg.called)
|
||||
self.assertFalse(mock_gu.grub1_install.called)
|
||||
|
||||
@mock.patch.object(bootloader, 'gu', autospec=True)
|
||||
@mock.patch.object(bootloader, 'utils', autospec=True)
|
||||
def test_do_bootloader_writes(self, mock_utils, mock_gu):
|
||||
# actually covers only write() calls
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
self.drv.configdrive_scheme.common.udevrules = "08:00:27:79:da:80_"\
|
||||
"eth0,08:00:27:46:43:60_eth1,08:00:27:b1:d7:15_eth2"
|
||||
self.drv.partition_scheme.fss = [
|
||||
objects.FS('device', mount='/boot', fs_type='ext2'),
|
||||
objects.FS('device', mount='/tmp', fs_type='ext2'),
|
||||
objects.FS('device', mount='/', fs_type='ext4'),
|
||||
objects.FS('device', mount='swap', fs_type='swap'),
|
||||
objects.FS('device', mount='/var/lib/glance')]
|
||||
with mock.patch.object(bootloader, 'open', create=True) as mock_open:
|
||||
file_handle_mock = mock_open.return_value.__enter__.return_value
|
||||
self.action.execute()
|
||||
expected_open_calls = [
|
||||
mock.call('/tmp/target/etc/udev/rules.d/70-persistent-net.'
|
||||
'rules', 'wt', encoding='utf-8'),
|
||||
mock.call('/tmp/target/etc/udev/rules.d/75-persistent-net-'
|
||||
'generator.rules', 'wt', encoding='utf-8'),
|
||||
mock.call('/tmp/target/etc/nailgun-agent/nodiscover', 'w'),
|
||||
mock.call('/tmp/target/etc/fstab', 'wt', encoding='utf-8')]
|
||||
self.assertEqual(expected_open_calls, mock_open.call_args_list)
|
||||
expected_write_calls = [
|
||||
mock.call('# Generated by bareon during provisioning: '
|
||||
'BEGIN\n'),
|
||||
mock.call('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
|
||||
'ATTR{address}=="08:00:27:79:da:80", ATTR{type}=="1"'
|
||||
', KERNEL=="eth*", NAME="eth0"\n'),
|
||||
mock.call('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
|
||||
'ATTR{address}=="08:00:27:46:43:60", ATTR{type}=="1"'
|
||||
', KERNEL=="eth*", NAME="eth1"\n'),
|
||||
mock.call('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
|
||||
'ATTR{address}=="08:00:27:b1:d7:15", ATTR{type}=="1"'
|
||||
', KERNEL=="eth*", NAME="eth2"\n'),
|
||||
mock.call('# Generated by bareon during provisioning: '
|
||||
'END\n'),
|
||||
mock.call('# Generated by bareon during provisioning:\n# '
|
||||
'DO NOT DELETE. It is needed to disable '
|
||||
'net-generator\n'),
|
||||
mock.call('UUID=fake_UUID /boot ext2 defaults 0 0\n'),
|
||||
mock.call('UUID=fake_UUID /tmp ext2 defaults 0 0\n'),
|
||||
mock.call(
|
||||
'UUID=fake_UUID / ext4 defaults,errors=panic 0 0\n'),
|
||||
mock.call('UUID=fake_UUID swap swap defaults 0 0\n'),
|
||||
mock.call('UUID=fake_UUID /var/lib/glance xfs defaults 0 0\n')
|
||||
]
|
||||
self.assertEqual(expected_write_calls,
|
||||
file_handle_mock.write.call_args_list)
|
||||
self.action._mount_target.assert_called_once_with(
|
||||
'/tmp/target', os_id=None, pseudo=True, treat_mtab=True)
|
||||
mock_utils.makedirs_if_not_exists.assert_called_once_with(
|
||||
'/tmp/target/etc/nailgun-agent')
|
||||
self.action._umount_target.assert_called_once_with(
|
||||
'/tmp/target', os_id=None, pseudo=True)
|
@ -21,11 +21,7 @@ import unittest2
|
||||
|
||||
import bareon
|
||||
from bareon.drivers.data import nailgun as nailgun_data
|
||||
from bareon.drivers.deploy import nailgun as nailgun_deploy
|
||||
from bareon import errors
|
||||
from bareon import objects
|
||||
from bareon.tests import test_nailgun
|
||||
from bareon.utils import hardware as hu
|
||||
from bareon.utils import utils
|
||||
|
||||
if six.PY2:
|
||||
@ -36,334 +32,6 @@ elif six.PY3:
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
@unittest2.skip("Fix after cray rebase")
|
||||
class TestManager(unittest2.TestCase):
|
||||
|
||||
@mock.patch('bareon.drivers.data.nailgun.Nailgun.parse_image_meta',
|
||||
return_value={})
|
||||
@mock.patch.object(hu, 'list_block_devices')
|
||||
def setUp(self, mock_lbd, mock_image_meta):
|
||||
super(TestManager, self).setUp()
|
||||
mock_lbd.return_value = test_nailgun.LIST_BLOCK_DEVICES_SAMPLE
|
||||
self.mgr = nailgun_deploy.Manager(test_nailgun.PROVISION_SAMPLE_DATA)
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.open',
|
||||
create=True, new_callable=mock.mock_open)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.gu', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'mount_target')
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'umount_target')
|
||||
def test_do_bootloader_grub1_kernel_initrd_guessed(self, mock_umount,
|
||||
mock_mount, mock_utils,
|
||||
mock_gu, mock_open):
|
||||
mock_utils.execute.return_value = ('', '')
|
||||
mock_gu.guess_grub_version.return_value = 1
|
||||
# grub has kernel_name and initrd_name both set to None
|
||||
self.mgr.driver.grub.kernel_name = None
|
||||
self.mgr.driver.grub.initrd_name = None
|
||||
self.mgr.driver.grub.kernel_params = 'fake_kernel_params'
|
||||
self.mgr.driver.grub.kernel_regexp = 'fake_kernel_regexp'
|
||||
self.mgr.driver.grub.initrd_regexp = 'fake_initrd_regexp'
|
||||
mock_gu.guess_kernel.return_value = 'guessed_kernel'
|
||||
mock_gu.guess_initrd.return_value = 'guessed_initrd'
|
||||
self.mgr.do_bootloader()
|
||||
self.assertFalse(mock_gu.grub2_cfg.called)
|
||||
self.assertFalse(mock_gu.grub2_install.called)
|
||||
mock_gu.grub1_cfg.assert_called_once_with(
|
||||
kernel_params='fake_kernel_params root=UUID= ',
|
||||
initrd='guessed_initrd', kernel='guessed_kernel',
|
||||
chroot='/tmp/target', grub_timeout=5)
|
||||
mock_gu.grub1_install.assert_called_once_with(
|
||||
['/dev/sda', '/dev/sdb', '/dev/sdc'],
|
||||
'/dev/sda3', chroot='/tmp/target')
|
||||
mock_gu.guess_initrd.assert_called_once_with(
|
||||
regexp='fake_initrd_regexp', chroot='/tmp/target')
|
||||
mock_gu.guess_kernel.assert_called_once_with(
|
||||
regexp='fake_kernel_regexp', chroot='/tmp/target')
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.open',
|
||||
create=True, new_callable=mock.mock_open)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.gu', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'mount_target')
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'umount_target')
|
||||
def test_do_bootloader_grub1_kernel_initrd_set(self, mock_umount,
|
||||
mock_mount, mock_utils,
|
||||
mock_gu, mock_open):
|
||||
mock_utils.execute.return_value = ('', '')
|
||||
mock_gu.guess_grub_version.return_value = 1
|
||||
self.mgr.driver.grub.kernel_params = 'fake_kernel_params'
|
||||
# grub has kernel_name and initrd_name set
|
||||
self.mgr.driver.grub.kernel_name = 'kernel_name'
|
||||
self.mgr.driver.grub.initrd_name = 'initrd_name'
|
||||
self.mgr.do_bootloader()
|
||||
self.assertFalse(mock_gu.grub2_cfg.called)
|
||||
self.assertFalse(mock_gu.grub2_install.called)
|
||||
mock_gu.grub1_cfg.assert_called_once_with(
|
||||
kernel_params='fake_kernel_params root=UUID= ',
|
||||
initrd='initrd_name', kernel='kernel_name', chroot='/tmp/target',
|
||||
grub_timeout=5)
|
||||
mock_gu.grub1_install.assert_called_once_with(
|
||||
['/dev/sda', '/dev/sdb', '/dev/sdc'],
|
||||
'/dev/sda3', chroot='/tmp/target')
|
||||
self.assertFalse(mock_gu.guess_initrd.called)
|
||||
self.assertFalse(mock_gu.guess_kernel.called)
|
||||
|
||||
@mock.patch('bareon.objects.bootloader.Grub', autospec=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.open',
|
||||
create=True, new_callable=mock.mock_open)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.gu', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'mount_target')
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'umount_target')
|
||||
def test_do_bootloader_rootfs_uuid(self, mock_umount, mock_mount,
|
||||
mock_utils, mock_gu, mock_open,
|
||||
mock_grub):
|
||||
def _fake_uuid(*args, **kwargs):
|
||||
if len(args) >= 6 and args[5] == '/dev/mapper/os-root':
|
||||
return ('FAKE_ROOTFS_UUID', None)
|
||||
else:
|
||||
return ('FAKE_UUID', None)
|
||||
mock_utils.execute.side_effect = _fake_uuid
|
||||
mock_grub.version = 2
|
||||
mock_gu.guess_grub_version.return_value = 2
|
||||
mock_grub.kernel_name = 'fake_kernel_name'
|
||||
mock_grub.initrd_name = 'fake_initrd_name'
|
||||
mock_grub.kernel_params = 'fake_kernel_params'
|
||||
self.mgr.driver._grub = mock_grub
|
||||
self.mgr.do_bootloader()
|
||||
mock_grub.append_kernel_params.assert_called_once_with(
|
||||
'root=UUID=FAKE_ROOTFS_UUID ')
|
||||
self.assertEqual(2, mock_grub.version)
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'mount_target')
|
||||
def test_do_bootloader_rootfs_not_found(self, mock_umount, mock_utils):
|
||||
mock_utils.execute.return_value = ('fake', 'fake')
|
||||
self.mgr.driver._partition_scheme = objects.PartitionScheme()
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='/boot', fs_type='ext2')
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='swap', fs_type='swap')
|
||||
self.assertRaises(errors.WrongPartitionSchemeError,
|
||||
self.mgr.do_bootloader)
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.open',
|
||||
create=True, new_callable=mock.mock_open)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.gu', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'mount_target')
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'umount_target')
|
||||
def test_do_bootloader_grub_version_changes(
|
||||
self, mock_umount, mock_mount, mock_utils, mock_gu, mock_open):
|
||||
# actually covers only grub1 related logic
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
mock_gu.guess_grub_version.return_value = 'expected_version'
|
||||
self.mgr.do_bootloader()
|
||||
mock_gu.guess_grub_version.assert_called_once_with(
|
||||
chroot='/tmp/target')
|
||||
self.assertEqual('expected_version', self.mgr.driver.grub.version)
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.open',
|
||||
create=True, new_callable=mock.mock_open)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.gu', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'mount_target')
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'umount_target')
|
||||
def test_do_bootloader_grub1(self, mock_umount, mock_mount, mock_utils,
|
||||
mock_gu, mock_open):
|
||||
# actually covers only grub1 related logic
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
mock_gu.guess_initrd.return_value = 'guessed_initrd'
|
||||
mock_gu.guess_kernel.return_value = 'guessed_kernel'
|
||||
mock_gu.guess_grub_version.return_value = 1
|
||||
self.mgr.do_bootloader()
|
||||
mock_gu.guess_grub_version.assert_called_once_with(
|
||||
chroot='/tmp/target')
|
||||
mock_gu.grub1_cfg.assert_called_once_with(
|
||||
kernel_params=' console=ttyS0,9600 console=tty0 rootdelay=90 '
|
||||
'nomodeset root=UUID=fake_UUID ',
|
||||
initrd='guessed_initrd',
|
||||
chroot='/tmp/target',
|
||||
kernel='guessed_kernel',
|
||||
grub_timeout=5)
|
||||
mock_gu.grub1_install.assert_called_once_with(
|
||||
['/dev/sda', '/dev/sdb', '/dev/sdc'],
|
||||
'/dev/sda3', chroot='/tmp/target')
|
||||
self.assertFalse(mock_gu.grub2_cfg.called)
|
||||
self.assertFalse(mock_gu.grub2_install.called)
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.open',
|
||||
create=True, new_callable=mock.mock_open)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.gu', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'mount_target')
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'umount_target')
|
||||
def test_do_bootloader_grub2(self, mock_umount, mock_mount, mock_utils,
|
||||
mock_gu, mock_open):
|
||||
# actually covers only grub2 related logic
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
mock_gu.guess_grub_version.return_value = 2
|
||||
self.mgr.do_bootloader()
|
||||
mock_gu.guess_grub_version.assert_called_once_with(
|
||||
chroot='/tmp/target')
|
||||
mock_gu.grub2_cfg.assert_called_once_with(
|
||||
kernel_params=' console=ttyS0,9600 console=tty0 rootdelay=90 '
|
||||
'nomodeset root=UUID=fake_UUID ',
|
||||
chroot='/tmp/target', grub_timeout=5)
|
||||
mock_gu.grub2_install.assert_called_once_with(
|
||||
['/dev/sda', '/dev/sdb', '/dev/sdc'],
|
||||
chroot='/tmp/target')
|
||||
self.assertFalse(mock_gu.grub1_cfg.called)
|
||||
self.assertFalse(mock_gu.grub1_install.called)
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.gu', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'mount_target')
|
||||
@mock.patch.object(bareon.drivers.deploy.nailgun, 'umount_target')
|
||||
def test_do_bootloader_writes(self, mock_umount, mock_mount, mock_utils,
|
||||
mock_gu):
|
||||
# actually covers only write() calls
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
with mock.patch('bareon.drivers.deploy.nailgun.open',
|
||||
create=True) as mock_open:
|
||||
file_handle_mock = mock_open.return_value.__enter__.return_value
|
||||
self.mgr.do_bootloader()
|
||||
expected_open_calls = [
|
||||
mock.call('/tmp/target/etc/udev/rules.d/70-persistent-net.'
|
||||
'rules', 'wt', encoding='utf-8'),
|
||||
mock.call('/tmp/target/etc/udev/rules.d/75-persistent-net-'
|
||||
'generator.rules', 'wt', encoding='utf-8'),
|
||||
mock.call('/tmp/target/etc/nailgun-agent/nodiscover', 'w'),
|
||||
mock.call('/tmp/target/etc/fstab', 'wt', encoding='utf-8')]
|
||||
self.assertEqual(expected_open_calls, mock_open.call_args_list)
|
||||
expected_write_calls = [
|
||||
mock.call('# Generated by bareon during provisioning: '
|
||||
'BEGIN\n'),
|
||||
mock.call('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
|
||||
'ATTR{address}=="08:00:27:79:da:80", ATTR{type}=="1"'
|
||||
', KERNEL=="eth*", NAME="eth0"\n'),
|
||||
mock.call('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
|
||||
'ATTR{address}=="08:00:27:46:43:60", ATTR{type}=="1"'
|
||||
', KERNEL=="eth*", NAME="eth1"\n'),
|
||||
mock.call('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
|
||||
'ATTR{address}=="08:00:27:b1:d7:15", ATTR{type}=="1"'
|
||||
', KERNEL=="eth*", NAME="eth2"\n'),
|
||||
mock.call('# Generated by bareon during provisioning: '
|
||||
'END\n'),
|
||||
mock.call('# Generated by bareon during provisioning:\n# '
|
||||
'DO NOT DELETE. It is needed to disable '
|
||||
'net-generator\n'),
|
||||
mock.call('UUID=fake_UUID /boot ext2 defaults 0 0\n'),
|
||||
mock.call('UUID=fake_UUID /tmp ext2 defaults 0 0\n'),
|
||||
mock.call(
|
||||
'UUID=fake_UUID / ext4 defaults,errors=panic 0 0\n'),
|
||||
mock.call('UUID=fake_UUID swap swap defaults 0 0\n'),
|
||||
mock.call('UUID=fake_UUID /var/lib/glance xfs defaults 0 0\n')
|
||||
]
|
||||
self.assertEqual(expected_write_calls,
|
||||
file_handle_mock.write.call_args_list)
|
||||
mock_umount.assert_called_once_with('/tmp/target')
|
||||
mock_mount.assert_called_once_with('/tmp/target')
|
||||
mock_utils.makedirs_if_not_exists.assert_called_once_with(
|
||||
'/tmp/target/etc/nailgun-agent')
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.fu', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.open',
|
||||
create=True, new_callable=mock.mock_open)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.os', create=True)
|
||||
def test_mount_target_mtab_is_link(self, mock_os, mock_open, mock_utils,
|
||||
mock_fu):
|
||||
mock_os.path.islink.return_value = True
|
||||
mock_utils.execute.return_value = (None, None)
|
||||
self.mgr.driver._partition_scheme = objects.PartitionScheme()
|
||||
self.mgr.mount_target('fake_chroot')
|
||||
mock_open.assert_called_once_with('fake_chroot/etc/mtab', 'wt',
|
||||
encoding='utf-8')
|
||||
mock_os.path.islink.assert_called_once_with('fake_chroot/etc/mtab')
|
||||
mock_os.remove.assert_called_once_with('fake_chroot/etc/mtab')
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.fu', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.utils', create=True)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.open',
|
||||
create=True, new_callable=mock.mock_open)
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.os', create=True)
|
||||
def test_mount_target(self, mock_os, mock_open, mock_utils, mock_fu):
|
||||
mock_os.path.islink.return_value = False
|
||||
self.mgr.driver._partition_scheme = objects.PartitionScheme()
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='/var/lib', fs_type='xfs')
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='/', fs_type='ext4')
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='/boot', fs_type='ext2')
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='swap', fs_type='swap')
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='/var', fs_type='ext4')
|
||||
fake_mtab = """
|
||||
proc /proc proc rw,noexec,nosuid,nodev 0 0
|
||||
sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0
|
||||
none /sys/fs/fuse/connections fusectl rw 0 0
|
||||
none /sys/kernel/debug debugfs rw 0 0
|
||||
none /sys/kernel/security securityfs rw 0 0
|
||||
udev /dev devtmpfs rw,mode=0755 0 0
|
||||
devpts /dev/pts devpts rw,noexec,nosuid,gid=5,mode=0620 0 0
|
||||
tmpfs /run tmpfs rw,noexec,nosuid,size=10%,mode=0755 0 0
|
||||
none /run/lock tmpfs rw,noexec,nosuid,nodev,size=5242880 0 0
|
||||
none /run/shm tmpfs rw,nosuid,nodev 0 0"""
|
||||
mock_utils.execute.return_value = (fake_mtab, None)
|
||||
self.mgr.mount_target('fake_chroot')
|
||||
self.assertEqual([mock.call('fake_chroot/'),
|
||||
mock.call('fake_chroot/boot'),
|
||||
mock.call('fake_chroot/var'),
|
||||
mock.call('fake_chroot/var/lib'),
|
||||
mock.call('fake_chroot/sys'),
|
||||
mock.call('fake_chroot/dev'),
|
||||
mock.call('fake_chroot/proc')],
|
||||
mock_utils.makedirs_if_not_exists.call_args_list)
|
||||
self.assertEqual([mock.call('ext4', 'fake', 'fake_chroot/'),
|
||||
mock.call('ext2', 'fake', 'fake_chroot/boot'),
|
||||
mock.call('ext4', 'fake', 'fake_chroot/var'),
|
||||
mock.call('xfs', 'fake', 'fake_chroot/var/lib')],
|
||||
mock_fu.mount_fs.call_args_list)
|
||||
self.assertEqual([mock.call('fake_chroot', '/sys'),
|
||||
mock.call('fake_chroot', '/dev'),
|
||||
mock.call('fake_chroot', '/proc')],
|
||||
mock_fu.mount_bind.call_args_list)
|
||||
file_handle = mock_open.return_value.__enter__.return_value
|
||||
file_handle.write.assert_called_once_with(fake_mtab)
|
||||
mock_open.assert_called_once_with('fake_chroot/etc/mtab', 'wt',
|
||||
encoding='utf-8')
|
||||
mock_os.path.islink.assert_called_once_with('fake_chroot/etc/mtab')
|
||||
self.assertFalse(mock_os.remove.called)
|
||||
|
||||
@mock.patch('bareon.drivers.deploy.nailgun.fu', create=True)
|
||||
def test_umount_target(self, mock_fu):
|
||||
self.mgr.driver._partition_scheme = objects.PartitionScheme()
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='/var/lib', fs_type='xfs')
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='/', fs_type='ext4')
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='/boot', fs_type='ext2')
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='swap', fs_type='swap')
|
||||
self.mgr.driver.partition_scheme.add_fs(
|
||||
device='fake', mount='/var', fs_type='ext4')
|
||||
self.mgr.umount_target('fake_chroot')
|
||||
self.assertEqual([mock.call('fake_chroot/proc'),
|
||||
mock.call('fake_chroot/dev'),
|
||||
mock.call('fake_chroot/sys/fs/fuse/connections'),
|
||||
mock.call('fake_chroot/sys'),
|
||||
mock.call('fake_chroot/var/lib'),
|
||||
mock.call('fake_chroot/boot'),
|
||||
mock.call('fake_chroot/var'),
|
||||
mock.call('fake_chroot/')],
|
||||
mock_fu.umount_fs.call_args_list)
|
||||
|
||||
|
||||
@unittest2.skip("Fix after cray rebase")
|
||||
class TestImageBuild(unittest2.TestCase):
|
||||
|
||||
|
@ -43,6 +43,7 @@ bareon.actions =
|
||||
do_partitioning = bareon.actions.partitioning:PartitioningAction
|
||||
do_configdrive = bareon.actions.configdrive:ConfigDriveAction
|
||||
do_copyimage = bareon.actions.copyimage:CopyImageAction
|
||||
do_bootloader = bareon.actions.bootloader:BootLoaderAction
|
||||
|
||||
oslo.config.opts =
|
||||
bareon.manager = bareon.manager:list_opts
|
||||
|
Loading…
Reference in New Issue
Block a user