forked from dapplegatecp/lpp-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpackage_application.py
More file actions
170 lines (128 loc) · 5.32 KB
/
package_application.py
File metadata and controls
170 lines (128 loc) · 5.32 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env python3
import configparser
import datetime
import hashlib
import json
import os
import re
import shutil
import sys
import uuid
import tarfile
import gzip
META_DATA_FOLDER = 'METADATA'
CONFIG_FILE = 'package.ini'
SIGNATURE_FILE = 'SIGNATURE.DS'
MANIFEST_FILE = 'MANIFEST.json'
BYTE_CODE_FILES = re.compile(r'^.*/.(pyc|pyo|pyd)$')
BYTE_CODE_FOLDERS = re.compile('^(__pycache__)$')
def file_checksum(hash_func=hashlib.sha256, file=None):
h = hash_func()
buffer_size = h.block_size * 64
with open(file, 'rb') as f:
for buffer in iter(lambda: f.read(buffer_size), b''):
h.update(buffer)
return h.hexdigest()
def hash_dir(target, hash_func=hashlib.sha256):
hashed_files = {}
for path, d, f in os.walk(target):
for fl in f:
if not fl.startswith('.') and not os.path.basename(path).startswith('.'):
# we need this be LINUX fashion!
if sys.platform == "win32":
# swap the network\\tcp_echo to be network/tcp_echo
fully_qualified_file = path.replace('\\', '/') + '/' + fl
else: # else allow normal method
fully_qualified_file = os.path.join(path, fl)
hashed_files[fully_qualified_file[len(target) + 1:]] =\
file_checksum(hash_func, fully_qualified_file)
else:
print("Did not include {} in the App package.".format(fl))
return hashed_files
def pack_package(app_root, app_name):
print('app_root: {}'.format(app_root))
print('app_name: {}'.format(app_name))
print("pack TAR:%s.tar" % app_name)
tar_name = "{}.tar".format(app_name)
tar = tarfile.open(tar_name, 'w')
tar.add(app_root, arcname=os.path.basename(app_root))
tar.close()
print("gzip archive:%s.tar.gz" % app_name)
gzip_name = "{}.tar.gz".format(app_name)
with open(tar_name, 'rb') as f_in:
with gzip.open(gzip_name, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
if os.path.isfile(tar_name):
os.remove(tar_name)
def create_signature(meta_data_folder):
manifest_file = os.path.join(meta_data_folder, MANIFEST_FILE)
with open(os.path.join(meta_data_folder, SIGNATURE_FILE), 'wb') as sf:
checksum = file_checksum(hashlib.sha256, manifest_file).encode('utf-8')
sf.write(checksum)
def clean_manifest_folder(app_metadata_folder):
path, dirs, files = next(os.walk(app_metadata_folder))
for file in files:
fully_qualified_file = os.path.join(path, file)
os.remove(fully_qualified_file)
for d in dirs:
shutil.rmtree(os.path.join(path, d))
def clean_bytecode_files(app_root):
for path, dirs, files in os.walk(app_root):
for file in filter(lambda x: BYTE_CODE_FILES.match(x), files):
os.remove(os.path.join(path, file))
for d in filter(lambda x: BYTE_CODE_FOLDERS.match(x), dirs):
shutil.rmtree(os.path.join(path, d))
pass
def package_application(app_root):
app_root = os.path.realpath(app_root)
app_config_file = os.path.join(app_root, CONFIG_FILE)
app_metadata_folder = os.path.join(app_root, META_DATA_FOLDER)
app_manifest_file = os.path.join(app_metadata_folder, MANIFEST_FILE)
config = configparser.ConfigParser()
config.read(app_config_file)
if not os.path.exists(app_metadata_folder):
os.makedirs(app_metadata_folder)
for section in config.sections():
app_name = section
assert os.path.basename(app_root) == app_name
clean_manifest_folder(app_metadata_folder)
clean_bytecode_files(app_root)
pmf = {}
pmf['version_major'] = int(1)
pmf['version_minor'] = int(0)
pmf['version_patch'] = int(0)
app = {}
app['name'] = str(section)
try:
app['uuid'] = config[section]['uuid']
except KeyError:
app['uuid'] = str(uuid.uuid4())
app['vendor'] = config[section]['vendor']
app['notes'] = config[section]['notes']
app['version_major'] = int(config[section]['version_major'])
app['version_minor'] = int(config[section]['version_minor'])
app['firmware_major'] = int(config[section]['firmware_major'])
app['firmware_minor'] = int(config[section]['firmware_minor'])
app['version_patch'] = int(config[section].get('version_patch', '0'))
app['restart'] = config[section].getboolean('restart')
app['reboot'] = config[section].getboolean('reboot')
app['date'] = datetime.datetime.now().isoformat()
if config.has_option(section, 'auto_start'):
app['auto_start'] = config[section].getboolean('auto_start')
if config.has_option(section, 'app_type'):
app['app_type'] = int(config[section]['app_type'])
data = {}
data['pmf'] = pmf
data['app'] = app
app['files'] = hash_dir(app_root)
with open(app_manifest_file, 'w') as f:
f.write(json.dumps(data, indent=4, sort_keys=True))
create_signature(app_metadata_folder)
pack_package(app_root, section)
print('Package {}.tar.gz created'.format(section))
def argument_list(args):
print('{} <applicationRoot>'.format(args[0]))
if __name__ == "__main__":
if len(sys.argv) < 1:
argument_list(sys.argv)
package_application(sys.argv[1])