1 | import logging |
---|
2 | import subprocess |
---|
3 | import re |
---|
4 | import os |
---|
5 | import configparser |
---|
6 | import selectors |
---|
7 | |
---|
8 | logger = logging.getLogger ('boottools') |
---|
9 | |
---|
10 | def run (args): |
---|
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() |
---|
33 | stdout = stdout.strip() |
---|
34 | stderr = stderr.strip() |
---|
35 | |
---|
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:') |
---|
41 | #if stdout: |
---|
42 | # for i in stdout.split('\n'): logger.error (' ' + i) |
---|
43 | |
---|
44 | logger.error ('stderr follows:') |
---|
45 | if stderr: |
---|
46 | for i in stderr.split('\n'): logger.error (' ' + i) |
---|
47 | |
---|
48 | raise Exception ('command "{}" failed with rc "{}"'.format (' '.join(args), p.returncode)) |
---|
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') |
---|