Example #1
0
    def archive(self):
        """
        It triggers the creation of the archive.

        :rtype: bool
        :return: it returns false in case of failure
        """
        #we need a valid swirl
        if not self.sergeant.check():
            logger.error("The fingerprint " + self.sergeant.filename +
                         " fails:\n  " +
                         "\n  ".join(self.sergeant.getError()) +
                         "\n\nThe archive creation failed.\n")
            return False
        # prepare the folders for the tar
        base_tar = tempfile.mkdtemp()
        base_path = os.path.join(base_tar, def_base_dir)
        os.mkdir(base_path)
        # copy all the files referenced by this swirl
        for swf in self.sergeant.swirl.swirlFiles:
            if swf.path[0] == '$' or sergeant.is_special_folder(swf.path) or \
                            is_special_file(swf.path):
                #TODO maybe we could keep user data into a special folder?
                # this file belongs to the special folders let's skip it
                continue
            if os.path.exists(swf.path) and swf.md5sum:
                # the file was not a temporary file
                dest_path_dir = os.path.join(base_path, swf.md5sum)
                dest_path_full = os.path.join(dest_path_dir,
                                              os.path.basename(swf.path))
                if not os.path.exists(dest_path_full):
                    # do not copy twice the same file
                    if not os.path.exists(dest_path_dir):
                        os.mkdir(dest_path_dir)
                    shutil.copy2(swf.path, dest_path_dir)
                    if sergeant.prelink:
                        utils.getOutputAsList(
                            [sergeant.prelink, "-u", dest_path_full])
            #for i in swf.links:
            #    new_link = os.path.join(temp_path, os.path.basename(i))
            #    if not os.path.exists( new_link ):
            #        os.symlink( os.path.basename(swf.path), new_link)
        # copy the swirl itself
        shutil.copy2(self.sergeant.filename,
                     os.path.join(base_tar, def_swirl_path))
        # let's do the tar
        tar = tarfile.open(self.archive_filename, "w:gz")
        cwd = os.getcwd()
        os.chdir(base_tar)
        tar.add(".")
        tar.close()
        os.chdir(cwd)
        shutil.rmtree(base_tar)
        return True
Example #2
0
    def archive(self):
        """
        It triggers the creation of the archive.

        :rtype: bool
        :return: it returns false in case of failure
        """
        #we need a valid swirl
        if not self.sergeant.check():
            logger.error("The fingerprint " + self.sergeant.filename + " fails:\n  " +
                "\n  ".join(self.sergeant.getError()) + "\n\nThe archive creation failed.\n")
            return False
        # prepare the folders for the tar
        base_tar = tempfile.mkdtemp()
        base_path = os.path.join(base_tar, def_base_dir)
        os.mkdir(base_path)
        # copy all the files referenced by this swirl
        for swf in self.sergeant.swirl.swirlFiles:
            if swf.path[0] == '$' or sergeant.is_special_folder(swf.path) or \
                            is_special_file(swf.path):
                #TODO maybe we could keep user data into a special folder?
                # this file belongs to the special folders let's skip it
                continue
            if os.path.exists(swf.path) and swf.md5sum:
		# the file was not a temporary file
                dest_path_dir = os.path.join(base_path, swf.md5sum)
                dest_path_full = os.path.join(dest_path_dir, os.path.basename(swf.path))
                if not os.path.exists(dest_path_full):
                    # do not copy twice the same file
                    if not os.path.exists(dest_path_dir):
                        os.mkdir(dest_path_dir)
                    shutil.copy2(swf.path, dest_path_dir)
                    if sergeant.prelink :
                        utils.getOutputAsList([sergeant.prelink, "-u", dest_path_full])
            #for i in swf.links:
            #    new_link = os.path.join(temp_path, os.path.basename(i))
            #    if not os.path.exists( new_link ):
            #        os.symlink( os.path.basename(swf.path), new_link)
        # copy the swirl itself
        shutil.copy2(self.sergeant.filename, os.path.join(base_tar, def_swirl_path))
        # let's do the tar
        tar = tarfile.open(self.archive_filename, "w:gz")
        cwd = os.getcwd()
        os.chdir(base_tar)
        tar.add(".")
        tar.close()
        os.chdir(cwd)
        shutil.rmtree(base_tar)
        return True
Example #3
0
    def _resolve_file(self, swirl_file, use_remapping = False):
        """ this function recursively try to resolve the swirlFile

        this function will add the package name to self.packages if it can find
        an rpm which can sattisfy it, if not, it will add this swirlf_file to the
        self.files """
        if swirl_file in self.files or swirl_file in self.processed_package:
            return
        self.processed_package.append(swirl_file)
        # if swirl_file.path in yum db add rpm to self.packages
        # else add swirl_file to self.files
        packages = []
        if 'ELF' in swirl_file.type and swirl_file.executable \
                and not (use_remapping and swirl_file.isLoader()):
            # executable and not a loader if we are using remppaing
            packages = self._get_package_from_dep([swirl_file.path])
        elif 'ELF' in swirl_file.type and not swirl_file.executable and not use_remapping:
            # library
            # do not process it if we are using remapping
            packages = self._get_package_from_dep(swirl_file.getPaths(), False)
        elif swirl_file.path[0] == '$' or sergeant.is_special_folder(swirl_file.path) \
                or is_special_file(swirl_file.path):
            # this file belongs to the special folders or it's a relative path
            return
        elif 'ELF' not in swirl_file.type:
            # data
            # TODO what do we do with this when we use remapping?
            packages = self._get_package_from_dep([swirl_file.path])
        if packages :
            if len(packages) > 1 :
                error_message = "The file " + swirl_file.path + " "
                error_message += "is provided by more than one RPM: " + ", ".join(packages)
                error_message += "\nAdding " + packages[0]
                logger.error(error_message)
            if swirl_file.package not in self.wanted_pcks and \
                packages[0] not in self._excluded_packages:
                self.skipped_swfs.add( swirl_file  )
                self.packages.add( packages[0] )
                # so we found a package which can handle this swf but we should still process its
                # opened file in case it is an interpreter
                self._process_open_file(swirl_file, use_remapping)
                logger.debug("Adding package " + packages[0] + " for swirl " + swirl_file.path)
                return
            else:
                self.disable_pcks |= set(packages)
        logger.debug("Adding swirl: " + swirl_file.path)
        if 'ELF' in swirl_file.type and not use_remapping:
            # for ELF swf if we select the libmpi.so.2 we also want to carry all its dynamic libraries
            # even if their name matches an available package for this reason we use wanted_pcks
            self.wanted_pcks.add(swirl_file.package)
        self.files.append(swirl_file)
        #
        # for each swf in swirlFile.all_dependencies
        #   if not already in self.files _resolve_file(swf)
        deps = self.swirl.getListSwirlFileProvide( swirl_file.staticDependencies )+\
                                swirl_file.dynamicDependencies
        for new_swf in deps:
            if new_swf not in self.files:
                #this file is already in the included files
                self._resolve_file(new_swf, use_remapping)
        self._process_open_file(swirl_file, use_remapping)
Example #4
0
    def _resolve_file(self, swirl_file, use_remapping=False):
        """ this function recursively try to resolve the swirlFile

        this function will add the package name to self.packages if it can find
        an rpm which can sattisfy it, if not, it will add this swirlf_file to the
        self.files """
        if swirl_file in self.files or swirl_file in self.processed_package:
            return
        self.processed_package.append(swirl_file)
        # if swirl_file.path in yum db add rpm to self.packages
        # else add swirl_file to self.files
        packages = []
        if 'ELF' in swirl_file.type and swirl_file.executable \
                and not (use_remapping and swirl_file.isLoader()):
            # executable and not a loader if we are using remppaing
            packages = self._get_package_from_dep([swirl_file.path])
        elif 'ELF' in swirl_file.type and not swirl_file.executable and not use_remapping:
            # library
            # do not process it if we are using remapping
            packages = self._get_package_from_dep(swirl_file.getPaths(), False)
        elif swirl_file.path[0] == '$' or sergeant.is_special_folder(swirl_file.path) \
                or is_special_file(swirl_file.path):
            # this file belongs to the special folders or it's a relative path
            return
        elif 'ELF' not in swirl_file.type:
            # data
            # TODO what do we do with this when we use remapping?
            packages = self._get_package_from_dep([swirl_file.path])
        if packages:
            if len(packages) > 1:
                error_message = "The file " + swirl_file.path + " "
                error_message += "is provided by more than one RPM: " + ", ".join(
                    packages)
                error_message += "\nAdding " + packages[0]
                logger.error(error_message)
            if swirl_file.package not in self.wanted_pcks and \
                packages[0] not in self._excluded_packages:
                self.skipped_swfs.add(swirl_file)
                self.packages.add(packages[0])
                # so we found a package which can handle this swf but we should still process its
                # opened file in case it is an interpreter
                self._process_open_file(swirl_file, use_remapping)
                logger.debug("Adding package " + packages[0] + " for swirl " +
                             swirl_file.path)
                return
            else:
                self.disable_pcks |= set(packages)
        logger.debug("Adding swirl: " + swirl_file.path)
        if 'ELF' in swirl_file.type and not use_remapping:
            # for ELF swf if we select the libmpi.so.2 we also want to carry all its dynamic libraries
            # even if their name matches an available package for this reason we use wanted_pcks
            self.wanted_pcks.add(swirl_file.package)
        self.files.append(swirl_file)
        #
        # for each swf in swirlFile.all_dependencies
        #   if not already in self.files _resolve_file(swf)
        deps = self.swirl.getListSwirlFileProvide( swirl_file.staticDependencies )+\
                                swirl_file.dynamicDependencies
        for new_swf in deps:
            if new_swf not in self.files:
                #this file is already in the included files
                self._resolve_file(new_swf, use_remapping)
        self._process_open_file(swirl_file, use_remapping)
Example #5
0
    def __init__(self, name, fileList, processIDs, execCmd):
        """give a file list and a name construct a swirl into memory """
        self._detectedPackageManager()
        self.swirl = Swirl(name, datetime.now())
        if execCmd:
            self.swirl.cmdLine = execCmd
        #
        # dependencies discovered with dinamic methods
        # dynamicDependencies = { 'binarypath' : [list of file it depends to],
        # '/bin/bash' : ['/lib/x86_64-linux-gnu/libnss_files-2.15.so',
        # '/lib/x86_64-linux-gnu/libnss_nis-2.15.so']}

        if execCmd:
            self._straceCmd(execCmd)

        # let's see if we have proecss ID we might need to scan for dynamic dependecies
        # with the help of the /proc FS
        elif processIDs:

            for proc in processIDs.split(','):
                pid = proc.strip()
                # add the binary
                tcb = FingerPrint.syscalltracer.TracerControlBlock(pid)
                tcb.updateSharedLibraries()

        dynamicDependecies = FingerPrint.syscalltracer.TracerControlBlock.dependencies
        # set up the fileList for the static dependency detection
        if not fileList:
            fileList = []
        # it does not work on python 2.5 aka RHEL 5.X
        # fileList = [f if f[0] == '/' else os.path.normpath(os.getcwd() + '/' + f)  for f in fileList]
        def norm_path(path):
            if path[0] == '/':
                return os.path.normpath(path)
            else:
                return os.path.normpath(os.getcwd() + '/' + path)

        fileList = [norm_path(f) for f in fileList]
        fileList = fileList + dynamicDependecies.keys()
        # add all the fileList to the swirl and figure out all their static libraries
        for binPath in fileList:
            if os.path.isfile(binPath):
                cmd = binPath
                if binPath in FingerPrint.syscalltracer.TracerControlBlock.cmdline:
                    # the user cmdline could be a symlink so we want to keep track
                    cmd = FingerPrint.syscalltracer.TracerControlBlock.cmdline[
                        binPath][0]
                    cmd = utils.which(cmd)
                    if not cmd:
                        cmd = binPath
                    if cmd and cmd[0] != '/':
                        # hmm we have a relative path
                        pwd = FingerPrint.syscalltracer.TracerControlBlock.get_env_variable(
                            binPath, "PWD")
                        pwd = pwd + '/' + cmd
                        if os.path.isfile(pwd) and os.access(pwd, os.X_OK):
                            cmd = pwd
                        else:
                            # TODO this way to resolving relative path is not 100% correct
                            # it should be done in the syscalltracer
                            cmd = binPath
                # load the env
                tmpenv = []
                if binPath in FingerPrint.syscalltracer.TracerControlBlock.env:
                    for var in FingerPrint.syscalltracer.TracerControlBlock.env[
                            binPath]:
                        if '=' in var and '=()' not in var:
                            tmpenv.append(var)
                swirlFile = PluginManager.getSwirl(cmd, self.swirl, tmpenv)
                self.swirl.execedFiles.append(swirlFile)

            elif os.path.isdir(binPath):
                pass
            else:
                raise IOError("The file %s cannot be opened." % binPath)
        #
        # we might need to add the dynamic dependencies to the swirl
        # if they did not get detected already
        for fileName in dynamicDependecies.keys():
            swirlFile = PluginManager.getSwirl(fileName, self.swirl)
            #let's add it to the execed file list
            if swirlFile not in self.swirl.execedFiles:
                # TODO remove me... this should never be called
                self.swirl.execedFiles.append(swirlFile)
            for dynamicDepFile in dynamicDependecies[fileName]:
                newSwirlFileDependency = PluginManager.getSwirl(
                    dynamicDepFile, self.swirl, swirlFile.env)
                #I need to verify it if is static dep or dynamic dep
                #TODO need to optimize this
                swirlDependencies = self.swirl.getListSwirlFilesDependentStatic(
                    swirlFile)
                if newSwirlFileDependency.path not in [
                        x.path for x in swirlDependencies
                ]:
                    swirlFile.dynamicDependencies.append(
                        newSwirlFileDependency)

        # let's see if it used some Data files
        # files is a double dictionary see TraceContrlBlock for its structure
        files = FingerPrint.syscalltracer.TracerControlBlock.files
        # excludeFileName: file whcih should be ingored and not added to the swirl
        excludeFileName = ['/etc/ld.so.cache']
        for lib_swFile in files:
            swirlFile = PluginManager.getSwirl(lib_swFile, self.swirl)
            if swirlFile.isLoader():
                continue
            all_dependencies_files = []
            #TODO take this for loop out of the for lib_swFile loop
            for deps in self.swirl.getListSwirlFilesDependentStaticAndDynamic(
                    swirlFile):
                all_dependencies_files += deps.getPaths()
            for execFile in files[lib_swFile]:
                for openedFile in files[lib_swFile][execFile]:
                    # we need to remove some useless files from the opened list
                    # if not depenedencies will be listed as opned files
                    if openedFile not in excludeFileName and not os.path.isdir(
                            openedFile):
                        swirlOpenedFile = PluginManager.getSwirl(
                            openedFile, self.swirl)
                        if swirlOpenedFile.path not in all_dependencies_files:
                            if execFile not in swirlFile.openedFiles:
                                swirlFile.openedFiles[execFile] = []
                            swirlFile.openedFiles[execFile].append(
                                swirlOpenedFile)
        self.swirl.ldconf_paths = self._get_ldconf_paths()
        # get hash and package name for each swirlFile
        for swf in self.swirl.swirlFiles:
            #let's skip relative path
            if swf.path[0] != '$' and os.path.exists(swf.path):
                swf.md5sum = sergeant.getHash(swf.path, swf.type)
                #TODO make this code nicer
                if sergeant.is_special_folder(swf.path):
                    swf.package = None
                else:
                    swf.package = self._getPackage(swf.path)
Example #6
0
    def __init__(self, name, fileList, processIDs, execCmd):
        """give a file list and a name construct a swirl into memory """
        self._detectedPackageManager()
        self.swirl = Swirl(name, datetime.now())
        if execCmd :
            self.swirl.cmdLine = execCmd
        # 
        # dependencies discovered with dinamic methods
        # dynamicDependencies = { 'binarypath' : [list of file it depends to],
        # '/bin/bash' : ['/lib/x86_64-linux-gnu/libnss_files-2.15.so',
        # '/lib/x86_64-linux-gnu/libnss_nis-2.15.so']}

        if execCmd :
            self._straceCmd(execCmd)

        # let's see if we have proecss ID we might need to scan for dynamic dependecies
        # with the help of the /proc FS
        elif processIDs :

            for proc in processIDs.split(','):
                pid = proc.strip()
                # add the binary
                tcb = FingerPrint.syscalltracer.TracerControlBlock(pid)
                tcb.updateSharedLibraries()

        dynamicDependecies = FingerPrint.syscalltracer.TracerControlBlock.dependencies
        # set up the fileList for the static dependency detection
        if not fileList :
            fileList = []
        # it does not work on python 2.5 aka RHEL 5.X
        # fileList = [f if f[0] == '/' else os.path.normpath(os.getcwd() + '/' + f)  for f in fileList]
        def norm_path(path):
            if path[0] == '/':
                return os.path.normpath(path)
            else:
                return os.path.normpath(os.getcwd() + '/' + path)
        fileList = [ norm_path(f) for f in fileList ]
        fileList = fileList + dynamicDependecies.keys()
        # add all the fileList to the swirl and figure out all their static libraries
        for binPath in fileList:
            if os.path.isfile(binPath):
                cmd = binPath
                if binPath in FingerPrint.syscalltracer.TracerControlBlock.cmdline:
                    # the user cmdline could be a symlink so we want to keep track
                    cmd = FingerPrint.syscalltracer.TracerControlBlock.cmdline[binPath][0]
                    cmd = utils.which(cmd)
                    if not cmd :
                        cmd = binPath
                    if cmd and cmd[0] != '/':
                        # hmm we have a relative path
                        pwd = FingerPrint.syscalltracer.TracerControlBlock.get_env_variable(binPath, "PWD")
                        pwd = pwd + '/' + cmd
                        if os.path.isfile(pwd) and os.access(pwd, os.X_OK):
                            cmd = pwd
                        else:
                            # TODO this way to resolving relative path is not 100% correct
                            # it should be done in the syscalltracer
                            cmd = binPath
                # load the env
                tmpenv = []
                if binPath in FingerPrint.syscalltracer.TracerControlBlock.env:
                    for var in FingerPrint.syscalltracer.TracerControlBlock.env[binPath]:
                        if '=' in var and '=()' not in var:
                            tmpenv.append(var)
                swirlFile = PluginManager.getSwirl(cmd, self.swirl, tmpenv)
                self.swirl.execedFiles.append(swirlFile)

            elif os.path.isdir(binPath):
                pass
            else:
                raise IOError("The file %s cannot be opened." % binPath)
        #
        # we might need to add the dynamic dependencies to the swirl
        # if they did not get detected already
        for fileName in dynamicDependecies.keys():
            swirlFile = PluginManager.getSwirl(fileName, self.swirl)
            #let's add it to the execed file list
            if swirlFile not in self.swirl.execedFiles:
                # TODO remove me... this should never be called
                self.swirl.execedFiles.append(swirlFile)
            for dynamicDepFile in dynamicDependecies[fileName]:
                newSwirlFileDependency = PluginManager.getSwirl(dynamicDepFile, self.swirl,
                        swirlFile.env)
                #I need to verify it if is static dep or dynamic dep
                #TODO need to optimize this
                swirlDependencies = self.swirl.getListSwirlFilesDependentStatic( swirlFile )
                if newSwirlFileDependency.path not in [x.path for x in swirlDependencies]:
                    swirlFile.dynamicDependencies.append(newSwirlFileDependency)

        # let's see if it used some Data files
        # files is a double dictionary see TraceContrlBlock for its structure
        files = FingerPrint.syscalltracer.TracerControlBlock.files
        # excludeFileName: file whcih should be ingored and not added to the swirl
        excludeFileName = ['/etc/ld.so.cache']
        for lib_swFile in files:
            swirlFile = PluginManager.getSwirl(lib_swFile, self.swirl)
            if swirlFile.isLoader() :
                continue
            all_dependencies_files=[]
            #TODO take this for loop out of the for lib_swFile loop
            for deps in self.swirl.getListSwirlFilesDependentStaticAndDynamic(swirlFile):
                all_dependencies_files += deps.getPaths()
            for execFile in files[lib_swFile]:
                for openedFile in files[lib_swFile][execFile]:
                    # we need to remove some useless files from the opened list
                    # if not depenedencies will be listed as opned files
                    if openedFile not in excludeFileName and not os.path.isdir(openedFile):
                        swirlOpenedFile = PluginManager.getSwirl(openedFile, self.swirl)
                        if swirlOpenedFile.path not in all_dependencies_files:
                            if execFile not in swirlFile.openedFiles:
                                swirlFile.openedFiles[execFile] = []
                            swirlFile.openedFiles[execFile].append(swirlOpenedFile)
        self.swirl.ldconf_paths = self._get_ldconf_paths()
        # get hash and package name for each swirlFile
        for swf in self.swirl.swirlFiles:
            #let's skip relative path
            if swf.path[0] != '$' and os.path.exists(swf.path):
                swf.md5sum = sergeant.getHash(swf.path, swf.type)
                #TODO make this code nicer
                if sergeant.is_special_folder( swf.path ) :
                    swf.package = None
                else:
                    swf.package = self._getPackage(swf.path)