thestage 0.5.46__py3-none-any.whl → 0.5.49__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 (179) hide show
  1. thestage/.env +5 -0
  2. thestage/__init__.py +3 -3
  3. thestage/__main__.py +9 -9
  4. thestage/cli_command.py +56 -0
  5. thestage/cli_command_helper.py +51 -0
  6. thestage/color_scheme/color_scheme.py +7 -7
  7. thestage/config/__init__.py +18 -18
  8. thestage/config/config_storage.py +5 -0
  9. thestage/config/env_base.py +7 -7
  10. thestage/controllers/__init__.py +0 -0
  11. thestage/controllers/base_controller.py +67 -63
  12. thestage/controllers/config_controller.py +137 -145
  13. thestage/controllers/container_controller.py +389 -425
  14. thestage/controllers/instance_controller.py +183 -200
  15. thestage/controllers/project_controller.py +802 -872
  16. thestage/controllers/utils_controller.py +32 -28
  17. thestage/debug_main.dist.py +28 -28
  18. thestage/entities/__init__.py +0 -0
  19. thestage/entities/container.py +17 -22
  20. thestage/entities/enums/__init__.py +0 -0
  21. thestage/entities/enums/order_direction_type.py +6 -6
  22. thestage/entities/enums/shell_type.py +7 -7
  23. thestage/entities/enums/tail_output_type.py +6 -6
  24. thestage/entities/enums/yes_no_response.py +7 -7
  25. thestage/entities/file_item.py +27 -27
  26. thestage/entities/project_inference_simulator.py +18 -18
  27. thestage/entities/project_inference_simulator_model.py +16 -16
  28. thestage/entities/project_task.py +19 -19
  29. thestage/entities/rented_instance.py +19 -24
  30. thestage/entities/self_hosted_instance.py +18 -20
  31. thestage/exceptions/__init__.py +0 -0
  32. thestage/exceptions/auth_exception.py +6 -6
  33. thestage/exceptions/base_exception.py +13 -13
  34. thestage/exceptions/business_logic_exception.py +6 -6
  35. thestage/exceptions/config_exception.py +6 -6
  36. thestage/exceptions/file_system_exception.py +6 -6
  37. thestage/exceptions/git_access_exception.py +17 -17
  38. thestage/exceptions/remote_server_exception.py +24 -24
  39. thestage/git/ProgressPrinter.py +22 -22
  40. thestage/helpers/__init__.py +0 -0
  41. thestage/helpers/error_handler.py +115 -115
  42. thestage/helpers/exception_hook.py +14 -0
  43. thestage/helpers/logger/__init__.py +0 -0
  44. thestage/helpers/logger/app_logger.py +50 -51
  45. thestage/helpers/ssh_util.py +38 -38
  46. thestage/i18n/en_GB/messages.po +947 -947
  47. thestage/i18n/translation.py +9 -9
  48. thestage/main.py +36 -24
  49. thestage/services/.env +6 -6
  50. thestage/services/__init__.py +0 -0
  51. thestage/services/abstract_mapper.py +9 -9
  52. thestage/services/abstract_service.py +87 -127
  53. thestage/services/app_config_service.py +52 -51
  54. thestage/services/clients/__init__.py +0 -0
  55. thestage/services/clients/git/__init__.py +0 -0
  56. thestage/services/clients/git/git_client.py +433 -331
  57. thestage/services/clients/thestage_api/__init__.py +0 -0
  58. thestage/services/clients/thestage_api/api_client.py +718 -734
  59. thestage/services/clients/thestage_api/core/api_client_core.py +108 -25
  60. thestage/services/clients/thestage_api/core/http_client_exception.py +12 -12
  61. thestage/services/clients/thestage_api/dtos/__init__.py +0 -0
  62. thestage/services/clients/thestage_api/dtos/base_response.py +13 -13
  63. thestage/services/clients/thestage_api/dtos/cloud_provider_region.py +19 -19
  64. thestage/services/clients/thestage_api/dtos/container_param_request.py +11 -11
  65. thestage/services/clients/thestage_api/dtos/container_response.py +67 -67
  66. thestage/services/clients/thestage_api/dtos/docker_container_assigned_device.py +10 -10
  67. thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_request.py +13 -13
  68. thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_response.py +13 -13
  69. thestage/services/clients/thestage_api/dtos/docker_container_mapping.py +10 -10
  70. thestage/services/clients/thestage_api/dtos/entity_filter_request.py +14 -14
  71. thestage/services/clients/thestage_api/dtos/enums/__init__.py +0 -0
  72. thestage/services/clients/thestage_api/dtos/enums/container_pending_action.py +10 -10
  73. thestage/services/clients/thestage_api/dtos/enums/container_status.py +17 -17
  74. thestage/services/clients/thestage_api/dtos/enums/cpu_type.py +8 -8
  75. thestage/services/clients/thestage_api/dtos/enums/currency_type.py +10 -10
  76. thestage/services/clients/thestage_api/dtos/enums/daemon_status.py +9 -9
  77. thestage/services/clients/thestage_api/dtos/enums/disk_type.py +7 -7
  78. thestage/services/clients/thestage_api/dtos/enums/drive_type.py +7 -7
  79. thestage/services/clients/thestage_api/dtos/enums/gpu_name.py +8 -8
  80. thestage/services/clients/thestage_api/dtos/enums/inference_model_status.py +9 -9
  81. thestage/services/clients/thestage_api/dtos/enums/inference_simulator_status.py +15 -15
  82. thestage/services/clients/thestage_api/dtos/enums/instance_rented_status.py +17 -17
  83. thestage/services/clients/thestage_api/dtos/enums/instance_type.py +7 -7
  84. thestage/services/clients/thestage_api/dtos/enums/location_region.py +11 -11
  85. thestage/services/clients/thestage_api/dtos/enums/power_status.py +10 -10
  86. thestage/services/clients/thestage_api/dtos/enums/provider_name.py +11 -11
  87. thestage/services/clients/thestage_api/dtos/enums/selfhosted_status.py +10 -10
  88. thestage/services/clients/thestage_api/dtos/enums/task_execution_status.py +12 -12
  89. thestage/services/clients/thestage_api/dtos/enums/task_status.py +12 -12
  90. thestage/services/clients/thestage_api/dtos/frontend_status.py +10 -10
  91. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_request.py +13 -13
  92. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_response.py +13 -13
  93. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_request.py +12 -12
  94. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_response.py +12 -12
  95. thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_request.py +10 -10
  96. thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_response.py +13 -13
  97. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_list_for_project_request.py +14 -14
  98. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_list_for_project_response.py +12 -12
  99. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_request.py +12 -12
  100. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_response.py +13 -13
  101. thestage/services/clients/thestage_api/dtos/inference_simulator_model_response.py +11 -11
  102. thestage/services/clients/thestage_api/dtos/inference_simulator_response.py +11 -11
  103. thestage/services/clients/thestage_api/dtos/installed_service.py +17 -17
  104. thestage/services/clients/thestage_api/dtos/instance_detected_gpus.py +20 -20
  105. thestage/services/clients/thestage_api/dtos/instance_rented_response.py +71 -71
  106. thestage/services/clients/thestage_api/dtos/logging_controller/docker_container_log_stream_request.py +7 -7
  107. thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_request.py +13 -13
  108. thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_response.py +14 -14
  109. thestage/services/clients/thestage_api/dtos/logging_controller/task_log_stream_request.py +7 -7
  110. thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_request.py +21 -21
  111. thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_response.py +14 -14
  112. thestage/services/clients/thestage_api/dtos/paginated_entity_list.py +11 -11
  113. thestage/services/clients/thestage_api/dtos/pagination_data.py +10 -10
  114. thestage/services/clients/thestage_api/dtos/price_definition.py +14 -14
  115. thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_request.py +7 -7
  116. thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_response.py +10 -10
  117. thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_request.py +8 -8
  118. thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_response.py +6 -6
  119. thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_request.py +15 -15
  120. thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_response.py +10 -10
  121. thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py +13 -14
  122. thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_response.py +10 -10
  123. thestage/services/clients/thestage_api/dtos/project_response.py +32 -32
  124. thestage/services/clients/thestage_api/dtos/selfhosted_instance_response.py +56 -56
  125. thestage/services/clients/thestage_api/dtos/sftp_path_helper.py +13 -13
  126. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_request.py +8 -8
  127. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_response.py +11 -11
  128. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_request.py +8 -8
  129. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_response.py +11 -11
  130. thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_request.py +7 -7
  131. thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_response.py +12 -12
  132. thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py +10 -10
  133. thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_response.py +12 -12
  134. thestage/services/clients/thestage_api/dtos/task_controller/task_status_localized_map_response.py +9 -9
  135. thestage/services/clients/thestage_api/dtos/task_controller/task_view_response.py +12 -12
  136. thestage/services/clients/thestage_api/dtos/user_controller/user_profile.py +12 -12
  137. thestage/services/clients/thestage_api/dtos/validate_token_response.py +11 -0
  138. thestage/services/config_provider/__init__.py +0 -0
  139. thestage/services/config_provider/config_provider.py +237 -209
  140. thestage/services/connect/connect_service.py +196 -207
  141. thestage/services/connect/dto/remote_server_config.py +9 -9
  142. thestage/services/container/__init__.py +0 -0
  143. thestage/services/container/container_service.py +374 -391
  144. thestage/services/container/mapper/__init__.py +0 -0
  145. thestage/services/container/mapper/container_mapper.py +30 -30
  146. thestage/services/core_files/config_entity.py +26 -20
  147. thestage/services/filesystem_service.py +133 -133
  148. thestage/services/instance/__init__.py +0 -0
  149. thestage/services/instance/instance_service.py +303 -317
  150. thestage/services/instance/mapper/__init__.py +0 -0
  151. thestage/services/instance/mapper/instance_mapper.py +24 -24
  152. thestage/services/instance/mapper/selfhosted_mapper.py +33 -33
  153. thestage/services/logging/byte_print_style.py +5 -5
  154. thestage/services/logging/dto/log_message.py +15 -15
  155. thestage/services/logging/dto/log_type.py +6 -6
  156. thestage/services/logging/exception/log_polling_exception.py +6 -6
  157. thestage/services/logging/logging_constants.py +3 -3
  158. thestage/services/logging/logging_service.py +367 -395
  159. thestage/services/project/__init__.py +0 -0
  160. thestage/services/project/dto/inference_simulator_dto.py +22 -22
  161. thestage/services/project/dto/inference_simulator_model_dto.py +20 -20
  162. thestage/services/project/dto/project_config.py +14 -14
  163. thestage/services/project/mapper/__init__.py +0 -0
  164. thestage/services/project/mapper/project_inference_simulator_mapper.py +21 -21
  165. thestage/services/project/mapper/project_inference_simulator_model_mapper.py +21 -21
  166. thestage/services/project/mapper/project_task_mapper.py +22 -22
  167. thestage/services/project/project_service.py +1260 -1280
  168. thestage/services/remote_server_service.py +609 -610
  169. thestage/services/service_factory.py +97 -103
  170. thestage/services/task/dto/task_dto.py +40 -40
  171. thestage/services/validation_service.py +61 -56
  172. {thestage-0.5.46.dist-info → thestage-0.5.49.dist-info}/LICENSE.txt +12 -12
  173. {thestage-0.5.46.dist-info → thestage-0.5.49.dist-info}/METADATA +3 -4
  174. thestage-0.5.49.dist-info/RECORD +176 -0
  175. {thestage-0.5.46.dist-info → thestage-0.5.49.dist-info}/WHEEL +1 -1
  176. thestage/exceptions/http_error_exception.py +0 -12
  177. thestage/services/clients/thestage_api/core/api_client_abstract.py +0 -91
  178. thestage-0.5.46.dist-info/RECORD +0 -172
  179. {thestage-0.5.46.dist-info → thestage-0.5.49.dist-info}/entry_points.txt +0 -0
@@ -1,200 +1,183 @@
1
- from pathlib import Path
2
- from typing import Optional, List
3
-
4
- from thestage.services.clients.thestage_api.dtos.enums.instance_rented_status import InstanceRentedBusinessStatus
5
-
6
- from thestage.entities.rented_instance import RentedInstanceEntity
7
- from thestage.entities.self_hosted_instance import SelfHostedInstanceEntity
8
- from thestage.helpers.logger.app_logger import app_logger
9
- from thestage.services.clients.thestage_api.dtos.enums.selfhosted_status import SelfhostedBusinessStatus
10
- from thestage.services.instance.mapper.instance_mapper import InstanceMapper
11
- from thestage.services.instance.mapper.selfhosted_mapper import SelfHostedMapper
12
- from thestage.services.instance.instance_service import InstanceService
13
- from thestage.i18n.translation import __
14
- from thestage.controllers.utils_controller import \
15
- validate_config_and_get_service_factory
16
-
17
- import typer
18
-
19
-
20
- app = typer.Typer(no_args_is_help=True, help=__("Manage server instances"))
21
-
22
- rented = typer.Typer(no_args_is_help=True, help=__("Manage rented server instances"))
23
- self_hosted = typer.Typer(no_args_is_help=True, help=__("Manage self-hosted instances"))
24
-
25
- app.add_typer(rented, name="rented")
26
- app.add_typer(self_hosted, name="self-hosted")
27
-
28
-
29
- @rented.command(name="ls", help=__("List rented server instances"))
30
- def rented_list(
31
- row: int = typer.Option(
32
- 5,
33
- '--row',
34
- '-r',
35
- help=__("Set number of rows displayed per page"),
36
- is_eager=False,
37
- ),
38
- page: int = typer.Option(
39
- 1,
40
- '--page',
41
- '-p',
42
- help=__("Set starting page for displaying output"),
43
- is_eager=False,
44
- ),
45
- statuses: List[str] = typer.Option(
46
- None,
47
- '--status',
48
- '-s',
49
- help=__("Filter by status, use --status all to list all rented server instances"),
50
- is_eager=False,
51
- ),
52
- ):
53
- """
54
- Lists rented server instances
55
- """
56
- service_factory = validate_config_and_get_service_factory()
57
- config = service_factory.get_config_provider().get_full_config()
58
-
59
- instance_service: InstanceService = service_factory.get_instance_service()
60
-
61
- instance_service.print_rented_instance_list(
62
- config=config,
63
- statuses=statuses,
64
- row=row,
65
- page=page
66
- )
67
-
68
- typer.echo(__("Rented server instances listing complete"))
69
- raise typer.Exit(0)
70
-
71
-
72
- @rented.command(name="connect", no_args_is_help=True, help=__("Connect to rented server instance"))
73
- def instance_connect(
74
- instance_uid: Optional[str] = typer.Argument(
75
- help=__("Rented server instance unique ID"),
76
- ),
77
- private_ssh_key_path: str = typer.Option(
78
- None,
79
- "--private-key-path",
80
- "-pk",
81
- help=__("Path to private key that will be accepted by remote server (optional)"),
82
- is_eager=False,
83
- )
84
- ):
85
- """
86
- Connects to rented server instance
87
- """
88
- app_logger.info(f'Connect to rented server instance')
89
-
90
- if not instance_uid:
91
- typer.echo(__('Rented server instance unique ID is required'))
92
- raise typer.Exit(1)
93
-
94
- if private_ssh_key_path and not Path(private_ssh_key_path).is_file():
95
- typer.echo(f'No file found at provided path {private_ssh_key_path}')
96
- raise typer.Exit(1)
97
-
98
- service_factory = validate_config_and_get_service_factory()
99
- config = service_factory.get_config_provider().get_full_config()
100
-
101
- instance_service: InstanceService = service_factory.get_instance_service()
102
-
103
- instance_service.connect_to_rented_instance(
104
- instance_rented_slug=instance_uid,
105
- config=config,
106
- input_ssh_key_path=private_ssh_key_path
107
- )
108
-
109
- app_logger.info(f'Stop connecting to rented server instance')
110
- raise typer.Exit(0)
111
-
112
-
113
- @self_hosted.command(name="ls", help=__("List self-hosted instances"))
114
- def self_hosted_list(
115
- row: int = typer.Option(
116
- 5,
117
- '--row',
118
- '-r',
119
- help=__("Set number of rows displayed per page"),
120
- is_eager=False,
121
- ),
122
- page: int = typer.Option(
123
- 1,
124
- '--page',
125
- '-p',
126
- help=__("Set starting page for displaying output"),
127
- is_eager=False,
128
- ),
129
- statuses: List[str] = typer.Option(
130
- None,
131
- '--status',
132
- '-s',
133
- help=__("Filter by status, use --status all to list all self-hosted server instances"),
134
- is_eager=False,
135
- ),
136
- ):
137
- """
138
- Lists self-hosted instances
139
- """
140
- service_factory = validate_config_and_get_service_factory()
141
- config = service_factory.get_config_provider().get_full_config()
142
-
143
- instance_service: InstanceService = service_factory.get_instance_service()
144
-
145
- instance_service.print_self_hosted_instance_list(
146
- config=config,
147
- statuses=statuses,
148
- row=row,
149
- page=page
150
- )
151
-
152
- typer.echo(__("Self-hosted instances listing complete"))
153
- raise typer.Exit(0)
154
-
155
-
156
- @self_hosted.command(name="connect", no_args_is_help=True, help=__("Connect to self-hosted instance"))
157
- def self_hosted_connect(
158
- instance_slug: Optional[str] = typer.Argument(help=__("Self-hosted instance unique ID"),),
159
- username: Optional[str] = typer.Option(
160
- None,
161
- '--username',
162
- '-u',
163
- help=__("Username for server instance (required when connecting to self-hosted instance)"),
164
- is_eager=False,
165
- ),
166
- private_ssh_key_path: str = typer.Option(
167
- None,
168
- "--private-key-path",
169
- "-pk",
170
- help=__("Path to private key that will be accepted by remote server (optional)"),
171
- is_eager=False,
172
- ),
173
- ):
174
- """
175
- Connects to self-hosted instance
176
- """
177
- app_logger.info(f'Connect to self-hosted instance')
178
-
179
- if not instance_slug:
180
- typer.echo(__('Self-hosted instance unique ID is required'))
181
- raise typer.Exit(1)
182
-
183
- if private_ssh_key_path and not Path(private_ssh_key_path).is_file():
184
- typer.echo(f'No file found at provided path {private_ssh_key_path}')
185
- raise typer.Exit(1)
186
-
187
- service_factory = validate_config_and_get_service_factory()
188
- config = service_factory.get_config_provider().get_full_config()
189
-
190
- instance_service: InstanceService = service_factory.get_instance_service()
191
-
192
- instance_service.connect_to_selfhosted_instance(
193
- selfhosted_instance_slug=instance_slug,
194
- username=username,
195
- config=config,
196
- input_ssh_key_path=private_ssh_key_path
197
- )
198
-
199
- app_logger.info(f'Stop connecting to self-hosted instance')
200
- raise typer.Exit(0)
1
+ from pathlib import Path
2
+ from typing import Optional, List
3
+
4
+ from thestage.cli_command import CliCommand
5
+ from thestage.cli_command_helper import get_command_group_help_panel, get_command_metadata, check_command_permission
6
+ from thestage.helpers.logger.app_logger import app_logger
7
+ from thestage.services.instance.instance_service import InstanceService
8
+ from thestage.i18n.translation import __
9
+ from thestage.controllers.utils_controller import \
10
+ validate_config_and_get_service_factory, get_current_directory
11
+
12
+ import typer
13
+
14
+
15
+ app = typer.Typer(no_args_is_help=True, help=__("Manage server instances"))
16
+
17
+ rented = typer.Typer(no_args_is_help=True, help=__("Manage rented server instances"))
18
+ self_hosted = typer.Typer(no_args_is_help=True, help=__("Manage self-hosted instances"))
19
+
20
+ app.add_typer(rented, name="rented", rich_help_panel=get_command_group_help_panel())
21
+ app.add_typer(self_hosted, name="self-hosted", rich_help_panel=get_command_group_help_panel())
22
+
23
+
24
+ @rented.command(name="ls", help=__("List rented server instances"), **get_command_metadata(CliCommand.INSTANCE_RENTED_LS))
25
+ def rented_list(
26
+ row: int = typer.Option(
27
+ 5,
28
+ '--row',
29
+ '-r',
30
+ help=__("Set number of rows displayed per page"),
31
+ is_eager=False,
32
+ ),
33
+ page: int = typer.Option(
34
+ 1,
35
+ '--page',
36
+ '-p',
37
+ help=__("Set starting page for displaying output"),
38
+ is_eager=False,
39
+ ),
40
+ statuses: List[str] = typer.Option(
41
+ None,
42
+ '--status',
43
+ '-s',
44
+ help=__("Filter by status, use --status all to list all rented server instances"),
45
+ is_eager=False,
46
+ ),
47
+ ):
48
+ command_name = CliCommand.INSTANCE_RENTED_LS
49
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
50
+ check_command_permission(command_name)
51
+
52
+ service_factory = validate_config_and_get_service_factory()
53
+ instance_service: InstanceService = service_factory.get_instance_service()
54
+
55
+ instance_service.print_rented_instance_list(
56
+ statuses=statuses,
57
+ row=row,
58
+ page=page
59
+ )
60
+
61
+ typer.echo(__("Rented server instances listing complete"))
62
+ raise typer.Exit(0)
63
+
64
+
65
+ @rented.command(name="connect", no_args_is_help=True, help=__("Connect to rented server instance"), **get_command_metadata(CliCommand.INSTANCE_RENTED_CONNECT))
66
+ def instance_connect(
67
+ instance_uid: Optional[str] = typer.Argument(
68
+ help=__("Rented server instance unique ID"),
69
+ ),
70
+ private_ssh_key_path: str = typer.Option(
71
+ None,
72
+ "--private-key-path",
73
+ "-pk",
74
+ help=__("Path to private key that will be accepted by remote server (optional)"),
75
+ is_eager=False,
76
+ )
77
+ ):
78
+ command_name = CliCommand.INSTANCE_RENTED_CONNECT
79
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
80
+ check_command_permission(command_name)
81
+
82
+ if not instance_uid:
83
+ typer.echo(__('Rented server instance unique ID is required'))
84
+ raise typer.Exit(1)
85
+
86
+ if private_ssh_key_path and not Path(private_ssh_key_path).is_file():
87
+ typer.echo(f'No file found at provided path {private_ssh_key_path}')
88
+ raise typer.Exit(1)
89
+
90
+ service_factory = validate_config_and_get_service_factory()
91
+ instance_service: InstanceService = service_factory.get_instance_service()
92
+
93
+ instance_service.connect_to_rented_instance(
94
+ instance_rented_slug=instance_uid,
95
+ input_ssh_key_path=private_ssh_key_path
96
+ )
97
+
98
+ app_logger.info(f'Stop connecting to rented server instance')
99
+ raise typer.Exit(0)
100
+
101
+
102
+ @self_hosted.command(name="ls", help=__("List self-hosted instances"), **get_command_metadata(CliCommand.INSTANCE_SELF_HOSTED_LS))
103
+ def self_hosted_list(
104
+ row: int = typer.Option(
105
+ 5,
106
+ '--row',
107
+ '-r',
108
+ help=__("Set number of rows displayed per page"),
109
+ is_eager=False,
110
+ ),
111
+ page: int = typer.Option(
112
+ 1,
113
+ '--page',
114
+ '-p',
115
+ help=__("Set starting page for displaying output"),
116
+ is_eager=False,
117
+ ),
118
+ statuses: List[str] = typer.Option(
119
+ None,
120
+ '--status',
121
+ '-s',
122
+ help=__("Filter by status, use --status all to list all self-hosted server instances"),
123
+ is_eager=False,
124
+ ),
125
+ ):
126
+ command_name = CliCommand.INSTANCE_SELF_HOSTED_LS
127
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
128
+ check_command_permission(command_name)
129
+
130
+ service_factory = validate_config_and_get_service_factory()
131
+ instance_service: InstanceService = service_factory.get_instance_service()
132
+
133
+ instance_service.print_self_hosted_instance_list(
134
+ statuses=statuses,
135
+ row=row,
136
+ page=page
137
+ )
138
+
139
+ typer.echo(__("Self-hosted instances listing complete"))
140
+ raise typer.Exit(0)
141
+
142
+
143
+ @self_hosted.command(name="connect", no_args_is_help=True, help=__("Connect to self-hosted instance"), **get_command_metadata(CliCommand.INSTANCE_SELF_HOSTED_CONNECT))
144
+ def self_hosted_connect(
145
+ instance_slug: Optional[str] = typer.Argument(help=__("Self-hosted instance unique ID"),),
146
+ username: Optional[str] = typer.Option(
147
+ None,
148
+ '--username',
149
+ '-u',
150
+ help=__("Username for server instance (required when connecting to self-hosted instance)"),
151
+ is_eager=False,
152
+ ),
153
+ private_ssh_key_path: str = typer.Option(
154
+ None,
155
+ "--private-key-path",
156
+ "-pk",
157
+ help=__("Path to private key that will be accepted by remote server (optional)"),
158
+ is_eager=False,
159
+ ),
160
+ ):
161
+ command_name = CliCommand.INSTANCE_SELF_HOSTED_CONNECT
162
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
163
+ check_command_permission(command_name)
164
+
165
+ if not instance_slug:
166
+ typer.echo(__('Self-hosted instance unique ID is required'))
167
+ raise typer.Exit(1)
168
+
169
+ if private_ssh_key_path and not Path(private_ssh_key_path).is_file():
170
+ typer.echo(f'No file found at provided path {private_ssh_key_path}')
171
+ raise typer.Exit(1)
172
+
173
+ service_factory = validate_config_and_get_service_factory()
174
+ instance_service: InstanceService = service_factory.get_instance_service()
175
+
176
+ instance_service.connect_to_selfhosted_instance(
177
+ selfhosted_instance_slug=instance_slug,
178
+ username=username,
179
+ input_ssh_key_path=private_ssh_key_path
180
+ )
181
+
182
+ app_logger.info(f'Stop connecting to self-hosted instance')
183
+ raise typer.Exit(0)