Blame org_fedora_oscap/ks/oscap.py

Packit Service 39273c
#
Packit Service 39273c
# Copyright (C) 2013  Red Hat, Inc.
Packit Service 39273c
#
Packit Service 39273c
# This copyrighted material is made available to anyone wishing to use,
Packit Service 39273c
# modify, copy, or redistribute it subject to the terms and conditions of
Packit Service 39273c
# the GNU General Public License v.2, or (at your option) any later version.
Packit Service 39273c
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit Service 39273c
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit Service 39273c
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit Service 39273c
# Public License for more details.  You should have received a copy of the
Packit Service 39273c
# GNU General Public License along with this program; if not, write to the
Packit Service 39273c
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 39273c
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit Service 39273c
# source code or documentation are not subject to the GNU General Public
Packit Service 39273c
# License and may only be used or replicated with the express permission of
Packit Service 39273c
# Red Hat, Inc.
Packit Service 39273c
#
Packit Service 39273c
# Red Hat Author(s): Vratislav Podzimek <vpodzime@redhat.com>
Packit Service 39273c
#
Packit Service 39273c
Packit Service 39273c
"""Module with the OSCAPdata class."""
Packit Service 39273c
Packit Service 39273c
import shutil
Packit Service 39273c
import re
Packit Service 39273c
import os
Packit Service 39273c
import time
Packit Service 39273c
import logging
Packit Service 39273c
Packit Service 39273c
from pyanaconda.addons import AddonData
Packit Service 39273c
from pyanaconda.core.configuration.anaconda import conf
Packit Service 39273c
from pyanaconda.progress import progressQ
Packit Service 39273c
from pyanaconda import errors
Packit Service 39273c
from pyanaconda.core import util
Packit Service 39273c
from pyanaconda import flags
Packit Service 39273c
from pykickstart.errors import KickstartParseError, KickstartValueError
Packit Service 39273c
from org_fedora_oscap import utils, common, rule_handling, data_fetch
Packit Service 39273c
from org_fedora_oscap.common import SUPPORTED_ARCHIVES, _
Packit Service 39273c
from org_fedora_oscap.content_handling import ContentCheckError
Packit Service 39273c
Packit Service 39273c
log = logging.getLogger("anaconda")
Packit Service 39273c
Packit Service 39273c
# export OSCAPdata class to prevent Anaconda's collect method from taking
Packit Service 39273c
# AddonData class instead of the OSCAPdata class
Packit Service 39273c
# @see: pyanaconda.kickstart.AnacondaKSHandler.__init__
Packit Service 39273c
__all__ = ["OSCAPdata"]
Packit Service 39273c
Packit Service 39273c
SUPPORTED_CONTENT_TYPES = ("datastream", "rpm", "archive",
Packit Service 39273c
                           "scap-security-guide",
Packit Service 39273c
                           )
Packit Service 39273c
Packit Service 39273c
SUPPORTED_URL_PREFIXES = ("http://", "https://", "ftp://"
Packit Service 39273c
                          # LABEL:?, hdaX:?,
Packit Service 39273c
                          )
Packit Service 39273c
Packit Service 39273c
REQUIRED_PACKAGES = ("openscap", "openscap-scanner", )
Packit Service 39273c
Packit Service 39273c
FINGERPRINT_REGEX = re.compile(r'^[a-z0-9]+$')
Packit Service 39273c
Packit Service 39273c
Packit Service 39273c
class MisconfigurationError(common.OSCAPaddonError):
Packit Service 39273c
    """Exception for reporting misconfiguration."""
Packit Service 39273c
Packit Service 39273c
    pass
Packit Service 39273c
Packit Service 39273c
Packit Service 39273c
class OSCAPdata(AddonData):
Packit Service 39273c
    """
Packit Service 39273c
    Class parsing and storing data for the OSCAP addon.
Packit Service 39273c
Packit Service 39273c
    :see: pyanaconda.addons.AddonData
Packit Service 39273c
Packit Service 39273c
    """
Packit Service 39273c
Packit Service 39273c
    def __init__(self, name, just_clear=False):
Packit Service 39273c
        """
Packit Service 39273c
        :param name: name of the addon
Packit Service 39273c
        :type name: str
Packit Service 39273c
Packit Service 39273c
        """
Packit Service 39273c
Packit Service 39273c
        if not just_clear:
Packit Service 39273c
            # do not call the parent's __init__ more than once
Packit Service 39273c
            AddonData.__init__(self, name)
Packit Service 39273c
Packit Service 39273c
        # values specifying the content
Packit Service 39273c
        self.content_type = ""
Packit Service 39273c
        self.content_url = ""
Packit Service 39273c
        self.datastream_id = ""
Packit Service 39273c
        self.xccdf_id = ""
Packit Service 39273c
        self.profile_id = ""
Packit Service 39273c
        self.content_path = ""
Packit Service 39273c
        self.cpe_path = ""
Packit Service 39273c
        self.tailoring_path = ""
Packit Service 39273c
Packit Service 39273c
        # additional values
Packit Service 39273c
        self.fingerprint = ""
Packit Service 39273c
Packit Service 39273c
        # certificate to verify HTTPS connection or signed data
Packit Service 39273c
        self.certificates = ""
Packit Service 39273c
Packit Service 39273c
        # internal values
Packit Service 39273c
        self.rule_data = rule_handling.RuleData()
Packit Service 39273c
        self.dry_run = False
Packit Service 39273c
Packit Service 39273c
    def __str__(self):
Packit Service 39273c
        """
Packit Service 39273c
        What should end up in the resulting kickstart file, i.e. string
Packit Service 39273c
        representation of the stored data.
Packit Service 39273c
Packit Service 39273c
        """
Packit Service 39273c
Packit Service 39273c
        if self.dry_run or not self.profile_id:
Packit Service 39273c
            # the addon was run in the dry run mode, omit it from the kickstart
Packit Service 39273c
            return ""
Packit Service 39273c
Packit Service 39273c
        def key_value_pair(key, value, indent=4):
Packit Service 39273c
            return "%s%s = %s" % (indent * " ", key, value)
Packit Service 39273c
Packit Service 39273c
        ret = "%%addon %s" % self.name
Packit Service 39273c
        ret += "\n%s" % key_value_pair("content-type", self.content_type)
Packit Service 39273c
Packit Service 39273c
        if self.content_url:
Packit Service 39273c
            ret += "\n%s" % key_value_pair("content-url", self.content_url)
Packit Service 39273c
        if self.datastream_id:
Packit Service 39273c
            ret += "\n%s" % key_value_pair("datastream-id", self.datastream_id)
Packit Service 39273c
        if self.xccdf_id:
Packit Service 39273c
            ret += "\n%s" % key_value_pair("xccdf-id", self.xccdf_id)
Packit Service 39273c
        if self.content_path and self.content_type != "scap-security-guide":
Packit Service 39273c
            ret += "\n%s" % key_value_pair("content-path", self.content_path)
Packit Service 39273c
        if self.cpe_path:
Packit Service 39273c
            ret += "\n%s" % key_value_pair("cpe-path", self.cpe_path)
Packit Service 39273c
        if self.tailoring_path:
Packit Service 39273c
            ret += "\n%s" % key_value_pair("tailoring-path",
Packit Service 39273c
                                           self.tailoring_path)
Packit Service 39273c
Packit Service 39273c
        ret += "\n%s" % key_value_pair("profile", self.profile_id)
Packit Service 39273c
Packit Service 39273c
        if self.fingerprint:
Packit Service 39273c
            ret += "\n%s" % key_value_pair("fingerprint", self.fingerprint)
Packit Service 39273c
Packit Service 39273c
        if self.certificates:
Packit Service 39273c
            ret += "\n%s" % key_value_pair("certificates", self.certificates)
Packit Service 39273c
Packit Service 39273c
        ret += "\n%end\n\n"
Packit Service 39273c
        return ret
Packit Service 39273c
Packit Service 39273c
    def _parse_content_type(self, value):
Packit Service 39273c
        value_low = value.lower()
Packit Service 39273c
        if value_low in SUPPORTED_CONTENT_TYPES:
Packit Service 39273c
            self.content_type = value_low
Packit Service 39273c
        else:
Packit Service 39273c
            msg = "Unsupported content type '%s' in the %s addon" % (value,
Packit Service 39273c
                                                                     self.name)
Packit Service 39273c
            raise KickstartValueError(msg)
Packit Service 39273c
Packit Service 39273c
    def _parse_content_url(self, value):
Packit Service 39273c
        if any(value.startswith(prefix)
Packit Service 39273c
               for prefix in SUPPORTED_URL_PREFIXES):
Packit Service 39273c
            self.content_url = value
Packit Service 39273c
        else:
Packit Service 39273c
            msg = "Unsupported url '%s' in the %s addon" % (value, self.name)
Packit Service 39273c
            raise KickstartValueError(msg)
Packit Service 39273c
Packit Service 39273c
    def _parse_datastream_id(self, value):
Packit Service 39273c
        # need to be checked?
Packit Service 39273c
        self.datastream_id = value
Packit Service 39273c
Packit Service 39273c
    def _parse_xccdf_id(self, value):
Packit Service 39273c
        # need to be checked?
Packit Service 39273c
        self.xccdf_id = value
Packit Service 39273c
Packit Service 39273c
    def _parse_profile_id(self, value):
Packit Service 39273c
        # need to be checked?
Packit Service 39273c
        self.profile_id = value
Packit Service 39273c
Packit Service 39273c
    def _parse_content_path(self, value):
Packit Service 39273c
        # need to be checked?
Packit Service 39273c
        self.content_path = value
Packit Service 39273c
Packit Service 39273c
    def _parse_cpe_path(self, value):
Packit Service 39273c
        # need to be checked?
Packit Service 39273c
        self.cpe_path = value
Packit Service 39273c
Packit Service 39273c
    def _parse_tailoring_path(self, value):
Packit Service 39273c
        # need to be checked?
Packit Service 39273c
        self.tailoring_path = value
Packit Service 39273c
Packit Service 39273c
    def _parse_fingerprint(self, value):
Packit Service 39273c
        if FINGERPRINT_REGEX.match(value) is None:
Packit Service 39273c
            msg = "Unsupported or invalid fingerprint"
Packit Service 39273c
            raise KickstartValueError(msg)
Packit Service 39273c
Packit Service 39273c
        if utils.get_hashing_algorithm(value) is None:
Packit Service 39273c
            msg = "Unsupported fingerprint"
Packit Service 39273c
            raise KickstartValueError(msg)
Packit Service 39273c
Packit Service 39273c
        self.fingerprint = value
Packit Service 39273c
Packit Service 39273c
    def _parse_certificates(self, value):
Packit Service 39273c
        self.certificates = value
Packit Service 39273c
Packit Service 39273c
    def handle_line(self, line):
Packit Service 39273c
        """
Packit Service 39273c
        The handle_line method that is called with every line from this addon's
Packit Service 39273c
        %addon section of the kickstart file.
Packit Service 39273c
Packit Service 39273c
        :param line: a single line from the %addon section
Packit Service 39273c
        :type line: str
Packit Service 39273c
Packit Service 39273c
        """
Packit Service 39273c
Packit Service 39273c
        actions = {"content-type": self._parse_content_type,
Packit Service 39273c
                   "content-url": self._parse_content_url,
Packit Service 39273c
                   "content-path": self._parse_content_path,
Packit Service 39273c
                   "datastream-id": self._parse_datastream_id,
Packit Service 39273c
                   "profile": self._parse_profile_id,
Packit Service 39273c
                   "xccdf-id": self._parse_xccdf_id,
Packit Service 39273c
                   "xccdf-path": self._parse_content_path,
Packit Service 39273c
                   "cpe-path": self._parse_cpe_path,
Packit Service 39273c
                   "tailoring-path": self._parse_tailoring_path,
Packit Service 39273c
                   "fingerprint": self._parse_fingerprint,
Packit Service 39273c
                   "certificates": self._parse_certificates,
Packit Service 39273c
                   }
Packit Service 39273c
Packit Service 39273c
        line = line.strip()
Packit Service 39273c
        (pre, sep, post) = line.partition("=")
Packit Service 39273c
        pre = pre.strip()
Packit Service 39273c
        post = post.strip()
Packit Service 39273c
        post = post.strip('"')
Packit Service 39273c
Packit Service 39273c
        try:
Packit Service 39273c
            actions[pre](post)
Packit Service 39273c
        except KeyError:
Packit Service 39273c
            msg = "Unknown item '%s' for %s addon" % (line, self.name)
Packit Service 39273c
            raise KickstartParseError(msg)
Packit Service 39273c
Packit Service 39273c
    def finalize(self):
Packit Service 39273c
        """
Packit Service 39273c
        The finalize method that is called when the end of the %addon section
Packit Service 39273c
        (the %end line) is reached. It means no more kickstart data will come.
Packit Service 39273c
Packit Service 39273c
        """
Packit Service 39273c
Packit Service 39273c
        tmpl = "%s missing for the %s addon"
Packit Service 39273c
Packit Service 39273c
        # check provided data
Packit Service 39273c
        if not self.content_type:
Packit Service 39273c
            raise KickstartValueError(tmpl % ("content-type", self.name))
Packit Service 39273c
Packit Service 39273c
        if self.content_type != "scap-security-guide" and not self.content_url:
Packit Service 39273c
            raise KickstartValueError(tmpl % ("content-url", self.name))
Packit Service 39273c
Packit Service 39273c
        if not self.profile_id:
Packit Service 39273c
            self.profile_id = "default"
Packit Service 39273c
Packit Service 39273c
        if self.content_type in ("rpm", "archive") and not self.content_path:
Packit Service 39273c
            msg = "Path to the XCCDF file has to be given if content in RPM "\
Packit Service 39273c
                  "or archive is used"
Packit Service 39273c
            raise KickstartValueError(msg)
Packit Service 39273c
Packit Service 39273c
        if self.content_type == "rpm" and not self.content_url.endswith(".rpm"):
Packit Service 39273c
            msg = "Content type set to RPM, but the content URL doesn't end "\
Packit Service 39273c
                  "with '.rpm'"
Packit Service 39273c
            raise KickstartValueError(msg)
Packit Service 39273c
Packit Service 39273c
        if self.content_type == "archive":
Packit Service 39273c
            supported_archive = any(self.content_url.endswith(arch_type)
Packit Service 39273c
                                    for arch_type in SUPPORTED_ARCHIVES)
Packit Service 39273c
            if not supported_archive:
Packit Service 39273c
                msg = "Unsupported archive type of the content "\
Packit Service 39273c
                      "file '%s'" % self.content_url
Packit Service 39273c
                raise KickstartValueError(msg)
Packit Service 39273c
Packit Service 39273c
        # do some initialization magic in case of SSG
Packit Service 39273c
        if self.content_type == "scap-security-guide":
Packit Service 39273c
            if not common.ssg_available():
Packit Service 39273c
                msg = "SCAP Security Guide not found on the system"
Packit Service 39273c
                raise KickstartValueError(msg)
Packit Service 39273c
Packit Service 39273c
            self.content_path = common.SSG_DIR + common.SSG_CONTENT
Packit Service 39273c
Packit Service 39273c
    @property
Packit Service 39273c
    def content_defined(self):
Packit Service 39273c
        return self.content_url or self.content_type == "scap-security-guide"
Packit Service 39273c
Packit Service 39273c
    @property
Packit Service 39273c
    def content_name(self):
Packit Service 39273c
        if self.content_type == "scap-security-guide":
Packit Service 39273c
            raise ValueError("Using scap-security-guide, no single content file")
Packit Service 39273c
Packit Service 39273c
        rest = "/anonymous_content"
Packit Service 39273c
        for prefix in SUPPORTED_URL_PREFIXES:
Packit Service 39273c
            if self.content_url.startswith(prefix):
Packit Service 39273c
                rest = self.content_url[len(prefix):]
Packit Service 39273c
                break
Packit Service 39273c
Packit Service 39273c
        parts = rest.rsplit("/", 1)
Packit Service 39273c
        if len(parts) != 2:
Packit Service 39273c
            msg = "Unsupported url '%s' in the %s addon" % (self.content_url,
Packit Service 39273c
                                                            self.name)
Packit Service 39273c
            raise KickstartValueError(msg)
Packit Service 39273c
Packit Service 39273c
        return parts[1]
Packit Service 39273c
Packit Service 39273c
    @property
Packit Service 39273c
    def raw_preinst_content_path(self):
Packit Service 39273c
        """Path to the raw (unextracted, ...) pre-installation content file"""
Packit Service 39273c
Packit Service 39273c
        return utils.join_paths(common.INSTALLATION_CONTENT_DIR,
Packit Service 39273c
                                self.content_name)
Packit Service 39273c
Packit Service 39273c
    @property
Packit Service 39273c
    def raw_postinst_content_path(self):
Packit Service 39273c
        """Path to the raw (unextracted, ...) post-installation content file"""
Packit Service 39273c
Packit Service 39273c
        return utils.join_paths(common.TARGET_CONTENT_DIR,
Packit Service 39273c
                                self.content_name)
Packit Service 39273c
Packit Service 39273c
    @property
Packit Service 39273c
    def preinst_content_path(self):
Packit Service 39273c
        """Path to the pre-installation content file"""
Packit Service 39273c
Packit Service 39273c
        if self.content_type == "datastream":
Packit Service 39273c
            return utils.join_paths(common.INSTALLATION_CONTENT_DIR,
Packit Service 39273c
                                    self.content_name)
Packit Service 39273c
        elif self.content_type == "scap-security-guide":
Packit Service 39273c
            # SSG is not copied to the standard place
Packit Service 39273c
            return self.content_path
Packit Service 39273c
        else:
Packit Service 39273c
            return utils.join_paths(common.INSTALLATION_CONTENT_DIR,
Packit Service 39273c
                                    self.content_path)
Packit Service 39273c
Packit Service 39273c
    @property
Packit Service 39273c
    def postinst_content_path(self):
Packit Service 39273c
        """Path to the post-installation content file"""
Packit Service 39273c
Packit Service 39273c
        if self.content_type == "datastream":
Packit Service 39273c
            return utils.join_paths(common.TARGET_CONTENT_DIR,
Packit Service 39273c
                                    self.content_name)
Packit Service 39273c
        elif self.content_type in ("rpm", "scap-security-guide"):
Packit Service 39273c
            # no path magic in case of RPM (SSG is installed as an RPM)
Packit Service 39273c
            return self.content_path
Packit Service 39273c
        else:
Packit Service 39273c
            return utils.join_paths(common.TARGET_CONTENT_DIR,
Packit Service 39273c
                                    self.content_path)
Packit Service 39273c
Packit Service 39273c
    @property
Packit Service 39273c
    def preinst_tailoring_path(self):
Packit Service 39273c
        """Path to the pre-installation tailoring file (if any)"""
Packit Service 39273c
Packit Service 39273c
        if not self.tailoring_path:
Packit Service 39273c
            return ""
Packit Service 39273c
Packit Service 39273c
        return utils.join_paths(common.INSTALLATION_CONTENT_DIR,
Packit Service 39273c
                                self.tailoring_path)
Packit Service 39273c
Packit Service 39273c
    @property
Packit Service 39273c
    def postinst_tailoring_path(self):
Packit Service 39273c
        """Path to the post-installation tailoring file (if any)"""
Packit Service 39273c
Packit Service 39273c
        if not self.tailoring_path:
Packit Service 39273c
            return ""
Packit Service 39273c
Packit Service 39273c
        if self.content_type == "rpm":
Packit Service 39273c
            # no path magic in case of RPM
Packit Service 39273c
            return self.tailoring_path
Packit Service 39273c
Packit Service 39273c
        return utils.join_paths(common.TARGET_CONTENT_DIR,
Packit Service 39273c
                                self.tailoring_path)
Packit Service 39273c
Packit Service 39273c
    def _fetch_content_and_initialize(self):
Packit Service 39273c
        """Fetch content and initialize from it"""
Packit Service 39273c
Packit Service 39273c
        data_fetch.fetch_data(self.content_url, self.raw_preinst_content_path,
Packit Service 39273c
                              self.certificates)
Packit Service 39273c
        # RPM is an archive at this phase
Packit Service 39273c
        if self.content_type in ("archive", "rpm"):
Packit Service 39273c
            # extract the content
Packit Service 39273c
            common.extract_data(self.raw_preinst_content_path,
Packit Service 39273c
                                common.INSTALLATION_CONTENT_DIR,
Packit Service 39273c
                                [self.content_path])
Packit Service 39273c
Packit Service 39273c
        rules = common.get_fix_rules_pre(self.profile_id,
Packit Service 39273c
                                         self.preinst_content_path,
Packit Service 39273c
                                         self.datastream_id, self.xccdf_id,
Packit Service 39273c
                                         self.preinst_tailoring_path)
Packit Service 39273c
Packit Service 39273c
        # parse and store rules with a clean RuleData instance
Packit Service 39273c
        self.rule_data = rule_handling.RuleData()
Packit Service 39273c
        for rule in rules.splitlines():
Packit Service 39273c
            self.rule_data.new_rule(rule)
Packit Service 39273c
Packit Service 39273c
    def setup(self, storage, ksdata, payload):
Packit Service 39273c
        """
Packit Service 39273c
        The setup method that should make changes to the runtime environment
Packit Service 39273c
        according to the data stored in this object.
Packit Service 39273c
Packit Service 39273c
        :param storage: object storing storage-related information
Packit Service 39273c
                        (disks, partitioning, bootloader, etc.)
Packit Service 39273c
        :type storage: blivet.Blivet instance
Packit Service 39273c
        :param ksdata: data parsed from the kickstart file and set in the
Packit Service 39273c
                       installation process
Packit Service 39273c
        :type ksdata: pykickstart.base.BaseHandler instance
Packit Service 39273c
Packit Service 39273c
        """
Packit Service 39273c
Packit Service 39273c
        if self.dry_run or not self.profile_id:
Packit Service 39273c
            # nothing more to be done in the dry-run mode or if no profile is
Packit Service 39273c
            # selected
Packit Service 39273c
            return
Packit Service 39273c
Packit Service 39273c
        if not os.path.exists(self.preinst_content_path) and not os.path.exists(self.raw_preinst_content_path):
Packit Service 39273c
            # content not available/fetched yet
Packit Service 39273c
            try:
Packit Service 39273c
                self._fetch_content_and_initialize()
Packit Service 39273c
            except (common.OSCAPaddonError, data_fetch.DataFetchError) as e:
Packit Service 39273c
                log.error("Failed to fetch and initialize SCAP content!")
Packit Service 39273c
                msg = _("There was an error fetching and loading the security content:\n" +
Packit Service 39273c
                        "%s\n" +
Packit Service 39273c
                        "The installation should be aborted. Do you wish to continue anyway?") % e
Packit Service 39273c
Packit Service 39273c
                if flags.flags.automatedInstall and not flags.flags.ksprompt:
Packit Service 39273c
                    # cannot have ask in a non-interactive kickstart
Packit Service 39273c
                    # installation
Packit Service 39273c
                    raise errors.CmdlineError(msg)
Packit Service 39273c
Packit Service 39273c
                answ = errors.errorHandler.ui.showYesNoQuestion(msg)
Packit Service 39273c
                if answ == errors.ERROR_CONTINUE:
Packit Service 39273c
                    # prevent any futher actions here by switching to the dry
Packit Service 39273c
                    # run mode and let things go on
Packit Service 39273c
                    self.dry_run = True
Packit Service 39273c
                    return
Packit Service 39273c
                else:
Packit Service 39273c
                    # Let's sleep forever to prevent any further actions and
Packit Service 39273c
                    # wait for the main thread to quit the process.
Packit Service 39273c
                    progressQ.send_quit(1)
Packit Service 39273c
                    while True:
Packit Service 39273c
                        time.sleep(100000)
Packit Service 39273c
Packit Service 39273c
        # check fingerprint if given
Packit Service 39273c
        if self.fingerprint:
Packit Service 39273c
            hash_obj = utils.get_hashing_algorithm(self.fingerprint)
Packit Service 39273c
            digest = utils.get_file_fingerprint(self.raw_preinst_content_path,
Packit Service 39273c
                                                hash_obj)
Packit Service 39273c
            if digest != self.fingerprint:
Packit Service 39273c
                log.error("Failed to fetch and initialize SCAP content!")
Packit Service 39273c
                msg = _("The integrity check of the security content failed.\n" +
Packit Service 39273c
                        "The installation should be aborted. Do you wish to continue anyway?")
Packit Service 39273c
Packit Service 39273c
                if flags.flags.automatedInstall and not flags.flags.ksprompt:
Packit Service 39273c
                    # cannot have ask in a non-interactive kickstart
Packit Service 39273c
                    # installation
Packit Service 39273c
                    raise errors.CmdlineError(msg)
Packit Service 39273c
Packit Service 39273c
                answ = errors.errorHandler.ui.showYesNoQuestion(msg)
Packit Service 39273c
                if answ == errors.ERROR_CONTINUE:
Packit Service 39273c
                    # prevent any futher actions here by switching to the dry
Packit Service 39273c
                    # run mode and let things go on
Packit Service 39273c
                    self.dry_run = True
Packit Service 39273c
                    return
Packit Service 39273c
                else:
Packit Service 39273c
                    # Let's sleep forever to prevent any further actions and
Packit Service 39273c
                    # wait for the main thread to quit the process.
Packit Service 39273c
                    progressQ.send_quit(1)
Packit Service 39273c
                    while True:
Packit Service 39273c
                        time.sleep(100000)
Packit Service 39273c
Packit Service 39273c
        # evaluate rules, do automatic fixes and stop if something that cannot
Packit Service 39273c
        # be fixed automatically is wrong
Packit Service 39273c
        fatal_messages = [message for message in self.rule_data.eval_rules(ksdata, storage)
Packit Service 39273c
                          if message.type == common.MESSAGE_TYPE_FATAL]
Packit Service 39273c
        if any(fatal_messages):
Packit Service 39273c
            msg = "Wrong configuration detected!\n"
Packit Service 39273c
            msg += "\n".join(message.text for message in fatal_messages)
Packit Service 39273c
            msg += "\nThe installation should be aborted. Do you wish to continue anyway?"
Packit Service 39273c
            if flags.flags.automatedInstall and not flags.flags.ksprompt:
Packit Service 39273c
                # cannot have ask in a non-interactive kickstart installation
Packit Service 39273c
                raise errors.CmdlineError(msg)
Packit Service 39273c
Packit Service 39273c
            answ = errors.errorHandler.ui.showYesNoQuestion(msg)
Packit Service 39273c
            if answ == errors.ERROR_CONTINUE:
Packit Service 39273c
                # prevent any futher actions here by switching to the dry
Packit Service 39273c
                # run mode and let things go on
Packit Service 39273c
                self.dry_run = True
Packit Service 39273c
                return
Packit Service 39273c
            else:
Packit Service 39273c
                # Let's sleep forever to prevent any further actions and wait
Packit Service 39273c
                # for the main thread to quit the process.
Packit Service 39273c
                progressQ.send_quit(1)
Packit Service 39273c
                while True:
Packit Service 39273c
                    time.sleep(100000)
Packit Service 39273c
Packit Service 39273c
        # add packages needed on the target system to the list of packages
Packit Service 39273c
        # that are requested to be installed
Packit Service 39273c
        pkgs_to_install = list(REQUIRED_PACKAGES)
Packit Service 39273c
        if self.content_type == "scap-security-guide":
Packit Service 39273c
            pkgs_to_install.append("scap-security-guide")
Packit Service 39273c
        for pkg in pkgs_to_install:
Packit Service 39273c
            if pkg not in ksdata.packages.packageList:
Packit Service 39273c
                ksdata.packages.packageList.append(pkg)
Packit Service 39273c
Packit Service 39273c
    def execute(self, storage, ksdata, users, payload):
Packit Service 39273c
        """
Packit Service 39273c
        The execute method that should make changes to the installed system. It
Packit Service 39273c
        is called only once in the post-install setup phase.
Packit Service 39273c
Packit Service 39273c
        :see: setup
Packit Service 39273c
        :param users: information about created users
Packit Service 39273c
        :type users: pyanaconda.users.Users instance
Packit Service 39273c
Packit Service 39273c
        """
Packit Service 39273c
Packit Service 39273c
        if self.dry_run or not self.profile_id:
Packit Service 39273c
            # nothing more to be done in the dry-run mode or if no profile is
Packit Service 39273c
            # selected
Packit Service 39273c
            return
Packit Service 39273c
Packit Service 39273c
        target_content_dir = utils.join_paths(conf.target.system_root,
Packit Service 39273c
                                              common.TARGET_CONTENT_DIR)
Packit Service 39273c
        utils.ensure_dir_exists(target_content_dir)
Packit Service 39273c
Packit Service 39273c
        if self.content_type == "datastream":
Packit Service 39273c
            shutil.copy2(self.preinst_content_path, target_content_dir)
Packit Service 39273c
        elif self.content_type == "rpm":
Packit Service 39273c
            # copy the RPM to the target system
Packit Service 39273c
            shutil.copy2(self.raw_preinst_content_path, target_content_dir)
Packit Service 39273c
Packit Service 39273c
            # and install it with yum
Packit Service 39273c
            ret = util.execInSysroot("yum", ["-y", "--nogpg", "install",
Packit Service 39273c
                                             self.raw_postinst_content_path])
Packit Service 39273c
            if ret != 0:
Packit Service 39273c
                raise common.ExtractionError("Failed to install content "
Packit Service 39273c
                                             "RPM to the target system")
Packit Service 39273c
        elif self.content_type == "scap-security-guide":
Packit Service 39273c
            # nothing needed
Packit Service 39273c
            pass
Packit Service 39273c
        else:
Packit Service 39273c
            utils.universal_copy(utils.join_paths(common.INSTALLATION_CONTENT_DIR,
Packit Service 39273c
                                                  "*"),
Packit Service 39273c
                                 target_content_dir)
Packit Service 39273c
        if os.path.exists(self.preinst_tailoring_path):
Packit Service 39273c
            shutil.copy2(self.preinst_tailoring_path, target_content_dir)
Packit Service 39273c
Packit Service 39273c
        common.run_oscap_remediate(self.profile_id, self.postinst_content_path,
Packit Service 39273c
                                   self.datastream_id, self.xccdf_id,
Packit Service 39273c
                                   self.postinst_tailoring_path,
Packit Service 39273c
                                   chroot=conf.target.system_root)
Packit Service 39273c
Packit Service 39273c
    def clear_all(self):
Packit Service 39273c
        """Clear all the stored values."""
Packit Service 39273c
Packit Service 39273c
        self.__init__(self.name, just_clear=True)