kaqing 2.0.184__py3-none-any.whl → 2.0.227__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.

Potentially problematic release.


This version of kaqing might be problematic. Click here for more details.

Files changed (205) hide show
  1. adam/app_session.py +1 -1
  2. adam/batch.py +15 -15
  3. adam/checks/compactionstats.py +2 -1
  4. adam/checks/cpu.py +2 -1
  5. adam/checks/disk.py +6 -5
  6. adam/checks/gossip.py +2 -1
  7. adam/checks/memory.py +2 -1
  8. adam/checks/status.py +2 -1
  9. adam/commands/app/app.py +4 -4
  10. adam/commands/app/app_ping.py +2 -2
  11. adam/commands/{login.py → app/login.py} +2 -2
  12. adam/commands/app/show_app_actions.py +3 -3
  13. adam/commands/app/show_app_id.py +2 -2
  14. adam/commands/app/show_app_queues.py +2 -2
  15. adam/commands/{show → app}/show_login.py +3 -3
  16. adam/commands/app/utils_app.py +9 -1
  17. adam/commands/audit/audit.py +8 -24
  18. adam/commands/audit/audit_repair_tables.py +3 -3
  19. adam/commands/audit/audit_run.py +3 -3
  20. adam/commands/audit/completions_l.py +15 -0
  21. adam/commands/audit/show_last10.py +2 -3
  22. adam/commands/audit/show_slow10.py +2 -2
  23. adam/commands/audit/show_top10.py +2 -2
  24. adam/commands/bash/bash.py +3 -3
  25. adam/commands/bash/utils_bash.py +1 -1
  26. adam/commands/cassandra/download_cassandra_log.py +45 -0
  27. adam/commands/cassandra/restart_cluster.py +47 -0
  28. adam/commands/cassandra/restart_node.py +51 -0
  29. adam/commands/cassandra/restart_nodes.py +47 -0
  30. adam/commands/{rollout.py → cassandra/rollout.py} +3 -3
  31. adam/commands/{show → cassandra}/show_cassandra_repairs.py +7 -5
  32. adam/commands/{show → cassandra}/show_cassandra_status.py +24 -17
  33. adam/commands/{show → cassandra}/show_cassandra_version.py +2 -2
  34. adam/commands/cassandra/show_processes.py +50 -0
  35. adam/commands/cassandra/show_storage.py +44 -0
  36. adam/commands/{watch.py → cassandra/watch.py} +2 -2
  37. adam/commands/cli/__init__.py +0 -0
  38. adam/commands/{cli_commands.py → cli/cli_commands.py} +6 -1
  39. adam/commands/{clipboard_copy.py → cli/clipboard_copy.py} +4 -4
  40. adam/commands/{show/show_commands.py → cli/show_cli_commands.py} +5 -5
  41. adam/commands/code.py +2 -2
  42. adam/commands/command.py +54 -14
  43. adam/commands/commands_utils.py +14 -6
  44. adam/commands/config/__init__.py +0 -0
  45. adam/commands/{param_get.py → config/param_get.py} +2 -2
  46. adam/commands/{param_set.py → config/param_set.py} +2 -2
  47. adam/commands/{show → config}/show_params.py +3 -3
  48. adam/commands/{alter_tables.py → cql/alter_tables.py} +3 -3
  49. adam/commands/cql/completions_c.py +29 -0
  50. adam/commands/cql/cqlsh.py +4 -8
  51. adam/commands/cql/utils_cql.py +36 -17
  52. adam/commands/debug/__init__.py +0 -0
  53. adam/commands/debug/debug.py +22 -0
  54. adam/commands/debug/debug_completes.py +35 -0
  55. adam/commands/debug/debug_timings.py +35 -0
  56. adam/commands/debug/show_offloaded_completes.py +45 -0
  57. adam/commands/deploy/code_start.py +2 -2
  58. adam/commands/deploy/code_stop.py +2 -2
  59. adam/commands/deploy/deploy_frontend.py +2 -2
  60. adam/commands/deploy/deploy_pg_agent.py +2 -2
  61. adam/commands/deploy/deploy_pod.py +2 -2
  62. adam/commands/deploy/undeploy_frontend.py +2 -2
  63. adam/commands/deploy/undeploy_pg_agent.py +2 -2
  64. adam/commands/deploy/undeploy_pod.py +2 -2
  65. adam/commands/devices/device.py +37 -11
  66. adam/commands/devices/device_app.py +7 -7
  67. adam/commands/devices/device_auit_log.py +2 -2
  68. adam/commands/devices/device_cass.py +6 -6
  69. adam/commands/devices/device_export.py +7 -4
  70. adam/commands/devices/device_postgres.py +19 -9
  71. adam/commands/devices/devices.py +1 -1
  72. adam/commands/diag/__init__.py +0 -0
  73. adam/commands/{check.py → diag/check.py} +3 -3
  74. adam/commands/diag/generate_report.py +52 -0
  75. adam/commands/{issues.py → diag/issues.py} +3 -2
  76. adam/commands/exit.py +2 -2
  77. adam/commands/export/clean_up_all_export_sessions.py +2 -2
  78. adam/commands/export/clean_up_export_sessions.py +2 -2
  79. adam/commands/export/completions_x.py +11 -0
  80. adam/commands/export/download_export_session.py +5 -5
  81. adam/commands/export/drop_export_database.py +2 -2
  82. adam/commands/export/drop_export_databases.py +2 -2
  83. adam/commands/export/export.py +3 -19
  84. adam/commands/export/export_databases.py +20 -11
  85. adam/commands/export/export_select.py +9 -34
  86. adam/commands/export/export_sessions.py +13 -11
  87. adam/commands/export/export_use.py +6 -6
  88. adam/commands/export/export_x_select.py +48 -0
  89. adam/commands/export/exporter.py +140 -53
  90. adam/commands/export/import_files.py +3 -7
  91. adam/commands/export/import_session.py +2 -6
  92. adam/commands/export/importer.py +12 -13
  93. adam/commands/export/importer_athena.py +15 -35
  94. adam/commands/export/importer_sqlite.py +19 -8
  95. adam/commands/export/show_column_counts.py +11 -12
  96. adam/commands/export/show_export_databases.py +4 -4
  97. adam/commands/export/show_export_session.py +5 -5
  98. adam/commands/export/show_export_sessions.py +4 -4
  99. adam/commands/export/utils_export.py +40 -25
  100. adam/commands/fs/__init__.py +0 -0
  101. adam/commands/{cat.py → fs/cat.py} +4 -4
  102. adam/commands/fs/cat_local.py +42 -0
  103. adam/commands/{cd.py → fs/cd.py} +4 -4
  104. adam/commands/{download_file.py → fs/download_file.py} +7 -7
  105. adam/commands/{find_files.py → fs/find_files.py} +7 -7
  106. adam/commands/{find_processes.py → fs/find_processes.py} +14 -22
  107. adam/commands/{head.py → fs/head.py} +5 -5
  108. adam/commands/fs/head_local.py +46 -0
  109. adam/commands/{ls.py → fs/ls.py} +4 -4
  110. adam/commands/fs/ls_local.py +40 -0
  111. adam/commands/{pwd.py → fs/pwd.py} +2 -2
  112. adam/commands/fs/rm.py +18 -0
  113. adam/commands/fs/rm_downloads.py +39 -0
  114. adam/commands/fs/rm_logs.py +44 -0
  115. adam/commands/fs/rm_logs_local.py +38 -0
  116. adam/commands/{shell.py → fs/shell.py} +2 -2
  117. adam/commands/{show → fs}/show_adam.py +3 -3
  118. adam/commands/{show → fs}/show_host.py +2 -2
  119. adam/commands/fs/show_last_results.py +39 -0
  120. adam/commands/fs/tail.py +36 -0
  121. adam/commands/fs/tail_local.py +46 -0
  122. adam/commands/fs/utils_fs.py +192 -0
  123. adam/commands/help.py +2 -2
  124. adam/commands/intermediate_command.py +3 -0
  125. adam/commands/kubectl.py +2 -2
  126. adam/commands/medusa/medusa_backup.py +2 -2
  127. adam/commands/medusa/medusa_restore.py +4 -18
  128. adam/commands/medusa/medusa_show_backupjobs.py +2 -2
  129. adam/commands/medusa/medusa_show_restorejobs.py +2 -2
  130. adam/commands/medusa/utils_medusa.py +15 -0
  131. adam/commands/nodetool/__init__.py +0 -0
  132. adam/commands/nodetool/nodetool.py +87 -0
  133. adam/commands/nodetool/utils_nodetool.py +44 -0
  134. adam/commands/postgres/completions_p.py +22 -0
  135. adam/commands/postgres/postgres.py +10 -20
  136. adam/commands/postgres/postgres_databases.py +3 -3
  137. adam/commands/postgres/postgres_ls.py +3 -3
  138. adam/commands/postgres/postgres_preview.py +2 -2
  139. adam/commands/postgres/utils_postgres.py +12 -2
  140. adam/commands/preview_table.py +3 -4
  141. adam/commands/reaper/reaper_forward.py +2 -2
  142. adam/commands/reaper/reaper_forward_stop.py +2 -2
  143. adam/commands/reaper/reaper_restart.py +2 -2
  144. adam/commands/reaper/reaper_run_abort.py +2 -2
  145. adam/commands/reaper/reaper_runs.py +14 -12
  146. adam/commands/reaper/reaper_runs_abort.py +2 -2
  147. adam/commands/reaper/reaper_schedule_activate.py +8 -4
  148. adam/commands/reaper/reaper_schedule_start.py +3 -4
  149. adam/commands/reaper/reaper_schedule_stop.py +3 -4
  150. adam/commands/reaper/reaper_schedules.py +2 -2
  151. adam/commands/reaper/reaper_status.py +2 -2
  152. adam/commands/reaper/utils_reaper.py +41 -6
  153. adam/commands/repair/repair_log.py +2 -2
  154. adam/commands/repair/repair_run.py +2 -2
  155. adam/commands/repair/repair_scan.py +2 -4
  156. adam/commands/repair/repair_stop.py +2 -3
  157. adam/commands/{show/show.py → show.py} +12 -11
  158. adam/config.py +4 -5
  159. adam/embedded_params.py +1 -1
  160. adam/repl.py +24 -10
  161. adam/repl_commands.py +68 -45
  162. adam/repl_session.py +16 -1
  163. adam/repl_state.py +16 -1
  164. adam/sql/async_executor.py +62 -0
  165. adam/sql/lark_completer.py +286 -0
  166. adam/sql/lark_parser.py +604 -0
  167. adam/sql/qingl.lark +1075 -0
  168. adam/sso/cred_cache.py +2 -5
  169. adam/utils.py +259 -82
  170. adam/utils_async_job.py +73 -0
  171. adam/utils_k8s/app_clusters.py +11 -4
  172. adam/utils_k8s/app_pods.py +10 -5
  173. adam/utils_k8s/cassandra_clusters.py +19 -7
  174. adam/utils_k8s/cassandra_nodes.py +16 -6
  175. adam/utils_k8s/k8s.py +9 -0
  176. adam/utils_k8s/kube_context.py +1 -4
  177. adam/{pod_exec_result.py → utils_k8s/pod_exec_result.py} +8 -2
  178. adam/utils_k8s/pods.py +189 -29
  179. adam/utils_k8s/statefulsets.py +5 -2
  180. adam/utils_local.py +78 -2
  181. adam/utils_repl/appendable_completer.py +6 -0
  182. adam/utils_repl/repl_completer.py +51 -4
  183. adam/utils_sqlite.py +3 -8
  184. adam/version.py +1 -1
  185. {kaqing-2.0.184.dist-info → kaqing-2.0.227.dist-info}/METADATA +1 -1
  186. kaqing-2.0.227.dist-info/RECORD +280 -0
  187. kaqing-2.0.227.dist-info/top_level.txt +2 -0
  188. teddy/__init__.py +0 -0
  189. teddy/lark_parser.py +436 -0
  190. teddy/lark_parser2.py +618 -0
  191. adam/commands/cql/cql_completions.py +0 -32
  192. adam/commands/export/export_select_x.py +0 -54
  193. adam/commands/logs.py +0 -37
  194. adam/commands/nodetool.py +0 -69
  195. adam/commands/postgres/psql_completions.py +0 -11
  196. adam/commands/report.py +0 -61
  197. adam/commands/restart.py +0 -60
  198. adam/commands/show/show_processes.py +0 -49
  199. adam/commands/show/show_storage.py +0 -42
  200. kaqing-2.0.184.dist-info/RECORD +0 -244
  201. kaqing-2.0.184.dist-info/top_level.txt +0 -1
  202. /adam/commands/{show → cassandra}/__init__.py +0 -0
  203. /adam/commands/{nodetool_commands.py → nodetool/nodetool_commands.py} +0 -0
  204. {kaqing-2.0.184.dist-info → kaqing-2.0.227.dist-info}/WHEEL +0 -0
  205. {kaqing-2.0.184.dist-info → kaqing-2.0.227.dist-info}/entry_points.txt +0 -0
@@ -3,9 +3,8 @@ import click
3
3
  from adam.commands import extract_trailing_options
4
4
  from adam.commands.command import Command
5
5
  from adam.commands.command_helpers import ClusterOrPodCommandHelper
6
- from adam.commands.cql.cql_completions import cql_completions
6
+ from adam.commands.cql.completions_c import completions_c
7
7
  from adam.commands.cql.utils_cql import cassandra
8
- from adam.utils_k8s.statefulsets import StatefulSets
9
8
  from adam.repl_state import ReplState, RequiredState
10
9
  from adam.utils import log
11
10
 
@@ -38,18 +37,15 @@ class Cqlsh(Command):
38
37
 
39
38
  def completion(self, state: ReplState) -> dict[str, any]:
40
39
  if state.device != state.C:
41
- # conflicts with psql completions
42
40
  return {}
43
41
 
44
42
  if state.sts or state.pod:
45
- c = cql_completions(state)
46
- return c | \
47
- {f'@{p}': c for p in StatefulSets.pod_names(state.sts, state.namespace)}
43
+ return completions_c(state)
48
44
 
49
45
  return {}
50
46
 
51
- def help(self, _: ReplState) -> str:
52
- return f'<cql-statements> [&]\t run cqlsh with queries'
47
+ def help(self, state: ReplState) -> str:
48
+ return super().help(state, 'run cqlsh with queries', command='[cql] <cql-statement>;...', args='[&]')
53
49
 
54
50
  class CqlCommandHelper(click.Command):
55
51
  def get_help(self, ctx: click.Context):
@@ -7,11 +7,19 @@ from adam.commands.commands_utils import show_table
7
7
  from adam.utils_k8s.cassandra_clusters import CassandraClusters
8
8
  from adam.utils_k8s.cassandra_nodes import CassandraNodes
9
9
  from adam.utils_k8s.secrets import Secrets
10
- from adam.pod_exec_result import PodExecResult
10
+ from adam.utils_k8s.pod_exec_result import PodExecResult
11
11
  from adam.repl_state import ReplState
12
- from adam.utils import log2, log_timing, wait_log
12
+ from adam.utils import ing, log2, log_timing, wait_log
13
13
  from adam.utils_k8s.statefulsets import StatefulSets
14
14
 
15
+ def cd_dirs(state: ReplState) -> list[str]:
16
+ if state.pod:
17
+ return [".."]
18
+ elif state.sts:
19
+ return [".."] + StatefulSets.pod_names(state.sts, state.namespace)
20
+ else:
21
+ return StatefulSets.list_sts_names()
22
+
15
23
  @functools.lru_cache()
16
24
  def cassandra_keyspaces(state: ReplState, on_any=True):
17
25
  if state.pod:
@@ -47,7 +55,7 @@ def table_spec(state: ReplState, table: str, on_any=False) -> 'TableSpec':
47
55
 
48
56
  return parse_cql_desc_table(r.stdout if state.pod else r[0].stdout)
49
57
 
50
- def run_cql(state: ReplState, cql: str, opts: list = [], show_out = False, show_query = False, use_single_quotes = False, on_any = False, backgrounded=False, log_file=None) -> list[PodExecResult]:
58
+ def run_cql(state: ReplState, cql: str, opts: list = [], show_out = False, show_query = False, use_single_quotes = False, on_any = False, backgrounded=False, log_file=None, history=True) -> list[PodExecResult]:
51
59
  if show_query:
52
60
  log2(cql)
53
61
 
@@ -61,7 +69,7 @@ def run_cql(state: ReplState, cql: str, opts: list = [], show_out = False, show_
61
69
 
62
70
  with log_timing(cql):
63
71
  with cassandra(state) as pods:
64
- return pods.exec(command, action='cql', show_out=show_out, on_any=on_any, backgrounded=backgrounded, log_file=log_file)
72
+ return pods.exec(command, action='cql', show_out=show_out, on_any=on_any, backgrounded=backgrounded, log_file=log_file, history=history)
65
73
 
66
74
  def parse_cql_desc_tables(out: str):
67
75
  # Keyspace data_endpoint_auth
@@ -219,16 +227,26 @@ class CassandraPodService:
219
227
  def __init__(self, handler: 'CassandraExecHandler'):
220
228
  self.handler = handler
221
229
 
222
- def exec(self, command: str, action='bash', show_out = True, on_any = False, throw_err = False, shell = '/bin/sh', backgrounded = False, log_file = None) -> Union[PodExecResult, list[PodExecResult]]:
230
+ def exec(self,
231
+ command: str,
232
+ action='bash',
233
+ show_out = True,
234
+ on_any = False,
235
+ throw_err = False,
236
+ shell = '/bin/sh',
237
+ backgrounded = False,
238
+ log_file = None,
239
+ history=True,
240
+ text_color: str = None) -> Union[PodExecResult, list[PodExecResult]]:
223
241
  state = self.handler.state
224
242
  pod = self.handler.pod
225
243
 
226
244
  if pod:
227
245
  return CassandraNodes.exec(pod, state.namespace, command,
228
- show_out=show_out, throw_err=throw_err, shell=shell, backgrounded=backgrounded, log_file=log_file)
246
+ show_out=show_out, throw_err=throw_err, shell=shell, backgrounded=backgrounded, log_file=log_file, history=history, text_color=text_color)
229
247
  elif state.sts:
230
248
  return CassandraClusters.exec(state.sts, state.namespace, command, action=action,
231
- show_out=show_out, on_any=on_any, shell=shell, backgrounded=backgrounded, log_file=log_file)
249
+ show_out=show_out, on_any=on_any, shell=shell, backgrounded=backgrounded, log_file=log_file, history=history, text_color=text_color)
232
250
 
233
251
  return []
234
252
 
@@ -259,16 +277,17 @@ class CassandraPodService:
259
277
 
260
278
  return run_cql(state, query, opts=opts, show_out=show_out, show_query=show_query, use_single_quotes=use_single_quotes, on_any=on_any, backgrounded=backgrounded, log_file=log_file)
261
279
 
262
- def display_table(self, cols: str, header: str, show_out = True):
280
+ def display_table(self, cols: str, header: str, show_out = True, backgrounded = False, msg: str = None):
263
281
  state = self.handler.state
264
282
 
265
- if state.pod:
266
- show_table(state, [state.pod], cols, header, show_out=show_out)
267
- elif state.sts:
268
- pod_names = [pod.metadata.name for pod in StatefulSets.pods(state.sts, state.namespace)]
269
- show_table(state, pod_names, cols, header, show_out=show_out)
283
+ with ing(msg=msg, condition=backgrounded and msg):
284
+ if state.pod:
285
+ return show_table(state, [state.pod], cols, header, show_out=show_out, backgrounded = backgrounded)
286
+ elif state.sts:
287
+ pod_names = [pod.metadata.name for pod in StatefulSets.pods(state.sts, state.namespace)]
288
+ return show_table(state, pod_names, cols, header, show_out=show_out, backgrounded = backgrounded)
270
289
 
271
- def nodetool(self, args: str, status = False, show_out = True) -> Union[PodExecResult, list[PodExecResult]]:
290
+ def nodetool(self, args: str, status = False, show_out = True, backgrounded = False) -> Union[PodExecResult, list[PodExecResult]]:
272
291
  state = self.handler.state
273
292
  pod = self.handler.pod
274
293
 
@@ -276,9 +295,9 @@ class CassandraPodService:
276
295
  command = f"nodetool -u {user} -pw {pw} {args}"
277
296
 
278
297
  if pod:
279
- return CassandraNodes.exec(pod, state.namespace, command, show_out=show_out)
298
+ return CassandraNodes.exec(pod, state.namespace, command, show_out=show_out, backgrounded=backgrounded)
280
299
  else:
281
- return CassandraClusters.exec(state.sts, state.namespace, command, action='nodetool.status' if status else 'nodetool', show_out=show_out)
300
+ return CassandraClusters.exec(state.sts, state.namespace, command, action='nodetool.status' if status else 'nodetool', show_out=show_out, backgrounded=backgrounded)
282
301
 
283
302
  class CassandraExecHandler:
284
303
  def __init__(self, state: ReplState, pod: str = None):
@@ -294,4 +313,4 @@ class CassandraExecHandler:
294
313
  return False
295
314
 
296
315
  def cassandra(state: ReplState, pod: str=None):
297
- return CassandraExecHandler(state, pod=pod)
316
+ return CassandraExecHandler(state, pod=pod)
File without changes
@@ -0,0 +1,22 @@
1
+ from adam.commands.command import Command
2
+ from adam.commands.debug.debug_completes import DebugCompletes
3
+ from adam.commands.debug.debug_timings import DebugTimings
4
+ from adam.commands.intermediate_command import IntermediateCommand
5
+
6
+ class Debug(IntermediateCommand):
7
+ COMMAND = 'debug'
8
+
9
+ # the singleton pattern
10
+ def __new__(cls, *args, **kwargs):
11
+ if not hasattr(cls, 'instance'): cls.instance = super(Debug, cls).__new__(cls)
12
+
13
+ return cls.instance
14
+
15
+ def __init__(self, successor: Command=None):
16
+ super().__init__(successor)
17
+
18
+ def command(self):
19
+ return Debug.COMMAND
20
+
21
+ def cmd_list(self):
22
+ return [DebugTimings(), DebugCompletes()]
@@ -0,0 +1,35 @@
1
+ from adam.commands import validate_args
2
+ from adam.commands.command import Command
3
+ from adam.config import Config
4
+ from adam.repl_state import ReplState
5
+
6
+ class DebugCompletes(Command):
7
+ COMMAND = 'debug completes'
8
+
9
+ # the singleton pattern
10
+ def __new__(cls, *args, **kwargs):
11
+ if not hasattr(cls, 'instance'): cls.instance = super(DebugCompletes, cls).__new__(cls)
12
+
13
+ return cls.instance
14
+
15
+ def __init__(self, successor: Command=None):
16
+ super().__init__(successor)
17
+
18
+ def command(self):
19
+ return DebugCompletes.COMMAND
20
+
21
+ def run(self, cmd: str, state: ReplState):
22
+ if not(args := self.args(cmd)):
23
+ return super().run(cmd, state)
24
+
25
+ with self.validate(args, state) as (args, state):
26
+ with validate_args(args, state, name='on, off or file') as args:
27
+ Config().set('debugs.complete', args)
28
+
29
+ return state
30
+
31
+ def completion(self, state: ReplState):
32
+ return super().completion(state, {f: None for f in ['on', 'off', 'file']})
33
+
34
+ def help(self, state: ReplState):
35
+ return super().help(state, 'turn auto complete debug on or off', args='on|off|file')
@@ -0,0 +1,35 @@
1
+ from adam.commands import validate_args
2
+ from adam.commands.command import Command
3
+ from adam.config import Config
4
+ from adam.repl_state import ReplState
5
+
6
+ class DebugTimings(Command):
7
+ COMMAND = 'debug timings'
8
+
9
+ # the singleton pattern
10
+ def __new__(cls, *args, **kwargs):
11
+ if not hasattr(cls, 'instance'): cls.instance = super(DebugTimings, cls).__new__(cls)
12
+
13
+ return cls.instance
14
+
15
+ def __init__(self, successor: Command=None):
16
+ super().__init__(successor)
17
+
18
+ def command(self):
19
+ return DebugTimings.COMMAND
20
+
21
+ def run(self, cmd: str, state: ReplState):
22
+ if not(args := self.args(cmd)):
23
+ return super().run(cmd, state)
24
+
25
+ with self.validate(args, state) as (args, state):
26
+ with validate_args(args, state, name='on, off or file') as args:
27
+ Config().set('debugs.timings', args)
28
+
29
+ return state
30
+
31
+ def completion(self, state: ReplState):
32
+ return super().completion(state, {f: None for f in ['on', 'off', 'file']})
33
+
34
+ def help(self, state: ReplState):
35
+ return super().help(state, 'turn timing debug on or off', args='on|off|file')
@@ -0,0 +1,45 @@
1
+ from adam.commands.command import Command
2
+ from adam.repl_state import ReplState
3
+ from adam.sql.async_executor import AsyncExecutor
4
+ from adam.utils import tabulize
5
+
6
+ class ShowOffloadedCompletes(Command):
7
+ COMMAND = 'show offloaded completes'
8
+
9
+ # the singleton pattern
10
+ def __new__(cls, *args, **kwargs):
11
+ if not hasattr(cls, 'instance'): cls.instance = super(ShowOffloadedCompletes, cls).__new__(cls)
12
+
13
+ return cls.instance
14
+
15
+ def __init__(self, successor: Command=None):
16
+ super().__init__(successor)
17
+
18
+ def command(self):
19
+ return ShowOffloadedCompletes.COMMAND
20
+
21
+ def run(self, cmd: str, state: ReplState):
22
+ if not(args := self.args(cmd)):
23
+ return super().run(cmd, state)
24
+
25
+ with self.validate(args, state) as (args, state):
26
+ pending, processed, first, last = AsyncExecutor.entries_in_queue()
27
+ lines = []
28
+ for k, v in processed.items():
29
+ lines.append(f'{k}\t{v:2.2f}')
30
+ for k in pending:
31
+ lines.append(f'{k}\tpending')
32
+ lines += [
33
+ f'---------------------------',
34
+ f'duration\t{last-first:2.2f}'
35
+ ]
36
+
37
+ tabulize(lines, header='key\tduration(in sec)', separator='\t')
38
+
39
+ return state
40
+
41
+ def completion(self, state: ReplState):
42
+ return super().completion(state)
43
+
44
+ def help(self, state: ReplState):
45
+ return super().help(state, 'show offloaded completes')
@@ -42,5 +42,5 @@ class CodeStart(Command):
42
42
 
43
43
  return {}
44
44
 
45
- def help(self, _: ReplState):
46
- return f'{CodeStart.COMMAND}\t start code server'
45
+ def help(self, state: ReplState):
46
+ return super().help(state, 'start code server')
@@ -36,5 +36,5 @@ class CodeStop(Command):
36
36
 
37
37
  return {}
38
38
 
39
- def help(self, _: ReplState):
40
- return f'{CodeStop.COMMAND}\t stop code server'
39
+ def help(self, state: ReplState):
40
+ return super().help(state, 'stop code server')
@@ -45,5 +45,5 @@ class DeployFrontend(Command):
45
45
  def completion(self, state: ReplState):
46
46
  return super().completion(state)
47
47
 
48
- def help(self, _: ReplState):
49
- return f'{DeployFrontend.COMMAND}\t deploy Web frontend'
48
+ def help(self, state: ReplState):
49
+ return super().help(state, 'deploy Web frontend')
@@ -31,5 +31,5 @@ class DeployPgAgent(Command):
31
31
  def completion(self, state: ReplState):
32
32
  return super().completion(state)
33
33
 
34
- def help(self, _: ReplState):
35
- return f'{DeployPgAgent.COMMAND}\t deploy Postgres agent'
34
+ def help(self, state: ReplState):
35
+ return super().help(state, 'deploy Postgres agent')
@@ -102,5 +102,5 @@ class DeployPod(Command):
102
102
  def completion(self, state: ReplState):
103
103
  return super().completion(state, {'--force': None})
104
104
 
105
- def help(self, _: ReplState):
106
- return f'{DeployPod.COMMAND} [--force]\t deploy Ops pod, --force to undeploy first'
105
+ def help(self, state: ReplState):
106
+ return super().help(state, 'deploy Ops pod --force to undeploy first', args='[--force]')
@@ -34,5 +34,5 @@ class UndeployFrontend(Command):
34
34
  def completion(self, state: ReplState):
35
35
  return super().completion(state)
36
36
 
37
- def help(self, _: ReplState):
38
- return f'{UndeployFrontend.COMMAND}\t undeploy Web frontend'
37
+ def help(self, state: ReplState):
38
+ return super().help(state, 'undeploy Web frontend')
@@ -35,5 +35,5 @@ class UndeployPgAgent(Command):
35
35
  def completion(self, state: ReplState):
36
36
  return super().completion(state)
37
37
 
38
- def help(self, _: ReplState):
39
- return f'{UndeployPgAgent.COMMAND}\t undeploy Postgres agent'
38
+ def help(self, state: ReplState):
39
+ return super().help(state, 'undeploy Postgres agent')
@@ -44,5 +44,5 @@ class UndeployPod(Command):
44
44
  def completion(self, state: ReplState):
45
45
  return super().completion(state)
46
46
 
47
- def help(self, _: ReplState):
48
- return f'{UndeployPod.COMMAND}\t undeploy Ops pod'
47
+ def help(self, state: ReplState):
48
+ return super().help(state, 'undeploy Ops pod')
@@ -2,13 +2,23 @@ from abc import abstractmethod
2
2
 
3
3
  from adam.commands.command import Command
4
4
  from adam.config import Config
5
- from adam.pod_exec_result import PodExecResult
5
+ from adam.utils_k8s.pod_exec_result import PodExecResult
6
6
  from adam.repl_state import BashSession, ReplState
7
7
  from adam.utils import log2
8
+ from adam.utils_k8s.pods import Pods
8
9
 
9
10
  class Device:
10
- def pods(self, state: ReplState) -> tuple[list[str], str]:
11
- return self.pod_names(state), self.pod(state)
11
+ def pods(self, state: ReplState, me: str = None) -> tuple[list[str], str]:
12
+ return self.pod_names(state), me if me else self.pod(state)
13
+
14
+ def default_pod(self, state: ReplState) -> tuple[list[str], str]:
15
+ if me := self.pod(state):
16
+ return me
17
+
18
+ if pods := self.pod_names(state):
19
+ return pods[0]
20
+
21
+ return None
12
22
 
13
23
  def pod(self, state: ReplState) -> str:
14
24
  return None
@@ -32,6 +42,9 @@ class Device:
32
42
  def cd_completion(self, cmd: str, state: ReplState, default: dict = {}):
33
43
  return default
34
44
 
45
+ def direct_dirs(self, cmd: str, state: ReplState, default: dict = {}) -> list[str]:
46
+ return []
47
+
35
48
  @abstractmethod
36
49
  def pwd(self, state: ReplState):
37
50
  pass
@@ -70,12 +83,12 @@ class Device:
70
83
  def show_table_preview(self, state: ReplState, table: str, rows: int):
71
84
  pass
72
85
 
73
- def bash(self, s0: ReplState, s1: ReplState, args: list[str]):
86
+ def bash(self, s0: ReplState, s1: ReplState, args: list[str], text_color: str = None):
74
87
  if s1.in_repl:
75
88
  if self.bash_target_changed(s0, s1):
76
- r = self._exec_with_dir(s1, args)
89
+ r = self._exec_with_dir(s1, args, text_color=text_color)
77
90
  else:
78
- r = self._exec_with_dir(s0, args)
91
+ r = self._exec_with_dir(s0, args, text_color=text_color)
79
92
 
80
93
  if not r:
81
94
  s1.exit_bash()
@@ -88,7 +101,7 @@ class Device:
88
101
 
89
102
  return s1
90
103
 
91
- def _exec_with_dir(self, state: ReplState, args: list[str]) -> list[PodExecResult]:
104
+ def _exec_with_dir(self, state: ReplState, args: list[str], text_color: str = None) -> list[PodExecResult]:
92
105
  session_just_created = False
93
106
  if not args:
94
107
  session_just_created = True
@@ -105,19 +118,32 @@ class Device:
105
118
  if pwd := state.bash_session.pwd(state):
106
119
  args = ['cd', pwd, '&&'] + args
107
120
 
108
- return self.exec_with_dir(' '.join(args), session_just_created, state)
121
+ return self.exec_with_dir(' '.join(args), session_just_created, state, text_color=text_color)
109
122
 
110
123
  @abstractmethod
111
124
  def bash_target_changed(self, s0: ReplState, s1: ReplState):
112
125
  pass
113
126
 
114
127
  @abstractmethod
115
- def exec_no_dir(self, command: str, state: ReplState):
128
+ def exec_no_dir(self, command: str, state: ReplState, text_color: str = None):
116
129
  pass
117
130
 
118
131
  @abstractmethod
119
- def exec_with_dir(self, command: str, session_just_created: bool, state: ReplState):
132
+ def exec_with_dir(self, command: str, session_just_created: bool, state: ReplState, text_color: str = None):
120
133
  pass
121
134
 
122
135
  def bash_completion(self, cmd: str, state: ReplState, default: dict = {}):
123
- return default
136
+ return default
137
+
138
+ def files(self, state: ReplState):
139
+ r: PodExecResult = Pods.exec(self.default_pod(state), self.default_container(state), state.namespace, f'find -maxdepth 1 -type f', show_out=Config().is_debug(), shell='bash')
140
+
141
+ log_files = []
142
+ for line in r.stdout.split('\n'):
143
+ line = line.strip(' \r')
144
+ if line:
145
+ if line.startswith('./'):
146
+ line = line[2:]
147
+ log_files.append(line)
148
+
149
+ return log_files
@@ -35,8 +35,8 @@ class DeviceApp(Command, Device):
35
35
  def completion(self, state: ReplState):
36
36
  return super().completion(state)
37
37
 
38
- def help(self, _: ReplState):
39
- return f'{DeviceApp.COMMAND}\t move to App Operations device'
38
+ def help(self, state: ReplState):
39
+ return super().help(state, 'move to App Operations device')
40
40
 
41
41
  def pod(self, state: ReplState) -> str:
42
42
  return state.app_pod
@@ -116,7 +116,7 @@ class DeviceApp(Command, Device):
116
116
  if state.app_app:
117
117
  words.append(f'app/{state.app_app}')
118
118
 
119
- return '\t'.join([f'{ReplState.X}:>'] + (words if words else ['/']))
119
+ return '\t'.join([f'{ReplState.A}:>'] + (words if words else ['/']))
120
120
 
121
121
  def try_fallback_action(self, chain: Command, state: ReplState, cmd: str):
122
122
  if state.app_app:
@@ -150,13 +150,13 @@ class DeviceApp(Command, Device):
150
150
  def bash_target_changed(self, s0: ReplState, s1: ReplState):
151
151
  return s0.app_env != s1.app_env or s0.app_app != s1.app_app or s0.app_pod != s1.app_pod
152
152
 
153
- def exec_no_dir(self, command: str, state: ReplState):
153
+ def exec_no_dir(self, command: str, state: ReplState, text_color: str = None):
154
154
  with app(state) as pods:
155
- return pods.exec(command)
155
+ return pods.exec(command, text_color=text_color)
156
156
 
157
- def exec_with_dir(self, command: str, session_just_created: bool, state: ReplState):
157
+ def exec_with_dir(self, command: str, session_just_created: bool, state: ReplState, text_color: str = None):
158
158
  with app(state) as pods:
159
- return pods.exec(command, not session_just_created)
159
+ return pods.exec(command, not session_just_created, text_color=text_color)
160
160
 
161
161
  def bash_completion(self, cmd: str, state: ReplState, default: dict = {}):
162
162
  return {cmd: BashCompleter(lambda: [])} | \
@@ -30,8 +30,8 @@ class DeviceAuditLog(Command, Device):
30
30
  def completion(self, state: ReplState):
31
31
  return super().completion(state)
32
32
 
33
- def help(self, _: ReplState):
34
- return f'{DeviceAuditLog.COMMAND}\t move to Audit Log Operations device'
33
+ def help(self, state: ReplState):
34
+ return super().help(state, 'move to Audit Log Operations device')
35
35
 
36
36
  def ls(self, cmd: str, _: ReplState):
37
37
  tabulize(Athena.table_names(), header='NAME', separator=',')
@@ -43,8 +43,8 @@ class DeviceCass(Command, Device):
43
43
  def completion(self, state: ReplState):
44
44
  return super().completion(state)
45
45
 
46
- def help(self, _: ReplState):
47
- return f'{DeviceCass.COMMAND}\t move to Cassandra Operations device'
46
+ def help(self, state: ReplState):
47
+ return super().help(state, 'move to Cassandra Operations device')
48
48
 
49
49
  def default_container(self, _: ReplState) -> str:
50
50
  return 'cassandra'
@@ -161,13 +161,13 @@ class DeviceCass(Command, Device):
161
161
  def bash_target_changed(self, s0: ReplState, s1: ReplState):
162
162
  return s0.sts != s1.sts or s0.pod != s1.pod
163
163
 
164
- def exec_no_dir(self, command: str, state: ReplState):
164
+ def exec_no_dir(self, command: str, state: ReplState, text_color: str = None):
165
165
  with cassandra(state) as pods:
166
- return pods.exec(command, action='bash', show_out=True, shell='bash')
166
+ return pods.exec(command, action='bash', show_out=True, shell='bash', text_color=text_color)
167
167
 
168
- def exec_with_dir(self, command: str, session_just_created: bool, state: ReplState):
168
+ def exec_with_dir(self, command: str, session_just_created: bool, state: ReplState, text_color: str = None):
169
169
  with cassandra(state) as pods:
170
- return pods.exec(command, action='bash', show_out=not session_just_created, shell='bash')
170
+ return pods.exec(command, action='bash', show_out=not session_just_created, shell='bash', text_color=text_color)
171
171
 
172
172
  def bash_completion(self, cmd: str, state: ReplState, default: dict = {}):
173
173
  completions = {cmd: BashCompleter(lambda: [])}
@@ -3,7 +3,7 @@ from adam.commands.devices.device import Device
3
3
  from adam.commands.export.export_databases import ExportDatabases, export_db
4
4
  from adam.config import Config
5
5
  from adam.repl_state import ReplState
6
- from adam.utils import tabulize, log, log2, wait_log
6
+ from adam.utils import tabulize, log2, wait_log
7
7
 
8
8
  class DeviceExport(Command, Device):
9
9
  COMMAND = f'{ReplState.X}:'
@@ -31,8 +31,8 @@ class DeviceExport(Command, Device):
31
31
  def completion(self, state: ReplState):
32
32
  return super().completion(state)
33
33
 
34
- def help(self, _: ReplState):
35
- return f'{DeviceExport.COMMAND}\t move to Export Database Operations device'
34
+ def help(self, state: ReplState):
35
+ return super().help(state, 'Export Database Operations device')
36
36
 
37
37
  def ls(self, cmd: str, state: ReplState):
38
38
  if state.export_session:
@@ -66,7 +66,10 @@ class DeviceExport(Command, Device):
66
66
  return '\t'.join([f'{ReplState.X}:>'] + (words if words else ['/']))
67
67
 
68
68
  def try_fallback_action(self, chain: Command, state: ReplState, cmd: str):
69
- result = chain.run(f'.{cmd}', state)
69
+ if cmd.startswith('select '):
70
+ cmd = f'xelect {cmd[7:]}'
71
+
72
+ result = chain.run(cmd, state)
70
73
  if type(result) is ReplState:
71
74
  if state.export_session and not result.export_session:
72
75
  state.export_session = None
@@ -32,8 +32,8 @@ class DevicePostgres(Command, Device):
32
32
  def completion(self, state: ReplState):
33
33
  return super().completion(state)
34
34
 
35
- def help(self, _: ReplState):
36
- return f'{DevicePostgres.COMMAND}\t move to Postgres Operations device'
35
+ def help(self, state: ReplState):
36
+ return super().help(state, 'move to Postgres Operations device')
37
37
 
38
38
  def pod(self, state: ReplState) -> str:
39
39
  pod, _ = PostgresDatabases.pod_and_container(state.namespace)
@@ -47,6 +47,10 @@ class DevicePostgres(Command, Device):
47
47
  return container
48
48
 
49
49
  def ls(self, cmd: str, state: ReplState):
50
+ if state.pod_targetted:
51
+ self.bash(state, state, ['ls'])
52
+ return
53
+
50
54
  with pg_path(state) as (host, database):
51
55
  if database:
52
56
  tabulize(pg_table_names(state), header='NAME', separator=',')
@@ -94,13 +98,16 @@ class DevicePostgres(Command, Device):
94
98
  state.pg_path = host
95
99
 
96
100
  def cd_completion(self, cmd: str, state: ReplState, default: dict = {}):
101
+ return {cmd: {d: None for d in self.direct_dirs(cmd, state, default=default)}}
102
+
103
+ def direct_dirs(self, cmd: str, state: ReplState, default: dict = {}) -> list[str]:
97
104
  with pg_path(state) as (host, database):
98
105
  if database:
99
- return {cmd: {'..': None}}
106
+ return ['..']
100
107
  elif host:
101
- return {cmd: {'..': None} | {p: None for p in pg_database_names(state)}}
108
+ return ['..'] + [p for p in pg_database_names(state)]
102
109
  else:
103
- return {cmd: {p: None for p in PostgresDatabases.host_names(state.namespace)}}
110
+ return [p for p in PostgresDatabases.host_names(state.namespace)]
104
111
 
105
112
  def pwd(self, state: ReplState):
106
113
  words = []
@@ -115,6 +122,9 @@ class DevicePostgres(Command, Device):
115
122
 
116
123
  def try_fallback_action(self, chain: Command, state: ReplState, cmd: str):
117
124
  with pg_path(state) as (_, database):
125
+ if not database:
126
+ database = PostgresDatabases.default_db()
127
+
118
128
  if database:
119
129
  return True, chain.run(f'pg {cmd}', state)
120
130
 
@@ -138,13 +148,13 @@ class DevicePostgres(Command, Device):
138
148
  def bash_target_changed(self, s0: ReplState, s1: ReplState):
139
149
  return s0.pg_path != s1.pg_path
140
150
 
141
- def exec_no_dir(self, command: str, state: ReplState):
151
+ def exec_no_dir(self, command: str, state: ReplState, text_color: str = None):
142
152
  with postgres(state) as pod:
143
- return pod.exec(command, show_out=True)
153
+ return pod.exec(command, show_out=True, text_color=text_color)
144
154
 
145
- def exec_with_dir(self, command: str, session_just_created: bool, state: ReplState):
155
+ def exec_with_dir(self, command: str, session_just_created: bool, state: ReplState, text_color: str = None):
146
156
  with postgres(state) as pod:
147
- return pod.exec(command, show_out=not session_just_created)
157
+ return pod.exec(command, show_out=not session_just_created, text_color=text_color)
148
158
 
149
159
  def bash_completion(self, cmd: str, state: ReplState, default: dict = {}):
150
160
  return {cmd: BashCompleter(lambda: [])}
@@ -7,7 +7,7 @@ from adam.commands.devices.device_postgres import DevicePostgres
7
7
  from adam.repl_state import ReplState
8
8
 
9
9
  class Devices:
10
- def device(state: ReplState) -> Device:
10
+ def of(state: ReplState) -> Device:
11
11
  if state.device == ReplState.A:
12
12
  return DeviceApp()
13
13
  elif state.device == ReplState.C:
File without changes