Blame org_fedora_oscap/ks/oscap.py

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