[1bd24c9] | 1 | import logging |
---|
| 2 | import subprocess |
---|
| 3 | import re |
---|
| 4 | import os |
---|
| 5 | import configparser |
---|
[ef4ff2a] | 6 | import selectors |
---|
[1bd24c9] | 7 | |
---|
| 8 | logger = logging.getLogger ('boottools') |
---|
| 9 | |
---|
| 10 | def run (args): |
---|
[ef4ff2a] | 11 | stdout = stderr = '' |
---|
| 12 | logger.debug ('run 10 args "{}"'.format (' '.join(args))) |
---|
| 13 | sel = selectors.DefaultSelector() |
---|
| 14 | p = subprocess.Popen (args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) |
---|
| 15 | sel.register (p.stdout.fileno(), selectors.EVENT_READ) |
---|
| 16 | sel.register (p.stderr.fileno(), selectors.EVENT_READ) |
---|
| 17 | while True: |
---|
| 18 | events = sel.select() |
---|
| 19 | for key, _ in events: |
---|
| 20 | if key.fileobj == p.stdout.fileno(): |
---|
| 21 | line = p.stdout.readline() |
---|
| 22 | if not line: break |
---|
| 23 | stdout += line |
---|
| 24 | logger.debug (line.rstrip()) |
---|
| 25 | elif key.fileobj == p.stderr.fileno(): |
---|
| 26 | line = p.stderr.readline() |
---|
| 27 | if not line: break |
---|
| 28 | stderr += line |
---|
| 29 | logger.warn (line.rstrip()) |
---|
| 30 | if p.poll() != None: |
---|
| 31 | break |
---|
| 32 | sel.close() |
---|
[f002c56] | 33 | stdout = stdout.strip() |
---|
| 34 | stderr = stderr.strip() |
---|
[1bd24c9] | 35 | |
---|
[ef4ff2a] | 36 | logger.debug (f'p.returncode {p.returncode}') |
---|
| 37 | if p.returncode: |
---|
| 38 | logger.error ('command "{}" failed with rc "{}"'.format (' '.join(args), p.returncode)) |
---|
| 39 | |
---|
| 40 | #logger.error ('stdout follows:') |
---|
[f002c56] | 41 | #if stdout: |
---|
| 42 | # for i in stdout.split('\n'): logger.error (' ' + i) |
---|
[1bd24c9] | 43 | |
---|
| 44 | logger.error ('stderr follows:') |
---|
[f002c56] | 45 | if stderr: |
---|
| 46 | for i in stderr.split('\n'): logger.error (' ' + i) |
---|
[1bd24c9] | 47 | |
---|
[ef4ff2a] | 48 | raise Exception ('command "{}" failed with rc "{}"'.format (' '.join(args), p.returncode)) |
---|
[1bd24c9] | 49 | return stdout, stderr |
---|
| 50 | |
---|
| 51 | def grep (regex, file): |
---|
| 52 | with open (file, 'r') as f: |
---|
| 53 | for l in f: |
---|
| 54 | if (re.findall (regex, l)): return 1 |
---|
| 55 | return 0 |
---|
| 56 | |
---|
| 57 | def is_mounted (mntpt): |
---|
| 58 | return grep (mntpt, '/proc/mounts') |
---|
| 59 | |
---|
| 60 | def mount (dev, mntpt, opts=[]): |
---|
| 61 | if not is_mounted (mntpt): |
---|
| 62 | run (['mount', dev, mntpt] + opts) |
---|
| 63 | |
---|
| 64 | def umount (mntpt): |
---|
| 65 | if (is_mounted (mntpt)): |
---|
| 66 | run (['umount', mntpt]) |
---|
| 67 | |
---|
| 68 | def read_config (fn): |
---|
| 69 | if not os.path.exists (fn): |
---|
| 70 | print (f'configuration file "{fn}" not found') |
---|
| 71 | return |
---|
| 72 | config = configparser.ConfigParser (comment_prefixes='#', inline_comment_prefixes='#') |
---|
| 73 | config.read (fn) |
---|
| 74 | return config |
---|
| 75 | |
---|
| 76 | def write_md5 (fn): |
---|
| 77 | md5, _ = run (['md5sum', fn]) |
---|
| 78 | md5, rest = md5.split (' ', 1) |
---|
| 79 | with open (f'{fn}.sum', 'w') as fd: |
---|
| 80 | fd.write (md5 + '\n') |
---|