2024-06-29 18:29:49 +00:00
|
|
|
import base64
|
|
|
|
import json
|
|
|
|
import os
|
2024-06-30 02:44:12 +00:00
|
|
|
import subprocess
|
2024-06-29 18:29:49 +00:00
|
|
|
import sys
|
|
|
|
|
2024-06-29 20:02:25 +00:00
|
|
|
path_prefix = "./_minified/"
|
|
|
|
|
2024-06-30 02:44:12 +00:00
|
|
|
# get git build info
|
|
|
|
build = subprocess.check_output(["git", "describe", "--tags"]).strip().decode("utf-8")
|
|
|
|
|
|
|
|
# list files in a directory
|
|
|
|
def list_files(path):
|
|
|
|
list = []
|
|
|
|
|
|
|
|
for (root, dirs, files) in os.walk(path):
|
|
|
|
for f in files:
|
|
|
|
list.append((root[2:] + "/" + f).replace('\\','/'))
|
|
|
|
|
|
|
|
return list
|
|
|
|
|
2024-06-29 20:02:25 +00:00
|
|
|
# recursively encode files with base64
|
2024-06-29 18:29:49 +00:00
|
|
|
def encode_recursive(path):
|
|
|
|
list = {}
|
|
|
|
|
|
|
|
for item in os.listdir(path):
|
|
|
|
item_path = path + '/' + item
|
|
|
|
|
|
|
|
if os.path.isfile(item_path):
|
|
|
|
handle = open(item_path, 'r')
|
|
|
|
list[item] = base64.b64encode(bytes(handle.read(), 'UTF-8')).decode('ASCII')
|
|
|
|
handle.close()
|
|
|
|
else:
|
|
|
|
list[item] = encode_recursive(item_path)
|
|
|
|
|
|
|
|
return list
|
|
|
|
|
2024-06-29 20:02:25 +00:00
|
|
|
# encode listed files with base64
|
2024-06-29 18:29:49 +00:00
|
|
|
def encode_files(files):
|
|
|
|
list = {}
|
|
|
|
|
|
|
|
for item in files:
|
2024-06-29 20:02:25 +00:00
|
|
|
item_path = path_prefix + './' + item
|
2024-06-29 18:29:49 +00:00
|
|
|
|
|
|
|
handle = open(item_path, 'r')
|
|
|
|
list[item] = base64.b64encode(bytes(handle.read(), 'UTF-8')).decode('ASCII')
|
|
|
|
handle.close()
|
|
|
|
|
|
|
|
return list
|
|
|
|
|
2024-06-30 02:44:12 +00:00
|
|
|
# get the version of an application at the provided path
|
|
|
|
def get_version(path, is_lib = False):
|
|
|
|
ver = ""
|
|
|
|
string = ".version = \""
|
|
|
|
|
|
|
|
if not is_lib:
|
|
|
|
string = "_VERSION = \""
|
|
|
|
|
|
|
|
f = open(path, "r")
|
|
|
|
|
|
|
|
for line in f:
|
|
|
|
pos = line.find(string)
|
|
|
|
if pos >= 0:
|
|
|
|
ver = line[(pos + len(string)):(len(line) - 2)]
|
|
|
|
break
|
|
|
|
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
return ver
|
|
|
|
|
2024-06-29 20:02:25 +00:00
|
|
|
# file manifest (reflects imgen.py)
|
2024-06-29 18:29:49 +00:00
|
|
|
manifest = {
|
2024-06-30 02:44:12 +00:00
|
|
|
"common_versions" : {
|
|
|
|
"bootloader" : get_version("./startup.lua"),
|
|
|
|
"common" : get_version("./scada-common/util.lua", True),
|
|
|
|
"comms" : get_version("./scada-common/comms.lua", True),
|
|
|
|
"graphics" : get_version("./graphics/core.lua", True),
|
|
|
|
"lockbox" : get_version("./lockbox/init.lua", True),
|
|
|
|
},
|
|
|
|
"app_versions" : {
|
|
|
|
"reactor-plc" : get_version("./reactor-plc/startup.lua"),
|
|
|
|
"rtu" : get_version("./rtu/startup.lua"),
|
|
|
|
"supervisor" : get_version("./supervisor/startup.lua"),
|
|
|
|
"coordinator" : get_version("./coordinator/startup.lua"),
|
|
|
|
"pocket" : get_version("./pocket/startup.lua")
|
|
|
|
},
|
2024-06-29 18:29:49 +00:00
|
|
|
"files" : {
|
|
|
|
# common files
|
|
|
|
"system" : encode_files([ "initenv.lua", "startup.lua", "configure.lua", "LICENSE" ]),
|
2024-06-30 02:44:12 +00:00
|
|
|
"scada-common" : encode_recursive(path_prefix + "./scada-common"),
|
2024-06-29 20:02:25 +00:00
|
|
|
"graphics" : encode_recursive(path_prefix + "./graphics"),
|
|
|
|
"lockbox" : encode_recursive(path_prefix + "./lockbox"),
|
2024-06-29 18:29:49 +00:00
|
|
|
# platform files
|
2024-06-29 20:02:25 +00:00
|
|
|
"reactor-plc" : encode_recursive(path_prefix + "./reactor-plc"),
|
|
|
|
"rtu" : encode_recursive(path_prefix + "./rtu"),
|
|
|
|
"supervisor" : encode_recursive(path_prefix + "./supervisor"),
|
|
|
|
"coordinator" : encode_recursive(path_prefix + "./coordinator"),
|
|
|
|
"pocket" : encode_recursive(path_prefix + "./pocket"),
|
2024-06-29 18:29:49 +00:00
|
|
|
},
|
2024-06-30 02:44:12 +00:00
|
|
|
"install_files" : {
|
|
|
|
# common files
|
|
|
|
"system" : [ "initenv.lua", "startup.lua", "configure.lua", "LICENSE" ],
|
|
|
|
"scada-common" : list_files("./scada-common"),
|
|
|
|
"graphics" : list_files("./graphics"),
|
|
|
|
"lockbox" : list_files("./lockbox"),
|
|
|
|
# platform files
|
|
|
|
"reactor-plc" : list_files("./reactor-plc"),
|
|
|
|
"rtu" : list_files("./rtu"),
|
|
|
|
"supervisor" : list_files("./supervisor"),
|
|
|
|
"coordinator" : list_files("./coordinator"),
|
|
|
|
"pocket" : list_files("./pocket"),
|
|
|
|
},
|
|
|
|
"depends" : [ "system", "scada-common", "graphics", "lockbox" ],
|
2024-06-29 18:29:49 +00:00
|
|
|
}
|
|
|
|
|
2024-06-29 20:02:25 +00:00
|
|
|
# write the application installation items as Lua tables
|
2024-06-29 18:29:49 +00:00
|
|
|
def write_items(body, items, indent):
|
|
|
|
indent_str = " " * indent
|
|
|
|
for key, value in items.items():
|
|
|
|
if isinstance(value, str):
|
|
|
|
body = body + f"{indent_str}['{key}'] = \"{value}\",\n"
|
|
|
|
else:
|
|
|
|
body = body + f"{indent_str}['{key}'] = {{\n"
|
|
|
|
body = write_items(body, value, indent + 4)
|
|
|
|
body = body + f"{indent_str}}},\n"
|
|
|
|
|
|
|
|
return body
|
|
|
|
|
2024-06-30 02:44:12 +00:00
|
|
|
# create output directory
|
|
|
|
if not os.path.exists("./BUNDLE"):
|
|
|
|
os.makedirs("./BUNDLE")
|
|
|
|
|
|
|
|
# get offline installer
|
|
|
|
ccmsim_file = open("./build/ccmsim.lua", "r")
|
|
|
|
ccmsim_script = ccmsim_file.read()
|
|
|
|
ccmsim_file.close()
|
|
|
|
|
|
|
|
# create dependency bundled file
|
|
|
|
dep_file = "common_" + build + ".lua"
|
|
|
|
f_d = open("./BUNDLE/" + dep_file, "w")
|
|
|
|
|
|
|
|
body_b = "local dep_files = {\n"
|
2024-06-29 18:29:49 +00:00
|
|
|
|
2024-06-30 02:44:12 +00:00
|
|
|
for depend in manifest["depends"]:
|
|
|
|
body_b = body_b + write_items("", { f"{depend}": manifest["files"][depend] }, 4)
|
|
|
|
body_b = body_b + "}\n"
|
2024-06-29 20:02:25 +00:00
|
|
|
|
2024-06-30 02:44:12 +00:00
|
|
|
body_b = body_b + f"""
|
|
|
|
if select("#", ...) == 0 then
|
|
|
|
term.setTextColor(colors.red)
|
|
|
|
print("You must run the other file you should have uploaded (it has the app in its name).")
|
|
|
|
term.setTextColor(colors.white)
|
|
|
|
end
|
|
|
|
|
|
|
|
return dep_files
|
|
|
|
"""
|
|
|
|
|
|
|
|
f_d.write(body_b)
|
|
|
|
f_d.close()
|
|
|
|
|
|
|
|
# application bundled files
|
2024-06-29 18:29:49 +00:00
|
|
|
for app in [ "reactor-plc", "rtu", "supervisor", "coordinator", "pocket" ]:
|
2024-06-30 02:44:12 +00:00
|
|
|
app_file = app + "_" + build + ".lua"
|
|
|
|
|
|
|
|
f_script = open("./build/_offline.lua", "r")
|
|
|
|
script = f_script.read()
|
|
|
|
f_script.close()
|
|
|
|
|
|
|
|
f_a = open("./BUNDLE/" + app_file, "w")
|
|
|
|
|
|
|
|
body_a = "local app_files = {\n"
|
|
|
|
|
|
|
|
body_a = body_a + write_items("", { f"{app}": manifest["files"][app] }, 4) + "}\n"
|
|
|
|
|
|
|
|
versions = manifest["common_versions"].copy()
|
|
|
|
versions[app] = manifest["app_versions"][app]
|
|
|
|
|
|
|
|
depends = manifest["depends"].copy()
|
|
|
|
depends.append(app)
|
|
|
|
|
|
|
|
install_manifest = json.dumps({ "versions" : versions, "files" : manifest["install_files"], "depends" : depends })
|
|
|
|
|
|
|
|
body_a = body_a + f"""
|
|
|
|
-- install manifest JSON and offline installer
|
|
|
|
local install_manifest = "{base64.b64encode(bytes(install_manifest, 'UTF-8')).decode('ASCII')}"
|
|
|
|
local ccmsi_offline = "{base64.b64encode(bytes(ccmsim_script, 'UTF-8')).decode('ASCII')}"
|
|
|
|
|
|
|
|
local function red() term.setTextColor(colors.red) end
|
|
|
|
local function green() term.setTextColor(colors.green) end
|
|
|
|
local function white() term.setTextColor(colors.white) end
|
|
|
|
local function lgray() term.setTextColor(colors.lightGray) end
|
|
|
|
|
|
|
|
if not fs.exists("{dep_file}") then
|
|
|
|
red()
|
|
|
|
print("Missing '{dep_file}'! Please upload it, then run this file again.")
|
|
|
|
white()
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
-- rename the dependency file
|
|
|
|
fs.move("{dep_file}", "install_depends.lua")
|
|
|
|
|
|
|
|
-- load the other file
|
|
|
|
local dep_files = require("install_depends")
|
|
|
|
|
|
|
|
-- delete the uploaded files to free up space to actually install
|
|
|
|
fs.delete("{app_file}")
|
|
|
|
fs.delete("install_depends.lua")
|
|
|
|
|
|
|
|
-- get started installing
|
|
|
|
{script}"""
|
|
|
|
|
|
|
|
f_a.write(body_a)
|
|
|
|
f_a.close()
|