Merge "Configure admin NIC prior the first system boot"
This commit is contained in:
commit
62a7800e26
|
@ -15,22 +15,6 @@ cloud-init-per instance disable_selinux_on_the_fly setenforce 0
|
|||
|
||||
cloud-init-per instance disable_selinux sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/sysconfig/selinux
|
||||
|
||||
|
||||
# configure udev rules
|
||||
|
||||
# udev persistent net
|
||||
cloud-init-per instance udev_persistent_net1 service network stop
|
||||
|
||||
ADMIN_MAC={{ common.admin_mac }}
|
||||
ADMIN_IF=$(echo {{ common.udevrules }} | sed 's/[,=]/\n/g' | grep "$ADMIN_MAC" | cut -d_ -f2 | head -1)
|
||||
cloud-init-per instance configure_admin_interface /bin/sh -c "echo -e \"# FROM COBBLER SNIPPET\nDEVICE=$ADMIN_IF\nIPADDR={{ common.admin_ip }}\nNETMASK={{ common.admin_mask }}\nBOOTPROTO=none\nONBOOT=yes\nUSERCTL=no\n\" | tee /etc/sysconfig/network-scripts/ifcfg-$ADMIN_IF"
|
||||
|
||||
cloud-init-per instance set_gateway /bin/sh -c 'echo GATEWAY="{{ common.gw }}" | tee -a /etc/sysconfig/network'
|
||||
|
||||
cloud-init-per instance udev_persistent_net5 service network start
|
||||
|
||||
# end of udev
|
||||
|
||||
#FIXME(agordeev): if operator updates dns settings on masternode after the node had been provisioned,
|
||||
# cloud-init will start to generate resolv.conf with non-actual data
|
||||
cloud-init-per instance resolv_conf_remove rm -f /etc/resolv.conf
|
||||
|
|
|
@ -15,22 +15,6 @@ cloud-init-per instance disable_selinux_on_the_fly setenforce 0
|
|||
|
||||
cloud-init-per instance disable_selinux sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/sysconfig/selinux
|
||||
|
||||
|
||||
# configure udev rules
|
||||
|
||||
# udev persistent net
|
||||
cloud-init-per instance udev_persistent_net1 service network stop
|
||||
|
||||
ADMIN_MAC={{ common.admin_mac }}
|
||||
ADMIN_IF=$(echo {{ common.udevrules }} | sed 's/[,=]/\n/g' | grep "$ADMIN_MAC" | cut -d_ -f2 | head -1)
|
||||
cloud-init-per instance configure_admin_interface /bin/sh -c "echo -e \"# FROM COBBLER SNIPPET\nDEVICE=$ADMIN_IF\nIPADDR={{ common.admin_ip }}\nNETMASK={{ common.admin_mask }}\nBOOTPROTO=none\nONBOOT=yes\nUSERCTL=no\n\" | tee /etc/sysconfig/network-scripts/ifcfg-$ADMIN_IF"
|
||||
|
||||
cloud-init-per instance set_gateway /bin/sh -c 'echo GATEWAY="{{ common.gw }}" | tee -a /etc/sysconfig/network'
|
||||
|
||||
cloud-init-per instance udev_persistent_net5 service network start
|
||||
|
||||
# end of udev
|
||||
|
||||
#FIXME(agordeev): if operator updates dns settings on masternode after the node had been provisioned,
|
||||
# cloud-init will start to generate resolv.conf with non-actual data
|
||||
cloud-init-per instance resolv_conf_remove rm -f /etc/resolv.conf
|
||||
|
|
|
@ -12,26 +12,6 @@ function add_str_to_file_if_not_exists {
|
|||
|
||||
cloud-init-per instance wipe_sources_list_templates /bin/sh -c 'echo | tee /etc/cloud/templates/sources.list.ubuntu.tmpl'
|
||||
|
||||
# configure udev rules
|
||||
|
||||
# udev persistent net
|
||||
cloud-init-per instance udev_persistent_net1 /etc/init.d/networking stop
|
||||
|
||||
ADMIN_MAC={{ common.admin_mac }}
|
||||
ADMIN_IF=$(echo {{ common.udevrules }} | sed 's/[,=]/\n/g' | grep "$ADMIN_MAC" | cut -d_ -f2 | head -1)
|
||||
# Check if we do not already have static config (or interface seems unconfigured)
|
||||
if [ ! -d "/etc/network/interfaces.d" ]; then
|
||||
mkdir -p /etc/network/interfaces.d
|
||||
echo 'source /etc/network/interfaces.d/*' > /etc/network/interfaces
|
||||
fi
|
||||
if [ ! -e "/etc/network/interfaces.d/ifcfg-$ADMIN_IF" ]; then
|
||||
echo -e "auto $ADMIN_IF\niface $ADMIN_IF inet static\n\taddress {{ common.admin_ip }}\n\tnetmask {{ common.admin_mask }}\n\tgateway {{ common.gw }}" > /etc/network/interfaces.d/ifcfg-"$ADMIN_IF"
|
||||
fi
|
||||
|
||||
cloud-init-per instance udev_persistent_net5 /etc/init.d/networking start
|
||||
|
||||
# end of udev
|
||||
|
||||
#FIXME(agordeev): if operator updates dns settings on masternode after the node had been provisioned,
|
||||
# cloud-init will start to generate resolv.conf with non-actual data
|
||||
cloud-init-per instance resolv_conf_mkdir mkdir -p /etc/resolvconf/resolv.conf.d
|
||||
|
|
|
@ -15,22 +15,6 @@ cloud-init-per instance disable_selinux_on_the_fly setenforce 0
|
|||
|
||||
cloud-init-per instance disable_selinux sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/sysconfig/selinux
|
||||
|
||||
|
||||
# configure udev rules
|
||||
|
||||
# udev persistent net
|
||||
cloud-init-per instance udev_persistent_net1 service network stop
|
||||
|
||||
ADMIN_MAC={{ common.admin_mac }}
|
||||
ADMIN_IF=$(echo {{ common.udevrules }} | sed 's/[,=]/\n/g' | grep "$ADMIN_MAC" | cut -d_ -f2 | head -1)
|
||||
cloud-init-per instance configure_admin_interface /bin/sh -c "echo -e \"# FROM COBBLER SNIPPET\nDEVICE=$ADMIN_IF\nIPADDR={{ common.admin_ip }}\nNETMASK={{ common.admin_mask }}\nBOOTPROTO=none\nONBOOT=yes\nUSERCTL=no\n\" | tee /etc/sysconfig/network-scripts/ifcfg-$ADMIN_IF"
|
||||
|
||||
cloud-init-per instance set_gateway /bin/sh -c 'echo GATEWAY="{{ common.gw }}" | tee -a /etc/sysconfig/network'
|
||||
|
||||
cloud-init-per instance udev_persistent_net5 service network start
|
||||
|
||||
# end of udev
|
||||
|
||||
#FIXME(agordeev): if operator updates dns settings on masternode after the node had been provisioned,
|
||||
# cloud-init will start to generate resolv.conf with non-actual data
|
||||
cloud-init-per instance resolv_conf_remove rm -f /etc/resolv.conf
|
||||
|
|
|
@ -12,26 +12,6 @@ function add_str_to_file_if_not_exists {
|
|||
|
||||
cloud-init-per instance wipe_sources_list_templates /bin/sh -c 'echo | tee /etc/cloud/templates/sources.list.ubuntu.tmpl'
|
||||
|
||||
# configure udev rules
|
||||
|
||||
# udev persistent net
|
||||
cloud-init-per instance udev_persistent_net1 /etc/init.d/networking stop
|
||||
|
||||
ADMIN_MAC={{ common.admin_mac }}
|
||||
ADMIN_IF=$(echo {{ common.udevrules }} | sed 's/[,=]/\n/g' | grep "$ADMIN_MAC" | cut -d_ -f2 | head -1)
|
||||
# Check if we do not already have static config (or interface seems unconfigured)
|
||||
if [ ! -d "/etc/network/interfaces.d" ]; then
|
||||
mkdir -p /etc/network/interfaces.d
|
||||
echo 'source /etc/network/interfaces.d/*' > /etc/network/interfaces
|
||||
fi
|
||||
if [ ! -e "/etc/network/interfaces.d/ifcfg-$ADMIN_IF" ]; then
|
||||
echo -e "auto $ADMIN_IF\niface $ADMIN_IF inet static\n\taddress {{ common.admin_ip }}\n\tnetmask {{ common.admin_mask }}\n\tgateway {{ common.gw }}" > /etc/network/interfaces.d/ifcfg-"$ADMIN_IF"
|
||||
fi
|
||||
|
||||
cloud-init-per instance udev_persistent_net5 /etc/init.d/networking start
|
||||
|
||||
# end of udev
|
||||
|
||||
#FIXME(agordeev): if operator updates dns settings on masternode after the node had been provisioned,
|
||||
# cloud-init will start to generate resolv.conf with non-actual data
|
||||
cloud-init-per instance resolv_conf_mkdir mkdir -p /etc/resolvconf/resolv.conf.d
|
||||
|
|
|
@ -12,26 +12,6 @@ function add_str_to_file_if_not_exists {
|
|||
|
||||
cloud-init-per instance wipe_sources_list_templates /bin/sh -c 'echo | tee /etc/cloud/templates/sources.list.ubuntu.tmpl'
|
||||
|
||||
# configure udev rules
|
||||
|
||||
# udev persistent net
|
||||
cloud-init-per instance udev_persistent_net1 /etc/init.d/networking stop
|
||||
|
||||
ADMIN_MAC={{ common.admin_mac }}
|
||||
ADMIN_IF=$(echo {{ common.udevrules }} | sed 's/[,=]/\n/g' | grep "$ADMIN_MAC" | cut -d_ -f2 | head -1)
|
||||
# Check if we do not already have static config (or interface seems unconfigured)
|
||||
if [ ! -d "/etc/network/interfaces.d" ]; then
|
||||
mkdir -p /etc/network/interfaces.d
|
||||
echo 'source /etc/network/interfaces.d/*' > /etc/network/interfaces
|
||||
fi
|
||||
if [ ! -e "/etc/network/interfaces.d/ifcfg-$ADMIN_IF" ]; then
|
||||
echo -e "auto $ADMIN_IF\niface $ADMIN_IF inet static\n\taddress {{ common.admin_ip }}\n\tnetmask {{ common.admin_mask }}\n\tgateway {{ common.gw }}" > /etc/network/interfaces.d/ifcfg-"$ADMIN_IF"
|
||||
fi
|
||||
|
||||
cloud-init-per instance udev_persistent_net5 /etc/init.d/networking start
|
||||
|
||||
# end of udev
|
||||
|
||||
#FIXME(agordeev): if operator updates dns settings on masternode after the node had been provisioned,
|
||||
# cloud-init will start to generate resolv.conf with non-actual data
|
||||
cloud-init-per instance resolv_conf_mkdir mkdir -p /etc/resolvconf/resolv.conf.d
|
||||
|
|
|
@ -12,26 +12,6 @@ function add_str_to_file_if_not_exists {
|
|||
|
||||
cloud-init-per instance wipe_sources_list_templates /bin/sh -c 'echo | tee /etc/cloud/templates/sources.list.ubuntu.tmpl'
|
||||
|
||||
# configure udev rules
|
||||
|
||||
# udev persistent net
|
||||
cloud-init-per instance udev_persistent_net1 /etc/init.d/networking stop
|
||||
|
||||
ADMIN_MAC={{ common.admin_mac }}
|
||||
ADMIN_IF=$(echo {{ common.udevrules }} | sed 's/[,=]/\n/g' | grep "$ADMIN_MAC" | cut -d_ -f2 | head -1)
|
||||
# Check if we do not already have static config (or interface seems unconfigured)
|
||||
if [ ! -d "/etc/network/interfaces.d" ]; then
|
||||
mkdir -p /etc/network/interfaces.d
|
||||
echo 'source /etc/network/interfaces.d/*' > /etc/network/interfaces
|
||||
fi
|
||||
if [ ! -e "/etc/network/interfaces.d/ifcfg-$ADMIN_IF" ]; then
|
||||
echo -e "auto $ADMIN_IF\niface $ADMIN_IF inet static\n\taddress {{ common.admin_ip }}\n\tnetmask {{ common.admin_mask }}\n\tgateway {{ common.gw }}" > /etc/network/interfaces.d/ifcfg-"$ADMIN_IF"
|
||||
fi
|
||||
|
||||
cloud-init-per instance udev_persistent_net5 /etc/init.d/networking start
|
||||
|
||||
# end of udev
|
||||
|
||||
#FIXME(agordeev): if operator updates dns settings on masternode after the node had been provisioned,
|
||||
# cloud-init will start to generate resolv.conf with non-actual data
|
||||
cloud-init-per instance resolv_conf_mkdir mkdir -p /etc/resolvconf/resolv.conf.d
|
||||
|
@ -96,4 +76,4 @@ cloud-init-per instance skel_bash cp -f /etc/skel/.bash* /root/
|
|||
|
||||
cloud-init-per instance hiera_puppet mkdir -p /etc/puppet /var/lib/hiera
|
||||
cloud-init-per instance touch_puppet touch /var/lib/hiera/common.yaml /etc/puppet/hiera.yaml /var/log/puppet.log
|
||||
cloud-init-per instance chmod_puppet chmod 600 /var/log/puppet.log
|
||||
cloud-init-per instance chmod_puppet chmod 600 /var/log/puppet.log
|
||||
|
|
|
@ -12,26 +12,6 @@ function add_str_to_file_if_not_exists {
|
|||
|
||||
cloud-init-per instance wipe_sources_list_templates /bin/sh -c 'echo | tee /etc/cloud/templates/sources.list.ubuntu.tmpl'
|
||||
|
||||
# configure udev rules
|
||||
|
||||
# udev persistent net
|
||||
cloud-init-per instance udev_persistent_net1 /etc/init.d/networking stop
|
||||
|
||||
ADMIN_MAC={{ common.admin_mac }}
|
||||
ADMIN_IF=$(echo {{ common.udevrules }} | sed 's/[,=]/\n/g' | grep "$ADMIN_MAC" | cut -d_ -f2 | head -1)
|
||||
# Check if we do not already have static config (or interface seems unconfigured)
|
||||
if [ ! -d "/etc/network/interfaces.d" ]; then
|
||||
mkdir -p /etc/network/interfaces.d
|
||||
echo 'source /etc/network/interfaces.d/*' > /etc/network/interfaces
|
||||
fi
|
||||
if [ ! -e "/etc/network/interfaces.d/ifcfg-$ADMIN_IF" ]; then
|
||||
echo -e "auto $ADMIN_IF\niface $ADMIN_IF inet static\n\taddress {{ common.admin_ip }}\n\tnetmask {{ common.admin_mask }}\n\tgateway {{ common.gw }}" > /etc/network/interfaces.d/ifcfg-"$ADMIN_IF"
|
||||
fi
|
||||
|
||||
cloud-init-per instance udev_persistent_net5 /etc/init.d/networking start
|
||||
|
||||
# end of udev
|
||||
|
||||
#FIXME(agordeev): if operator updates dns settings on masternode after the node had been provisioned,
|
||||
# cloud-init will start to generate resolv.conf with non-actual data
|
||||
cloud-init-per instance resolv_conf_mkdir mkdir -p /etc/resolvconf/resolv.conf.d
|
||||
|
|
|
@ -182,3 +182,7 @@ class WrongOutputContainer(BaseError):
|
|||
|
||||
class BootstrapFileAlreadyExists(BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class UnsupportedNetworkConfiguration(BaseError):
|
||||
pass
|
||||
|
|
|
@ -32,6 +32,7 @@ from fuel_agent.utils import hardware as hw
|
|||
from fuel_agent.utils import lvm as lu
|
||||
from fuel_agent.utils import md as mu
|
||||
from fuel_agent.utils import partition as pu
|
||||
from fuel_agent.utils import provision
|
||||
from fuel_agent.utils import utils
|
||||
|
||||
opts = [
|
||||
|
@ -922,31 +923,19 @@ class Manager(object):
|
|||
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 fuel-agent 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 fuel-agent 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 fuel-agent during provisioning:\n'
|
||||
u'# DO NOT DELETE. It is needed to disable '
|
||||
u'net-generator\n')
|
||||
provision.udev_nic_naming_rules(
|
||||
chroot, self.driver.configdrive_scheme.common.udevrules)
|
||||
|
||||
if CONF.prepare_configdrive:
|
||||
# FIXME(agordeev): Normally, that should be handled out side of
|
||||
# fuel-agent. Just a temporary fix to avoid dealing with cloud-init
|
||||
# boothooks.
|
||||
provision.configure_admin_nic(
|
||||
chroot=chroot,
|
||||
iface=self.driver.configdrive_scheme.common.admin_iface_name,
|
||||
ip=self.driver.configdrive_scheme.common.admin_ip,
|
||||
netmask=self.driver.configdrive_scheme.common.admin_mask,
|
||||
gw=self.driver.configdrive_scheme.common.gw)
|
||||
|
||||
# FIXME(kozhukalov): Prevent nailgun-agent from doing anything.
|
||||
# This ugly hack is to be used together with the command removing
|
||||
|
|
|
@ -61,6 +61,7 @@ class TestManager(unittest2.TestCase):
|
|||
mock_lbd.return_value = test_nailgun.LIST_BLOCK_DEVICES_SAMPLE
|
||||
self.mgr = manager.Manager(test_nailgun.PROVISION_SAMPLE_DATA)
|
||||
|
||||
@mock.patch('fuel_agent.manager.provision', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.hw', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.bu', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.open',
|
||||
|
@ -72,7 +73,8 @@ class TestManager(unittest2.TestCase):
|
|||
def test_do_bootloader_grub1_kernel_initrd_guessed(self, mock_umount,
|
||||
mock_mount, mock_utils,
|
||||
mock_gu, mock_open,
|
||||
mock_bu, mock_hw):
|
||||
mock_bu, mock_hw,
|
||||
mock_prov):
|
||||
mock_hw.is_multipath_device.return_value = False
|
||||
mock_utils.execute.return_value = ('', '')
|
||||
mock_gu.guess_grub_version.return_value = 1
|
||||
|
@ -99,6 +101,7 @@ class TestManager(unittest2.TestCase):
|
|||
mock_gu.guess_kernel.assert_called_once_with(
|
||||
regexp='fake_kernel_regexp', chroot='/tmp/target')
|
||||
|
||||
@mock.patch('fuel_agent.manager.provision', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.hw', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.bu', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.open',
|
||||
|
@ -110,7 +113,8 @@ class TestManager(unittest2.TestCase):
|
|||
def test_do_bootloader_grub1_kernel_initrd_set(self, mock_umount,
|
||||
mock_mount, mock_utils,
|
||||
mock_gu, mock_open,
|
||||
mock_bu, mock_hw):
|
||||
mock_bu, mock_hw,
|
||||
mock_prov):
|
||||
mock_hw.is_multipath_device.return_value = False
|
||||
mock_utils.execute.return_value = ('', '')
|
||||
mock_gu.guess_grub_version.return_value = 1
|
||||
|
@ -132,6 +136,7 @@ class TestManager(unittest2.TestCase):
|
|||
self.assertFalse(mock_gu.guess_kernel.called)
|
||||
self.assertFalse(mock_bu.override_lvm_config.called)
|
||||
|
||||
@mock.patch('fuel_agent.manager.provision', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.hw', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.bu', autospec=True)
|
||||
@mock.patch('fuel_agent.objects.bootloader.Grub', autospec=True)
|
||||
|
@ -143,7 +148,7 @@ class TestManager(unittest2.TestCase):
|
|||
@mock.patch.object(manager.Manager, 'umount_target')
|
||||
def test_do_bootloader_rootfs_uuid(self, mock_umount, mock_mount,
|
||||
mock_utils, mock_gu, mock_open,
|
||||
mock_grub, mock_bu, mock_hw):
|
||||
mock_grub, mock_bu, mock_hw, mock_prov):
|
||||
def _fake_uuid(*args, **kwargs):
|
||||
if len(args) >= 8 and args[7] == '/dev/mapper/os-root':
|
||||
return ('FAKE_ROOTFS_UUID', None)
|
||||
|
@ -179,6 +184,7 @@ class TestManager(unittest2.TestCase):
|
|||
self.assertRaises(errors.WrongPartitionSchemeError,
|
||||
self.mgr.do_bootloader)
|
||||
|
||||
@mock.patch('fuel_agent.manager.provision', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.hw', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.bu', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.open',
|
||||
|
@ -189,7 +195,7 @@ class TestManager(unittest2.TestCase):
|
|||
@mock.patch.object(manager.Manager, 'umount_target')
|
||||
def test_do_bootloader_grub_version_changes(
|
||||
self, mock_umount, mock_mount, mock_utils, mock_gu, mock_open,
|
||||
mock_bu, mock_hw):
|
||||
mock_bu, mock_hw, mock_prov):
|
||||
# actually covers only grub1 related logic
|
||||
mock_hw.is_multipath_device.return_value = False
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
|
@ -199,6 +205,7 @@ class TestManager(unittest2.TestCase):
|
|||
chroot='/tmp/target')
|
||||
self.assertEqual('expected_version', self.mgr.driver.grub.version)
|
||||
|
||||
@mock.patch('fuel_agent.manager.provision', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.hw', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.bu', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.open',
|
||||
|
@ -208,7 +215,8 @@ class TestManager(unittest2.TestCase):
|
|||
@mock.patch.object(manager.Manager, 'mount_target')
|
||||
@mock.patch.object(manager.Manager, 'umount_target')
|
||||
def test_do_bootloader_grub1(self, mock_umount, mock_mount, mock_utils,
|
||||
mock_gu, mock_open, mock_bu, mock_hw):
|
||||
mock_gu, mock_open, mock_bu, mock_hw,
|
||||
mock_prov):
|
||||
# actually covers only grub1 related logic
|
||||
mock_hw.is_multipath_device.return_value = False
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
|
@ -231,6 +239,7 @@ class TestManager(unittest2.TestCase):
|
|||
self.assertFalse(mock_gu.grub2_cfg.called)
|
||||
self.assertFalse(mock_gu.grub2_install.called)
|
||||
|
||||
@mock.patch('fuel_agent.manager.provision', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.hw', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.bu', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.open',
|
||||
|
@ -240,7 +249,8 @@ class TestManager(unittest2.TestCase):
|
|||
@mock.patch.object(manager.Manager, 'mount_target')
|
||||
@mock.patch.object(manager.Manager, 'umount_target')
|
||||
def test_do_bootloader_grub2(self, mock_umount, mock_mount, mock_utils,
|
||||
mock_gu, mock_open, mock_bu, mock_hw):
|
||||
mock_gu, mock_open, mock_bu, mock_hw,
|
||||
mock_prov):
|
||||
# actually covers only grub2 related logic
|
||||
mock_hw.is_multipath_device.return_value = False
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
|
@ -258,6 +268,7 @@ class TestManager(unittest2.TestCase):
|
|||
self.assertFalse(mock_gu.grub1_cfg.called)
|
||||
self.assertFalse(mock_gu.grub1_install.called)
|
||||
|
||||
@mock.patch('fuel_agent.manager.provision', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.hw', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.bu', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.open',
|
||||
|
@ -268,7 +279,7 @@ class TestManager(unittest2.TestCase):
|
|||
@mock.patch.object(manager.Manager, 'umount_target')
|
||||
def test_do_bootloader_with_multipath(
|
||||
self, mock_umount, mock_mount, mock_utils, mock_gu, mock_open,
|
||||
mock_bu, mock_hw):
|
||||
mock_bu, mock_hw, mock_prov):
|
||||
# actually covers only multipath related logic
|
||||
# Lets assume that only /dev/sda device is not-multipath
|
||||
mock_hw.is_multipath_device.side_effect = False, False, True
|
||||
|
@ -294,6 +305,7 @@ class TestManager(unittest2.TestCase):
|
|||
update_initramfs=True,
|
||||
lvm_conf_path='/etc/lvm/lvm.conf')
|
||||
|
||||
@mock.patch('fuel_agent.manager.provision', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.hw', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.bu', autospec=True)
|
||||
@mock.patch('fuel_agent.manager.gu', create=True)
|
||||
|
@ -301,7 +313,7 @@ class TestManager(unittest2.TestCase):
|
|||
@mock.patch.object(manager.Manager, 'mount_target')
|
||||
@mock.patch.object(manager.Manager, 'umount_target')
|
||||
def test_do_bootloader_writes(self, mock_umount, mock_mount, mock_utils,
|
||||
mock_gu, mock_bu, mock_hw):
|
||||
mock_gu, mock_bu, mock_hw, mock_prov):
|
||||
# actually covers only write() calls
|
||||
mock_hw.is_multipath_device.return_value = False
|
||||
mock_utils.execute.return_value = ('fake_UUID\n', None)
|
||||
|
@ -309,30 +321,10 @@ class TestManager(unittest2.TestCase):
|
|||
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 fuel-agent 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 fuel-agent during provisioning: '
|
||||
'END\n'),
|
||||
mock.call('# Generated by fuel-agent 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(
|
||||
|
@ -346,6 +338,14 @@ class TestManager(unittest2.TestCase):
|
|||
mock_mount.assert_called_once_with('/tmp/target')
|
||||
mock_utils.makedirs_if_not_exists.assert_called_once_with(
|
||||
'/tmp/target/etc/nailgun-agent')
|
||||
mock_prov.udev_nic_naming_rules.assert_called_once_with(
|
||||
'/tmp/target', self.mgr.driver.configdrive_scheme.common.udevrules)
|
||||
mock_prov.configure_admin_nic.assert_called_once_with(
|
||||
chroot='/tmp/target',
|
||||
iface=self.mgr.driver.configdrive_scheme.common.admin_iface_name,
|
||||
ip=self.mgr.driver.configdrive_scheme.common.admin_ip,
|
||||
netmask=self.mgr.driver.configdrive_scheme.common.admin_mask,
|
||||
gw=self.mgr.driver.configdrive_scheme.common.gw)
|
||||
|
||||
@mock.patch('fuel_agent.drivers.nailgun.Nailgun.parse_image_meta',
|
||||
return_value={})
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
# 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 mock
|
||||
import unittest2
|
||||
|
||||
from fuel_agent import errors
|
||||
from fuel_agent.utils import provision
|
||||
|
||||
|
||||
class TestProvisionUtils(unittest2.TestCase):
|
||||
|
||||
def test_udev_nic_naming_rules(self):
|
||||
udevrules = "08:00:27:79:da:80_eth0,08:00:27:46:43:60_eth1,"\
|
||||
"08:00:27:b1:d7:15_eth2"
|
||||
with mock.patch.object(provision, 'open', create=True) as mock_open:
|
||||
file_handle_mock = mock_open.return_value.__enter__.return_value
|
||||
provision.udev_nic_naming_rules('/tmp/target', udevrules)
|
||||
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')]
|
||||
self.assertEqual(expected_open_calls, mock_open.call_args_list)
|
||||
expected_write_calls = [
|
||||
mock.call('# Generated by fuel-agent 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 fuel-agent during provisioning: '
|
||||
'END\n'),
|
||||
mock.call('# Generated by fuel-agent during provisioning:\n# '
|
||||
'DO NOT DELETE. It is needed to disable '
|
||||
'net-generator\n'),
|
||||
]
|
||||
self.assertEqual(expected_write_calls,
|
||||
file_handle_mock.write.call_args_list)
|
||||
|
||||
@mock.patch.object(provision, 'os', autospec=True)
|
||||
def test_configure_admin_nic_failed(self, mock_os):
|
||||
mock_os.path.exists.return_value = False
|
||||
self.assertRaises(errors.UnsupportedNetworkConfiguration,
|
||||
provision.configure_admin_nic,
|
||||
'chroot', 'iface', 'ip', 'netmask', 'gw')
|
||||
self.assertEqual([mock.call('chroot/etc/network/interfaces'),
|
||||
mock.call('chroot/etc/sysconfig/network-scripts')],
|
||||
mock_os.path.exists.call_args_list)
|
||||
|
||||
@mock.patch.object(provision, 'utils', autospec=True)
|
||||
def test_configure_admin_nic_ubuntu(self, mock_utils):
|
||||
with mock.patch.object(provision, 'open', create=True) as mock_open:
|
||||
file_handle_mock = mock_open.return_value.__enter__.return_value
|
||||
provision.configure_admin_nic_ubuntu(
|
||||
'/tmp/target', 'IFACE', 'IP', 'NETMASK', 'GW')
|
||||
expected_open_calls = [
|
||||
mock.call('/tmp/target/etc/network/interfaces',
|
||||
'wt', encoding='utf-8'),
|
||||
mock.call('/tmp/target/etc/network/interfaces.d/ifcfg-IFACE',
|
||||
'wt', encoding='utf-8')]
|
||||
self.assertEqual(expected_open_calls, mock_open.call_args_list)
|
||||
expected_write_calls = [
|
||||
mock.call(u'# Generated by fuel-agent during provisioning:\n'
|
||||
u'source-directory /etc/network/interfaces.d\n'),
|
||||
mock.call(u'# Generated by fuel-agent during provisioning:\n'
|
||||
u'auto IFACE\n'
|
||||
u'iface IFACE inet static\n'
|
||||
u'\taddress IP\n'
|
||||
u'\tnetmask NETMASK\n'
|
||||
u'\tgateway GW\n'),
|
||||
]
|
||||
self.assertEqual(expected_write_calls,
|
||||
file_handle_mock.write.call_args_list)
|
||||
|
||||
@mock.patch.object(provision, 'utils', autospec=True)
|
||||
def test_configure_admin_nic_centos(self, mock_utils):
|
||||
with mock.patch.object(provision, 'open', create=True) as mock_open:
|
||||
file_handle_mock = mock_open.return_value.__enter__.return_value
|
||||
provision.configure_admin_nic_centos(
|
||||
'/tmp/target', 'IFACE', 'IP', 'NETMASK', 'GW')
|
||||
expected_open_calls = [
|
||||
mock.call('/tmp/target/etc/sysconfig/network-scripts/'
|
||||
'ifcfg-IFACE',
|
||||
'wt', encoding='utf-8'),
|
||||
mock.call('/tmp/target/etc/sysconfig/network',
|
||||
'at', encoding='utf-8')]
|
||||
self.assertEqual(expected_open_calls, mock_open.call_args_list)
|
||||
expected_write_calls = [
|
||||
mock.call(u'# Generated by fuel-agent during provisioning:\n'
|
||||
u'DEVICE=IFACE\n'
|
||||
u'IPADDR=IP\n'
|
||||
u'NETMASK=NETMASK\n'
|
||||
u'BOOTPROTO=none\n'
|
||||
u'ONBOOT=yes\n'
|
||||
u'USERCTL=no\n'),
|
||||
mock.call(u'GATEWAY="GW"\n'),
|
||||
]
|
||||
self.assertEqual(expected_write_calls,
|
||||
file_handle_mock.write.call_args_list)
|
|
@ -0,0 +1,100 @@
|
|||
# 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_log import log as logging
|
||||
|
||||
from fuel_agent import errors
|
||||
from fuel_agent.utils import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def udev_nic_naming_rules(chroot, udevrules):
|
||||
"""Generates NIC naming rules for udev.
|
||||
|
||||
Expected string formatting: "(macaddrX)_(nicX)" comma separated.
|
||||
Eg.: "08:00:27:79:da:80_eth0,08:00:27:46:43:60_eth1"
|
||||
"""
|
||||
# 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 fuel-agent during provisioning: '
|
||||
u'BEGIN\n')
|
||||
# pattern is aa:bb:cc:dd:ee:ff_eth0,aa:bb:cc:dd:ee:ff_eth1
|
||||
for mapping in 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 fuel-agent during provisioning: END\n')
|
||||
# FIXME(agordeev): Disable net-generator that will add 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 fuel-agent during provisioning:\n'
|
||||
u'# DO NOT DELETE. It is needed to disable '
|
||||
u'net-generator\n')
|
||||
|
||||
|
||||
def configure_admin_nic(chroot, iface, ip, netmask, gw):
|
||||
debian_conf = '/etc/network/interfaces'
|
||||
redhat_conf = '/etc/sysconfig/network-scripts'
|
||||
if os.path.exists(chroot + debian_conf):
|
||||
configure_admin_nic_ubuntu(chroot, iface, ip, netmask, gw)
|
||||
elif os.path.exists(chroot + redhat_conf):
|
||||
configure_admin_nic_centos(chroot, iface, ip, netmask, gw)
|
||||
else:
|
||||
raise errors.UnsupportedNetworkConfiguration(
|
||||
"Can't find suitable configuration files for admin NIC")
|
||||
|
||||
|
||||
def configure_admin_nic_ubuntu(chroot, iface, ip, netmask, gw):
|
||||
ifaces_dir = '/etc/network/interfaces.d'
|
||||
ifcfg_path = os.path.join(ifaces_dir, 'ifcfg-{0}'.format(iface))
|
||||
utils.makedirs_if_not_exists(ifaces_dir)
|
||||
with open(chroot + '/etc/network/interfaces', 'wt', encoding='utf-8') as f:
|
||||
f.write(u'# Generated by fuel-agent during provisioning:\n'
|
||||
u'source-directory /etc/network/interfaces.d\n')
|
||||
with open(chroot + ifcfg_path, 'wt', encoding='utf-8') as f:
|
||||
f.write(u'# Generated by fuel-agent during provisioning:\n'
|
||||
u'auto {iface}\n'
|
||||
u'iface {iface} inet static\n'
|
||||
u'\taddress {ip}\n'
|
||||
u'\tnetmask {netmask}\n'
|
||||
u'\tgateway {gw}\n'.format(iface=iface,
|
||||
ip=ip,
|
||||
netmask=netmask,
|
||||
gw=gw))
|
||||
|
||||
|
||||
def configure_admin_nic_centos(chroot, iface, ip, netmask, gw):
|
||||
ifcfg_path = '/etc/sysconfig/network-scripts/ifcfg-{0}'.format(iface)
|
||||
with open(chroot + ifcfg_path, 'wt', encoding='utf-8') as f:
|
||||
f.write(u'# Generated by fuel-agent during provisioning:\n'
|
||||
u'DEVICE={iface}\n'
|
||||
u'IPADDR={ip}\n'
|
||||
u'NETMASK={netmask}\n'
|
||||
u'BOOTPROTO=none\n'
|
||||
u'ONBOOT=yes\n'
|
||||
u'USERCTL=no\n'.format(iface=iface, ip=ip, netmask=netmask))
|
||||
with open(chroot + '/etc/sysconfig/network', 'at', encoding='utf-8') as f:
|
||||
f.write(u'GATEWAY="{gw}"\n'.format(gw=gw))
|
Loading…
Reference in New Issue