def check(events: dict): """ Check all of needed files and dirs for cati installation Args: events: - failed_to_repair: will run when cati installation is corrupt and user has not root permission to repair it and passes filepath and type of that to function """ required_files = [ '/var/lib/cati/state.f', '/var/lib/cati/unremoved-conffiles.list', '/etc/cati/repos.list', '/etc/cati/allowed-architectures.list', ] required_dirs = [ '/var', '/var/lib', '/var/lib/cati', '/var/lib/cati/lists', '/var/lib/cati/installed', '/var/lib/cati/security-blacklist', '/var/lib/cati/any-scripts', '/var/cache', '/var/cache/cati', '/var/cache/cati/archives', '/etc', '/etc/cati', '/etc/cati/repos.list.d', ] for d in required_dirs: if not os.path.isdir(Env.base_path('/' + d)): repair_once_dir(d, events) for f in required_files: if not os.path.isfile(Env.base_path('/' + f)): repair_once_file(f, events)
def repair_once_dir(dirpath: str, events: dict): """ Repairs once dir Args: dirpath (str): the dirpath to repair events (dict): - faild_to_repair """ try: os.mkdir(Env.base_path('/' + dirpath)) except: events['failed_to_repair']('/' + dirpath, 'dir')
def repair_once_file(filepath: str, events: dict): """ Repairs once file Args: filepath (str): the filepath to repair events (dict): - faild_to_repair """ try: f = open(Env.base_path('/' + filepath).replace('//', '/'), 'w') f.write('') f.close() except: events['failed_to_repair']('/' + filepath, 'file')
def copy_once_file(self, paths): """ Copy one of package files (this method is called from `copy_files` method) """ if os.path.isfile(paths[1]): if paths[0] in self.conffiles: self.copied_files.append('cf:' + paths[0]) old_conffiles = [item[-1] for item in self.old_conffiles] if paths[0] in old_conffiles: f_hash = calc_file_sha256(paths[1]) if [f_hash, paths[0]] in self.old_conffiles: self.uncopied_conffiles[paths[0]] = f_hash return else: if self.keep_conffiles: self.uncopied_conffiles[paths[0]] = f_hash return else: self.copied_files.append('f:' + paths[0]) os.system('cp "' + paths[1] + '" "' + Env.base_path(paths[0]) + '"') else: os.mkdir(Env.base_path(paths[0])) if paths[1] in self.conffiles: self.copied_files.append('cd:' + paths[0]) else: self.copied_files.append('d:' + paths[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()
def env(self, path=''): return Env.base_path(path)
def check_state(query_string: str, virtual=None, get_false_pkg=False, get_false_pkg_next=0, get_true_pkg=False, get_true_pkg_next=0) -> bool: """ Checks package state by query string. Examples: "somepackage >= 1.5", "somepackage", "somepackage = 2.0", "somepackage < 1.7", "pkga | pkgb >= 1.0", "pkga | pkgb | pkgc", "pkga | pkgb & pkgc = 1.0", also there is a feature to check files: "@/usr/bin/somefile", "somepackage | @/path/to/somefile", "testpkga >= 3.0 | @/somefile" "@/file/one | @/file/two", "@<sha256-hash>@/path/to/file", "@76883f0fd14015c93296f0e4202241f4eb3a23189dbc17990a197477f1dc441a@/path/to/file" `virtual` argument: this argument can make a virtual package state for example package `testpkgz` is not installed, but we want to check the query when this is installed we can set that package in virtual system to query checker calculate tha package as installed/removed virtual structure: this is dictonary: { 'install': [ ## a list from installed packages: ['testpkgx', '1.0'], ['testpkgz', '3.7.11'], ... ] 'remove': [ ## a list from removed packages: ['testpkgx', '1.0'], ['testpkgz', '3.7.11'], ... ] ## set it True if you want to ignore real installations 'no_real_installs': True/False ## set it True if you want to ignore real not installations 'all_real_is_installed': True/False } """ # parse query string parts = query_string.strip().split('|') orig_parts = [] for part in parts: tmp = part.strip().split('&') orig_parts.append(tmp) # load virtual item no_real_installs = False all_real_is_installed = False if virtual: try: tmp = virtual['install'] except: virtual['install'] = [] try: tmp = virtual['remove'] except: virtual['remove'] = [] virtual_installed_names_list = [] virtual_installed_versions_dict = {} for item in virtual['install']: virtual_installed_versions_dict[item[0]] = item[1] virtual_installed_names_list.append(item[0]) virtual_removed_names_list = [] virtual_removed_versions_dict = {} for item in virtual['remove']: virtual_removed_versions_dict[item[0]] = item[1] virtual_removed_names_list.append(item[0]) try: no_real_installs = virtual['no_real_installs'] except: no_real_installs = False try: all_real_is_installed = virtual['all_real_is_installed'] except: all_real_is_installed = False else: virtual_installed_names_list = [] virtual_installed_versions_dict = {} virtual_removed_names_list = [] virtual_removed_versions_dict = {} no_real_installs = False all_real_is_installed = False # parse once query i = 0 while i < len(orig_parts): j = 0 while j < len(orig_parts[i]): orig_parts[i][j] = orig_parts[i][j].strip() spliter = None if '>=' in orig_parts[i][j]: spliter = '>=' elif '<=' in orig_parts[i][j]: spliter = '<=' elif '>' in orig_parts[i][j]: spliter = '>' elif '<' in orig_parts[i][j]: spliter = '<' elif '=' in orig_parts[i][j]: spliter = '=' if spliter != None: orig_parts[i][j] = orig_parts[i][j].split(spliter) orig_parts[i][j].insert(1, spliter) else: orig_parts[i][j] = [orig_parts[i][j]] z = 0 while z < len(orig_parts[i][j]): orig_parts[i][j][z] = orig_parts[i][j][z].strip() z += 1 j += 1 i += 1 # check query for tmp in orig_parts: ands_ok = True for p in tmp: if p[0][0] == '@': # check file query parts = p[0].split('@') if len(parts) == 2: if not os.path.exists(Env.base_path(parts[-1])): ands_ok = False elif len(parts) == 3: if not os.path.exists(Env.base_path(parts[-1])): ands_ok = False else: if os.path.isfile(Env.base_path(parts[-1])): sha256_sum = calc_file_sha256( Env.base_path(parts[-1])) if parts[1] != sha256_sum: ands_ok = False elif not p[ 0] in virtual_installed_names_list and no_real_installs: ands_ok = False if get_false_pkg and get_false_pkg_next <= 0: return p else: get_false_pkg_next -= 1 elif not p[ 0] in virtual_removed_names_list and all_real_is_installed: pass elif len(p) == 1: if not Pkg.is_installed(p[0]) and not p[ 0] in virtual_installed_names_list or p[ 0] in virtual_removed_names_list: ands_ok = False if get_false_pkg and get_false_pkg_next <= 0: return p else: get_false_pkg_next -= 1 elif len(p) == 3: if not Pkg.is_installed(p[0]) and not p[ 0] in virtual_installed_names_list or p[ 0] in virtual_removed_names_list: ands_ok = False if get_false_pkg and get_false_pkg_next <= 0: return p else: get_false_pkg_next -= 1 else: if p[0] in virtual_installed_names_list: a_ver = virtual_installed_versions_dict[p[0]] else: a_ver = Pkg.installed_version(p[0]) b_ver = p[2] if p[1] == '=': if Pkg.compare_version(a_ver, b_ver) != 0: ands_ok = False if get_false_pkg and get_false_pkg_next <= 0: return p else: get_false_pkg_next -= 1 elif p[1] == '>': if Pkg.compare_version(a_ver, b_ver) != 1: ands_ok = False if get_false_pkg and get_false_pkg_next <= 0: return p else: get_false_pkg_next -= 1 elif p[1] == '<': if Pkg.compare_version(a_ver, b_ver) != -1: ands_ok = False if get_false_pkg and get_false_pkg_next <= 0: return p else: get_false_pkg_next -= 1 elif p[1] == '<=': if Pkg.compare_version( a_ver, b_ver) != -1 and Pkg.compare_version( a_ver, b_ver) != 0: ands_ok = False if get_false_pkg and get_false_pkg_next <= 0: return p else: get_false_pkg_next -= 1 elif p[1] == '>=': if Pkg.compare_version( a_ver, b_ver) != 1 and Pkg.compare_version( a_ver, b_ver) != 0: ands_ok = False if get_false_pkg and get_false_pkg_next <= 0: return p else: get_false_pkg_next -= 1 else: ands_ok = False if get_false_pkg and get_false_pkg_next <= 0: return p else: get_false_pkg_next -= 1 if ands_ok and get_true_pkg and get_true_pkg_next <= 0: return p else: get_true_pkg_next -= 1 if ands_ok: return True return False
def run(self): """ Run command """ # require root permission require_root_permission() result_code = 0 packages_to_reinstall = [] if not self.is_quiet(): pr.p('Starting checking system health and security...') pr.p('===============================================') # check state state_cmd = StateCommand() out = state_cmd.handle(ArgParser.parse(['cati', 'state'])) if out > 0: return out # search for conflict and dependency corruptions if not self.is_quiet(): pr.p('Checking dependency and conflict corruptions...') dependency_problems = [] conflict_problems = [] installed_packages = Pkg.installed_list()['list'] for pkg in installed_packages: if self.is_verbose(): pr.p('[info] checking dependencies and conflicts for ' + pkg.data['name'] + '...') for dp in pkg.get_depends(): if not Pkg.check_state(dp): dependency_problems.append([pkg, dp]) for conflict in pkg.get_conflicts(): if Pkg.check_state(conflict): conflict_problems.append([pkg, conflict]) if dependency_problems or conflict_problems: for depend in dependency_problems: pr.p(ansi.red + 'dependency problem for ' + depend[0].data['name'] + ': ' + depend[1] + ansi.reset) packages_to_reinstall.append(depend[0]) for conflict in conflict_problems: pr.p(ansi.red + 'conflict problem for ' + conflict[0].data['name'] + ': ' + conflict[1] + ansi.reset) packages_to_reinstall.append(conflict[0]) result_code = 1 else: pr.p( ansi.green + 'There is not any conflict or dependnecy problem and everything is ok' + ansi.reset) # check static files if not self.is_quiet(): pr.p('Checking packages static files...') staticfile_problems = [] for pkg in installed_packages: if self.is_verbose(): pr.p('[info] checking static files for ' + pkg.data['name'] + '...') files = pkg.installed_static_files() for f in files: f[1] = Env.base_path(f[1]) if os.path.isfile(f[1]): wanted_hash = f[0] current_hash = calc_file_sha256(f[1]) if wanted_hash != current_hash: staticfile_problems.append([pkg, f, 'file is changed']) else: staticfile_problems.append([pkg, f, 'file is deleted']) if staticfile_problems: for problem in staticfile_problems: pr.p(ansi.red + 'staticfile problem in package ' + problem[0].data['name'] + ': ' + problem[1][1] + ': ' + problem[2] + ansi.reset) packages_to_reinstall.append(problem[0]) result_code = 1 else: pr.p(ansi.green + 'all of static files are ok' + ansi.reset) # check repos config files health if not self.is_quiet(): pr.p('Checking cati configuration files...') if self.is_verbose(): pr.p('[info] checking repositories config...') repos = Repo.get_list() pr.p(ansi.red, end='') ReposListErrorShower.show(repos) pr.p(ansi.reset, end='') is_any_repo_error = False for repo in repos: if repo.syntax_errors: is_any_repo_error = True result_code = 1 if not is_any_repo_error: pr.p(ansi.green + 'all of cati configuration files are ok' + ansi.reset) # check database files if not self.is_quiet(): pr.p('Checking cati database...') database_problems = [] for f in os.listdir(Env.installed_lists()): if self.is_verbose(): pr.p('[info] checking database install dir for ' + f + '...') if not os.path.isfile(Env.installed_lists( '/' + f + '/files')) or not os.path.isfile( Env.installed_lists('/' + f + '/ver')): database_problems.append( 'installed packages database: directory ' + Env.installed_lists('/' + f) + ' is corrupt') for f in os.listdir(Env.security_blacklist()): if self.is_verbose(): pr.p('[info] checking security blacklist part ' + f + '...') if not os.path.isfile(Env.security_blacklist('/' + f)): database_problems.append( 'security blacklist: an directory detected: ' + Env.security_blacklist('/' + f)) else: tmp = open(Env.security_blacklist('/' + f), 'r') try: json.loads(tmp.read()) except: database_problems.append( 'security blacklist: invalid json data in ' + Env.security_blacklist('/' + f)) if database_problems: for problem in database_problems: pr.p(ansi.red + 'database: ' + problem + ansi.reset) result_code = 1 else: pr.p(ansi.green + 'all of cati database is ok' + ansi.reset) if not self.is_quiet(): if packages_to_reinstall: pr.p(ansi.blue + 'We suggest re-install this packages:') for pkg in packages_to_reinstall: pr.p('- ' + pkg.data['name']) if not self.has_option('--autofix'): pr.p( 'use --autofix option to re-install them or do this manually' ) pr.p(ansi.reset, end='') else: pr.p(ansi.reset, end='') packages_names = [ pkg.data['name'] for pkg in packages_to_reinstall ] install_cmd = InstallCommand() args = ['cati', 'install', '--reinstall', *packages_names] cmd_str = '' for arg in args: cmd_str += arg + ' ' cmd_str = cmd_str.strip() pr.p(cmd_str) return install_cmd.handle(ArgParser.parse(args)) return result_code
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)
def copy_files(self, pkg: BaseArchive, directory_not_empty_event, target_path='') -> list: """ Copy package files on system Args: pkg (BaseArchive): the package archive object directory_not_empty_event (callable): the function will be run when we want to delete old direcotry of package and that is not empty. target_path (str): target path prefix of copied files location. default is `/` means copies files on the root directory. you can change it. Returns: list[str]: list of copied files """ # load package old files list old_files = [] if os.path.isfile(Env.installed_lists('/' + pkg.data['name'] + '/files')): try: f = open(Env.installed_lists('/' + pkg.data['name'] + '/files'), 'r') for line in f.read().strip().split('\n'): if line != '': old_files.append(line.strip()) except: pass old_files = list(reversed(old_files)) # load unremoved conffiles list unremoved_conffiles_f = open(Env.unremoved_conffiles(), 'r') unremoved_conffiles = unremoved_conffiles_f.read().strip().split('\n') unremoved_conffiles_f.close() temp_dir = self.extracted_package_dir # load files list from `files` directory of package self.loaded_files = [] self.load_files(temp_dir + '/files', temp_dir + '/files') self.loaded_files = [[target_path + f[0], f[1]] for f in self.loaded_files] # check file conflicts all_installed_files = Pkg.get_all_installed_files_list() for lf in self.loaded_files: if not os.path.isdir(lf[1]): for insf in all_installed_files: if insf[0].split(':', 1)[0] != pkg.data['name']: if lf[0] == insf[2]: insf_pkg = Pkg.load_last(insf[0]) if insf_pkg: insf[0] = insf[0] + ':' + insf_pkg.installed() # check package is in `replaces` list do_raise_error = True replaces_list = pkg.get_replaces() for rep in replaces_list: if Pkg.check_state(rep): tmp_parts = rep.split(' ') tmp_parts = tmp_parts[0].split('>') tmp_parts = tmp_parts[0].split('<') tmp_parts = tmp_parts[0].split('=') tmp_parts = tmp_parts[0] if tmp_parts == insf[0].split(':', 1)[0]: do_raise_error = False if do_raise_error: raise FileConflictError( 'package ' + pkg.data['name'] + ':' + pkg.data['version'] + ' and ' + insf[0] + ' both has file "' + lf[0] + '"' ) # copy loaded files self.copied_files = [] for f in self.loaded_files: if os.path.exists(Env.base_path(f[0])): if os.path.isfile(Env.base_path(f[0])): if ('f:' + f[0]) in old_files or ('cf:' + f[0]) in old_files: self.copy_once_file(f) try: old_files.pop(old_files.index(('f:' + f[0]))) except: pass else: if f[0] in unremoved_conffiles: self.copy_once_file(f) unremoved_conffiles.pop(unremoved_conffiles.index(f[0])) else: self.copy_once_file(f) else: if ('d:' + f[0]) in old_files or ('cd:' + f[0]) in old_files: if ('cd:' + f[0]) in old_files: self.copied_files.append('cd:' + f[0]) old_files.pop(old_files.index(('cd:' + f[0]))) else: self.copied_files.append('d:' + f[0]) old_files.pop(old_files.index(('d:' + f[0]))) else: if f[0] in unremoved_conffiles: self.copied_files.append('d:' + f[0]) unremoved_conffiles.pop(unremoved_conffiles.index(f[0])) else: self.copy_once_file(f) # delete not wanted old files for item in old_files: parts = item.strip().split(':', 1) if parts[0] == 'cf' or parts[0] == 'cd': pass else: if os.path.isfile(parts[1]): os.remove(parts[1]) else: try: os.rmdir(parts[1]) except: # directory is not emptyr directory_not_empty_event(pkg, parts[1]) # write new unremoved conffiles list unremoved_conffiles_f = open(Env.unremoved_conffiles(), 'w') new_content = '' for item in unremoved_conffiles: new_content += item + '\n' unremoved_conffiles_f.write(new_content) unremoved_conffiles_f.close() return self.copied_files
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)