-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathobs-compute-binaries-size.py
executable file
·119 lines (98 loc) · 3.79 KB
/
obs-compute-binaries-size.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env python3
import argparse
import subprocess
import shutil
import os
import tempfile
import json
from termcolor import colored
parser = argparse.ArgumentParser(description = 'Get RPM sizes and sizes of ELF files')
parser.add_argument('api', help = 'API')
parser.add_argument('project', help = 'OBS project name')
parser.add_argument('repository', help = 'OBS repository')
parser.add_argument('tmp', help = 'TMP folder where to extract RPM packages')
parser.add_argument('output_folder', help = 'Output folder where to save JSON files')
args = parser.parse_args()
result = subprocess.check_output('osc -A {} r {} -r {} -a {} --csv'.format(args.api, args.project, args.repository, 'x86_64'), shell = True)
packages = result.decode('utf-8', 'ignore').strip().split('\n')
packages = [x.split(';')[0] for x in packages if 'succeeded' in x]
packages = [x for x in packages if x != '_' and not 'gcc' in x]
branched = set()
print('Successfull packages: %d: %s' % (len(packages), str(packages)))
binfolder = args.tmp
assert '/dev/shm' in binfolder
root = os.path.join(binfolder, 'root')
def clean():
shutil.rmtree(binfolder, ignore_errors = True)
os.mkdir(binfolder)
def cleanroot():
shutil.rmtree(root, ignore_errors = True)
os.mkdir(root)
def get_category(rpm):
if '-devel-' in rpm:
return 'devel'
elif '-debuginfo-' in rpm or '-debug-' in rpm:
return 'debug'
else:
return 'normal'
def process_rpm(full):
cleanroot()
vm = {'name': full, 'size': os.path.getsize(full), 'files': []}
subprocess.check_output(f'rpm2cpio {full} | cpio -idmv -D {root}', shell = True, stderr = subprocess.PIPE)
r = subprocess.check_output('du -bs %s' % root, shell = True, encoding = 'utf8')
value = int(r.strip().split('\t')[0])
vm['extracted_size'] = value
print(' extracting: %s: %d' % (full, value))
# process all files
candidates = set()
for r, dirs, files in os.walk(root):
for f in files:
a = os.path.realpath(os.path.join(r, f))
if os.path.exists(a):
candidates.add(a)
else:
# TODO
pass
elfs = []
for f in candidates:
if '- ' in f:
print('skipping due to dash %s' % f)
continue
try:
r = subprocess.run('file %s' % f, shell = True, capture_output=True, encoding = 'utf8', timeout = 30)
if 'ELF' in r.stdout:
s = os.path.getsize(f)
vm['files'].append((f, s))
print(' file: %s: %d' % (f, s))
except subprocess.TimeoutExpired:
print('timeout %s' % f)
pass
return vm
def process_category(name):
vm = []
for f in os.listdir(binfolder):
full = os.path.join(binfolder, f)
if f.endswith('.rpm') and get_category(f) == name:
vm.append(process_rpm(full))
return vm
for i, p in enumerate(packages):
if p in branched:
print('Skipping, branched: %s' % p)
continue
print('Downloading: %s (%d/%d)' % (p, i, len(packages)))
if not os.path.exists(args.output_folder):
os.mkdir(args.output_folder)
jsonfile = os.path.join(args.output_folder, p + '.json')
if os.path.exists(jsonfile):
continue
clean()
try:
vm = {'name': p, 'sections': {}}
subprocess.check_output(f'osc -A {args.api} getbinaries {args.project} {p} {args.repository} x86_64 --debug -d {binfolder}', shell = True, stderr = subprocess.PIPE)
vm['sections']['normal'] = process_category('normal')
vm['sections']['devel'] = process_category('devel')
vm['sections']['debug'] = process_category('debug')
with open(jsonfile, 'w') as of:
json.dump(vm, of)
except subprocess.CalledProcessError as e:
print(str(e))