lorax/tests/pylorax/test_compose.py
Brian C. Lane 3b8de2a233 Move the package requirements for live-iso setup out of the template
In order to support iso creation on multiple arches with the templates
we need to be able to select different packages based on arch.
lorax-composer uses the arch-specific Lorax templates in order to
generate the output iso so this patch:

1. Creates a new template and type to parse it, live-install.tmpl
   which contains only installpkg commands and #if clauses for arch
2. Removes bootloader related packages from the live-iso.ks
3. Remove dracut-config-rescue exclusion because it can cause problems
   with some blueprints.
4. Switch logo requirement to system-logos which is satisfied by
   generic-logos or fedora-logos. This prevents conflicts when a blueprint
   installs fedora-release-workstation.

So in the future, if x86.tmpl, etc. need a new package to support
creating the iso it should be added to the correct section in
./share/live/live-install.tmpl
2019-02-25 13:49:12 -08:00

270 lines
9.2 KiB
Python

#
# Copyright (C) 2018 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from io import StringIO
import os
import shutil
import tempfile
import unittest
from pylorax import get_buildarch
from pylorax.api.compose import add_customizations, get_extra_pkgs
from pylorax.api.config import configure, make_dnf_dirs
from pylorax.api.dnfbase import get_base_object
from pylorax.api.recipes import recipe_from_toml
BASE_RECIPE = """name = "test-cases"
description = "Used for testing"
version = "0.0.1"
"""
HOSTNAME = BASE_RECIPE + """[customizations]
hostname = "testhostname"
"""
SSHKEY = BASE_RECIPE + """[[customizations.sshkey]]
user = "root"
key = "ROOT SSH KEY"
"""
USER = BASE_RECIPE + """[[customizations.user]]
name = "tester"
"""
ROOT_USER = BASE_RECIPE + """[[customizations.user]]
name = "root"
"""
USER_KEY = """
key = "A SSH KEY FOR THE USER"
"""
USER_DESC = """
description = "a test user account"
"""
USER_CRYPT = """
password = "$6$CHO2$3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31LeOUleVK/R/aeWVHVZDi26zAH.o0ywBKH9Tc0/wm7sW/q39uyd1"
"""
USER_PLAIN = """
password = "plainpassword"
"""
USER_HOME = """
home = "/opt/users/tester/"
"""
USER_SHELL = """
shell = "/usr/bin/zsh"
"""
USER_UID = """
uid = 1013
"""
USER_GID = """
gid = 4242
"""
USER_GROUPS = """
groups = ["wheel", "users"]
"""
USER_ALL = USER + USER_KEY + USER_DESC + USER_CRYPT + USER_HOME + USER_SHELL + USER_UID + USER_GID
GROUP = BASE_RECIPE + """[[customizations.group]]
name = "testgroup"
"""
GROUP_GID = GROUP + """
gid = 1011
"""
USER_GROUP = USER + """[[customizations.group]]
name = "tester"
"""
KS_USER_ALL = '''sshkey --user tester "A SSH KEY FOR THE USER"
user --name tester --homedir /opt/users/tester/ --iscrypted --password "$6$CHO2$3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31LeOUleVK/R/aeWVHVZDi26zAH.o0ywBKH9Tc0/wm7sW/q39uyd1" --shell /usr/bin/zsh --uid 1013 --gid 4242 --gecos "a test user account"
rootpw --lock
'''
# ROOT TESTS
ROOT_CRYPT = ROOT_USER + USER_CRYPT
ROOT_PLAIN = ROOT_USER + USER_PLAIN
ROOT_CRYPT_KEY = ROOT_USER + USER_CRYPT + USER_KEY
ROOT_PLAIN_KEY = ROOT_USER + USER_PLAIN + USER_KEY
ROOT_KEY = ROOT_USER + USER_KEY
class CustomizationsTestCase(unittest.TestCase):
def assertCustomization(self, test, result):
r = recipe_from_toml(test)
f = StringIO()
add_customizations(f, r)
self.assertTrue(result in f.getvalue(), f.getvalue())
def assertNotCustomization(self, test, result):
r = recipe_from_toml(test)
f = StringIO()
add_customizations(f, r)
self.assertTrue(result not in f.getvalue(), f.getvalue())
def test_no_customizations(self):
"""Test not setting any customizations"""
self.assertCustomization(BASE_RECIPE, "rootpw --lock")
def test_set_hostname(self):
"""Test setting the hostname"""
self.assertCustomization(HOSTNAME, "network --hostname=testhostname")
self.assertCustomization(HOSTNAME, "rootpw --lock")
def test_set_sshkey(self):
"""Test setting sshkey without user"""
self.assertCustomization(SSHKEY, 'sshkey --user root "ROOT SSH KEY"')
def test_sshkey_only(self):
"""Test adding a sshkey to an existing user account"""
self.assertCustomization(USER + USER_KEY, 'sshkey --user tester "A SSH KEY FOR THE USER"')
self.assertCustomization(USER + USER_KEY, "rootpw --lock")
def test_create_user(self):
"""Test creating a user with no options"""
self.assertCustomization(USER, "user --name tester")
self.assertCustomization(USER, "rootpw --lock")
def test_create_user_desc(self):
"""Test creating a user with a description"""
self.assertCustomization(USER + USER_DESC, '--gecos "a test user account"')
self.assertCustomization(USER + USER_DESC, "rootpw --lock")
def test_create_user_crypt(self):
"""Test creating a user with a pre-crypted password"""
self.assertCustomization(USER + USER_CRYPT, '--password "$6$CHO2$3r')
self.assertCustomization(USER + USER_CRYPT, "rootpw --lock")
def test_create_user_plain(self):
"""Test creating a user with a plaintext password"""
self.assertCustomization(USER + USER_PLAIN, '--password "plainpassword"')
self.assertCustomization(USER + USER_PLAIN, "rootpw --lock")
def test_create_user_home(self):
"""Test creating user with a home directory"""
self.assertCustomization(USER + USER_HOME, "--homedir /opt/users/tester/")
self.assertCustomization(USER + USER_HOME, "rootpw --lock")
def test_create_user_shell(self):
"""Test creating user with shell set"""
self.assertCustomization(USER + USER_SHELL, "--shell /usr/bin/zsh")
self.assertCustomization(USER + USER_SHELL, "rootpw --lock")
def test_create_user_uid(self):
"""Test creating user with uid set"""
self.assertCustomization(USER + USER_UID, "--uid 1013")
self.assertCustomization(USER + USER_UID, "rootpw --lock")
def test_create_user_gid(self):
"""Test creating user with gid set"""
self.assertCustomization(USER + USER_GID, "--gid 4242")
self.assertCustomization(USER + USER_GID, "rootpw --lock")
def test_create_user_groups(self):
"""Test creating user with group membership"""
self.assertCustomization(USER + USER_GROUPS, "--groups wheel,users")
self.assertCustomization(USER + USER_GROUPS, "rootpw --lock")
def test_user_same_group(self):
"""Test creating a group with the same name as a user"""
# Creating a group with the same name should skip the group creation
self.assertCustomization(USER_GROUP, "user --name tester")
self.assertNotCustomization(USER_GROUP, "group --name tester")
self.assertCustomization(USER_GROUP, "rootpw --lock")
def test_create_user_all(self):
"""Test creating user with all settings"""
r = recipe_from_toml(USER_ALL)
f = StringIO()
add_customizations(f, r)
self.assertEqual(KS_USER_ALL, f.getvalue())
def test_create_group(self):
"""Test creating group without gid set"""
self.assertCustomization(GROUP, "group --name testgroup")
self.assertCustomization(GROUP, "rootpw --lock")
def test_create_group_gid(self):
"""Test creating group with gid set"""
self.assertCustomization(GROUP_GID, "group --name testgroup --gid 1011")
self.assertCustomization(GROUP_GID, "rootpw --lock")
def test_root_crypt(self):
self.assertCustomization(ROOT_CRYPT, 'rootpw --iscrypted "$6$CHO2$3r')
self.assertNotCustomization(ROOT_CRYPT, "rootpw --lock")
def test_root_plain(self):
self.assertCustomization(ROOT_PLAIN, 'rootpw --plaintext "plainpassword"')
self.assertNotCustomization(ROOT_PLAIN, "rootpw --lock")
def test_root_crypt_key(self):
self.assertCustomization(ROOT_CRYPT_KEY, 'rootpw --iscrypted "$6$CHO2$3r')
self.assertCustomization(ROOT_CRYPT_KEY, 'sshkey --user root "A SSH KEY FOR THE USER"')
self.assertNotCustomization(ROOT_CRYPT_KEY, "rootpw --lock")
def test_root_plain_key(self):
self.assertCustomization(ROOT_PLAIN_KEY, 'rootpw --plaintext "plainpassword"')
self.assertCustomization(ROOT_PLAIN_KEY, 'sshkey --user root "A SSH KEY FOR THE USER"')
self.assertNotCustomization(ROOT_PLAIN_KEY, "rootpw --lock")
class ExtraPkgsTest(unittest.TestCase):
@classmethod
def setUpClass(self):
self.tmp_dir = tempfile.mkdtemp(prefix="lorax.test.repo.")
self.config = configure(root_dir=self.tmp_dir, test_config=True)
make_dnf_dirs(self.config, os.getuid(), os.getgid())
self.dbo = get_base_object(self.config)
@classmethod
def tearDownClass(self):
shutil.rmtree(self.tmp_dir)
def test_live_install(self):
"""Check that live-install.tmpl is parsed correctly"""
# A package for each arch to test for
arch_pkg = {
"aarch64": "shim-aa64",
"arm": "grub2-efi-arm-cdboot",
"armhfp": "grub2-efi-arm-cdboot",
"x86_64": "shim-x64",
"i386": "memtest86+",
"ppc64le": "powerpc-utils",
"s390x": "s390utils-base"
}
extra_pkgs = get_extra_pkgs(self.dbo, "./share/", "live-iso")
self.assertTrue(len(extra_pkgs) > 0)
# Results depend on arch
arch = get_buildarch(self.dbo)
self.assertTrue(arch_pkg[arch] in extra_pkgs)
def test_other_install(self):
"""Test that non-live doesn't parse live-install.tmpl"""
extra_pkgs = get_extra_pkgs(self.dbo, "./share/", "qcow2")
self.assertEqual(extra_pkgs, [])