Пример #1
0
def exit(code=0):
    """
    Exits program with exit code and deletes temp files before exit

    Args:
        code: the exit code (default 0)
    """
    if is_testing:
    	return
    # delete temp files before exit
    Temp.clean()
    # exit
    sys.exit(code)
Пример #2
0
    def compress(self, dirpath: str, output: str):
        """
        This function compresses content of target directory and build package
        in output file

        Args:
            dirpath: (str) package directory path
            output: (str) that filepath you want to compress file in that

        Raises:
            InvalidPackageDirException: when the output path is invalid
        """
        try:
            pkg = archive_factory(output, "w:gz")
        except:
            raise InvalidPackageDirException(
                'file "' + output + '" for output of package not found')

        pkg.add(dirpath, arcname='/')
        # add `cati-version` file
        cati_version_tmp_f = Temp.make_file()
        tmp_f = open(cati_version_tmp_f, 'w')
        tmp_f.write('1.0')
        tmp_f.close()
        pkg.add(cati_version_tmp_f, arcname='/')
        pkg.close()
Пример #3
0
def run():
    """ start running tests """
    print('Starting test system...')
    print('=======================')

    # load test environment
    print('Loading test environment...', end=' ')
    load_test_env()
    print(ansi.green + 'created in ' + Env.base_path() + ansi.reset)
    print()

    # enable testing mode
    pr.is_testing = True
    SysArch.is_testing = True

    # load tests list
    tests_list = os.listdir('tests/items')

    # clean up tests list
    orig_tests = []
    for test in tests_list:
        if test[len(test) - 3:] == '.py':
            exec('from items.' + test[:len(test) - 3] + ' import ' +
                 test[:len(test) - 3])
            exec("orig_tests.append(" + test[:len(test) - 3] + "())")

    # start running tests
    count = 0
    for test in orig_tests:
        test_name = test.get_name()
        print('\t[' + str(count + 1) + '/' + str(len(orig_tests)) + ']\t' +
              test_name.replace('_', ' ') + ': ',
              end='',
              flush=True)
        test.refresh_env()
        test.run()
        test.refresh_env()
        print(ansi.green + 'PASS' + ansi.reset)
        count += 1

    print()
    print(ansi.green + 'All ' + str(count) + ' tests passed successfuly')
    print('Cleaning up...' + ansi.reset)
    if os.path.isfile('testpkgc-1.0.cati'):
        os.remove('testpkgc-1.0.cati')
    shutil.rmtree(Env.base_path_dir)
    Temp.clean()
Пример #4
0
def rpm2cati(file_path: str) -> str:
    """
    Converts rpm package to cati package and returns generated cati package file path

    Args:
        file_path: rpm package filepath

    Returns:
        returns generated cati package filepath
    """
    # require alien
    if os.system('alien 2> /dev/null') != 256:
        return file_path

    file_path = os.path.abspath(file_path)
    cwd = os.getcwd()
    tmp_dir = Temp.make_dir()
    os.chdir(tmp_dir)

    try:
        shutil.copy(file_path, 'package.rpm')
        res = os.system('alien package.rpm 2> /dev/null')
        if res != 0:
            return file_path

        os.system('mv *.deb package.deb')

        rpm_path = file_path + '.deb'
        try:
            shutil.copy('package.deb', rpm_path)
        except:
            rpm_path = Temp.make_file()
            shutil.copy('package.deb', rpm_path)

        os.chdir(cwd)
        return deb2cati(rpm_path)
    except:
        os.chdir(cwd)
        return file_path
Пример #5
0
 def get_data(self, download_event=None) -> str:
     """ Returns repo data """
     i = 0
     last_res = None
     temp_file = Temp.make_file()
     os.remove(temp_file)
     while i < 5:
         if i > 4:
             return last_res
         last_res = download_event(self.url + '?get_data=1', temp_file)
         if last_res == True:
             f = open(temp_file, 'r')
             content = f.read().strip()
             f.close()
             if content != '':
                 return content
         i += 1
Пример #6
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)
Пример #7
0
def deb2cati(file_path: str) -> str:
    """
    Converts deb package to cati package and returns generated cati package file path

    Args:
        file_path: deb package filepath

    Returns:
        returns generated cati package filepath
    """
    file_path = os.path.abspath(file_path)
    tmp_dir = Temp.make_dir()
    cwd = os.getcwd()
    os.chdir(tmp_dir)
    try:
        shutil.copy(file_path, './package.deb')

        script = '''
        ar -x package.deb
        mkdir cati
        mkdir cati/control cati/scripts
        mv control.tar.* cati/control
        mkdir cati/files
        mv data.tar.* cati/files
        rm debian-binary package.deb
        touch cati/data.json
        '''.strip().split('\n')
        script = [l.strip() for l in script]

        for line in script:
            result = os.system(line)
            if result != 0:
                # script has error, return current filepath
                os.chdir(cwd)
                return file_path
        os.chdir('cati/control')
        os.system('tar -xf control.tar.*')
        os.system('rm control.tar.*')
        os.chdir('..')
        os.chdir('files')
        os.system('tar -xf data.tar.*')
        os.system('rm data.tar.*')
        os.chdir('..')

        # convert content data to cati json
        control_f = open('control/control', 'r').read()
        control_f_lines = control_f.strip().split('\n')
        control_fields = {}
        tmp_last_key = None
        for line in control_f_lines:
            if line != '':
                if line[0] == ' ':
                    if tmp_last_key != None:
                        control_fields[tmp_last_key] += '\n' + line
                else:
                    key = line.split(':', 1)[0]
                    value = line.split(':', 1)[1].strip()
                    tmp_last_key = key
                    control_fields[key] = value

        # convert scripts
        if os.path.isfile('control/preinst'):
            shutil.copy('control/preinst', 'scripts/ins-before')

        if os.path.isfile('control/postinst'):
            shutil.copy('control/postinst', 'scripts/ins-after')

        if os.path.isfile('control/prerm'):
            shutil.copy('control/prerm', 'scripts/rm-before')

        if os.path.isfile('control/postrm'):
            shutil.copy('control/postrm', 'scripts/rm-after')

        # convert control fields to cati data.json
        cati_data = {}
        for k in control_fields:
            if k == 'Package':
                cati_data['name'] = control_fields[k].strip()
            elif k == 'Version':
                cati_data['version'] = control_fields[k].strip()
            elif k == 'Architecture':
                cati_data['arch'] = control_fields[k].strip()
            elif k == 'Maintainer':
                cati_data['maintainer'] = control_fields[k].strip()
            elif k == 'Original-Maintainer':
                cati_data['X-Original-Maintainer'] = control_fields[k].strip()
            elif k == 'Uploaders':
                cati_data['uploaders'] = control_fields[k].strip().split(',')
                cati_data['uploaders'] = [a.strip() for a in cati_data['uploaders']]
            elif k == 'Description':
                cati_data['description'] = control_fields[k]
            elif k == 'Changed-By':
                cati_data['changed-by'] = control_fields[k]
            elif k == 'Changes':
                cati_data['changes'] = control_fields[k]
            elif k == 'Date':
                cati_data['date'] = control_fields[k]
            elif k == 'Urgency':
                cati_data['urgency'] = control_fields[k]
            elif k == 'Essential':
                cati_data['essential'] = control_fields[k]
                if cati_data['essential'] == 'yes' or cati_data['essential'] == 'Yes':
                    cati_data['essential'] = True
                else:
                    cati_data['essential'] = False
            elif k == 'Homepage':
                cati_data['homepage'] = control_fields[k].strip()
            elif k == 'Section':
                cati_data['category'] = [control_fields[k].strip()]
            elif k == 'Depends' or k == 'Pre-Depends':
                try:
                    cati_data['depends']
                except:
                    cati_data['depends'] = []
                cati_data['depends'] = [*cati_data['depends'], *convert_depends_list(control_fields[k].strip())]
            elif k == 'Conflicts' or k == 'Breaks':
                try:
                    cati_data['conflicts']
                except:
                    cati_data['conflicts'] = []
                cati_data['conflicts'] = [*cati_data['conflicts'], *convert_depends_list(control_fields[k].strip())]
            elif k == 'Recommends':
                cati_data['recommends'] = convert_depends_list(control_fields[k].strip())
            elif k == 'Replaces':
                cati_data['replaces'] = convert_depends_list(control_fields[k].strip())
            elif k == 'Suggests':
                cati_data['suggests'] = convert_depends_list(control_fields[k].strip())
                cati_data['suggests'] = [item_tmp.split(' ')[0] for item_tmp in cati_data['suggests']]
            elif k == 'Enhances':
                cati_data['enhances'] = convert_depends_list(control_fields[k].strip())
                cati_data['enhances'] = [item_tmp.split(' ')[0] for item_tmp in cati_data['enhances']]
            elif k == 'Provides':
                cati_data['provides'] = convert_depends_list(control_fields[k].strip())
                cati_data['provides'] = [item_tmp.split(' ')[0] for item_tmp in cati_data['provides']]
            elif k[0] == 'X' or k[0] == 'x':
                cati_data[k] = control_fields[k].strip()
        os.system('rm control -rf')
        cati_data_f = open('data.json', 'w')
        cati_data_f.write(json.dumps(cati_data))
        cati_data_f.close()
        os.chdir('..')

        # build pkg
        pkg_command = PkgCommand.PkgCommand()
        pkg_command.handle(ArgParser.parse(['cati', 'pkg', 'build', 'cati', '-q']))

        if os.path.isfile('cati.cati'):
            try:
                shutil.copy('cati.cati', file_path + '.cati')
                os.chdir(cwd)
                return file_path + '.cati'
            except:
                tmp_file_path = Temp.make_file()
                shutil.copy('cati.cati', tmp_file_path)
                return tmp_file_path
    except Exception as ex:
        print('error: ' + str(ex))
        os.chdir(cwd)
        return file_path

    os.chdir(cwd)
    return file_path