kaqing 1.77.0__py3-none-any.whl → 2.0.171__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.
- adam/__init__.py +1 -0
- adam/app_session.py +182 -0
- {walker → adam}/apps.py +8 -24
- {walker → adam}/batch.py +54 -97
- {walker → adam}/checks/check.py +3 -3
- {walker → adam}/checks/check_result.py +1 -1
- adam/checks/check_utils.py +65 -0
- {walker → adam}/checks/compactionstats.py +6 -6
- {walker → adam}/checks/cpu.py +14 -8
- adam/checks/cpu_metrics.py +52 -0
- {walker → adam}/checks/disk.py +6 -6
- {walker → adam}/checks/gossip.py +5 -5
- {walker → adam}/checks/memory.py +7 -7
- {walker → adam}/checks/status.py +5 -5
- {walker → adam}/cli.py +3 -3
- {walker → adam}/columns/column.py +1 -1
- adam/columns/columns.py +45 -0
- {walker → adam}/columns/compactions.py +5 -5
- {walker → adam}/columns/cpu.py +6 -4
- adam/columns/cpu_metrics.py +22 -0
- {walker → adam}/columns/dir_data.py +3 -3
- {walker → adam}/columns/dir_snapshots.py +3 -3
- {walker → adam}/columns/gossip.py +5 -5
- {walker → adam}/columns/host_id.py +3 -3
- {walker → adam}/columns/memory.py +3 -3
- {walker → adam}/columns/node_address.py +3 -3
- {walker → adam}/columns/node_load.py +3 -3
- {walker → adam}/columns/node_owns.py +3 -3
- {walker → adam}/columns/node_status.py +3 -3
- {walker → adam}/columns/node_tokens.py +3 -3
- {walker → adam}/columns/node_utils.py +2 -2
- {walker → adam}/columns/pod_name.py +2 -2
- {walker → adam}/columns/volume_cassandra.py +4 -4
- {walker → adam}/columns/volume_root.py +3 -3
- adam/commands/__init__.py +15 -0
- adam/commands/alter_tables.py +81 -0
- adam/commands/app_cmd.py +38 -0
- {walker → adam}/commands/app_ping.py +10 -16
- adam/commands/audit/audit.py +84 -0
- adam/commands/audit/audit_repair_tables.py +74 -0
- adam/commands/audit/audit_run.py +50 -0
- adam/commands/audit/show_last10.py +48 -0
- adam/commands/audit/show_slow10.py +47 -0
- adam/commands/audit/show_top10.py +45 -0
- adam/commands/audit/utils_show_top10.py +59 -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 +50 -0
- adam/commands/cd.py +43 -0
- adam/commands/check.py +73 -0
- {walker → adam}/commands/cli_commands.py +7 -8
- adam/commands/code.py +57 -0
- adam/commands/command.py +190 -0
- {walker → adam}/commands/command_helpers.py +1 -1
- {walker → adam}/commands/commands_utils.py +15 -25
- adam/commands/cp.py +89 -0
- adam/commands/cql/cql_completions.py +33 -0
- {walker/commands → adam/commands/cql}/cqlsh.py +20 -35
- adam/commands/cql/utils_cql.py +343 -0
- {walker/commands/frontend → adam/commands/deploy}/code_start.py +11 -14
- adam/commands/deploy/code_stop.py +40 -0
- {walker/commands/frontend → adam/commands/deploy}/code_utils.py +7 -9
- adam/commands/deploy/deploy.py +25 -0
- adam/commands/deploy/deploy_frontend.py +49 -0
- adam/commands/deploy/deploy_pg_agent.py +35 -0
- adam/commands/deploy/deploy_pod.py +108 -0
- adam/commands/deploy/deploy_utils.py +29 -0
- adam/commands/deploy/undeploy.py +25 -0
- adam/commands/deploy/undeploy_frontend.py +38 -0
- adam/commands/deploy/undeploy_pg_agent.py +39 -0
- adam/commands/deploy/undeploy_pod.py +48 -0
- adam/commands/devices/device.py +118 -0
- adam/commands/devices/device_app.py +173 -0
- adam/commands/devices/device_auit_log.py +49 -0
- adam/commands/devices/device_cass.py +185 -0
- adam/commands/devices/device_export.py +86 -0
- adam/commands/devices/device_postgres.py +144 -0
- adam/commands/devices/devices.py +25 -0
- {walker → adam}/commands/exit.py +3 -6
- adam/commands/export/clean_up_all_export_sessions.py +37 -0
- adam/commands/export/clean_up_export_sessions.py +51 -0
- adam/commands/export/drop_export_database.py +55 -0
- adam/commands/export/drop_export_databases.py +43 -0
- adam/commands/export/export.py +53 -0
- adam/commands/export/export_databases.py +170 -0
- adam/commands/export/export_handlers.py +71 -0
- adam/commands/export/export_select.py +81 -0
- adam/commands/export/export_select_x.py +54 -0
- adam/commands/export/export_use.py +52 -0
- adam/commands/export/exporter.py +352 -0
- adam/commands/export/import_session.py +40 -0
- adam/commands/export/importer.py +67 -0
- adam/commands/export/importer_athena.py +80 -0
- adam/commands/export/importer_sqlite.py +47 -0
- adam/commands/export/show_column_counts.py +54 -0
- adam/commands/export/show_export_databases.py +36 -0
- adam/commands/export/show_export_session.py +48 -0
- adam/commands/export/show_export_sessions.py +44 -0
- adam/commands/export/utils_export.py +314 -0
- {walker → adam}/commands/help.py +17 -12
- adam/commands/intermediate_command.py +49 -0
- adam/commands/issues.py +43 -0
- adam/commands/kubectl.py +38 -0
- adam/commands/login.py +70 -0
- {walker → adam}/commands/logs.py +8 -10
- adam/commands/ls.py +41 -0
- adam/commands/medusa/medusa.py +27 -0
- adam/commands/medusa/medusa_backup.py +57 -0
- adam/commands/medusa/medusa_restore.py +83 -0
- adam/commands/medusa/medusa_show_backupjobs.py +51 -0
- adam/commands/medusa/medusa_show_restorejobs.py +47 -0
- {walker → adam}/commands/nodetool.py +17 -21
- {walker → adam}/commands/param_get.py +15 -16
- adam/commands/param_set.py +43 -0
- adam/commands/postgres/postgres.py +104 -0
- adam/commands/postgres/postgres_context.py +274 -0
- {walker → adam}/commands/postgres/postgres_ls.py +7 -11
- {walker → adam}/commands/postgres/postgres_preview.py +8 -13
- adam/commands/postgres/psql_completions.py +10 -0
- adam/commands/postgres/utils_postgres.py +66 -0
- adam/commands/preview_table.py +37 -0
- adam/commands/pwd.py +47 -0
- adam/commands/reaper/reaper.py +35 -0
- adam/commands/reaper/reaper_forward.py +93 -0
- adam/commands/reaper/reaper_forward_session.py +6 -0
- {walker → adam}/commands/reaper/reaper_forward_stop.py +13 -19
- {walker → adam}/commands/reaper/reaper_restart.py +10 -17
- adam/commands/reaper/reaper_run_abort.py +46 -0
- adam/commands/reaper/reaper_runs.py +82 -0
- adam/commands/reaper/reaper_runs_abort.py +63 -0
- adam/commands/reaper/reaper_schedule_activate.py +45 -0
- adam/commands/reaper/reaper_schedule_start.py +45 -0
- adam/commands/reaper/reaper_schedule_stop.py +45 -0
- {walker → adam}/commands/reaper/reaper_schedules.py +6 -16
- {walker → adam}/commands/reaper/reaper_status.py +11 -19
- adam/commands/reaper/utils_reaper.py +196 -0
- adam/commands/repair/repair.py +26 -0
- {walker → adam}/commands/repair/repair_log.py +7 -10
- adam/commands/repair/repair_run.py +70 -0
- adam/commands/repair/repair_scan.py +71 -0
- {walker → adam}/commands/repair/repair_stop.py +8 -11
- adam/commands/report.py +61 -0
- adam/commands/restart.py +60 -0
- {walker → adam}/commands/rollout.py +25 -30
- adam/commands/shell.py +34 -0
- adam/commands/show/show.py +39 -0
- walker/commands/show/show_version.py → adam/commands/show/show_adam.py +14 -10
- adam/commands/show/show_app_actions.py +57 -0
- {walker → adam}/commands/show/show_app_id.py +12 -15
- {walker → adam}/commands/show/show_app_queues.py +9 -12
- adam/commands/show/show_cassandra_repairs.py +38 -0
- adam/commands/show/show_cassandra_status.py +124 -0
- {walker → adam}/commands/show/show_cassandra_version.py +6 -16
- adam/commands/show/show_commands.py +59 -0
- walker/commands/show/show_storage.py → adam/commands/show/show_host.py +11 -13
- adam/commands/show/show_login.py +62 -0
- {walker → adam}/commands/show/show_params.py +4 -4
- adam/commands/show/show_processes.py +51 -0
- adam/commands/show/show_storage.py +42 -0
- adam/commands/watch.py +82 -0
- {walker → adam}/config.py +10 -22
- {walker → adam}/embedded_apps.py +1 -1
- adam/embedded_params.py +2 -0
- adam/log.py +47 -0
- {walker → adam}/pod_exec_result.py +10 -2
- adam/repl.py +182 -0
- adam/repl_commands.py +124 -0
- adam/repl_state.py +458 -0
- adam/sql/__init__.py +0 -0
- adam/sql/sql_completer.py +120 -0
- adam/sql/sql_state_machine.py +618 -0
- adam/sql/term_completer.py +76 -0
- adam/sso/__init__.py +0 -0
- {walker → adam}/sso/authenticator.py +5 -1
- adam/sso/authn_ad.py +170 -0
- {walker → adam}/sso/authn_okta.py +39 -22
- adam/sso/cred_cache.py +60 -0
- adam/sso/id_token.py +23 -0
- adam/sso/idp.py +143 -0
- adam/sso/idp_login.py +50 -0
- adam/sso/idp_session.py +55 -0
- adam/sso/sso_config.py +63 -0
- adam/utils.py +679 -0
- adam/utils_app.py +98 -0
- adam/utils_athena.py +145 -0
- adam/utils_audits.py +106 -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 +33 -0
- adam/utils_k8s/cassandra_clusters.py +36 -0
- adam/utils_k8s/cassandra_nodes.py +33 -0
- adam/utils_k8s/config_maps.py +34 -0
- {walker/k8s_utils → adam/utils_k8s}/custom_resources.py +7 -2
- adam/utils_k8s/deployment.py +56 -0
- {walker/k8s_utils → adam/utils_k8s}/ingresses.py +3 -4
- {walker/k8s_utils → adam/utils_k8s}/jobs.py +3 -3
- adam/utils_k8s/k8s.py +87 -0
- {walker/k8s_utils → adam/utils_k8s}/kube_context.py +4 -4
- adam/utils_k8s/pods.py +290 -0
- {walker/k8s_utils → adam/utils_k8s}/secrets.py +8 -4
- adam/utils_k8s/service_accounts.py +170 -0
- {walker/k8s_utils → adam/utils_k8s}/services.py +3 -4
- {walker/k8s_utils → adam/utils_k8s}/statefulsets.py +6 -16
- {walker/k8s_utils → adam/utils_k8s}/volumes.py +10 -1
- adam/utils_net.py +24 -0
- adam/utils_repl/__init__.py +0 -0
- adam/utils_repl/automata_completer.py +48 -0
- adam/utils_repl/repl_completer.py +46 -0
- adam/utils_repl/state_machine.py +173 -0
- adam/utils_sqlite.py +109 -0
- adam/version.py +5 -0
- {kaqing-1.77.0.dist-info → kaqing-2.0.171.dist-info}/METADATA +1 -1
- kaqing-2.0.171.dist-info/RECORD +236 -0
- kaqing-2.0.171.dist-info/entry_points.txt +3 -0
- kaqing-2.0.171.dist-info/top_level.txt +1 -0
- kaqing-1.77.0.dist-info/RECORD +0 -159
- kaqing-1.77.0.dist-info/entry_points.txt +0 -3
- kaqing-1.77.0.dist-info/top_level.txt +0 -1
- walker/__init__.py +0 -3
- walker/app_session.py +0 -168
- walker/checks/check_utils.py +0 -97
- walker/columns/columns.py +0 -43
- walker/commands/add_user.py +0 -68
- walker/commands/app.py +0 -67
- walker/commands/bash.py +0 -87
- walker/commands/cd.py +0 -115
- walker/commands/check.py +0 -68
- walker/commands/command.py +0 -104
- walker/commands/cp.py +0 -95
- walker/commands/cql_utils.py +0 -53
- walker/commands/devices.py +0 -89
- walker/commands/frontend/code_stop.py +0 -57
- walker/commands/frontend/setup.py +0 -60
- walker/commands/frontend/setup_frontend.py +0 -58
- walker/commands/frontend/teardown.py +0 -61
- walker/commands/frontend/teardown_frontend.py +0 -42
- walker/commands/issues.py +0 -69
- walker/commands/login.py +0 -72
- walker/commands/ls.py +0 -145
- walker/commands/medusa/medusa.py +0 -69
- walker/commands/medusa/medusa_backup.py +0 -61
- walker/commands/medusa/medusa_restore.py +0 -86
- walker/commands/medusa/medusa_show_backupjobs.py +0 -52
- walker/commands/medusa/medusa_show_restorejobs.py +0 -52
- walker/commands/param_set.py +0 -44
- walker/commands/postgres/postgres.py +0 -113
- walker/commands/postgres/postgres_session.py +0 -225
- walker/commands/preview_table.py +0 -98
- walker/commands/processes.py +0 -53
- walker/commands/pwd.py +0 -64
- walker/commands/reaper/reaper.py +0 -78
- walker/commands/reaper/reaper_forward.py +0 -100
- walker/commands/reaper/reaper_run_abort.py +0 -65
- walker/commands/reaper/reaper_runs.py +0 -97
- walker/commands/reaper/reaper_runs_abort.py +0 -83
- walker/commands/reaper/reaper_schedule_activate.py +0 -64
- walker/commands/reaper/reaper_schedule_start.py +0 -64
- walker/commands/reaper/reaper_schedule_stop.py +0 -64
- walker/commands/reaper/reaper_session.py +0 -159
- walker/commands/repair/repair.py +0 -68
- walker/commands/repair/repair_run.py +0 -72
- walker/commands/repair/repair_scan.py +0 -79
- walker/commands/report.py +0 -57
- walker/commands/restart.py +0 -61
- walker/commands/show/show.py +0 -72
- walker/commands/show/show_app_actions.py +0 -53
- walker/commands/show/show_cassandra_status.py +0 -35
- walker/commands/show/show_commands.py +0 -58
- walker/commands/show/show_processes.py +0 -35
- walker/commands/show/show_repairs.py +0 -47
- walker/commands/status.py +0 -128
- walker/commands/storage.py +0 -52
- walker/commands/user_entry.py +0 -69
- walker/commands/watch.py +0 -85
- walker/embedded_params.py +0 -2
- walker/k8s_utils/cassandra_clusters.py +0 -48
- walker/k8s_utils/cassandra_nodes.py +0 -26
- walker/k8s_utils/pods.py +0 -211
- walker/repl.py +0 -165
- walker/repl_commands.py +0 -58
- walker/repl_state.py +0 -211
- walker/sso/authn_ad.py +0 -94
- walker/sso/idp.py +0 -150
- walker/sso/idp_login.py +0 -29
- walker/sso/sso_config.py +0 -45
- walker/utils.py +0 -194
- walker/version.py +0 -5
- {walker → adam}/checks/__init__.py +0 -0
- {walker → adam}/checks/check_context.py +0 -0
- {walker → adam}/checks/issue.py +0 -0
- {walker → adam}/cli_group.py +0 -0
- {walker → adam}/columns/__init__.py +0 -0
- {walker/commands → adam/commands/audit}/__init__.py +0 -0
- {walker/commands/frontend → adam/commands/cql}/__init__.py +0 -0
- {walker/commands/medusa → adam/commands/deploy}/__init__.py +0 -0
- {walker/commands/postgres → adam/commands/devices}/__init__.py +0 -0
- {walker/commands/reaper → adam/commands/export}/__init__.py +0 -0
- {walker/commands/repair → adam/commands/medusa}/__init__.py +0 -0
- {walker → adam}/commands/nodetool_commands.py +0 -0
- {walker/commands/show → adam/commands/postgres}/__init__.py +0 -0
- {walker/k8s_utils → adam/commands/reaper}/__init__.py +0 -0
- {walker/sso → adam/commands/repair}/__init__.py +0 -0
- /walker/medusa_show_restorejobs.py → /adam/commands/show/__init__.py +0 -0
- {walker → adam}/repl_session.py +0 -0
- {kaqing-1.77.0.dist-info → kaqing-2.0.171.dist-info}/WHEEL +0 -0
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
import re
|
|
3
|
-
import subprocess
|
|
4
|
-
|
|
5
|
-
from walker.config import Config
|
|
6
|
-
from walker.k8s_utils.kube_context import KubeContext
|
|
7
|
-
from walker.k8s_utils.pods import Pods
|
|
8
|
-
from walker.k8s_utils.secrets import Secrets
|
|
9
|
-
from walker.utils import log2
|
|
10
|
-
|
|
11
|
-
class PostgresSession:
|
|
12
|
-
def __init__(self, ns: str, path: str):
|
|
13
|
-
self.namespace = ns
|
|
14
|
-
self.conn_details = None
|
|
15
|
-
self.host = None
|
|
16
|
-
self.db = None
|
|
17
|
-
|
|
18
|
-
if path:
|
|
19
|
-
tks = path.split('/')
|
|
20
|
-
hn = tks[0].split('@')
|
|
21
|
-
self.host = hn[0]
|
|
22
|
-
if len(hn) > 1 and not ns:
|
|
23
|
-
self.namespace = hn[1]
|
|
24
|
-
|
|
25
|
-
if len(tks) > 1:
|
|
26
|
-
self.db = tks[1]
|
|
27
|
-
|
|
28
|
-
# work for databases()
|
|
29
|
-
def __eq__(self, other: 'PostgresSession'):
|
|
30
|
-
return self.host == other.host
|
|
31
|
-
|
|
32
|
-
def __hash__(self):
|
|
33
|
-
return hash(self.host)
|
|
34
|
-
|
|
35
|
-
def find_namespace(self, arg: str):
|
|
36
|
-
if arg:
|
|
37
|
-
tks = arg.split('@')
|
|
38
|
-
if len(tks) > 1:
|
|
39
|
-
return tks[1]
|
|
40
|
-
|
|
41
|
-
return None
|
|
42
|
-
|
|
43
|
-
def directory(self, arg: str = None):
|
|
44
|
-
if arg:
|
|
45
|
-
if arg == '..':
|
|
46
|
-
if self.db:
|
|
47
|
-
self.db = None
|
|
48
|
-
else:
|
|
49
|
-
self.host = None
|
|
50
|
-
else:
|
|
51
|
-
tks = arg.split('@')
|
|
52
|
-
arg = tks[0]
|
|
53
|
-
if not self.host:
|
|
54
|
-
self.host = arg
|
|
55
|
-
else:
|
|
56
|
-
self.db = arg
|
|
57
|
-
|
|
58
|
-
if not self.host:
|
|
59
|
-
return None
|
|
60
|
-
|
|
61
|
-
d = self.host
|
|
62
|
-
if not self.db:
|
|
63
|
-
return d
|
|
64
|
-
|
|
65
|
-
return f'{self.host}/{self.db}'
|
|
66
|
-
|
|
67
|
-
def hosts(ns: str):
|
|
68
|
-
return PostgresSession.hosts_for_namespace(ns)
|
|
69
|
-
|
|
70
|
-
@functools.lru_cache()
|
|
71
|
-
def hosts_for_namespace(ns: str):
|
|
72
|
-
ss = Secrets.list_secrets(ns, name_pattern=Config().get('pg.name-pattern', '^{namespace}.*k8spg.*'))
|
|
73
|
-
|
|
74
|
-
def excludes(name: str):
|
|
75
|
-
exs = Config().get('pg.excludes', '.helm., -admin-secret')
|
|
76
|
-
if exs:
|
|
77
|
-
for ex in exs.split(','):
|
|
78
|
-
if ex.strip(' ') in name:
|
|
79
|
-
return True
|
|
80
|
-
|
|
81
|
-
return False
|
|
82
|
-
|
|
83
|
-
return [s for s in ss if not excludes(s)]
|
|
84
|
-
|
|
85
|
-
@functools.lru_cache()
|
|
86
|
-
def databases(self):
|
|
87
|
-
dbs = []
|
|
88
|
-
# List of databases
|
|
89
|
-
# Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
|
|
90
|
-
# ---------------------------------------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
|
|
91
|
-
# postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
|
|
92
|
-
# stgawsscpsr_c3_c3 | postgres | UTF8 | C | C | | libc |
|
|
93
|
-
# template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
|
|
94
|
-
# | | | | | | | postgres=CTc/postgres
|
|
95
|
-
# (48 rows)
|
|
96
|
-
r = self.run_sql('\l', show_out=False)
|
|
97
|
-
s = 0
|
|
98
|
-
for line in r.stdout.split('\n'):
|
|
99
|
-
line: str = line.strip(' \r')
|
|
100
|
-
if s == 0:
|
|
101
|
-
if 'List of databases' in line:
|
|
102
|
-
s = 1
|
|
103
|
-
elif s == 1:
|
|
104
|
-
if 'Name' in line and 'Owner' in line and 'Encoding' in line:
|
|
105
|
-
s = 2
|
|
106
|
-
elif s == 2:
|
|
107
|
-
if line.startswith('---------'):
|
|
108
|
-
s = 3
|
|
109
|
-
elif s == 3:
|
|
110
|
-
groups = re.match(r'^\s*(\S*)\s*\|\s*(\S*)\s*\|.*', line)
|
|
111
|
-
if groups and groups[1] != '|':
|
|
112
|
-
dbs.append({'name': groups[1], 'owner': groups[2]})
|
|
113
|
-
|
|
114
|
-
return dbs
|
|
115
|
-
|
|
116
|
-
def tables(self):
|
|
117
|
-
dbs = []
|
|
118
|
-
# List of relations
|
|
119
|
-
# Schema | Name | Type | Owner
|
|
120
|
-
# ----------+------------------------------------------------------------+-------+---------------
|
|
121
|
-
# postgres | c3_2_admin_aclpriv | table | postgres
|
|
122
|
-
# postgres | c3_2_admin_aclpriv_a | table | postgres
|
|
123
|
-
r = self.run_sql('\dt', show_out=False)
|
|
124
|
-
s = 0
|
|
125
|
-
for line in r.stdout.split('\n'):
|
|
126
|
-
line: str = line.strip(' \r')
|
|
127
|
-
if s == 0:
|
|
128
|
-
if 'List of relations' in line:
|
|
129
|
-
s = 1
|
|
130
|
-
elif s == 1:
|
|
131
|
-
if 'Schema' in line and 'Name' in line and 'Type' in line:
|
|
132
|
-
s = 2
|
|
133
|
-
elif s == 2:
|
|
134
|
-
if line.startswith('---------'):
|
|
135
|
-
s = 3
|
|
136
|
-
elif s == 3:
|
|
137
|
-
groups = re.match(r'^\s*(\S*)\s*\|\s*(\S*)\s*\|.*', line)
|
|
138
|
-
if groups and groups[1] != '|':
|
|
139
|
-
dbs.append({'schema': groups[1], 'name': groups[2]})
|
|
140
|
-
|
|
141
|
-
return dbs
|
|
142
|
-
|
|
143
|
-
def run_sql(self, sql: str, show_out = True):
|
|
144
|
-
db = self.db if self.db else PostgresSession.default_db()
|
|
145
|
-
|
|
146
|
-
if KubeContext.in_cluster():
|
|
147
|
-
cmd1 = f'env PGPASSWORD={self.password()} psql -h {self.endpoint()} -p {self.port()} -U {self.username()} {db} --pset pager=off -c'
|
|
148
|
-
log2(f'{cmd1} "{sql}"')
|
|
149
|
-
# remove double quotes from the sql argument
|
|
150
|
-
cmd = cmd1.split(' ') + [sql]
|
|
151
|
-
r = subprocess.run(cmd, capture_output=True, text=True)
|
|
152
|
-
if show_out:
|
|
153
|
-
log2(r.stdout)
|
|
154
|
-
log2(r.stderr)
|
|
155
|
-
|
|
156
|
-
return r
|
|
157
|
-
else:
|
|
158
|
-
ns = self.namespace
|
|
159
|
-
image = Config().get('pg.agent.image', 'seanahnsf/kaqing')
|
|
160
|
-
pod_name = Config().get('pg.agent.name', 'kaqing-agent')
|
|
161
|
-
timeout = Config().get('pg.agent.timeout', 3600)
|
|
162
|
-
|
|
163
|
-
try:
|
|
164
|
-
Pods.create(ns, pod_name, image, ['sleep', f'{timeout}'], env={'NAMESPACE': ns}, sa_name='c3')
|
|
165
|
-
except Exception as e:
|
|
166
|
-
if e.status == 409:
|
|
167
|
-
if Pods.completed(ns, pod_name):
|
|
168
|
-
try:
|
|
169
|
-
Pods.delete(pod_name, ns)
|
|
170
|
-
Pods.create(ns, pod_name, image, ['sleep', f'{timeout}'], env={'NAMESPACE': ns}, sa_name='c3')
|
|
171
|
-
except Exception as e2:
|
|
172
|
-
log2("Exception when calling BatchV1Api->create_pod: %s\n" % e2)
|
|
173
|
-
|
|
174
|
-
return
|
|
175
|
-
else:
|
|
176
|
-
log2("Exception when calling BatchV1Api->create_pod: %s\n" % e)
|
|
177
|
-
|
|
178
|
-
return
|
|
179
|
-
|
|
180
|
-
Pods.wait_for_running(ns, pod_name)
|
|
181
|
-
|
|
182
|
-
cmd = f'PGPASSWORD="{self.password()}" psql -h {self.endpoint()} -p {self.port()} -U {self.username()} {db} --pset pager=off -c "{sql}"'
|
|
183
|
-
|
|
184
|
-
return Pods.exec(pod_name, pod_name, ns, cmd, show_out=show_out)
|
|
185
|
-
|
|
186
|
-
def endpoint(self):
|
|
187
|
-
if not self.conn_details:
|
|
188
|
-
self.conn_details = Secrets.get_data(self.namespace, self.host)
|
|
189
|
-
|
|
190
|
-
endpoint_key = Config().get('pg.secret.endpoint-key', 'postgres-db-endpoint')
|
|
191
|
-
|
|
192
|
-
return self.conn_details[endpoint_key] if endpoint_key in self.conn_details else ''
|
|
193
|
-
|
|
194
|
-
def port(self):
|
|
195
|
-
if not self.conn_details:
|
|
196
|
-
self.conn_details = Secrets.get_data(self.namespace, self.host)
|
|
197
|
-
|
|
198
|
-
port_key = Config().get('pg.secret.port-key', 'postgres-db-port')
|
|
199
|
-
|
|
200
|
-
return self.conn_details[port_key] if port_key in self.conn_details else ''
|
|
201
|
-
|
|
202
|
-
def username(self):
|
|
203
|
-
if not self.conn_details:
|
|
204
|
-
self.conn_details = Secrets.get_data(self.namespace, self.host)
|
|
205
|
-
|
|
206
|
-
username_key = Config().get('pg.secret.username-key', 'postgres-admin-username')
|
|
207
|
-
|
|
208
|
-
return self.conn_details[username_key] if username_key in self.conn_details else ''
|
|
209
|
-
|
|
210
|
-
def password(self):
|
|
211
|
-
if not self.conn_details:
|
|
212
|
-
self.conn_details = Secrets.get_data(self.namespace, self.host)
|
|
213
|
-
|
|
214
|
-
password_key = Config().get('pg.secret.password-key', 'postgres-admin-password')
|
|
215
|
-
|
|
216
|
-
return self.conn_details[password_key] if password_key in self.conn_details else ''
|
|
217
|
-
|
|
218
|
-
def default_db():
|
|
219
|
-
return Config().get('pg.default-db', 'postgres')
|
|
220
|
-
|
|
221
|
-
def default_owner():
|
|
222
|
-
return Config().get('pg.default-owner', 'postgres')
|
|
223
|
-
|
|
224
|
-
def default_schema():
|
|
225
|
-
return Config().get('pg.default-schema', 'postgres')
|
walker/commands/preview_table.py
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
|
|
3
|
-
from walker.commands.command import Command
|
|
4
|
-
from walker.commands.cql_utils import parse_cql_desc_tables, run_cql
|
|
5
|
-
from walker.commands.postgres.postgres_session import PostgresSession
|
|
6
|
-
from walker.config import Config
|
|
7
|
-
from walker.pod_exec_result import PodExecResult
|
|
8
|
-
from walker.repl_state import ReplState, RequiredState
|
|
9
|
-
from walker.utils import lines_to_tabular, log, log2
|
|
10
|
-
|
|
11
|
-
class PreviewTable(Command):
|
|
12
|
-
COMMAND = 'preview'
|
|
13
|
-
|
|
14
|
-
# the singleton pattern
|
|
15
|
-
def __new__(cls, *args, **kwargs):
|
|
16
|
-
if not hasattr(cls, 'instance'): cls.instance = super(PreviewTable, cls).__new__(cls)
|
|
17
|
-
|
|
18
|
-
return cls.instance
|
|
19
|
-
|
|
20
|
-
def __init__(self, successor: Command=None):
|
|
21
|
-
super().__init__(successor)
|
|
22
|
-
|
|
23
|
-
def command(self):
|
|
24
|
-
return PreviewTable.COMMAND
|
|
25
|
-
|
|
26
|
-
def required(self):
|
|
27
|
-
return RequiredState.CLUSTER_OR_POD
|
|
28
|
-
|
|
29
|
-
def run(self, cmd: str, state: ReplState):
|
|
30
|
-
if not(args := self.args(cmd)):
|
|
31
|
-
return super().run(cmd, state)
|
|
32
|
-
|
|
33
|
-
state, args = self.apply_state(args, state)
|
|
34
|
-
if state.device == ReplState.P:
|
|
35
|
-
if not self.validate_state(state, RequiredState.PG_DATABASE):
|
|
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]
|
|
64
|
-
|
|
65
|
-
rows = Config().get('preview.rows', 10)
|
|
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}}
|
|
81
|
-
|
|
82
|
-
return {}
|
|
83
|
-
|
|
84
|
-
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
|
walker/commands/processes.py
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
from walker.commands.command import Command
|
|
2
|
-
from walker.commands.commands_utils import show_table
|
|
3
|
-
from walker.config import Config
|
|
4
|
-
from walker.k8s_utils.statefulsets import StatefulSets
|
|
5
|
-
from walker.repl_state import ReplState, RequiredState
|
|
6
|
-
|
|
7
|
-
class Processes(Command):
|
|
8
|
-
COMMAND = 'processes'
|
|
9
|
-
|
|
10
|
-
# the singleton pattern
|
|
11
|
-
def __new__(cls, *args, **kwargs):
|
|
12
|
-
if not hasattr(cls, 'instance'): cls.instance = super(Processes, cls).__new__(cls)
|
|
13
|
-
|
|
14
|
-
return cls.instance
|
|
15
|
-
|
|
16
|
-
def __init__(self, successor: Command=None):
|
|
17
|
-
super().__init__(successor)
|
|
18
|
-
|
|
19
|
-
def command(self):
|
|
20
|
-
return Processes.COMMAND
|
|
21
|
-
|
|
22
|
-
def required(self):
|
|
23
|
-
return RequiredState.CLUSTER_OR_POD
|
|
24
|
-
|
|
25
|
-
def run(self, cmd: str, state: ReplState):
|
|
26
|
-
if not(args := self.args(cmd)):
|
|
27
|
-
return super().run(cmd, state)
|
|
28
|
-
|
|
29
|
-
state, args = self.apply_state(args, state)
|
|
30
|
-
if not self.validate_state(state):
|
|
31
|
-
return state
|
|
32
|
-
|
|
33
|
-
args, show_output = Command.extract_options(args, ['-s', '--show'])
|
|
34
|
-
|
|
35
|
-
cols = Config().get('processes.columns', 'pod,cpu,mem')
|
|
36
|
-
header = Config().get('processes.header', 'POD_NAME,CPU,MEM/LIMIT')
|
|
37
|
-
|
|
38
|
-
if state.pod:
|
|
39
|
-
show_table(state, [state.pod], cols, header, show_output=show_output)
|
|
40
|
-
elif state.sts:
|
|
41
|
-
pod_names = [pod.metadata.name for pod in StatefulSets.pods(state.sts, state.namespace)]
|
|
42
|
-
show_table(state, pod_names, cols, header, show_output=show_output)
|
|
43
|
-
|
|
44
|
-
return state
|
|
45
|
-
|
|
46
|
-
def completion(self, state: ReplState):
|
|
47
|
-
if not state.sts:
|
|
48
|
-
return {}
|
|
49
|
-
|
|
50
|
-
return {Processes.COMMAND: None}
|
|
51
|
-
|
|
52
|
-
def help(self, _: ReplState):
|
|
53
|
-
return f'{Processes.COMMAND} [-s]\t show process overview -s show commands on nodes'
|
walker/commands/pwd.py
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
from walker.commands.command import Command
|
|
2
|
-
from walker.commands.postgres.postgres_session import PostgresSession
|
|
3
|
-
from walker.repl_state import ReplState
|
|
4
|
-
from walker.utils import lines_to_tabular, log
|
|
5
|
-
|
|
6
|
-
class Pwd(Command):
|
|
7
|
-
COMMAND = 'pwd'
|
|
8
|
-
|
|
9
|
-
# the singleton pattern
|
|
10
|
-
def __new__(cls, *args, **kwargs):
|
|
11
|
-
if not hasattr(cls, 'instance'): cls.instance = super(Pwd, 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 Pwd.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
|
-
state, args = self.apply_state(args, state)
|
|
26
|
-
|
|
27
|
-
def device_line(state: ReplState, device: str):
|
|
28
|
-
words = []
|
|
29
|
-
|
|
30
|
-
if device == ReplState.P:
|
|
31
|
-
pg = PostgresSession(state.namespace, state.pg_path)
|
|
32
|
-
|
|
33
|
-
if pg.host:
|
|
34
|
-
words.append(f'host/{pg.host}')
|
|
35
|
-
if pg.db:
|
|
36
|
-
words.append(f'database/{pg.db}')
|
|
37
|
-
elif device == ReplState.A:
|
|
38
|
-
if state.app_env:
|
|
39
|
-
words.append(f'env/{state.app_env}')
|
|
40
|
-
if state.app_app:
|
|
41
|
-
words.append(f'app/{state.app_app}')
|
|
42
|
-
else:
|
|
43
|
-
if state.sts:
|
|
44
|
-
words.append(f'sts/{state.sts}')
|
|
45
|
-
if state.pod:
|
|
46
|
-
words.append(f'pod/{state.pod}')
|
|
47
|
-
|
|
48
|
-
return '\t'.join([f'{device}:>'] + (words if words else ['/']))
|
|
49
|
-
|
|
50
|
-
log(lines_to_tabular([
|
|
51
|
-
device_line(state, ReplState.A),
|
|
52
|
-
device_line(state, ReplState.C),
|
|
53
|
-
device_line(state, ReplState.P),
|
|
54
|
-
f'NAMESPACE\t{state.namespace if state.namespace else "/"}'
|
|
55
|
-
], 'DEVICE\tLOCATION', separator='\t'))
|
|
56
|
-
log()
|
|
57
|
-
|
|
58
|
-
return state
|
|
59
|
-
|
|
60
|
-
def completion(self, state: ReplState):
|
|
61
|
-
return super().completion(state)
|
|
62
|
-
|
|
63
|
-
def help(self, _: ReplState):
|
|
64
|
-
return f'{Pwd.COMMAND}\t print current working directories'
|
walker/commands/reaper/reaper.py
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import click
|
|
2
|
-
|
|
3
|
-
from walker.commands.command import Command
|
|
4
|
-
from walker.commands.command_helpers import ClusterCommandHelper
|
|
5
|
-
from .reaper_forward import ReaperForward
|
|
6
|
-
from .reaper_forward_stop import ReaperForwardStop
|
|
7
|
-
from .reaper_restart import ReaperRestart
|
|
8
|
-
from .reaper_run_abort import ReaperRunAbort
|
|
9
|
-
from .reaper_runs import ReaperRuns
|
|
10
|
-
from .reaper_runs_abort import ReaperRunsAbort
|
|
11
|
-
from .reaper_schedule_activate import ReaperScheduleActivate
|
|
12
|
-
from .reaper_schedule_start import ReaperScheduleStart
|
|
13
|
-
from .reaper_schedule_stop import ReaperScheduleStop
|
|
14
|
-
from .reaper_schedules import ReaperSchedules
|
|
15
|
-
from .reaper_status import ReaperStatus
|
|
16
|
-
from walker.repl_state import ReplState, RequiredState
|
|
17
|
-
from walker.utils import lines_to_tabular, log, log2
|
|
18
|
-
|
|
19
|
-
class Reaper(Command):
|
|
20
|
-
COMMAND = 'reaper'
|
|
21
|
-
reaper_login = None
|
|
22
|
-
|
|
23
|
-
# the singleton pattern
|
|
24
|
-
def __new__(cls, *args, **kwargs):
|
|
25
|
-
if not hasattr(cls, 'instance'): cls.instance = super(Reaper, cls).__new__(cls)
|
|
26
|
-
|
|
27
|
-
return cls.instance
|
|
28
|
-
|
|
29
|
-
def __init__(self, successor: Command=None):
|
|
30
|
-
super().__init__(successor)
|
|
31
|
-
|
|
32
|
-
def command(self):
|
|
33
|
-
return Reaper.COMMAND
|
|
34
|
-
|
|
35
|
-
def required(self):
|
|
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=':'))
|
|
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():
|
|
58
|
-
return [ReaperSchedules(), ReaperScheduleStop(), ReaperScheduleActivate(), ReaperScheduleStart(),
|
|
59
|
-
ReaperForwardStop(), ReaperForward(), ReaperRunAbort(), ReaperRunsAbort(), ReaperRestart(), ReaperRuns(), ReaperStatus()]
|
|
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
|
|
69
|
-
|
|
70
|
-
class ReaperCommandHelper(click.Command):
|
|
71
|
-
def get_help(self, ctx: click.Context):
|
|
72
|
-
log(super().get_help(ctx))
|
|
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=':'))
|
|
77
|
-
log()
|
|
78
|
-
ClusterCommandHelper.cluster_help()
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import threading
|
|
2
|
-
import time
|
|
3
|
-
|
|
4
|
-
from walker.commands.command import Command
|
|
5
|
-
from .reaper_session import ReaperSession
|
|
6
|
-
from walker.config import Config
|
|
7
|
-
from walker.repl_session import ReplSession
|
|
8
|
-
from walker.repl_state import ReplState, RequiredState
|
|
9
|
-
from walker.utils import lines_to_tabular, log2
|
|
10
|
-
|
|
11
|
-
class ReaperForward(Command):
|
|
12
|
-
COMMAND = 'reaper forward'
|
|
13
|
-
reaper_login = None
|
|
14
|
-
|
|
15
|
-
# the singleton pattern
|
|
16
|
-
def __new__(cls, *args, **kwargs):
|
|
17
|
-
if not hasattr(cls, 'instance'): cls.instance = super(ReaperForward, cls).__new__(cls)
|
|
18
|
-
|
|
19
|
-
return cls.instance
|
|
20
|
-
|
|
21
|
-
def __init__(self, successor: Command=None):
|
|
22
|
-
super().__init__(successor)
|
|
23
|
-
|
|
24
|
-
def command(self):
|
|
25
|
-
return ReaperForward.COMMAND
|
|
26
|
-
|
|
27
|
-
def required(self):
|
|
28
|
-
return RequiredState.CLUSTER
|
|
29
|
-
|
|
30
|
-
def run(self, cmd: str, state: ReplState):
|
|
31
|
-
if not(args := self.args(cmd)):
|
|
32
|
-
return super().run(cmd, state)
|
|
33
|
-
|
|
34
|
-
state, args = self.apply_state(args, state)
|
|
35
|
-
if not self.validate_state(state):
|
|
36
|
-
return state
|
|
37
|
-
|
|
38
|
-
if not(reaper := ReaperSession.create(state)):
|
|
39
|
-
return state
|
|
40
|
-
|
|
41
|
-
spec = reaper.reaper_spec(state)
|
|
42
|
-
if state.in_repl:
|
|
43
|
-
if ReaperSession.is_forwarding:
|
|
44
|
-
log2("Another port-forward is already running.")
|
|
45
|
-
|
|
46
|
-
return "already-running"
|
|
47
|
-
|
|
48
|
-
# make it a daemon to exit with a Ctrl-D
|
|
49
|
-
thread = threading.Thread(target=self.loop, args=(state, reaper), daemon=True)
|
|
50
|
-
thread.start()
|
|
51
|
-
|
|
52
|
-
while not ReaperSession.is_forwarding:
|
|
53
|
-
time.sleep(1)
|
|
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"]}')
|
|
72
|
-
log2()
|
|
73
|
-
log2(f"Press Ctrl+C to break.")
|
|
74
|
-
|
|
75
|
-
time.sleep(Config().get('reaper.port-forward.timeout', 3600 * 24))
|
|
76
|
-
except KeyboardInterrupt:
|
|
77
|
-
pass
|
|
78
|
-
|
|
79
|
-
return state
|
|
80
|
-
|
|
81
|
-
def loop(self, state: ReplState, reaper: ReaperSession):
|
|
82
|
-
def body(uri: str, _: dict[str, str]):
|
|
83
|
-
ReaperSession.is_forwarding = True
|
|
84
|
-
try:
|
|
85
|
-
while not ReaperSession.stopping.is_set():
|
|
86
|
-
time.sleep(1)
|
|
87
|
-
finally:
|
|
88
|
-
ReaperSession.stopping.clear()
|
|
89
|
-
ReaperSession.is_forwarding = False
|
|
90
|
-
|
|
91
|
-
return reaper.port_forwarded(state, 'webui', body)
|
|
92
|
-
|
|
93
|
-
def completion(self, state: ReplState):
|
|
94
|
-
if state.sts:
|
|
95
|
-
return super().completion(state)
|
|
96
|
-
|
|
97
|
-
return {}
|
|
98
|
-
|
|
99
|
-
def help(self, _: ReplState):
|
|
100
|
-
return f'{ReaperForward.COMMAND}\t port-forward to reaper'
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import requests
|
|
2
|
-
|
|
3
|
-
from walker.commands.command import Command
|
|
4
|
-
from .reaper_session import ReaperSession
|
|
5
|
-
from walker.repl_state import ReplState, RequiredState
|
|
6
|
-
from walker.utils import log2
|
|
7
|
-
|
|
8
|
-
class ReaperRunAbort(Command):
|
|
9
|
-
COMMAND = 'reaper abort run'
|
|
10
|
-
reaper_login = None
|
|
11
|
-
|
|
12
|
-
# the singleton pattern
|
|
13
|
-
def __new__(cls, *args, **kwargs):
|
|
14
|
-
if not hasattr(cls, 'instance'): cls.instance = super(ReaperRunAbort, cls).__new__(cls)
|
|
15
|
-
|
|
16
|
-
return cls.instance
|
|
17
|
-
|
|
18
|
-
def __init__(self, successor: Command=None):
|
|
19
|
-
super().__init__(successor)
|
|
20
|
-
|
|
21
|
-
def command(self):
|
|
22
|
-
return ReaperRunAbort.COMMAND
|
|
23
|
-
|
|
24
|
-
def required(self):
|
|
25
|
-
return RequiredState.CLUSTER
|
|
26
|
-
|
|
27
|
-
def run(self, cmd: str, state: ReplState):
|
|
28
|
-
if not(args := self.args(cmd)):
|
|
29
|
-
return super().run(cmd, state)
|
|
30
|
-
|
|
31
|
-
state, args = self.apply_state(args, state)
|
|
32
|
-
if not self.validate_state(state):
|
|
33
|
-
return state
|
|
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
|
|
45
|
-
|
|
46
|
-
self.stop_run(state, reaper, args[0])
|
|
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')
|
|
57
|
-
|
|
58
|
-
def completion(self, state: ReplState):
|
|
59
|
-
if state.sts:
|
|
60
|
-
return super().completion(state)
|
|
61
|
-
|
|
62
|
-
return {}
|
|
63
|
-
|
|
64
|
-
def help(self, _: ReplState):
|
|
65
|
-
return f'{ReaperRunAbort.COMMAND} <run-id>\t abort reaper run'
|