paasta-tools 1.27.0__py3-none-any.whl → 1.35.8__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 paasta-tools might be problematic. Click here for more details.
- paasta_tools/__init__.py +1 -1
- paasta_tools/api/api_docs/swagger.json +9 -1
- paasta_tools/api/tweens/auth.py +2 -1
- paasta_tools/api/views/instance.py +9 -2
- paasta_tools/api/views/remote_run.py +2 -0
- paasta_tools/async_utils.py +4 -1
- paasta_tools/bounce_lib.py +8 -5
- paasta_tools/check_services_replication_tools.py +10 -4
- paasta_tools/check_spark_jobs.py +1 -1
- paasta_tools/cli/cli.py +4 -4
- paasta_tools/cli/cmds/autoscale.py +2 -0
- paasta_tools/cli/cmds/check.py +2 -0
- paasta_tools/cli/cmds/cook_image.py +2 -0
- paasta_tools/cli/cmds/get_docker_image.py +2 -0
- paasta_tools/cli/cmds/get_image_version.py +2 -0
- paasta_tools/cli/cmds/get_latest_deployment.py +2 -0
- paasta_tools/cli/cmds/info.py +10 -3
- paasta_tools/cli/cmds/itest.py +2 -0
- paasta_tools/cli/cmds/list_namespaces.py +2 -0
- paasta_tools/cli/cmds/local_run.py +122 -27
- paasta_tools/cli/cmds/logs.py +31 -7
- paasta_tools/cli/cmds/mark_for_deployment.py +14 -4
- paasta_tools/cli/cmds/mesh_status.py +3 -2
- paasta_tools/cli/cmds/push_to_registry.py +2 -0
- paasta_tools/cli/cmds/remote_run.py +156 -12
- paasta_tools/cli/cmds/rollback.py +6 -2
- paasta_tools/cli/cmds/secret.py +4 -2
- paasta_tools/cli/cmds/security_check.py +2 -0
- paasta_tools/cli/cmds/spark_run.py +7 -3
- paasta_tools/cli/cmds/status.py +59 -29
- paasta_tools/cli/cmds/validate.py +325 -40
- paasta_tools/cli/cmds/wait_for_deployment.py +2 -0
- paasta_tools/cli/schemas/adhoc_schema.json +3 -0
- paasta_tools/cli/schemas/autoscaling_schema.json +3 -2
- paasta_tools/cli/schemas/eks_schema.json +24 -1
- paasta_tools/cli/schemas/kubernetes_schema.json +1 -0
- paasta_tools/cli/schemas/smartstack_schema.json +14 -0
- paasta_tools/cli/utils.py +34 -20
- paasta_tools/contrib/bounce_log_latency_parser.py +1 -1
- paasta_tools/contrib/check_orphans.py +1 -1
- paasta_tools/contrib/get_running_task_allocation.py +1 -1
- paasta_tools/contrib/ide_helper.py +14 -14
- paasta_tools/contrib/mock_patch_checker.py +1 -1
- paasta_tools/contrib/paasta_update_soa_memcpu.py +10 -14
- paasta_tools/contrib/render_template.py +1 -1
- paasta_tools/contrib/shared_ip_check.py +1 -1
- paasta_tools/generate_deployments_for_service.py +2 -0
- paasta_tools/instance/hpa_metrics_parser.py +3 -5
- paasta_tools/instance/kubernetes.py +70 -36
- paasta_tools/kubernetes/application/controller_wrappers.py +23 -2
- paasta_tools/kubernetes/remote_run.py +52 -25
- paasta_tools/kubernetes_tools.py +60 -69
- paasta_tools/long_running_service_tools.py +15 -5
- paasta_tools/mesos/master.py +1 -1
- paasta_tools/metrics/metastatus_lib.py +1 -25
- paasta_tools/metrics/metrics_lib.py +12 -3
- paasta_tools/paastaapi/__init__.py +1 -1
- paasta_tools/paastaapi/api/autoscaler_api.py +1 -1
- paasta_tools/paastaapi/api/default_api.py +1 -1
- paasta_tools/paastaapi/api/remote_run_api.py +1 -1
- paasta_tools/paastaapi/api/resources_api.py +1 -1
- paasta_tools/paastaapi/api/service_api.py +1 -1
- paasta_tools/paastaapi/api_client.py +1 -1
- paasta_tools/paastaapi/configuration.py +2 -2
- paasta_tools/paastaapi/exceptions.py +1 -1
- paasta_tools/paastaapi/model/adhoc_launch_history.py +1 -1
- paasta_tools/paastaapi/model/autoscaler_count_msg.py +1 -1
- paasta_tools/paastaapi/model/autoscaling_override.py +1 -1
- paasta_tools/paastaapi/model/deploy_queue.py +1 -1
- paasta_tools/paastaapi/model/deploy_queue_service_instance.py +1 -1
- paasta_tools/paastaapi/model/envoy_backend.py +1 -1
- paasta_tools/paastaapi/model/envoy_location.py +1 -1
- paasta_tools/paastaapi/model/envoy_status.py +1 -1
- paasta_tools/paastaapi/model/flink_cluster_overview.py +1 -1
- paasta_tools/paastaapi/model/flink_config.py +1 -1
- paasta_tools/paastaapi/model/flink_job.py +1 -1
- paasta_tools/paastaapi/model/flink_job_details.py +1 -1
- paasta_tools/paastaapi/model/flink_jobs.py +1 -1
- paasta_tools/paastaapi/model/float_and_error.py +1 -1
- paasta_tools/paastaapi/model/hpa_metric.py +1 -1
- paasta_tools/paastaapi/model/inline_object.py +1 -1
- paasta_tools/paastaapi/model/inline_response200.py +1 -1
- paasta_tools/paastaapi/model/inline_response2001.py +1 -1
- paasta_tools/paastaapi/model/inline_response202.py +1 -1
- paasta_tools/paastaapi/model/inline_response403.py +1 -1
- paasta_tools/paastaapi/model/instance_bounce_status.py +1 -1
- paasta_tools/paastaapi/model/instance_mesh_status.py +1 -1
- paasta_tools/paastaapi/model/instance_status.py +1 -1
- paasta_tools/paastaapi/model/instance_status_adhoc.py +1 -1
- paasta_tools/paastaapi/model/instance_status_cassandracluster.py +1 -1
- paasta_tools/paastaapi/model/instance_status_flink.py +1 -1
- paasta_tools/paastaapi/model/instance_status_kafkacluster.py +1 -1
- paasta_tools/paastaapi/model/instance_status_kubernetes.py +1 -1
- paasta_tools/paastaapi/model/instance_status_kubernetes_autoscaling_status.py +1 -1
- paasta_tools/paastaapi/model/instance_status_kubernetes_v2.py +1 -1
- paasta_tools/paastaapi/model/instance_status_tron.py +1 -1
- paasta_tools/paastaapi/model/instance_tasks.py +1 -1
- paasta_tools/paastaapi/model/integer_and_error.py +1 -1
- paasta_tools/paastaapi/model/kubernetes_container.py +1 -1
- paasta_tools/paastaapi/model/kubernetes_container_v2.py +1 -1
- paasta_tools/paastaapi/model/kubernetes_healthcheck.py +1 -1
- paasta_tools/paastaapi/model/kubernetes_pod.py +1 -1
- paasta_tools/paastaapi/model/kubernetes_pod_event.py +1 -1
- paasta_tools/paastaapi/model/kubernetes_pod_v2.py +1 -1
- paasta_tools/paastaapi/model/kubernetes_replica_set.py +1 -1
- paasta_tools/paastaapi/model/kubernetes_version.py +4 -1
- paasta_tools/paastaapi/model/remote_run_outcome.py +1 -1
- paasta_tools/paastaapi/model/remote_run_start.py +4 -1
- paasta_tools/paastaapi/model/remote_run_stop.py +1 -1
- paasta_tools/paastaapi/model/remote_run_token.py +1 -1
- paasta_tools/paastaapi/model/resource.py +1 -1
- paasta_tools/paastaapi/model/resource_item.py +1 -1
- paasta_tools/paastaapi/model/resource_value.py +1 -1
- paasta_tools/paastaapi/model/smartstack_backend.py +1 -1
- paasta_tools/paastaapi/model/smartstack_location.py +1 -1
- paasta_tools/paastaapi/model/smartstack_status.py +1 -1
- paasta_tools/paastaapi/model/task_tail_lines.py +1 -1
- paasta_tools/paastaapi/model_utils.py +1 -1
- paasta_tools/paastaapi/rest.py +1 -1
- paasta_tools/remote_git.py +2 -2
- paasta_tools/run-paasta-api-in-dev-mode.py +2 -2
- paasta_tools/run-paasta-api-playground.py +2 -2
- paasta_tools/setup_kubernetes_job.py +43 -1
- paasta_tools/setup_prometheus_adapter_config.py +82 -0
- paasta_tools/setup_tron_namespace.py +2 -2
- paasta_tools/tron_tools.py +4 -1
- paasta_tools/utils.py +29 -11
- paasta_tools/yaml_tools.py +1 -1
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/check_orphans.py +1 -1
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/check_spark_jobs.py +1 -1
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/generate_deployments_for_service.py +2 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/get_running_task_allocation.py +1 -1
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/ide_helper.py +14 -14
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/paasta_update_soa_memcpu.py +10 -14
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/setup_kubernetes_job.py +43 -1
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/setup_prometheus_adapter_config.py +82 -0
- paasta_tools-1.35.8.dist-info/METADATA +79 -0
- {paasta_tools-1.27.0.dist-info → paasta_tools-1.35.8.dist-info}/RECORD +186 -191
- {paasta_tools-1.27.0.dist-info → paasta_tools-1.35.8.dist-info}/WHEEL +1 -1
- paasta_tools/frameworks/adhoc_scheduler.py +0 -71
- paasta_tools/frameworks/native_scheduler.py +0 -652
- paasta_tools/frameworks/task_store.py +0 -245
- paasta_tools/mesos_maintenance.py +0 -848
- paasta_tools/paasta_native_serviceinit.py +0 -21
- paasta_tools-1.27.0.dist-info/METADATA +0 -75
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/apply_external_resources.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/bounce_log_latency_parser.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/check_autoscaler_max_instances.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/check_cassandracluster_services_replication.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/check_flink_services_health.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/check_kubernetes_api.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/check_kubernetes_services_replication.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/check_manual_oapi_changes.sh +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/check_oom_events.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/cleanup_kubernetes_cr.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/cleanup_kubernetes_crd.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/cleanup_kubernetes_jobs.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/create_dynamodb_table.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/create_paasta_playground.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/delete_kubernetes_deployments.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/emit_allocated_cpu_metrics.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/generate_all_deployments +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/generate_authenticating_services.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/generate_services_file.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/generate_services_yaml.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/habitat_fixer.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/is_pod_healthy_in_proxy.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/is_pod_healthy_in_smartstack.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/kill_bad_containers.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/kubernetes_remove_evicted_pods.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/mass-deploy-tag.sh +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/mock_patch_checker.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/paasta_cleanup_remote_run_resources.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/paasta_cleanup_stale_nodes.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/paasta_deploy_tron_jobs +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/paasta_execute_docker_command.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/paasta_secrets_sync.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/paasta_tabcomplete.sh +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/render_template.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/rightsizer_soaconfigs_update.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/service_shard_remove.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/service_shard_update.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/setup_istio_mesh.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/setup_kubernetes_cr.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/setup_kubernetes_crd.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/setup_kubernetes_internal_crd.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/shared_ip_check.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/synapse_srv_namespaces_fact.py +0 -0
- {paasta_tools-1.27.0.data → paasta_tools-1.35.8.data}/scripts/timeouts_metrics_prom.py +0 -0
- {paasta_tools-1.27.0.dist-info → paasta_tools-1.35.8.dist-info}/entry_points.txt +0 -0
- {paasta_tools-1.27.0.dist-info → paasta_tools-1.35.8.dist-info/licenses}/LICENSE +0 -0
- {paasta_tools-1.27.0.dist-info → paasta_tools-1.35.8.dist-info}/top_level.txt +0 -0
|
@@ -157,6 +157,8 @@ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
157
157
|
help="Name of the service which you wish to mark for deployment. Leading "
|
|
158
158
|
'"services-" will be stripped.',
|
|
159
159
|
required=True,
|
|
160
|
+
# strip any potential trailing / for folks tab-completing directories
|
|
161
|
+
type=lambda x: x.rstrip("/"),
|
|
160
162
|
)
|
|
161
163
|
arg_service.completer = lazy_choices_completer(list_services) # type: ignore
|
|
162
164
|
list_parser.add_argument(
|
|
@@ -1157,7 +1159,7 @@ class MarkForDeploymentProcess(RollbackSlackDeploymentProcess):
|
|
|
1157
1159
|
|
|
1158
1160
|
def on_enter_deploy_errored(self) -> None:
|
|
1159
1161
|
report_waiting_aborted(self.service, self.deploy_group)
|
|
1160
|
-
self.update_slack_status(
|
|
1162
|
+
self.update_slack_status("Deploy aborted, but it will still try to converge.")
|
|
1161
1163
|
self.send_manual_rollback_instructions()
|
|
1162
1164
|
if self.deploy_group_is_set_to_notify("notify_after_abort"):
|
|
1163
1165
|
self.ping_authors("Deploy errored")
|
|
@@ -1264,7 +1266,15 @@ class MarkForDeploymentProcess(RollbackSlackDeploymentProcess):
|
|
|
1264
1266
|
self.ping_authors()
|
|
1265
1267
|
|
|
1266
1268
|
def send_manual_rollback_instructions(self) -> None:
|
|
1267
|
-
|
|
1269
|
+
# NOTE: new deploy groups are not exactly a particularly frequent occurrence, but
|
|
1270
|
+
# we want to prevent sending messages that look like
|
|
1271
|
+
# `If you need to roll back manually, run: paasta rollback --service $S --deploy-group $G --commit None`
|
|
1272
|
+
# since that's not actually valid/actionable.
|
|
1273
|
+
# thus the seemingly out-of-nowhere old_git_sha check: new deploy groups won't have value set there.
|
|
1274
|
+
if (
|
|
1275
|
+
self.deployment_version != self.old_deployment_version
|
|
1276
|
+
and self.old_git_sha is not None
|
|
1277
|
+
):
|
|
1268
1278
|
extra_rollback_args = ""
|
|
1269
1279
|
if self.old_deployment_version.image_version:
|
|
1270
1280
|
extra_rollback_args = (
|
|
@@ -1317,7 +1327,7 @@ class MarkForDeploymentProcess(RollbackSlackDeploymentProcess):
|
|
|
1317
1327
|
inactive_button_texts = {
|
|
1318
1328
|
"forward": f"Continue Forward to {version_short_str} :arrow_forward:",
|
|
1319
1329
|
"complete": f"Complete deploy to {version_short_str} :white_check_mark:",
|
|
1320
|
-
"snooze":
|
|
1330
|
+
"snooze": "Reset countdown",
|
|
1321
1331
|
"enable_auto_rollbacks": "Enable auto rollbacks :eyes:",
|
|
1322
1332
|
"disable_auto_rollbacks": "Disable auto rollbacks :close_eyes_monkey:",
|
|
1323
1333
|
}
|
|
@@ -1843,7 +1853,7 @@ async def wait_for_deployment(
|
|
|
1843
1853
|
system_paasta_config.get_mark_for_deployment_default_time_before_first_diagnosis()
|
|
1844
1854
|
)
|
|
1845
1855
|
|
|
1846
|
-
with progressbar.ProgressBar(
|
|
1856
|
+
with progressbar.ProgressBar(max_value=total_instances) as bar:
|
|
1847
1857
|
instance_done_futures = []
|
|
1848
1858
|
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
1849
1859
|
for cluster, instance_configs in instance_configs_per_cluster.items():
|
|
@@ -44,9 +44,10 @@ def add_subparser(subparsers) -> None:
|
|
|
44
44
|
mesh_status_parser.add_argument(
|
|
45
45
|
"-s",
|
|
46
46
|
"--service",
|
|
47
|
-
type=str,
|
|
48
47
|
help="The name of the service you wish to inspect",
|
|
49
48
|
required=True,
|
|
49
|
+
# strip any potential trailing / for folks tab-completing directories
|
|
50
|
+
type=lambda x: x.rstrip("/"),
|
|
50
51
|
).completer = lazy_choices_completer(list_services)
|
|
51
52
|
mesh_status_parser.add_argument(
|
|
52
53
|
"-i",
|
|
@@ -124,7 +125,7 @@ def paasta_mesh_status_on_api_endpoint(
|
|
|
124
125
|
[PaastaColors.red(f"Could not connect to API: {exc.__class__.__name__}")],
|
|
125
126
|
)
|
|
126
127
|
except Exception as e:
|
|
127
|
-
output = [PaastaColors.red(
|
|
128
|
+
output = [PaastaColors.red("Exception when talking to the API:")]
|
|
128
129
|
output.extend(str(e).split("\n"))
|
|
129
130
|
return 1, output
|
|
130
131
|
|
|
@@ -62,6 +62,8 @@ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
62
62
|
help='Name of service for which you wish to upload a docker image. Leading "services-", '
|
|
63
63
|
"as included in a Jenkins job name, will be stripped.",
|
|
64
64
|
required=True,
|
|
65
|
+
# strip any potential trailing / for folks tab-completing directories
|
|
66
|
+
type=lambda x: x.rstrip("/"),
|
|
65
67
|
)
|
|
66
68
|
list_parser.add_argument(
|
|
67
69
|
"-c",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
import argparse
|
|
16
16
|
import json
|
|
17
|
+
import os
|
|
17
18
|
import shutil
|
|
18
19
|
import subprocess
|
|
19
20
|
import sys
|
|
@@ -24,6 +25,8 @@ from paasta_tools.cli.utils import get_paasta_oapi_api_clustername
|
|
|
24
25
|
from paasta_tools.cli.utils import get_paasta_oapi_client_with_auth
|
|
25
26
|
from paasta_tools.cli.utils import lazy_choices_completer
|
|
26
27
|
from paasta_tools.cli.utils import run_interactive_cli
|
|
28
|
+
from paasta_tools.kubernetes.remote_run import format_remote_run_job_name
|
|
29
|
+
from paasta_tools.kubernetes.remote_run import load_eks_or_adhoc_deployment_config
|
|
27
30
|
from paasta_tools.kubernetes.remote_run import TOOLBOX_MOCK_SERVICE
|
|
28
31
|
from paasta_tools.paastaapi.exceptions import ApiException
|
|
29
32
|
from paasta_tools.paastaapi.model.remote_run_start import RemoteRunStart
|
|
@@ -39,8 +42,14 @@ from paasta_tools.utils import SystemPaastaConfig
|
|
|
39
42
|
KUBECTL_EXEC_CMD_TEMPLATE = (
|
|
40
43
|
"{kubectl_wrapper} --token {token} exec -it -n {namespace} {pod} -- /bin/bash"
|
|
41
44
|
)
|
|
42
|
-
|
|
43
|
-
"{kubectl_wrapper} --token {token} -n {namespace} cp {
|
|
45
|
+
KUBECTL_CP_TO_CMD_TEMPLATE = (
|
|
46
|
+
"{kubectl_wrapper} --token {token} -n {namespace} cp {source} {pod}:{dest}"
|
|
47
|
+
)
|
|
48
|
+
KUBECTL_CP_FROM_CMD_TEMPLATE = (
|
|
49
|
+
"{kubectl_wrapper} --token {token} -n {namespace} cp {pod}:{source} {dest}"
|
|
50
|
+
)
|
|
51
|
+
KUBECTL_LOGS_CMD_TEMPLATE = (
|
|
52
|
+
"{kubectl_wrapper} --token {token} logs -n {namespace} -f {pod}"
|
|
44
53
|
)
|
|
45
54
|
|
|
46
55
|
|
|
@@ -59,6 +68,13 @@ def _list_services_and_toolboxes() -> List[str]:
|
|
|
59
68
|
)
|
|
60
69
|
|
|
61
70
|
|
|
71
|
+
def _get_kubectl_wrapper(cluster: str) -> str:
|
|
72
|
+
kubectl_wrapper = f"kubectl-eks-{cluster}"
|
|
73
|
+
if not shutil.which(kubectl_wrapper):
|
|
74
|
+
kubectl_wrapper = f"kubectl-{cluster}"
|
|
75
|
+
return kubectl_wrapper
|
|
76
|
+
|
|
77
|
+
|
|
62
78
|
def parse_error(body: str) -> str:
|
|
63
79
|
try:
|
|
64
80
|
body_object = json.loads(body)
|
|
@@ -71,6 +87,81 @@ def parse_error(body: str) -> str:
|
|
|
71
87
|
)
|
|
72
88
|
|
|
73
89
|
|
|
90
|
+
def paasta_remote_run_copy(
|
|
91
|
+
args: argparse.Namespace,
|
|
92
|
+
system_paasta_config: SystemPaastaConfig,
|
|
93
|
+
) -> int:
|
|
94
|
+
client = get_paasta_oapi_client_with_auth(
|
|
95
|
+
cluster=get_paasta_oapi_api_clustername(cluster=args.cluster, is_eks=True),
|
|
96
|
+
system_paasta_config=system_paasta_config,
|
|
97
|
+
)
|
|
98
|
+
if not client:
|
|
99
|
+
print("Cannot get a paasta-api client")
|
|
100
|
+
return 1
|
|
101
|
+
|
|
102
|
+
# Create the config and extract the job name
|
|
103
|
+
user = get_username()
|
|
104
|
+
deployment_config = load_eks_or_adhoc_deployment_config(
|
|
105
|
+
args.service, args.instance, args.cluster, args.toolbox, user
|
|
106
|
+
)
|
|
107
|
+
deployment_name = deployment_config.get_sanitised_deployment_name()
|
|
108
|
+
job_name = format_remote_run_job_name(deployment_name, user)
|
|
109
|
+
|
|
110
|
+
poll_response = client.remote_run.remote_run_poll(
|
|
111
|
+
service=args.service,
|
|
112
|
+
instance=args.instance,
|
|
113
|
+
job_name=job_name,
|
|
114
|
+
user=user,
|
|
115
|
+
toolbox=args.toolbox,
|
|
116
|
+
)
|
|
117
|
+
if poll_response.status != 200:
|
|
118
|
+
print(
|
|
119
|
+
"Unable to find running remote-run pod: have you started one with `paasta remote-run start`?"
|
|
120
|
+
)
|
|
121
|
+
return 1
|
|
122
|
+
|
|
123
|
+
if args.to_pod:
|
|
124
|
+
# Create the toolbox copy command
|
|
125
|
+
exec_command = f"scp -A {args.copy_file_source} {poll_response.pod_address}:{args.copy_file_dest}"
|
|
126
|
+
# Pick the correct template and force /tmp/ for non-toolbox
|
|
127
|
+
kubectl_cp_template = KUBECTL_CP_TO_CMD_TEMPLATE
|
|
128
|
+
if not args.copy_file_dest.startswith("/tmp") and not args.toolbox:
|
|
129
|
+
args.copy_file_dest = os.path.join("/tmp/", args.copy_file_dest)
|
|
130
|
+
else:
|
|
131
|
+
exec_command = f"scp -A {poll_response.pod_address}:{args.copy_file_source} {args.copy_file_dest}"
|
|
132
|
+
kubectl_cp_template = KUBECTL_CP_FROM_CMD_TEMPLATE
|
|
133
|
+
|
|
134
|
+
# Kubectl cp doesnt like directories as a destination
|
|
135
|
+
if os.path.isdir(args.copy_file_dest):
|
|
136
|
+
args.copy_file_dest = os.path.join(
|
|
137
|
+
args.copy_file_dest, os.path.basename(args.copy_file_source)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
if args.toolbox:
|
|
141
|
+
cp_command = exec_command.split(" ")
|
|
142
|
+
else:
|
|
143
|
+
token_response = client.remote_run.remote_run_token(
|
|
144
|
+
args.service, args.instance, user
|
|
145
|
+
)
|
|
146
|
+
kubectl_wrapper = _get_kubectl_wrapper(args.cluster)
|
|
147
|
+
cp_command = kubectl_cp_template.format(
|
|
148
|
+
kubectl_wrapper=kubectl_wrapper,
|
|
149
|
+
namespace=poll_response.namespace,
|
|
150
|
+
pod=poll_response.pod_name,
|
|
151
|
+
source=args.copy_file_source,
|
|
152
|
+
dest=args.copy_file_dest,
|
|
153
|
+
token=token_response.token,
|
|
154
|
+
).split(" ")
|
|
155
|
+
call = subprocess.run(cp_command, capture_output=True)
|
|
156
|
+
if call.returncode != 0:
|
|
157
|
+
print("Error copying file from remote-run pod: ", file=sys.stderr)
|
|
158
|
+
print(call.stderr.decode("utf-8"), file=sys.stderr)
|
|
159
|
+
return 1
|
|
160
|
+
print(f"{args.copy_file_source} successfully copied to {args.copy_file_dest}")
|
|
161
|
+
|
|
162
|
+
return 0
|
|
163
|
+
|
|
164
|
+
|
|
74
165
|
def paasta_remote_run_start(
|
|
75
166
|
args: argparse.Namespace,
|
|
76
167
|
system_paasta_config: SystemPaastaConfig,
|
|
@@ -84,7 +175,6 @@ def paasta_remote_run_start(
|
|
|
84
175
|
if not client:
|
|
85
176
|
print("Cannot get a paasta-api client")
|
|
86
177
|
return 1
|
|
87
|
-
|
|
88
178
|
user = get_username()
|
|
89
179
|
try:
|
|
90
180
|
start_response = client.remote_run.remote_run_start(
|
|
@@ -96,6 +186,7 @@ def paasta_remote_run_start(
|
|
|
96
186
|
recreate=args.recreate,
|
|
97
187
|
max_duration=args.max_duration,
|
|
98
188
|
toolbox=args.toolbox,
|
|
189
|
+
command=args.cmd or "",
|
|
99
190
|
),
|
|
100
191
|
)
|
|
101
192
|
except ApiException as e:
|
|
@@ -132,7 +223,7 @@ def paasta_remote_run_start(
|
|
|
132
223
|
print(f"{status_prefix}Timed out while waiting for job to start")
|
|
133
224
|
return 1
|
|
134
225
|
|
|
135
|
-
if not args.interactive
|
|
226
|
+
if not (args.interactive or args.toolbox or args.follow):
|
|
136
227
|
print("Successfully started remote-run job")
|
|
137
228
|
return 0
|
|
138
229
|
|
|
@@ -148,10 +239,10 @@ def paasta_remote_run_start(
|
|
|
148
239
|
token_response = client.remote_run.remote_run_token(
|
|
149
240
|
args.service, args.instance, user
|
|
150
241
|
)
|
|
151
|
-
kubectl_wrapper =
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
242
|
+
kubectl_wrapper = _get_kubectl_wrapper(args.cluster)
|
|
243
|
+
exec_command = (
|
|
244
|
+
KUBECTL_LOGS_CMD_TEMPLATE if args.follow else KUBECTL_EXEC_CMD_TEMPLATE
|
|
245
|
+
).format(
|
|
155
246
|
kubectl_wrapper=kubectl_wrapper,
|
|
156
247
|
namespace=poll_response.namespace,
|
|
157
248
|
pod=poll_response.pod_name,
|
|
@@ -160,11 +251,12 @@ def paasta_remote_run_start(
|
|
|
160
251
|
|
|
161
252
|
if args.copy_file:
|
|
162
253
|
for filename in args.copy_file:
|
|
163
|
-
cp_command =
|
|
254
|
+
cp_command = KUBECTL_CP_TO_CMD_TEMPLATE.format(
|
|
164
255
|
kubectl_wrapper=kubectl_wrapper,
|
|
165
256
|
namespace=poll_response.namespace,
|
|
166
257
|
pod=poll_response.pod_name,
|
|
167
|
-
|
|
258
|
+
source=filename,
|
|
259
|
+
dest=os.path.join("/tmp", os.path.basename(filename)),
|
|
168
260
|
token=token_response.token,
|
|
169
261
|
).split(" ")
|
|
170
262
|
call = subprocess.run(cp_command, capture_output=True)
|
|
@@ -203,11 +295,20 @@ def paasta_remote_run_stop(
|
|
|
203
295
|
|
|
204
296
|
|
|
205
297
|
def add_common_args_to_parser(parser: argparse.ArgumentParser):
|
|
298
|
+
def _validate_service_name(name: str) -> str:
|
|
299
|
+
# remove trailing slash if present for folks tab-completing directories
|
|
300
|
+
if name.rstrip("/") not in _list_services_and_toolboxes():
|
|
301
|
+
raise ValueError(f"{name} is not a known service name")
|
|
302
|
+
return name
|
|
303
|
+
|
|
206
304
|
service_arg = parser.add_argument(
|
|
207
305
|
"-s",
|
|
208
306
|
"--service",
|
|
209
307
|
help="The name of the service you wish to inspect. Required.",
|
|
210
308
|
required=True,
|
|
309
|
+
# not using `choices` for validation to avoid the help text
|
|
310
|
+
# for the command being incredibly large
|
|
311
|
+
type=_validate_service_name,
|
|
211
312
|
)
|
|
212
313
|
service_arg.completer = lazy_choices_completer(_list_services_and_toolboxes) # type: ignore
|
|
213
314
|
instance_or_toolbox = parser.add_mutually_exclusive_group()
|
|
@@ -231,6 +332,7 @@ def add_common_args_to_parser(parser: argparse.ArgumentParser):
|
|
|
231
332
|
"--cluster",
|
|
232
333
|
help="The name of the cluster you wish to run your task on. Required.",
|
|
233
334
|
required=True,
|
|
335
|
+
choices=list_clusters(),
|
|
234
336
|
)
|
|
235
337
|
cluster_arg.completer = lazy_choices_completer(list_clusters) # type: ignore
|
|
236
338
|
|
|
@@ -249,7 +351,8 @@ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
249
351
|
description="Starts or connects to a remote-run-job",
|
|
250
352
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
251
353
|
)
|
|
252
|
-
start_parser.
|
|
354
|
+
cmd_or_interactive = start_parser.add_mutually_exclusive_group()
|
|
355
|
+
cmd_or_interactive.add_argument(
|
|
253
356
|
"-I",
|
|
254
357
|
"--interactive",
|
|
255
358
|
help=(
|
|
@@ -259,6 +362,15 @@ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
259
362
|
action="store_true",
|
|
260
363
|
default=False,
|
|
261
364
|
)
|
|
365
|
+
cmd_or_interactive.add_argument(
|
|
366
|
+
"-C",
|
|
367
|
+
"--cmd",
|
|
368
|
+
help=(
|
|
369
|
+
"Run container with particular command, rather than the one specified in soa-configs"
|
|
370
|
+
),
|
|
371
|
+
required=False,
|
|
372
|
+
default=None,
|
|
373
|
+
)
|
|
262
374
|
start_parser.add_argument(
|
|
263
375
|
"-m",
|
|
264
376
|
"--max-duration",
|
|
@@ -267,7 +379,14 @@ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
267
379
|
"automatically stopped (capped by the API backend)"
|
|
268
380
|
),
|
|
269
381
|
type=int,
|
|
270
|
-
default=
|
|
382
|
+
default=7200,
|
|
383
|
+
)
|
|
384
|
+
start_parser.add_argument(
|
|
385
|
+
"-f",
|
|
386
|
+
"--follow",
|
|
387
|
+
help="Attach to and follow container output",
|
|
388
|
+
action="store_true",
|
|
389
|
+
default=False,
|
|
271
390
|
)
|
|
272
391
|
start_parser.add_argument(
|
|
273
392
|
"-r",
|
|
@@ -295,8 +414,31 @@ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
295
414
|
description="Stop your remote-run job if it exists",
|
|
296
415
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
297
416
|
)
|
|
417
|
+
copy_parser = subparsers.add_parser(
|
|
418
|
+
"copy",
|
|
419
|
+
help="Copy a file from a running remote-run job",
|
|
420
|
+
description="Copy a file from a running remote-run job",
|
|
421
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
422
|
+
)
|
|
423
|
+
copy_parser.add_argument(
|
|
424
|
+
"copy_file_source",
|
|
425
|
+
help="Location of the file within the pod",
|
|
426
|
+
type=str,
|
|
427
|
+
)
|
|
428
|
+
copy_parser.add_argument(
|
|
429
|
+
"copy_file_dest",
|
|
430
|
+
help="Location on the local host to copy the file to",
|
|
431
|
+
type=str,
|
|
432
|
+
)
|
|
433
|
+
copy_parser.add_argument(
|
|
434
|
+
"--to-pod",
|
|
435
|
+
help="Copy a file to the pod instead of from the pod",
|
|
436
|
+
action="store_true",
|
|
437
|
+
default=False,
|
|
438
|
+
)
|
|
298
439
|
add_common_args_to_parser(start_parser)
|
|
299
440
|
add_common_args_to_parser(stop_parser)
|
|
441
|
+
add_common_args_to_parser(copy_parser)
|
|
300
442
|
remote_run_parser.set_defaults(command=paasta_remote_run)
|
|
301
443
|
|
|
302
444
|
|
|
@@ -306,4 +448,6 @@ def paasta_remote_run(args: argparse.Namespace) -> int:
|
|
|
306
448
|
return paasta_remote_run_start(args, system_paasta_config)
|
|
307
449
|
elif args.remote_run_command == "stop":
|
|
308
450
|
return paasta_remote_run_stop(args, system_paasta_config)
|
|
451
|
+
elif args.remote_run_command == "copy":
|
|
452
|
+
return paasta_remote_run_copy(args, system_paasta_config)
|
|
309
453
|
raise ValueError(f"Unsupported subcommand: {args.remote_run_command}")
|
|
@@ -107,7 +107,11 @@ def add_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
107
107
|
)
|
|
108
108
|
|
|
109
109
|
arg_service = list_parser.add_argument(
|
|
110
|
-
"-s",
|
|
110
|
+
"-s",
|
|
111
|
+
"--service",
|
|
112
|
+
help='Name of the service to rollback (e.g. "service1")',
|
|
113
|
+
# strip any potential trailing / for folks tab-completing directories
|
|
114
|
+
type=lambda x: x.rstrip("/"),
|
|
111
115
|
)
|
|
112
116
|
arg_service.completer = lazy_choices_completer(list_services) # type: ignore
|
|
113
117
|
list_parser.add_argument(
|
|
@@ -340,7 +344,7 @@ def paasta_rollback(args: argparse.Namespace) -> int:
|
|
|
340
344
|
)
|
|
341
345
|
print(
|
|
342
346
|
PaastaColors.yellow(
|
|
343
|
-
|
|
347
|
+
"WARNING: Failing to do so means that Jenkins will redeploy the latest code on the next scheduled build!"
|
|
344
348
|
)
|
|
345
349
|
)
|
|
346
350
|
|
paasta_tools/cli/cmds/secret.py
CHANGED
|
@@ -212,7 +212,7 @@ def _add_vault_auth_args(parser: argparse.ArgumentParser):
|
|
|
212
212
|
dest="vault_auth_method",
|
|
213
213
|
required=False,
|
|
214
214
|
default="token",
|
|
215
|
-
choices=["token", "
|
|
215
|
+
choices=["token", "okta"],
|
|
216
216
|
)
|
|
217
217
|
parser.add_argument(
|
|
218
218
|
"--vault-token-file",
|
|
@@ -246,6 +246,8 @@ def _add_common_args(parser: argparse.ArgumentParser, allow_shared: bool = True)
|
|
|
246
246
|
"--service",
|
|
247
247
|
required=not allow_shared,
|
|
248
248
|
help="The name of the service on which you wish to act",
|
|
249
|
+
# strip any potential trailing / for folks tab-completing directories
|
|
250
|
+
type=lambda x: x.rstrip("/"),
|
|
249
251
|
).completer = lazy_choices_completer(list_services)
|
|
250
252
|
|
|
251
253
|
if allow_shared:
|
|
@@ -456,7 +458,7 @@ def paasta_secret(args):
|
|
|
456
458
|
"vault_token_file": args.vault_token_file,
|
|
457
459
|
# best solution so far is to change the below string to "token",
|
|
458
460
|
# so that token file is picked up from argparse
|
|
459
|
-
"vault_auth_method": "
|
|
461
|
+
"vault_auth_method": "okta", # must use Okta to get 2FA push
|
|
460
462
|
},
|
|
461
463
|
)
|
|
462
464
|
secret_provider.write_secret(
|
|
@@ -28,6 +28,8 @@ def add_subparser(subparsers):
|
|
|
28
28
|
help='Name of service for which you wish to check. Leading "services-", as included in a '
|
|
29
29
|
"Jenkins job name, will be stripped.",
|
|
30
30
|
required=True,
|
|
31
|
+
# strip any potential trailing / for folks tab-completing directories
|
|
32
|
+
type=lambda x: x.rstrip("/"),
|
|
31
33
|
)
|
|
32
34
|
list_parser.add_argument(
|
|
33
35
|
"-c", "--commit", help="Git sha of the image to check", required=True
|
|
@@ -238,6 +238,8 @@ def add_subparser(subparsers):
|
|
|
238
238
|
"--service",
|
|
239
239
|
help="The name of the service from which the Spark image is built.",
|
|
240
240
|
default=DEFAULT_SPARK_SERVICE,
|
|
241
|
+
# strip any potential trailing / for folks tab-completing directories
|
|
242
|
+
type=lambda x: x.rstrip("/"),
|
|
241
243
|
).completer = lazy_choices_completer(list_services)
|
|
242
244
|
|
|
243
245
|
list_parser.add_argument(
|
|
@@ -897,20 +899,22 @@ def configure_and_run_docker_container(
|
|
|
897
899
|
)
|
|
898
900
|
) # type:ignore
|
|
899
901
|
environment.update(extra_driver_envs)
|
|
902
|
+
if "jupyter-lab" == args.cmd:
|
|
903
|
+
environment["SPARK_DRIVER_TYPE"] = "jupyter"
|
|
900
904
|
|
|
901
905
|
if args.use_service_auth_token:
|
|
902
906
|
environment["YELP_SVC_AUTHZ_TOKEN"] = get_service_auth_token()
|
|
903
907
|
|
|
904
908
|
webui_url = get_webui_url(spark_conf["spark.ui.port"])
|
|
905
|
-
webui_url_msg = PaastaColors.green(
|
|
909
|
+
webui_url_msg = PaastaColors.green("\nSpark monitoring URL: ") + f"{webui_url}\n"
|
|
906
910
|
|
|
907
911
|
docker_cmd = get_docker_cmd(args, instance_config, spark_conf_str)
|
|
908
912
|
if "history-server" in docker_cmd:
|
|
909
|
-
print(PaastaColors.green(
|
|
913
|
+
print(PaastaColors.green("\nSpark history server URL: ") + f"{webui_url}\n")
|
|
910
914
|
elif any(c in docker_cmd for c in ["pyspark", "spark-shell", "spark-submit"]):
|
|
911
915
|
grafana_url = get_grafana_url(spark_conf)
|
|
912
916
|
dashboard_url_msg = (
|
|
913
|
-
PaastaColors.green(
|
|
917
|
+
PaastaColors.green("\nGrafana dashboard: ") + f"{grafana_url}\n"
|
|
914
918
|
)
|
|
915
919
|
print(webui_url_msg)
|
|
916
920
|
print(dashboard_url_msg)
|