示例#1
0
class Sample2Plugin(Plugin):
    """This plugin will defin one more function and use it in a newly defined fix flow."""
    #
    # Additional flow defprepareion.
    #
    flows = Flow.init(Plugin)
    flows["fix"] = Flow({
                    Plugin.initial: {Return: "prepare"},
                    "prepare"     : {ReturnSuccess: "diagnose"},
                    "diagnose"    : {ReturnSuccess: "clean", ReturnFailure: "backup"},
                    "backup"      : {ReturnSuccess: "fix", ReturnFailure: "clean"},
                    "restore"     : {ReturnSuccess: "clean", ReturnFailure: "clean"},
                    "fix"         : {ReturnSuccess: "extraStep", ReturnFailure: "restore"},
                    "extraStep"   : {ReturnSuccess: "clean", ReturnFailure: "clean"},
                    "clean"       : {ReturnSuccess: Plugin.final}
                    }, description="Fixing sequence with one added extraStep")

    name = "Sample2Plugin"
    version = "0.0.1"
    author = "Joel Andres Granados"

    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)
        self._issue = SimpleIssue(self.name, self.description)

    def prepare(self):
        self._issue.set(reporting  = self._reporting, origin = self, level = PLUGIN)
        self._result=ReturnSuccess

    def clean(self):
        self._result=ReturnSuccess

    def backup(self):
        self._result=ReturnSuccess

    def restore(self):
        self._result=ReturnSuccess

    def diagnose(self):
        self._issue.set(checked = True, happened = True, reporting  = self._reporting, origin = self, level = PLUGIN)
        self._result=ReturnFailure

    def fix(self):
        self._issue.set(fixed = True, reporting  = self._reporting, origin = self, level = PLUGIN)
        self._result=ReturnSuccess

    def extraStep(self):
        self._result=ReturnSuccess
示例#2
0
class OpenSCAPPlugin(Plugin):
    """Performs security audit according to the SCAP policy"""
    name = "OpenSCAP audit"
    version = "0.1.0"
    author = "Martin Sivak <*****@*****.**>"

    flows = Flow.init()
    flows["oscap_scan"] = Flow({
        Plugin.initial: {Return: "prepare"},
        "prepare": {ReturnSuccess: "policy", ReturnFailure: "clean"},
        "policy": {ReturnSuccess: "rules", ReturnFailure: "clean",
                   ReturnAbort: "clean"},
        "rules": {ReturnSuccess: "tailoring", ReturnFailure: "clean",
                  ReturnBack: "policy", ReturnAbort: "clean"},
        "tailoring": {ReturnSuccess: "diagnose", ReturnFailure: "clean",
                      ReturnBack: "rules", ReturnAbort: "clean"},
        "diagnose": {ReturnSuccess: "results", ReturnFailure: "clean"},
        "results": {ReturnSuccess: "clean", ReturnFailure: "clean"},
        "clean": {ReturnSuccess: Plugin.final}
        }, description = "Performs a security and configuration audit of running system")
    flows["oscap_scan"].title = "Security Audit"

    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)
        self._oval = "/usr/share/openscap/oval.xml"
        self._xccdf = "/usr/share/openscap/scap-xccdf.xml"
        self._issues = {}
    
    def prepare(self):
        try:
            self._objs = openscap.xccdf.init(self._xccdf)
        except ImportError, e:
            self._reporting.error(str(e), origin = self, level = PLUGIN)
            self._result=ReturnFailure
            return
        
        self._xccdf_policy_model = self._objs["policy_model"]
        self._policy = None
        
        self._xccdf_policy_model.register_output_callback(self.oscap_callback, self)
        self._xccdf_policy_model.register_start_callback(self.oscap_callback_start, self)
        
        self._reporting.info("OpenSCAP initialized", origin = self, level = PLUGIN)
        self._result=ReturnSuccess
示例#3
0
class BlueprintPlugin(Plugin):
    """This blueprint plugin template."""
    name = "Yum repositories"
    version = "0.0.1"
    author = "Martin Sivak"

    flows = Flow.init(Plugin)
    del flows["fix"]
    flows["blueprint"] = flows["diagnose"]

    def blueprint(self):
        pass
示例#4
0
class RPMPlugin(IssuesPlugin):
    """This plugin provides checks for RPM database."""
    #
    # Additional flow defprepareion.
    #
    flows = Flow.init(IssuesPlugin)

    name = "RPM plugin"
    version = "0.0.1"
    author = "Martin Sivak"

    issue_tests = [RequiredPackages]
    set_flags = ["rpm_consistent"]

    @classmethod
    def getDeps(cls):
        return set(["root", "experimental", "filesystem", "rpm_lowlevel"])

    def __init__(self, *args, **kwargs):
        IssuesPlugin.__init__(self, *args, **kwargs)
        self.rpm = None

    def prepare(self):
        self._reporting.info(self.name + " in Prepare task",
                             origin=self,
                             level=PLUGIN)
        self.rpm = rpm.ts(Config.system.root)
        IssuesPlugin.prepare(self)

    def backup(self):
        self._reporting.info(self.name + " in backup task",
                             origin=self,
                             level=PLUGIN)
        self._result = ReturnSuccess

    def restore(self):
        self._reporting.info(self.name + " in Restore task",
                             origin=self,
                             level=PLUGIN)
        self._result = ReturnSuccess

    def clean(self):
        self._reporting.info(self.name + " in Clean task",
                             origin=self,
                             level=PLUGIN)
        del self.rpm
        self._result = ReturnSuccess
示例#5
0
class PluginInfo(Plugin):
    name = "TestInfoPlugin"
    version = "3.4.5"
    author = "John Galt"
    flows = {}
    flows["newflow"] = Flow(
        {
            Plugin.initial: {
                Return: "prepare"
            },
            "prepare": {
                ReturnSuccess: "fix"
            },
            "fix": {
                ReturnSuccess: "clean",
                ReturnFailure: "clean"
            },
            "clean": {
                ReturnSuccess: Plugin.final
            }
        },
        description="This is the newflow")

    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)

    def prepare(self):
        pass

    def backup(self):
        pass

    def restore(self):
        pass

    def diagnose(self):
        pass

    def fix(self):
        pass

    def clean(self):
        pass
示例#6
0
class RPMLowlevelPlugin(IssuesPlugin):
    """This plugin provides lowlevel checks for RPM database."""
    #
    # Additional flow defprepareion.
    #
    flows = Flow.init(IssuesPlugin)

    name = "RPM lowlevel structure plugin"
    version = "0.0.1"
    author = "Martin Sivak"

    issue_tests = [Packages, Locks]
    set_flags = ["rpm_lowlevel"]

    @classmethod
    def getDeps(cls):
        return set(["root", "experimental", "filesystem"])

    def __init__(self, *args, **kwargs):
        IssuesPlugin.__init__(self, *args, **kwargs)
        self.rpm = None

    def prepare(self):
        self.backup = self._backups.getBackup(self.__class__.__name__+" -- "+self.name)
        IssuesPlugin.prepare(self)

    def backup(self):
        IssuesPlugin.backup(self)
        self.backup.backupPath(path = os.path.join(Config.system.root,"/var/lib/rpm"), name="rpm")
        self._result=ReturnSuccess

    def restore(self):
        self.backup.restorePath(path = os.path.join(Config.system.root,"/var/lib/rpm"), name="rpm")
        IssuesPlugin.restore(self)
        self._result=ReturnSuccess

    def clean(self):
        self._backups.closeBackup(self.backup._id)
        IssuesPlugin.clean(self)
        self._result=ReturnSuccess
示例#7
0
class KeyRecoveryPlugin(Plugin):
    """This plugin allows restoring access to encrypted volumes using escrow
    packets generated by volume_key."""

    flows = {}
    flows["recoverEncryptionKey"] = Flow(
        {
            Plugin.initial: {
                Return: "findEncryptedVolumes"
            },
            "findEncryptedVolumes": {
                ReturnSuccess: "openPacket",
                ReturnFailure: Plugin.final,
                None: Plugin.final
            },
            "openPacket": {
                ReturnSuccess: "addPassphrase",
                ReturnFailure: Plugin.final,
                None: Plugin.final
            },
            "addPassphrase": {
                ReturnSuccess: Plugin.final,
                ReturnFailure: Plugin.final,
                None: Plugin.final
            }
        },
        description="Add a password to an encrypted volume "
        "using a provided escrow packet")

    name = "Encryption key recovery plugin"
    version = "0.0.1"
    author = "Miloslav Trmač"
    description = "Automates recovery of LUKS volume key"

    @classmethod
    def getDeps(cls):
        return set(["root"])

    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)

        self._ui = volume_key.UI()
        self._ui.generic_cb = self._vk_ui_generic_cb
        self._ui.passphrase_cb = self._vk_ui_passphrase_cb

    def _vk_ui_generic_cb(self, prompt, echo):
        prompt = "%s:" % (prompt, )
        if echo:
            r = self._reporting.text_question_wait(prompt, origin=self)
        else:
            r = self._reporting.password_question_wait(prompt, origin=self)
        if r == '':
            return None
        return r

    def _vk_ui_passphrase_cb(self, prompt, unused_failed_attempts):
        r = self._reporting.password_question_wait("%s:" % (prompt, ),
                                                   origin=self)
        if r == '':
            return None
        return r

    def findEncryptedVolumes(self):
        # Note: This assumes "the system" has automatically set up RAID, LVM
        # etc. to make the encrypted volumes visible.
        self._volumes = collections.defaultdict(list)
        with open("/proc/partitions") as f:
            for line in f.readlines()[2:]:
                (major, minor, blocks, name) = line.split()
                if name.startswith("ram"):
                    continue
                path = "/dev/%s" % name
                try:
                    vol = volume_key.Volume.open(path)
                except RuntimeError, e:
                    self._reporting.info("Error examining %s: %s" %
                                         (path, str(e)),
                                         origin=self,
                                         importance=logging.DEBUG)
                else:
                    if vol.format in (volume_key.VOLUME_FORMAT_LUKS, ):
                        self._volumes[vol.uuid].append(path)
        if len(self._volumes) == 0:
            self._reporting.info("No encrypted volume found", origin=self)
            self._result = ReturnFailure
            return
        self._result = ReturnSuccess
示例#8
0
class Xserver(Plugin):
    """ Plugin to detect an rescue faulty xserver configurations. """
    flows = Flow.init(Plugin)
    flows["force"] = Flow({
            Plugin.initial: {Return: "prepare"},
            "prepare"     : {ReturnSuccess: "diagnose2"},
            "diagnose2"   : {ReturnSuccess: "clean", ReturnFailure: "backup"},
            "backup"      : {ReturnSuccess: "fix", ReturnFailure: "clean"},
            "restore"     : {ReturnSuccess: "clean", ReturnFailure: "clean"},
            "fix"         : {ReturnSuccess: "clean", ReturnFailure: "restore"},
            "clean"       : {ReturnSuccess: Plugin.final}
          }, description="This flow skips the search for the xserver lock file")
    name = "X server"
    version = "0.0.1"
    author = "Joel Andres Granados"
    description = "Automates recovery of the xserver"

    @classmethod
    def getDeps(cls):
        return set(["root", "filesystem"])

    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)
        # Arbitrary test display
        self.display = ":10"
        self.confPath = "/etc/X11/xorg.conf"
        self.backupSpace = self._backups.getBackup(str(self))
        self._issue = SimpleIssue(self.name, "X server didn't start")

    def prepare(self):
        # Nothing to prepare really.
        self._result = ReturnSuccess
        self._issue.set(reporting = self._reporting, level = PLUGIN,
                origin = self)

    def diagnose(self):
        # Lets see if there is a server active.
        if os.path.exists("/tmp/.X0-lock"):
            self._reporting.info("An X server is already running.",
                    level = PLUGIN, origin = self)
            self._reporting.info("You can run the \"force\" flow to "
                    "avoud this check. In some cases it works.",
                    level = PLUGIN, origin = self)
            self._result = ReturnSuccess

        elif self.serverStart():
            self._reporting.info("Everything seems ok with the X server.",
                    level = PLUGIN, origin = self)
            self._result = ReturnSuccess

        elif not os.path.exists(self.confPath):
            # If the configuration is not there dont even bother to try
            #fixing it.  This will go through the proces of trying to fix
            #it.  at least we told the user.
            self._reporting.info("The error is in the xservers autodetection "
                    "mechanism, this does not have an automated solution yet.",
                    level = PLUGIN, origin = self)
            self._result = ReturnFailure

        else:
            self._reporting.info("X server is missconfigured.", level = PLUGIN,
                    origin = self)
            self._result = ReturnFailure
        self._issue.set(checked = True,
                happened = (self._result == ReturnFailure),
                reporting = self._reporting, level = PLUGIN, origin = self)

    def diagnose2(self):
        """Just a diagnose without the lock check"""
        if self.serverStart():
            self._reporting.info("Everything seems ok with the X server.",
                    level = PLUGIN, origin = self)
            self._result = ReturnSuccess

        elif not os.path.exists(self.confPath):
            # If the configuration is not there dont even bother to try fixing it.
            # This will go through the proces of trying to fix it.  at least we
            #told the user.
            self._reporting.info("The error is in the xservers autodetection "
                    "mechanism, this does not have an automated solution yet.",
                    level = PLUGIN, origin = self)
            self._result = ReturnFailure

        else:
            self._reporting.info("X server is missconfigured.", level = PLUGIN,
                    origin = self)
            self._result = ReturnFailure
        self._issue.set(checked = True,
                happened = (self._result == ReturnFailure),
                reporting = self._reporting, level = PLUGIN, origin = self)


    def backup(self):
        if os.path.isfile(self.confPath):
            self.backupSpace.backupPath(self.confPath)
        else:
            self._reporting.info("%s does not exist." % self.confPath,
                    level = PLUGIN, origin = self)
        self._result = ReturnSuccess

    def fix(self):
        self._reporting.info("Starting the fix task.", level = PLUGIN,
                origin = self)
        # With the current xorg server the only thing that we need to do is to 
        # erase the conf file.
        if os.path.exists(self.confPath):
            os.remove(self.confPath)

        self._reporting.info("Testing modified environment", level = PLUGIN,
                origin = self)
        if self.serverStart():
            self._reporting.info("X server started successfully with no "
                    "config file.", level = PLUGIN, origin = self)
            self._reporting.info("If you must have a config file, create "
                    "one with system-config-display and place it at "
                    "/etc/X11/xorg.conf", level = PLUGIN, origin = self )
            self._result = ReturnSuccess

            # Lets give the user his previous file.
            if self.backupSpace.exists(path=self.confPath):
                self.backupSpace.restoreName(self.confPath,
                        "%s-FAKbackup"%self.confPath)

        else:
            self._reporting.info("X server is does not autodetect the users "
                    "environment.", level = PLUGIN, origin = self)
            self._result = ReturnFailure

        self._issue.set(fixed = (self._result == ReturnSuccess),
                reporting = self._reporting, level = PLUGIN, origin = self)

    def restore(self):
        if not self.backupSpace.exists(path=self.confPath):
            # This is the case where there is no config file.
            self._reporting.info("The backedup file was not present. Assuming "
                    "that xorg did not have a config file to begin with.", 
                    level = PLUGIN, origin = self)
        else:
            self._reporting.info("Restoring original file.", level = PLUGIN ,
                    origin = self)
            self.backupSpace.restoreName(self.confPath)

        self._result = ReturnSuccess

    def clean(self):
        self._result = ReturnSuccess


    def serverStart(self):
        self._reporting.info("Trying to start X server", level = PLUGIN,
                origin = self)
        xorgargs = [self.display]
        try:
            proc = spawnvch(executable = "/usr/bin/Xorg", args = xorgargs,
                    chroot = Config.system.root)
            self._reporting.info("Waiting for the X server to start...",
                    level = PLUGIN, origin = self)
            time.sleep(5)
            if proc.poll() is not None:
                # process has terminated, failed.
                raise OSError
        except:
            self._reporting.info("The X server has failed to start",
                    level = PLUGIN, origin = self)
            return False
        self._reporting.info("The X server has started successfully",
                level = PLUGIN, origin = self)
        os.kill(proc.pid, signal.SIGINT)
        return True
class UndeletePartition(Plugin):
    """Plugin to detect and correct deleted partitions from system disks.

    Uses parted libriary to search for partitions that are not included in
    the partition table of a disk.  If it is possible, this plugin will put
    the partition back into the parition table so it is visible to the
    system again.
    """

    flows = Flow.init(Plugin)
    # We have not restore in the noBackup flow because we have no information to restore with.
    flows["noBackup"] = Flow({
                    Plugin.initial: {Return: "prepare"},
                    "prepare"     : {ReturnSuccess: "diagnose"},
                    "diagnose"    : {ReturnSuccess: "clean", ReturnFailure: "fix"},
                    "fix"         : {ReturnSuccess: "clean", ReturnFailure: "clean"},
                    "clean"       : {ReturnSuccess: Plugin.final}
                    }, description="This flow skips the backup test.  Use with care.")

    name = "Undelete Partitions"
    version = "0.1.0"
    author = "Joel Andres Granados"
    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)

        # Dictionary that will hold the partitions that are not included in the
        # partition table of a certain disk and can be recovered. It will also
        # house the initial partition table and the partition table that is a
        # result of running the fix.  The structure is:
        # slef.disks={diskname: [ [recoverables], initialPT, finalPT ], .... }
        self.disks = {}

    def prepare(self):
        # For now there is no real action in the prepare task.
        self._result=ReturnSuccess

    #
    # The diagnose will not be a real diagnose but more of an informative task.
    # It will report all the possible paritions that could house a rescuable
    # partition.
    #
    def diagnose(self):
        self._reporting.info("Beginning Diagnose...", origin = self, level = PLUGIN)
        self.disks = _undelpart.getDiskList()
        self._reporting.info("Disks present in the system %s"%self.disks.keys(),
                origin = self, level = PLUGIN)
        # When we find a rescuable partition we change this to true.
        rescuablePresent = False
        for disk, elements in self.disks.iteritems():
            self.disks[disk] = [ _undelpart.getRescuable(disk), _undelpart.getPartitionList(disk), [] ]
            if len(self.disks[disk][0]) > 0:
                self._reporting.info("Possible partitions to recover in disk %s: %s"%(disk, self.disks[disk][0]),
                        origin = self, level = PLUGIN)
                rescuablePresent = True
        if not rescuablePresent:
            self._result = ReturnSuccess
            self._reporting.info("Did not find any partitions that need rescueing.",
                    origin = self, level = PLUGIN)
        else:
            self._result = ReturnFailure

    def backup(self):
        self._reporting.info("Backing up partition table." , origin = self, level = PLUGIN)
        # We actually already have the backup of the partition table in the self.disks dict.
        # Lets check anyway.
        backupSane = True
        for disk, members in self.disks.iteritems():
            if members[1] == None or len(members[1]) <= 0:
                # We don't really have the partition table backup.
                self._reporting.info("Couldn't backup the partition table for %s."%disk,
                        origin = self, level = PLUGIN)
                self._reporting.info("To force the recovery of this disk without the backup " \
                    "please run the flow named noBackup from this plugin.",
                    origin = self, level = PLUGIN)
                backupSane = False
                self._result = ReturnFailure

        if backupSane:
            self._result = ReturnSuccess

    #
    # Every partition that we suspect is rescuable, (given that it has a partition table from
    # wich we can recover if we mess up) we try to rescue.  This will take a long time.
    #
    def fix(self):
        self._reporting.info("Lets see if I can fix this... Starting fix task.",
                origin = self, level = PLUGIN)
        self._reporting.info("Might want to go and get a cup of coffee,"
                "this could take a looooooong time...", origin = self, level = PLUGIN)
        self._result = ReturnSuccess
        rescued = []
        try:
            for disk, members in self.disks.iteritems():
                if len(members[0]) > 0:#there are partitions to rescue :)
                    self._reporting.info("Trying to rescue %s from disk %s"%(members[0], disk),
                            origin = self, level = PLUGIN)
                    rescued = _undelpart.rescue(disk,members[0])
                    self._reporting.info("Partitions rescued: %s"%rescued,
                            origin = self, level = PLUGIN)
                elif len(members[0]) ==  0:
                    self._reporting.info("Nothing to rescue on disk %s."%disk,
                            origin = self, level = PLUGIN)
                else:
                    self_result = ReturnFailure
                    break
        except KeyboardInterrupt, e:
            self._reporting.error("Received a user interruption... Moving to Restore task.",
                    origin = self, level = PLUGIN, action = None)
            # The user might want to keep on pushing ctrl-c, lets lock the SIGINT signal.
            signal.signal(signal.SIGINT, keyboaordInterruptHandler)
            self._reporting.info("Please wait until the original partition table is recovered.",
                    origin = self, level = PLUGIN)
            self._result = ReturnFailure
示例#10
0
class RepositoriesPlugin(BlueprintPlugin):
    """This blueprint plugin retrieve list of all installed Yum repositories."""
    name = "Yum repositories"
    version = "0.0.1"
    author = "Martin Sivak"

    flows = Flow.init(Plugin)
    del flows["fix"]
    flows["blueprint"] = flows["diagnose"]

    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)
        self._issue = SimpleIssue(self.name, self.description)
        self._yum_repos_d = "/etc/yum.repos.d"

    def prepare(self):
        self._result = ReturnSuccess
        self._issue.set(reporting=self._reporting, origin=self, level=PLUGIN)

    def diagnose(self):
        self._reporting.info("Getting list of Yum repository files",
                             origin=self,
                             level=PLUGIN)
        repos = [
            n[:-5] for n in os.listdir(self._yum_repos_d)
            if n.endswith(".repo")
        ]

        for fn in repos:
            repo_issue = None
            try:
                repo_issue = SimpleIssue(
                    "reading Yum repo config %s" % fn,
                    "I was unable to process the repository configuration.")
                repo_issue.set(checked=False,
                               happened=False,
                               reporting=self._reporting,
                               origin=self,
                               level=PLUGIN)
                f = open(os.path.join(self._yum_repos_d, fn + ".repo"))
                content = f.read().replace("\\", "\\\\").replace("\n", "\\n")
                setattr(self._info, fn, content)
                f.close()
                repo_issue.set(checked=True,
                               happened=False,
                               reporting=self._reporting,
                               origin=self,
                               level=PLUGIN)
            except IOError:
                repo_issue.set(checked=True,
                               happened=True,
                               reporting=self._reporting,
                               origin=self,
                               level=PLUGIN)

        self._result = ReturnSuccess
        self._issue.set(checked=True,
                        happened=False,
                        reporting=self._reporting,
                        origin=self,
                        level=PLUGIN)

    def clean(self):
        self._result = ReturnSuccess
示例#11
0
class MdadmConfig(Plugin):
    """ Addresses the validity and presence of /etc/mdadm.conf """
    flows = Flow.init(Plugin)
    name = "mdadm configuration"
    version = "0.0.1"
    author = "Joel Andres Granados"
    description = "Assess the validity and existence of the mdadm.conf file"

    @classmethod
    def getDeps(cls):
        return set(["root", "filesystem"])

    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)
        self.currentFileDict = {}  #what we read from /etc/mdadm.conf
        self.scannedFileDict = {}  #what `mdadm --misc --detail --scan`
        self.scannedFile = None  # what `mdadm --misc --detail --scan` returns
        self.configFile = os.path.join(Config.system.root, "/etc/mdadm.conf")
        self.backupSpace = self._backups.getBackup(str(self))
        self._issue = SimpleIssue(self.name, "mdadm.con misconfigured")

    def prepare(self):
        # We read the configuration file if it exists
        if os.path.exists(self.configFile):
            self._reporting.info("Gathering information from %s." %
                                 self.configFile,
                                 level=PLUGIN,
                                 origin=self)
            fd = open(self.configFile, "r")
            for line in fd.readlines():
                splitline = line.strip("\n").split(" ")
                if "ARRAY" in splitline:
                    self.currentFileDict[splitline[1]] = splitline
            fd.close()

        else:
            self._reporting.info("File %s was not found." % self.configFile,
                                 level=PLUGIN,
                                 origin=self)

        # We execute the mdadm command
        self._reporting.info("Scanning for software raid with mdadm.",
                             level=PLUGIN,
                             origin=self)
        mdadmargs = ["--misc", "--detail", "--scan"]
        proc = spawnvch(executable="mdadm",
                        args=mdadmargs,
                        chroot=Config.system.root)
        (out, err) = proc.communicate()

        if err == '':
            # means that the command ran with no errors.
            for line in out.__str__().split("\n"):
                splitline = line.strip("\n").split(" ")
                if "ARRAY" in splitline:
                    self.scannedFileDict[splitline[1]] = splitline
            self.scannedFile = out
        else:
            # This should make the flow go to clean.  If there is an error we
            # should not trust what mdadm tells us.
            self._reporting.info("The mdadm command had the following " \
                    "error:%s. The plugin will silently exit."%err,
                    level = PLUGIN, origin = self)
            self._result = None
            return
        self._result = ReturnSuccess
        self._issue.set(reporting=self._reporting, level=PLUGIN, origin=self)

    def diagnose(self):
        # If nothing was returned by the mdadm command.  we dont have software
        # raid.
        if len(self.scannedFileDict) == 0:
            self._reporting.info("There was no sofware raid found by the " \
                    "mdadm command.... Nothing to do.", level = PLUGIN,
                    origin = self)
            self._result = ReturnSuccess
            self._issue.set(checked=True,
                            happened=False,
                            reporting=self._reporting,
                            level=PLUGIN,
                            origin=self)
            return

        # If nothing is detected the result is successfull.
        self._result = ReturnSuccess

        # If there is one difference between the configs, regarding the
        # ARRAYS.  We replace the config file. Lets check for missing arrays
        # in the curren config file.
        for key, value in self.scannedFileDict.iteritems():
            if not self.currentFileDict.has_key(key):
                self._reporting.info("Found that the current mdadm.conf is " \
                        "missing: %s."%value, level = PLUGIN, origin = self)
                self._result = ReturnFailure

        # Lets check for additional ARRAYS that should not be there.
        for key, value in self.currentFileDict.iteritems():
            if not self.scannedFileDict.has_key(key):
                self._reporting.info("The followint entry: %s, is in the " \
                        "config file but was not detected by mdadm."%value,
                        level = PLUGIN, origin = self)
                self._result = ReturnFailure

        if self._result == ReturnSuccess:
            self._reporting.info("There was no problem found with the " \
                    "current mdadm.conf file.", level = PLUGIN, origin = self)

        self._issue.set(checked=True,
                        happened=(self._result == ReturnFailure),
                        reporting=self._reporting,
                        level=PLUGIN,
                        origin=self)

    def backup(self):
        if os.path.isfile(self.configFile):
            self._reporting.info("Making a backup of %s." % self.configFile,
                                 level=PLUGIN,
                                 origin=self)
            self.backupSpace.backupPath(self.configFile)

        else:
            self._reporting.info("It appears that the file %s does not "\
                    "exist.  No backup attempt will be made."%self.configFile,
                    level = PLUGIN, origin = self)

        self._result = ReturnSuccess

    def fix(self):
        try:
            self._reporting.info("Going to write configuration to %s." %
                                 self.configFile,
                                 level=PLUGIN,
                                 origin=self)
            fd = open(self.configFile, "w")
            fd.write("# File created by Firstaidkit.\n")
            fd.write("# DEVICE partitions\n")
            fd.write("# MAILADDR root\n")
            fd.write(self.scannedFile)
            fd.close()
            self._reporting.info("Configuration file writen.",
                                 level=PLUGIN,
                                 origin=self)

            # The original mdadm.conf will be restore to
            # mdadm.conf.firstaidkit, just in case.
            self._reporting.info(
                "Will put the old mdadm.conf in %s." % os.path.join(
                    Config.system.root, self.configFile + ".firstaidkit"),
                level=PLUGIN,
                origin=self)
            self.backupSpace.restoreName(self.configFile,
                                         path=self.configFile + ".firstaidkit")
            self._result = ReturnSuccess

        except IOError:
            fd.close()
            self._reporting.info("Error occurred while writing %s." %
                                 self.configFile,
                                 level=PLUGIN,
                                 origin=self)
            self._result = ReturnFailure
        self._issue.set(fixed=(self._result == ReturnSuccess),
                        reporting=self._reporting,
                        level=PLUGIN,
                        origin=self)

    def restore(self):
        if not self.backupSpace.exists(self.configFile):
            # This is the case where there is no config file.
            self._reporting.info("The backedup file was not present. " \
                    "Assuming that %s was ont present to begin with."%
                    self.configFile, level = PLUGIN, original = self)
        else:
            self._reporting.info("Restoring original file.",
                                 level=PLUGIN,
                                 origin=self)
            self.backupSpace.restoreName(self.configFile)
        self._result = ReturnSuccess

    def clean(self):
        self._result = ReturnSuccess
示例#12
0
class mkinitrd(Plugin):
    """This plugin uses the predefined flow in the Plugin abstract class."""
    name = "mkinitrd"
    version = "0.0.1"
    author = "Adam Pribyl"

    flows = Flow.init(Plugin)
    flows["mkinitrd"] = flows["fix"]
    del flows["fix"]
    del flows["diagnose"]

    @classmethod
    def getDeps(cls):
        return set(["root"]).union(Plugin.getDeps())

    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)
        self._issue = SimpleIssue(self.name, self.description)
        self.initrd = None  #
        self.initrd_path = None
        self.kernel_version = None
        self.kernel_re = re.compile(".*initrd-(?P<kernel>.*)\.img")
        self.initrds = []  # array of intirds found ing menu.lst

    def prepare(self):
        self._issue.set(reporting=self._reporting, origin=self, level=PLUGIN)
        self._backup = self._backups.getBackup(self.__class__.__name__ +
                                               " -- " + self.name,
                                               persistent=False)
        self._reporting.info("mkinitrd in Prepare task",
                             origin=self,
                             level=PLUGIN)
        f = open(os.path.join(Config.system.root, "/boot/grub/menu.lst"))
        for l in f:
            ltmp = l.strip()
            self._reporting.debug("parsing line: %s" % ltmp,
                                  origin=self,
                                  level=PLUGIN)
            if ltmp.startswith("default"):
                self.initrd = int(ltmp[8:])
                self._reporting.debug("found default: %d" % self.initrd,
                                      origin=self,
                                      level=PLUGIN)
            elif ltmp.startswith("initrd"):
                self.initrds.append(ltmp.split()[1][1:])
                self._reporting.debug("found initrd: %s" % self.initrds[-1],
                                      origin=self,
                                      level=PLUGIN)

        self._reporting.debug("config root: %s" % Config.system.root,
                              origin=self,
                              level=PLUGIN)
        self._reporting.debug(
            "looking for: %s" %
            os.path.join(Config.system.root, self.initrds[self.initrd]),
            origin=self,
            level=PLUGIN)
        self._reporting.debug("looking for: %s" % os.path.join(
            Config.system.root, "boot", self.initrds[self.initrd]),
                              origin=self,
                              level=PLUGIN)
        if os.path.exists(
                os.path.join(Config.system.root, self.initrds[self.initrd])):
            self.initrd_path = os.path.join(Config.system.root,
                                            self.initrds[self.initrd])
        elif os.path.exists(
                os.path.join(Config.system.root, "boot",
                             self.initrds[self.initrd])):
            self.initrd_path = os.path.join(Config.system.root, "boot",
                                            self.initrds[self.initrd])
        else:
            self.result = ReturnFailure
            self._reporting.error("initrd not found",
                                  origin=self,
                                  level=PLUGIN)
            return

        self._reporting.info("initrd found: %s" % (self.initrd_path, ),
                             origin=self,
                             level=PLUGIN)
        m = self.kernel_re.match(self.initrds[self.initrd])
        if not m:
            self._reporting.error("kernel version not identified",
                                  origin=self,
                                  level=PLUGIN)
            self._result = ReturnFailure
            return

        self.kernel_version = m.group("kernel")
        self._reporting.info("kernel version: %s" % (self.kernel_version, ),
                             origin=self,
                             level=PLUGIN)
        self._result = ReturnSuccess

    def backup(self):
        self._reporting.info("mkinitrd in backup task",
                             origin=self,
                             level=PLUGIN)
        self._backup.backupPath(self.initrd_path)
        self._result = ReturnSuccess

    def restore(self):
        self._reporting.info("mkinitrd in Restore task",
                             origin=self,
                             level=PLUGIN)
        self._backup.restorePath(self.initrd_path)
        self._result = ReturnSuccess

    def diagnose(self):
        self._result = ReturnFailure
        self._issue.set(checked=True,
                        happened=True,
                        reporting=self._reporting,
                        origin=self,
                        level=PLUGIN)
        self._reporting.info("mkinitrd in diagnose task",
                             origin=self,
                             level=PLUGIN)

    def fix(self):
        self._issue.set(fixed=False,
                        reporting=self._reporting,
                        origin=self,
                        level=PLUGIN)
        self._reporting.info("mkinitrd in Fix task", origin=self, level=PLUGIN)
        print spawnvch("/sbin/mkinitrd", [
            "mkinitrd", self.initrd_path[len(Config.system.root):],
            self.kernel_version
        ], Config.system.root).communicate()
        self._result = ReturnFailure

    def clean(self):
        self._result = ReturnSuccess
        self._backups.closeBackup(self._backup._id)
        self._reporting.info("mkinitrd in Clean task",
                             origin=self,
                             level=PLUGIN)
示例#13
0
class Sample1Plugin(Plugin):
    """Discover information about the system"""
    name = "Discovery"
    description = "Discover properties of the system"
    version = "0.0.1"
    author = "Martin Sivak"

    flows = Flow.init(Plugin)
    flows["fix"] = flows["diagnose"]

    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)
        self._issue = SimpleIssue(self.name, "Discovering system properties failed")

    def prepare(self):
        self._issue.set(reporting  = self._reporting, origin = self, level = PLUGIN)
        self._result=ReturnSuccess

    def diagnose(self):
        #architecture and cpus
        (unamestdout, unamestderr) = spawnvch(executable = "/bin/uname", args = ["uname", "-a"], chroot = Config.system.root).communicate("")
        self._info.uname = unamestdout.split("\n")[0]

        #memory
        (freestdout, freestderr) = spawnvch(executable = "/usr/bin/free", args = ["free"], chroot = Config.system.root).communicate("")
        freedata = freestdout.split("\n")
        self._info.memory = freedata[1].split()[1]
        self._info.swap = freedata[3].split()[1]

        #pci
        pcilist = []
        (lspcistdout, lspcistderr) = spawnvch(executable = "/sbin/lspci", args = ["lspci"], chroot = Config.system.root).communicate("")
        for l in lspcistdout.split("\n"):
            try:
                (id, name) = l.split(" ", 1)
                setattr(self._info, "_".join(["pci", id]), name)
                pcilist.append(id)
            except:
                pass
        self._info.pci = " ".join(pcilist)

        #usb
        if os.path.exists(os.path.join(Config.system.root, "/proc/bus/usb")):
            self._info.usb = "True"
        else:
            self._info.usb = "False"

        #scsi
        if os.path.exists(os.path.join(Config.system.root, "/proc/scsi/device_info")):
            self._info.scsi = "True"
        else:
            self._info.scsi = "False"

        #ide
        if os.path.exists(os.path.join(Config.system.root, "/proc/ide")):
            self._info.ide = "True"
        else:
            self._info.ide = "False"

        #partitions
        partitionlist = []
        for l in open("/proc/partitions").readlines()[2:]:
            try:
                (major, minor, blocks, name) = l.split()
                if name.startswith("ram"):
                    continue
                setattr(self._info, "_".join(["partition", name]), blocks)
                partitionlist.append(name)
            except:
                continue
        self._info.partition = " ".join(partitionlist)

        #net


        self._dependencies.provide("discovery")
        self._issue.set(checked = True, happened = False, reporting  = self._reporting, origin = self, level = PLUGIN)
        self._result=ReturnSuccess

    def clean(self):
        self._result=ReturnSuccess