|
Packit Service |
a04d08 |
# Copyright (C) 2016 Canonical Ltd.
|
|
Packit Service |
a04d08 |
#
|
|
Packit Service |
a04d08 |
# Author: Scott Moser <scott.moser@canonical.com>
|
|
Packit Service |
a04d08 |
#
|
|
Packit Service |
a04d08 |
# This file is part of cloud-init. See LICENSE file for license information.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
import base64
|
|
Packit Service |
a04d08 |
import os
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
from collections import OrderedDict
|
|
Packit Service |
a04d08 |
from textwrap import dedent
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
751c4a |
from cloudinit import subp
|
|
Packit Service |
a04d08 |
from cloudinit import util
|
|
Packit Service |
a04d08 |
from cloudinit.tests.helpers import CiTestCase, mock, wrap_and_call
|
|
Packit Service |
a04d08 |
from cloudinit.helpers import Paths
|
|
Packit Service |
a04d08 |
from cloudinit.sources import DataSourceOVF as dsovf
|
|
Packit Service |
a04d08 |
from cloudinit.sources.helpers.vmware.imc.config_custom_script import (
|
|
Packit Service |
a04d08 |
CustomScriptNotFound)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
MPATH = 'cloudinit.sources.DataSourceOVF.'
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
NOT_FOUND = None
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
OVF_ENV_CONTENT = """
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
Packit Service |
a04d08 |
xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
|
|
Packit Service |
a04d08 |
xsi:schemaLocation="http://schemas.dmtf.org/ovf/environment/1 ../dsp8027.xsd"
|
|
Packit Service |
a04d08 |
oe:id="WebTier">
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
<oe:PlatformSection>
|
|
Packit Service |
a04d08 |
<Kind>ESX Server</Kind>
|
|
Packit Service |
a04d08 |
<Version>3.0.1</Version>
|
|
Packit Service |
a04d08 |
<Vendor>VMware, Inc.</Vendor>
|
|
Packit Service |
a04d08 |
<Locale>en_US</Locale>
|
|
Packit Service |
a04d08 |
</oe:PlatformSection>
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
<PropertySection>
|
|
Packit Service |
a04d08 |
{properties}
|
|
Packit Service |
a04d08 |
</PropertySection>
|
|
Packit Service |
a04d08 |
</Environment>
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def fill_properties(props, template=OVF_ENV_CONTENT):
|
|
Packit Service |
a04d08 |
lines = []
|
|
Packit Service |
a04d08 |
prop_tmpl = '<Property oe:key="{key}" oe:value="{val}"/>'
|
|
Packit Service |
a04d08 |
for key, val in props.items():
|
|
Packit Service |
a04d08 |
lines.append(prop_tmpl.format(key=key, val=val))
|
|
Packit Service |
a04d08 |
indent = " "
|
|
Packit Service |
751c4a |
properties = ''.join([indent + line + "\n" for line in lines])
|
|
Packit Service |
a04d08 |
return template.format(properties=properties)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestReadOvfEnv(CiTestCase):
|
|
Packit Service |
a04d08 |
def test_with_b64_userdata(self):
|
|
Packit Service |
a04d08 |
user_data = "#!/bin/sh\necho hello world\n"
|
|
Packit Service |
a04d08 |
user_data_b64 = base64.b64encode(user_data.encode()).decode()
|
|
Packit Service |
a04d08 |
props = {"user-data": user_data_b64, "password": "passw0rd",
|
|
Packit Service |
a04d08 |
"instance-id": "inst-001"}
|
|
Packit Service |
a04d08 |
env = fill_properties(props)
|
|
Packit Service |
a04d08 |
md, ud, cfg = dsovf.read_ovf_environment(env)
|
|
Packit Service |
a04d08 |
self.assertEqual({"instance-id": "inst-001"}, md)
|
|
Packit Service |
a04d08 |
self.assertEqual(user_data.encode(), ud)
|
|
Packit Service |
a04d08 |
self.assertEqual({'password': "passw0rd"}, cfg)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_with_non_b64_userdata(self):
|
|
Packit Service |
a04d08 |
user_data = "my-user-data"
|
|
Packit Service |
a04d08 |
props = {"user-data": user_data, "instance-id": "inst-001"}
|
|
Packit Service |
a04d08 |
env = fill_properties(props)
|
|
Packit Service |
a04d08 |
md, ud, cfg = dsovf.read_ovf_environment(env)
|
|
Packit Service |
a04d08 |
self.assertEqual({"instance-id": "inst-001"}, md)
|
|
Packit Service |
a04d08 |
self.assertEqual(user_data.encode(), ud)
|
|
Packit Service |
a04d08 |
self.assertEqual({}, cfg)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_with_no_userdata(self):
|
|
Packit Service |
a04d08 |
props = {"password": "passw0rd", "instance-id": "inst-001"}
|
|
Packit Service |
a04d08 |
env = fill_properties(props)
|
|
Packit Service |
a04d08 |
md, ud, cfg = dsovf.read_ovf_environment(env)
|
|
Packit Service |
a04d08 |
self.assertEqual({"instance-id": "inst-001"}, md)
|
|
Packit Service |
a04d08 |
self.assertEqual({'password': "passw0rd"}, cfg)
|
|
Packit Service |
a04d08 |
self.assertIsNone(ud)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestMarkerFiles(CiTestCase):
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def setUp(self):
|
|
Packit Service |
a04d08 |
super(TestMarkerFiles, self).setUp()
|
|
Packit Service |
a04d08 |
self.tdir = self.tmp_dir()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_false_when_markerid_none(self):
|
|
Packit Service |
a04d08 |
"""Return False when markerid provided is None."""
|
|
Packit Service |
a04d08 |
self.assertFalse(
|
|
Packit Service |
a04d08 |
dsovf.check_marker_exists(markerid=None, marker_dir=self.tdir))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_markerid_file_exist(self):
|
|
Packit Service |
a04d08 |
"""Return False when markerid file path does not exist,
|
|
Packit Service |
a04d08 |
True otherwise."""
|
|
Packit Service |
a04d08 |
self.assertFalse(
|
|
Packit Service |
a04d08 |
dsovf.check_marker_exists('123', self.tdir))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
marker_file = self.tmp_path('.markerfile-123.txt', self.tdir)
|
|
Packit Service |
a04d08 |
util.write_file(marker_file, '')
|
|
Packit Service |
a04d08 |
self.assertTrue(
|
|
Packit Service |
a04d08 |
dsovf.check_marker_exists('123', self.tdir)
|
|
Packit Service |
a04d08 |
)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_marker_file_setup(self):
|
|
Packit Service |
a04d08 |
"""Test creation of marker files."""
|
|
Packit Service |
a04d08 |
markerfilepath = self.tmp_path('.markerfile-hi.txt', self.tdir)
|
|
Packit Service |
a04d08 |
self.assertFalse(os.path.exists(markerfilepath))
|
|
Packit Service |
a04d08 |
dsovf.setup_marker_files(markerid='hi', marker_dir=self.tdir)
|
|
Packit Service |
a04d08 |
self.assertTrue(os.path.exists(markerfilepath))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestDatasourceOVF(CiTestCase):
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
with_logs = True
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def setUp(self):
|
|
Packit Service |
a04d08 |
super(TestDatasourceOVF, self).setUp()
|
|
Packit Service |
a04d08 |
self.datasource = dsovf.DataSourceOVF
|
|
Packit Service |
a04d08 |
self.tdir = self.tmp_dir()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_false_on_none_dmi_data(self):
|
|
Packit Service |
a04d08 |
"""When dmi for system-product-name is None, get_data returns False."""
|
|
Packit Service |
a04d08 |
paths = Paths({'cloud_dir': self.tdir})
|
|
Packit Service |
a04d08 |
ds = self.datasource(sys_cfg={}, distro={}, paths=paths)
|
|
Packit Service |
a04d08 |
retcode = wrap_and_call(
|
|
Packit Service |
a04d08 |
'cloudinit.sources.DataSourceOVF',
|
|
Packit Service |
a04d08 |
{'util.read_dmi_data': None,
|
|
Packit Service |
a04d08 |
'transport_iso9660': NOT_FOUND,
|
|
Packit Service |
a04d08 |
'transport_vmware_guestinfo': NOT_FOUND},
|
|
Packit Service |
a04d08 |
ds.get_data)
|
|
Packit Service |
a04d08 |
self.assertFalse(retcode, 'Expected False return from ds.get_data')
|
|
Packit Service |
a04d08 |
self.assertIn(
|
|
Packit Service |
a04d08 |
'DEBUG: No system-product-name found', self.logs.getvalue())
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_no_vmware_customization_disabled(self):
|
|
Packit Service |
a04d08 |
"""When vmware customization is disabled via sys_cfg log a message."""
|
|
Packit Service |
a04d08 |
paths = Paths({'cloud_dir': self.tdir})
|
|
Packit Service |
a04d08 |
ds = self.datasource(
|
|
Packit Service |
a04d08 |
sys_cfg={'disable_vmware_customization': True}, distro={},
|
|
Packit Service |
a04d08 |
paths=paths)
|
|
Packit Service |
a04d08 |
retcode = wrap_and_call(
|
|
Packit Service |
a04d08 |
'cloudinit.sources.DataSourceOVF',
|
|
Packit Service |
a04d08 |
{'util.read_dmi_data': 'vmware',
|
|
Packit Service |
a04d08 |
'transport_iso9660': NOT_FOUND,
|
|
Packit Service |
a04d08 |
'transport_vmware_guestinfo': NOT_FOUND},
|
|
Packit Service |
a04d08 |
ds.get_data)
|
|
Packit Service |
a04d08 |
self.assertFalse(retcode, 'Expected False return from ds.get_data')
|
|
Packit Service |
a04d08 |
self.assertIn(
|
|
Packit Service |
a04d08 |
'DEBUG: Customization for VMware platform is disabled.',
|
|
Packit Service |
a04d08 |
self.logs.getvalue())
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_vmware_customization_disabled(self):
|
|
Packit Service |
a04d08 |
"""When cloud-init workflow for vmware is enabled via sys_cfg log a
|
|
Packit Service |
a04d08 |
message.
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
paths = Paths({'cloud_dir': self.tdir})
|
|
Packit Service |
a04d08 |
ds = self.datasource(
|
|
Packit Service |
a04d08 |
sys_cfg={'disable_vmware_customization': False}, distro={},
|
|
Packit Service |
a04d08 |
paths=paths)
|
|
Packit Service |
a04d08 |
conf_file = self.tmp_path('test-cust', self.tdir)
|
|
Packit Service |
a04d08 |
conf_content = dedent("""\
|
|
Packit Service |
a04d08 |
[CUSTOM-SCRIPT]
|
|
Packit Service |
a04d08 |
SCRIPT-NAME = test-script
|
|
Packit Service |
a04d08 |
[MISC]
|
|
Packit Service |
a04d08 |
MARKER-ID = 12345345
|
|
Packit Service |
a04d08 |
""")
|
|
Packit Service |
a04d08 |
util.write_file(conf_file, conf_content)
|
|
Packit Service |
a04d08 |
with mock.patch(MPATH + 'get_tools_config', return_value='true'):
|
|
Packit Service |
a04d08 |
with self.assertRaises(CustomScriptNotFound) as context:
|
|
Packit Service |
a04d08 |
wrap_and_call(
|
|
Packit Service |
a04d08 |
'cloudinit.sources.DataSourceOVF',
|
|
Packit Service |
a04d08 |
{'util.read_dmi_data': 'vmware',
|
|
Packit Service |
a04d08 |
'util.del_dir': True,
|
|
Packit Service |
a04d08 |
'search_file': self.tdir,
|
|
Packit Service |
a04d08 |
'wait_for_imc_cfg_file': conf_file,
|
|
Packit Service |
a04d08 |
'get_nics_to_enable': ''},
|
|
Packit Service |
a04d08 |
ds.get_data)
|
|
Packit Service |
a04d08 |
customscript = self.tmp_path('test-script', self.tdir)
|
|
Packit Service |
a04d08 |
self.assertIn('Script %s not found!!' % customscript,
|
|
Packit Service |
a04d08 |
str(context.exception))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_cust_script_disabled(self):
|
|
Packit Service |
a04d08 |
"""If custom script is disabled by VMware tools configuration,
|
|
Packit Service |
a04d08 |
raise a RuntimeError.
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
paths = Paths({'cloud_dir': self.tdir})
|
|
Packit Service |
a04d08 |
ds = self.datasource(
|
|
Packit Service |
a04d08 |
sys_cfg={'disable_vmware_customization': False}, distro={},
|
|
Packit Service |
a04d08 |
paths=paths)
|
|
Packit Service |
a04d08 |
# Prepare the conf file
|
|
Packit Service |
a04d08 |
conf_file = self.tmp_path('test-cust', self.tdir)
|
|
Packit Service |
a04d08 |
conf_content = dedent("""\
|
|
Packit Service |
a04d08 |
[CUSTOM-SCRIPT]
|
|
Packit Service |
a04d08 |
SCRIPT-NAME = test-script
|
|
Packit Service |
a04d08 |
[MISC]
|
|
Packit Service |
a04d08 |
MARKER-ID = 12345346
|
|
Packit Service |
a04d08 |
""")
|
|
Packit Service |
a04d08 |
util.write_file(conf_file, conf_content)
|
|
Packit Service |
a04d08 |
# Prepare the custom sript
|
|
Packit Service |
a04d08 |
customscript = self.tmp_path('test-script', self.tdir)
|
|
Packit Service |
a04d08 |
util.write_file(customscript, "This is the post cust script")
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
with mock.patch(MPATH + 'get_tools_config', return_value='invalid'):
|
|
Packit Service |
a04d08 |
with mock.patch(MPATH + 'set_customization_status',
|
|
Packit Service |
a04d08 |
return_value=('msg', b'')):
|
|
Packit Service |
a04d08 |
with self.assertRaises(RuntimeError) as context:
|
|
Packit Service |
a04d08 |
wrap_and_call(
|
|
Packit Service |
a04d08 |
'cloudinit.sources.DataSourceOVF',
|
|
Packit Service |
a04d08 |
{'util.read_dmi_data': 'vmware',
|
|
Packit Service |
a04d08 |
'util.del_dir': True,
|
|
Packit Service |
a04d08 |
'search_file': self.tdir,
|
|
Packit Service |
a04d08 |
'wait_for_imc_cfg_file': conf_file,
|
|
Packit Service |
a04d08 |
'get_nics_to_enable': ''},
|
|
Packit Service |
a04d08 |
ds.get_data)
|
|
Packit Service |
a04d08 |
self.assertIn('Custom script is disabled by VM Administrator',
|
|
Packit Service |
a04d08 |
str(context.exception))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
751c4a |
def test_get_data_cust_script_enabled(self):
|
|
Packit Service |
751c4a |
"""If custom script is enabled by VMware tools configuration,
|
|
Packit Service |
751c4a |
execute the script.
|
|
Packit Service |
751c4a |
"""
|
|
Packit Service |
751c4a |
paths = Paths({'cloud_dir': self.tdir})
|
|
Packit Service |
751c4a |
ds = self.datasource(
|
|
Packit Service |
751c4a |
sys_cfg={'disable_vmware_customization': False}, distro={},
|
|
Packit Service |
751c4a |
paths=paths)
|
|
Packit Service |
751c4a |
# Prepare the conf file
|
|
Packit Service |
751c4a |
conf_file = self.tmp_path('test-cust', self.tdir)
|
|
Packit Service |
751c4a |
conf_content = dedent("""\
|
|
Packit Service |
751c4a |
[CUSTOM-SCRIPT]
|
|
Packit Service |
751c4a |
SCRIPT-NAME = test-script
|
|
Packit Service |
751c4a |
[MISC]
|
|
Packit Service |
751c4a |
MARKER-ID = 12345346
|
|
Packit Service |
751c4a |
""")
|
|
Packit Service |
751c4a |
util.write_file(conf_file, conf_content)
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
# Mock custom script is enabled by return true when calling
|
|
Packit Service |
751c4a |
# get_tools_config
|
|
Packit Service |
751c4a |
with mock.patch(MPATH + 'get_tools_config', return_value="true"):
|
|
Packit Service |
751c4a |
with mock.patch(MPATH + 'set_customization_status',
|
|
Packit Service |
751c4a |
return_value=('msg', b'')):
|
|
Packit Service |
751c4a |
with self.assertRaises(CustomScriptNotFound) as context:
|
|
Packit Service |
751c4a |
wrap_and_call(
|
|
Packit Service |
751c4a |
'cloudinit.sources.DataSourceOVF',
|
|
Packit Service |
751c4a |
{'util.read_dmi_data': 'vmware',
|
|
Packit Service |
751c4a |
'util.del_dir': True,
|
|
Packit Service |
751c4a |
'search_file': self.tdir,
|
|
Packit Service |
751c4a |
'wait_for_imc_cfg_file': conf_file,
|
|
Packit Service |
751c4a |
'get_nics_to_enable': ''},
|
|
Packit Service |
751c4a |
ds.get_data)
|
|
Packit Service |
751c4a |
# Verify custom script is trying to be executed
|
|
Packit Service |
751c4a |
customscript = self.tmp_path('test-script', self.tdir)
|
|
Packit Service |
751c4a |
self.assertIn('Script %s not found!!' % customscript,
|
|
Packit Service |
751c4a |
str(context.exception))
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
def test_get_data_force_run_post_script_is_yes(self):
|
|
Packit Service |
751c4a |
"""If DEFAULT-RUN-POST-CUST-SCRIPT is yes, custom script could run if
|
|
Packit Service |
751c4a |
enable-custom-scripts is not defined in VM Tools configuration
|
|
Packit Service |
751c4a |
"""
|
|
Packit Service |
751c4a |
paths = Paths({'cloud_dir': self.tdir})
|
|
Packit Service |
751c4a |
ds = self.datasource(
|
|
Packit Service |
751c4a |
sys_cfg={'disable_vmware_customization': False}, distro={},
|
|
Packit Service |
751c4a |
paths=paths)
|
|
Packit Service |
751c4a |
# Prepare the conf file
|
|
Packit Service |
751c4a |
conf_file = self.tmp_path('test-cust', self.tdir)
|
|
Packit Service |
751c4a |
# set DEFAULT-RUN-POST-CUST-SCRIPT = yes so that enable-custom-scripts
|
|
Packit Service |
751c4a |
# default value is TRUE
|
|
Packit Service |
751c4a |
conf_content = dedent("""\
|
|
Packit Service |
751c4a |
[CUSTOM-SCRIPT]
|
|
Packit Service |
751c4a |
SCRIPT-NAME = test-script
|
|
Packit Service |
751c4a |
[MISC]
|
|
Packit Service |
751c4a |
MARKER-ID = 12345346
|
|
Packit Service |
751c4a |
DEFAULT-RUN-POST-CUST-SCRIPT = yes
|
|
Packit Service |
751c4a |
""")
|
|
Packit Service |
751c4a |
util.write_file(conf_file, conf_content)
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
# Mock get_tools_config(section, key, defaultVal) to return
|
|
Packit Service |
751c4a |
# defaultVal
|
|
Packit Service |
751c4a |
def my_get_tools_config(*args, **kwargs):
|
|
Packit Service |
751c4a |
return args[2]
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
with mock.patch(MPATH + 'get_tools_config',
|
|
Packit Service |
751c4a |
side_effect=my_get_tools_config):
|
|
Packit Service |
751c4a |
with mock.patch(MPATH + 'set_customization_status',
|
|
Packit Service |
751c4a |
return_value=('msg', b'')):
|
|
Packit Service |
751c4a |
with self.assertRaises(CustomScriptNotFound) as context:
|
|
Packit Service |
751c4a |
wrap_and_call(
|
|
Packit Service |
751c4a |
'cloudinit.sources.DataSourceOVF',
|
|
Packit Service |
751c4a |
{'util.read_dmi_data': 'vmware',
|
|
Packit Service |
751c4a |
'util.del_dir': True,
|
|
Packit Service |
751c4a |
'search_file': self.tdir,
|
|
Packit Service |
751c4a |
'wait_for_imc_cfg_file': conf_file,
|
|
Packit Service |
751c4a |
'get_nics_to_enable': ''},
|
|
Packit Service |
751c4a |
ds.get_data)
|
|
Packit Service |
751c4a |
# Verify custom script still runs although it is
|
|
Packit Service |
751c4a |
# disabled by VMware Tools
|
|
Packit Service |
751c4a |
customscript = self.tmp_path('test-script', self.tdir)
|
|
Packit Service |
751c4a |
self.assertIn('Script %s not found!!' % customscript,
|
|
Packit Service |
751c4a |
str(context.exception))
|
|
Packit Service |
751c4a |
|
|
Packit Service |
a04d08 |
def test_get_data_non_vmware_seed_platform_info(self):
|
|
Packit Service |
a04d08 |
"""Platform info properly reports when on non-vmware platforms."""
|
|
Packit Service |
a04d08 |
paths = Paths({'cloud_dir': self.tdir, 'run_dir': self.tdir})
|
|
Packit Service |
a04d08 |
# Write ovf-env.xml seed file
|
|
Packit Service |
a04d08 |
seed_dir = self.tmp_path('seed', dir=self.tdir)
|
|
Packit Service |
a04d08 |
ovf_env = self.tmp_path('ovf-env.xml', dir=seed_dir)
|
|
Packit Service |
a04d08 |
util.write_file(ovf_env, OVF_ENV_CONTENT)
|
|
Packit Service |
a04d08 |
ds = self.datasource(sys_cfg={}, distro={}, paths=paths)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.assertEqual('ovf', ds.cloud_name)
|
|
Packit Service |
a04d08 |
self.assertEqual('ovf', ds.platform_type)
|
|
Packit Service |
a04d08 |
with mock.patch(MPATH + 'util.read_dmi_data', return_value='!VMware'):
|
|
Packit Service |
a04d08 |
with mock.patch(MPATH + 'transport_vmware_guestinfo') as m_guestd:
|
|
Packit Service |
a04d08 |
with mock.patch(MPATH + 'transport_iso9660') as m_iso9660:
|
|
Packit Service |
a04d08 |
m_iso9660.return_value = NOT_FOUND
|
|
Packit Service |
a04d08 |
m_guestd.return_value = NOT_FOUND
|
|
Packit Service |
a04d08 |
self.assertTrue(ds.get_data())
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'ovf (%s/seed/ovf-env.xml)' % self.tdir,
|
|
Packit Service |
a04d08 |
ds.subplatform)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_vmware_seed_platform_info(self):
|
|
Packit Service |
a04d08 |
"""Platform info properly reports when on VMware platform."""
|
|
Packit Service |
a04d08 |
paths = Paths({'cloud_dir': self.tdir, 'run_dir': self.tdir})
|
|
Packit Service |
a04d08 |
# Write ovf-env.xml seed file
|
|
Packit Service |
a04d08 |
seed_dir = self.tmp_path('seed', dir=self.tdir)
|
|
Packit Service |
a04d08 |
ovf_env = self.tmp_path('ovf-env.xml', dir=seed_dir)
|
|
Packit Service |
a04d08 |
util.write_file(ovf_env, OVF_ENV_CONTENT)
|
|
Packit Service |
a04d08 |
ds = self.datasource(sys_cfg={}, distro={}, paths=paths)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.assertEqual('ovf', ds.cloud_name)
|
|
Packit Service |
a04d08 |
self.assertEqual('ovf', ds.platform_type)
|
|
Packit Service |
a04d08 |
with mock.patch(MPATH + 'util.read_dmi_data', return_value='VMWare'):
|
|
Packit Service |
a04d08 |
with mock.patch(MPATH + 'transport_vmware_guestinfo') as m_guestd:
|
|
Packit Service |
a04d08 |
with mock.patch(MPATH + 'transport_iso9660') as m_iso9660:
|
|
Packit Service |
a04d08 |
m_iso9660.return_value = NOT_FOUND
|
|
Packit Service |
a04d08 |
m_guestd.return_value = NOT_FOUND
|
|
Packit Service |
a04d08 |
self.assertTrue(ds.get_data())
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'vmware (%s/seed/ovf-env.xml)' % self.tdir,
|
|
Packit Service |
a04d08 |
ds.subplatform)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestTransportIso9660(CiTestCase):
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def setUp(self):
|
|
Packit Service |
a04d08 |
super(TestTransportIso9660, self).setUp()
|
|
Packit Service |
a04d08 |
self.add_patch('cloudinit.util.find_devs_with',
|
|
Packit Service |
a04d08 |
'm_find_devs_with')
|
|
Packit Service |
a04d08 |
self.add_patch('cloudinit.util.mounts', 'm_mounts')
|
|
Packit Service |
a04d08 |
self.add_patch('cloudinit.util.mount_cb', 'm_mount_cb')
|
|
Packit Service |
a04d08 |
self.add_patch('cloudinit.sources.DataSourceOVF.get_ovf_env',
|
|
Packit Service |
a04d08 |
'm_get_ovf_env')
|
|
Packit Service |
a04d08 |
self.m_get_ovf_env.return_value = ('myfile', 'mycontent')
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_find_already_mounted(self):
|
|
Packit Service |
a04d08 |
"""Check we call get_ovf_env from on matching mounted devices"""
|
|
Packit Service |
a04d08 |
mounts = {
|
|
Packit Service |
a04d08 |
'/dev/sr9': {
|
|
Packit Service |
a04d08 |
'fstype': 'iso9660',
|
|
Packit Service |
a04d08 |
'mountpoint': 'wark/media/sr9',
|
|
Packit Service |
a04d08 |
'opts': 'ro',
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
self.m_mounts.return_value = mounts
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.assertEqual("mycontent", dsovf.transport_iso9660())
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_find_already_mounted_skips_non_iso9660(self):
|
|
Packit Service |
a04d08 |
"""Check we call get_ovf_env ignoring non iso9660"""
|
|
Packit Service |
a04d08 |
mounts = {
|
|
Packit Service |
a04d08 |
'/dev/xvdb': {
|
|
Packit Service |
a04d08 |
'fstype': 'vfat',
|
|
Packit Service |
a04d08 |
'mountpoint': 'wark/foobar',
|
|
Packit Service |
a04d08 |
'opts': 'defaults,noatime',
|
|
Packit Service |
a04d08 |
},
|
|
Packit Service |
a04d08 |
'/dev/xvdc': {
|
|
Packit Service |
a04d08 |
'fstype': 'iso9660',
|
|
Packit Service |
a04d08 |
'mountpoint': 'wark/media/sr9',
|
|
Packit Service |
a04d08 |
'opts': 'ro',
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
# We use an OrderedDict here to ensure we check xvdb before xvdc
|
|
Packit Service |
a04d08 |
# as we're not mocking the regex matching, however, if we place
|
|
Packit Service |
a04d08 |
# an entry in the results then we can be reasonably sure that
|
|
Packit Service |
a04d08 |
# we're skipping an entry which fails to match.
|
|
Packit Service |
a04d08 |
self.m_mounts.return_value = (
|
|
Packit Service |
a04d08 |
OrderedDict(sorted(mounts.items(), key=lambda t: t[0])))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.assertEqual("mycontent", dsovf.transport_iso9660())
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_find_already_mounted_matches_kname(self):
|
|
Packit Service |
a04d08 |
"""Check we dont regex match on basename of the device"""
|
|
Packit Service |
a04d08 |
mounts = {
|
|
Packit Service |
a04d08 |
'/dev/foo/bar/xvdc': {
|
|
Packit Service |
a04d08 |
'fstype': 'iso9660',
|
|
Packit Service |
a04d08 |
'mountpoint': 'wark/media/sr9',
|
|
Packit Service |
a04d08 |
'opts': 'ro',
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
a04d08 |
# we're skipping an entry which fails to match.
|
|
Packit Service |
a04d08 |
self.m_mounts.return_value = mounts
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.assertEqual(NOT_FOUND, dsovf.transport_iso9660())
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_mount_cb_called_on_blkdevs_with_iso9660(self):
|
|
Packit Service |
a04d08 |
"""Check we call mount_cb on blockdevs with iso9660 only"""
|
|
Packit Service |
a04d08 |
self.m_mounts.return_value = {}
|
|
Packit Service |
a04d08 |
self.m_find_devs_with.return_value = ['/dev/sr0']
|
|
Packit Service |
a04d08 |
self.m_mount_cb.return_value = ("myfile", "mycontent")
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.assertEqual("mycontent", dsovf.transport_iso9660())
|
|
Packit Service |
a04d08 |
self.m_mount_cb.assert_called_with(
|
|
Packit Service |
a04d08 |
"/dev/sr0", dsovf.get_ovf_env, mtype="iso9660")
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_mount_cb_called_on_blkdevs_with_iso9660_check_regex(self):
|
|
Packit Service |
a04d08 |
"""Check we call mount_cb on blockdevs with iso9660 and match regex"""
|
|
Packit Service |
a04d08 |
self.m_mounts.return_value = {}
|
|
Packit Service |
a04d08 |
self.m_find_devs_with.return_value = [
|
|
Packit Service |
a04d08 |
'/dev/abc', '/dev/my-cdrom', '/dev/sr0']
|
|
Packit Service |
a04d08 |
self.m_mount_cb.return_value = ("myfile", "mycontent")
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.assertEqual("mycontent", dsovf.transport_iso9660())
|
|
Packit Service |
a04d08 |
self.m_mount_cb.assert_called_with(
|
|
Packit Service |
a04d08 |
"/dev/sr0", dsovf.get_ovf_env, mtype="iso9660")
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_mount_cb_not_called_no_matches(self):
|
|
Packit Service |
a04d08 |
"""Check we don't call mount_cb if nothing matches"""
|
|
Packit Service |
a04d08 |
self.m_mounts.return_value = {}
|
|
Packit Service |
a04d08 |
self.m_find_devs_with.return_value = ['/dev/vg/myovf']
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.assertEqual(NOT_FOUND, dsovf.transport_iso9660())
|
|
Packit Service |
a04d08 |
self.assertEqual(0, self.m_mount_cb.call_count)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_mount_cb_called_require_iso_false(self):
|
|
Packit Service |
a04d08 |
"""Check we call mount_cb on blockdevs with require_iso=False"""
|
|
Packit Service |
a04d08 |
self.m_mounts.return_value = {}
|
|
Packit Service |
a04d08 |
self.m_find_devs_with.return_value = ['/dev/xvdz']
|
|
Packit Service |
a04d08 |
self.m_mount_cb.return_value = ("myfile", "mycontent")
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
"mycontent", dsovf.transport_iso9660(require_iso=False))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.m_mount_cb.assert_called_with(
|
|
Packit Service |
a04d08 |
"/dev/xvdz", dsovf.get_ovf_env, mtype=None)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_maybe_cdrom_device_none(self):
|
|
Packit Service |
a04d08 |
"""Test maybe_cdrom_device returns False for none/empty input"""
|
|
Packit Service |
a04d08 |
self.assertFalse(dsovf.maybe_cdrom_device(None))
|
|
Packit Service |
a04d08 |
self.assertFalse(dsovf.maybe_cdrom_device(''))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_maybe_cdrom_device_non_string_exception(self):
|
|
Packit Service |
a04d08 |
"""Test maybe_cdrom_device raises ValueError on non-string types"""
|
|
Packit Service |
a04d08 |
with self.assertRaises(ValueError):
|
|
Packit Service |
a04d08 |
dsovf.maybe_cdrom_device({'a': 'eleven'})
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_maybe_cdrom_device_false_on_multi_dir_paths(self):
|
|
Packit Service |
a04d08 |
"""Test maybe_cdrom_device is false on /dev[/.*]/* paths"""
|
|
Packit Service |
a04d08 |
self.assertFalse(dsovf.maybe_cdrom_device('/dev/foo/sr0'))
|
|
Packit Service |
a04d08 |
self.assertFalse(dsovf.maybe_cdrom_device('foo/sr0'))
|
|
Packit Service |
a04d08 |
self.assertFalse(dsovf.maybe_cdrom_device('../foo/sr0'))
|
|
Packit Service |
a04d08 |
self.assertFalse(dsovf.maybe_cdrom_device('../foo/sr0'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_maybe_cdrom_device_true_on_hd_partitions(self):
|
|
Packit Service |
a04d08 |
"""Test maybe_cdrom_device is false on /dev/hd[a-z][0-9]+ paths"""
|
|
Packit Service |
a04d08 |
self.assertTrue(dsovf.maybe_cdrom_device('/dev/hda1'))
|
|
Packit Service |
a04d08 |
self.assertTrue(dsovf.maybe_cdrom_device('hdz9'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_maybe_cdrom_device_true_on_valid_relative_paths(self):
|
|
Packit Service |
a04d08 |
"""Test maybe_cdrom_device normalizes paths"""
|
|
Packit Service |
a04d08 |
self.assertTrue(dsovf.maybe_cdrom_device('/dev/wark/../sr9'))
|
|
Packit Service |
a04d08 |
self.assertTrue(dsovf.maybe_cdrom_device('///sr0'))
|
|
Packit Service |
a04d08 |
self.assertTrue(dsovf.maybe_cdrom_device('/sr0'))
|
|
Packit Service |
a04d08 |
self.assertTrue(dsovf.maybe_cdrom_device('//dev//hda'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_maybe_cdrom_device_true_on_xvd_partitions(self):
|
|
Packit Service |
a04d08 |
"""Test maybe_cdrom_device returns true on xvd*"""
|
|
Packit Service |
a04d08 |
self.assertTrue(dsovf.maybe_cdrom_device('/dev/xvda'))
|
|
Packit Service |
a04d08 |
self.assertTrue(dsovf.maybe_cdrom_device('/dev/xvda1'))
|
|
Packit Service |
a04d08 |
self.assertTrue(dsovf.maybe_cdrom_device('xvdza1'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
751c4a |
@mock.patch(MPATH + "subp.which")
|
|
Packit Service |
751c4a |
@mock.patch(MPATH + "subp.subp")
|
|
Packit Service |
a04d08 |
class TestTransportVmwareGuestinfo(CiTestCase):
|
|
Packit Service |
a04d08 |
"""Test the com.vmware.guestInfo transport implemented in
|
|
Packit Service |
a04d08 |
transport_vmware_guestinfo."""
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
rpctool = 'vmware-rpctool'
|
|
Packit Service |
a04d08 |
with_logs = True
|
|
Packit Service |
a04d08 |
rpctool_path = '/not/important/vmware-rpctool'
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_without_vmware_rpctool_returns_notfound(self, m_subp, m_which):
|
|
Packit Service |
a04d08 |
m_which.return_value = None
|
|
Packit Service |
a04d08 |
self.assertEqual(NOT_FOUND, dsovf.transport_vmware_guestinfo())
|
|
Packit Service |
a04d08 |
self.assertEqual(0, m_subp.call_count,
|
|
Packit Service |
a04d08 |
"subp should not be called if no rpctool in path.")
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_notfound_on_exit_code_1(self, m_subp, m_which):
|
|
Packit Service |
a04d08 |
"""If vmware-rpctool exits 1, then must return not found."""
|
|
Packit Service |
a04d08 |
m_which.return_value = self.rpctool_path
|
|
Packit Service |
751c4a |
m_subp.side_effect = subp.ProcessExecutionError(
|
|
Packit Service |
a04d08 |
stdout="", stderr="No value found", exit_code=1, cmd=["unused"])
|
|
Packit Service |
a04d08 |
self.assertEqual(NOT_FOUND, dsovf.transport_vmware_guestinfo())
|
|
Packit Service |
a04d08 |
self.assertEqual(1, m_subp.call_count)
|
|
Packit Service |
a04d08 |
self.assertNotIn("WARNING", self.logs.getvalue(),
|
|
Packit Service |
a04d08 |
"exit code of 1 by rpctool should not cause warning.")
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_notfound_if_no_content_but_exit_zero(self, m_subp, m_which):
|
|
Packit Service |
a04d08 |
"""If vmware-rpctool exited 0 with no stdout is normal not-found.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
This isn't actually a case I've seen. normally on "not found",
|
|
Packit Service |
a04d08 |
rpctool would exit 1 with 'No value found' on stderr. But cover
|
|
Packit Service |
a04d08 |
the case where it exited 0 and just wrote nothing to stdout.
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
m_which.return_value = self.rpctool_path
|
|
Packit Service |
a04d08 |
m_subp.return_value = ('', '')
|
|
Packit Service |
a04d08 |
self.assertEqual(NOT_FOUND, dsovf.transport_vmware_guestinfo())
|
|
Packit Service |
a04d08 |
self.assertEqual(1, m_subp.call_count)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_notfound_and_warns_on_unexpected_exit_code(self, m_subp, m_which):
|
|
Packit Service |
a04d08 |
"""If vmware-rpctool exits non zero or 1, warnings should be logged."""
|
|
Packit Service |
a04d08 |
m_which.return_value = self.rpctool_path
|
|
Packit Service |
751c4a |
m_subp.side_effect = subp.ProcessExecutionError(
|
|
Packit Service |
a04d08 |
stdout=None, stderr="No value found", exit_code=2, cmd=["unused"])
|
|
Packit Service |
a04d08 |
self.assertEqual(NOT_FOUND, dsovf.transport_vmware_guestinfo())
|
|
Packit Service |
a04d08 |
self.assertEqual(1, m_subp.call_count)
|
|
Packit Service |
a04d08 |
self.assertIn("WARNING", self.logs.getvalue(),
|
|
Packit Service |
a04d08 |
"exit code of 2 by rpctool should log WARNING.")
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_found_when_guestinfo_present(self, m_subp, m_which):
|
|
Packit Service |
a04d08 |
"""When there is a ovf info, transport should return it."""
|
|
Packit Service |
a04d08 |
m_which.return_value = self.rpctool_path
|
|
Packit Service |
a04d08 |
content = fill_properties({})
|
|
Packit Service |
a04d08 |
m_subp.return_value = (content, '')
|
|
Packit Service |
a04d08 |
self.assertEqual(content, dsovf.transport_vmware_guestinfo())
|
|
Packit Service |
a04d08 |
self.assertEqual(1, m_subp.call_count)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
#
|
|
Packit Service |
a04d08 |
# vi: ts=4 expandtab
|