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)
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
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 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)