Example #1
0
def get_depends(file_path):
    """Parses ldd's output and returns depends of shared lib or executable file"""
    depends = []
    if not os.access(ldd_path, os.X_OK):
        out.error("%s seems problematic. please check it." % ldd_path)
        lpms.terminate()

    if not os.path.exists(file_path):
        raise FileNotFound("%s not found." % file_path)

    if not utils.get_mimetype(file_path) in (
        "application/x-executable",
        "application/x-archive",
        "application/x-sharedlib",
    ):
        out.error("%s is invalid for me." % file_path)
        return

    for line in subprocess.Popen([ldd_path, file_path], stdout=subprocess.PIPE).stdout:
        data = line.strip().split("=>")
        if len(data) == 2:
            parsed = data[1].split(" ")
            if parsed[1] != "":
                if shelltools.is_link(parsed[1]):
                    depends.append(shelltools.real_path(parsed[1]))
                else:
                    depends.append(parsed[1])
    return depends
Example #2
0
def get_depends(file_path):
    '''Parses ldd's output and returns depends of shared lib or executable file'''
    depends = []
    if not os.access(ldd_path, os.X_OK):
        out.error("%s seems problematic. please check it." % ldd_path)
        lpms.terminate()

    if not os.path.exists(file_path):
        raise FileNotFound("%s not found." % file_path)

    if not utils.get_mimetype(file_path) in ('application/x-executable', \
            'application/x-archive', 'application/x-sharedlib'):
        out.error("%s is invalid for me." % file_path)
        return

    for line in subprocess.Popen([ldd_path, file_path], \
            stdout=subprocess.PIPE).stdout:
        data = line.strip().split("=>")
        if len(data) == 2:
            parsed = data[1].split(" ")
            if parsed[1] != "":
                if shelltools.is_link(parsed[1]):
                    depends.append(shelltools.real_path(parsed[1]))
                else:
                    depends.append(parsed[1])
    return depends
Example #3
0
    def merge_package(self):
        '''Moves files to the target destination in the most safest way.'''
        def get_perms(path):
            '''Get permissions of given path, it may be file or directory'''
            return {"uid": utils.get_uid(path),
                    "gid": utils.get_gid(path),
                    "mod": utils.get_mod(path)
            }
        out.normal("%s/%s/%s-%s:%s is merging to %s" % (self.environment.repo, self.environment.category, \
                self.environment.name, self.environment.version, self.environment.slot, \
                self.environment.real_root))
        # Remove files db entries for this package:slot if it exists
        self.filesdb.delete_item_by_pkgdata(self.environment.category, self.environment.name, \
            self.environment.previous_version, commit=True)

        # Remove file_relations db entries for this package:slot if it exists
        self.file_relationsdb.delete_item_by_pkgdata(self.environment.category, \
                self.environment.name, self.environment.previous_version, commit=True)

        # Merge the package, now
        walk_iter = os.walk(self.environment.install_dir, followlinks=True)
        while True:
            try:
                parent, directories, files = next(walk_iter)
                # TODO: Check the target path's permissions for writing or reading
                # Remove install_dir from parent to get real parent path
                pruned_parent = parent.replace(self.environment.install_dir, "")
                # create directories
                for directory in directories:
                    source = os.path.join(parent, directory)
                    target = os.path.join(self.environment.real_root, pruned_parent, directory)
                    real_target = "/".join([pruned_parent, directory])
                    if self.is_parent_symlink(target):
                        break
                    if os.path.islink(source):
                        self.symlinks.append(target+"/")
                        realpath = os.path.realpath(source)
                        if os.path.islink(target):
                            shelltools.remove_file(target)
                        # create real directory
                        if len(realpath.split(self.environment.install_dir)) > 1:
                            realpath = realpath.split(self.environment.install_dir)[1][1:]

                        shelltools.makedirs(os.path.join(self.environment.real_root, realpath))
                        # make symlink
                        if os.path.isdir(target):
                            shelltools.remove_dir(target)
                        elif os.path.isfile(target):
                            shelltools.remove_file(target)
                        shelltools.make_symlink(os.readlink(source), target)
                    else:
                        if os.path.isfile(target):
                            # TODO: Rename this file and warn the user
                            shelltools.remove_file(target)
                        shelltools.makedirs(target)
                    # Get permissions
                    perms = get_perms(source)
                    # if path is a symlink, pass permission mumbo-jumbos
                    if not os.path.islink(source):
                        # Set permissions
                        shelltools.set_id(target, perms["uid"], perms["gid"])
                        shelltools.set_mod(target, perms["mod"])
                        # TODO: Common items?
                        # Add the item to filesdb
                        self.append_filesdb("dir", real_target, perms)
                    else:
                        # Add the item to filesdb
                        self.append_filesdb("link", real_target, perms, \
                                realpath=os.path.realpath(source))

                # Merge regular files to the target
                # Firstly, handle reserved files
                reserve_files = []
                if self.environment.reserve_files:
                    if isinstance(self.environment.reserve_files, basestring):
                        reserve_files.extend([f_item for f_item in self.environment.reserve_files.split(" ") \
                                if f_item != ""])
                    elif isinstance(self.environment.reserve_files, list) or isinstance(self.environment.reserve_files, tuple):
                        reserve_files.extend(self.environment.reserve_files)

                if os.path.isfile(os.path.join(cst.user_dir, cst.protect_file)):
                    with open(os.path.join(cst.user_dir, cst.protect_file)) as data:
                        for rf in data.readlines():
                            if not rf.startswith("#"):
                                reserve_files.append(rf.strip())

                # Here we are starting to merge
                for _file in files:
                    source = os.path.join(parent, _file)
                    target = os.path.join(self.environment.real_root, pruned_parent, _file)
                    real_target = "/".join([pruned_parent, _file])
                    if self.is_parent_symlink(target):
                        break
                    # Keep file relations for using after to handle reverse dependencies
                    if os.path.exists(source) and os.access(source, os.X_OK):
                        if utils.get_mimetype(source) in self.binary_filetypes:
                            self.file_relationsdb.append_query((
                                self.environment.repo,
                                self.environment.category,
                                self.environment.name,
                                self.environment.version,
                                target,
                                file_relations.get_depends(source))
                            )
                    # Strip binary files and keep them smaller
                    if self.strip_debug_symbols and utils.get_mimetype(source) in self.binary_filetypes:
                        utils.run_strip(source)
                    if self.environment.ignore_reserve_files:
                        reserve_files = []
                        self.environment.reserve_files = True

                    def add_file_item():
                        # Prevent code duplication
                        if not os.path.islink(target):
                            shelltools.set_id(target, perms["uid"], perms["gid"])
                            shelltools.set_mod(target, perms["mod"])
                            self.append_filesdb("file", real_target, perms, \
                                    sha1sum=utils.sha1sum(target),
                                    size = utils.get_size(source, dec=True)
                            )
                        else:
                            self.append_filesdb("link", real_target, perms,\
                                    realpath=os.path.realpath(source))

                    if self.environment.reserve_files is not False:
                        conf_file = os.path.join(pruned_parent, _file)
                        isconf = (_file.endswith(".conf") or _file.endswith(".cfg"))
                        def is_reserve():
                            if self.environment.ignore_reserve_files:
                                return False
                            elif not conf_file in reserve_files:
                                return False
                            return True

                        if os.path.exists(target) and not is_reserve():
                            if pruned_parent[0:4] == "/etc" or isconf:
                                if os.path.isfile(conf_file) and utils.sha1sum(source) != utils.sha1sum(conf_file):
                                    self.append_merge_conf(conf_file)
                                    target = target+".lpms-backup" 
                                    self.backup.append(target)

                        if os.path.exists(target) and is_reserve():
                            # The file is reserved.
                            # Adds to filesdb
                            add_file_item()
                            # We don't need the following operations
                            continue

                    if os.path.islink(source):
                        sha1 = False
                        realpath = os.readlink(source)
                        if self.environment.install_dir in realpath:
                            realpath = realpath.split(self.environment.install_dir)[1]

                        if os.path.isdir(target):
                            shelltools.remove_dir(target)
                        elif os.path.isfile(target) or os.path.islink(target):
                            shelltools.remove_file(target)
                        shelltools.make_symlink(realpath, target)
                    else:
                        sha1 = utils.sha1sum(source)
                        perms = get_perms(source)
                        shelltools.move(source, target)
                    # Adds to filesdb
                    add_file_item()
            except StopIteration as err:
                break

        self.file_relationsdb.insert_query(commit=True)
        self.filesdb.insert_query(commit=True)

        lpms.logger.info("%s/%s has been merged to %s." % (self.environment.category, self.environment.fullname, \
                self.environment.real_root))
Example #4
0
    def merge_package(self):
        '''Moves files to the target destination in the most safest way.'''
        def get_perms(path):
            '''Get permissions of given path, it may be file or directory'''
            return {
                "uid": utils.get_uid(path),
                "gid": utils.get_gid(path),
                "mod": utils.get_mod(path)
            }
        out.normal("%s/%s/%s-%s:%s is merging to %s" % (self.environment.repo, self.environment.category, \
                self.environment.name, self.environment.version, self.environment.slot, \
                self.environment.real_root))
        # Remove files db entries for this package:slot if it exists
        self.filesdb.delete_item_by_pkgdata(self.environment.category, self.environment.name, \
            self.environment.previous_version, commit=True)

        # Remove file_relations db entries for this package:slot if it exists
        self.file_relationsdb.delete_item_by_pkgdata(self.environment.category, \
                self.environment.name, self.environment.previous_version, commit=True)

        # Merge the package, now
        walk_iter = os.walk(self.environment.install_dir, followlinks=True)
        while True:
            try:
                parent, directories, files = next(walk_iter)
                # TODO: Check the target path's permissions for writing or reading
                # Remove install_dir from parent to get real parent path
                pruned_parent = parent.replace(self.environment.install_dir,
                                               "")
                # create directories
                for directory in directories:
                    source = os.path.join(parent, directory)
                    target = os.path.join(self.environment.real_root,
                                          pruned_parent, directory)
                    real_target = "/".join([pruned_parent, directory])
                    if self.is_parent_symlink(target):
                        break
                    if os.path.islink(source):
                        self.symlinks.append(target + "/")
                        realpath = os.path.realpath(source)
                        if os.path.islink(target):
                            shelltools.remove_file(target)
                        # create real directory
                        if len(realpath.split(
                                self.environment.install_dir)) > 1:
                            realpath = realpath.split(
                                self.environment.install_dir)[1][1:]

                        shelltools.makedirs(
                            os.path.join(self.environment.real_root, realpath))
                        # make symlink
                        if os.path.isdir(target):
                            shelltools.remove_dir(target)
                        elif os.path.isfile(target):
                            shelltools.remove_file(target)
                        shelltools.make_symlink(os.readlink(source), target)
                    else:
                        if os.path.isfile(target):
                            # TODO: Rename this file and warn the user
                            shelltools.remove_file(target)
                        shelltools.makedirs(target)
                    # Get permissions
                    perms = get_perms(source)
                    # if path is a symlink, pass permission mumbo-jumbos
                    if not os.path.islink(source):
                        # Set permissions
                        shelltools.set_id(target, perms["uid"], perms["gid"])
                        shelltools.set_mod(target, perms["mod"])
                        # TODO: Common items?
                        # Add the item to filesdb
                        self.append_filesdb("dir", real_target, perms)
                    else:
                        # Add the item to filesdb
                        self.append_filesdb("link", real_target, perms, \
                                realpath=os.path.realpath(source))

                # Merge regular files to the target
                # Firstly, handle reserved files
                reserve_files = []
                if self.environment.reserve_files:
                    if isinstance(self.environment.reserve_files, basestring):
                        reserve_files.extend([f_item for f_item in self.environment.reserve_files.split(" ") \
                                if f_item != ""])
                    elif isinstance(self.environment.reserve_files,
                                    list) or isinstance(
                                        self.environment.reserve_files, tuple):
                        reserve_files.extend(self.environment.reserve_files)

                if os.path.isfile(os.path.join(cst.user_dir,
                                               cst.protect_file)):
                    with open(os.path.join(cst.user_dir,
                                           cst.protect_file)) as data:
                        for rf in data.readlines():
                            if not rf.startswith("#"):
                                reserve_files.append(rf.strip())

                # Here we are starting to merge
                for _file in files:
                    source = os.path.join(parent, _file)
                    target = os.path.join(self.environment.real_root,
                                          pruned_parent, _file)
                    real_target = "/".join([pruned_parent, _file])
                    if self.is_parent_symlink(target):
                        break
                    # Keep file relations for using after to handle reverse dependencies
                    if os.path.exists(source) and os.access(source, os.X_OK):
                        if utils.get_mimetype(source) in self.binary_filetypes:
                            self.file_relationsdb.append_query(
                                (self.environment.repo,
                                 self.environment.category,
                                 self.environment.name,
                                 self.environment.version, target,
                                 file_relations.get_depends(source)))
                    # Strip binary files and keep them smaller
                    if self.strip_debug_symbols and utils.get_mimetype(
                            source) in self.binary_filetypes:
                        utils.run_strip(source)
                    if self.environment.ignore_reserve_files:
                        reserve_files = []
                        self.environment.reserve_files = True

                    def add_file_item():
                        # Prevent code duplication
                        if not os.path.islink(target):
                            shelltools.set_id(target, perms["uid"],
                                              perms["gid"])
                            shelltools.set_mod(target, perms["mod"])
                            self.append_filesdb("file", real_target, perms, \
                                    sha1sum=utils.sha1sum(target),
                                    size = utils.get_size(source, dec=True)
                            )
                        else:
                            self.append_filesdb("link", real_target, perms,\
                                    realpath=os.path.realpath(source))

                    if self.environment.reserve_files is not False:
                        conf_file = os.path.join(pruned_parent, _file)
                        isconf = (_file.endswith(".conf")
                                  or _file.endswith(".cfg"))

                        def is_reserve():
                            if self.environment.ignore_reserve_files:
                                return False
                            elif not conf_file in reserve_files:
                                return False
                            return True

                        if os.path.exists(target) and not is_reserve():
                            if pruned_parent[0:4] == "/etc" or isconf:
                                if os.path.isfile(conf_file) and utils.sha1sum(
                                        source) != utils.sha1sum(conf_file):
                                    self.append_merge_conf(conf_file)
                                    target = target + ".lpms-backup"
                                    self.backup.append(target)

                        if os.path.exists(target) and is_reserve():
                            # The file is reserved.
                            # Adds to filesdb
                            add_file_item()
                            # We don't need the following operations
                            continue

                    if os.path.islink(source):
                        sha1 = False
                        realpath = os.readlink(source)
                        if self.environment.install_dir in realpath:
                            realpath = realpath.split(
                                self.environment.install_dir)[1]

                        if os.path.isdir(target):
                            shelltools.remove_dir(target)
                        elif os.path.isfile(target) or os.path.islink(target):
                            shelltools.remove_file(target)
                        shelltools.make_symlink(realpath, target)
                    else:
                        sha1 = utils.sha1sum(source)
                        perms = get_perms(source)
                        shelltools.move(source, target)
                    # Adds to filesdb
                    add_file_item()
            except StopIteration as err:
                break

        self.file_relationsdb.insert_query(commit=True)
        self.filesdb.insert_query(commit=True)

        lpms.logger.info("%s/%s has been merged to %s." % (self.environment.category, self.environment.fullname, \
                self.environment.real_root))
Example #5
0
if "--quiet" in cmdline:
    out.normal("creating file relations database...")

if os.path.exists("/var/db/lpms/file_relations.db"):
    shelltools.remove_file("/var/db/lpms/file_relations.db")

relationsdb = dbapi.FileRelationsDB()

for package in installdb.get_all_names():
    repo, category, name = package
    versions = []
    map(lambda ver: versions.extend(ver),
        installdb.get_version(name, pkg_category=category).values())
    for version in versions:
        content = filesdb.list_files(category, name, version)
        for file_path in content["file"]:
            if os.path.exists(file_path) and os.access(file_path, os.X_OK):
                if utils.get_mimetype(file_path) in ('application/x-executable', 'application/x-archive', \
                        'application/x-sharedlib'):
                    if not "--quiet" in cmdline:
                        out.green("%s/%s/%s/%s\n" %
                                  (repo, category, name, version))
                        out.write("\t" + file_path + "\n")
                    relationsdb.add_file(
                        (repo, category, name, version, file_path,
                         file_relations.get_depends(file_path)))

relationsdb.commit()
out.write("OK\n")