bareon/bareon/tests/test_manager.py
Nikita Zubkov 10687832f2 Get root password for build image from settings
Image building process reads from settings hashed version of root
password and apply it instead of default.

Conflicts:

	bareon/drivers/data/nailgun.py
	bareon/drivers/deploy/nailgun.py
	bareon/utils/utils.py
	fuel_agent/tests/test_manager.py

Change-Id: Ibb614ddd1973c8fae25dae8217d207ffc92f1b15
Partial-Bug: #1537496
Depends-On: I2092bfca78fb721a8df3c8c6e4e6fd18e64ba353
2016-06-14 18:18:24 +03:00

281 lines
13 KiB
Python

# Copyright 2014 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 os
import signal
from oslo_config import cfg
import six
import unittest2
from bareon.drivers.data import nailgun as nailgun_data
from bareon.drivers.deploy import nailgun as nailgun_deploy
from bareon import objects
from bareon.utils import utils
if six.PY2:
import mock
elif six.PY3:
import unittest.mock as mock
CONF = cfg.CONF
class TestImageBuild(unittest2.TestCase):
@mock.patch('yaml.load')
@mock.patch.object(utils, 'init_http_request')
@mock.patch.object(utils, 'get_driver')
def setUp(self, mock_driver, mock_http, mock_yaml):
super(self.__class__, self).setUp()
mock_driver.return_value = nailgun_data.NailgunBuildImage
# TEST_ROOT_PASSWORD = crypt.crypt('qwerty')
self.TEST_ROOT_PASSWORD = ('$6$KyOsgFgf9cLbGNST$Ej0Usihfy7W/WT2H0z0mC'
'1DapC/IUpA0jF.Fs83mFIdkGYHL9IOYykRCjfssH.'
'YL4lHbmrvOd/6TIfiyh1hDY1')
image_conf = {
"image_data": {
"/": {
"container": "gzip",
"format": "ext4",
"uri": "http:///centos_65_x86_64.img.gz",
},
},
"output": "/var/www/nailgun/targetimages",
"repos": [
{
"name": "repo",
"uri": "http://some",
'type': 'deb',
'suite': '/',
'section': '',
'priority': 1001
}
],
"codename": "trusty",
"hashed_root_password": self.TEST_ROOT_PASSWORD,
}
self.mgr = nailgun_deploy.Manager(
nailgun_data.NailgunBuildImage(image_conf))
@mock.patch.object(nailgun_deploy.Manager, '_set_apt_repos')
@mock.patch.object(nailgun_deploy, 'bu', autospec=True)
@mock.patch.object(nailgun_deploy, 'fu', autospec=True)
@mock.patch.object(nailgun_deploy, 'utils', autospec=True)
@mock.patch.object(nailgun_deploy, 'os', autospec=True)
@mock.patch.object(nailgun_deploy.shutil, 'move')
@mock.patch.object(nailgun_deploy, 'open', create=True,
new_callable=mock.mock_open)
@mock.patch.object(nailgun_deploy.yaml, 'safe_dump')
@mock.patch.object(nailgun_deploy.Manager, 'mount_target')
@mock.patch.object(nailgun_deploy.Manager, 'umount_target')
def test_do_build_image(self, mock_umount_target, mock_mount_target,
mock_yaml_dump, mock_open, mock_shutil_move,
mock_os, mock_utils,
mock_fu, mock_bu, mock_set_apt_repos):
loops = [objects.Loop(), objects.Loop()]
self.mgr.driver._image_scheme = objects.ImageScheme([
objects.Image('file:///fake/img.img.gz', loops[0], 'ext4', 'gzip'),
objects.Image('file:///fake/img-boot.img.gz',
loops[1], 'ext2', 'gzip')])
self.mgr.driver._partition_scheme = objects.PartitionScheme()
self.mgr.driver.partition_scheme.add_fs(
device=loops[0], mount='/', fs_type='ext4')
self.mgr.driver.partition_scheme.add_fs(
device=loops[1], mount='/boot', fs_type='ext2')
self.mgr.driver.metadata_uri = 'file:///fake/img.yaml'
self.mgr.driver._operating_system = objects.Ubuntu(
repos=[
objects.DEBRepo('ubuntu', 'http://fakeubuntu',
'trusty', 'fakesection', priority=900),
objects.DEBRepo('ubuntu_zero', 'http://fakeubuntu_zero',
'trusty', 'fakesection', priority=None),
objects.DEBRepo('mos', 'http://fakemos',
'mosX.Y', 'fakesection', priority=1000)],
packages=['fakepackage1', 'fakepackage2'],
user_accounts=[
objects.User(name='root', password=None, homedir='/root',
hashed_password=self.TEST_ROOT_PASSWORD)])
self.mgr.driver.operating_system.proxies = objects.RepoProxies(
proxies={'fake': 'fake'},
direct_repo_addr_list='fake_addr')
self.mgr.driver.operating_system.minor = 4
self.mgr.driver.operating_system.major = 14
mock_os.path.exists.return_value = False
mock_os.path.join.return_value = '/tmp/imgdir/proc'
mock_os.path.basename.side_effect = ['img.img.gz', 'img-boot.img.gz']
mock_bu.create_sparse_tmp_file.side_effect = \
['/tmp/img', '/tmp/img-boot']
mock_bu.attach_file_to_free_loop_device.side_effect = [
'/dev/loop0', '/dev/loop1']
mock_bu.mkdtemp_smart.return_value = '/tmp/imgdir'
getsize_side = [20, 2, 10, 1]
mock_os.path.getsize.side_effect = getsize_side
md5_side = ['fakemd5_raw', 'fakemd5_gzip',
'fakemd5_raw_boot', 'fakemd5_gzip_boot']
mock_utils.calculate_md5.side_effect = md5_side
mock_bu.containerize.side_effect = ['/tmp/img.gz', '/tmp/img-boot.gz']
mock_bu.stop_chrooted_processes.side_effect = [
False, True, False, True]
metadata = {'os': {'name': 'Ubuntu', 'major': 14, 'minor': 4},
'packages': self.mgr.driver.operating_system.packages}
self.mgr.do_build_image()
self.assertEqual(
[mock.call('/fake/img.img.gz'),
mock.call('/fake/img-boot.img.gz')],
mock_os.path.exists.call_args_list)
self.assertEqual([mock.call(dir=CONF.image_build_dir,
suffix=CONF.image_build_suffix,
size=CONF.sparse_file_size)] * 2,
mock_bu.create_sparse_tmp_file.call_args_list)
self.assertEqual(
[mock.call(
'/tmp/img',
loop_device_major_number=CONF.loop_device_major_number,
max_loop_devices_count=CONF.max_loop_devices_count,
max_attempts=CONF.max_allowed_attempts_attach_image),
mock.call(
'/tmp/img-boot',
loop_device_major_number=CONF.loop_device_major_number,
max_loop_devices_count=CONF.max_loop_devices_count,
max_attempts=CONF.max_allowed_attempts_attach_image)
],
mock_bu.attach_file_to_free_loop_device.call_args_list)
self.assertEqual([mock.call(fs_type='ext4', fs_options='',
fs_label='', dev='/dev/loop0'),
mock.call(fs_type='ext2', fs_options='',
fs_label='', dev='/dev/loop1')],
mock_fu.make_fs.call_args_list)
mock_bu.mkdtemp_smart.assert_called_once_with(
CONF.image_build_dir, CONF.image_build_suffix)
mock_mount_target.assert_called_once_with(
'/tmp/imgdir', treat_mtab=False, pseudo=False)
self.assertEqual([mock.call('/tmp/imgdir')] * 2,
mock_bu.suppress_services_start.call_args_list)
mock_bu.run_debootstrap.assert_called_once_with(
uri='http://fakeubuntu', suite='trusty', chroot='/tmp/imgdir',
attempts=CONF.fetch_packages_attempts,
proxies={'fake': 'fake'}, direct_repo_addr='fake_addr')
mock_bu.set_apt_get_env.assert_called_once_with()
mock_bu.pre_apt_get.assert_called_once_with(
'/tmp/imgdir', allow_unsigned_file=CONF.allow_unsigned_file,
force_ipv4_file=CONF.force_ipv4_file, proxies={'fake': 'fake'},
direct_repo_addr='fake_addr')
driver_os = self.mgr.driver.operating_system
mock_set_apt_repos.assert_called_with(
'/tmp/imgdir',
driver_os.repos,
proxies=driver_os.proxies.proxies,
direct_repo_addrs=driver_os.proxies.direct_repo_addr_list
)
mock_utils.makedirs_if_not_exists.assert_called_once_with(
'/tmp/imgdir/proc')
self.assertEqual([
mock.call('tune2fs', '-O', '^has_journal', '/dev/loop0'),
mock.call('tune2fs', '-O', 'has_journal', '/dev/loop0')],
mock_utils.execute.call_args_list)
mock_fu.mount_bind.assert_called_once_with('/tmp/imgdir', '/proc')
mock_bu.populate_basic_dev.assert_called_once_with('/tmp/imgdir')
mock_bu.run_apt_get.assert_called_once_with(
'/tmp/imgdir', packages=['fakepackage1', 'fakepackage2'],
attempts=CONF.fetch_packages_attempts)
mock_bu.do_post_inst.assert_called_once_with(
'/tmp/imgdir',
hashed_root_password=self.TEST_ROOT_PASSWORD,
allow_unsigned_file=CONF.allow_unsigned_file,
force_ipv4_file=CONF.force_ipv4_file)
signal_calls = mock_bu.stop_chrooted_processes.call_args_list
self.assertEqual(2 * [mock.call('/tmp/imgdir', signal=signal.SIGTERM),
mock.call('/tmp/imgdir', signal=signal.SIGKILL)],
signal_calls)
self.assertEqual(
[mock.call('/tmp/imgdir/proc')] * 2,
mock_fu.umount_fs.call_args_list)
self.assertEqual(
[mock.call(
'/tmp/imgdir', pseudo=False)] * 2,
mock_umount_target.call_args_list)
self.assertEqual(
[mock.call('/dev/loop0'), mock.call('/dev/loop1')] * 2,
mock_bu.deattach_loop.call_args_list)
self.assertEqual([mock.call('/tmp/img'), mock.call('/tmp/img-boot')],
mock_bu.shrink_sparse_file.call_args_list)
self.assertEqual([mock.call('/tmp/img'),
mock.call('/fake/img.img.gz'),
mock.call('/tmp/img-boot'),
mock.call('/fake/img-boot.img.gz')],
mock_os.path.getsize.call_args_list)
self.assertEqual([mock.call('/tmp/img', 20),
mock.call('/fake/img.img.gz', 2),
mock.call('/tmp/img-boot', 10),
mock.call('/fake/img-boot.img.gz', 1)],
mock_utils.calculate_md5.call_args_list)
self.assertEqual([mock.call('/tmp/img', 'gzip',
chunk_size=CONF.data_chunk_size),
mock.call('/tmp/img-boot', 'gzip',
chunk_size=CONF.data_chunk_size)],
mock_bu.containerize.call_args_list)
mock_open.assert_called_once_with('/fake/img.yaml', 'wt',
encoding='utf-8')
self.assertEqual(
[mock.call('/tmp/img.gz', '/fake/img.img.gz'),
mock.call('/tmp/img-boot.gz', '/fake/img-boot.img.gz')],
mock_shutil_move.call_args_list)
for repo in self.mgr.driver.operating_system.repos:
metadata.setdefault('repos', []).append({
'type': 'deb',
'name': repo.name,
'uri': repo.uri,
'suite': repo.suite,
'section': repo.section,
'priority': repo.priority,
'meta': repo.meta})
metadata['images'] = [
{
'raw_md5': md5_side[0],
'raw_size': getsize_side[0],
'raw_name': None,
'container_name':
os.path.basename(
self.mgr.driver.image_scheme.images[0].uri.split(
'file://', 1)[1]),
'container_md5': md5_side[1],
'container_size': getsize_side[1],
'container': self.mgr.driver.image_scheme.images[0].container,
'format': self.mgr.driver.image_scheme.images[0].format
},
{
'raw_md5': md5_side[2],
'raw_size': getsize_side[2],
'raw_name': None,
'container_name':
os.path.basename(
self.mgr.driver.image_scheme.images[1].uri.split(
'file://', 1)[1]),
'container_md5': md5_side[3],
'container_size': getsize_side[3],
'container': self.mgr.driver.image_scheme.images[1].container,
'format': self.mgr.driver.image_scheme.images[1].format
}
]
mock_yaml_dump.assert_called_once_with(metadata, stream=mock_open())