Exemple #1
0
 def run_any_scripts(runed_transactions: list, events: dict):
     """
     run all of `any` scripts.
     
     events:
     - start_run_script: will run when starting to run once script (gets package name)
     """
     runed_transactions_str = ''
     for rt in runed_transactions[1]:
         runed_transactions_str += rt + ' '
     runed_transactions_str = runed_transactions_str.strip()
     scripts = os.listdir(Env.any_scripts())
     for script in scripts:
         events['start_run_script'](script)
         # run script
         os.system('chmod +x "' + Env.any_scripts('/' + script) + '"')
         os.system(
             Env.any_scripts('/' + script) + ' ' + runed_transactions[0] +
             ' ' + runed_transactions_str)
Exemple #2
0
def require_root_permission(is_cli=True, die_action=None):
    """
    checks root premission.

    Args:
        is_cli (bool): if is True, when user have not root permission,
            error will print in terminal. but if is False,
            the `die_action` will run as a function.
            (will be disable in testing environment)
        die_action (callable): the function will be run when `is_cli` is False
    """

    # if program is in testing mode don't check permission
    if is_testing:
        return

    if os.getuid() == 0:
        return

    # check write and read access for needed files
    files_to_check = [
        Env.packages_lists(),
        Env.installed_lists(),
        Env.state_file(),
        Env.unremoved_conffiles(),
        Env.security_blacklist(),
        Env.any_scripts(),
        Env.repos_config(),
        Env.repos_config_dir(),
        Env.cache_dir(),
        Env.allowed_archs(),
    ]
    for f in files_to_check:
        if not os.access(f, os.W_OK) or not os.access(f, os.R_OK):
            if is_cli:
                pr.e(ansi.red + sys.argv[0] + ': permission is denied' +
                     ansi.reset)
                pr.exit(1)
                return
            else:
                die_action()
                return
Exemple #3
0
    def run(pkg: Pkg, events: dict, remove_conffiles=False, run_scripts=True):
        """ Remove pkg """
        events['removing_package'](pkg)

        # run rm-before script
        if run_scripts:
            if os.path.isfile(
                    Env.installed_lists('/' + pkg.data['name'] +
                                        '/rm-before')):
                os.system('chmod +x "' +
                          Env.installed_lists('/' + pkg.data['name'] +
                                              '/rm-before') + '"')
                with_conffiles_arg = 'without-conffiles'
                if remove_conffiles:
                    with_conffiles_arg = 'with-conffiles'
                os.system(
                    Env.installed_lists('/' + pkg.data['name'] +
                                        '/rm-before') + ' ' +
                    with_conffiles_arg)

        # remove package
        installed_files = open(
            Env.installed_lists('/' + pkg.data['name'] + '/files'),
            'r').read()
        installed_files = installed_files.strip().split('\n')
        for f in list(reversed(installed_files)):
            if f != '':
                f_type = f.strip().split(':', 1)[0]
                f_path = f.strip().split(':', 1)[1]
                if f_type == 'f':
                    if os.path.isfile(Env.base_path(f_path)):
                        os.remove(Env.base_path(f_path))
                elif f_type == 'd':
                    try:
                        os.rmdir(Env.base_path(f_path))
                    except:
                        events['dir_is_not_empty'](pkg, f)
                elif f_type == 'cf':
                    if remove_conffiles:
                        if os.path.isfile(Env.base_path(f_path)):
                            os.remove(Env.base_path(f_path))
                    else:
                        Remove.add_to_unremoved_conffiles(pkg, f_path)
                elif f_type == 'cd':
                    if remove_conffiles:
                        try:
                            os.rmdir(Env.base_path(f_path))
                        except:
                            events['dir_is_not_empty'](pkg, f)
                    else:
                        Remove.add_to_unremoved_conffiles(pkg, f_path)

        # run rm-after script
        if run_scripts:
            if os.path.isfile(
                    Env.installed_lists('/' + pkg.data['name'] + '/rm-after')):
                with_conffiles_arg = 'without-conffiles'
                if remove_conffiles:
                    with_conffiles_arg = 'with-conffiles'
                os.system('chmod +x "' +
                          Env.installed_lists('/' + pkg.data['name'] +
                                              '/rm-after') + '"')
                os.system(
                    Env.installed_lists('/' + pkg.data['name'] + '/rm-after') +
                    ' ' + with_conffiles_arg)

        # remove installation config
        shutil.rmtree(Env.installed_lists('/' + pkg.data['name']))

        # remove any script
        if os.path.isfile(Env.any_scripts('/' + pkg.data['name'])):
            os.remove(Env.any_scripts('/' + pkg.data['name']))

        events['package_remove_finished'](pkg)
Exemple #4
0
    def install(self, pkg: BaseArchive, index_updater_events: dict, installer_events: dict, is_manual=True, run_scripts=True, target_path='', keep_conffiles=False, check_security_blacklist=True):
        """
        Install .cati package

        Args:
            pkg (BaseArchive): the package archive object
            index_updater_events (dict): events will be passed to `dotcati.ListUpdater.update_indexes()`
            installer_events (dict): The events
                - package_currently_install: gets the current installed version
                - package_new_installs: gets package archive
                - package_installed: will call after package installation
                - dep_and_conflict_error: will run when there is depends or conflict error
                - arch_error: will run when package arch is not sync with sys arch
            is_manual (bool): installed package as manual or not (default is True means manual)
            run_scripts (bool): run package install scripts or not (default is True)
            target_path (str): where is the target path for installed files (will pass to `self.copy_files()`)
            keep_conffiles (bool): stil keep config files if changed (default is True)
            check_security_blacklist (bool): check package is in security blacklist or not
        """

        self.conffiles = pkg.get_conffiles()
        self.pkg = pkg
        self.keep_conffiles = keep_conffiles
        self.uncopied_conffiles = {}

        # check package is in security blacklist
        if check_security_blacklist:
            self.check_security_blacklist(pkg)

        # check package architecture
        if not pkg.data['arch'] in SysArch.allowed_archs():
            return installer_events['arch_error'](pkg)

        # check package dependencies and conflicts
        try:
            self.check_dep_and_conf(pkg)
        except DependencyError as ex:
            return installer_events['dep_and_conflict_error'](pkg, ex)
        except ConflictError as ex:
            return installer_events['dep_and_conflict_error'](pkg, ex)

        # load old conffiles
        self.old_conffiles = []
        try:
            f = open(Env.installed_lists('/' + pkg.data['name'] + '/conffiles'), 'r')
            content = f.read()
            f.close()
            tmp = content.strip().split('\n')
            self.old_conffiles = [item.strip().split('@') for item in tmp]
        except:
            pass

        # add package data to lists
        if not os.path.isdir(Env.packages_lists('/' + pkg.data['name'])):
            os.mkdir(Env.packages_lists('/' + pkg.data['name']))

        lists_path = Env.packages_lists('/' + pkg.data['name'] + '/' + pkg.data['version'] + '-' + pkg.data['arch'])

        try:
            lists_f = open(lists_path, 'r')
            old_repo = json.loads(lists_f.read())['repo']
            lists_f.close()
        except:
            old_repo = 'Local'

        try:
            lists_f = open(lists_path, 'r')
            old_file_path = json.loads(lists_f.read())['file_path']
            lists_f.close()
        except:
            old_file_path = False

        try:
            lists_f = open(lists_path, 'r')
            old_file_sha256 = json.loads(lists_f.read())['file_sha256']
            lists_f.close()
        except:
            old_file_sha256 = False

        try:
            lists_f = open(lists_path, 'r')
            old_file_md5 = json.loads(lists_f.read())['file_md5']
            lists_f.close()
        except:
            old_file_md5 = False

        lists_f = open(lists_path, 'w')
        pkg.data['repo'] = old_repo
        if old_file_path != False:
            pkg.data['file_path'] = old_file_path
        tmp_pkg_data = pkg.data
        if old_file_md5:
            tmp_pkg_data['file_md5'] = old_file_md5
        if old_file_sha256:
            tmp_pkg_data['file_sha256'] = old_file_sha256
        tmp_pkg_data['files'] = ['/' + member[6:] for member in pkg.members() if member[:6] == 'files/']
        lists_f.write(json.dumps(tmp_pkg_data))
        lists_f.close()

        ListUpdater.update_indexes(index_updater_events)

        # extract package in a temp place
        temp_dir = Temp.make_dir()
        os.rmdir(temp_dir)
        try:
            pkg.extractall(temp_dir)
        except IsADirectoryError:
            pass
        self.extracted_package_dir = temp_dir

        # install package
        if Pkg.is_installed(pkg.data['name']):
            installer_events['package_currently_installed'](pkg, Pkg.installed_version(pkg.data['name']))
        else:
            installer_events['package_new_installs'](pkg)

        if run_scripts:
            self.run_script('ins-before')

        copied_files = self.copy_files(pkg, installer_events['directory_not_empty'], target_path)

        # set install configuration
        if not os.path.isdir(Env.installed_lists('/' + pkg.data['name'])):
            os.mkdir(Env.installed_lists('/' + pkg.data['name']))
        f_ver = open(Env.installed_lists('/' + pkg.data['name'] + '/ver'), 'w')
        f_ver.write(pkg.data['version']) # write installed version
        f_ver.close()

        # write copied files list
        f_files = open(Env.installed_lists('/' + pkg.data['name'] + '/files'), 'w')
        copied_files_str = ''
        for copied_file in copied_files:
            copied_files_str += copied_file + '\n'
        f_files.write(copied_files_str.strip()) # write copied files
        f_files.close()

        # write conffiles list
        f_conffiles = open(Env.installed_lists('/' + pkg.data['name'] + '/conffiles'), 'w')
        copied_conffiles_str = ''
        for copied_conffile in copied_files:
            if copied_conffile.split(':')[0] == 'cf':
                try:
                    conffile_hash = self.uncopied_conffiles[copied_conffile.split(':', 1)[-1]]
                except:
                    conffile_hash = calc_file_sha256(Env.base_path(copied_conffile.split(':', 1)[-1]))
                copied_conffiles_str += conffile_hash + '@' + copied_conffile.split(':', 1)[-1] + '\n'
        f_conffiles.write(copied_conffiles_str.strip()) # write copied conffiles
        f_conffiles.close()

        # copy `any` script
        if os.path.isfile(self.extracted_package_dir + '/scripts/any'):
            os.system('cp "' + self.extracted_package_dir + '/scripts/any' + '" "' + Env.any_scripts('/' + pkg.data['name']) + '"')

        # save static files list
        static_files_list = pkg.get_static_files()
        f_static_files = open(Env.installed_lists('/' + pkg.data['name'] + '/staticfiles'), 'w')
        static_files_str = ''
        for copied_file in copied_files:
            copied_file_path = copied_file.split(':', 1)[1]
            if copied_file_path in static_files_list:
                if os.path.isfile(Env.base_path('/' + copied_file_path)):
                    # calculate file sha256 sum
                    copied_file_sha256 = calc_file_sha256(Env.base_path('/' + copied_file_path))
                    # add file to list
                    static_files_str += copied_file_sha256 + '@' + copied_file_path + '\n'
        f_static_files.write(static_files_str.strip()) # write copied files
        f_static_files.close()

        f_installed_at = open(Env.installed_lists('/' + pkg.data['name'] + '/installed_at'), 'w')
        f_installed_at.write(str(time.time())) # write time (installed at)
        f_installed_at.close()

        if is_manual:
            f_manual = open(Env.installed_lists('/' + pkg.data['name'] + '/manual'), 'w')
            f_manual.write('')
            f_manual.close()

        if run_scripts:
            self.run_script('ins-after')

        # copy remove scripts
        if os.path.isfile(self.extracted_package_dir + '/scripts/rm-before'):
            os.system(
                'cp "' + self.extracted_package_dir + '/scripts/rm-before' + '" "' + Env.installed_lists('/' + pkg.data['name'] + '/rm-before') + '"'
            )
        if os.path.isfile(self.extracted_package_dir + '/scripts/rm-after'):
            os.system(
                'cp "' + self.extracted_package_dir + '/scripts/rm-after' + '" "' + Env.installed_lists('/' + pkg.data['name'] + '/rm-after') + '"'
            )

        # pop package from state
        BaseTransaction.pop_state()

        # call package installed event
        installer_events['package_installed'](pkg)