lorax-composer: Add timezone support to blueprint
For example:
[customizations.timezone]
timezone = "US/Samoa"
ntpservers = ["0.pool.ntp.org"]
Also includes tests.
This removes the timezone kickstart command from all of the templates
except for google.ks which needs to set it's own ntp servers and timezone.
If timezone isn't included in the blueprint, and it is not already in a
template, it will be set to 'timezone UTC' by default.
If timezone is set in a template it is left as-is, under the assumption
that the image type requires it to boot correctly.
(cherry picked from commit 9bdbb29662
)
Related: rhbz#1718473
This commit is contained in:
parent
e72debe1d1
commit
956ebfc77c
@ -21,8 +21,6 @@ selinux --enforcing
|
|||||||
logging --level=info
|
logging --level=info
|
||||||
# Shutdown after installation
|
# Shutdown after installation
|
||||||
shutdown
|
shutdown
|
||||||
# System timezone
|
|
||||||
timezone US/Eastern
|
|
||||||
# System bootloader configuration
|
# System bootloader configuration
|
||||||
bootloader --location=mbr --append="no_timer_check console=ttyS0,115200n8 console=tty1 net.ifnames=0"
|
bootloader --location=mbr --append="no_timer_check console=ttyS0,115200n8 console=tty1 net.ifnames=0"
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@ selinux --enforcing
|
|||||||
logging --level=info
|
logging --level=info
|
||||||
# Shutdown after installation
|
# Shutdown after installation
|
||||||
shutdown
|
shutdown
|
||||||
# System timezone
|
|
||||||
timezone US/Eastern
|
|
||||||
# System bootloader configuration (unpartitioned fs image doesn't use a bootloader)
|
# System bootloader configuration (unpartitioned fs image doesn't use a bootloader)
|
||||||
bootloader --location=none
|
bootloader --location=none
|
||||||
|
|
||||||
|
@ -21,8 +21,6 @@ logging --level=info
|
|||||||
shutdown
|
shutdown
|
||||||
# System services
|
# System services
|
||||||
services --disabled="network,sshd" --enabled="NetworkManager"
|
services --disabled="network,sshd" --enabled="NetworkManager"
|
||||||
# System timezone
|
|
||||||
timezone US/Eastern
|
|
||||||
# System bootloader configuration
|
# System bootloader configuration
|
||||||
bootloader --location=mbr
|
bootloader --location=mbr
|
||||||
# Clear the Master Boot Record
|
# Clear the Master Boot Record
|
||||||
|
@ -16,8 +16,6 @@ selinux --enforcing
|
|||||||
logging --level=info
|
logging --level=info
|
||||||
# Shutdown after installation
|
# Shutdown after installation
|
||||||
shutdown
|
shutdown
|
||||||
# System timezone
|
|
||||||
timezone US/Eastern
|
|
||||||
# System bootloader configuration
|
# System bootloader configuration
|
||||||
bootloader --location=mbr --append="no_timer_check console=ttyS0,115200n8 console=tty1 net.ifnames=0"
|
bootloader --location=mbr --append="no_timer_check console=ttyS0,115200n8 console=tty1 net.ifnames=0"
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@ selinux --enforcing
|
|||||||
logging --level=info
|
logging --level=info
|
||||||
# Shutdown after installation
|
# Shutdown after installation
|
||||||
shutdown
|
shutdown
|
||||||
# System timezone
|
|
||||||
timezone US/Eastern
|
|
||||||
# System bootloader configuration
|
# System bootloader configuration
|
||||||
bootloader --location=mbr
|
bootloader --location=mbr
|
||||||
# Clear the Master Boot Record
|
# Clear the Master Boot Record
|
||||||
|
@ -16,8 +16,6 @@ selinux --enforcing
|
|||||||
logging --level=info
|
logging --level=info
|
||||||
# Shutdown after installation
|
# Shutdown after installation
|
||||||
shutdown
|
shutdown
|
||||||
# System timezone
|
|
||||||
timezone US/Eastern
|
|
||||||
# System bootloader configuration
|
# System bootloader configuration
|
||||||
bootloader --location=mbr
|
bootloader --location=mbr
|
||||||
# Clear the Master Boot Record
|
# Clear the Master Boot Record
|
||||||
|
@ -16,8 +16,6 @@ selinux --enforcing
|
|||||||
logging --level=info
|
logging --level=info
|
||||||
# Shutdown after installation
|
# Shutdown after installation
|
||||||
shutdown
|
shutdown
|
||||||
# System timezone
|
|
||||||
timezone US/Eastern
|
|
||||||
# System bootloader configuration (tar doesn't need a bootloader)
|
# System bootloader configuration (tar doesn't need a bootloader)
|
||||||
bootloader --location=none
|
bootloader --location=none
|
||||||
|
|
||||||
|
@ -19,8 +19,6 @@ selinux --enforcing
|
|||||||
logging --level=info
|
logging --level=info
|
||||||
# Shutdown after installation
|
# Shutdown after installation
|
||||||
shutdown
|
shutdown
|
||||||
# System timezone
|
|
||||||
timezone US/Eastern
|
|
||||||
# System bootloader configuration
|
# System bootloader configuration
|
||||||
bootloader --location=mbr --append="no_timer_check console=ttyS0,115200n8 earlyprintk=ttyS0,115200 rootdelay=300 net.ifnames=0"
|
bootloader --location=mbr --append="no_timer_check console=ttyS0,115200n8 earlyprintk=ttyS0,115200 rootdelay=300 net.ifnames=0"
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@ selinux --enforcing
|
|||||||
logging --level=info
|
logging --level=info
|
||||||
# Shutdown after installation
|
# Shutdown after installation
|
||||||
shutdown
|
shutdown
|
||||||
# System timezone
|
|
||||||
timezone US/Eastern
|
|
||||||
# System bootloader configuration
|
# System bootloader configuration
|
||||||
bootloader --location=mbr
|
bootloader --location=mbr
|
||||||
|
|
||||||
|
@ -170,6 +170,44 @@ def get_kernel_append(recipe):
|
|||||||
return recipe["customizations"]["kernel"]["append"]
|
return recipe["customizations"]["kernel"]["append"]
|
||||||
|
|
||||||
|
|
||||||
|
def timezone_cmd(line, settings):
|
||||||
|
""" Update the timezone line with the settings
|
||||||
|
|
||||||
|
:param line: The timezone ... line
|
||||||
|
:type line: str
|
||||||
|
:param settings: A dict with timezone and/or ntpservers list
|
||||||
|
:type settings: dict
|
||||||
|
|
||||||
|
Using pykickstart to process the line is the best way to make sure it
|
||||||
|
is parsed correctly, and re-assembled for inclusion into the final kickstart
|
||||||
|
"""
|
||||||
|
ks_version = makeVersion()
|
||||||
|
ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False)
|
||||||
|
ks.readKickstartFromString(line)
|
||||||
|
|
||||||
|
if "timezone" in settings:
|
||||||
|
ks.handler.timezone.timezone = settings["timezone"]
|
||||||
|
if "ntpservers" in settings:
|
||||||
|
ks.handler.timezone.ntpservers = settings["ntpservers"]
|
||||||
|
|
||||||
|
# Converting back to a string includes a comment, return just the timezone line
|
||||||
|
return str(ks.handler.timezone).splitlines()[-1]
|
||||||
|
|
||||||
|
|
||||||
|
def get_timezone_settings(recipe):
|
||||||
|
"""Return the customizations.timezone dict
|
||||||
|
|
||||||
|
:param recipe:
|
||||||
|
:type recipe: Recipe object
|
||||||
|
:returns: append value or empty string
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
if "customizations" not in recipe or \
|
||||||
|
"timezone" not in recipe["customizations"]:
|
||||||
|
return {}
|
||||||
|
return recipe["customizations"]["timezone"]
|
||||||
|
|
||||||
|
|
||||||
def customize_ks_template(ks_template, recipe):
|
def customize_ks_template(ks_template, recipe):
|
||||||
""" Customize the kickstart template and return it
|
""" Customize the kickstart template and return it
|
||||||
|
|
||||||
@ -178,26 +216,60 @@ def customize_ks_template(ks_template, recipe):
|
|||||||
:param recipe:
|
:param recipe:
|
||||||
:type recipe: Recipe object
|
:type recipe: Recipe object
|
||||||
|
|
||||||
|
Apply customizations to existing template commands, or add defaults for ones that are
|
||||||
|
missing and required.
|
||||||
|
|
||||||
Apply customizations.kernel.append to the bootloader argument in the template.
|
Apply customizations.kernel.append to the bootloader argument in the template.
|
||||||
Add bootloader line if it is missing.
|
Add bootloader line if it is missing.
|
||||||
|
|
||||||
|
Add default timezone if needed. It does NOT replace an existing timezone entry
|
||||||
"""
|
"""
|
||||||
kernel_append = get_kernel_append(recipe)
|
# Commands to be modified [NEW-COMMAND-FUNC, NEW-VALUE, DEFAULT, REPLACE]
|
||||||
if not kernel_append:
|
# The function is called with a kickstart command string and the value to replace
|
||||||
return ks_template
|
# The value is specific to the command, and is understood by the function
|
||||||
found_bootloader = False
|
# The default is a complete kickstart command string, suitable for writing to the template
|
||||||
|
# If REPLACE is False it will not change an existing entry only add a missing one
|
||||||
|
commands = {"bootloader": [bootloader_append,
|
||||||
|
get_kernel_append(recipe),
|
||||||
|
'bootloader --location=none', True],
|
||||||
|
"timezone": [timezone_cmd,
|
||||||
|
get_timezone_settings(recipe),
|
||||||
|
'timezone UTC', False],
|
||||||
|
}
|
||||||
|
found = {}
|
||||||
|
|
||||||
output = StringIO()
|
output = StringIO()
|
||||||
for line in ks_template.splitlines():
|
for line in ks_template.splitlines():
|
||||||
if not line.startswith("bootloader"):
|
for cmd in commands:
|
||||||
print(line.decode("utf-8"), file=output)
|
(new_command, value, default, replace) = commands[cmd]
|
||||||
continue
|
if line.startswith(cmd):
|
||||||
found_bootloader = True
|
found[cmd] = True
|
||||||
log.debug("Found bootloader line: %s", line)
|
if value and replace:
|
||||||
print(bootloader_append(line, kernel_append).decode("utf-8"), file=output)
|
log.debug("Replacing %s with %s", cmd, value)
|
||||||
|
print(new_command(line, value), file=output)
|
||||||
if found_bootloader:
|
|
||||||
return output.getvalue()
|
|
||||||
else:
|
else:
|
||||||
return 'bootloader --append="%s" --location=none' % kernel_append + output.getvalue()
|
log.debug("Skipping %s", cmd)
|
||||||
|
print(line, file=output)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# No matches, write the line as-is
|
||||||
|
print(line, file=output)
|
||||||
|
|
||||||
|
# Write out defaults for the ones not found
|
||||||
|
# These must go FIRST because the template still needs to have the packages added
|
||||||
|
defaults = StringIO()
|
||||||
|
for cmd in commands:
|
||||||
|
if cmd in found:
|
||||||
|
continue
|
||||||
|
(new_command, value, default, _) = commands[cmd]
|
||||||
|
if value and default:
|
||||||
|
log.debug("Setting %s to use %s", cmd, value)
|
||||||
|
print(new_command(default, value), file=defaults)
|
||||||
|
elif default:
|
||||||
|
log.debug("Setting %s to %s", cmd, default)
|
||||||
|
print(default, file=defaults)
|
||||||
|
|
||||||
|
return defaults.getvalue() + output.getvalue()
|
||||||
|
|
||||||
|
|
||||||
def write_ks_root(f, user):
|
def write_ks_root(f, user):
|
||||||
|
@ -18,7 +18,8 @@ from StringIO import StringIO
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from pylorax.api.compose import add_customizations, compose_types
|
from pylorax.api.compose import add_customizations, compose_types
|
||||||
from pylorax.api.compose import bootloader_append, customize_ks_template
|
from pylorax.api.compose import timezone_cmd, get_timezone_settings
|
||||||
|
from pylorax.api.compose import get_kernel_append, bootloader_append, customize_ks_template
|
||||||
from pylorax.api.recipes import recipe_from_toml
|
from pylorax.api.recipes import recipe_from_toml
|
||||||
from pylorax.sysutils import joinpaths
|
from pylorax.sysutils import joinpaths
|
||||||
|
|
||||||
@ -32,6 +33,10 @@ HOSTNAME = BASE_RECIPE + """[customizations]
|
|||||||
hostname = "testhostname"
|
hostname = "testhostname"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
TIMEZONE = BASE_RECIPE + """[customizations]
|
||||||
|
timezone = "US/Samoa"
|
||||||
|
"""
|
||||||
|
|
||||||
SSHKEY = BASE_RECIPE + """[[customizations.sshkey]]
|
SSHKEY = BASE_RECIPE + """[[customizations.sshkey]]
|
||||||
user = "root"
|
user = "root"
|
||||||
key = "ROOT SSH KEY"
|
key = "ROOT SSH KEY"
|
||||||
@ -204,6 +209,22 @@ class CustomizationsTestCase(unittest.TestCase):
|
|||||||
self.assertCustomization(ROOT_PLAIN_KEY, 'sshkey --user root "A SSH KEY FOR THE USER"')
|
self.assertCustomization(ROOT_PLAIN_KEY, 'sshkey --user root "A SSH KEY FOR THE USER"')
|
||||||
self.assertNotCustomization(ROOT_PLAIN_KEY, "rootpw --lock")
|
self.assertNotCustomization(ROOT_PLAIN_KEY, "rootpw --lock")
|
||||||
|
|
||||||
|
def test_get_kernel_append(self):
|
||||||
|
"""Test get_kernel_append function"""
|
||||||
|
blueprint_data = """name = "test-kernel"
|
||||||
|
description = "test recipe"
|
||||||
|
version = "0.0.1"
|
||||||
|
"""
|
||||||
|
blueprint2_data = blueprint_data + """
|
||||||
|
[customizations.kernel]
|
||||||
|
append="nosmt=force"
|
||||||
|
"""
|
||||||
|
recipe = recipe_from_toml(blueprint_data)
|
||||||
|
self.assertEqual(get_kernel_append(recipe), "")
|
||||||
|
|
||||||
|
recipe = recipe_from_toml(blueprint2_data)
|
||||||
|
self.assertEqual(get_kernel_append(recipe), "nosmt=force")
|
||||||
|
|
||||||
def test_bootloader_append(self):
|
def test_bootloader_append(self):
|
||||||
"""Test bootloader_append function"""
|
"""Test bootloader_append function"""
|
||||||
|
|
||||||
@ -219,19 +240,148 @@ class CustomizationsTestCase(unittest.TestCase):
|
|||||||
self.assertEqual(bootloader_append('bootloader --append="console=tty1" --location=mbr --password="BADPASSWORD"', "nosmt=force"),
|
self.assertEqual(bootloader_append('bootloader --append="console=tty1" --location=mbr --password="BADPASSWORD"', "nosmt=force"),
|
||||||
'bootloader --append="console=tty1 nosmt=force" --location=mbr --password="BADPASSWORD"')
|
'bootloader --append="console=tty1 nosmt=force" --location=mbr --password="BADPASSWORD"')
|
||||||
|
|
||||||
def _checkBootloader(self, result, append_str):
|
def test_get_timezone_settings(self):
|
||||||
"""Find the bootloader line and make sure append_str is in it"""
|
"""Test get_timezone_settings function"""
|
||||||
|
blueprint_data = """name = "test-kernel"
|
||||||
|
description = "test recipe"
|
||||||
|
version = "0.0.1"
|
||||||
|
"""
|
||||||
|
blueprint2_data = blueprint_data + """
|
||||||
|
[customizations.timezone]
|
||||||
|
timezone = "US/Samoa"
|
||||||
|
"""
|
||||||
|
blueprint3_data = blueprint_data + """
|
||||||
|
[customizations.timezone]
|
||||||
|
ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]
|
||||||
|
"""
|
||||||
|
blueprint4_data = blueprint_data + """
|
||||||
|
[customizations.timezone]
|
||||||
|
timezone = "US/Samoa"
|
||||||
|
ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]
|
||||||
|
"""
|
||||||
|
recipe = recipe_from_toml(blueprint_data)
|
||||||
|
self.assertEqual(get_timezone_settings(recipe), {})
|
||||||
|
|
||||||
|
recipe = recipe_from_toml(blueprint2_data)
|
||||||
|
self.assertEqual(get_timezone_settings(recipe), {"timezone": "US/Samoa"})
|
||||||
|
|
||||||
|
recipe = recipe_from_toml(blueprint3_data)
|
||||||
|
self.assertEqual(get_timezone_settings(recipe),
|
||||||
|
{"ntpservers": ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]})
|
||||||
|
|
||||||
|
recipe = recipe_from_toml(blueprint4_data)
|
||||||
|
self.assertEqual(get_timezone_settings(recipe),
|
||||||
|
{"timezone": "US/Samoa",
|
||||||
|
"ntpservers": ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]})
|
||||||
|
|
||||||
|
def test_timezone_cmd(self):
|
||||||
|
"""Test timezone_cmd function"""
|
||||||
|
|
||||||
|
self.assertEqual(timezone_cmd("timezone UTC", {}), 'timezone UTC')
|
||||||
|
self.assertEqual(timezone_cmd("timezone FOO", {"timezone": "US/Samoa"}),
|
||||||
|
'timezone US/Samoa')
|
||||||
|
self.assertEqual(timezone_cmd("timezone FOO",
|
||||||
|
{"timezone": "US/Samoa", "ntpservers": ["0.ntp.org", "1.ntp.org"]}),
|
||||||
|
'timezone US/Samoa --ntpservers=0.ntp.org,1.ntp.org')
|
||||||
|
|
||||||
|
self.assertEqual(timezone_cmd("timezone --ntpservers=a,b,c FOO",
|
||||||
|
{"timezone": "US/Samoa", "ntpservers": ["0.pool.ntp.org", "1.pool.ntp.org"]}),
|
||||||
|
'timezone US/Samoa --ntpservers=0.pool.ntp.org,1.pool.ntp.org')
|
||||||
|
|
||||||
|
def _checkBootloader(self, result, append_str, line_limit=0):
|
||||||
|
"""Find the bootloader line and make sure append_str is in it"""
|
||||||
|
# Optionally check to make sure the change is at the top of the template
|
||||||
|
line_num = 0
|
||||||
for line in result.splitlines():
|
for line in result.splitlines():
|
||||||
if line.startswith("bootloader") and append_str in line:
|
if line.startswith("bootloader") and append_str in line:
|
||||||
|
if line_limit == 0 or line_num < line_limit:
|
||||||
return True
|
return True
|
||||||
|
else:
|
||||||
|
print("FAILED: bootloader not in the first %d lines of the output" % line_limit)
|
||||||
|
return False
|
||||||
|
line_num += 1
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _checkTemplates(self, recipe):
|
def _checkTimezone(self, result, settings, line_limit=0):
|
||||||
"""Apply the recipe to all the templates"""
|
"""Find the timezone line and make sure it is as expected"""
|
||||||
|
# Optionally check to make sure the change is at the top of the template
|
||||||
|
line_num = 0
|
||||||
|
for line in result.splitlines():
|
||||||
|
if line.startswith("timezone"):
|
||||||
|
if settings["timezone"] in line and all([True for n in settings["ntpservers"] if n in line]):
|
||||||
|
if line_limit == 0 or line_num < line_limit:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("FAILED: timezone not in the first %d lines of the output" % line_limit)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print("FAILED: %s not matching %s" % (settings, line))
|
||||||
|
line_num += 1
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_template_defaults(self):
|
||||||
|
"""Test that customize_ks_template includes defaults correctly"""
|
||||||
|
blueprint_data = """name = "test-kernel"
|
||||||
|
description = "test recipe"
|
||||||
|
version = "0.0.1"
|
||||||
|
|
||||||
|
[[packages]]
|
||||||
|
name = "lorax"
|
||||||
|
version = "*"
|
||||||
|
"""
|
||||||
|
recipe = recipe_from_toml(blueprint_data)
|
||||||
|
|
||||||
|
# Make sure that a kickstart with no bootloader and no timezone has them added
|
||||||
|
result = customize_ks_template("firewall --enabled\n", recipe)
|
||||||
|
print(result)
|
||||||
|
self.assertEqual(sum([1 for l in result.splitlines() if l.startswith("bootloader")]), 1)
|
||||||
|
self.assertTrue(self._checkBootloader(result, "none", line_limit=2))
|
||||||
|
self.assertEqual(sum([1 for l in result.splitlines() if l.startswith("timezone")]), 1)
|
||||||
|
self.assertTrue(self._checkTimezone(result, {"timezone": "UTC", "ntpservers": []}, line_limit=2))
|
||||||
|
|
||||||
|
# Make sure that a kickstart with a bootloader, and no timezone has timezone added to the top
|
||||||
|
result = customize_ks_template("firewall --enabled\nbootloader --location=mbr\n", recipe)
|
||||||
|
print(result)
|
||||||
|
self.assertEqual(sum([1 for l in result.splitlines() if l.startswith("bootloader")]), 1)
|
||||||
|
self.assertTrue(self._checkBootloader(result, "mbr"))
|
||||||
|
self.assertEqual(sum([1 for l in result.splitlines() if l.startswith("timezone")]), 1)
|
||||||
|
self.assertTrue(self._checkTimezone(result, {"timezone": "UTC", "ntpservers": []}, line_limit=1))
|
||||||
|
|
||||||
|
# Make sure that a kickstart with a bootloader and timezone has neither added
|
||||||
|
result = customize_ks_template("firewall --enabled\nbootloader --location=mbr\ntimezone US/Samoa\n", recipe)
|
||||||
|
print(result)
|
||||||
|
self.assertEqual(sum([1 for l in result.splitlines() if l.startswith("bootloader")]), 1)
|
||||||
|
self.assertTrue(self._checkBootloader(result, "mbr"))
|
||||||
|
self.assertEqual(sum([1 for l in result.splitlines() if l.startswith("timezone")]), 1)
|
||||||
|
self.assertTrue(self._checkTimezone(result, {"timezone": "US/Samoa", "ntpservers": []}))
|
||||||
|
|
||||||
|
def test_customize_ks_template(self):
|
||||||
|
"""Test that customize_ks_template works correctly"""
|
||||||
|
blueprint_data = """name = "test-kernel"
|
||||||
|
description = "test recipe"
|
||||||
|
version = "0.0.1"
|
||||||
|
|
||||||
|
[customizations.kernel]
|
||||||
|
append="nosmt=force"
|
||||||
|
|
||||||
|
[customizations.timezone]
|
||||||
|
timezone = "US/Samoa"
|
||||||
|
ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]
|
||||||
|
"""
|
||||||
|
tz_dict = {"timezone": "US/Samoa", "ntpservers": ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]}
|
||||||
|
recipe = recipe_from_toml(blueprint_data)
|
||||||
|
|
||||||
# Test against a kickstart without bootloader
|
# Test against a kickstart without bootloader
|
||||||
result = customize_ks_template("firewall --enabled\n", recipe)
|
result = customize_ks_template("firewall --enabled\n", recipe)
|
||||||
|
self.assertTrue(self._checkBootloader(result, "nosmt=force", line_limit=2))
|
||||||
|
self.assertEqual(sum([1 for l in result.splitlines() if l.startswith("bootloader")]), 1)
|
||||||
|
self.assertTrue(self._checkTimezone(result, tz_dict, line_limit=2))
|
||||||
|
self.assertEqual(sum([1 for l in result.splitlines() if l.startswith("timezone")]), 1)
|
||||||
|
|
||||||
|
# Test against a kickstart with a bootloader line
|
||||||
|
result = customize_ks_template("firewall --enabled\nbootloader --location=mbr\n", recipe)
|
||||||
self.assertTrue(self._checkBootloader(result, "nosmt=force"))
|
self.assertTrue(self._checkBootloader(result, "nosmt=force"))
|
||||||
|
self.assertTrue(self._checkTimezone(result, tz_dict, line_limit=2))
|
||||||
|
|
||||||
# Test against all of the available templates
|
# Test against all of the available templates
|
||||||
share_dir = "./share/"
|
share_dir = "./share/"
|
||||||
@ -242,37 +392,23 @@ class CustomizationsTestCase(unittest.TestCase):
|
|||||||
ks_template = open(ks_template_path, "r").read()
|
ks_template = open(ks_template_path, "r").read()
|
||||||
result = customize_ks_template(ks_template, recipe)
|
result = customize_ks_template(ks_template, recipe)
|
||||||
if not self._checkBootloader(result, "nosmt=force"):
|
if not self._checkBootloader(result, "nosmt=force"):
|
||||||
errors.append(("compose_type %s failed" % compose_type, result))
|
errors.append(("bootloader for compose_type %s failed" % compose_type, result))
|
||||||
|
if sum([1 for l in result.splitlines() if l.startswith("bootloader")]) != 1:
|
||||||
|
errors.append(("bootloader for compose_type %s failed: More than 1 entry" % compose_type, result))
|
||||||
|
|
||||||
|
|
||||||
|
# google images should retain their timezone settings
|
||||||
|
if compose_type == "google":
|
||||||
|
if self._checkTimezone(result, tz_dict):
|
||||||
|
errors.append(("timezone for compose_type %s failed" % compose_type, result))
|
||||||
|
elif not self._checkTimezone(result, tz_dict, line_limit=2):
|
||||||
|
# None of the templates have a timezone to modify, it should be placed at the top
|
||||||
|
errors.append(("timezone for compose_type %s failed" % compose_type, result))
|
||||||
|
if sum([1 for l in result.splitlines() if l.startswith("timezone")]) != 1:
|
||||||
|
errors.append(("timezone for compose_type %s failed: More than 1 entry" % compose_type, result))
|
||||||
|
|
||||||
# Print the bad results
|
# Print the bad results
|
||||||
for e, r in errors:
|
for e, r in errors:
|
||||||
print("%s:\n%s\n\n" % (e, r))
|
print("%s:\n%s\n\n" % (e, r))
|
||||||
|
|
||||||
self.assertEqual(errors, [])
|
self.assertEqual(errors, [])
|
||||||
|
|
||||||
def test_customize_ks_template(self):
|
|
||||||
"""Test that [customizations.kernel] works correctly"""
|
|
||||||
blueprint_data = """name = "test-kernel"
|
|
||||||
description = "test recipe"
|
|
||||||
version = "0.0.1"
|
|
||||||
|
|
||||||
[customizations.kernel]
|
|
||||||
append="nosmt=force"
|
|
||||||
"""
|
|
||||||
recipe = recipe_from_toml(blueprint_data)
|
|
||||||
self._checkTemplates(recipe)
|
|
||||||
|
|
||||||
def test_customize_list(self):
|
|
||||||
"""Test that [customizations.kernel] works correctly with [[customizations]] error"""
|
|
||||||
blueprint_data = """name = "test-kernel"
|
|
||||||
description = "test recipe"
|
|
||||||
version = "0.0.1"
|
|
||||||
|
|
||||||
[[customizations]]
|
|
||||||
hostname = "testing"
|
|
||||||
|
|
||||||
[customizations.kernel]
|
|
||||||
append="nosmt=force"
|
|
||||||
"""
|
|
||||||
recipe = recipe_from_toml(blueprint_data)
|
|
||||||
self._checkTemplates(recipe)
|
|
||||||
|
@ -22,7 +22,7 @@ import tempfile
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import pylorax.api.recipes as recipes
|
import pylorax.api.recipes as recipes
|
||||||
from pylorax.api.compose import add_customizations
|
from pylorax.api.compose import add_customizations, customize_ks_template
|
||||||
from pylorax.sysutils import joinpaths
|
from pylorax.sysutils import joinpaths
|
||||||
|
|
||||||
from pykickstart.parser import KickstartParser
|
from pykickstart.parser import KickstartParser
|
||||||
@ -364,6 +364,7 @@ class CustomizationsTests(unittest.TestCase):
|
|||||||
|
|
||||||
# write out the customization data, and parse the resulting kickstart
|
# write out the customization data, and parse the resulting kickstart
|
||||||
with tempfile.NamedTemporaryFile(prefix="lorax.test.customizations", mode="w") as f:
|
with tempfile.NamedTemporaryFile(prefix="lorax.test.customizations", mode="w") as f:
|
||||||
|
f.write(customize_ks_template("", recipe_obj))
|
||||||
add_customizations(f, recipe_obj)
|
add_customizations(f, recipe_obj)
|
||||||
f.flush()
|
f.flush()
|
||||||
ks.readKickstart(f.name)
|
ks.readKickstart(f.name)
|
||||||
@ -415,6 +416,30 @@ hostname = "testy.example.com"
|
|||||||
ks = self._blueprint_to_ks(blueprint_data)
|
ks = self._blueprint_to_ks(blueprint_data)
|
||||||
self.assertEqual(ks.handler.network.hostname, "testy.example.com")
|
self.assertEqual(ks.handler.network.hostname, "testy.example.com")
|
||||||
|
|
||||||
|
def test_timezone(self):
|
||||||
|
blueprint_data = """name = "test-timezone"
|
||||||
|
description = "test recipe"
|
||||||
|
version = "0.0.1"
|
||||||
|
|
||||||
|
[customizations.timezone]
|
||||||
|
timezone = "US/Samoa"
|
||||||
|
"""
|
||||||
|
ks = self._blueprint_to_ks(blueprint_data)
|
||||||
|
self.assertEqual(ks.handler.timezone.timezone, "US/Samoa")
|
||||||
|
|
||||||
|
def test_timezone_ntpservers(self):
|
||||||
|
blueprint_data = """name = "test-ntpservers"
|
||||||
|
description = "test recipe"
|
||||||
|
version = "0.0.1"
|
||||||
|
|
||||||
|
[customizations.timezone]
|
||||||
|
timezone = "US/Samoa"
|
||||||
|
ntpservers = ["1.north-america.pool.ntp.org"]
|
||||||
|
"""
|
||||||
|
ks = self._blueprint_to_ks(blueprint_data)
|
||||||
|
self.assertEqual(ks.handler.timezone.timezone, "US/Samoa")
|
||||||
|
self.assertEqual(ks.handler.timezone.ntpservers, ["1.north-america.pool.ntp.org"])
|
||||||
|
|
||||||
def test_user(self):
|
def test_user(self):
|
||||||
blueprint_data = """name = "test-user"
|
blueprint_data = """name = "test-user"
|
||||||
description = "test recipe"
|
description = "test recipe"
|
||||||
@ -525,6 +550,10 @@ name = "widget"
|
|||||||
|
|
||||||
[[customizations.group]]
|
[[customizations.group]]
|
||||||
name = "students"
|
name = "students"
|
||||||
|
|
||||||
|
[customizations.timezone]
|
||||||
|
timezone = "US/Samoa"
|
||||||
|
ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]
|
||||||
"""
|
"""
|
||||||
ks = self._blueprint_to_ks(blueprint_data)
|
ks = self._blueprint_to_ks(blueprint_data)
|
||||||
|
|
||||||
@ -564,3 +593,6 @@ name = "students"
|
|||||||
studentsGroup = self._find_group(ks, "students")
|
studentsGroup = self._find_group(ks, "students")
|
||||||
self.assertIsNotNone(studentsGroup)
|
self.assertIsNotNone(studentsGroup)
|
||||||
self.assertEqual(studentsGroup.name, "students")
|
self.assertEqual(studentsGroup.name, "students")
|
||||||
|
|
||||||
|
self.assertEqual(ks.handler.timezone.timezone, "US/Samoa")
|
||||||
|
self.assertEqual(ks.handler.timezone.ntpservers, ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"])
|
||||||
|
Loading…
Reference in New Issue
Block a user