#!/usr/bin/python3 from pathlib import Path from json import load as load_json, decoder import shutil from sys import exit class ControlParser(): def __init__(self): try: fp = Path('debian/control').open('r', encoding='utf-8') except IOError: raise Exception('cannot find debian/control file') self.lines = fp.readlines() self.packages = [] self.source_name = None def load_info(self): for line in self.lines: if line.lower().startswith('package:'): self.packages.append(line[8:].strip()) elif line.lower().startswith('source:'): self.source_name = line[7:].strip() class DHelper(): def __init__(self, controlparser): self.n4d_base_path = Path('/var/lib/n4d') self.n4d_inbox_path = self.n4d_base_path.joinpath('variables-inbox') self.n4d_trash_path = self.n4d_base_path.joinpath('variables-trash') self.n4d_vars_path = self.n4d_base_path.joinpath('variables') self.packages_to_remove={} self.controlparser = controlparser if Path('debian/n4dvars').exists(): shutil.copyfile('debian/n4dvars', 'debian/{f}.n4dvars'.format(f=controlparser.packages[0])) def write_lintian(self, package): with Path( 'debian/{package}.lintian-overrides'.format( package = package )).open('a', encoding = 'utf-8' ) as fd: fd.write( '{package}: possibly-insecure-handling-of-tmp-files-in-maintainer-script\n'.format( package = package ) ) def process_vars(self, package): error_list = [] file_path = Path('debian/{package}.n4dvars'.format( package = package )) if not file_path.exists(): return error_list with file_path.open('r', encoding='utf-8' ) as fd: for line in fd.readlines(): variable_path = Path(line.strip()) if not variable_path.exists(): error_list.append('[{package}]: {file} var file not exists. You can delete this reference in {parentfile} or create {file}' .format(package=package, file=str(variable_path), parentfile=str(file_path))) continue if variable_path.is_file(): error_list.extend( self.install_files( package, variable_path ) ) if variable_path.is_dir(): for iter_variable_path in variable_path.iterdir(): if iter_variable_path.is_file(): error_list.extend( self.install_files( package, iter_variable_path ) ) self.write_postinst(package) self.write_prerm(package) return error_list def install_files( self, package, variable_file_path ): error_list = [] try: j = load_json( variable_file_path.open('r',encoding='utf-8') ) except decoder.JSONDecodeError: error_list.append('[{package}]: {file} has syntax error'.format(package=package, file=str(variable_file_path))) vars_template = {'package': package, 'inboxpath': str(self.n4d_inbox_path), 'varspath':str(self.n4d_vars_path), 'name': variable_file_path.name} Path('debian/{package}/{inboxpath}'.format(**vars_template)).mkdir(parents=True,exist_ok=True) shutil.copyfile(str(variable_file_path), 'debian/{package}/{inboxpath}/{package}.n4dvars.{name}'.format(**vars_template)) self.packages_to_remove[package].append('{varspath}/{package}.n4dvars.{name}'.format(**vars_template)) return error_list def run(self): error_list = [] for package in self.controlparser.packages: self.packages_to_remove[package]=[] error_list.extend(self.process_vars(package)) self.write_lintian(package) if len(error_list) > 0: print("Error on n4d debhelper") print("======================") for x in error_list: print(x+"\n") exit(1) def write_postinst(self, package): with Path('debian/{package}.postinst.debhelper'.format(package=package)).open('a',encoding='utf-8') as fd: fd.write(''' ############################################ # Automatically generated by dn4dh_install # ############################################ case "$1" in configure) if [ -e '/run/n4d/token' ]; then AUX_PID=$(cat /run/n4d/token) STATUS=$(ps -p $AUX_PID -o args= | grep n4d-server || true) if [ "$STATUS" != "" ]; then n4d-vars readinbox || true fi fi ;; *) ;; esac ################################################ # END Automatically generated by dn4dh_install # ################################################ ''') def write_prerm(self, package): packages_to_remove = " ".join("'{0}'".format(w) for w in self.packages_to_remove[package] ) with Path('debian/{package}.prerm.debhelper'.format(package=package)).open('a',encoding='utf-8') as fd: fd.write(''' ############################################ # Automatically generated by dn4dh_install # ############################################ case "$1" in remove|purge) if [ -d "{path_installed_vars}" ]; then for x in {vars_to_delete}; do if [ -e "$x" ]; then cp $x {path_trash_vars} fi done if [ -e '/run/n4d/token' ]; then AUX_PID=$(cat /run/n4d/token) STATUS=$(ps -p $AUX_PID -o args= | grep n4d-server || true) if [ "$STATUS" != "" ]; then n4d-vars emptytrash || true fi fi fi ;; *) ;; esac ################################################ # END Automatically generated by dn4dh_install # ################################################ '''.format(path_installed_vars=self.n4d_vars_path, path_trash_vars=self.n4d_trash_path, vars_to_delete=packages_to_remove)) def main(): control = ControlParser() control.load_info() dhelper = DHelper(control) dhelper.run() if __name__ == '__main__': main()