atomicshop 2.11.47__py3-none-any.whl → 3.10.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
  3. atomicshop/a_mains/addons/process_list/compile.cmd +7 -0
  4. atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.dll +0 -0
  5. atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.exp +0 -0
  6. atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.lib +0 -0
  7. atomicshop/{addons → a_mains/addons}/process_list/process_list.cpp +8 -1
  8. atomicshop/a_mains/dns_gateway_setting.py +11 -0
  9. atomicshop/a_mains/get_local_tcp_ports.py +85 -0
  10. atomicshop/a_mains/github_wrapper.py +11 -0
  11. atomicshop/a_mains/install_ca_certificate.py +172 -0
  12. atomicshop/{addons/mains → a_mains}/msi_unpacker.py +3 -1
  13. atomicshop/a_mains/process_from_port.py +119 -0
  14. atomicshop/a_mains/set_default_dns_gateway.py +90 -0
  15. atomicshop/a_mains/update_config_toml.py +38 -0
  16. atomicshop/appointment_management.py +5 -3
  17. atomicshop/basics/ansi_escape_codes.py +3 -1
  18. atomicshop/basics/argparse_template.py +2 -0
  19. atomicshop/basics/booleans.py +27 -30
  20. atomicshop/basics/bytes_arrays.py +43 -0
  21. atomicshop/basics/classes.py +149 -1
  22. atomicshop/basics/dicts.py +12 -0
  23. atomicshop/basics/enums.py +2 -2
  24. atomicshop/basics/exceptions.py +5 -1
  25. atomicshop/basics/list_of_classes.py +29 -0
  26. atomicshop/basics/list_of_dicts.py +69 -5
  27. atomicshop/basics/lists.py +14 -0
  28. atomicshop/basics/multiprocesses.py +374 -50
  29. atomicshop/basics/package_module.py +10 -0
  30. atomicshop/basics/strings.py +160 -7
  31. atomicshop/basics/threads.py +14 -0
  32. atomicshop/basics/tracebacks.py +13 -4
  33. atomicshop/certificates.py +153 -52
  34. atomicshop/config_init.py +12 -7
  35. atomicshop/console_user_response.py +7 -14
  36. atomicshop/consoles.py +9 -0
  37. atomicshop/datetimes.py +98 -0
  38. atomicshop/diff_check.py +340 -40
  39. atomicshop/dns.py +128 -12
  40. atomicshop/etws/_pywintrace_fix.py +17 -0
  41. atomicshop/etws/const.py +38 -0
  42. atomicshop/etws/providers.py +21 -0
  43. atomicshop/etws/sessions.py +43 -0
  44. atomicshop/etws/trace.py +168 -0
  45. atomicshop/etws/traces/trace_dns.py +162 -0
  46. atomicshop/etws/traces/trace_sysmon_process_creation.py +126 -0
  47. atomicshop/etws/traces/trace_tcp.py +130 -0
  48. atomicshop/file_io/csvs.py +222 -24
  49. atomicshop/file_io/docxs.py +35 -18
  50. atomicshop/file_io/file_io.py +35 -19
  51. atomicshop/file_io/jsons.py +49 -0
  52. atomicshop/file_io/tomls.py +139 -0
  53. atomicshop/filesystem.py +864 -293
  54. atomicshop/get_process_list.py +133 -0
  55. atomicshop/{process_name_cmd.py → get_process_name_cmd_dll.py} +52 -19
  56. atomicshop/http_parse.py +149 -93
  57. atomicshop/ip_addresses.py +6 -1
  58. atomicshop/mitm/centered_settings.py +132 -0
  59. atomicshop/mitm/config_static.py +207 -0
  60. atomicshop/mitm/config_toml_editor.py +55 -0
  61. atomicshop/mitm/connection_thread_worker.py +875 -357
  62. atomicshop/mitm/engines/__parent/parser___parent.py +4 -17
  63. atomicshop/mitm/engines/__parent/recorder___parent.py +108 -51
  64. atomicshop/mitm/engines/__parent/requester___parent.py +116 -0
  65. atomicshop/mitm/engines/__parent/responder___parent.py +75 -114
  66. atomicshop/mitm/engines/__reference_general/parser___reference_general.py +10 -7
  67. atomicshop/mitm/engines/__reference_general/recorder___reference_general.py +5 -5
  68. atomicshop/mitm/engines/__reference_general/requester___reference_general.py +47 -0
  69. atomicshop/mitm/engines/__reference_general/responder___reference_general.py +95 -13
  70. atomicshop/mitm/engines/create_module_template.py +58 -14
  71. atomicshop/mitm/import_config.py +359 -139
  72. atomicshop/mitm/initialize_engines.py +160 -74
  73. atomicshop/mitm/message.py +64 -23
  74. atomicshop/mitm/mitm_main.py +892 -0
  75. atomicshop/mitm/recs_files.py +183 -0
  76. atomicshop/mitm/shared_functions.py +4 -10
  77. atomicshop/mitm/ssh_tester.py +82 -0
  78. atomicshop/mitm/statistic_analyzer.py +257 -166
  79. atomicshop/mitm/statistic_analyzer_helper/analyzer_helper.py +136 -0
  80. atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +525 -0
  81. atomicshop/monitor/change_monitor.py +96 -120
  82. atomicshop/monitor/checks/dns.py +139 -70
  83. atomicshop/monitor/checks/file.py +77 -0
  84. atomicshop/monitor/checks/network.py +81 -77
  85. atomicshop/monitor/checks/process_running.py +33 -34
  86. atomicshop/monitor/checks/url.py +94 -0
  87. atomicshop/networks.py +671 -0
  88. atomicshop/on_exit.py +205 -0
  89. atomicshop/package_mains_processor.py +84 -0
  90. atomicshop/permissions/permissions.py +22 -0
  91. atomicshop/permissions/ubuntu_permissions.py +239 -0
  92. atomicshop/permissions/win_permissions.py +33 -0
  93. atomicshop/print_api.py +24 -41
  94. atomicshop/process.py +63 -17
  95. atomicshop/process_poller/__init__.py +0 -0
  96. atomicshop/process_poller/pollers/__init__.py +0 -0
  97. atomicshop/process_poller/pollers/psutil_pywin32wmi_dll.py +95 -0
  98. atomicshop/process_poller/process_pool.py +207 -0
  99. atomicshop/process_poller/simple_process_pool.py +311 -0
  100. atomicshop/process_poller/tracer_base.py +45 -0
  101. atomicshop/process_poller/tracers/__init__.py +0 -0
  102. atomicshop/process_poller/tracers/event_log.py +46 -0
  103. atomicshop/process_poller/tracers/sysmon_etw.py +68 -0
  104. atomicshop/python_file_patcher.py +1 -1
  105. atomicshop/python_functions.py +27 -75
  106. atomicshop/question_answer_engine.py +2 -2
  107. atomicshop/scheduling.py +24 -5
  108. atomicshop/sound.py +4 -2
  109. atomicshop/speech_recognize.py +8 -0
  110. atomicshop/ssh_remote.py +158 -172
  111. atomicshop/startup/__init__.py +0 -0
  112. atomicshop/startup/win/__init__.py +0 -0
  113. atomicshop/startup/win/startup_folder.py +53 -0
  114. atomicshop/startup/win/task_scheduler.py +119 -0
  115. atomicshop/system_resource_monitor.py +61 -46
  116. atomicshop/system_resources.py +8 -8
  117. atomicshop/tempfiles.py +1 -2
  118. atomicshop/timer.py +30 -11
  119. atomicshop/urls.py +41 -0
  120. atomicshop/venvs.py +28 -0
  121. atomicshop/versioning.py +27 -0
  122. atomicshop/web.py +110 -25
  123. atomicshop/web_apis/__init__.py +0 -0
  124. atomicshop/web_apis/google_custom_search.py +44 -0
  125. atomicshop/web_apis/google_llm.py +188 -0
  126. atomicshop/websocket_parse.py +450 -0
  127. atomicshop/wrappers/certauthw/certauth.py +1 -0
  128. atomicshop/wrappers/cryptographyw.py +29 -8
  129. atomicshop/wrappers/ctyping/etw_winapi/__init__.py +0 -0
  130. atomicshop/wrappers/ctyping/etw_winapi/const.py +335 -0
  131. atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py +393 -0
  132. atomicshop/wrappers/ctyping/file_details_winapi.py +67 -0
  133. atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py +2 -1
  134. atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py +13 -9
  135. atomicshop/wrappers/ctyping/msi_windows_installer/tables.py +35 -0
  136. atomicshop/wrappers/ctyping/setup_device.py +466 -0
  137. atomicshop/wrappers/ctyping/win_console.py +39 -0
  138. atomicshop/wrappers/dockerw/dockerw.py +113 -2
  139. atomicshop/wrappers/elasticsearchw/config_basic.py +0 -12
  140. atomicshop/wrappers/elasticsearchw/elastic_infra.py +75 -0
  141. atomicshop/wrappers/elasticsearchw/elasticsearchw.py +2 -20
  142. atomicshop/wrappers/factw/get_file_data.py +12 -5
  143. atomicshop/wrappers/factw/install/install_after_restart.py +89 -5
  144. atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +20 -14
  145. atomicshop/wrappers/factw/postgresql/firmware.py +4 -6
  146. atomicshop/wrappers/githubw.py +583 -51
  147. atomicshop/wrappers/loggingw/consts.py +49 -0
  148. atomicshop/wrappers/loggingw/filters.py +102 -0
  149. atomicshop/wrappers/loggingw/formatters.py +58 -71
  150. atomicshop/wrappers/loggingw/handlers.py +459 -40
  151. atomicshop/wrappers/loggingw/loggers.py +19 -0
  152. atomicshop/wrappers/loggingw/loggingw.py +1010 -178
  153. atomicshop/wrappers/loggingw/reading.py +344 -19
  154. atomicshop/wrappers/mongodbw/__init__.py +0 -0
  155. atomicshop/wrappers/mongodbw/mongo_infra.py +31 -0
  156. atomicshop/wrappers/mongodbw/mongodbw.py +1432 -0
  157. atomicshop/wrappers/netshw.py +271 -0
  158. atomicshop/wrappers/playwrightw/engine.py +34 -19
  159. atomicshop/wrappers/playwrightw/infra.py +5 -0
  160. atomicshop/wrappers/playwrightw/javascript.py +7 -3
  161. atomicshop/wrappers/playwrightw/keyboard.py +14 -0
  162. atomicshop/wrappers/playwrightw/scenarios.py +172 -5
  163. atomicshop/wrappers/playwrightw/waits.py +9 -7
  164. atomicshop/wrappers/powershell_networking.py +80 -0
  165. atomicshop/wrappers/psutilw/processes.py +81 -0
  166. atomicshop/wrappers/psutilw/psutil_networks.py +85 -0
  167. atomicshop/wrappers/psutilw/psutilw.py +9 -0
  168. atomicshop/wrappers/pyopensslw.py +9 -2
  169. atomicshop/wrappers/pywin32w/__init__.py +0 -0
  170. atomicshop/wrappers/pywin32w/cert_store.py +116 -0
  171. atomicshop/wrappers/pywin32w/console.py +34 -0
  172. atomicshop/wrappers/pywin32w/win_event_log/__init__.py +0 -0
  173. atomicshop/wrappers/pywin32w/win_event_log/fetch.py +174 -0
  174. atomicshop/wrappers/pywin32w/win_event_log/subscribe.py +212 -0
  175. atomicshop/wrappers/pywin32w/win_event_log/subscribes/__init__.py +0 -0
  176. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py +57 -0
  177. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +49 -0
  178. atomicshop/wrappers/pywin32w/win_event_log/subscribes/schannel_logging.py +97 -0
  179. atomicshop/wrappers/pywin32w/winshell.py +19 -0
  180. atomicshop/wrappers/pywin32w/wmis/__init__.py +0 -0
  181. atomicshop/wrappers/pywin32w/wmis/msft_netipaddress.py +113 -0
  182. atomicshop/wrappers/pywin32w/wmis/win32_networkadapterconfiguration.py +259 -0
  183. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +112 -0
  184. atomicshop/wrappers/pywin32w/wmis/wmi_helpers.py +236 -0
  185. atomicshop/wrappers/socketw/accepter.py +21 -7
  186. atomicshop/wrappers/socketw/certificator.py +216 -150
  187. atomicshop/wrappers/socketw/creator.py +190 -50
  188. atomicshop/wrappers/socketw/dns_server.py +500 -173
  189. atomicshop/wrappers/socketw/exception_wrapper.py +45 -52
  190. atomicshop/wrappers/socketw/process_getter.py +86 -0
  191. atomicshop/wrappers/socketw/receiver.py +144 -102
  192. atomicshop/wrappers/socketw/sender.py +65 -35
  193. atomicshop/wrappers/socketw/sni.py +334 -165
  194. atomicshop/wrappers/socketw/socket_base.py +134 -0
  195. atomicshop/wrappers/socketw/socket_client.py +137 -95
  196. atomicshop/wrappers/socketw/socket_server_tester.py +14 -9
  197. atomicshop/wrappers/socketw/socket_wrapper.py +717 -116
  198. atomicshop/wrappers/socketw/ssl_base.py +15 -14
  199. atomicshop/wrappers/socketw/statistics_csv.py +148 -17
  200. atomicshop/wrappers/sysmonw.py +157 -0
  201. atomicshop/wrappers/ubuntu_terminal.py +65 -26
  202. atomicshop/wrappers/win_auditw.py +189 -0
  203. atomicshop/wrappers/winregw/__init__.py +0 -0
  204. atomicshop/wrappers/winregw/winreg_installed_software.py +58 -0
  205. atomicshop/wrappers/winregw/winreg_network.py +232 -0
  206. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/METADATA +31 -49
  207. atomicshop-3.10.5.dist-info/RECORD +306 -0
  208. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/WHEEL +1 -1
  209. atomicshop/_basics_temp.py +0 -101
  210. atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh +0 -3
  211. atomicshop/addons/a_setup_scripts/install_pywintrace_0.3.cmd +0 -2
  212. atomicshop/addons/mains/install_docker_rootless_ubuntu.py +0 -11
  213. atomicshop/addons/mains/install_docker_ubuntu_main_sudo.py +0 -11
  214. atomicshop/addons/mains/install_elastic_search_and_kibana_ubuntu.py +0 -10
  215. atomicshop/addons/mains/install_wsl_ubuntu_lts_admin.py +0 -9
  216. atomicshop/addons/package_setup/CreateWheel.cmd +0 -7
  217. atomicshop/addons/package_setup/Setup in Edit mode.cmd +0 -6
  218. atomicshop/addons/package_setup/Setup.cmd +0 -7
  219. atomicshop/addons/process_list/compile.cmd +0 -2
  220. atomicshop/addons/process_list/compiled/Win10x64/process_list.dll +0 -0
  221. atomicshop/addons/process_list/compiled/Win10x64/process_list.exp +0 -0
  222. atomicshop/addons/process_list/compiled/Win10x64/process_list.lib +0 -0
  223. atomicshop/archiver/_search_in_zip.py +0 -189
  224. atomicshop/archiver/archiver.py +0 -34
  225. atomicshop/archiver/search_in_archive.py +0 -250
  226. atomicshop/archiver/sevenz_app_w.py +0 -86
  227. atomicshop/archiver/sevenzs.py +0 -44
  228. atomicshop/archiver/zips.py +0 -293
  229. atomicshop/etw/dns_trace.py +0 -118
  230. atomicshop/etw/etw.py +0 -61
  231. atomicshop/file_types.py +0 -24
  232. atomicshop/mitm/engines/create_module_template_example.py +0 -13
  233. atomicshop/mitm/initialize_mitm_server.py +0 -240
  234. atomicshop/monitor/checks/hash.py +0 -44
  235. atomicshop/monitor/checks/hash_checks/file.py +0 -55
  236. atomicshop/monitor/checks/hash_checks/url.py +0 -62
  237. atomicshop/pbtkmultifile_argparse.py +0 -88
  238. atomicshop/permissions.py +0 -110
  239. atomicshop/process_poller.py +0 -237
  240. atomicshop/script_as_string_processor.py +0 -38
  241. atomicshop/ssh_scripts/process_from_ipv4.py +0 -37
  242. atomicshop/ssh_scripts/process_from_port.py +0 -27
  243. atomicshop/wrappers/_process_wrapper_curl.py +0 -27
  244. atomicshop/wrappers/_process_wrapper_tar.py +0 -21
  245. atomicshop/wrappers/dockerw/install_docker.py +0 -209
  246. atomicshop/wrappers/elasticsearchw/infrastructure.py +0 -265
  247. atomicshop/wrappers/elasticsearchw/install_elastic.py +0 -232
  248. atomicshop/wrappers/ffmpegw.py +0 -125
  249. atomicshop/wrappers/loggingw/checks.py +0 -20
  250. atomicshop/wrappers/nodejsw/install_nodejs.py +0 -139
  251. atomicshop/wrappers/process_wrapper_pbtk.py +0 -16
  252. atomicshop/wrappers/socketw/base.py +0 -59
  253. atomicshop/wrappers/socketw/get_process.py +0 -107
  254. atomicshop/wrappers/wslw.py +0 -191
  255. atomicshop-2.11.47.dist-info/RECORD +0 -251
  256. /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
  257. /atomicshop/{addons → a_mains/addons}/PlayWrightCodegen.cmd +0 -0
  258. /atomicshop/{addons → a_mains/addons}/ScriptExecution.cmd +0 -0
  259. /atomicshop/{addons/mains → a_mains/addons}/inits/init_to_import_all_modules.py +0 -0
  260. /atomicshop/{addons → a_mains/addons}/process_list/ReadMe.txt +0 -0
  261. /atomicshop/{addons/mains → a_mains}/search_for_hyperlinks_in_docx.py +0 -0
  262. /atomicshop/{archiver → etws}/__init__.py +0 -0
  263. /atomicshop/{etw → etws/traces}/__init__.py +0 -0
  264. /atomicshop/{monitor/checks/hash_checks → mitm/statistic_analyzer_helper}/__init__.py +0 -0
  265. /atomicshop/{wrappers/nodejsw → permissions}/__init__.py +0 -0
  266. /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
  267. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info/licenses}/LICENSE.txt +0 -0
  268. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,466 @@
1
+ import ctypes
2
+ from ctypes import wintypes
3
+ import uuid
4
+
5
+
6
+ # Constants and functions for creating root-enumerated device nodes
7
+ # ---------------------------------------------------------------------------
8
+ # Compatibility shim: wintypes.ULONG_PTR is missing on some builds
9
+ # ---------------------------------------------------------------------------
10
+ if not hasattr(wintypes, "ULONG_PTR"):
11
+ if ctypes.sizeof(ctypes.c_void_p) == 8: # 64-bit Python
12
+ wintypes.ULONG_PTR = ctypes.c_uint64
13
+ else: # 32-bit Python
14
+ wintypes.ULONG_PTR = ctypes.c_uint32
15
+
16
+ # ------------------------------------------------------------------
17
+ # SetupDi* “device‑registry property” indices (SPDRP_…)
18
+ # From Microsoft’s setupapi.h – keep them as ints.
19
+ # ------------------------------------------------------------------
20
+ SPDRP_DEVICEDESC = 0 # REG_SZ – Device description (friendly name)
21
+ SPDRP_HARDWAREID = 1 # REG_MULTI_SZ – Hardware‑ID list
22
+ SPDRP_COMPATIBLEIDS = 2 # REG_MULTI_SZ – Compatible‑ID list
23
+ SPDRP_SERVICE = 4 # REG_SZ – Service/miniport to load
24
+ SPDRP_CLASS = 7 # REG_SZ – Class name (e.g. "Net")
25
+ SPDRP_CLASSGUID = 8 # REG_SZ – Class GUID in string form
26
+
27
+ # newdev.h (Windows SDK) / SetupAPI
28
+ DIF_REGISTERDEVICE = 0x00000019
29
+ DIF_REMOVE = 0x00000005
30
+ DICD_GENERATE_ID = 0x00000001
31
+ INSTALLFLAG_FORCE = 0x00000001 # install even if “better” driver exists
32
+ INSTALLFLAG_READONLY = 0x00000002 # don’t write driver to driver store
33
+ INSTALLFLAG_NONINTERACTIVE = 0x00000004 # never display UI (silent mode)
34
+
35
+ DIGCF_PRESENT = 0x00000002
36
+ ERROR_NO_MORE_ITEMS = 259
37
+
38
+ setupapi = ctypes.WinDLL("setupapi", use_last_error=True)
39
+ newdev = ctypes.WinDLL("newdev", use_last_error=True)
40
+
41
+ # ---------------------------------------------------------------------------
42
+ # Structures & prototypes
43
+ # ---------------------------------------------------------------------------
44
+ class SP_DEVINFO_DATA(ctypes.Structure):
45
+ _fields_ = [
46
+ ("cbSize", wintypes.DWORD),
47
+ ("ClassGuid", ctypes.c_byte * 16),
48
+ ("DevInst", wintypes.DWORD),
49
+ ("Reserved", wintypes.ULONG_PTR),
50
+ ]
51
+
52
+ # --- creation helpers ------------------------------------------------------
53
+ SetupDiCreateDeviceInfoList = setupapi.SetupDiCreateDeviceInfoList
54
+ SetupDiCreateDeviceInfoList.argtypes = [ctypes.POINTER(ctypes.c_byte * 16), wintypes.HWND]
55
+ SetupDiCreateDeviceInfoList.restype = wintypes.HANDLE
56
+
57
+ SetupDiCreateDeviceInfoW = setupapi.SetupDiCreateDeviceInfoW
58
+ SetupDiCreateDeviceInfoW.argtypes = [
59
+ wintypes.HANDLE, wintypes.LPCWSTR,
60
+ ctypes.POINTER(ctypes.c_byte * 16),
61
+ wintypes.LPCWSTR, wintypes.HWND, wintypes.DWORD,
62
+ ctypes.POINTER(SP_DEVINFO_DATA)
63
+ ]
64
+ SetupDiCreateDeviceInfoW.restype = wintypes.BOOL
65
+
66
+ SetupDiSetDeviceRegistryPropertyW = setupapi.SetupDiSetDeviceRegistryPropertyW
67
+ SetupDiSetDeviceRegistryPropertyW.argtypes = [
68
+ wintypes.HANDLE, ctypes.POINTER(SP_DEVINFO_DATA), wintypes.DWORD,
69
+ wintypes.LPBYTE, wintypes.DWORD
70
+ ]
71
+ SetupDiSetDeviceRegistryPropertyW.restype = wintypes.BOOL
72
+
73
+ SetupDiCallClassInstaller = setupapi.SetupDiCallClassInstaller
74
+ SetupDiCallClassInstaller.argtypes = [
75
+ wintypes.DWORD, wintypes.HANDLE, ctypes.POINTER(SP_DEVINFO_DATA)
76
+ ]
77
+ SetupDiCallClassInstaller.restype = wintypes.BOOL
78
+
79
+ # --- enumeration / removal -------------------------------------------------
80
+ SetupDiGetClassDevsW = setupapi.SetupDiGetClassDevsW
81
+ SetupDiGetClassDevsW.argtypes = [ctypes.POINTER(ctypes.c_byte * 16),
82
+ wintypes.LPCWSTR, wintypes.HWND, wintypes.DWORD]
83
+ SetupDiGetClassDevsW.restype = wintypes.HANDLE
84
+
85
+ SetupDiEnumDeviceInfo = setupapi.SetupDiEnumDeviceInfo
86
+ SetupDiEnumDeviceInfo.argtypes = [wintypes.HANDLE, wintypes.DWORD,
87
+ ctypes.POINTER(SP_DEVINFO_DATA)]
88
+ SetupDiEnumDeviceInfo.restype = wintypes.BOOL
89
+
90
+ SetupDiGetDeviceRegistryPropertyW = setupapi.SetupDiGetDeviceRegistryPropertyW
91
+ SetupDiGetDeviceRegistryPropertyW.argtypes = [
92
+ wintypes.HANDLE, ctypes.POINTER(SP_DEVINFO_DATA), wintypes.DWORD,
93
+ ctypes.POINTER(wintypes.DWORD), wintypes.PBYTE, wintypes.DWORD,
94
+ ctypes.POINTER(wintypes.DWORD)
95
+ ]
96
+ SetupDiGetDeviceRegistryPropertyW.restype = wintypes.BOOL
97
+
98
+ SetupDiDestroyDeviceInfoList = setupapi.SetupDiDestroyDeviceInfoList
99
+ SetupDiDestroyDeviceInfoList.argtypes = [wintypes.HANDLE]
100
+ SetupDiDestroyDeviceInfoList.restype = wintypes.BOOL
101
+
102
+ UpdateDriverForPlugAndPlayDevicesW = newdev.UpdateDriverForPlugAndPlayDevicesW
103
+ UpdateDriverForPlugAndPlayDevicesW.argtypes = [
104
+ wintypes.HWND, wintypes.LPCWSTR, wintypes.LPCWSTR,
105
+ wintypes.DWORD, ctypes.POINTER(wintypes.BOOL)
106
+ ]
107
+ UpdateDriverForPlugAndPlayDevicesW.restype = wintypes.BOOL
108
+
109
+
110
+ # ---------------------------------------------------------------------------
111
+ # 1. Create a root-enumerated devnode (idempotent)
112
+ # ---------------------------------------------------------------------------
113
+ def create_root_enumerated_devnode(
114
+ class_guid: str,
115
+ friendly_name: str, # what shows in Device Manager
116
+ hardware_ids: "list[str] | str",
117
+ compatible_ids: "list[str] | str | None" = None,
118
+ devdesc_override: str | None = None,
119
+ create_flags: int = DICD_GENERATE_ID,
120
+ existing_ok: bool = True,
121
+ ) -> None:
122
+ """
123
+ Programmatically create a *root‑enumerated* device node, set its
124
+ Hardware‑ID (and optional Compatible‑ID) list, then ask Plug and Play
125
+ to register/ install whatever driver matches those IDs.
126
+
127
+ Parameters
128
+ ----------
129
+ class_guid : string representation of a GUID.
130
+ Device‑class GUID (e.g. GUID_DEVCLASS_NET, GUID_DEVCLASS_MEDIA …).
131
+ Example:
132
+ class_guid="{4d36e972-e325-11ce-bfc1-08002be10318}"
133
+ This is the GUID for network adapters.
134
+
135
+ friendly_name : str
136
+ Initial instance name placed in the registry (DeviceDesc).
137
+ Also, will be shown in Device Manager.
138
+
139
+ hardware_ids : str | list[str]
140
+ One or more hardware IDs (MULTI_SZ). The *first* one is the key
141
+ identifier PnP uses when selecting an INF.
142
+
143
+ compatible_ids : str | list[str] | None
144
+ Optional Compatible‑ID list (another MULTI_SZ, lower priority).
145
+
146
+ devdesc_override : str | None
147
+ If supplied, written to SPDRP_DEVICEDESC (rarely necessary because
148
+ the INF’s own DeviceDesc usually replaces it).
149
+
150
+ create_flags : int
151
+ Flags for SetupDiCreateDeviceInfoW. Default is DICD_GENERATE_ID.
152
+
153
+ existing_ok : bool
154
+ If True, silently succeed when the devnode already exists.
155
+ """
156
+
157
+ class_guid_bytes = uuid.UUID(class_guid).bytes_le
158
+ class_guid_object = (ctypes.c_byte * 16).from_buffer_copy(class_guid_bytes)
159
+
160
+ # --- 1. Create a temporary empty device‑info set -------------------
161
+ hdi = SetupDiCreateDeviceInfoList(class_guid_object, None) # Open a new, empty set
162
+ if hdi == wintypes.HANDLE(-1).value: # INVALID_HANDLE_VALUE?
163
+ raise ctypes.WinError(ctypes.get_last_error()) # Bail out on failure
164
+
165
+ # Prepare the SP_DEVINFO_DATA structure -----------------------------
166
+ devinfo = SP_DEVINFO_DATA() # Zero‑initialised struct
167
+ devinfo.cbSize = ctypes.sizeof(devinfo) # Must set cbSize field
168
+
169
+ # --- 2. Create (or open) the devnode itself ------------------------
170
+ if not SetupDiCreateDeviceInfoW(
171
+ hdi, # Info‑set handle
172
+ friendly_name, # Instance name
173
+ class_guid_object, # Class GUID
174
+ None, None, # (Description, parent window)
175
+ create_flags, # e.g. DICD_GENERATE_ID
176
+ ctypes.byref(devinfo) # Receives devinfo data
177
+ ):
178
+ err = ctypes.get_last_error() # Capture error now
179
+ SetupDiDestroyDeviceInfoList(hdi) # Clean up handle
180
+ if not (existing_ok and err == 0xE0000217): # ERROR_DEVINST_ALREADY_EXISTS
181
+ raise ctypes.WinError(err) # Re‑raise unless allowed
182
+
183
+ # --- 3. Build MULTI_SZ buffers and write registry properties -------
184
+ def _multisz(lst_or_str): # Helper → MULTI_SZ buffer
185
+ buf = lst_or_str if isinstance(lst_or_str, str) else "\0".join(lst_or_str)
186
+ return ctypes.create_unicode_buffer(buf + "\0") # Extra trailing NUL
187
+
188
+ # Hardware‑ID list (required) ---------------------------
189
+ hwid = _multisz(hardware_ids) # Build MULTI_SZ buffer
190
+ if not SetupDiSetDeviceRegistryPropertyW(
191
+ hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, # Property to set
192
+ ctypes.cast(hwid, wintypes.LPBYTE), # Cast to LPBYTE
193
+ (len(hwid) + 1) * ctypes.sizeof(ctypes.c_wchar) # Size in bytes
194
+ ):
195
+ SetupDiDestroyDeviceInfoList(hdi)
196
+ raise ctypes.WinError(ctypes.get_last_error())
197
+
198
+ # Compatible‑ID list (optional) -------------------------
199
+ if compatible_ids:
200
+ cid = _multisz(compatible_ids) # Build MULTI_SZ buffer
201
+ if not SetupDiSetDeviceRegistryPropertyW(
202
+ hdi, ctypes.byref(devinfo), SPDRP_COMPATIBLEIDS,
203
+ ctypes.cast(cid, wintypes.LPBYTE),
204
+ (len(cid) + 1) * ctypes.sizeof(ctypes.c_wchar)
205
+ ):
206
+ SetupDiDestroyDeviceInfoList(hdi)
207
+ raise ctypes.WinError(ctypes.get_last_error())
208
+
209
+ # DeviceDesc override (optional) -----------------------
210
+ if devdesc_override:
211
+ desc = ctypes.create_unicode_buffer(devdesc_override + "\0")
212
+ if not SetupDiSetDeviceRegistryPropertyW(
213
+ hdi, ctypes.byref(devinfo), SPDRP_DEVICEDESC,
214
+ ctypes.cast(desc, wintypes.LPBYTE),
215
+ (len(desc) + 1) * ctypes.sizeof(ctypes.c_wchar)
216
+ ):
217
+ SetupDiDestroyDeviceInfoList(hdi)
218
+ raise ctypes.WinError(ctypes.get_last_error())
219
+
220
+ # --- 4. Hand the devnode to the class installer --------------------
221
+ if not SetupDiCallClassInstaller(
222
+ DIF_REGISTERDEVICE, # “Install this device”
223
+ hdi, ctypes.byref(devinfo)
224
+ ):
225
+ err = ctypes.get_last_error()
226
+ # ERROR_DI_DO_DEFAULT means “already registered / nothing to do”
227
+ if not (existing_ok and err == 0xE000020E):
228
+ SetupDiDestroyDeviceInfoList(hdi)
229
+ raise ctypes.WinError(err)
230
+
231
+ # --- 5. Final cleanup ----------------------------------------------
232
+ SetupDiDestroyDeviceInfoList(hdi) # Always release handle
233
+
234
+
235
+ # ---------------------------------------------------------------------------
236
+ # 2. Bind driver from netloop.inf (idempotent)
237
+ # ---------------------------------------------------------------------------
238
+ def update_driver_for_hwids(
239
+ hardware_ids: "str | list[str]",
240
+ inf_path: str,
241
+ force_install: bool = False,
242
+ quiet: bool = True,
243
+ existing_ok: bool = True,
244
+ ) -> bool:
245
+ """
246
+ Install / update the driver in *inf_path* for every present device whose first
247
+ Hardware‑ID matches *hardware_ids*.
248
+
249
+ Parameters
250
+ ----------
251
+ hardware_ids : str | list[str]
252
+ Single Hardware‑ID string or a list of IDs. Each is passed separately to
253
+ UpdateDriverForPlugAndPlayDevicesW.
254
+
255
+ inf_path : str
256
+ Full path to the target driver’s .INF file (must already be accessible or
257
+ pre‑staged).
258
+
259
+ force_install : bool, default False
260
+ If True the function sets INSTALLFLAG_FORCE so the specified INF will be
261
+ applied even when Windows thinks a “better” driver is already installed.
262
+
263
+ quiet : bool, default True
264
+ If True the installation runs without UI (parent window = NULL). Set
265
+ False if you want progress dialogs.
266
+
267
+ existing_ok : bool, default True
268
+ When *False*, a return code of ERROR_NO_MORE_ITEMS (no devices found) or
269
+ ERROR_DI_DO_DEFAULT (“already using this driver”) is treated as an error.
270
+
271
+ Returns
272
+ -------
273
+ bool
274
+ True → Windows signalled that a reboot is required.
275
+ False → No reboot required.
276
+
277
+ =====================================================================
278
+
279
+ Examples
280
+ --------
281
+ 1. Force‑install the Microsoft KM‑Test Loopback driver that ships with
282
+ Windows (the same scenario as the original hard‑coded function)::
283
+
284
+ reboot_needed = update_driver_for_hwids(
285
+ hardware_ids="*ROOT\\NET\\0000",
286
+ inf_path=r"C:\\Windows\\INF\\netloop.inf",
287
+ force_install=True
288
+ )
289
+
290
+ 2. Install an Intel i219‑V NIC driver only if Windows agrees it is the best
291
+ match (no force flag) for either of two possible PCI IDs::
292
+
293
+ reboot_needed = update_driver_for_hwids(
294
+ hardware_ids=[
295
+ "PCI\\VEN_8086&DEV_15B8",
296
+ "PCI\\VEN_8086&DEV_15BB"
297
+ ],
298
+ inf_path=r"D:\\Drivers\\PRO1000\\e1r.inf"
299
+ )
300
+ """
301
+ # Normalise to a Python list for uniform processing
302
+ ids: list[str] = [hardware_ids] if isinstance(hardware_ids, str) else list(hardware_ids)
303
+
304
+ # Build the flag word sent to UpdateDriverForPlugAndPlayDevicesW
305
+ flags = INSTALLFLAG_FORCE if force_install else 0
306
+ if quiet:
307
+ flags |= INSTALLFLAG_NONINTERACTIVE
308
+
309
+ any_reboot = False # track whether *any* call needs reboot
310
+ for hid in ids:
311
+ reboot = wintypes.BOOL(False)
312
+ ok = UpdateDriverForPlugAndPlayDevicesW(
313
+ None, # hwndParent → silent (we add INSTALLFLAG_NONINTERACTIVE)
314
+ hid, # first Hardware‑ID to match
315
+ inf_path, # target driver INF
316
+ flags, # INSTALLFLAG_* bitmask
317
+ ctypes.byref(reboot) # tells us if reboot required
318
+ )
319
+ if not ok:
320
+ err = ctypes.get_last_error()
321
+ # ERROR_NO_MORE_ITEMS (0xE000020B): no matching devices present
322
+ # ERROR_DI_DO_DEFAULT (0xE000020E): already using this driver
323
+ benign = {0xE000020B, 0xE000020E}
324
+ if not (existing_ok and err in benign):
325
+ raise ctypes.WinError(err)
326
+ any_reboot |= bool(reboot.value)
327
+
328
+ return any_reboot
329
+
330
+
331
+ def add_device(
332
+ class_guid: str,
333
+ friendly_name: str,
334
+ hardware_ids: "list[str] | str",
335
+ inf_path: str,
336
+ compatible_ids: "list[str] | str | None" = None,
337
+ devdesc_override: str | None = None,
338
+ create_flags: int = DICD_GENERATE_ID,
339
+ existing_ok: bool = True,
340
+ force_install: bool = False,
341
+ quiet: bool = True
342
+ ) -> None:
343
+ """
344
+ Create a root-enumerated device node and bind a driver to it.
345
+ This is a wrapper around the two functions create_root_enumerated_devnode() and
346
+ update_driver_for_hwids().
347
+
348
+ This adds the device to the system and binds the driver to it.
349
+
350
+ :param class_guid: string representation of a GUID.
351
+ Device class GUID (e.g. GUID_DEVCLASS_NET, GUID_DEVCLASS_MEDIA …).
352
+ Example:
353
+ class_guid="{4d36e972-e325-11ce-bfc1-08002be10318}"
354
+ This is the GUID for network adapters.
355
+ :param friendly_name: str
356
+ Initial instance name placed in the registry (DeviceDesc).
357
+ Also, will be shown in Device Manager.
358
+ :param hardware_ids: str | list[str]
359
+ One or more hardware IDs (MULTI_SZ). The *first* one is the key
360
+ identifier PnP uses when selecting an INF.
361
+ :param inf_path: str
362
+ Full path to the target driver’s .INF file (must already be accessible or
363
+ pre-staged).
364
+ :param compatible_ids: str | list[str] | None
365
+ Optional Compatible-ID list (another MULTI_SZ, lower priority).
366
+ :param devdesc_override: str | None
367
+ If supplied, written to SPDRP_DEVICEDESC (rarely necessary because
368
+ the INF’s own DeviceDesc usually replaces it).
369
+ :param create_flags: int
370
+ Flags for SetupDiCreateDeviceInfoW. Default is DICD_GENERATE_ID.
371
+ :param existing_ok: bool
372
+ If True, silently succeed when the devnode already exists.
373
+ :param force_install: bool, default False
374
+ If True the function sets INSTALLFLAG_FORCE so the specified INF will be
375
+ applied even when Windows thinks a “better” driver is already installed.
376
+ :param quiet: bool, default True
377
+ If True the installation runs without UI (parent window = NULL). Set
378
+ False if you want progress dialogs.
379
+ :return: None
380
+
381
+ =====================================================================
382
+ Examples
383
+ --------
384
+
385
+
386
+
387
+ """
388
+ create_root_enumerated_devnode(
389
+ class_guid=class_guid,
390
+ friendly_name=friendly_name,
391
+ hardware_ids=hardware_ids,
392
+ compatible_ids=compatible_ids,
393
+ devdesc_override=devdesc_override,
394
+ create_flags=create_flags,
395
+ existing_ok=existing_ok
396
+ )
397
+
398
+ update_driver_for_hwids(
399
+ hardware_ids=hardware_ids,
400
+ inf_path=inf_path,
401
+ force_install=force_install,
402
+ quiet=quiet,
403
+ existing_ok=existing_ok
404
+ )
405
+
406
+
407
+ def remove_device(
408
+ pnp_device_id: str,
409
+ class_guid: str
410
+ ) -> bool:
411
+ """
412
+ Delete the single device whose PNPDeviceID
413
+ equals the string you pass in (case-insensitive). Returns True on
414
+ success, False if no matching devnode was found.
415
+
416
+ :param pnp_device_id: PNPDeviceID of the device to remove.
417
+ If you're using the Win32_NetworkAdapter class, you can
418
+ get the PNPDeviceID from the object itself: network_config.PNPDeviceID
419
+ :param class_guid: string representation of the device class GUID.
420
+ Example: '{4d36e972-e325-11ce-bfc1-08002be10318}' for network adapters.
421
+ """
422
+
423
+ class_guid_bytes = uuid.UUID(class_guid).bytes_le
424
+ class_guid_object = (ctypes.c_byte * 16).from_buffer_copy(class_guid_bytes)
425
+
426
+ # Get only PRESENT devices in the Network class
427
+ hdi = SetupDiGetClassDevsW(class_guid_object, None, None, DIGCF_PRESENT)
428
+ if hdi == wintypes.HANDLE(-1).value:
429
+ raise ctypes.WinError(ctypes.get_last_error())
430
+
431
+ devinfo = SP_DEVINFO_DATA()
432
+ devinfo.cbSize = ctypes.sizeof(devinfo)
433
+ index = 0
434
+ removed = False
435
+
436
+ # Helper to fetch the instance-ID of the current element
437
+ instance_buf_len = 512
438
+ GetInstanceId = setupapi.SetupDiGetDeviceInstanceIdW
439
+ GetInstanceId.argtypes = [
440
+ wintypes.HANDLE, ctypes.POINTER(SP_DEVINFO_DATA),
441
+ wintypes.LPWSTR, wintypes.DWORD, ctypes.POINTER(wintypes.DWORD)
442
+ ]
443
+ GetInstanceId.restype = wintypes.BOOL
444
+ inst_buf = ctypes.create_unicode_buffer(instance_buf_len)
445
+
446
+ while SetupDiEnumDeviceInfo(hdi, index, ctypes.byref(devinfo)):
447
+ index += 1
448
+
449
+ if not GetInstanceId(hdi, ctypes.byref(devinfo),
450
+ inst_buf, instance_buf_len, None):
451
+ continue
452
+
453
+ if inst_buf.value.lower() != pnp_device_id.lower():
454
+ continue # not the target
455
+
456
+ # Found it → remove
457
+ if not SetupDiCallClassInstaller(DIF_REMOVE, hdi, ctypes.byref(devinfo)):
458
+ err = ctypes.get_last_error()
459
+ SetupDiDestroyDeviceInfoList(hdi)
460
+ raise ctypes.WinError(err)
461
+
462
+ removed = True
463
+ break
464
+
465
+ SetupDiDestroyDeviceInfoList(hdi)
466
+ return removed
@@ -0,0 +1,39 @@
1
+ import ctypes
2
+
3
+
4
+ class NotWindowsConsoleError(Exception):
5
+ pass
6
+
7
+
8
+ # Define QuickEdit mode bit (0x0040)
9
+ ENABLE_QUICK_EDIT = 0x0040
10
+
11
+
12
+ def disable_quick_edit():
13
+ """
14
+ Disables QuickEdit mode in the Windows Command Prompt.
15
+ This prevents the console from being paused when the user selects text.
16
+ NO ADMIN REQUIRED
17
+ """
18
+
19
+ kernel32 = ctypes.windll.kernel32
20
+ h_stdin = kernel32.GetStdHandle(-10) # -10 is STD_INPUT_HANDLE
21
+
22
+ # Get current console mode
23
+ mode = ctypes.c_uint()
24
+ if kernel32.GetConsoleMode(h_stdin, ctypes.byref(mode)) == 0:
25
+ try:
26
+ raise ctypes.WinError()
27
+ except OSError as e:
28
+ # This means that the code is not running in console window.
29
+ if e.errno == 9 and e.winerror == 6:
30
+ raise NotWindowsConsoleError("This code is not running in a Windows console.")
31
+ else:
32
+ raise e
33
+
34
+ # Disable QuickEdit Mode by clearing the corresponding bit
35
+ mode.value &= ~ENABLE_QUICK_EDIT
36
+
37
+ # Set the new console mode
38
+ if kernel32.SetConsoleMode(h_stdin, mode) == 0:
39
+ raise ctypes.WinError()
@@ -1,4 +1,8 @@
1
+ import threading
2
+
1
3
  import docker
4
+ from docker.models.containers import Container
5
+ from docker import DockerClient
2
6
 
3
7
  from ...print_api import print_api
4
8
 
@@ -64,8 +68,8 @@ def change_image_content(
64
68
  dockerw.change_image_content(
65
69
  image_id_or_name="your_docker_image_id_or_name",
66
70
  list_of_commands=[
67
- "apt-get update",
68
- "apt-get install -y python3"
71
+ "apt update",
72
+ "apt install -y python3"
69
73
  ]
70
74
  )
71
75
  ----------------------
@@ -167,3 +171,110 @@ def add_execution_permissions_for_file(image_id_or_name: str, file_path: str, pr
167
171
  list_of_commands=[f"chmod +x {file_path}"],
168
172
  print_kwargs=print_kwargs
169
173
  )
174
+
175
+
176
+ def stop_remove_containers_by_image_name(image_name: str):
177
+ """
178
+ Remove all containers by image name.
179
+ :param image_name: str, the name of the image.
180
+ :return:
181
+ """
182
+
183
+ def stop_remove_containers(container_instance: Container):
184
+ """
185
+ Stop and remove a container instance.
186
+ :param container_instance: Container, the docker container object.
187
+ """
188
+ if container_instance.status == "running":
189
+ print_api(f"Stopping container: [{container_instance.name}]. Short ID: [{container_instance.short_id}]")
190
+ container_instance.stop()
191
+ print_api(f"Removing container: [{container_instance.name}]. Short ID: [{container_instance.short_id}]")
192
+ container_instance.remove()
193
+ print_api(f"Container removed: [{container_instance.name}]. Short ID: [{container_instance.short_id}]", color='blue')
194
+
195
+
196
+ client = docker.from_env()
197
+ all_containers = client.containers.list(all=True)
198
+
199
+ containers_to_remove: list[Container] = []
200
+ for container in all_containers:
201
+ if any(image_name in tag for tag in container.image.tags):
202
+ containers_to_remove.append(container)
203
+
204
+ for removing_container in containers_to_remove:
205
+ threading.Thread(target=stop_remove_containers, args=(removing_container,), daemon=True).start()
206
+
207
+ client.close()
208
+
209
+
210
+ def start_container_without_stop(
211
+ image_name: str,
212
+ client: DockerClient = None,
213
+ **kwargs) -> tuple[DockerClient, Container]:
214
+ """
215
+ Start a container in detached mode, this container will not run the entry point, but will run the infinite sleep.
216
+ This way the container will continue running, you can execute commands in it and stop it manually when needed.
217
+ :param image_name: str, the name of the image.
218
+ :param client: docker.DockerClient, the docker client. If not provided, it will use the default client.
219
+ :return: Container, the docker container object.
220
+ """
221
+
222
+ if client is None:
223
+ client = docker.from_env()
224
+
225
+ kwargs.setdefault('detach', True)
226
+ kwargs.setdefault('mem_limit', '512m')
227
+ kwargs.setdefault('ulimits', [docker.types.Ulimit(name='nofile', soft=20000, hard=50000)])
228
+ kwargs.setdefault('remove', False)
229
+
230
+ # Start the container with a "do nothing" command so it stays running
231
+ print_api(f"Starting container from image '{image_name}'...")
232
+ container = client.containers.run(
233
+ image=image_name,
234
+ entrypoint=["/bin/sh", "-c", "tail -f /dev/null"],
235
+ **kwargs
236
+ )
237
+
238
+ stdout = container.logs(stdout=True, stderr=False).decode()
239
+ stderr = container.logs(stdout=False, stderr=True).decode()
240
+ if stdout:
241
+ print_api(f"Container stdout: {stdout}")
242
+ if stderr:
243
+ print_api(f"Container stderr: {stderr}")
244
+
245
+ if not stderr:
246
+ print_api("Container started successfully.")
247
+
248
+ print_api(f"Started container: [{container.name}]. Short ID: [{container.short_id}]")
249
+
250
+ return client, container
251
+
252
+
253
+ def run_command_in_running_container(container: Container, command: list) -> tuple[int, bytes, str]:
254
+ """
255
+ Run a command in a running container.
256
+ :param container: Container, the docker container object.
257
+ :param command: list, the command to run.
258
+ :return: tuple of (exit_code, output, string_output).
259
+ """
260
+
261
+ # Run the command inside the already running container
262
+ exec_result = container.exec_run(cmd=command, stdout=True, stderr=True)
263
+ # Capture logs
264
+ output_text = exec_result.output.decode("utf-8", errors="replace")
265
+ execution_result_message: str = str()
266
+ if output_text:
267
+ execution_result_message = f"Container execution result:\n{output_text}"
268
+
269
+ if exec_result.exit_code != 0:
270
+ # logging.warning(f"Extraction command returned code {exec_result.exit_code} for '{filename}'")
271
+ code_message = f"Extraction command returned code {exec_result.exit_code}"
272
+ else:
273
+ code_message = "Extraction succeeded"
274
+
275
+ if execution_result_message:
276
+ execution_result_message += f"\n{code_message}"
277
+ else:
278
+ execution_result_message = code_message
279
+
280
+ return exec_result.exit_code, exec_result.output, execution_result_message
@@ -7,17 +7,5 @@ DEFAULT_KIBANA_PORT: str = '5601'
7
7
  DEFAULT_KIBANA_HOST: str = 'localhost'
8
8
  DEFAULT_KIBANA_URL: str = f"http://{DEFAULT_KIBANA_HOST}:{DEFAULT_KIBANA_PORT}"
9
9
 
10
- ELASTIC_SEARCH_CONFIG_DIRECTORY: str = "/etc/elasticsearch"
11
-
12
- ELASTIC_CONFIG_FILE: str = f"{ELASTIC_SEARCH_CONFIG_DIRECTORY}/elasticsearch.yml"
13
- XPACK_SECURITY_SETTING_NAME: str = "xpack.security.enabled"
14
-
15
- ELASTIC_JVM_OPTIONS_DIRECTORY: str = f"{ELASTIC_SEARCH_CONFIG_DIRECTORY}/jvm.options.d"
16
- ELASTIC_JVM_OPTIONS_4GB_CUSTOM_FILE: str = f"{ELASTIC_JVM_OPTIONS_DIRECTORY}/4gb_memory_heap.options"
17
- ELASTIC_JVM_OPTIONS_4GB_MEMORY_USAGE: list[str] = ['-Xms4g', '-Xmx4g']
18
-
19
- UBUNTU_DEPENDENCY_PACKAGES: list[str] = ['apt-transport-https', 'openjdk-11-jdk', 'wget']
20
- UBUNTU_ELASTIC_PACKAGE_NAME: str = 'elasticsearch'
21
10
  UBUNTU_ELASTIC_SERVICE_NAME: str = 'elasticsearch'
22
- UBUNTU_KIBANA_PACKAGE_NAME: str = 'kibana'
23
11
  UBUNTU_KIBANA_SERVICE_NAME: str = 'kibana'