xrnarchive-cli 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. #!/usr/bin/env python3
  2. '''
  3. Software License
  4. Copyright (C) 2021-05-24 Xoronos
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, version 3.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. '''
  15. '''
  16. Liabilities
  17. The software is provided "AS IS" without any warranty of any kind, either expressed,
  18. implied, or statutory, including, but not limited to, any warranty that the software
  19. will conform to specifications, any implied warranties of merchantability, fitness
  20. for a particular purpose, and freedom from infringement, and any warranty that the
  21. documentation will conform to the software, or any warranty that the software will
  22. be error free.
  23. In no event shall Xoronos be liable for any damages, including, but not limited to,
  24. direct, indirect, special or consequential damages, arising out of, resulting from,
  25. or in any way connected with this software, whether or not based upon warranty,
  26. contract, tort, or otherwise, whether or not injury was sustained by persons or
  27. property or otherwise, and whether or not loss was sustained from, or arose out of
  28. the results of, or use of, the software or services provided hereunder.
  29. To request the provided software under a different license you can contact us at
  30. support@xoronos.com
  31. '''
  32. import os
  33. import sys
  34. import re
  35. import json
  36. import tarfile
  37. tool_file_path="/usr/lib/xoronos/py/xrntools_description.json"
  38. def is_valid_json_file(filename):
  39. # Check if the file exists
  40. if not os.path.isfile(filename):
  41. print(f"Error: The file {filename} does not exist.")
  42. return False
  43. # Check if the file content is valid JSON
  44. try:
  45. with open(filename, 'r') as file:
  46. json.load(file)
  47. except json.JSONDecodeError:
  48. print(f"Error: The file {filename} is not a valid JSON file.")
  49. return False
  50. return True
  51. def file_to_expected_name( file_str ):
  52. if ( "xmatrix-comp" in file_str ) :
  53. expected_res = "matrix_compressed"
  54. elif ( "xmatrix" in file_str ) :
  55. expected_res = "matrix"
  56. elif ( "start_point" in file_str ) :
  57. expected_res = "start"
  58. elif ( "point" in file_str ) :
  59. expected_res = "point"
  60. elif ( "binomial_key" in file_str ) :
  61. expected_res = "binomial_key"
  62. elif ( "monomial_key" in file_str ) :
  63. expected_res = "monomial_key"
  64. elif ( "monomial_commitment" in file_str ) :
  65. expected_res = "monomial_commitment"
  66. elif ( "binomial_commitment" in file_str ) :
  67. expected_res = "binomial_commitment"
  68. elif ( "monomial_response" in file_str ) :
  69. expected_res = "monomial_response"
  70. elif ( "monomial_proof" in file_str ) :
  71. expected_res = "monomial_proof"
  72. elif ( "monovalent_key" in file_str ) :
  73. expected_res = "monovalent_key"
  74. elif ( "polyvalent_proof" in file_str ) :
  75. expected_res = "polyvalent_proof"
  76. elif ( "polyvalent_key" in file_str ) :
  77. expected_res = "polyvalent_key"
  78. elif ( "sym_signature" in file_str ) :
  79. expected_res = "signature_sym"
  80. elif ( "asy_signature" in file_str ) :
  81. expected_res = "signature_asy"
  82. elif ( "ring_signature" in file_str ) :
  83. expected_res = "ring_signature"
  84. elif ( "hash" in file_str ) :
  85. expected_res = "hash"
  86. elif ( "sym_certificate" in file_str ) :
  87. expected_res = "certificate_sym"
  88. elif ( "asy_certificate" in file_str ) :
  89. expected_res = "certificate_asy"
  90. else :
  91. expected_res = ""
  92. return expected_res
  93. #########
  94. # lexer #
  95. #########
  96. tool_name_str = "xrnarchive-cli"
  97. cmdgenerate_client_script = "--generate-client-scripts"
  98. optjson_command = "-json-command"
  99. optinput_copy_archive = "-copy-inputs-and-archive-script"
  100. cmdcheck_input = "--check-inputs"
  101. cmdcheck_output = "--check-outputs"
  102. optcopy_output_script = "-extract-outputs-and-copy-script"
  103. cmdgenerate_server_script = "--generate-server-scripts"
  104. optcopy_outputs_and_archive = "-archive-outputs-script"
  105. optlogfile = "-json-log"
  106. def print_help():
  107. print("\n# help page for the {} command\n".format(tool_name_str))
  108. print("# to create client scripts")
  109. print("{} {} \\".format(tool_name_str,cmdgenerate_client_script))
  110. print(" {} command.json \\".format(optjson_command ))
  111. print(" {} copy_and_archive.sh \\".format(optinput_copy_archive ))
  112. print(" {} exctract_and_copy_script.sh ".format(optcopy_output_script ))
  113. print("\n")
  114. print("./copy_and_archive.sh archive.tar /path/to/cache_dir ")
  115. print("./extract_and_copy_script.sh archive.tar /path/to/cache_dir ")
  116. print("")
  117. print("# to check the inputs or outputs files")
  118. print("{} {} {} command.json {} input_log.json ".format(tool_name_str,cmdcheck_input, optjson_command, optlogfile))
  119. print("{} {} {} command.json {} output_log.json ".format(tool_name_str,cmdcheck_output, optjson_command, optlogfile))
  120. print("\n# to create server scripts")
  121. print("{} {} \\".format(tool_name_str,cmdgenerate_server_script))
  122. print(" {} command.json \\".format(optjson_command ))
  123. print(" {} archive_outputs.sh ".format(optcopy_outputs_and_archive ))
  124. print("\n")
  125. print("./archive_outputs.sh archive.tar /path/to/cache_dir ")
  126. print("")
  127. # check syntax
  128. if (( len(sys.argv) != 8 ) and ( len(sys.argv) != 6 )) :
  129. print_help()
  130. exit(-1)
  131. if ( (( len(sys.argv) == 8 ) and ( sys.argv[1] != cmdgenerate_client_script )) and (( len(sys.argv) == 4 ) and ( sys.argv[1] != cmdcheck_input )) and (( len(sys.argv) == 4 ) and ( sys.argv[1] != cmdcheck_output )) and (( len(sys.argv) == 6 ) and ( sys.argv[1] != cmdgenerate_server_script )) ) :
  132. print_help()
  133. exit(-1)
  134. filejson_command = ""
  135. fileinput_copy_archive = ""
  136. filecopy_output_script = ""
  137. fileserver = ""
  138. filelog = ""
  139. check_inputs = 0
  140. check_outputs = 0
  141. if ( sys.argv[1] == cmdgenerate_client_script ) :
  142. for i in range(1, 8):
  143. if ( sys.argv[i] == optjson_command ) :
  144. filejson_command = sys.argv[i+1]
  145. if ( sys.argv[i] == optinput_copy_archive ) :
  146. fileinput_copy_archive = sys.argv[i+1]
  147. if ( sys.argv[i] == optcopy_output_script ) :
  148. filecopy_output_script = sys.argv[i+1]
  149. all_files = [ filejson_command , fileinput_copy_archive , filecopy_output_script ]
  150. for file in all_files :
  151. if ( file == "" ) :
  152. print_help()
  153. exit(-1)
  154. elif (( sys.argv[1] == cmdcheck_input ) and (sys.argv[2] == optjson_command) and ( sys.argv[4] == optlogfile )) :
  155. if ( is_valid_json_file(sys.argv[3]) ):
  156. filejson_command = sys.argv[3]
  157. check_inputs = 1
  158. filelog = sys.argv[5]
  159. elif (( sys.argv[1] == cmdcheck_input ) and (sys.argv[4] == optjson_command) and ( sys.argv[2] == optlogfile )) :
  160. if ( is_valid_json_file(sys.argv[5]) ):
  161. filejson_command = sys.argv[5]
  162. check_inputs = 1
  163. filelog = sys.argv[3]
  164. elif (( sys.argv[1] == cmdcheck_output ) and (sys.argv[2] == optjson_command) and ( sys.argv[4] == optlogfile )) :
  165. if ( is_valid_json_file(sys.argv[3]) ):
  166. filejson_command = sys.argv[3]
  167. check_outputs = 1
  168. filelog = sys.argv[5]
  169. elif (( sys.argv[1] == cmdcheck_output ) and (sys.argv[4] == optjson_command) and ( sys.argv[2] == optlogfile )) :
  170. if ( is_valid_json_file(sys.argv[5]) ):
  171. filejson_command = sys.argv[5]
  172. check_outputs = 1
  173. filelog = sys.argv[3]
  174. elif (( sys.argv[1] == cmdgenerate_server_script ) and (sys.argv[2] == optjson_command) and (sys.argv[4] == optcopy_outputs_and_archive )) :
  175. if ( is_valid_json_file(sys.argv[3]) ):
  176. filejson_command = sys.argv[3]
  177. fileserver = sys.argv[5]
  178. elif (( sys.argv[1] == cmdgenerate_server_script ) and (sys.argv[4] == optjson_command) and (sys.argv[2] == optcopy_outputs_and_archive )) :
  179. if ( is_valid_json_file(sys.argv[5]) ):
  180. filejson_command = sys.argv[5]
  181. fileserver = sys.argv[3]
  182. else :
  183. print_help()
  184. exit(-1)
  185. ###################
  186. # load json files #
  187. ###################
  188. def strip_paths( command_json, tool_data_json ) :
  189. default_input_file = []
  190. default_output_file = []
  191. command_input_file = []
  192. command_output_file = []
  193. destination_command = command_json
  194. command_index = 0
  195. # change configuration files
  196. for configuration_command in command_json["configurations"] :
  197. for configuration_tool in tool_data_json["configurations"] :
  198. if ( configuration_command["name"] == configuration_tool["name"] ) :
  199. for option_tool in configuration_tool["options"] :
  200. option_index = 0
  201. for option_command in configuration_command["options"] :
  202. if (( option_command["name"] == option_tool["name"] ) and ( option_command["value"] != None )) :
  203. if ( option_tool["type"] == "file_read") :
  204. command_input_file.append( option_command["value"] )
  205. destination_command["configurations"][command_index]["options"][option_index]["value"] = os.path.basename(option_tool["default"])
  206. default_input_file.append( os.path.basename(option_tool["default"]))
  207. if ( option_tool["type"] == "file_write" ) :
  208. command_output_file.append( option_command["value"] )
  209. destination_command["configurations"][command_index]["options"][option_index]["value"] = os.path.basename(option_tool["default"])
  210. default_output_file.append( os.path.basename(option_tool["default"]))
  211. option_index = option_index + 1
  212. command_index = command_index + 1
  213. # change command files
  214. for configuration_tool in tool_data_json["commands"] :
  215. if ( command_json["command"][0]["name"] == configuration_tool["name"] ) :
  216. for option_tool in configuration_tool["options"] :
  217. option_index = 0
  218. for option_command in command_json["command"][0]["options"] :
  219. if (( option_command["name"] == option_tool["name"] ) and ( option_command["value"] != None )) :
  220. if ( option_tool["type"] == "file_read") :
  221. command_input_file.append( option_command["value"] )
  222. destination_command["command"][0]["options"][option_index]["value"] = os.path.basename(option_tool["default"])
  223. default_input_file.append( os.path.basename(option_tool["default"]))
  224. if ( option_tool["type"] == "file_write" ) :
  225. command_output_file.append( option_command["value"] )
  226. destination_command["command"][0]["options"][option_index]["value"] = os.path.basename(option_tool["default"])
  227. default_output_file.append( os.path.basename(option_tool["default"]))
  228. option_index = option_index + 1
  229. return destination_command, default_input_file, default_output_file, command_input_file, command_output_file
  230. if ( filejson_command != "" ) :
  231. if ( is_valid_json_file( filejson_command ) ):
  232. with open(filejson_command, 'r') as file:
  233. command_json_tmp = json.load(file)
  234. else :
  235. exit(-1)
  236. if (( command_json_tmp["tool"] != "xrnlib-cli" ) and ( command_json_tmp["tool"] != "xrnconv-cli" )) :
  237. print("wrong tool")
  238. exit(-1)
  239. if ( is_valid_json_file( tool_file_path ) ):
  240. with open( tool_file_path , 'r') as file:
  241. tools_data = json.load( file )
  242. for tool in tools_data["tool_list"] :
  243. if ( tool["name"] == command_json_tmp["tool"] ) :
  244. tool_data_json = tool
  245. stripped_command_json, default_input_file, default_output_file, command_input_file, command_output_file = strip_paths( command_json_tmp, tool_data_json )
  246. with open(filejson_command, 'r') as file:
  247. command_json = json.load(file)
  248. if ( check_inputs == 1 ) :
  249. get_configuration = "decoding-conf"
  250. default_file_set = default_input_file
  251. command_file_set = command_input_file
  252. if ( check_outputs == 1 ) :
  253. get_configuration = "encoding-conf"
  254. default_file_set = default_output_file
  255. command_file_set = command_output_file
  256. ####################
  257. # check data types #
  258. ####################
  259. gotten_configuration = 0
  260. if (( check_inputs == 1 ) or ( check_outputs == 1 )) :
  261. for configuration in command_json["configurations"]:
  262. if ( configuration["name"] == get_configuration ) :
  263. gotten_configuration = 1
  264. build_cmd = "xrnlib-cli --decoding-conf "
  265. # get decoding-conf
  266. for option in configuration["options"] :
  267. if option["value"] != None :
  268. if option["value"] != "void" :
  269. build_cmd = build_cmd + "-" + option["name"] + " " + option["value"] + " "
  270. else :
  271. build_cmd = build_cmd + "-" + option["name"] + " "
  272. if (( configuration["name"] == "permutation-conf" ) and ( gotten_configuration == 1 )):
  273. for option in configuration["options"] :
  274. if option["name"] == "arch" :
  275. build_cmd = build_cmd + "--permutation-conf -arch " + option["value"] + " --logging-conf -force-write -lib-info-log /dev/stdout --print-header -xrn-file "
  276. if ( gotten_configuration == 0 ):
  277. build_response = '{ "tool": "xrnarchive-cli", "files": [ ] }'
  278. with open(filelog, 'w') as logfile:
  279. logfile.write(build_response)
  280. exit(-1)
  281. file_index = 0
  282. build_response = '{ "tool": "xrnarchive-cli", "files": [ '
  283. for file in default_file_set :
  284. expected_name = file_to_expected_name(file)
  285. if ( expected_name != "" ) :
  286. exec_command = build_cmd + command_input_file[file_index]
  287. json_response_str = os.popen( exec_command ).read()
  288. json_response = json.loads(json_response_str)
  289. build_response = build_response + '{ "name": "'+ file + '", "xrnfile": '
  290. if ( json_response["message_type"] == "data_structure" ) :
  291. if ( json_response["header"]["type"] != expected_name ) :
  292. build_response = build_response + 'false, "error_message" : "' + json_response_str +'" } ] }'
  293. with open(filelog, 'w') as logfile:
  294. logfile.write(build_response)
  295. exit(-1)
  296. else :
  297. build_response = build_response + 'true, "error_message" : "" },'
  298. else :
  299. build_response = build_response + 'false, "error_message" : "' + json_response_str +'" } ] }'
  300. with open(filelog, 'w') as logfile:
  301. logfile.write(build_response)
  302. exit(-1)
  303. file_index = file_index + 1
  304. build_response = build_response[:-1]
  305. if ( check_inputs == 1 ) :
  306. build_response = build_response + ' ] }'
  307. with open(filelog, 'w') as logfile:
  308. logfile.write(build_response)
  309. elif ( check_outputs == 1 ) :
  310. build_response = build_response + ' ] }'
  311. with open(filelog, 'w') as logfile:
  312. logfile.write(build_response)
  313. exit(0)
  314. ######################
  315. # create copy script #
  316. ######################
  317. if ( fileinput_copy_archive != "" ):
  318. with open(fileinput_copy_archive, 'w') as file:
  319. i = 0
  320. file.write("#!/bin/bash\n\n")
  321. file.write("if [ -z \"$1\" ]; then\n")
  322. file.write(" echo \"arguments not provided\"\n")
  323. file.write(" echo \"./"+fileinput_copy_archive+" archive.tar /path/to/cache\"\n")
  324. file.write(" exit -1\n")
  325. file.write("fi\n")
  326. file.write("if [ ! -d \"$2\" ]; then\n")
  327. file.write(" echo \"$2 is not a directory\"\n")
  328. file.write(" echo \"./"+fileinput_copy_archive+" archive.tar /path/to/cache\"\n")
  329. file.write(" exit -1\n")
  330. file.write("fi\n\n")
  331. for file_name in default_input_file :
  332. if os.path.isfile(command_input_file[i]):
  333. file.write("cp " + command_input_file[i] + " $2/" + file_name +"\n")
  334. i = i + 1
  335. else :
  336. file.write("echo " + command_input_file[i] + " file does not exist;\n exit -1;\n")
  337. file.write("\necho \"" + str(stripped_command_json).replace("'","\\\"").replace("None","null") + " \" > $2/command.json\n\n")
  338. file.write("archive_name=$(basename \"$1\")\n")
  339. file.write("\ncd $2; tar -cvf $archive_name ./*;\nif [ $archive_name != $1 ]; then\n mv $archive_name $1\nfi" )
  340. if ( filecopy_output_script != "" ):
  341. with open(filecopy_output_script, 'w') as file:
  342. i = 0
  343. file.write("#!/bin/bash\n\n")
  344. file.write("if [ -z \"$1\" ]; then\n")
  345. file.write(" echo \"arguments not provided\"\n")
  346. file.write(" echo \"./"+filecopy_output_script+" archive.tar /path/to/cache\"\n")
  347. file.write(" exit -1\n")
  348. file.write("fi\n")
  349. file.write("if [ ! -d \"$2\" ]; then\n")
  350. file.write(" echo \"$2 is not a directory\"\n")
  351. file.write(" echo \"./"+filecopy_output_script+" archive.tar /path/to/cache\"\n")
  352. file.write(" exit -1\n")
  353. file.write("fi\n\n")
  354. file.write("tar -xf $1 -C $2\n\n")
  355. for file_name in command_output_file :
  356. file.write("if [ -f $2/" + default_output_file[i] + " ]; then\n")
  357. file.write(" cp $2/" + default_output_file[i] + " " + file_name +"\n")
  358. file.write("else\n")
  359. file.write(" echo \"$2/" + default_output_file[i] + " file does not exist\"\n exit -1\n")
  360. file.write("fi\n\n")
  361. i = i + 1
  362. file.write("\n" )
  363. if ( fileserver != "" ):
  364. with open(fileserver, 'w') as file:
  365. file.write("#!/bin/bash\n\n")
  366. file.write("if [ -z \"$1\" ]; then\n")
  367. file.write(" echo \"arguments not provided\"\n")
  368. file.write(" echo \"./"+fileserver+" archive.tar /path/to/cache\"\n")
  369. file.write(" exit -1\n")
  370. file.write("fi\n")
  371. file.write("if [ ! -d \"$2\" ]; then\n")
  372. file.write(" echo \"$2 is not a directory\"\n")
  373. file.write(" echo \"./"+fileserver+" archive.tar /path/to/cache\"\n")
  374. file.write(" exit -1\n")
  375. file.write("fi\n\n")
  376. for file_name in default_output_file :
  377. file.write("if [ ! -f $2/" + file_name + " ]; then\n")
  378. file.write(" echo \"$2/" + file_name + " file does not exist\"\n exit -1\n")
  379. file.write("fi\n\n")
  380. file.write("tar -cf $1")
  381. for file_name in default_output_file :
  382. file.write(" $2/" + file_name )
  383. file.write("\n" )