class zzzTestRuleSetSSCorners(RuleTest):

    def setUp(self):
        RuleTest.setUp(self)
        self.rule = SetSSCorners(self.config,
                                                  self.environ,
                                                  self.logdispatch,
                                                  self.statechglogger)
        self.rulename = self.rule.rulename
        self.rulenumber = self.rule.rulenumber
        self.ch = CommandHelper(self.logdispatch)

    def tearDown(self):
        pass

    def runTest(self):
        self.simpleRuleTest()

    def setConditionsForRule(self):
        '''
        Configure system for the unit test
        @param self: essential if you override this definition
        @return: boolean - If successful True; If failure False
        @author: Breen Malmberg
        '''
        success = True
        self.cmdhelper = CommandHelper(self.logdispatch)
        optdict = {"wvous-bl-corner": 6,
                    "wvous-br-corner": 6,
                    "wvous-tl-corner": 6,
                    "wvous-tr-corner": 6}
        cmd = 'defaults write ' + self.environ.geteuidhome() + '/Library/Preferences/com.apple.dock.plist '
        for item in optdict:
            self.cmdhelper.executeCommand(cmd + item + ' -int ' + str(optdict[item]))
            errout = self.cmdhelper.getErrorString()
            if errout:
                success = False
        return success

    def checkReportForRule(self, pCompliance, pRuleSuccess):
        '''
        check on whether report was correct
        @param self: essential if you override this definition
        @param pCompliance: the self.iscompliant value of rule
        @param pRuleSuccess: did report run successfully
        @return: boolean - If successful True; If failure False
        @author: Breen Malmberg
        '''
        self.logdispatch.log(LogPriority.DEBUG, "pCompliance = " + \
                             str(pCompliance) + ".")
        self.logdispatch.log(LogPriority.DEBUG, "pRuleSuccess = " + \
                             str(pRuleSuccess) + ".")
        success = True
        return success

    def checkFixForRule(self, pRuleSuccess):
        '''
        check on whether fix was correct
        @param self: essential if you override this definition
        @param pRuleSuccess: did report run successfully
        @return: boolean - If successful True; If failure False
        @author: Breen Malmberg
        '''
        self.logdispatch.log(LogPriority.DEBUG, "pRuleSuccess = " + \
                             str(pRuleSuccess) + ".")
        success = True
        return success

    def checkUndoForRule(self, pRuleSuccess):
        '''
        check on whether undo was correct
        @param self: essential if you override this definition
        @param pRuleSuccess: did report run successfully
        @return: boolean - If successful True; If failure False
        @author: Breen Malmberg
        '''
        self.logdispatch.log(LogPriority.DEBUG, "pRuleSuccess = " + \
                             str(pRuleSuccess) + ".")
        success = True
        return success
class zzzTestReqPassSysPref(RuleTest):

    def setUp(self):

        RuleTest.setUp(self)
        self.rule = ReqPassSysPref(self.config,
                                self.environ,
                                self.logdispatch,
                                self.statechglogger)
        self.cmdhelper = CommandHelper(self.logdispatch)
        self.rulename = self.rule.rulename
        self.rulenumber = self.rule.rulenumber

    def tearDown(self):
        pass

    def runTest(self):
        self.simpleRuleTest()

    def setConditionsForRule(self):
        '''
        Configure system for the unit test
        @param self: essential if you override this definition
        @return: boolean - If successful True; If failure False
        @author: ekkehard j. koch
        '''
        success = True
        setuplist = ["system.preferences", "system.preferences.accessibility",
                     "system.preferences.accounts", "system.preferences.datetime",
                     "system.preferences.energysaver", "system.preferences.location",
                     "system.preferences.network", "system.preferences.nvram",
                     "system.preferences.parental-controls", "system.preferences.printing",
                     "system.preferences.security", "system.preferences.security.remotepair",
                     "system.preferences.sharing", "system.preferences.softwareupdate",
                     "system.preferences.startupdisk", "system.preferences.timemachine",
                     "system.preferences.version-cue"]
        plistfile = "/System/Library/Security/authorization.plist"
        plistbuddy = "/usr/libexec/PlistBuddy"

        for option in setuplist:
            self.cmdhelper.executeCommand(plistbuddy + " -c 'Set rights:" + option + ":shared 1 " + plistfile)
            errorout = self.cmdhelper.getErrorString()
            if errorout:
                if re.search("Does Not Exist", errorout):
                    self.cmdhelper.executeCommand(plistbuddy + " -c 'Add rights:" + option + ":shared bool true " + plistfile)
                    erradd = self.cmdhelper.getErrorString()
                    if erradd:
                        success = False
        return success

    def checkReportForRule(self, pCompliance, pRuleSuccess):
        '''
        check on whether report was correct
        @param self: essential if you override this definition
        @param pCompliance: the self.iscompliant value of rule
        @param pRuleSuccess: did report run successfully
        @return: boolean - If successful True; If failure False
        @author: ekkehard j. koch
        '''
        self.logdispatch.log(LogPriority.DEBUG, "pCompliance = " + \
                             str(pCompliance) + ".")
        self.logdispatch.log(LogPriority.DEBUG, "pRuleSuccess = " + \
                             str(pRuleSuccess) + ".")
        success = True
        return success

    def checkFixForRule(self, pRuleSuccess):
        '''
        check on whether fix was correct
        @param self: essential if you override this definition
        @param pRuleSuccess: did report run successfully
        @return: boolean - If successful True; If failure False
        @author: ekkehard j. koch
        '''
        self.logdispatch.log(LogPriority.DEBUG, "pRuleSuccess = " + \
                             str(pRuleSuccess) + ".")
        success = True
        return success

    def checkUndoForRule(self, pRuleSuccess):
        '''
        check on whether undo was correct
        @param self: essential if you override this definition
        @param pRuleSuccess: did report run successfully
        @return: boolean - If successful True; If failure False
        @author: ekkehard j. koch
        '''
        self.logdispatch.log(LogPriority.DEBUG, "pRuleSuccess = " + \
                             str(pRuleSuccess) + ".")
        success = True
        return success
Beispiel #3
0
class Zypper(object):
    """The template class that provides a framework that must be implemented by
    all platform specific pkgmgr classes.
    
    @author: Derek T Walker
    @change: 2012/08/08 Derek Walker - Original Implementation
    @change: 2014/09/10 dkennel - Added -n option to search command string
    @change: 2014/12/24 Breen Malmberg - fixed a typo in the old search string;
            fixed multiple pep8 violations; changed search strings to be match exact and
            search for installed or available separately
    @change: 2015/08/20 eball - Added getPackageFromFile and self.rpm var
    @change: 2016/08/02 eball - Moved checkInstall return out of else block
    @change: 2017/04/19 Breen Malmberg - refactored multiple methods; cleaned up doc
            strings; added logging; added two methods: Update and checkUpdate;
            removed detailedresults reset in __init__ (this should always be handled
            in the calling rule); replaced detailedresults instances with logging;
            added the flag "--quiet" to the install variable


    """
    def __init__(self, logger):
        self.logger = logger
        self.ch = CommandHelper(self.logger)
        self.zyploc = "/usr/bin/zypper"
        self.install = self.zyploc + " --non-interactive --quiet install "
        self.remove = self.zyploc + " --non-interactive remove "
        self.searchi = self.zyploc + " --non-interactive search --match-exact -i "
        self.searchu = self.zyploc + " --non-interactive search --match-exact -u "
        self.updates = self.zyploc + " lu "
        self.upzypp = self.zyploc + " up "
        self.rpm = "/usr/bin/rpm -q "
        self.pkgtype = "zypper"
        self.pkgerrs = [1, 2, 3, 4, 5, 6]
        self.pkgnotfound = [104]

    def installpackage(self, package):
        """Install a package. Return a bool indicating success or failure.

        :param package: string; Name of the package to be installed, must be
                recognizable to the underlying package manager.
        :returns: installed
        :rtype: bool
@author: Derek Walker
@change: Breen Malmberg - 12/24/2014 - fixed method doc string formatting
@change: Breen Malmberg - 10/1/2018 - added check for package manager lock and retry loop

        """

        installed = True
        maxtries = 12
        trynum = 0

        while psRunning("zypper"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Timed out while attempting to install package due to zypper package manager being in-use by another process."
                )
                installed = False
                return installed
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "zypper package manager is in-use by another process. Waiting for it to be freed..."
                )
                time.sleep(5)

        try:

            self.ch.executeCommand(self.install + package)
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrs:
                errstr = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG,
                                "Package installation because:\n" + errstr)
                installed = False
            elif retcode in self.pkgnotfound:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Package installation failed because zypper could not find a package named: "
                    + str(package))
                installed = False

            if installed:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Package " + str(package) + " installed successfully")
            else:
                self.logger.log(LogPriority.DEBUG,
                                "Failed to install package " + str(package))

        except Exception:
            raise
        return installed

    def removepackage(self, package):
        """Remove a package. Return a bool indicating success or failure.

        :param package: string; Name of the package to be removed, must be
                recognizable to the underlying package manager.
        :returns: removed
        :rtype: bool
@author: Derek Walker
@change: 12/24/2014 - Breen Malmberg - fixed method doc string formatting;
        fixed an issue with var 'removed' not
        being initialized before it was called

        """

        removed = True
        maxtries = 12
        trynum = 0

        while psRunning("zypper"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Timed out while attempting to remove package due to zypper package manager being in-use by another process."
                )
                removed = False
                return removed
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "zypper package manager is in-use by another process. Waiting for it to be freed..."
                )
                time.sleep(5)

        try:

            self.ch.executeCommand(self.remove + package)
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrs:
                errstr = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG,
                                "Package removal failed because:\n" + errstr)
                removed = False
            elif retcode in self.pkgnotfound:
                self.logger.log(
                    LogPriority.DEBUG, "No package found matching: " +
                    str(package) + ". Nothing to remove")

            if removed:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Package " + str(package) + " was removed successfully")
            else:
                self.logger.log(LogPriority.DEBUG,
                                "Failed to remove package " + str(package))

        except Exception:
            raise
        return removed

    def checkInstall(self, package):
        """Check the installation status of a package. Return a bool; True if
        the package is installed.

        :param string package: Name of the package whose installation status
            is to be checked, must be recognizable to the underlying package
            manager.
        :param package: 
        :returns: bool
        @author: Derek Walker
        @change: 12/24/2014 - Breen Malmberg - fixed method doc string formatting
        @change: 12/24/2014 - Breen Malmberg - changed var name 'found' to
            'installed'
        @change: 12/24/2014 - Breen Malmberg - now uses correct search syntax
        @change: 12/24/2014 - Breen Malmberg - removed detailedresults update on
            'found but not installed' as this no longer applies to this method

        """

        installed = True
        maxtries = 12
        trynum = 0

        while psRunning("zypper"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Timed out while attempting to check status of  package due to zypper package manager being in-use by another process."
                )
                installed = False
                return installed
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "zypper package manager is in-use by another process. Waiting for it to be freed..."
                )
                time.sleep(5)

        try:

            self.ch.executeCommand(self.searchi + package)
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrs:
                errstr = self.ch.getErrorString()
                self.logger.log(
                    LogPriority.DEBUG, "Failed to check for package: " +
                    str(package) + " because:\n" + errstr)
                installed = False
            elif retcode in self.pkgnotfound:
                installed = False

            if installed:
                self.logger.log(LogPriority.DEBUG,
                                " Package " + str(package) + " is installed")
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    " Package " + str(package) + " is NOT installed")

        except Exception:
            raise
        return installed

    def checkAvailable(self, package):
        """check if given package is available to install on the current system

        :param package: 
        :returns: bool
        @author: Derek Walker
        @change: 12/24/2014 - Breen Malmberg - added method documentation
        @change: 12/24/2014 - Breen Malmberg - changed var name 'found' to
            'available'
        @change: 12/24/2014 - Breen Malmberg - fixed search syntax and updated search
            variable name
        @change: Breen Malmberg - 5/1/2017 - replaced detailedresults with logging;
                added parameter validation

        """

        available = True
        found = False
        maxtries = 12
        trynum = 0

        while psRunning("zypper"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Timed out while attempting to check availability of package, due to zypper package manager being in-use by another process."
                )
                available = False
                return available
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "zypper package manager is in-use by another process. Waiting for it to be freed..."
                )
                time.sleep(5)

        try:

            self.ch.executeCommand(self.searchu + package)
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrs:
                errstr = self.ch.getErrorString()
                self.logger.log(
                    LogPriority.DEBUG, "Failed to check if package: " +
                    str(package) + " is available, because:\n" + errstr)
                available = False
            elif retcode in self.pkgnotfound:
                available = False
            else:
                output = self.ch.getOutput()
                for line in output:
                    if re.search(package, line):
                        found = True
                if not found:
                    available = False

            if available:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Package " + str(package) + " is available to install")
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Package " + str(package) + " is NOT available to install")

        except Exception:
            raise
        return available

    def checkUpdate(self, package=""):
        """check for available updates for specified
        package.
        if no package is specified, then check for
        updates to the entire system.

        :param package: string; name of package to check (Default value = "")
        :returns: updatesavail
        :rtype: bool
@author: Breen Malmberg

        """

        # zypper does not have a package-specific list updates mechanism
        # you have to list all updates or nothing

        updatesavail = True

        try:

            if package:
                self.ch.executeCommand(self.updates + " | grep " + package)
            else:
                self.ch.executeCommand(self.updates)

            retcode = self.ch.getReturnCode()
            if retcode in [2, 3, 4, 5, 6]:
                errstr = self.ch.getErrorString()
                self.logger.log(
                    LogPriority.DEBUG,
                    "Failed to check for updates because:\n" + errstr)
                updatesavail = False
            elif retcode in self.pkgnotfound:
                updatesavail = False

            if not updatesavail:
                self.logger.log(LogPriority.DEBUG, "No updates available")
            else:
                self.logger.log(LogPriority.DEBUG, "Updates available")

        except Exception:
            raise
        return updatesavail

    def Update(self, package=""):
        """update a specified package
        if no package name is specified,
        then update all packages on the system

        :param package: string; name of package to update (Default value = "")
        :returns: updated
        :rtype: bool
@author: Breen Malmberg

        """

        updated = True

        try:

            self.ch.executeCommand(self.upzypp + package)
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrs:
                errstr = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG,
                                "Failed to update because:\n" + errstr)
                updated = False
            elif retcode in self.pkgnotfound:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Unable to find package named: " + str(package))
                updated = False

            if updated:
                self.logger.log(LogPriority.DEBUG,
                                "Updates applied successfully")
            else:
                self.logger.log(LogPriority.DEBUG, "Failed to apply updates")

        except Exception:
            raise
        return updated

    def getPackageFromFile(self, filename):
        """Returns the name of the package that provides the given
        filename/path.

        :param filename: 
        :returns: string name of package if found, None otherwise
        @author: Eric Ball

        """

        packagename = ""

        try:

            self.ch.executeCommand(self.rpm + "-f " + filename)
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrs:
                errstr = self.ch.getErrorString()
                self.logger.log(
                    LogPriority.DEBUG,
                    "Failed to get package name because:\n" + errstr)
            else:
                outputstr = self.ch.getOutputString()
                packagename = outputstr

        except Exception:
            raise

        return packagename

    def getInstall(self):
        """return the install command string for the zypper pkg manager


        :returns: string
        @author: Derek Walker
        @change: 12/24/2014 - Breen Malmberg - added method documentation

        """

        return self.install

    def getRemove(self):
        """return the uninstall/remove command string for the zypper pkg manager


        :returns: string
        @author: Derek Walker
        @change: 12/24/2014 - Breen Malmberg - added method documentation

        """

        return self.remove
Beispiel #4
0
class Yum(object):
    """The template class that provides a framework that must be implemented by
    all platform specific pkgmgr classes.

    """

    def __init__(self, logger):
        self.environ = Environment()
        self.logger = logger
        self.ch = CommandHelper(self.logger)
        self.yumloc = "/usr/bin/yum"
        self.install = self.yumloc + " install -y "
        self.remove = self.yumloc + " remove -y "
        self.search = self.yumloc + " list "
        self.checkupdates = self.search + "updates "
        self.listavail = self.search + "available "
        self.listinstalled = self.search + "installed "
        self.updatepkg = self.yumloc + " update -y --obsoletes "
        myos = self.environ.getostype().lower()
        if re.search("red hat.*?release 6", myos) or \
                re.search("^centos$", myos.strip()):
            self.rpmloc = "/bin/rpm"
        else:
            self.rpmloc = "/usr/bin/rpm"
        self.provides = self.rpmloc + " -qf "
        self.query = self.rpmloc + " -qa "

    def installpackage(self, package):
        """Install a package. Return a bool indicating success or failure.

        :param package: string; Name of the package to be installed, must be
                recognizable to the underlying package manager.
        :return: installed
        :rtype: bool

        """

        installed = True
        maxtries = 12
        trynum = 0

        while psRunning("yum"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(LogPriority.DEBUG, "Timed out while attempting to install package due to yum package manager being in-use by another process.")
                installed = False
                return installed
            else:
                self.logger.log(LogPriority.DEBUG, "Yum package manager is in-use by another process. Waiting for it to be freed...")
                time.sleep(5)

        try:

            self.ch.executeCommand(self.install + package)
            retcode = self.ch.getReturnCode()

            if retcode != 0:
                errstr = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG, "Yum command failed with: " + str(errstr))
                installed = False

            if installed:
                self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " was installed successfully")
            else:
                self.logger.log(LogPriority.DEBUG, "Failed to install package " + str(package))

        except Exception:
            raise
        return installed

    def removepackage(self, package):
        """Remove a package. Return a bool indicating success or failure.

        :param package: string; Name of the package to be removed, must be
                recognizable to the underlying package manager.
        :return: removed
        :rtype: bool

        """

        removed = True
        maxtries = 12
        trynum = 0

        while psRunning("yum"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(LogPriority.DEBUG, "Timed out while attempting to remove package, due to yum package manager being in-use by another process.")
                removed = False
                return removed
            else:
                self.logger.log(LogPriority.DEBUG, "Yum package manager is in-use by another process. Waiting for it to be freed...")
                time.sleep(5)

        try:

            self.ch.executeCommand(self.remove + package)
            retcode = self.ch.getReturnCode()
            if retcode != 0:
                errstr = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG, "Yum command failed with: " + str(errstr))
                removed = False

            if removed:
                self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " was successfully removed")
            else:
                self.logger.log(LogPriority.DEBUG, "Failed to remove package " + str(package))

        except Exception:
            raise
        return removed

    def checkInstall(self, package):
        """Check the installation status of a package. Return a bool; True if
        the package is installed.

        :param package: string; Name of the package whose installation status
            is to be checked, must be recognizable to the underlying package
            manager.
        :return: found
        :rtype: bool

        """

        installed = True
        maxtries = 12
        trynum = 0
        acceptablecodes = [1,0]

        while psRunning("yum"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(LogPriority.DEBUG, "Timed out while attempting to check status of package, due to yum package manager being in-use by another process.")
                installed = False
                return installed
            else:
                self.logger.log(LogPriority.DEBUG, "Yum package manager is in-use by another process. Waiting for it to be freed...")
                time.sleep(5)

        try:

            self.ch.executeCommand(self.listinstalled + package)
            retcode = self.ch.getReturnCode()
            if retcode not in acceptablecodes:
                installed = False
                errmsg = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG, "Yum command failed with: " + str(errmsg))
            else:
                outputlines = self.ch.getAllList()
                for line in outputlines:
                    if re.search("No matching Packages", line, re.I):
                        installed = False

            if installed:
                self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " is installed")
            else:
                self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " is NOT installed")

        except Exception:
            raise
        return installed

    def Update(self, package=""):
        """update specified package if any updates
        are available for it
        if no package is specified, update all
        packages which can be updated on the system

        :param package: string; name of package to update (Default value = "")
        :return: updated
        :rtype: bool

        """

        updated = True

        try:

            try:
                self.ch.executeCommand(self.updatepkg + package)
                retcode = self.ch.getReturnCode()
                errstr = self.ch.getErrorString()
                if retcode != 0:
                    updated = False
                    raise repoError('yum', retcode, str(errstr))
            except repoError as repoerr:
                if not repoerr.success:
                    self.logger.log(LogPriority.WARNING, str(errstr))
                    updated = False

            if package:
                if updated:
                    self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " was successfully updated")
                else:
                    self.logger.log(LogPriority.DEBUG, "No updates were found for package " + str(package))
            else:
                if updated:
                    self.logger.log(LogPriority.DEBUG, "All packages were successfully updated")
                else:
                    self.logger.log(LogPriority.DEBUG, "No updates were found for this system")

        except Exception:
            raise
        return updated

    def checkUpdate(self, package=""):
        """check if there are any updates available for
        specified package
        if no package is specified, check if any updates
        are available for the current system

        :param package: string; name of package to check (Default value = "")
        :return: updatesavail
        :rtype: bool

        """

        updatesavail = False

        try:

            try:
                self.ch.executeCommand(self.checkupdates + package)
                retcode = self.ch.getReturnCode()
                output = self.ch.getOutputString()
                errstr = self.ch.getErrorString()
                if retcode != 0:
                    raise repoError('yum', retcode, str(errstr))
                else:
                    if re.search("Updated packages", output, re.IGNORECASE):
                        updatesavail = True
            except repoError as repoerr:
                if not repoerr.success:
                    self.logger.log(LogPriority.WARNING, str(errstr))
                else:
                    if re.search("Updated packages", output, re.IGNORECASE):
                        updatesavail = True

            if package:
                if updatesavail:
                    self.logger.log(LogPriority.DEBUG, "Updates are available for package " + str(package))
                else:
                    self.logger.log(LogPriority.DEBUG, "No updates are available for package " + str(package))
            else:
                if updatesavail:
                    self.logger.log(LogPriority.DEBUG, "Updates are available for this system")
                else:
                    self.logger.log(LogPriority.DEBUG, "No updates are available for this system")

        except Exception:
            raise
        return updatesavail

    def checkAvailable(self, package):
        """check if specified package is available to install
        return True if it is
        return False if not

        :param package: string; name of package to check
        :return: available
        :rtype: bool

        """

        available = True
        maxtries = 12
        trynum = 0

        while psRunning("yum"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(LogPriority.DEBUG, "Timed out while attempting to check availability of package, due to yum package manager being in-use by another process.")
                available = False
                return available
            else:
                self.logger.log(LogPriority.DEBUG, "Yum package manager is in-use by another process. Waiting for it to be freed...")
                time.sleep(5)

        try:

            self.ch.executeCommand(self.listavail + package)
            retcode = self.ch.getReturnCode()
            if retcode in [0,1]:
                output = self.ch.getAllList()
                for line in output:
                    if re.search("No matching Packages", line, re.I):
                        available = False
            else:
                errstr = self.ch.getErrorString()
                available = False
                self.logger.log(LogPriority.DEBUG, errstr)

            if available:
                self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " is available to install")
            else:
                self.logger.log(LogPriority.DEBUG, "No package " + str(package) + " was found to install")

        except Exception:
            raise
        return available

    def getPackageFromFile(self, filename):
        """Returns the name of the package that provides the given
        filename/path.

        :param filename: string; The name or path of the file to resolve
        :return: packagename
        :rtype: string

        """

        packagename = ""

        try:

            try:
                self.ch.executeCommand(self.provides + filename)
                retcode = self.ch.getReturnCode()
                outputstr = self.ch.getOutputString()
                errstr = self.ch.getErrorString()
                if retcode != 0:
                    raise repoError('yum', retcode, str(errstr))
                else:
                    packagename = outputstr
            except repoError as repoerr:
                if not repoerr.success:
                    self.logger.log(LogPriority.WARNING, str(errstr))

        except Exception:
            raise
        return packagename

    def getInstall(self):
        return self.install

    def getRemove(self):
        return self.remove
Beispiel #5
0
class AptGet(object):
    """Linux specific package manager for distributions that use the apt-get
    command to install packages.
    
    @author: Derek T Walker
    @change: 2012/08/06 Derek Walker - Original Implementation
    @change: 2015/08/20 eball - Added getPackageFromFile
    @change: 2017/04/27 Breen Malmberg - added two methods checkUpdate
            and Update; fixed doc string formatting; removed detailedresults
            reset in init; replaced with --force-yes flag with --assume-yes
            (from the man page for apt-get: Force yes. This is a dangerous
            option that will cause apt-get to continue without prompting
            if it is doing something potentially harmful. It should not
            be used except in very special situations. Using --force-yes
            can potentially destroy your system!)
    @change: 2017/08/16 bgonz12 - Added DEBIAN_FRONTEND=noninteractive env var
            to remove function
    @change: 2017/10/18 Breen Malmberg - changed class var names to be more self-explanatory;
            changed command to check whether there are available packages to use the canonical
            debian/ubuntu method; added calls to repoError exception to determine exact nature
            and cause of any errors with querying or calling repositories on the system (this adds
            logging of the nature and cause(s) as well); changed log messaging to be more consistent
            in style/format; removed calls to validateParam due to concerns about the stability and
            reliability of that method


    """

    def __init__(self, logger):

        self.logger = logger
        self.ch = CommandHelper(self.logger)

        self.aptgetloc = "/usr/bin/apt-get"
        self.aptcacheloc = "/usr/bin/apt-cache"
        self.dpkgloc = "/usr/bin/dpkg"

        self.aptinstall = "DEBIAN_FRONTEND=noninteractive " + self.aptgetloc + " -y --assume-yes install "
        self.aptremove = "DEBIAN_FRONTEND=noninteractive " + self.aptgetloc + " -y remove "

        self.aptchkupdates = self.aptgetloc + " list --upgradeable "
        self.aptupgrade = self.aptgetloc + " -u upgrade --assume-yes "
        self.checkinstalled = "/usr/bin/apt list --installed "
        self.checkavailable = "/usr/bin/apt-cache search --names-only "
        self.findpkgforfilename = "/usr/bin/dpkg -S "
        self.pkgerrors = [1,100]

    def installpackage(self, package):
        """Install a package. Return a bool indicating success or failure.

        :param package: string; Name of the package to be installed, must be
                recognizable to the underlying package manager.
        :returns: installed
        :rtype: bool
@author: Derek Walker
@change: Breen Malmberg - 4/27/2017 - fixed doc string formatting;
        method now returns a variable; parameter validation added
        detailedresults replaced with logging
@change: Breen Malmberg - 10/1/2018 - added check for package manager lock and retry loop

        """

        installed = True
        maxtries = 12
        trynum = 0
        pslist = ["apt", "apt-get", "dpkg"]

        if type(package) is bytes:
            package = package.decode('utf-8')

        for ps in pslist:
            while psRunning(ps):
                trynum += 1
                if trynum == maxtries:
                    self.logger.log(LogPriority.DEBUG, "Timed out while attempting to install package, due to Apt package manager being in-use by another process.")
                    installed = False
                    return installed
                else:
                    self.logger.log(LogPriority.DEBUG, "Apt package manager is in-use by another process. Waiting for it to be freed...")
                    time.sleep(5)

        try:

            self.ch.executeCommand(self.aptinstall + package)
            retcode = self.ch.getReturnCode()
            errstr = self.ch.getErrorString()
            # recursive call to this method if package manager is still locked
            if re.search("Could not get lock", errstr, re.I):
                self.logger.log(LogPriority.DEBUG, "Apt package manager is in-use by another process. Waiting for it to be freed...")
                time.sleep(5)
                return self.installpackage(package)
            elif retcode in self.pkgerrors:
                installed = False
                self.logger.log(LogPriority.DEBUG, str(errstr))

            if installed:
                self.logger.log(LogPriority.DEBUG, "Successfully installed package " + str(package))
            else:
                self.logger.log(LogPriority.DEBUG, "Failed to install package " + str(package))

        except Exception:
            raise
        return installed

    def removepackage(self, package):
        """Remove a package. Return a bool indicating success or failure.

        :param package: string; Name of the package to be removed, must be
                recognizable to the underlying package manager.
        :returns: removed
        :rtype: bool
@author: Derek T. Walker

        """

        removed = True
        maxtries = 12
        trynum = 0
        pslist = ["apt", "apt-get", "dpkg"]

        if type(package) is bytes:
            package = package.decode('utf-8')

        for ps in pslist:
            while psRunning(ps):
                trynum += 1
                if trynum == maxtries:
                    self.logger.log(LogPriority.DEBUG, "Timed out while attempting to remove package, due to Apt package manager being in-use by another process.")
                    removed = False
                    return removed
                else:
                    self.logger.log(LogPriority.DEBUG, "Apt package manager is in-use by another process. Waiting for it to be freed...")
                    time.sleep(5)

        try:

            self.ch.executeCommand(self.aptremove + package)
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrors:
                errstr = self.ch.getErrorString()
                removed = False
                self.logger.log(LogPriority.DEBUG, str(errstr))

            if removed:
                self.logger.log(LogPriority.DEBUG, "Successfully removed package " + str(package))
            else:
                self.logger.log(LogPriority.DEBUG, "Failed to remove package " + str(package))

        except Exception:
            raise
        return removed

    def checkInstall(self, package):
        """Check the installation status of a package. Return a bool; True if
        the package is installed.

        :param package: 
        :returns: installed
        :rtype: bool
@author: Derek Walker
@change: Breen Malmberg - 4/27/2017 - fixed doc string formatting;
        method now returns a variable; replaced detailedresults with
        logging

        """

        installed = False
        maxtries = 12
        trynum = 0
        pslist = ["apt", "apt-get", "dpkg"]

        if type(package) is bytes:
            package = package.decode('utf-8')

        for ps in pslist:
            while psRunning(ps):
                trynum += 1
                if trynum == maxtries:
                    self.logger.log(LogPriority.DEBUG, "Timed out while attempting to check status of package, due to Apt package manager being in-use by another process.")
                    installed = False
                    return installed
                else:
                    self.logger.log(LogPriority.DEBUG, "Apt package manager is in-use by another process. Waiting for it to be freed...")
                    time.sleep(5)

        try:

            self.ch.executeCommand(self.checkinstalled + package)
            retcode = self.ch.getReturnCode()
            outputstr = self.ch.getOutputString()
            if retcode in self.pkgerrors:
                errstr = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG, str(errstr))

            if re.search(package + ".*installed", outputstr, re.I):
                installed = True

            if not installed:
                self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " is NOT installed")
            else:
                self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " is installed")

        except Exception:
            raise
        return installed

    def checkAvailable(self, package):
        """check if a given package is available

        :param package: string; Name of package to check
        :returns: found
        :rtype: bool
@author: Derek T. Walker
@change: Breen Malmberg - 4/27/2017 - created doc string;
        pulled result logging out of conditional

        """

        found = False
        outputstr = ""
        maxtries = 12
        trynum = 0
        pslist = ["apt", "apt-get", "dpkg"]

        if type(package) is bytes:
            package = package.decode('utf-8')

        for ps in pslist:
            while psRunning(ps):
                trynum += 1
                if trynum == maxtries:
                    self.logger.log(LogPriority.DEBUG,
                                    "Timed out while attempting to check availability of package, due to apt package manager being in-use by another process.")
                    available = False
                    return available
                else:
                    self.logger.log(LogPriority.DEBUG,
                                    "apt package manager is in-use by another process. Waiting for it to be freed...")
                    time.sleep(5)

        try:

            self.ch.executeCommand(self.checkavailable + "^" + package + "$")
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrors:
                errstr = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG, errstr)
            else:
                outputstr = self.ch.getOutputString()
                if re.search("^" + package, outputstr, re.I):
                    found = True

            if found:
                self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " is available to install")
            else:
                self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " is NOT available to install")

        except Exception:
            raise
        return found

    def Update(self, package=""):
        """update the specified package if any
        updates are available for it
        if no package is specified, apply
        all available updates for the system

        :param package: string; (OPTIONAL) name of package to update (Default value = "")
        :returns: updated
        :rtype: bool
@author: Breen Malmberg

        """

        updated = True

        try:

            if type(package) is bytes:
                package = package.decode('utf-8')

            self.ch.executeCommand(self.aptupgrade + package)
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrors:
                errstr = self.ch.getErrorString()
                updated = False
                self.logger.log(LogPriority.DEBUG, errstr)

            if package:
                if updated:
                    self.logger.log(LogPriority.DEBUG, "Package " + str(package) + " was updated successfully")
                else:
                    self.logger.log(LogPriority.DEBUG, "Failed to apply updates to package " + str(package))
            else:
                if updated:
                    self.logger.log(LogPriority.DEBUG, "All updates were installed successfully")
                else:
                    self.logger.log(LogPriority.DEBUG, "Failed to apply updates")

        except Exception:
            raise
        return updated

    def checkUpdate(self, package=""):
        """check for updates for specified package
        if no package is specified, then check
        for updates for the entire system

        :param package: string; (OPTIONAL) Name of package to check (Default value = "")
        :returns: updatesavail
        :rtype: bool
@author: Breen Malmberg

        """

        updatesavail = False

        try:

            self.ch.executeCommand(self.aptchkupdates + package)
            retcode = self.ch.getReturnCode()
            if retcode in self.pkgerrors:
                errstr = self.ch.getErrorString()
                self.logger.log(LogPriority.DEBUG, errstr)
            else:
                outputstr = self.ch.getOutputString()
                if re.search("upgradable", outputstr, re.I):
                    updatesavail = True

            if package:
                if updatesavail:
                    self.logger.log(LogPriority.DEBUG, "Updates are available for package " + str(package))
                else:
                    self.logger.log(LogPriority.DEBUG, "No updates are available for package " + str(package))
            else:
                if updatesavail:
                    self.logger.log(LogPriority.DEBUG, "Updates are available for this system")
                else:
                    self.logger.log(LogPriority.DEBUG, "No updates are available for this system")

        except Exception:
            raise
        return updatesavail

    def getPackageFromFile(self, filename):
        """Returns the name of the package that provides the given
        filename/path.

        :param filename: 
        :returns: packagename
        :rtype: string
@author: Eric Ball
@change: Breen Malmberg - 4/17/2017 - fixed doc string formatting;
        method now returns a variable; added param validation

        """

        packagename = ""

        try:

            try:
                self.ch.executeCommand(self.findpkgforfilename + filename)
                retcode = self.ch.getReturnCode()
                errstr = self.ch.getErrorString()
                if retcode != 0:
                    raise repoError('apt', retcode, str(errstr))
                if self.ch.getReturnCode() == 0:
                    output = self.ch.getOutputString()
                    packagename = output.split(":")[0]
            except repoError as repoerr:
                if not repoerr.success:
                    self.logger.log(LogPriority.WARNING, str(errstr))
                    pass

        except Exception:
            raise
        return packagename

    def getInstall(self):
        return self.aptinstall

    def getRemove(self):
        return self.aptremove
Beispiel #6
0
class SHupdaterc(ServiceHelperTemplate):
    """SHupdaterc is the Service Helper for systems using the rcupdate command to
    configure services. (Debian, Ubuntu and variants)


    """
    def __init__(self, environment, logdispatcher):
        """
        Constructor
        """
        super(SHupdaterc, self).__init__(environment, logdispatcher)
        self.environment = environment
        self.logdispatcher = logdispatcher
        self.ch = CommandHelper(self.logdispatcher)
        self.updaterc = "/usr/sbin/update-rc.d "
        self.svc = "/usr/sbin/service "

    def disableService(self, service, **kwargs):
        """Disables the service and terminates it if it is running.

        :param service: string; name of service
        :param kwargs: dict; dictionary of key-value arguments
        :param **kwargs: 
        :returns: enabled
        :rtype: bool
@author: ???

        """

        disabled = True

        self.logdispatcher.log(LogPriority.DEBUG,
                               "Disabling service: " + service)

        self.ch.executeCommand(self.updaterc + service + " disable")
        retcode = self.ch.getReturnCode()
        if retcode != 0:
            errmsg = self.ch.getErrorString()
            self.logdispatcher.log(LogPriority.DEBUG, errmsg)
            disabled = False
        else:
            if self.auditService(service):
                disabled = False

        if disabled:
            self.logdispatcher.log(LogPriority.DEBUG,
                                   "Successfully disabled service: " + service)

        return disabled

    def enableService(self, service, **kwargs):
        """Enables a service and starts it if it is not running as long as we are
        not in install mode

        :param service: string; name of service
        :param kwargs: dict; dictionary of key-value arguments
        :param **kwargs: 
        :returns: enabled
        :rtype: bool
@author: ???

        """

        enabled = True

        self.logdispatcher.log(LogPriority.DEBUG,
                               "Enabling service: " + service)

        self.ch.executeCommand(self.updaterc + service + " enable")
        retcode = self.ch.getReturnCode()
        if retcode != 0:
            errmsg = self.ch.getErrorString()
            self.logdispatcher.log(LogPriority.DEBUG, errmsg)
            enabled = False
        else:
            if not self.auditService(service):
                enabled = False

        if enabled:
            self.logdispatcher.log(LogPriority.DEBUG,
                                   "Successfully enabled service: " + service)

        return enabled

    def auditService(self, service, **kwargs):
        """Checks all /etc/rc*.d/ directories for the "S" (start) service entry
        in updaterc, if an "S" entry with the service name exists in any of the rc*.d/
        directories, it means that the service is scheduled to start at boot

        :param service: string; name of service
        :param kwargs: dict; dictionary of key-value arguments
        :param **kwargs: 
        :returns: enabled
        :rtype: bool
@author: ???

        """

        enabled = False

        self.logdispatcher.log(
            LogPriority.DEBUG,
            "Checking if service: " + service + " is enabled")

        self.ch.executeCommand("ls -l /etc/rc*.d/")
        if self.ch.findInOutput("S[0-9]+" + service):
            enabled = True

        if enabled:
            self.logdispatcher.log(LogPriority.DEBUG,
                                   "Service: " + service + " is enabled")
        else:
            self.logdispatcher.log(LogPriority.DEBUG,
                                   "Service: " + service + " is disabled")

        return enabled

    def isRunning(self, service, **kwargs):
        """Check to see if a service is currently running.

        :param service: string; name of service
        :param kwargs: dict; dictionary of key-value arguments
        :param **kwargs: 
        :returns: enabled
        :rtype: bool
@author: ???

        """

        running = False

        self.logdispatcher.log(
            LogPriority.DEBUG,
            "Checking if service: " + service + " is running")

        self.ch.executeCommand(self.svc + "--status-all")
        if self.ch.findInOutput("\[\s+\+\s+\]\s+" + service):
            running = True

        if running:
            self.logdispatcher.log(LogPriority.DEBUG,
                                   "Service: " + service + " IS running")
        else:
            self.logdispatcher.log(LogPriority.DEBUG,
                                   "Service: " + service + " is NOT running")

        return running

    def reloadService(self, service, **kwargs):
        """Reload (HUP) a service so that it re-reads it's config files. Called
        by rules that are configuring a service to make the new configuration
        active.

        :param service: string; name of service
        :param kwargs: dict; dictionary of key-value arguments
        :param **kwargs: 
        :returns: enabled
        :rtype: bool
@author: ???

        """

        reloaded = True

        self.logdispatcher.log(LogPriority.DEBUG,
                               "Reloading service: " + service)

        self.ch.executeCommand(self.svc + service + " stop")
        self.ch.executeCommand(self.svc + service + " start")
        retcode = self.ch.getReturnCode()
        if retcode != 0:
            reloaded = False
            errmsg = self.ch.getErrorString()
            self.logdispatcher.log(LogPriority.DEBUG, errmsg)
        else:
            if not self.isRunning(service):
                reloaded = False
                self.logdispatcher.log(LogPriority.DEBUG,
                                       "Failed to reload service: " + service)

        return reloaded

    def listServices(self, **kwargs):
        """Return a list containing strings that are service names.

        :param kwargs: dict; dictionary of key-value arguments
        :param **kwargs: 
        :returns: enabled
        :rtype: bool
@author: ???

        """

        services = []

        self.logdispatcher.log(LogPriority.DEBUG, "Fetching list of services")

        self.ch.executeCommand(self.svc + "--status-all")
        output = self.ch.getOutput()
        for line in output:
            if re.search("^\[", line):
                try:
                    services.append(line.split("]")[1].strip())
                except (IndexError, AttributeError):
                    continue

        return services

    def getStartCommand(self, service):
        """retrieve the start command.  Mostly used by event recording

        :param service: 
        :returns: string - start command
        @author: Derek Walker

        """
        return self.svc + service + ' start'

    def getStopCommand(self, service):
        """retrieve the stop command.  Mostly used by event recording

        :param service: 
        :returns: string - stop command
        @author: Derek Walker

        """
        return self.svc + service + ' stop'

    def getEnableCommand(self, service):
        """retrieve the enable command.  Mostly used by event recording

        :param service: 
        :returns: string - enable command
        @author: Derek Walker

        """
        return self.updaterc + service + ' enable'

    def getDisableCommand(self, service):
        """retrieve the start command.  Mostly used by event recording

        :param service: 
        :returns: string - disable command
        @author: Derek Walker

        """
        return self.updaterc + service + ' disable'
Beispiel #7
0
class Dnf(object):
    '''The template class that provides a framework that must be implemented by
    all platform specific pkgmgr classes.  Specifically for Fedora
    
    :version:
    @author: Derek T Walker 08-13-2015
    @change: Breen Malmberg - 4/18/2017 - refactor of multiple methods;
            removed detailedresults reset in __init__; added the -q
            (non-interactive) flag to install and remove command var's;
            added a dnf info command var;
            added parameter validation to each method


    '''
    def __init__(self, logger):
        self.logger = logger
        self.ch = CommandHelper(self.logger)
        self.dnfloc = "/usr/bin/dnf"
        self.install = self.dnfloc + " install -yq "
        self.remove = self.dnfloc + " remove -yq "
        self.search = self.dnfloc + " search "
        self.checkinstalled = self.dnfloc + " list --installed "
        self.chavailable = self.dnfloc + " list --available "
        self.checkupdate = self.dnfloc + " check-update "
        self.rpm = "/bin/rpm -qf "
        self.updatepackage = self.dnfloc + " -yq upgrade "
        self.lockfiles = [
            "/var/run/dnf.lock", "/var/run/dnf.pid", "/run/dnf.lock",
            "/run/dnf.pid"
        ]

    def installpackage(self, package):
        '''Install a package. Return a bool indicating success or failure.

        :param package: string; Name of the package to be installed, must be
                recognizable to the underlying package manager.
        :returns: installed
        :rtype: bool
@author: Derek T. Walker
@change: Breen Malmberg - 4/18/2017 - refactored method; added logging; replaced
        detailedresults with logging
@change: Breen Malmberg - 10/1/2018 - added check for package manager lock and retry loop

        '''

        installed = True
        maxtries = 12
        trynum = 0

        while psRunning("dnf"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Timed out while attempting to install package, due to dnf package manager being in-use by another process."
                )
                installed = False
                return installed
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "dnf package manager is in-use by another process. Waiting for it to be freed..."
                )
                time.sleep(5)

        try:

            try:
                self.ch.executeCommand(self.install + package)
                retcode = self.ch.getReturnCode()
                if retcode != 0:
                    raise repoError('dnf', retcode)
            except repoError as repoerr:
                if not repoerr.success:
                    installed = False

            if installed:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Successfully installed package " + str(package))
            else:
                self.logger.log(LogPriority.DEBUG,
                                "Failed to install package " + str(package))

        except Exception:
            raise
        return installed

    def removepackage(self, package):
        '''Remove a package. Return a bool indicating success or failure.

        :param package: string; Name of the package to be removed, must be
                recognizable to the underlying package manager.
        :returns: removed
        :rtype: bool
@author: Derek T. Walker
@change: Breen Malmberg - 4/18/2017

        '''

        removed = True
        maxtries = 12
        trynum = 0

        while psRunning("dnf"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Timed out while attempting to remove package, due to dnf package manager being in-use by another process."
                )
                installed = False
                return installed
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "dnf package manager is in-use by another process. Waiting for it to be freed..."
                )
                time.sleep(5)

        try:

            try:
                self.ch.executeCommand(self.remove + package)
                retcode = self.ch.getReturnCode()
                if retcode != 0:
                    raise repoError('dnf', retcode)
            except repoError as repoerr:
                if not repoerr.success:
                    removed = False

            if removed:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Package " + str(package) + " was successfully removed")
            else:
                self.logger.log(LogPriority.DEBUG,
                                "Failed to remove package " + str(package))

        except Exception:
            raise
        return removed

    def checkInstall(self, package):
        '''Check the installation status of a package. Return a bool; True if
        the package is installed.

        :param package: 
        :returns: installed
        :rtype: bool
@author: Derek T. Walker
@change: Breen Malmberg - 4/18/2017

        '''

        installed = False
        errstr = ""
        outputstr = ""
        maxtries = 12
        trynum = 0

        while psRunning("dnf"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Timed out while attempting to check status of package, due to dnf package manager being in-use by another process."
                )
                installed = False
                return installed
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "dnf package manager is in-use by another process. Waiting for it to be freed..."
                )
                time.sleep(5)

        try:

            try:
                # There is no dnf search command which will only return an
                # "installed" result set. Therefore we must parse the output
                # to determine if the package is installed or just available.
                # The below command string will produce stdout with only the
                # installed result set of packages
                self.ch.executeCommand(self.checkinstalled + package +
                                       " | grep -iA 1 installed")
                retcode = self.ch.getReturnCode()
                errstr = self.ch.getErrorString()
                outputstr = self.ch.getOutputString()
                # With this command specifically, in this package manager, we
                # can't count exit code 1 as being an error because the check installed
                # command (with dnf) will return an error (1) exit code if no results are
                # returned, even if there is no error. We also can't use error or output strings
                # to parse because it is possible for this command to also return no output of any
                # kind, in addition to returning a 1 exit code... Therefore we must exempt exit
                # code 1 for this command specifically...
                if retcode != 0 | 1:
                    raise repoError('dnf', retcode, str(errstr))
                else:
                    if re.search(package, outputstr, re.IGNORECASE):
                        installed = True
            except repoError as repoerr:
                if not repoerr.success:
                    self.logger.log(LogPriority.WARNING, str(errstr))
                    installed = False
                else:
                    if re.search(package, outputstr, re.IGNORECASE):
                        installed = True

            if installed:
                self.logger.log(LogPriority.DEBUG,
                                "Package " + str(package) + " is installed")
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Package " + str(package) + " is NOT installed")

        except Exception:
            raise
        return installed

    def checkAvailable(self, package):
        '''check if the given package is available to install

        :param package: string; name of package to check for
        :returns: found
        :rtype: bool
@author: Derek T. Walker
@change: Breen Malmberg - 4/18/2017 - added doc string; refactor of method

        '''

        found = False
        maxtries = 12
        trynum = 0

        while psRunning("dnf"):
            trynum += 1
            if trynum == maxtries:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Timed out while attempting to check availability of package, due to dnf package manager being in-use by another process."
                )
                found = False
                return found
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "dnf package manager is in-use by another process. Waiting for it to be freed..."
                )
                time.sleep(5)

        try:

            try:
                self.ch.executeCommand(self.chavailable + package)
                retcode = self.ch.getReturnCode()
                outputstr = self.ch.getOutputString()
                errstr = self.ch.getErrorString()
                if retcode != 0:
                    raise repoError('dnf', retcode, str(errstr))
                else:
                    if re.search(package, outputstr, re.IGNORECASE):
                        found = True
            except repoError as repoerr:
                if not repoerr.success:
                    self.logger.log(LogPriority.WARNING, str(errstr))
                else:
                    if re.search(package, outputstr, re.IGNORECASE):
                        found = True

            if found:
                self.logger.log(
                    LogPriority.DEBUG,
                    "Package " + str(package) + " is available to install")
            else:
                self.logger.log(
                    LogPriority.DEBUG,
                    "No package " + str(package) + " available to install")

        except Exception:
            raise
        return found

    def checkUpdate(self, package=""):
        '''check the specified package for updates
        if no package is specified, check for all/any
        updates on the system
        return True if there are updates available
        return False if there are no updates available

        :param package: string; name of package to check (Default value = "")
        :returns: updatesavail
        :rtype: bool
@author: Breen Malmberg

        '''

        updatesavail = False

        try:

            try:
                self.ch.executeCommand(self.checkupdate + package)
                retcode = self.ch.getReturnCode()
                errstr = self.ch.getErrorString()
                if retcode != 0:
                    raise repoError('dnf', retcode)
            except repoError as repoerr:
                if not repoerr.success:
                    self.logger.log(LogPriority.WARNING, str(errstr))
                    return False
                else:
                    updatesavail = True

            if package:
                if updatesavail:
                    self.logger.log(LogPriority.DEBUG, "Updates are available")
                else:
                    self.logger.log(LogPriority.DEBUG,
                                    "No updates are available")
            else:
                if updatesavail:
                    self.logger.log(
                        LogPriority.DEBUG,
                        "Updates are available for package " + str(package))
                else:
                    self.logger.log(
                        LogPriority.DEBUG,
                        "No updates are available for package " + str(package))

        except Exception:
            raise
        return updatesavail

    def Update(self, package=""):
        '''update the specified package
        if no package is specified, update
        all packages on the system

        :param package: string; name of package to update (Default value = "")
        :returns: updated
        :rtype: bool
@author: Breen Malmberg

        '''

        updated = True

        try:

            try:
                self.ch.executeCommand(self.updatepackage + package)
                retcode = self.ch.getReturnCode()
                errstr = self.ch.getErrorString()
                if retcode != 0:
                    raise repoError('dnf', retcode)
                else:
                    updated = True
            except repoError as repoerr:
                if not repoerr.success:
                    self.logger.log(LogPriority.WARNING, str(errstr))
                    return False
                else:
                    updated = True

            if package:
                if updated:
                    self.logger.log(
                        LogPriority.DEBUG,
                        "Package " + str(package) + " successfully updated")
                else:
                    self.logger.log(
                        LogPriority.DEBUG,
                        "Package " + str(package) + " was NOT updated")
            else:
                if updated:
                    self.logger.log(LogPriority.DEBUG,
                                    "All packages updated successfully")
                else:
                    self.logger.log(
                        LogPriority.DEBUG,
                        "One or more packages failed to update properly")

        except Exception:
            raise
        return updated

    def getPackageFromFile(self, filename):
        '''return a string with the name of the parent package
        in it

        :param filename: 
        :returns: packagename
        :rtype: string
@author: Eric Ball
@change: Breen Malmberg - 4/18/2017 - fixed doc string; refactored method

        '''

        packagename = ""

        try:

            try:
                self.ch.executeCommand(self.rpm + filename)
                retcode = self.ch.getReturnCode()
                errstr = self.ch.getErrorString()
                outputstr = self.ch.getOutputString()
                if retcode != 0:
                    raise repoError('dnf', retcode, str(errstr))
                else:
                    packagename = outputstr
            except repoError as repoerr:
                if not repoerr.success:
                    self.logger.log(LogPriority.WARNING, str(errstr))
                else:
                    packagename = outputstr

        except Exception:
            raise
        return packagename

    def getInstall(self):
        return self.install

    def getRemove(self):
        return self.remove

    def getSearch(self):
        return self.search

    def getInfo(self):
        return self.info

    def getCheck(self):
        return self.checkupdate