import logging import subprocess import re import os import configparser import selectors logger = logging.getLogger ('boottools') def run (args): stdout = stderr = '' logger.debug ('run 10 args "{}"'.format (' '.join(args))) sel = selectors.DefaultSelector() p = subprocess.Popen (args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) sel.register (p.stdout.fileno(), selectors.EVENT_READ) sel.register (p.stderr.fileno(), selectors.EVENT_READ) while True: events = sel.select() for key, _ in events: if key.fileobj == p.stdout.fileno(): line = p.stdout.readline() if not line: break stdout += line logger.debug (line.rstrip()) elif key.fileobj == p.stderr.fileno(): line = p.stderr.readline() if not line: break stderr += line logger.warn (line.rstrip()) if p.poll() != None: break sel.close() stdout = stdout.strip() stderr = stderr.strip() logger.debug (f'p.returncode {p.returncode}') if p.returncode: logger.error ('command "{}" failed with rc "{}"'.format (' '.join(args), p.returncode)) #logger.error ('stdout follows:') #if stdout: # for i in stdout.split('\n'): logger.error (' ' + i) logger.error ('stderr follows:') if stderr: for i in stderr.split('\n'): logger.error (' ' + i) raise Exception ('command "{}" failed with rc "{}"'.format (' '.join(args), p.returncode)) return stdout, stderr def grep (regex, file): with open (file, 'r') as f: for l in f: if (re.findall (regex, l)): return 1 return 0 def is_mounted (mntpt): return grep (mntpt, '/proc/mounts') def mount (dev, mntpt, opts=[]): if not is_mounted (mntpt): run (['mount', dev, mntpt] + opts) def umount (mntpt): if (is_mounted (mntpt)): run (['umount', mntpt]) def read_config (fn): if not os.path.exists (fn): print (f'configuration file "{fn}" not found') return config = configparser.ConfigParser (comment_prefixes='#', inline_comment_prefixes='#') config.read (fn) return config def write_md5 (fn): md5, _ = run (['md5sum', fn]) md5, rest = md5.split (' ', 1) with open (f'{fn}.sum', 'w') as fd: fd.write (md5 + '\n')