atomicshop 2.15.11__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 (221) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
  3. atomicshop/a_mains/dns_gateway_setting.py +11 -0
  4. atomicshop/a_mains/get_local_tcp_ports.py +85 -0
  5. atomicshop/a_mains/github_wrapper.py +11 -0
  6. atomicshop/a_mains/install_ca_certificate.py +172 -0
  7. atomicshop/a_mains/process_from_port.py +119 -0
  8. atomicshop/a_mains/set_default_dns_gateway.py +90 -0
  9. atomicshop/a_mains/update_config_toml.py +38 -0
  10. atomicshop/basics/ansi_escape_codes.py +3 -1
  11. atomicshop/basics/argparse_template.py +2 -0
  12. atomicshop/basics/booleans.py +27 -30
  13. atomicshop/basics/bytes_arrays.py +43 -0
  14. atomicshop/basics/classes.py +149 -1
  15. atomicshop/basics/enums.py +2 -2
  16. atomicshop/basics/exceptions.py +5 -1
  17. atomicshop/basics/list_of_classes.py +29 -0
  18. atomicshop/basics/multiprocesses.py +374 -50
  19. atomicshop/basics/strings.py +72 -3
  20. atomicshop/basics/threads.py +14 -0
  21. atomicshop/basics/tracebacks.py +13 -3
  22. atomicshop/certificates.py +153 -52
  23. atomicshop/config_init.py +11 -6
  24. atomicshop/console_user_response.py +7 -14
  25. atomicshop/consoles.py +9 -0
  26. atomicshop/datetimes.py +1 -1
  27. atomicshop/diff_check.py +3 -3
  28. atomicshop/dns.py +128 -3
  29. atomicshop/etws/_pywintrace_fix.py +17 -0
  30. atomicshop/etws/trace.py +40 -42
  31. atomicshop/etws/traces/trace_dns.py +56 -44
  32. atomicshop/etws/traces/trace_tcp.py +130 -0
  33. atomicshop/file_io/csvs.py +27 -5
  34. atomicshop/file_io/docxs.py +34 -17
  35. atomicshop/file_io/file_io.py +31 -17
  36. atomicshop/file_io/jsons.py +49 -0
  37. atomicshop/file_io/tomls.py +139 -0
  38. atomicshop/filesystem.py +616 -291
  39. atomicshop/get_process_list.py +3 -3
  40. atomicshop/http_parse.py +149 -93
  41. atomicshop/ip_addresses.py +6 -1
  42. atomicshop/mitm/centered_settings.py +132 -0
  43. atomicshop/mitm/config_static.py +207 -0
  44. atomicshop/mitm/config_toml_editor.py +55 -0
  45. atomicshop/mitm/connection_thread_worker.py +875 -357
  46. atomicshop/mitm/engines/__parent/parser___parent.py +4 -17
  47. atomicshop/mitm/engines/__parent/recorder___parent.py +108 -51
  48. atomicshop/mitm/engines/__parent/requester___parent.py +116 -0
  49. atomicshop/mitm/engines/__parent/responder___parent.py +75 -114
  50. atomicshop/mitm/engines/__reference_general/parser___reference_general.py +10 -7
  51. atomicshop/mitm/engines/__reference_general/recorder___reference_general.py +5 -5
  52. atomicshop/mitm/engines/__reference_general/requester___reference_general.py +47 -0
  53. atomicshop/mitm/engines/__reference_general/responder___reference_general.py +95 -13
  54. atomicshop/mitm/engines/create_module_template.py +58 -14
  55. atomicshop/mitm/import_config.py +359 -139
  56. atomicshop/mitm/initialize_engines.py +160 -80
  57. atomicshop/mitm/message.py +64 -23
  58. atomicshop/mitm/mitm_main.py +892 -0
  59. atomicshop/mitm/recs_files.py +183 -0
  60. atomicshop/mitm/shared_functions.py +4 -10
  61. atomicshop/mitm/ssh_tester.py +82 -0
  62. atomicshop/mitm/statistic_analyzer.py +136 -40
  63. atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +265 -83
  64. atomicshop/monitor/checks/dns.py +1 -1
  65. atomicshop/networks.py +671 -0
  66. atomicshop/on_exit.py +39 -9
  67. atomicshop/package_mains_processor.py +84 -0
  68. atomicshop/permissions/permissions.py +22 -0
  69. atomicshop/permissions/ubuntu_permissions.py +239 -0
  70. atomicshop/permissions/win_permissions.py +33 -0
  71. atomicshop/print_api.py +24 -42
  72. atomicshop/process.py +24 -6
  73. atomicshop/process_poller/process_pool.py +0 -1
  74. atomicshop/process_poller/simple_process_pool.py +204 -5
  75. atomicshop/python_file_patcher.py +1 -1
  76. atomicshop/python_functions.py +27 -75
  77. atomicshop/speech_recognize.py +8 -0
  78. atomicshop/ssh_remote.py +158 -172
  79. atomicshop/system_resource_monitor.py +61 -47
  80. atomicshop/system_resources.py +8 -8
  81. atomicshop/tempfiles.py +1 -2
  82. atomicshop/urls.py +6 -0
  83. atomicshop/venvs.py +28 -0
  84. atomicshop/versioning.py +27 -0
  85. atomicshop/web.py +98 -27
  86. atomicshop/web_apis/google_custom_search.py +44 -0
  87. atomicshop/web_apis/google_llm.py +188 -0
  88. atomicshop/websocket_parse.py +450 -0
  89. atomicshop/wrappers/certauthw/certauth.py +1 -0
  90. atomicshop/wrappers/cryptographyw.py +29 -8
  91. atomicshop/wrappers/ctyping/etw_winapi/const.py +97 -47
  92. atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py +178 -49
  93. atomicshop/wrappers/ctyping/file_details_winapi.py +67 -0
  94. atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py +2 -1
  95. atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py +2 -2
  96. atomicshop/wrappers/ctyping/setup_device.py +466 -0
  97. atomicshop/wrappers/ctyping/win_console.py +39 -0
  98. atomicshop/wrappers/dockerw/dockerw.py +113 -2
  99. atomicshop/wrappers/elasticsearchw/config_basic.py +0 -12
  100. atomicshop/wrappers/elasticsearchw/elastic_infra.py +75 -0
  101. atomicshop/wrappers/elasticsearchw/elasticsearchw.py +2 -20
  102. atomicshop/wrappers/factw/get_file_data.py +12 -5
  103. atomicshop/wrappers/factw/install/install_after_restart.py +89 -5
  104. atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +20 -14
  105. atomicshop/wrappers/githubw.py +537 -54
  106. atomicshop/wrappers/loggingw/consts.py +1 -1
  107. atomicshop/wrappers/loggingw/filters.py +23 -0
  108. atomicshop/wrappers/loggingw/formatters.py +12 -0
  109. atomicshop/wrappers/loggingw/handlers.py +214 -107
  110. atomicshop/wrappers/loggingw/loggers.py +19 -0
  111. atomicshop/wrappers/loggingw/loggingw.py +860 -22
  112. atomicshop/wrappers/loggingw/reading.py +134 -112
  113. atomicshop/wrappers/mongodbw/mongo_infra.py +31 -0
  114. atomicshop/wrappers/mongodbw/mongodbw.py +1324 -36
  115. atomicshop/wrappers/netshw.py +271 -0
  116. atomicshop/wrappers/playwrightw/engine.py +34 -19
  117. atomicshop/wrappers/playwrightw/infra.py +5 -0
  118. atomicshop/wrappers/playwrightw/javascript.py +7 -3
  119. atomicshop/wrappers/playwrightw/keyboard.py +14 -0
  120. atomicshop/wrappers/playwrightw/scenarios.py +172 -5
  121. atomicshop/wrappers/playwrightw/waits.py +9 -7
  122. atomicshop/wrappers/powershell_networking.py +80 -0
  123. atomicshop/wrappers/psutilw/processes.py +37 -1
  124. atomicshop/wrappers/psutilw/psutil_networks.py +85 -0
  125. atomicshop/wrappers/pyopensslw.py +9 -2
  126. atomicshop/wrappers/pywin32w/cert_store.py +116 -0
  127. atomicshop/wrappers/pywin32w/win_event_log/fetch.py +174 -0
  128. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py +3 -105
  129. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +3 -57
  130. atomicshop/wrappers/pywin32w/wmis/msft_netipaddress.py +113 -0
  131. atomicshop/wrappers/pywin32w/wmis/win32_networkadapterconfiguration.py +259 -0
  132. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +112 -0
  133. atomicshop/wrappers/pywin32w/wmis/wmi_helpers.py +236 -0
  134. atomicshop/wrappers/socketw/accepter.py +21 -7
  135. atomicshop/wrappers/socketw/certificator.py +216 -150
  136. atomicshop/wrappers/socketw/creator.py +190 -50
  137. atomicshop/wrappers/socketw/dns_server.py +491 -182
  138. atomicshop/wrappers/socketw/exception_wrapper.py +45 -52
  139. atomicshop/wrappers/socketw/process_getter.py +86 -0
  140. atomicshop/wrappers/socketw/receiver.py +144 -102
  141. atomicshop/wrappers/socketw/sender.py +65 -35
  142. atomicshop/wrappers/socketw/sni.py +334 -165
  143. atomicshop/wrappers/socketw/socket_base.py +134 -0
  144. atomicshop/wrappers/socketw/socket_client.py +137 -95
  145. atomicshop/wrappers/socketw/socket_server_tester.py +11 -7
  146. atomicshop/wrappers/socketw/socket_wrapper.py +717 -116
  147. atomicshop/wrappers/socketw/ssl_base.py +15 -14
  148. atomicshop/wrappers/socketw/statistics_csv.py +148 -17
  149. atomicshop/wrappers/sysmonw.py +1 -1
  150. atomicshop/wrappers/ubuntu_terminal.py +65 -26
  151. atomicshop/wrappers/win_auditw.py +189 -0
  152. atomicshop/wrappers/winregw/__init__.py +0 -0
  153. atomicshop/wrappers/winregw/winreg_installed_software.py +58 -0
  154. atomicshop/wrappers/winregw/winreg_network.py +232 -0
  155. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/METADATA +31 -51
  156. atomicshop-3.10.5.dist-info/RECORD +306 -0
  157. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/WHEEL +1 -1
  158. atomicshop/_basics_temp.py +0 -101
  159. atomicshop/a_installs/win/fibratus.py +0 -9
  160. atomicshop/a_installs/win/mongodb.py +0 -9
  161. atomicshop/a_installs/win/pycharm.py +0 -9
  162. atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh +0 -3
  163. atomicshop/addons/a_setup_scripts/install_pywintrace_0.3.cmd +0 -2
  164. atomicshop/addons/mains/__pycache__/install_fibratus_windows.cpython-312.pyc +0 -0
  165. atomicshop/addons/mains/__pycache__/msi_unpacker.cpython-312.pyc +0 -0
  166. atomicshop/addons/mains/install_docker_rootless_ubuntu.py +0 -11
  167. atomicshop/addons/mains/install_docker_ubuntu_main_sudo.py +0 -11
  168. atomicshop/addons/mains/install_elastic_search_and_kibana_ubuntu.py +0 -10
  169. atomicshop/addons/mains/install_wsl_ubuntu_lts_admin.py +0 -9
  170. atomicshop/addons/package_setup/CreateWheel.cmd +0 -7
  171. atomicshop/addons/package_setup/Setup in Edit mode.cmd +0 -6
  172. atomicshop/addons/package_setup/Setup.cmd +0 -7
  173. atomicshop/archiver/_search_in_zip.py +0 -189
  174. atomicshop/archiver/archiver.py +0 -34
  175. atomicshop/archiver/search_in_archive.py +0 -250
  176. atomicshop/archiver/sevenz_app_w.py +0 -86
  177. atomicshop/archiver/sevenzs.py +0 -44
  178. atomicshop/archiver/zips.py +0 -293
  179. atomicshop/file_types.py +0 -24
  180. atomicshop/mitm/config_editor.py +0 -37
  181. atomicshop/mitm/engines/create_module_template_example.py +0 -13
  182. atomicshop/mitm/initialize_mitm_server.py +0 -268
  183. atomicshop/pbtkmultifile_argparse.py +0 -88
  184. atomicshop/permissions.py +0 -151
  185. atomicshop/script_as_string_processor.py +0 -38
  186. atomicshop/ssh_scripts/process_from_ipv4.py +0 -37
  187. atomicshop/ssh_scripts/process_from_port.py +0 -27
  188. atomicshop/wrappers/_process_wrapper_curl.py +0 -27
  189. atomicshop/wrappers/_process_wrapper_tar.py +0 -21
  190. atomicshop/wrappers/dockerw/install_docker.py +0 -209
  191. atomicshop/wrappers/elasticsearchw/infrastructure.py +0 -265
  192. atomicshop/wrappers/elasticsearchw/install_elastic.py +0 -232
  193. atomicshop/wrappers/ffmpegw.py +0 -125
  194. atomicshop/wrappers/fibratusw/install.py +0 -81
  195. atomicshop/wrappers/mongodbw/infrastructure.py +0 -53
  196. atomicshop/wrappers/mongodbw/install_mongodb.py +0 -190
  197. atomicshop/wrappers/msiw.py +0 -149
  198. atomicshop/wrappers/nodejsw/install_nodejs.py +0 -139
  199. atomicshop/wrappers/process_wrapper_pbtk.py +0 -16
  200. atomicshop/wrappers/psutilw/networks.py +0 -45
  201. atomicshop/wrappers/pycharmw.py +0 -81
  202. atomicshop/wrappers/socketw/base.py +0 -59
  203. atomicshop/wrappers/socketw/get_process.py +0 -107
  204. atomicshop/wrappers/wslw.py +0 -191
  205. atomicshop-2.15.11.dist-info/RECORD +0 -302
  206. /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
  207. /atomicshop/{addons → a_mains/addons}/PlayWrightCodegen.cmd +0 -0
  208. /atomicshop/{addons → a_mains/addons}/ScriptExecution.cmd +0 -0
  209. /atomicshop/{addons → a_mains/addons}/inits/init_to_import_all_modules.py +0 -0
  210. /atomicshop/{addons → a_mains/addons}/process_list/ReadMe.txt +0 -0
  211. /atomicshop/{addons → a_mains/addons}/process_list/compile.cmd +0 -0
  212. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.dll +0 -0
  213. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.exp +0 -0
  214. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.lib +0 -0
  215. /atomicshop/{addons → a_mains/addons}/process_list/process_list.cpp +0 -0
  216. /atomicshop/{archiver → permissions}/__init__.py +0 -0
  217. /atomicshop/{wrappers/fibratusw → web_apis}/__init__.py +0 -0
  218. /atomicshop/wrappers/{nodejsw → pywin32w/wmis}/__init__.py +0 -0
  219. /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
  220. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info/licenses}/LICENSE.txt +0 -0
  221. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/top_level.txt +0 -0
@@ -1,88 +0,0 @@
1
- # v1.0.1 - 26.03.2023 23:50
2
- import sys
3
- import argparse
4
- from argparse import RawTextHelpFormatter
5
-
6
-
7
- class ArgparseWrapper:
8
- """
9
- # Usage in the main:
10
- args = ArgparseWrapper().parser_arguments
11
- # Defining variables to each argument
12
- input_path: str = args.input
13
- output_path: str = args.output
14
- """
15
-
16
- def __init__(self):
17
- self.application_short: str = 'pbtkMultiFile'
18
- self.application_full: str = 'pbtk Multi File wrapper'
19
- self.version: str = '1.0.0'
20
- self.description: str = 'Find ".proto" files in directory of binaries.'
21
- self.description_full: str = f'{self.application_full} v{self.version}\n' \
22
- f'Description: {self.description}'
23
- self.usage_variable: str = "%(prog)s [-h] -in folder_with_binary_files -out full_path_to_output_files\n" \
24
- "Input or Output path shouldn't end with separator. Example: '\\'."
25
- self.parser_arguments = None
26
-
27
- # Execute argparse.
28
- self.define_argparse()
29
-
30
- # Function to define argument parser
31
- def define_argparse(self):
32
- # Create the parser
33
- # formatter_class=RawTextHelpFormatter: shows raw text and not the default argparse text parsing.
34
- parser = argparse.ArgumentParser(description=self.description_full,
35
- usage=self.usage_variable,
36
- formatter_class=RawTextHelpFormatter)
37
-
38
- # Add arguments
39
- parser.add_argument('-in', '--input',
40
- action='store', type=str, metavar='PATH_TO_FOLDER_WITH_BINARY_FILES',
41
- required=True,
42
- help='Provide full path to folder that contains binary files.')
43
- parser.add_argument('-out', '--output', action='store', type=str, metavar='PATH_TO_SAVE_EXPORTED_FILES',
44
- required=True,
45
- help='Provide full path where you want to store exported file.')
46
-
47
- # A problem before executing 'parse_args()'.
48
- # If we get directory path as argument, on windows we can get a path that ends with backslash:
49
- # C:\Users\user\documents\
50
- # This is the default behaviour of windows when copying path of only the directory.
51
- # When the path contains spaces, we need to pass it with double quotes:
52
- # "C:\Users\user\documents\some folder name\another\"
53
- # When python receives the arguments from CMD they get already parsed, meaning python can do nothing about it.
54
- # From input:
55
- # python_script.py -in "C:\some folder name\another\" -out "C:\some folder name\another1\"
56
- # You will get output:
57
- # ['python_script.py',
58
- # '-in',
59
- # 'C:\some folder name\another" -out C:\some',
60
- # 'folder',
61
- # 'name\another1"]
62
- # 'parse_args()' gets its input from 'sys.argv'. Meaning, you will need to do some manipulations on that
63
- # Before executing the argparse argument parsing.
64
- # Probably the fix should be individual for each case.
65
- # The simplest solution though is to tell the user not to use backslash in the end of directory in case
66
- # of exception.
67
-
68
- try:
69
- # Execute parse_args()
70
- parsed_arguments = parser.parse_args()
71
- # The only thing that you can catch on without modifying Argparse code is 'SystemExit' exception.
72
- # You can also provide just 'except' without anything, which isn't the best practice.
73
- # Another fix would be to use
74
- # argparse.ArgumentParser(exit_on_error=False)
75
- # But as of python 3.10.8 it is not working yet.
76
- except SystemExit as exception_object:
77
- print('======================================')
78
- print('[*] Info: Error in provided arguments.')
79
- print('[*] Tip: Check if you have backslash "\\" in the end of folder path, if so remove it.')
80
- print('======================================')
81
- sys.exit()
82
-
83
- # if the folder path argument in the middle will have backslash "\" it will cause an exception.
84
- # If the backslash will be in the end, it will not cause exception, but the string will end with double quotes.
85
- parsed_arguments.input = parsed_arguments.input.replace('"', '')
86
- parsed_arguments.output = parsed_arguments.output.replace('"', '')
87
-
88
- self.parser_arguments = parsed_arguments
atomicshop/permissions.py DELETED
@@ -1,151 +0,0 @@
1
- import os
2
- import stat
3
- import ctypes
4
- import contextlib
5
- import subprocess
6
-
7
- # Import pwd only on linux.
8
- if os.name == 'posix':
9
- import pwd
10
-
11
-
12
- def is_admin() -> bool:
13
- """
14
- Function checks on Windows or POSIX OSes if the script is executed under Administrative Privileges.
15
- :return: True / False.
16
- """
17
-
18
- if os.name == 'nt':
19
- if ctypes.windll.shell32.IsUserAnAdmin() == 0:
20
- result = False
21
- else:
22
- result = True
23
- else:
24
- if 'SUDO_USER' in os.environ and os.geteuid() == 0:
25
- result = True
26
- else:
27
- result = False
28
-
29
- return result
30
-
31
-
32
- def get_ubuntu_sudo_executer_username() -> str:
33
- """
34
- Function gets the username of the user who executed the script with sudo.
35
- :return: str, username.
36
- """
37
-
38
- if 'SUDO_USER' in os.environ:
39
- return os.environ['SUDO_USER']
40
- else:
41
- return ''
42
-
43
-
44
- def set_executable_permission(file_path: str):
45
- """
46
- Function sets the executable permission on a file.
47
- Equivalent to: chmod +x <file_path>
48
-
49
- :param file_path: str, path to the file.
50
- :return:
51
- """
52
-
53
- # os.chmod(file_path, os.stat(file_path).st_mode | 0o111)
54
- os.chmod(file_path, os.stat(file_path).st_mode | stat.S_IXUSR)
55
-
56
-
57
- def change_file_owner_ubuntu(file_path: str, username: str):
58
- """
59
- Function changes the owner of the file to the specified user.
60
- :param file_path: str, path to the file.
61
- :param username: str, username of the new owner.
62
- :return:
63
- """
64
-
65
- uid = pwd.getpwnam(username).pw_uid
66
- os.chown(file_path, uid, -1)
67
-
68
-
69
- def is_executable_permission(file_path: str) -> bool:
70
- """
71
- Function checks if the file has the executable permission.
72
- Equivalent to: stat -c "%a %n" <file_path>
73
-
74
- :param file_path: str, path to the file.
75
- :return: bool, True / False.
76
- """
77
-
78
- return bool(os.stat(file_path).st_mode & stat.S_IXUSR)
79
-
80
-
81
- def run_as_root(command):
82
- subprocess.check_call(['sudo'] + command)
83
-
84
-
85
- @contextlib.contextmanager
86
- def temporary_regular_permissions():
87
- """
88
- This function is used to temporarily change the effective user and group ID to the original user's.
89
- This is used to run commands with the original user's permissions.
90
- If you executed a script with 'sudo' and wanted certain action to execute as regular user and not root.
91
-
92
- Example:
93
- with temporary_regular_permissions():
94
- # Do something with regular permissions.
95
- pass
96
-
97
- :return:
98
- """
99
- # Save the current effective user and group ID
100
- original_euid, original_egid = os.geteuid(), os.getegid()
101
-
102
- try:
103
- # Get the original user's UID and GID
104
- orig_uid = int(os.environ.get('SUDO_UID', os.getuid()))
105
- orig_gid = int(os.environ.get('SUDO_GID', os.getgid()))
106
-
107
- # Set the effective user and group ID to the original user's
108
- os.setegid(orig_gid)
109
- os.seteuid(orig_uid)
110
-
111
- # Provide the context to do something with these permissions
112
- yield
113
- finally:
114
- # Revert to the original effective user and group ID
115
- os.seteuid(original_euid)
116
- os.setegid(original_egid)
117
-
118
-
119
- def expand_user_path(user_name, path):
120
- pwnam = pwd.getpwnam(user_name)
121
- home_dir = pwnam.pw_dir
122
- return path.replace("~", home_dir)
123
-
124
-
125
- def unblock_file_windows(file_path):
126
- """
127
- Unblock a file on Windows. This is used to unblock files downloaded from the internet.
128
- When you Right-click then navigate to Properties, you will see the Unblock checkbox.
129
- :param file_path:
130
- :return:
131
- """
132
- try:
133
- subprocess.run(["powershell", "-Command", f"Unblock-File -Path '{file_path}'"], check=True)
134
- print(f"Successfully unblocked the file: {file_path}")
135
- except subprocess.CalledProcessError as e:
136
- print(f"Failed to unblock the file: {file_path}\nError: {e}")
137
-
138
-
139
- def get_command_to_run_as_admin_windows(command: str) -> str:
140
- """
141
- Function returns the command to run a command as administrator on Windows.
142
- :param command: str, command to run.
143
- :return: str, command to run as administrator.
144
- """
145
-
146
- executable = command.split()[0]
147
- command = (
148
- f"powershell -Command "
149
- f"\"Start-Process {executable} -ArgumentList '{' '.join(command.split()[1:])}' -Verb RunAs\"")
150
-
151
- return command
@@ -1,38 +0,0 @@
1
- """Loading resources using stdlib importlib.resources APIs (Python 3.7+)
2
- https://docs.python.org/3/library/importlib.html#module-importlib.resources"""
3
- import importlib.resources
4
-
5
- from .print_api import print_api
6
-
7
-
8
- class ScriptAsStringProcessor:
9
- def __init__(self):
10
- self.resources_directory_name: str = 'ssh_scripts'
11
-
12
- # string variable that is going to be exchanged with variable from main script.
13
- self.exchange_input_variable_string: str = "exchange_input_variable"
14
- self.script_string: str = str()
15
-
16
- def read_script_to_string(self, script_file_name: str):
17
- self.script_string = importlib.resources.read_text(
18
- f'{__package__}.{self.resources_directory_name}',
19
- f'{script_file_name}.py')
20
-
21
- return self
22
-
23
- def put_variable_into_script_string(self, input_variable: any, print_kwargs: dict = None):
24
- # Defining variables
25
- function_result: str = str()
26
-
27
- if self.exchange_input_variable_string in self.script_string:
28
- # string.replace(old, new, count)
29
- # old – old substring you want to replace.
30
- # new – new substring which would replace the old substring.
31
- # count – the number of times you want to replace the old substring with the new substring. (Optional)
32
- # We want to replace our string only one time in the beginning.
33
- function_result = self.script_string.replace(self.exchange_input_variable_string, str(input_variable), 1)
34
- else:
35
- message = f"The script string provided doesn't contain {self.exchange_input_variable_string}"
36
- print_api(message, error_type=True, logger_method='error', **print_kwargs)
37
-
38
- return function_result
@@ -1,37 +0,0 @@
1
- # importing the psutil library to get the source ports and get the process full command line from it.
2
- import psutil
3
- # 'psutil.Process(connection.pid).cmdline()' returns list of full command line parts, it is needed to reassemble
4
- # these parts to regular command line string.
5
- import shlex
6
-
7
-
8
- # User defined exception.
9
- class StopAllIterations(Exception):
10
- pass
11
-
12
-
13
- # 'input_variable' will be string exchanged in the real script. It is the first line, so it won't take time to find the
14
- # line for the main script.
15
- # noinspection PyUnresolvedReferences
16
- remote_ipv4_list = exchange_input_variable
17
-
18
-
19
- try:
20
- # for iteration in range(100):
21
- # Iterating through all the connections on the computer.
22
- for connection in psutil.net_connections(kind='all'):
23
- # 'connection.raddr' is a tuple consisting of IPv4 address [0] and the port [1].
24
- # Sometimes, if there's no remote address, "raddr" will be empty and since it's a tuple, we need to check that
25
- # before getting the first [0] index.
26
- if connection.raddr:
27
- for address in remote_ipv4_list:
28
- if connection.raddr[0] == address:
29
- # Get the command line from the connection PID.
30
- command_line = psutil.Process(connection.pid).cmdline()
31
- # Command line object is returned as list of parameters. We need 'shlex.join' to join the iterables
32
- # to regular, readable string.
33
- print(shlex.join(command_line))
34
- # Break the loops, when first match is found.
35
- raise StopAllIterations
36
- except StopAllIterations:
37
- pass
@@ -1,27 +0,0 @@
1
- # importing the psutil library to get the source ports and get the process full command line from it.
2
- import psutil
3
- # 'psutil.Process(connection.pid).cmdline()' returns list of full command line parts, it is needed to reassemble
4
- # these parts to regular command line string.
5
- import shlex
6
-
7
- # 'input_variable' will be string exchanged in the real script. It is the first line, so it won't take time to find the
8
- # line for the main script.
9
- # noinspection PyUnresolvedReferences
10
- source_port = exchange_input_variable
11
-
12
- # Iterating through all the connections on the computer.
13
- for connection in psutil.net_connections():
14
- # 'connection.laddr' is a tuple consisting of IPv4 address [0] and the port [1].
15
- if connection.laddr[1] == source_port:
16
- # Get the command line from the connection PID.
17
- command_line = psutil.Process(connection.pid).cmdline()
18
- # Command line object is returned as list of parameters. We need 'shlex.join' to join the iterables
19
- # to regular, readable string.
20
- result = shlex.join(command_line)
21
- # If the result is still a PID, we'll try to get process name.
22
- if result.isnumeric():
23
- # Get the process name from the connection PID.
24
- result = psutil.Process(connection.pid).name()
25
- print(result)
26
- # Break the loop, when first match is found.
27
- break
@@ -1,27 +0,0 @@
1
- # v1.0.2 - 21.03.2023 13:40
2
- import sys
3
- import shlex
4
-
5
- from .. import process
6
- from .. import web
7
-
8
-
9
- def download_file_with_curl(file_url: str, target_directory: str) -> None:
10
- """
11
- The function receives url and target filesystem directory to download the file.
12
-
13
- :param file_url: full URL to download the file.
14
- :param target_directory: The directory on the filesystem to save the file to.
15
- """
16
-
17
- # Get only the filename from URL.
18
- file_name = web.get_filename_from_url(file_url=file_url)
19
-
20
- cmd: str = f'curl -L {file_url} --output "{target_directory}"'
21
- cmd_list: list = shlex.split(cmd)
22
-
23
- output_list: list = process.execute_with_live_output(cmd=cmd_list)
24
- # If there was error in curl.
25
- if 'curl: ' in output_list[-1]:
26
- print('Curl error. Exiting...')
27
- sys.exit()
@@ -1,21 +0,0 @@
1
- # v1.0.2 - 21.03.2023 18:30
2
- import shlex
3
-
4
- from .. import process
5
-
6
-
7
- def extract_archive_with_tar(file_path: str, target_directory: str) -> None:
8
- """
9
- Function extracts the archive to target directory.
10
-
11
- :param file_path: Full file path to archived file to extract.
12
- :param target_directory: The directory on the filesystem to extract the file to.
13
- :return: None
14
- """
15
-
16
- # -v: Verbose, shows list of extracted files.
17
- # -C: Output directory.
18
- cmd: str = f'tar -xzvf "{file_path}" -C "{target_directory}"'
19
- cmd_list: list = shlex.split(cmd)
20
-
21
- output_list = process.execute_with_live_output(cmd=cmd_list)
@@ -1,209 +0,0 @@
1
- import sys
2
- import subprocess
3
- import getpass
4
-
5
- from ... import process, filesystem, permissions
6
- from ...print_api import print_api
7
- from .. import ubuntu_terminal
8
-
9
-
10
- def is_docker_installed():
11
- """
12
- The function will check if docker is installed.
13
- :return: bool.
14
- """
15
-
16
- try:
17
- # Run the command 'docker --version'
18
- result = subprocess.run(['docker', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
19
-
20
- # Check if the command was successful
21
- if result.returncode == 0:
22
- message = f"Docker is installed. Version: {result.stdout.strip()}"
23
- print_api(message, color='green')
24
- return True
25
- else:
26
- print_api("Docker is not installed.")
27
- return False
28
- except FileNotFoundError:
29
- print_api("Docker command not found. Docker is not installed.")
30
- return False
31
-
32
-
33
- def add_current_user_to_docker_group(print_kwargs: dict = None):
34
- """
35
- The function will add the current user to the docker group.
36
-
37
- :param print_kwargs: dict, the print arguments.
38
- :return:
39
- """
40
- # Check if current user that executed the script is a sudo user. If not, use the current user.
41
- sudo_executer_username: str = permissions.get_ubuntu_sudo_executer_username()
42
- if sudo_executer_username:
43
- current_user = sudo_executer_username
44
- else:
45
- current_user = getpass.getuser()
46
-
47
- # Add the current user to the docker group.
48
- # subprocess.check_call(['sudo', 'usermod', '-aG', 'docker', current_user])
49
- command = f"sudo usermod -aG docker {current_user}"
50
- # Execute the command
51
- subprocess.run(command, shell=True, capture_output=True, text=True)
52
-
53
- # Check if the user was added to the docker group.
54
- result = subprocess.run(['groups', current_user], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
55
- if 'docker' in result.stdout:
56
- print_api(f"User {current_user} was added to the docker group.", color='green', **(print_kwargs or {}))
57
- return True
58
- else:
59
- print_api(f"User {current_user} was not added to the docker group. Try executing with sudo", color='red',
60
- **(print_kwargs or {}))
61
- return False
62
-
63
-
64
- def install_docker_ubuntu(
65
- use_docker_installer: bool = True,
66
- rootless: bool = False,
67
- add_current_user_to_docker_group_bool: bool = False
68
- ):
69
- """
70
- The function will install docker on ubuntu.
71
- Note: If you want to install docker in rootless mode, you need to run the script without sudo.
72
-
73
- :param rootless: bool, if True, the rootless installation will be performed.
74
- Meaning, you will be able to run the 'docker' command without sudo and you will not need to add the
75
- current user to the docker group.
76
- :param use_docker_installer: bool, if True, the docker installer will be used.
77
- If False, the docker will be installed using the apt package manager, custom repo and keyring.
78
- :param add_current_user_to_docker_group_bool: bool, if True, the current user will be added to the docker group.
79
- So the user will be able to run the 'docker' command without sudo. If you install docker in rootless mode
80
- this is not needed.
81
-
82
- Usage in main.py (run with sudo):
83
- from atomicshop.wrappers.dockerw import install_docker
84
-
85
-
86
- def main():
87
- install_docker.install_docker_ubuntu()
88
-
89
-
90
- if __name__ == '__main__':
91
- main()
92
- """
93
-
94
- if rootless and permissions.is_admin():
95
- print_api('Rootless installation requires running the script without sudo.', color='red')
96
- sys.exit()
97
-
98
- if use_docker_installer:
99
- if not ubuntu_terminal.is_executable_exists('curl'):
100
- print_api('curl is not installed, installing...', color='yellow')
101
- ubuntu_terminal.update_system_packages()
102
- ubuntu_terminal.install_packages(['curl'])
103
-
104
- # Use the docker installer script.
105
- # The script will install docker and add the current user to the docker group.
106
- # The script will also install docker-compose and docker-buildx.
107
- # process.execute_script('curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh', shell=True)
108
- process.execute_script('curl -fsSL https://get.docker.com | sh', shell=True)
109
- # process.execute_script('curl -fsSL https://get.docker.com -o get-docker.sh', shell=True)
110
- # process.execute_script('sh get-docker.sh', shell=True)
111
- # filesystem.remove_file('get-docker.sh')
112
- else:
113
- # Remove the existing keyrings, so we will not be asked to overwrite it if it exists.
114
- docker_keyring_file_path: str = "/etc/apt/keyrings/docker.gpg"
115
- filesystem.remove_file(docker_keyring_file_path)
116
-
117
- script = f"""
118
- # Step 1: Set up Docker's apt repository
119
- sudo apt-get update
120
- sudo apt-get install -y ca-certificates curl gnupg
121
- sudo install -m 0755 -d /etc/apt/keyrings
122
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
123
- sudo chmod a+r /etc/apt/keyrings/docker.gpg
124
-
125
- # Add the repository to Apt sources
126
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
127
- sudo apt-get update
128
-
129
- # Step 2: Install the Docker packages
130
- sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
131
-
132
- # Step 3: Verify the installation
133
- # sudo docker run hello-world
134
-
135
- # Add Privileges to run docker without sudo. Add current user to Docker superuser group.
136
- # sudo usermod -aG docker $USER
137
- """
138
-
139
- process.execute_script(script, shell=True)
140
-
141
- if rootless:
142
- # Install uidmap package.
143
- if not ubuntu_terminal.is_package_installed('uidmap'):
144
- print_api('uidmap is not installed, installing...', color='yellow')
145
- ubuntu_terminal.update_system_packages()
146
- ubuntu_terminal.install_packages(['uidmap'])
147
-
148
- with permissions.temporary_regular_permissions():
149
- # After 'get-docker.sh' execution, we will install docker in rootless mode.
150
- # process.execute_script('dockerd-rootless-setuptool.sh install', shell=True, as_regular_user=True)
151
- process.execute_script(
152
- '/usr/bin/dockerd-rootless-setuptool.sh install',
153
- as_regular_user=True,
154
- shell=True,
155
- executable=None)
156
-
157
- # Start and enable the docker service in user mode.
158
- docker_start_command = ubuntu_terminal.get_command_execution_as_sudo_executer(
159
- 'systemctl --user start docker.service')
160
- docker_enable_command = ubuntu_terminal.get_command_execution_as_sudo_executer(
161
- 'systemctl --user enable docker.service')
162
- print_api('Starting and enabling the docker service in user mode...')
163
- process.execute_script(docker_start_command, shell=True, executable=None)
164
- process.execute_script(docker_enable_command, shell=True, executable=None)
165
-
166
- print_api('Executing "loginctl enable-linger" to enable Docker to run when the user is not logged in...')
167
- non_sudo_executer = permissions.get_ubuntu_sudo_executer_username()
168
- # Enable lingering so Docker runs when the user is not logged in
169
- process.execute_script(f'sudo loginctl enable-linger {non_sudo_executer}', shell=True)
170
-
171
- print_api('Adding $HOME/bin to your PATH...')
172
- # Add $HOME/bin to your PATH if it's not already there.
173
- with permissions.temporary_regular_permissions():
174
- ubuntu_terminal.add_path_to_bashrc(as_regular_user=True)
175
-
176
- # Add appropriate permissions to the docker socket, so the user can run docker commands without sudo in python.
177
- # with open('/etc/profile.d/docker_vars.sh', 'w') as file:
178
- # file.write('export DOCKER_HOST=unix:///run/user/1000/docker.sock')
179
-
180
- # Since we are installing the rootless mode, this script runs without sudo, so to add the DOCKER_HOST variable
181
- # to the environment, we need to add it to the /etc/profile.d/docker_vars.sh file with sudo.
182
- command = "echo 'export DOCKER_HOST=unix:///run/user/1000/docker.sock' | sudo tee /etc/profile.d/docker_vars.sh"
183
- subprocess.run(command, shell=True, check=True)
184
-
185
- # ubuntu_terminal.add_line_to_bashrc(
186
- # 'export DOCKER_HOST=unix:///run/user/1000/docker.sock', as_regular_user=True)
187
- # process.execute_script('export DOCKER_HOST=unix:///run/user/1000/docker.sock', shell=True)
188
- # Restart shell.
189
- # process.execute_script('source ~/.bashrc', shell=True)
190
-
191
- if add_current_user_to_docker_group_bool:
192
- # Check if current user that executed the script is a sudo user. If not, use the current user.
193
- # Add the current user to the docker group.
194
- add_current_user_to_docker_group()
195
-
196
- # Verify the installation.
197
- result: list = process.execute_with_live_output('sudo docker run hello-world')
198
- else:
199
- result: list = process.execute_with_live_output('docker run hello-world')
200
-
201
- print_api('\n'.join(result))
202
-
203
- if 'Hello from Docker!' in '\n'.join(result):
204
- print_api('Docker installed successfully.', color='green')
205
- return True
206
- else:
207
- print_api('Docker installation failed.', color='red')
208
- print_api('Please check the logs above for more information.', color='red')
209
- return False