kaqing 2.0.14__py3-none-any.whl → 2.0.189__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.
- adam/__init__.py +0 -2
- adam/app_session.py +9 -12
- adam/apps.py +20 -6
- adam/batch.py +16 -6
- adam/checks/check_utils.py +19 -49
- adam/checks/compactionstats.py +1 -1
- adam/checks/cpu.py +9 -3
- adam/checks/cpu_metrics.py +52 -0
- adam/checks/disk.py +3 -4
- adam/checks/gossip.py +1 -1
- adam/checks/memory.py +3 -3
- adam/checks/status.py +1 -1
- adam/columns/columns.py +3 -1
- adam/columns/cpu.py +3 -1
- adam/columns/cpu_metrics.py +22 -0
- adam/columns/memory.py +3 -4
- adam/commands/__init__.py +24 -0
- adam/commands/alter_tables.py +66 -0
- adam/commands/app/app.py +38 -0
- adam/commands/{app_ping.py → app/app_ping.py} +8 -14
- adam/commands/app/show_app_actions.py +49 -0
- adam/commands/{show → app}/show_app_id.py +9 -12
- adam/commands/{show → app}/show_app_queues.py +8 -14
- adam/commands/app/utils_app.py +106 -0
- adam/commands/audit/__init__.py +0 -0
- adam/commands/audit/audit.py +67 -0
- adam/commands/audit/audit_repair_tables.py +72 -0
- adam/commands/audit/audit_run.py +50 -0
- adam/commands/audit/completions_l.py +15 -0
- adam/commands/audit/show_last10.py +36 -0
- adam/commands/audit/show_slow10.py +36 -0
- adam/commands/audit/show_top10.py +36 -0
- adam/commands/audit/utils_show_top10.py +71 -0
- adam/commands/bash/__init__.py +5 -0
- adam/commands/bash/bash.py +36 -0
- adam/commands/bash/bash_completer.py +93 -0
- adam/commands/bash/utils_bash.py +16 -0
- adam/commands/cat.py +36 -0
- adam/commands/cd.py +14 -88
- adam/commands/check.py +18 -21
- adam/commands/cli_commands.py +11 -7
- adam/commands/clipboard_copy.py +87 -0
- adam/commands/code.py +57 -0
- adam/commands/command.py +220 -19
- adam/commands/commands_utils.py +28 -31
- adam/commands/cql/__init__.py +0 -0
- adam/commands/cql/completions_c.py +28 -0
- adam/commands/{cqlsh.py → cql/cqlsh.py} +13 -32
- adam/commands/cql/utils_cql.py +305 -0
- adam/commands/deploy/code_start.py +7 -10
- adam/commands/deploy/code_stop.py +4 -21
- adam/commands/deploy/code_utils.py +5 -5
- adam/commands/deploy/deploy.py +4 -40
- adam/commands/deploy/deploy_frontend.py +15 -18
- adam/commands/deploy/deploy_pg_agent.py +4 -7
- adam/commands/deploy/deploy_pod.py +74 -77
- adam/commands/deploy/deploy_utils.py +16 -26
- adam/commands/deploy/undeploy.py +4 -40
- adam/commands/deploy/undeploy_frontend.py +5 -8
- adam/commands/deploy/undeploy_pg_agent.py +7 -8
- adam/commands/deploy/undeploy_pod.py +16 -17
- adam/commands/devices/__init__.py +0 -0
- adam/commands/devices/device.py +149 -0
- adam/commands/devices/device_app.py +163 -0
- adam/commands/devices/device_auit_log.py +49 -0
- adam/commands/devices/device_cass.py +179 -0
- adam/commands/devices/device_export.py +87 -0
- adam/commands/devices/device_postgres.py +160 -0
- adam/commands/devices/devices.py +25 -0
- adam/commands/download_file.py +47 -0
- adam/commands/exit.py +1 -4
- adam/commands/export/__init__.py +0 -0
- adam/commands/export/clean_up_all_export_sessions.py +37 -0
- adam/commands/export/clean_up_export_sessions.py +39 -0
- adam/commands/export/completions_x.py +11 -0
- adam/commands/export/download_export_session.py +40 -0
- adam/commands/export/drop_export_database.py +39 -0
- adam/commands/export/drop_export_databases.py +37 -0
- adam/commands/export/export.py +37 -0
- adam/commands/export/export_databases.py +246 -0
- adam/commands/export/export_select.py +34 -0
- adam/commands/export/export_sessions.py +209 -0
- adam/commands/export/export_use.py +49 -0
- adam/commands/export/export_x_select.py +48 -0
- adam/commands/export/exporter.py +332 -0
- adam/commands/export/import_files.py +44 -0
- adam/commands/export/import_session.py +44 -0
- adam/commands/export/importer.py +81 -0
- adam/commands/export/importer_athena.py +148 -0
- adam/commands/export/importer_sqlite.py +67 -0
- adam/commands/export/show_column_counts.py +45 -0
- adam/commands/export/show_export_databases.py +39 -0
- adam/commands/export/show_export_session.py +39 -0
- adam/commands/export/show_export_sessions.py +37 -0
- adam/commands/export/utils_export.py +344 -0
- adam/commands/find_files.py +51 -0
- adam/commands/find_processes.py +76 -0
- adam/commands/head.py +36 -0
- adam/commands/help.py +14 -9
- adam/commands/intermediate_command.py +52 -0
- adam/commands/issues.py +14 -40
- adam/commands/kubectl.py +38 -0
- adam/commands/login.py +26 -25
- adam/commands/logs.py +5 -7
- adam/commands/ls.py +11 -115
- adam/commands/medusa/medusa.py +4 -46
- adam/commands/medusa/medusa_backup.py +22 -29
- adam/commands/medusa/medusa_restore.py +51 -49
- adam/commands/medusa/medusa_show_backupjobs.py +20 -21
- adam/commands/medusa/medusa_show_restorejobs.py +16 -21
- adam/commands/medusa/utils_medusa.py +15 -0
- adam/commands/nodetool.py +8 -17
- adam/commands/param_get.py +11 -14
- adam/commands/param_set.py +9 -13
- adam/commands/postgres/completions_p.py +22 -0
- adam/commands/postgres/postgres.py +49 -73
- adam/commands/postgres/postgres_databases.py +270 -0
- adam/commands/postgres/postgres_ls.py +4 -8
- adam/commands/postgres/postgres_preview.py +5 -9
- adam/commands/postgres/utils_postgres.py +79 -0
- adam/commands/preview_table.py +10 -69
- adam/commands/pwd.py +14 -43
- adam/commands/reaper/reaper.py +6 -49
- adam/commands/reaper/reaper_forward.py +49 -56
- adam/commands/reaper/reaper_forward_session.py +6 -0
- adam/commands/reaper/reaper_forward_stop.py +10 -16
- adam/commands/reaper/reaper_restart.py +8 -15
- adam/commands/reaper/reaper_run_abort.py +8 -33
- adam/commands/reaper/reaper_runs.py +43 -58
- adam/commands/reaper/reaper_runs_abort.py +29 -49
- adam/commands/reaper/reaper_schedule_activate.py +14 -33
- adam/commands/reaper/reaper_schedule_start.py +9 -33
- adam/commands/reaper/reaper_schedule_stop.py +9 -33
- adam/commands/reaper/reaper_schedules.py +4 -14
- adam/commands/reaper/reaper_status.py +8 -16
- adam/commands/reaper/utils_reaper.py +203 -0
- adam/commands/repair/repair.py +4 -46
- adam/commands/repair/repair_log.py +6 -12
- adam/commands/repair/repair_run.py +29 -36
- adam/commands/repair/repair_scan.py +33 -41
- adam/commands/repair/repair_stop.py +6 -13
- adam/commands/report.py +25 -21
- adam/commands/restart.py +27 -28
- adam/commands/rollout.py +20 -25
- adam/commands/shell.py +12 -4
- adam/commands/show/show.py +15 -46
- adam/commands/show/show_adam.py +3 -3
- adam/commands/show/show_cassandra_repairs.py +37 -0
- adam/commands/show/show_cassandra_status.py +48 -52
- adam/commands/show/show_cassandra_version.py +5 -18
- adam/commands/show/show_cli_commands.py +56 -0
- adam/commands/show/show_host.py +33 -0
- adam/commands/show/show_login.py +23 -27
- adam/commands/show/show_params.py +2 -5
- adam/commands/show/show_processes.py +18 -21
- adam/commands/show/show_storage.py +11 -20
- adam/commands/watch.py +27 -30
- adam/config.py +8 -6
- adam/embedded_params.py +1 -1
- adam/log.py +4 -4
- adam/pod_exec_result.py +13 -5
- adam/repl.py +136 -120
- adam/repl_commands.py +66 -24
- adam/repl_session.py +8 -1
- adam/repl_state.py +343 -73
- adam/sql/__init__.py +0 -0
- adam/sql/lark_completer.py +284 -0
- adam/sql/lark_parser.py +604 -0
- adam/sql/sql_completer.py +118 -0
- adam/sql/sql_state_machine.py +630 -0
- adam/sql/term_completer.py +76 -0
- adam/sso/authn_ad.py +7 -9
- adam/sso/authn_okta.py +4 -6
- adam/sso/cred_cache.py +4 -6
- adam/sso/idp.py +10 -13
- adam/utils.py +539 -11
- adam/utils_athena.py +145 -0
- adam/utils_audits.py +102 -0
- adam/utils_issues.py +32 -0
- adam/utils_k8s/__init__.py +0 -0
- adam/utils_k8s/app_clusters.py +28 -0
- adam/utils_k8s/app_pods.py +36 -0
- adam/utils_k8s/cassandra_clusters.py +44 -0
- adam/{k8s_utils → utils_k8s}/cassandra_nodes.py +12 -5
- adam/{k8s_utils → utils_k8s}/custom_resources.py +16 -17
- adam/{k8s_utils → utils_k8s}/deployment.py +2 -2
- adam/{k8s_utils → utils_k8s}/ingresses.py +2 -2
- adam/{k8s_utils → utils_k8s}/jobs.py +7 -11
- adam/utils_k8s/k8s.py +96 -0
- adam/{k8s_utils → utils_k8s}/kube_context.py +3 -3
- adam/{k8s_utils → utils_k8s}/pods.py +132 -83
- adam/{k8s_utils → utils_k8s}/secrets.py +7 -3
- adam/{k8s_utils → utils_k8s}/service_accounts.py +5 -4
- adam/{k8s_utils → utils_k8s}/services.py +2 -2
- adam/{k8s_utils → utils_k8s}/statefulsets.py +9 -16
- adam/utils_local.py +4 -0
- adam/utils_net.py +24 -0
- adam/utils_repl/__init__.py +0 -0
- adam/utils_repl/appendable_completer.py +6 -0
- adam/utils_repl/automata_completer.py +48 -0
- adam/utils_repl/repl_completer.py +172 -0
- adam/utils_repl/state_machine.py +173 -0
- adam/utils_sqlite.py +137 -0
- adam/version.py +1 -1
- {kaqing-2.0.14.dist-info → kaqing-2.0.189.dist-info}/METADATA +1 -1
- kaqing-2.0.189.dist-info/RECORD +253 -0
- kaqing-2.0.189.dist-info/top_level.txt +2 -0
- teddy/__init__.py +0 -0
- teddy/lark_parser.py +436 -0
- teddy/lark_parser2.py +618 -0
- adam/commands/app.py +0 -67
- adam/commands/bash.py +0 -87
- adam/commands/cp.py +0 -95
- adam/commands/cql_utils.py +0 -53
- adam/commands/devices.py +0 -89
- adam/commands/postgres/postgres_session.py +0 -247
- adam/commands/reaper/reaper_session.py +0 -159
- adam/commands/show/show_app_actions.py +0 -53
- adam/commands/show/show_commands.py +0 -61
- adam/commands/show/show_repairs.py +0 -47
- adam/k8s_utils/cassandra_clusters.py +0 -48
- kaqing-2.0.14.dist-info/RECORD +0 -167
- kaqing-2.0.14.dist-info/top_level.txt +0 -1
- /adam/{k8s_utils → commands/app}/__init__.py +0 -0
- /adam/{k8s_utils → utils_k8s}/config_maps.py +0 -0
- /adam/{k8s_utils → utils_k8s}/volumes.py +0 -0
- {kaqing-2.0.14.dist-info → kaqing-2.0.189.dist-info}/WHEEL +0 -0
- {kaqing-2.0.14.dist-info → kaqing-2.0.189.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
|
|
3
|
+
from adam.commands.postgres.postgres_databases import PostgresDatabases, pg_path
|
|
4
|
+
from adam.repl_state import ReplState
|
|
5
|
+
from adam.utils import log2, wait_log
|
|
6
|
+
from adam.utils_k8s.pods import Pods
|
|
7
|
+
|
|
8
|
+
TestPG = [False]
|
|
9
|
+
|
|
10
|
+
def direct_dirs(state: ReplState) -> list[str]:
|
|
11
|
+
with pg_path(state) as (host, database):
|
|
12
|
+
if database:
|
|
13
|
+
return ['..']
|
|
14
|
+
elif host:
|
|
15
|
+
return ['..'] + pg_database_names(state)
|
|
16
|
+
else:
|
|
17
|
+
return PostgresDatabases.host_names(state.namespace)
|
|
18
|
+
|
|
19
|
+
def pg_database_names(state: ReplState):
|
|
20
|
+
# cache on pg_path
|
|
21
|
+
return _pg_database_names(state, state.pg_path)
|
|
22
|
+
|
|
23
|
+
@functools.lru_cache()
|
|
24
|
+
def _pg_database_names(state: ReplState, pg_path: str):
|
|
25
|
+
if TestPG[0]:
|
|
26
|
+
return ['azops88_c3ai_c3']
|
|
27
|
+
|
|
28
|
+
wait_log('Inspecting Postgres Databases...')
|
|
29
|
+
|
|
30
|
+
return [db['name'] for db in PostgresDatabases.databases(state, default_owner=True)]
|
|
31
|
+
|
|
32
|
+
def pg_table_names(state: ReplState):
|
|
33
|
+
# cache on pg_path
|
|
34
|
+
return _pg_table_names(state, state.pg_path)
|
|
35
|
+
|
|
36
|
+
@functools.lru_cache()
|
|
37
|
+
def _pg_table_names(state: ReplState, pg_path: str):
|
|
38
|
+
if TestPG[0]:
|
|
39
|
+
return ['C3_2_XYZ1']
|
|
40
|
+
|
|
41
|
+
wait_log('Inspecting Postgres Database...')
|
|
42
|
+
return [table['name'] for table in PostgresDatabases.tables(state, default_schema=True)]
|
|
43
|
+
|
|
44
|
+
class PostgresPodService:
|
|
45
|
+
def __init__(self, handler: 'PostgresExecHandler'):
|
|
46
|
+
self.handler = handler
|
|
47
|
+
|
|
48
|
+
def exec(self, command: str, show_out=True):
|
|
49
|
+
state = self.handler.state
|
|
50
|
+
|
|
51
|
+
pod, container = PostgresDatabases.pod_and_container(state.namespace)
|
|
52
|
+
if not pod:
|
|
53
|
+
log2('Cannot locate postgres agent or ops pod.')
|
|
54
|
+
return state
|
|
55
|
+
|
|
56
|
+
return Pods.exec(pod, container, state.namespace, command, show_out=show_out)
|
|
57
|
+
|
|
58
|
+
def sql(self, args: list[str], backgrounded=False):
|
|
59
|
+
state = self.handler.state
|
|
60
|
+
|
|
61
|
+
query = args
|
|
62
|
+
if isinstance(args, list):
|
|
63
|
+
query = ' '.join(args)
|
|
64
|
+
|
|
65
|
+
PostgresDatabases.run_sql(state, query, backgrounded=backgrounded)
|
|
66
|
+
|
|
67
|
+
class PostgresExecHandler:
|
|
68
|
+
def __init__(self, state: ReplState, backgrounded=False):
|
|
69
|
+
self.state = state
|
|
70
|
+
self.backgrounded = backgrounded
|
|
71
|
+
|
|
72
|
+
def __enter__(self):
|
|
73
|
+
return PostgresPodService(self)
|
|
74
|
+
|
|
75
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
76
|
+
return False
|
|
77
|
+
|
|
78
|
+
def postgres(state: ReplState, backgrounded=False):
|
|
79
|
+
return PostgresExecHandler(state, backgrounded=backgrounded)
|
adam/commands/preview_table.py
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from adam.commands import validate_args
|
|
3
2
|
from adam.commands.command import Command
|
|
4
|
-
from adam.commands.
|
|
5
|
-
from adam.commands.postgres.postgres_session import PostgresSession
|
|
6
|
-
from adam.config import Config
|
|
7
|
-
from adam.pod_exec_result import PodExecResult
|
|
3
|
+
from adam.commands.devices.devices import Devices
|
|
8
4
|
from adam.repl_state import ReplState, RequiredState
|
|
9
|
-
from adam.utils import lines_to_tabular, log, log2
|
|
10
5
|
|
|
11
6
|
class PreviewTable(Command):
|
|
12
7
|
COMMAND = 'preview'
|
|
@@ -24,75 +19,21 @@ class PreviewTable(Command):
|
|
|
24
19
|
return PreviewTable.COMMAND
|
|
25
20
|
|
|
26
21
|
def required(self):
|
|
27
|
-
return RequiredState.CLUSTER_OR_POD
|
|
22
|
+
return [RequiredState.CLUSTER_OR_POD, RequiredState.PG_DATABASE, ReplState.L, RequiredState.EXPORT_DB]
|
|
28
23
|
|
|
29
24
|
def run(self, cmd: str, state: ReplState):
|
|
30
25
|
if not(args := self.args(cmd)):
|
|
31
26
|
return super().run(cmd, state)
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return state
|
|
37
|
-
else:
|
|
38
|
-
if not self.validate_state(state):
|
|
39
|
-
return state
|
|
40
|
-
|
|
41
|
-
if not args:
|
|
42
|
-
def show_tables():
|
|
43
|
-
if state.device == ReplState.P:
|
|
44
|
-
pg = PostgresSession(state.namespace, state.pg_path)
|
|
45
|
-
lines = [db["name"] for db in pg.tables() if db["schema"] == PostgresSession.default_schema()]
|
|
46
|
-
log(lines_to_tabular(lines, separator=','))
|
|
47
|
-
else:
|
|
48
|
-
run_cql(state, f'describe tables', show_out=True)
|
|
49
|
-
|
|
50
|
-
if state.in_repl:
|
|
51
|
-
log2('Table is required.')
|
|
52
|
-
log2()
|
|
53
|
-
log2('Tables:')
|
|
54
|
-
show_tables()
|
|
55
|
-
else:
|
|
56
|
-
log2('* Table is missing.')
|
|
57
|
-
show_tables()
|
|
58
|
-
|
|
59
|
-
Command.display_help()
|
|
60
|
-
|
|
61
|
-
return 'command-missing'
|
|
62
|
-
|
|
63
|
-
table = args[0]
|
|
28
|
+
with self.validate(args, state) as (args, state):
|
|
29
|
+
with validate_args(args, state, at_least=1) as table:
|
|
30
|
+
Devices.device(state).preview(table, state)
|
|
64
31
|
|
|
65
|
-
|
|
66
|
-
if state.device == ReplState.P:
|
|
67
|
-
PostgresSession(state.namespace, state.pg_path).run_sql(f'select * from {table} limit {rows}')
|
|
68
|
-
else:
|
|
69
|
-
run_cql(state, f'select * from {table} limit {rows}', show_out=True, use_single_quotes=True)
|
|
70
|
-
|
|
71
|
-
return state
|
|
72
|
-
|
|
73
|
-
def completion(self, state: ReplState):
|
|
74
|
-
if state.device == ReplState.P:
|
|
75
|
-
if tables := PreviewTable.pg_tables(state.namespace, state.pg_path):
|
|
76
|
-
return {PreviewTable.COMMAND: {db["name"]: None for db in tables if db["schema"] == PostgresSession.default_schema()}}
|
|
77
|
-
else:
|
|
78
|
-
if state.pod:
|
|
79
|
-
tables = PreviewTable.cql_tables(state)
|
|
80
|
-
return {PreviewTable.COMMAND: {f'{k}.{t}': None for k, ts in tables.items() for t in ts}}
|
|
32
|
+
return state
|
|
81
33
|
|
|
34
|
+
def completion(self, _: ReplState):
|
|
35
|
+
# taken care of by the sql completer
|
|
82
36
|
return {}
|
|
83
37
|
|
|
84
38
|
def help(self, _: ReplState):
|
|
85
|
-
return f'{PreviewTable.COMMAND} TABLE\t preview table'
|
|
86
|
-
|
|
87
|
-
@functools.lru_cache()
|
|
88
|
-
def cql_tables(state: ReplState):
|
|
89
|
-
r: PodExecResult = run_cql(state, 'describe tables', show_out=False)
|
|
90
|
-
return parse_cql_desc_tables(r.stdout)
|
|
91
|
-
|
|
92
|
-
@functools.lru_cache()
|
|
93
|
-
def pg_tables(ns: str, pg_path: str):
|
|
94
|
-
pg = PostgresSession(ns, pg_path)
|
|
95
|
-
if pg.db:
|
|
96
|
-
return pg.tables()
|
|
97
|
-
|
|
98
|
-
return None
|
|
39
|
+
return f'{PreviewTable.COMMAND} TABLE\t preview table'
|
adam/commands/pwd.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from adam.app_session import AppSession
|
|
2
2
|
from adam.commands.command import Command
|
|
3
|
-
from adam.commands.
|
|
3
|
+
from adam.commands.devices.devices import Devices
|
|
4
4
|
from adam.repl_state import ReplState
|
|
5
|
-
from adam.utils import
|
|
5
|
+
from adam.utils import tabulize, log, log_exc
|
|
6
6
|
|
|
7
7
|
class Pwd(Command):
|
|
8
8
|
COMMAND = 'pwd'
|
|
@@ -23,49 +23,20 @@ class Pwd(Command):
|
|
|
23
23
|
if not(args := self.args(cmd)):
|
|
24
24
|
return super().run(cmd, state)
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
with self.validate(args, state) as (_, state):
|
|
27
|
+
host = "unknown"
|
|
28
|
+
with log_exc():
|
|
29
|
+
app_session: AppSession = AppSession.create('c3', 'c3')
|
|
30
|
+
host = app_session.host
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
tabulize([device.pwd(state) for device in Devices.all()] + [
|
|
33
|
+
f'',
|
|
34
|
+
f'HOST\t{host}',
|
|
35
|
+
f'NAMESPACE\t{state.namespace if state.namespace else "/"}',
|
|
36
|
+
], header='DEVICE\tLOCATION', separator='\t')
|
|
37
|
+
log()
|
|
30
38
|
|
|
31
|
-
|
|
32
|
-
pg = PostgresSession(state.namespace, state.pg_path)
|
|
33
|
-
|
|
34
|
-
if pg.host:
|
|
35
|
-
words.append(f'host/{pg.host}')
|
|
36
|
-
if pg.db:
|
|
37
|
-
words.append(f'database/{pg.db}')
|
|
38
|
-
elif device == ReplState.A:
|
|
39
|
-
if state.app_env:
|
|
40
|
-
words.append(f'env/{state.app_env}')
|
|
41
|
-
if state.app_app:
|
|
42
|
-
words.append(f'app/{state.app_app}')
|
|
43
|
-
else:
|
|
44
|
-
if state.sts:
|
|
45
|
-
words.append(f'sts/{state.sts}')
|
|
46
|
-
if state.pod:
|
|
47
|
-
words.append(f'pod/{state.pod}')
|
|
48
|
-
|
|
49
|
-
return '\t'.join([f'{device}:>'] + (words if words else ['/']))
|
|
50
|
-
|
|
51
|
-
host = "unknown"
|
|
52
|
-
try:
|
|
53
|
-
app_session: AppSession = AppSession.create('c3', 'c3')
|
|
54
|
-
host = app_session.host
|
|
55
|
-
except:
|
|
56
|
-
pass
|
|
57
|
-
|
|
58
|
-
log(lines_to_tabular([
|
|
59
|
-
device_line(state, ReplState.A),
|
|
60
|
-
device_line(state, ReplState.C),
|
|
61
|
-
device_line(state, ReplState.P),
|
|
62
|
-
f'',
|
|
63
|
-
f'HOST\t{host}',
|
|
64
|
-
f'NAMESPACE\t{state.namespace if state.namespace else "/"}',
|
|
65
|
-
], 'DEVICE\tLOCATION', separator='\t'))
|
|
66
|
-
log()
|
|
67
|
-
|
|
68
|
-
return state
|
|
39
|
+
return state
|
|
69
40
|
|
|
70
41
|
def completion(self, state: ReplState):
|
|
71
42
|
return super().completion(state)
|
adam/commands/reaper/reaper.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import click
|
|
2
2
|
|
|
3
|
-
from adam.commands.
|
|
4
|
-
from adam.commands.command_helpers import ClusterCommandHelper
|
|
3
|
+
from adam.commands.intermediate_command import IntermediateCommand
|
|
5
4
|
from .reaper_forward import ReaperForward
|
|
6
5
|
from .reaper_forward_stop import ReaperForwardStop
|
|
7
6
|
from .reaper_restart import ReaperRestart
|
|
@@ -13,12 +12,9 @@ from .reaper_schedule_start import ReaperScheduleStart
|
|
|
13
12
|
from .reaper_schedule_stop import ReaperScheduleStop
|
|
14
13
|
from .reaper_schedules import ReaperSchedules
|
|
15
14
|
from .reaper_status import ReaperStatus
|
|
16
|
-
from adam.repl_state import ReplState, RequiredState
|
|
17
|
-
from adam.utils import lines_to_tabular, log, log2
|
|
18
15
|
|
|
19
|
-
class Reaper(
|
|
16
|
+
class Reaper(IntermediateCommand):
|
|
20
17
|
COMMAND = 'reaper'
|
|
21
|
-
reaper_login = None
|
|
22
18
|
|
|
23
19
|
# the singleton pattern
|
|
24
20
|
def __new__(cls, *args, **kwargs):
|
|
@@ -26,53 +22,14 @@ class Reaper(Command):
|
|
|
26
22
|
|
|
27
23
|
return cls.instance
|
|
28
24
|
|
|
29
|
-
def __init__(self, successor: Command=None):
|
|
30
|
-
super().__init__(successor)
|
|
31
|
-
|
|
32
25
|
def command(self):
|
|
33
26
|
return Reaper.COMMAND
|
|
34
27
|
|
|
35
|
-
def
|
|
36
|
-
return RequiredState.CLUSTER
|
|
37
|
-
|
|
38
|
-
def run(self, cmd: str, state: ReplState):
|
|
39
|
-
if not(args := self.args(cmd)):
|
|
40
|
-
return super().run(cmd, state)
|
|
41
|
-
|
|
42
|
-
state, args = self.apply_state(args, state)
|
|
43
|
-
if not self.validate_state(state):
|
|
44
|
-
return state
|
|
45
|
-
|
|
46
|
-
if state.in_repl:
|
|
47
|
-
log(lines_to_tabular([c.help(ReplState()) for c in Reaper.cmd_list()], separator='\t'))
|
|
48
|
-
|
|
49
|
-
return 'command-missing'
|
|
50
|
-
else:
|
|
51
|
-
# head with the Chain of Responsibility pattern
|
|
52
|
-
cmds = Command.chain(Reaper.cmd_list())
|
|
53
|
-
if not cmds.run(cmd, state):
|
|
54
|
-
log2('* Command is missing.')
|
|
55
|
-
Command.display_help()
|
|
56
|
-
|
|
57
|
-
def cmd_list():
|
|
28
|
+
def cmd_list(self):
|
|
58
29
|
return [ReaperSchedules(), ReaperScheduleStop(), ReaperScheduleActivate(), ReaperScheduleStart(),
|
|
59
|
-
ReaperForwardStop(), ReaperForward(), ReaperRunAbort(), ReaperRunsAbort(), ReaperRestart(),
|
|
60
|
-
|
|
61
|
-
def completion(self, state: ReplState):
|
|
62
|
-
if state.sts:
|
|
63
|
-
return super().completion(state)
|
|
64
|
-
|
|
65
|
-
return {}
|
|
66
|
-
|
|
67
|
-
def help(self, _: ReplState):
|
|
68
|
-
return None
|
|
30
|
+
ReaperForwardStop(), ReaperForward(), ReaperRunAbort(), ReaperRunsAbort(), ReaperRestart(),
|
|
31
|
+
ReaperRuns(), ReaperStatus()]
|
|
69
32
|
|
|
70
33
|
class ReaperCommandHelper(click.Command):
|
|
71
34
|
def get_help(self, ctx: click.Context):
|
|
72
|
-
|
|
73
|
-
log()
|
|
74
|
-
log('Sub-Commands:')
|
|
75
|
-
|
|
76
|
-
log(lines_to_tabular([c.help(ReplState()).replace(f'{Reaper.COMMAND} ', ' ', 1) for c in Reaper.cmd_list()], separator='\t'))
|
|
77
|
-
log()
|
|
78
|
-
ClusterCommandHelper.cluster_help()
|
|
35
|
+
IntermediateCommand.intermediate_help(super().get_help(ctx), Reaper.COMMAND, Reaper().cmd_list(), show_cluster_help=True)
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
from functools import partial
|
|
1
2
|
import threading
|
|
2
3
|
import time
|
|
3
4
|
|
|
4
5
|
from adam.commands.command import Command
|
|
5
|
-
from .
|
|
6
|
+
from adam.commands.reaper.reaper_forward_session import ReaperForwardSession
|
|
7
|
+
from adam.commands.reaper.utils_reaper import Reapers, port_forwarding
|
|
6
8
|
from adam.config import Config
|
|
7
9
|
from adam.repl_session import ReplSession
|
|
8
10
|
from adam.repl_state import ReplState, RequiredState
|
|
9
|
-
from adam.utils import
|
|
11
|
+
from adam.utils import tabulize, log2
|
|
10
12
|
|
|
11
13
|
class ReaperForward(Command):
|
|
12
14
|
COMMAND = 'reaper forward'
|
|
13
|
-
reaper_login = None
|
|
14
15
|
|
|
15
16
|
# the singleton pattern
|
|
16
17
|
def __new__(cls, *args, **kwargs):
|
|
@@ -31,70 +32,62 @@ class ReaperForward(Command):
|
|
|
31
32
|
if not(args := self.args(cmd)):
|
|
32
33
|
return super().run(cmd, state)
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
with self.validate(args, state) as (args, state):
|
|
36
|
+
if not Reapers.pod_name(state):
|
|
37
|
+
return state
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
spec = Reapers.reaper_spec(state)
|
|
40
|
+
if state.in_repl:
|
|
41
|
+
if ReaperForwardSession.is_forwarding:
|
|
42
|
+
log2("Another port-forward is already running.")
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
d = {
|
|
56
|
-
'reaper-ui': spec["web-uri"],
|
|
57
|
-
'reaper-username': spec["username"],
|
|
58
|
-
'reaper-password': spec["password"]
|
|
59
|
-
}
|
|
60
|
-
log2()
|
|
61
|
-
log2(lines_to_tabular([f'{k},{v}' for k, v in d.items()], separator=','))
|
|
62
|
-
|
|
63
|
-
for k, v in d.items():
|
|
64
|
-
ReplSession().prompt_session.history.append_string(f'cp {k}')
|
|
65
|
-
log2()
|
|
66
|
-
log2(f'Use <Up> arrow key to copy the values to clipboard.')
|
|
67
|
-
else:
|
|
68
|
-
try:
|
|
69
|
-
log2(f'Click: {spec["web-uri"]}')
|
|
70
|
-
log2(f'username: {spec["username"]}')
|
|
71
|
-
log2(f'password: {spec["password"]}')
|
|
44
|
+
return "already-running"
|
|
45
|
+
|
|
46
|
+
# make it a daemon to exit with a Ctrl-D
|
|
47
|
+
thread = threading.Thread(target=self.loop, args=(state,), daemon=True)
|
|
48
|
+
thread.start()
|
|
49
|
+
|
|
50
|
+
while not ReaperForwardSession.is_forwarding:
|
|
51
|
+
time.sleep(1)
|
|
52
|
+
|
|
53
|
+
d = {
|
|
54
|
+
'reaper-ui': spec["web-uri"],
|
|
55
|
+
'reaper-username': spec["username"],
|
|
56
|
+
'reaper-password': spec["password"]
|
|
57
|
+
}
|
|
72
58
|
log2()
|
|
73
|
-
|
|
59
|
+
tabulize(d.items(), lambda a: f'{a[0]},{a[1]}', separator=',')
|
|
74
60
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
61
|
+
for k, v in d.items():
|
|
62
|
+
ReplSession().prompt_session.history.append_string(f'cp {k}')
|
|
63
|
+
log2()
|
|
64
|
+
log2(f'Use <Up> arrow key to copy the values to clipboard.')
|
|
65
|
+
else:
|
|
66
|
+
try:
|
|
67
|
+
log2(f'Click: {spec["web-uri"]}')
|
|
68
|
+
log2(f'username: {spec["username"]}')
|
|
69
|
+
log2(f'password: {spec["password"]}')
|
|
70
|
+
log2()
|
|
71
|
+
log2(f"Press Ctrl+C to break.")
|
|
72
|
+
|
|
73
|
+
time.sleep(Config().get('reaper.port-forward.timeout', 3600 * 24))
|
|
74
|
+
except KeyboardInterrupt:
|
|
75
|
+
pass
|
|
78
76
|
|
|
79
|
-
|
|
77
|
+
return state
|
|
80
78
|
|
|
81
|
-
def loop(self, state: ReplState
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
def loop(self, state: ReplState):
|
|
80
|
+
with port_forwarding(state, Reapers.local_port(), partial(Reapers.svc_or_pod, state), Reapers.target_port()):
|
|
81
|
+
ReaperForwardSession.is_forwarding = True
|
|
84
82
|
try:
|
|
85
|
-
while not
|
|
83
|
+
while not ReaperForwardSession.stopping.is_set():
|
|
86
84
|
time.sleep(1)
|
|
87
85
|
finally:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return reaper.port_forwarded(state, 'webui', body)
|
|
86
|
+
ReaperForwardSession.stopping.clear()
|
|
87
|
+
ReaperForwardSession.is_forwarding = False
|
|
92
88
|
|
|
93
89
|
def completion(self, state: ReplState):
|
|
94
|
-
|
|
95
|
-
return super().completion(state)
|
|
96
|
-
|
|
97
|
-
return {}
|
|
90
|
+
return super().completion(state)
|
|
98
91
|
|
|
99
92
|
def help(self, _: ReplState):
|
|
100
93
|
return f'{ReaperForward.COMMAND}\t port-forward to reaper'
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from .
|
|
2
|
+
from adam.commands.reaper.reaper_forward_session import ReaperForwardSession
|
|
3
|
+
from adam.commands.reaper.utils_reaper import Reapers
|
|
3
4
|
from adam.repl_state import ReplState, RequiredState
|
|
4
5
|
from adam.utils import log2
|
|
5
6
|
|
|
6
7
|
class ReaperForwardStop(Command):
|
|
7
8
|
COMMAND = 'reaper forward stop'
|
|
8
|
-
reaper_login = None
|
|
9
9
|
|
|
10
10
|
# the singleton pattern
|
|
11
11
|
def __new__(cls, *args, **kwargs):
|
|
@@ -26,24 +26,18 @@ class ReaperForwardStop(Command):
|
|
|
26
26
|
if not(args := self.args(cmd)):
|
|
27
27
|
return super().run(cmd, state)
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if not ReaperSession.create(state):
|
|
34
|
-
return state
|
|
29
|
+
with self.validate(args, state) as (args, state):
|
|
30
|
+
if not Reapers.pod_name(state):
|
|
31
|
+
return state
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
ReaperForwardSession.is_forwarding = False
|
|
34
|
+
ReaperForwardSession.stopping.set()
|
|
35
|
+
log2("Stopped reaper forward session.")
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
return state
|
|
41
38
|
|
|
42
39
|
def completion(self, state: ReplState):
|
|
43
|
-
|
|
44
|
-
return super().completion(state)
|
|
45
|
-
|
|
46
|
-
return {}
|
|
40
|
+
return super().completion(state)
|
|
47
41
|
|
|
48
42
|
def help(self, _: ReplState):
|
|
49
43
|
return f'{ReaperForwardStop.COMMAND}\t stop port-forward to reaper'
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
from adam.commands.command import Command
|
|
2
|
-
from adam.
|
|
3
|
-
from .
|
|
2
|
+
from adam.commands.reaper.utils_reaper import Reapers
|
|
3
|
+
from adam.utils_k8s.pods import Pods
|
|
4
4
|
from adam.repl_state import ReplState, RequiredState
|
|
5
5
|
|
|
6
6
|
class ReaperRestart(Command):
|
|
7
7
|
COMMAND = 'reaper restart'
|
|
8
|
-
reaper_login = None
|
|
9
8
|
|
|
10
9
|
# the singleton pattern
|
|
11
10
|
def __new__(cls, *args, **kwargs):
|
|
@@ -26,22 +25,16 @@ class ReaperRestart(Command):
|
|
|
26
25
|
if not(args := self.args(cmd)):
|
|
27
26
|
return super().run(cmd, state)
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if not(reaper := ReaperSession.create(state)):
|
|
34
|
-
return state
|
|
28
|
+
with self.validate(args, state) as (args, state):
|
|
29
|
+
if not (pod := Reapers.pod_name(state)):
|
|
30
|
+
return state
|
|
35
31
|
|
|
36
|
-
|
|
32
|
+
Pods.delete(pod, state.namespace)
|
|
37
33
|
|
|
38
|
-
|
|
34
|
+
return state
|
|
39
35
|
|
|
40
36
|
def completion(self, state: ReplState):
|
|
41
|
-
|
|
42
|
-
return super().completion(state)
|
|
43
|
-
|
|
44
|
-
return {}
|
|
37
|
+
return super().completion(state)
|
|
45
38
|
|
|
46
39
|
def help(self, _: ReplState):
|
|
47
40
|
return f'{ReaperRestart.COMMAND}\t restart reaper'
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
from adam.commands import validate_args
|
|
3
2
|
from adam.commands.command import Command
|
|
4
|
-
from .
|
|
3
|
+
from adam.commands.reaper.utils_reaper import reaper
|
|
5
4
|
from adam.repl_state import ReplState, RequiredState
|
|
6
5
|
from adam.utils import log2
|
|
7
6
|
|
|
8
7
|
class ReaperRunAbort(Command):
|
|
9
8
|
COMMAND = 'reaper abort run'
|
|
10
|
-
reaper_login = None
|
|
11
9
|
|
|
12
10
|
# the singleton pattern
|
|
13
11
|
def __new__(cls, *args, **kwargs):
|
|
@@ -28,38 +26,15 @@ class ReaperRunAbort(Command):
|
|
|
28
26
|
if not(args := self.args(cmd)):
|
|
29
27
|
return super().run(cmd, state)
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if not args:
|
|
36
|
-
if state.in_repl:
|
|
37
|
-
log2('Specify run id to abort.')
|
|
38
|
-
else:
|
|
39
|
-
Command.display_help()
|
|
40
|
-
|
|
41
|
-
return state
|
|
42
|
-
|
|
43
|
-
if not(reaper := ReaperSession.create(state)):
|
|
44
|
-
return state
|
|
29
|
+
with self.validate(args, state) as (args, state):
|
|
30
|
+
with validate_args(args, state, name='run id') as run_id:
|
|
31
|
+
with reaper(state) as http:
|
|
32
|
+
http.put(f'repair_run/{run_id}/state/ABORTED')
|
|
45
33
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return state
|
|
49
|
-
|
|
50
|
-
def stop_run(self, state: ReplState, reaper: ReaperSession, run_id: str):
|
|
51
|
-
def body(uri: str, headers: dict[str, str]):
|
|
52
|
-
return requests.put(uri, headers=headers)
|
|
53
|
-
|
|
54
|
-
# PAUSED, RUNNING, ABORTED
|
|
55
|
-
# PUT /repair_run/{id}/state/{state}
|
|
56
|
-
reaper.port_forwarded(state, f'repair_run/{run_id}/state/ABORTED', body, method='PUT')
|
|
34
|
+
return state
|
|
57
35
|
|
|
58
36
|
def completion(self, state: ReplState):
|
|
59
|
-
|
|
60
|
-
return super().completion(state)
|
|
61
|
-
|
|
62
|
-
return {}
|
|
37
|
+
return super().completion(state)
|
|
63
38
|
|
|
64
39
|
def help(self, _: ReplState):
|
|
65
40
|
return f'{ReaperRunAbort.COMMAND} <run-id>\t abort reaper run'
|