# # Kickstart handler for packaging. # # Copyright (C) 2018 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU General Public License v.2, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY expressed or implied, including the implied warranties 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, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # from pykickstart.parser import Packages, Group from pykickstart.sections import PackageSection from pykickstart.constants import GROUP_DEFAULT, GROUP_ALL, GROUP_REQUIRED, KS_MISSING_IGNORE, \ KS_BROKEN_IGNORE from pyanaconda.core.constants import URL_TYPE_BASEURL, URL_TYPE_MIRRORLIST, URL_TYPE_METALINK, \ DNF_DEFAULT_REPO_COST, REPO_ORIGIN_SYSTEM, REPO_ORIGIN_USER, GROUP_PACKAGE_TYPES_ALL, \ GROUP_PACKAGE_TYPES_REQUIRED, RPM_LANGUAGES_NONE, MULTILIB_POLICY_ALL, RPM_LANGUAGES_ALL, \ DNF_DEFAULT_TIMEOUT, DNF_DEFAULT_RETRIES from pyanaconda.core.kickstart import KickstartSpecification, commands as COMMANDS from pyanaconda.modules.common.structures.packages import PackagesSelectionData, \ PackagesConfigurationData from pyanaconda.modules.common.structures.payload import RepoConfigurationData def convert_ks_repo_to_repo_data(ks_data): """Convert the kickstart command into a repo configuration. :param RepoData ks_data: a kickstart data :return RepoConfigurationData: a repo configuration """ repo_data = RepoConfigurationData() repo_data.name = ks_data.name if ks_data.baseurl: repo_data.url = ks_data.baseurl repo_data.type = URL_TYPE_BASEURL elif ks_data.mirrorlist: repo_data.url = ks_data.mirrorlist repo_data.type = URL_TYPE_MIRRORLIST elif ks_data.metalink: repo_data.url = ks_data.metalink repo_data.type = URL_TYPE_METALINK if not repo_data.url: repo_data.origin = REPO_ORIGIN_SYSTEM else: repo_data.origin = REPO_ORIGIN_USER repo_data.proxy = ks_data.proxy or "" repo_data.cost = ks_data.cost or DNF_DEFAULT_REPO_COST repo_data.included_packages = ks_data.includepkgs repo_data.excluded_packages = ks_data.excludepkgs repo_data.installation_enabled = ks_data.install repo_data.ssl_verification_enabled = not ks_data.noverifyssl repo_data.ssl_configuration.ca_cert_path = ks_data.sslcacert or "" repo_data.ssl_configuration.client_cert_path = ks_data.sslclientcert or "" repo_data.ssl_configuration.client_key_path = ks_data.sslclientkey or "" return repo_data def convert_repo_data_to_ks_repo(repo_data): """Convert the repo configuration into a kickstart command. :param RepoConfigurationData repo_data: a repo configuration :return RepoData: a kickstart data """ ks_data = COMMANDS.RepoData() ks_data.name = repo_data.name if repo_data.type == URL_TYPE_BASEURL: ks_data.baseurl = repo_data.url elif repo_data.type == URL_TYPE_MIRRORLIST: ks_data.mirrorlist = repo_data.url elif repo_data.type == URL_TYPE_METALINK: ks_data.metalink = repo_data.url ks_data.proxy = repo_data.proxy ks_data.noverifyssl = not repo_data.ssl_verification_enabled ks_data.sslcacert = repo_data.ssl_configuration.ca_cert_path ks_data.sslclientcert = repo_data.ssl_configuration.client_cert_path ks_data.sslclientkey = repo_data.ssl_configuration.client_key_path if repo_data.cost != DNF_DEFAULT_REPO_COST: ks_data.cost = repo_data.cost ks_data.includepkgs = repo_data.included_packages ks_data.excludepkgs = repo_data.excluded_packages ks_data.install = repo_data.installation_enabled return ks_data def convert_ks_data_to_packages_configuration(ks_data): """Convert the kickstart data into a packages configuration. :param KickstartHandler ks_data: a kickstart data :return PackagesSelectionData: a packages selection data """ configuration = PackagesConfigurationData() configuration.docs_excluded = ks_data.packages.excludeDocs configuration.weakdeps_excluded = ks_data.packages.excludeWeakdeps if ks_data.packages.handleMissing == KS_MISSING_IGNORE: configuration.missing_ignored = True if ks_data.packages.handleBroken == KS_BROKEN_IGNORE: configuration.broken_ignored = True if ks_data.packages.instLangs == "": configuration.languages = RPM_LANGUAGES_NONE elif ks_data.packages.instLangs is not None: configuration.languages = ks_data.packages.instLangs if ks_data.packages.multiLib: configuration.multilib_policy = MULTILIB_POLICY_ALL if ks_data.packages.timeout is not None: configuration.timeout = ks_data.packages.timeout if ks_data.packages.retries is not None: configuration.retries = ks_data.packages.retries return configuration def convert_packages_configuration_to_ksdata(configuration, ks_data): """Convert the packages configuration into a kickstart data. :param PackagesConfigurationData configuration: a packages configuration data :param KickstartHandler ks_data: a kickstart data to modify """ ks_data.packages.excludeDocs = configuration.docs_excluded ks_data.packages.excludeWeakdeps = configuration.weakdeps_excluded if configuration.missing_ignored: ks_data.packages.handleMissing = KS_MISSING_IGNORE if configuration.broken_ignored: ks_data.packages.handleBroken = KS_BROKEN_IGNORE if configuration.languages == RPM_LANGUAGES_NONE: ks_data.packages.instLangs = "" elif configuration.languages != RPM_LANGUAGES_ALL: ks_data.packages.instLangs = configuration.languages if configuration.multilib_policy == MULTILIB_POLICY_ALL: ks_data.packages.multiLib = True if configuration.timeout != DNF_DEFAULT_TIMEOUT: ks_data.packages.timeout = configuration.timeout if configuration.retries != DNF_DEFAULT_RETRIES: ks_data.packages.retries = configuration.retries def convert_ks_data_to_packages_selection(ks_data): """Convert the kickstart data into a packages selection. :param KickstartHandler ks_data: a kickstart data :return PackagesSelectionData: a packages selection data """ selection = PackagesSelectionData() selection.core_group_enabled = not ks_data.packages.nocore selection.default_environment_enabled = ks_data.packages.default if ks_data.packages.environment is not None: selection.environment = ks_data.packages.environment selection.packages = ks_data.packages.packageList selection.excluded_packages = ks_data.packages.excludedList for group in ks_data.packages.groupList: selection.groups.append(group.name) if group.include == GROUP_ALL: selection.groups_package_types[group.name] = GROUP_PACKAGE_TYPES_ALL if group.include == GROUP_REQUIRED: selection.groups_package_types[group.name] = GROUP_PACKAGE_TYPES_REQUIRED for group in ks_data.packages.excludedGroupList: selection.excluded_groups.append(group.name) for module in ks_data.module.dataList(): name = module.name if module.stream: name += ":" + module.stream if module.enable: selection.modules.append(name) else: selection.disabled_modules.append(name) return selection def convert_packages_selection_to_ksdata(selection, ks_data): """Convert the packages selection into a kickstart data. :param PackagesSelectionData selection: a packages selection data :param KickstartHandler ks_data: a kickstart data to modify """ # The empty packages section won't be printed without seen set to True. ks_data.packages.seen = True ks_data.packages.nocore = not selection.core_group_enabled ks_data.packages.default = selection.default_environment_enabled if selection.environment: ks_data.packages.environment = selection.environment ks_data.packages.packageList = selection.packages ks_data.packages.excludedList = selection.excluded_packages for group_name in selection.groups: package_types = selection.groups_package_types.get( group_name, [] ) group_include = GROUP_DEFAULT if set(package_types) == set(GROUP_PACKAGE_TYPES_ALL): group_include = GROUP_ALL if set(package_types) == set(GROUP_PACKAGE_TYPES_REQUIRED): group_include = GROUP_REQUIRED ks_group = create_ks_group( name=group_name, include=group_include ) ks_data.packages.groupList.append(ks_group) for group_name in selection.excluded_groups: ks_group = create_ks_group( name=group_name ) ks_data.packages.excludedGroupList.append(ks_group) for name in selection.modules: ks_module = create_ks_module(name) ks_data.module.dataList().append(ks_module) for name in selection.disabled_modules: ks_module = create_ks_module(name, enabled=False) ks_data.module.dataList().append(ks_module) def create_ks_module(name, enabled=True): """Create a new instance of a kickstart module. :param name: a name of the module :param enabled: True if the module is enabled, otherwise False :return: a kickstart module object """ names = name.split(":", maxsplit=1) + [""] return COMMANDS.ModuleData( name=names[0], stream=names[1], enable=enabled, ) def create_ks_group(name, include=GROUP_DEFAULT): """Create a new instance of a kickstart group. :param name: a name of the group :param include: a level of inclusion :return: a kickstart group object """ return Group(name=name, include=include) class PayloadKickstartSpecification(KickstartSpecification): """The kickstart specification of the Payloads module.""" commands = { "cdrom": COMMANDS.Cdrom, "harddrive": COMMANDS.HardDrive, "hmc": COMMANDS.Hmc, "liveimg": COMMANDS.Liveimg, "module": COMMANDS.Module, "nfs": COMMANDS.NFS, "ostreecontainer": COMMANDS.OSTreeContainer, "ostreesetup": COMMANDS.OSTreeSetup, "repo": COMMANDS.Repo, "url": COMMANDS.Url } commands_data = { "ModuleData": COMMANDS.ModuleData, "RepoData": COMMANDS.RepoData, } sections = { "packages": PackageSection } sections_data = { "packages": Packages }