-
Notifications
You must be signed in to change notification settings - Fork 2
/
create_minimal_image.py
82 lines (61 loc) · 2.97 KB
/
create_minimal_image.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
import re
import subprocess
import sys
BUILD_DIR = "build-output"
def main(directory):
find_command = ["find", directory, "-type", "f", "-perm", "/a+x", "-exec", "ldd", "{}", ";"]
find_std_out = _run_popen_command(find_command)
shared_objects = _std_out_to_shared_objects({}, find_std_out)
_copy_files_to_build_output_directory(directory, shared_objects)
return shared_objects
def _copy_files_to_build_output_directory(directory, shared_objects):
build_output_dir = "{0}{1}".format(BUILD_DIR, directory)
_run_popen_command(["mkdir", "-p", build_output_dir])
_run_popen_command(["cp", "-rL", "{0}/.".format(directory), build_output_dir + "/"])
output_dirs = set(build_output_dir)
for file_name in sorted(shared_objects.values()):
_mkdir_and_copy_file(file_name, output_dirs)
def _mkdir_and_copy_file(file_name, output_dirs):
file_directory = "/".join(file_name.split("/")[:-1])
build_output_dir = "{0}{1}/".format(BUILD_DIR, file_directory)
if build_output_dir not in output_dirs:
_run_popen_command(["mkdir", "-p", build_output_dir])
output_dirs.add(build_output_dir)
_run_popen_command(["cp", file_name, build_output_dir])
return output_dirs
def _ldd_of_shared_object(shared_objects, executable):
std_out = _run_popen_command(["ldd", str(executable).strip()])
return _std_out_to_shared_objects(shared_objects, std_out)
def _std_out_to_shared_objects(shared_objects, std_out):
for std_out_line in _convert_std_out_to_list(std_out):
_find_dependencies(shared_objects, std_out_line)
return shared_objects
def _convert_std_out_to_list(std_out):
return std_out.replace("\t", "").strip().split("\n")
def _find_dependencies(shared_objects, std_out_line):
shared_object_name, shared_object_location = _get_shared_object_name_and_location(std_out_line)
if shared_objects.get(shared_object_name, None) is None and shared_object_location:
shared_objects[shared_object_name] = shared_object_location
_ldd_of_shared_object(
shared_objects,
shared_objects[shared_object_name]
)
return shared_objects
def _get_shared_object_name_and_location(std_out_line):
shared_object_name = None
shared_object_location = None
shared_object_details = re.match("(.*)\s=>\s(.*)\s\(0x.*\)|(.*)\s\(0x.*\)", std_out_line)
if shared_object_details:
shared_object_name = shared_object_details.groups()[0]
shared_object_location = shared_object_details.groups()[1]
if shared_object_name is None:
shared_object_name = shared_object_details.groups()[2]
shared_object_location = shared_object_details.groups()[2]
return (shared_object_name, shared_object_location)
def _run_popen_command(command):
popen = subprocess.Popen(command, stdout=subprocess.PIPE)
std_out, std_err = popen.communicate("")
return std_out
if __name__ == "__main__":
for directory in sys.argv[1:]:
main(directory)