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
|
import os
import shutil
import stat
import struct
import subprocess
import sys
# Explicitly enable local imports
# Don't forget to add imported scripts to inputs of the calling command!
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import container # 1
def main(output_path, entry_path, input_paths, squashfs_path):
output_tmp_path = output_path + '.tmp'
shutil.copy2(entry_path, output_tmp_path)
st = os.stat(output_tmp_path)
os.chmod(output_tmp_path, st.st_mode | stat.S_IWUSR)
layer_paths = []
other_paths = []
for input_path in input_paths:
(layer_paths if input_path.endswith('.container_layer') else other_paths).append(input_path)
if len(other_paths) == 0:
raise Exception('No program in container dependencies')
if len(other_paths) > 1:
raise Exception('Multiple non-layer inputs')
program_path = other_paths[0]
program_container_path = os.path.basename(program_path)
os.symlink(program_container_path, 'entry')
add_cmd = [os.path.join(squashfs_path, 'mksquashfs')]
add_cmd.extend([program_path, 'entry', 'program_layer'])
subprocess.run(add_cmd)
layer_paths.append('program_layer')
container.join_layers(layer_paths, 'container_data', squashfs_path)
size = 0
block_size = 1024 * 1024
with open(output_tmp_path, 'ab') as output:
with open('container_data', 'rb') as input_:
while True:
data = input_.read(block_size)
output.write(data)
size += len(data)
if len(data) < block_size:
break
with open(os.path.join(squashfs_path, 'unsquashfs'), 'rb') as input_:
while True:
data = input_.read(block_size)
output.write(data)
size += len(data)
if len(data) == 0:
break
output.write(struct.pack('<Q', size))
os.rename(output_tmp_path, output_path)
def entry():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--output', required=True)
parser.add_argument('-s', '--squashfs-path', required=True)
parser.add_argument('input', nargs='*')
args = parser.parse_args()
def is_container_entry(path):
return os.path.basename(path) == '_container_entry'
input_paths = []
entry_paths = []
for input_path in args.input:
(entry_paths if is_container_entry(input_path) else input_paths).append(input_path)
if len(entry_paths) != 1:
raise Exception('Could not select container entry from {}'.format(entry_paths))
return main(args.output, entry_paths[0], input_paths, args.squashfs_path)
if __name__ == '__main__':
sys.exit(entry())
|