From bdea9940d9fe7853713ba8aafeb6cf55b650995c Mon Sep 17 00:00:00 2001 From: tejal29 Date: Wed, 24 Jun 2020 11:28:03 -0700 Subject: [PATCH 1/3] Refactor diag.Resource and deploy.Resource.Status to contain actionable error proto proto.ActionableErr In this PR, 1. For suggesting actionable errors for k8 infra errors, it would make sense to do it in the diag package. 2. Hence adding ActionableErr to diag.Resource package and propogating to depoyment status in skaffold.deploy.Resource.Status --- docs/content/en/api/skaffold.swagger.json | 72 ++-- docs/content/en/docs/references/api/grpc.md | 2 + pkg/diag/validator/pod.go | 47 +-- pkg/diag/validator/pod_test.go | 75 ++-- pkg/diag/validator/resource.go | 28 +- pkg/diag/validator/resource_test.go | 6 +- pkg/skaffold/deploy/resource/deployment.go | 82 +++-- .../deploy/resource/deployment_test.go | 78 ++-- pkg/skaffold/deploy/resource/status.go | 32 +- pkg/skaffold/deploy/resource/status_test.go | 47 +-- pkg/skaffold/deploy/status_check.go | 19 +- pkg/skaffold/deploy/status_check_test.go | 44 +-- pkg/skaffold/event/event.go | 33 +- pkg/skaffold/event/event_test.go | 10 +- proto/skaffold.pb.go | 348 +++++++++--------- proto/skaffold.proto | 8 + 16 files changed, 507 insertions(+), 424 deletions(-) diff --git a/docs/content/en/api/skaffold.swagger.json b/docs/content/en/api/skaffold.swagger.json index 2ed17f5b9ed..35cc79326a4 100644 --- a/docs/content/en/api/skaffold.swagger.json +++ b/docs/content/en/api/skaffold.swagger.json @@ -151,7 +151,7 @@ }, { "name": "event.buildEvent.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -192,13 +192,15 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, { "name": "event.buildEvent.actionableErr.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -239,7 +241,9 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, @@ -263,7 +267,7 @@ }, { "name": "event.deployEvent.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -304,13 +308,15 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, { "name": "event.deployEvent.actionableErr.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -351,7 +357,9 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, @@ -437,7 +445,7 @@ }, { "name": "event.statusCheckEvent.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -478,13 +486,15 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, { "name": "event.statusCheckEvent.actionableErr.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -525,7 +535,9 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, @@ -561,7 +573,7 @@ }, { "name": "event.resourceStatusCheckEvent.statusCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -602,13 +614,15 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, { "name": "event.resourceStatusCheckEvent.actionableErr.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -649,7 +663,9 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, @@ -686,7 +702,7 @@ }, { "name": "event.fileSyncEvent.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -727,13 +743,15 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, { "name": "event.fileSyncEvent.actionableErr.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -774,7 +792,9 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, @@ -841,7 +861,7 @@ }, { "name": "event.devLoopEvent.err.errCode", - "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.", + "description": " - OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded", "in": "query", "required": false, "type": "string", @@ -882,7 +902,9 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK" }, @@ -1573,10 +1595,12 @@ "DEVINIT_REGISTER_BUILD_DEPS", "DEVINIT_REGISTER_TEST_DEPS", "DEVINIT_REGISTER_DEPLOY_DEPS", - "DEVINIT_REGISTER_CONFIG_DEP" + "DEVINIT_REGISTER_CONFIG_DEP", + "STATUSCHECK_CONTEXT_CANCELLED", + "STATUSCHECK_DEADLINE_EXCEEDED" ], "default": "OK", - "description": "Enum for Status codes\nThese error codes are prepended by Phase Name e.g.\nBUILD, DEPLOY, STATUSCHECK, DEVINIT\n- OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file." + "description": "Enum for Status codes\nThese error codes are prepended by Phase Name e.g.\nBUILD, DEPLOY, STATUSCHECK, DEVINIT\n- OK: A default status code for events that do not have an associated phase.\nTypically seen with the DevEndEvent event on success.\n - STATUSCHECK_SUCCESS: Status Check Success\n - BUILD_SUCCESS: Build Success\n - BUILD_PUSH_ACCESS_DENIED: Build error due to push access denied\n - BUILD_PROJECT_NOT_FOUND: Build error due to GCP project not found.\n - STATUSCHECK_IMAGE_PULL_ERR: Container image pull error\n - STATUSCHECK_CONTAINER_CREATING: Container creating error\n - STATUSCHECK_RUN_CONTAINER_ERR: Container run error\n - STATUSCHECK_CONTAINER_TERMINATED: Container is already terminated\n - STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING: Deployment waiting for rollout\n - STATUSCHECK_CONTAINER_RESTARTING: Container restarting error\n - STATUSCHECK_UNHEALTHY: Readiness probe failed\n - STATUSCHECK_NODE_MEMORY_PRESSURE: Node memory pressure error\n - STATUSCHECK_NODE_DISK_PRESSURE: Node disk pressure error\n - STATUSCHECK_NODE_NETWORK_UNAVAILABLE: Node network unavailable error\n - STATUSCHECK_NODE_PID_PRESSURE: Node PID pressure error\n - STATUSCHECK_NODE_UNSCHEDULABLE: Node unschedulable error\n - STATUSCHECK_NODE_UNREACHABLE: Node unreachable error\n - STATUSCHECK_NODE_NOT_READY: Node not ready error\n - STATUSCHECK_FAILED_SCHEDULING: Scheduler failure error\n - STATUSCHECK_KUBECTL_CONNECTION_ERR: Kubectl connection error\n - STATUSCHECK_KUBECTL_PID_KILLED: Kubectl process killed error\n - UNKNOWN_ERROR: Could not determine error and phase\n - STATUSCHECK_UNKNOWN: Status Check error unknown\n - STATUSCHECK_UNKNOWN_UNSCHEDULABLE: Container is unschedulable due to unknown reasons\n - STATUSCHECK_CONTAINER_WAITING_UNKNOWN: Container is waiting due to unknown reason\n - STATUSCHECK_UNKNOWN_EVENT: Container event reason unknown\n - DEPLOY_UNKNOWN: Deploy failed due to unknown reason\n - SYNC_UNKNOWN: SYNC failed due to known reason\n - BUILD_UNKNOWN: Build failed due to unknown reason\n - DEVINIT_UNKNOWN: Dev Init failed due to unknown reason\n - CLEANUP_UNKNOWN: Cleanup failed due to unknown reason\n - SYNC_INIT_ERROR: File Sync Initialize failure\n - DEVINIT_REGISTER_BUILD_DEPS: Failed to configure watcher for build dependencies in dev loop\n - DEVINIT_REGISTER_TEST_DEPS: Failed to configure watcher for test dependencies in dev loop\n - DEVINIT_REGISTER_DEPLOY_DEPS: Failed to configure watcher for deploy dependencies in dev loop\n - DEVINIT_REGISTER_CONFIG_DEP: Failed to configure watcher for Skaffold configuration file.\n - STATUSCHECK_CONTEXT_CANCELLED: User cancelled the skaffold dev run\n - STATUSCHECK_DEADLINE_EXCEEDED: Deadline for status check exceeded" }, "protoSuggestion": { "type": "object", diff --git a/docs/content/en/docs/references/api/grpc.md b/docs/content/en/docs/references/api/grpc.md index cbe03a4951a..63191444647 100644 --- a/docs/content/en/docs/references/api/grpc.md +++ b/docs/content/en/docs/references/api/grpc.md @@ -785,6 +785,8 @@ skip 408 as STATUSCHECK_UNHEALTH code renumbered as 357 | | DEVINIT_REGISTER_TEST_DEPS | 702 | Failed to configure watcher for test dependencies in dev loop | | DEVINIT_REGISTER_DEPLOY_DEPS | 703 | Failed to configure watcher for deploy dependencies in dev loop | | DEVINIT_REGISTER_CONFIG_DEP | 704 | Failed to configure watcher for Skaffold configuration file. | +| STATUSCHECK_CONTEXT_CANCELLED | 800 | User cancelled the skaffold dev run | +| STATUSCHECK_DEADLINE_EXCEEDED | 801 | Deadline for status check exceeded | diff --git a/pkg/diag/validator/pod.go b/pkg/diag/validator/pod.go index 3ab4930ed9d..5b6b91ea19f 100644 --- a/pkg/diag/validator/pod.go +++ b/pkg/diag/validator/pod.go @@ -85,7 +85,7 @@ func (p *PodValidator) Validate(ctx context.Context, ns string, opts metav1.List if po.Kind == "" { po.Kind = podKind } - rs = append(rs, NewResourceFromObject(&po, Status(ps.phase), ps.err, ps.statusCode, ps.logs)) + rs = append(rs, NewResourceFromObject(&po, Status(ps.phase), ps.ae, ps.logs)) } return rs, nil } @@ -209,34 +209,35 @@ func processPodEvents(e corev1.EventInterface, pod v1.Pod, ps *podStatus) { } switch recentEvent.Reason { case failedScheduling: - ps.statusCode = proto.StatusCode_STATUSCHECK_FAILED_SCHEDULING - ps.err = fmt.Errorf(recentEvent.Message) + ps.ae.ErrCode = proto.StatusCode_STATUSCHECK_FAILED_SCHEDULING + ps.ae.Message = recentEvent.Message case unhealthy: - ps.statusCode = proto.StatusCode_STATUSCHECK_UNHEALTHY - ps.err = fmt.Errorf(recentEvent.Message) + ps.ae.ErrCode = proto.StatusCode_STATUSCHECK_UNHEALTHY + ps.ae.Message = recentEvent.Message default: // TODO: Add unique error codes for reasons - ps.statusCode = proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT - ps.err = fmt.Errorf("%s: %s", recentEvent.Reason, recentEvent.Message) + ps.ae.ErrCode = proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT + ps.ae.Message = fmt.Sprintf("%s: %s", recentEvent.Reason, recentEvent.Message) } } type podStatus struct { - name string - namespace string - phase string - logs []string - err error - statusCode proto.StatusCode + name string + namespace string + phase string + logs []string + ae *proto.ActionableErr } func (p *podStatus) isStable() bool { - return p.phase == success || (p.phase == running && p.err == nil) + return p.phase == success || (p.phase == running && p.ae.Message == "") } func (p *podStatus) withErrAndLogs(errCode proto.StatusCode, l []string, err error) *podStatus { - p.err = err - p.statusCode = errCode + if err != nil { + p.ae.Message = err.Error() + } + p.ae.ErrCode = errCode p.logs = l return p } @@ -246,8 +247,8 @@ func (p *podStatus) String() string { case p.isStable(): return "" default: - if p.err != nil { - return fmt.Sprintf("%s", p.err) + if p.ae.Message != "" { + return p.ae.Message } } return fmt.Sprintf(actionableMessage, p.namespace, p.name) @@ -275,10 +276,12 @@ func extractErrorMessageFromWaitingContainerStatus(po *v1.Pod, c v1.ContainerSta func newPodStatus(n string, ns string, p string) *podStatus { return &podStatus{ - name: n, - namespace: ns, - phase: p, - statusCode: proto.StatusCode_STATUSCHECK_SUCCESS, + name: n, + namespace: ns, + phase: p, + ae: &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, + }, } } diff --git a/pkg/diag/validator/pod_test.go b/pkg/diag/validator/pod_test.go index ffd27bb0b36..8f36fd06fc6 100644 --- a/pkg/diag/validator/pod_test.go +++ b/pkg/diag/validator/pod_test.go @@ -84,8 +84,10 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - fmt.Errorf("container foo-container is waiting to start: foo-image can't be pulled"), - proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, nil)}, + &proto.ActionableErr{ + Message: "container foo-container is waiting to start: foo-image can't be pulled", + ErrCode: proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, + }, nil)}, }, { description: "pod is Waiting condition due to ErrImageBackOffPullErr", @@ -113,8 +115,10 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - fmt.Errorf("container foo-container is waiting to start: foo-image can't be pulled"), - proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, nil)}, + &proto.ActionableErr{ + Message: "container foo-container is waiting to start: foo-image can't be pulled", + ErrCode: proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, + }, nil)}, }, { description: "pod is Waiting due to Image Backoff Pull error", @@ -142,8 +146,10 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - fmt.Errorf("container foo-container is waiting to start: foo-image can't be pulled"), - proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, nil)}, + &proto.ActionableErr{ + Message: "container foo-container is waiting to start: foo-image can't be pulled", + ErrCode: proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, + }, nil)}, }, { description: "pod is in Terminated State", @@ -158,8 +164,11 @@ func TestRun(t *testing.T) { Conditions: []v1.PodCondition{{Type: v1.PodScheduled, Status: v1.ConditionTrue}}, }, }}, - expected: []Resource{NewResource("test", "Pod", "foo", "Succeeded", nil, - proto.StatusCode_STATUSCHECK_SUCCESS, nil)}, + expected: []Resource{NewResource("test", "Pod", "foo", "Succeeded", + &proto.ActionableErr{ + Message: "", + ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, + }, nil)}, }, { description: "pod is in Stable State", @@ -180,8 +189,11 @@ func TestRun(t *testing.T) { }, }, }}, - expected: []Resource{NewResource("test", "Pod", "foo", "Running", nil, - proto.StatusCode_STATUSCHECK_SUCCESS, nil)}, + expected: []Resource{NewResource("test", "Pod", "foo", "Running", + &proto.ActionableErr{ + Message: "", + ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, + }, nil)}, }, { description: "pod condition unknown", @@ -201,7 +213,10 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - fmt.Errorf("could not determine"), proto.StatusCode_STATUSCHECK_UNKNOWN, nil)}, + &proto.ActionableErr{ + Message: "could not determine", + ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, + }, nil)}, }, { description: "pod could not be scheduled", @@ -222,8 +237,10 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - fmt.Errorf("Unschedulable: 0/2 nodes available: 1 node has disk pressure, 1 node is unreachable"), - proto.StatusCode_STATUSCHECK_NODE_DISK_PRESSURE, nil)}, + &proto.ActionableErr{ + Message: "Unschedulable: 0/2 nodes available: 1 node has disk pressure, 1 node is unreachable", + ErrCode: proto.StatusCode_STATUSCHECK_NODE_DISK_PRESSURE, + }, nil)}, }, { description: "pod is running but container terminated", @@ -248,8 +265,10 @@ func TestRun(t *testing.T) { output: []byte("main.go:57 \ngo panic"), }, expected: []Resource{NewResource("test", "Pod", "foo", "Running", - fmt.Errorf("container foo-container terminated with exit code 1"), - proto.StatusCode_STATUSCHECK_CONTAINER_TERMINATED, []string{ + &proto.ActionableErr{ + Message: "container foo-container terminated with exit code 1", + ErrCode: proto.StatusCode_STATUSCHECK_CONTAINER_TERMINATED, + }, []string{ "[foo foo-container] main.go:57 ", "[foo foo-container] go panic"}, )}, @@ -276,8 +295,10 @@ func TestRun(t *testing.T) { err: fmt.Errorf("error"), }, expected: []Resource{NewResource("test", "pod", "foo", "Running", - fmt.Errorf("container foo-container terminated with exit code 1"), - proto.StatusCode_STATUSCHECK_CONTAINER_TERMINATED, []string{ + &proto.ActionableErr{ + Message: "container foo-container terminated with exit code 1", + ErrCode: proto.StatusCode_STATUSCHECK_CONTAINER_TERMINATED, + }, []string{ "Error retrieving logs for pod foo. Try `kubectl logs foo -n test -c foo-container`"}, )}, }, @@ -306,7 +327,10 @@ func TestRun(t *testing.T) { }, }, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - fmt.Errorf("eventCode: dummy event"), proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, nil)}, + &proto.ActionableErr{ + Message: "eventCode: dummy event", + ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, + }, nil)}, }, { description: "pod condition a warning event followed up normal event", @@ -338,7 +362,10 @@ func TestRun(t *testing.T) { }, }, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - fmt.Errorf("eventCode: dummy event"), proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, nil)}, + &proto.ActionableErr{ + Message: "eventCode: dummy event", + ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, + }, nil)}, }, { description: "pod condition a normal event followed by a warning event", @@ -370,7 +397,10 @@ func TestRun(t *testing.T) { }, }, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - fmt.Errorf("eventCode: dummy event"), proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, nil)}, + &proto.ActionableErr{ + Message: "eventCode: dummy event", + ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, + }, nil)}, }, { description: "pod condition a warning event followed up by warning adds last warning seen", @@ -402,7 +432,10 @@ func TestRun(t *testing.T) { }, }, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - fmt.Errorf("0/1 nodes are available: 1 node(s) had taint {key: value}, that the pod didn't tolerate"), proto.StatusCode_STATUSCHECK_FAILED_SCHEDULING, nil)}, + &proto.ActionableErr{ + Message: "0/1 nodes are available: 1 node(s) had taint {key: value}, that the pod didn't tolerate", + ErrCode: proto.StatusCode_STATUSCHECK_FAILED_SCHEDULING, + }, nil)}, }, } diff --git a/pkg/diag/validator/resource.go b/pkg/diag/validator/resource.go index aa0856f5d8f..dd8f8d19c9f 100644 --- a/pkg/diag/validator/resource.go +++ b/pkg/diag/validator/resource.go @@ -26,20 +26,18 @@ import ( ) type Resource struct { - namespace string - kind string - name string - logs []string - status Status - err error - StatusCode proto.StatusCode + namespace string + kind string + name string + logs []string + status Status + ae *proto.ActionableErr } func (r Resource) Kind() string { return r.kind } func (r Resource) Name() string { return r.name } func (r Resource) Namespace() string { return r.namespace } func (r Resource) Status() Status { return r.status } -func (r Resource) Error() error { return r.err } func (r Resource) Logs() []string { return r.logs } func (r Resource) String() string { if r.namespace == "default" { @@ -47,10 +45,16 @@ func (r Resource) String() string { } return fmt.Sprintf("%s:%s/%s", r.namespace, r.kind, r.name) } +func (r Resource) ActionableError() *proto.ActionableErr { + return r.ae +} +func (r Resource) StatusUpdated(another Resource) bool { + return r.ae.ErrCode != another.ae.ErrCode +} // NewResource creates new Resource of kind -func NewResource(namespace, kind, name string, status Status, err error, statusCode proto.StatusCode, logs []string) Resource { - return Resource{namespace: namespace, kind: kind, name: name, status: status, err: err, StatusCode: statusCode, logs: logs} +func NewResource(namespace, kind, name string, status Status, ae *proto.ActionableErr, logs []string) Resource { + return Resource{namespace: namespace, kind: kind, name: name, status: status, ae: ae, logs: logs} } // objectWithMetadata is any k8s object that has kind and object metadata. @@ -60,6 +64,6 @@ type objectWithMetadata interface { } // NewResourceFromObject creates new Resource with fields populated from object metadata. -func NewResourceFromObject(object objectWithMetadata, status Status, err error, statusCode proto.StatusCode, logs []string) Resource { - return NewResource(object.GetNamespace(), object.GetObjectKind().GroupVersionKind().Kind, object.GetName(), status, err, statusCode, logs) +func NewResourceFromObject(object objectWithMetadata, status Status, ae *proto.ActionableErr, logs []string) Resource { + return NewResource(object.GetNamespace(), object.GetObjectKind().GroupVersionKind().Kind, object.GetName(), status, ae, logs) } diff --git a/pkg/diag/validator/resource_test.go b/pkg/diag/validator/resource_test.go index 093552d1510..9ed0436cf26 100644 --- a/pkg/diag/validator/resource_test.go +++ b/pkg/diag/validator/resource_test.go @@ -42,7 +42,7 @@ func TestNewResource(t *testing.T) { Name: "foo", }, }, - expected: Resource{"default", "pod", "foo", nil, Status(""), nil, 0}, + expected: Resource{"default", "pod", "foo", nil, Status(""), nil}, expectedName: "pod/foo", }, { @@ -54,13 +54,13 @@ func TestNewResource(t *testing.T) { Name: "bar", }, }, - expected: Resource{"test", "pod", "bar", nil, Status(""), nil, 0}, + expected: Resource{"test", "pod", "bar", nil, Status(""), nil}, expectedName: "test:pod/bar", }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - actual := NewResourceFromObject(test.resource, Status(""), nil, 0, nil) + actual := NewResourceFromObject(test.resource, Status(""), nil, nil) t.CheckDeepEqual(test.expected, actual, cmp.AllowUnexported(Resource{})) t.CheckDeepEqual(test.expectedName, actual.String(), cmp.AllowUnexported(Resource{})) }) diff --git a/pkg/skaffold/deploy/resource/deployment.go b/pkg/skaffold/deploy/resource/deployment.go index 7780e8792cd..b12f33691e9 100644 --- a/pkg/skaffold/deploy/resource/deployment.go +++ b/pkg/skaffold/deploy/resource/deployment.go @@ -18,7 +18,6 @@ package resource import ( "context" - "errors" "fmt" "strings" "time" @@ -44,8 +43,8 @@ const ( ) var ( - errKubectlKilled = errors.New("kubectl rollout status command interrupted") - ErrKubectlConnection = errors.New("kubectl connection error") + msgKubectlKilled = "kubectl rollout status command interrupted" + MsgKubectlConnection = "kubectl connection error" ) type Deployment struct { @@ -64,19 +63,15 @@ func (d *Deployment) Deadline() time.Duration { return d.deadline } -func (d *Deployment) UpdateStatus(details string, err error) { - errCode := proto.StatusCode_STATUSCHECK_SUCCESS - if err != nil { - errCode = proto.StatusCode_STATUSCHECK_UNKNOWN - } - updated := newStatus(details, errCode, err) +func (d *Deployment) UpdateStatus(ae *proto.ActionableErr) { + updated := newStatus(ae) if d.status.Equal(updated) { d.status.changed = false return } d.status = updated d.status.changed = true - if strings.Contains(details, rollOutSuccess) || isErrAndNotRetryAble(err) { + if ae.ErrCode == proto.StatusCode_STATUSCHECK_SUCCESS || isErrAndNotRetryAble(ae.ErrCode) { d.done = true } } @@ -86,7 +81,7 @@ func NewDeployment(name string, ns string, deadline time.Duration) *Deployment { name: name, namespace: ns, rType: deploymentType, - status: newStatus("", proto.StatusCode_STATUSCHECK_UNKNOWN, nil), + status: newStatus(&proto.ActionableErr{}), deadline: deadline, podValidator: diag.New(nil), } @@ -107,12 +102,12 @@ func (d *Deployment) CheckStatus(ctx context.Context, runCtx *runcontext.RunCont details := d.cleanupStatus(string(b)) - d.StatusCode, err = parseKubectlRolloutError(err) - if err == errKubectlKilled { - err = fmt.Errorf("received Ctrl-C or deployments could not stabilize within %v: %w", d.deadline, err) + ae := parseKubectlRolloutError(details, err) + if ae.ErrCode == proto.StatusCode_STATUSCHECK_KUBECTL_PID_KILLED { + ae.Message = fmt.Sprintf("received Ctrl-C or deployments could not stabilize within %v: %v", d.deadline, err) } - d.UpdateStatus(details, err) + d.UpdateStatus(ae) if err := d.fetchPods(ctx); err != nil { logrus.Debugf("pod statuses could be fetched this time due to %s", err) } @@ -153,8 +148,8 @@ func (d *Deployment) ReportSinceLastUpdated() string { var result strings.Builder result.WriteString(fmt.Sprintf("%s %s: %s", tabHeader, d, d.status)) for _, p := range d.pods { - if p.Error() != nil { - result.WriteString(fmt.Sprintf("%s %s %s: %s\n", tab, tabHeader, p, p.Error())) + if s := p.ActionableError().Message; s != "" { + result.WriteString(fmt.Sprintf("%s %s %s: %s\n", tab, tabHeader, p, s)) for _, l := range p.Logs() { result.WriteString(fmt.Sprintf("%s\n", l)) } @@ -179,24 +174,39 @@ func (d *Deployment) cleanupStatus(msg string) string { // $kubectl logs testPod -f // 2020/06/18 17:28:31 service is running // Killed: 9 -func parseKubectlRolloutError(err error) (proto.StatusCode, error) { - if err == nil { - return proto.StatusCode_STATUSCHECK_SUCCESS, err - } - if strings.Contains(err.Error(), connectionErrMsg) { - return proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR, ErrKubectlConnection - } - if strings.Contains(err.Error(), killedErrMsg) { - return proto.StatusCode_STATUSCHECK_KUBECTL_PID_KILLED, errKubectlKilled +func parseKubectlRolloutError(details string, err error) *proto.ActionableErr { + switch { + case err == nil && strings.Contains(details, rollOutSuccess): + return &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, + Message: details, + } + case err == nil: + return &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING, + Message: details, + } + case strings.Contains(err.Error(), connectionErrMsg): + return &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR, + Message: MsgKubectlConnection, + } + case strings.Contains(err.Error(), killedErrMsg): + return &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_PID_KILLED, + Message: msgKubectlKilled, + } + default: + return &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, + Message: err.Error(), + } } - return proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING, err } -func isErrAndNotRetryAble(err error) bool { - if err == nil { - return false - } - return err != ErrKubectlConnection +func isErrAndNotRetryAble(statusCode proto.StatusCode) bool { + return statusCode != proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR && + statusCode != proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING } func (d *Deployment) fetchPods(ctx context.Context) error { @@ -211,13 +221,13 @@ func (d *Deployment) fetchPods(ctx context.Context) error { d.status.changed = false for _, p := range pods { originalPod, found := d.pods[p.String()] - if !found || originalPod.StatusCode != p.StatusCode { + if !found || originalPod.StatusUpdated(p) { d.status.changed = true - switch p.StatusCode { + switch p.ActionableError().ErrCode { case proto.StatusCode_STATUSCHECK_CONTAINER_CREATING: - event.ResourceStatusCheckEventUpdated(p.String(), p.StatusCode, p.Error().Error()) + event.ResourceStatusCheckEventUpdated(p.String(), p.ActionableError()) default: - event.ResourceStatusCheckEventCompleted(p.String(), p.StatusCode, p.Error()) + event.ResourceStatusCheckEventCompleted(p.String(), p.ActionableError()) } } newPods[p.String()] = p diff --git a/pkg/skaffold/deploy/resource/deployment_test.go b/pkg/skaffold/deploy/resource/deployment_test.go index 143f140aa81..eb635203358 100644 --- a/pkg/skaffold/deploy/resource/deployment_test.go +++ b/pkg/skaffold/deploy/resource/deployment_test.go @@ -77,7 +77,7 @@ func TestDeploymentCheckStatus(t *testing.T) { "", errors.New("Unable to connect to the server"), ), - expectedErr: ErrKubectlConnection.Error(), + expectedErr: MsgKubectlConnection, }, } @@ -94,7 +94,7 @@ func TestDeploymentCheckStatus(t *testing.T) { if test.expectedErr != "" { t.CheckErrorContains(test.expectedErr, r.Status().Error()) } else { - t.CheckDeepEqual(r.status.details, test.expectedDetails) + t.CheckDeepEqual(r.status.ae.Message, test.expectedDetails) } }) } @@ -103,45 +103,47 @@ func TestDeploymentCheckStatus(t *testing.T) { func TestParseKubectlError(t *testing.T) { tests := []struct { description string + details string err error - expected string - expectedSc proto.StatusCode - shouldErr bool + expectedAe *proto.ActionableErr }{ { description: "rollout status connection error", err: errors.New("Unable to connect to the server"), - expected: ErrKubectlConnection.Error(), - expectedSc: proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR, - shouldErr: true, + expectedAe: &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR, + Message: MsgKubectlConnection, + }, }, { description: "rollout status kubectl command killed", err: errors.New("signal: killed"), - expected: errKubectlKilled.Error(), - expectedSc: proto.StatusCode_STATUSCHECK_KUBECTL_PID_KILLED, - shouldErr: true, + expectedAe: &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_PID_KILLED, + Message: msgKubectlKilled, + }, }, { description: "rollout status random error", err: errors.New("deployment test not found"), - expected: "deployment test not found", - expectedSc: proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING, - shouldErr: true, + expectedAe: &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, + Message: "deployment test not found", + }, }, { description: "rollout status nil error", - expectedSc: proto.StatusCode_STATUSCHECK_SUCCESS, + details: "successfully rolled out", + expectedAe: &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, + Message: "successfully rolled out", + }, }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - sc, actual := parseKubectlRolloutError(test.err) - t.CheckError(test.shouldErr, actual) - t.CheckDeepEqual(test.expectedSc, sc) - if test.shouldErr { - t.CheckErrorContains(test.expected, actual) - } + ae := parseKubectlRolloutError(test.details, test.err) + t.CheckDeepEqual(test.expectedAe, ae) }) } } @@ -149,40 +151,42 @@ func TestParseKubectlError(t *testing.T) { func TestIsErrAndNotRetriable(t *testing.T) { tests := []struct { description string - err error + statusCode proto.StatusCode expected bool }{ { description: "rollout status connection error", - err: ErrKubectlConnection, + statusCode: proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR, }, { description: "rollout status kubectl command killed", - err: errKubectlKilled, + statusCode: proto.StatusCode_STATUSCHECK_KUBECTL_PID_KILLED, expected: true, }, { description: "rollout status random error", - err: errors.New("deployment test not found"), + statusCode: proto.StatusCode_STATUSCHECK_UNKNOWN, expected: true, }, { - description: "rollout status parent context cancelled", - err: context.Canceled, + description: "rollout status parent context canceled", + statusCode: proto.StatusCode_STATUSCHECK_CONTEXT_CANCELLED, expected: true, }, { description: "rollout status parent context timed out", - err: context.DeadlineExceeded, + statusCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, expected: true, }, { description: "rollout status nil error", + statusCode: proto.StatusCode_STATUSCHECK_SUCCESS, + expected: true, }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - actual := isErrAndNotRetryAble(test.err) + actual := isErrAndNotRetryAble(test.statusCode) t.CheckDeepEqual(test.expected, actual) }) } @@ -191,27 +195,24 @@ func TestIsErrAndNotRetriable(t *testing.T) { func TestReportSinceLastUpdated(t *testing.T) { var tests = []struct { description string - message string - err error + ae *proto.ActionableErr expected string }{ { description: "updating an error status", - message: "cannot pull image", - err: errors.New("cannot pull image"), + ae: &proto.ActionableErr{Message: "cannot pull image"}, expected: " - test-ns:deployment/test: cannot pull image", }, { description: "updating a non error status", - message: "waiting for container", + ae: &proto.ActionableErr{Message: "waiting for container"}, expected: " - test-ns:deployment/test: waiting for container", }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { dep := NewDeployment("test", "test-ns", 1) - dep.UpdateStatus(test.message, test.err) - + dep.UpdateStatus(test.ae) t.CheckDeepEqual(test.expected, dep.ReportSinceLastUpdated()) t.CheckTrue(dep.status.changed) }) @@ -250,7 +251,10 @@ func TestReportSinceLastUpdatedMultipleTimes(t *testing.T) { var actual string for i, status := range test.statuses { // update to same status - dep.UpdateStatus(status, nil) + dep.UpdateStatus(&proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING, + Message: status, + }) if test.reportStatusSeq[i] { actual = dep.ReportSinceLastUpdated() } diff --git a/pkg/skaffold/deploy/resource/status.go b/pkg/skaffold/deploy/resource/status.go index 81602362bda..8b63a40100f 100644 --- a/pkg/skaffold/deploy/resource/status.go +++ b/pkg/skaffold/deploy/resource/status.go @@ -17,47 +17,39 @@ limitations under the License. package resource import ( + "fmt" + "github.com/GoogleContainerTools/skaffold/proto" ) type Status struct { - err error - details string - errCode proto.StatusCode + ae *proto.ActionableErr changed bool reported bool } func (rs Status) Error() error { - return rs.err + return fmt.Errorf(rs.ae.Message) } -func (rs Status) ErrorCode() proto.StatusCode { - return rs.errCode +func (rs Status) ActionableError() *proto.ActionableErr { + return rs.ae } func (rs Status) String() string { - if rs.err != nil { - return rs.err.Error() - } - return rs.details + return rs.ae.Message } func (rs Status) Equal(other Status) bool { - if rs.details != other.details { - return false - } - if rs.err != nil && other.err != nil { - return rs.err.Error() == other.err.Error() + if rs.ae != nil && other.ae != nil { + return rs.ae.Message == other.ae.Message && rs.ae.ErrCode == other.ae.ErrCode } - return rs.err == other.err + return rs.ae == other.ae } -func newStatus(msg string, errCode proto.StatusCode, err error) Status { +func newStatus(ae *proto.ActionableErr) Status { return Status{ - details: msg, - err: err, - errCode: errCode, + ae: ae, changed: true, } } diff --git a/pkg/skaffold/deploy/resource/status_test.go b/pkg/skaffold/deploy/resource/status_test.go index 6e4c069466e..d55e49f7f32 100644 --- a/pkg/skaffold/deploy/resource/status_test.go +++ b/pkg/skaffold/deploy/resource/status_test.go @@ -17,43 +17,36 @@ limitations under the License. package resource import ( - "errors" - "fmt" "testing" + "github.com/GoogleContainerTools/skaffold/proto" "github.com/GoogleContainerTools/skaffold/testutil" ) func TestString(t *testing.T) { var tests = []struct { description string - details string - err error + ae *proto.ActionableErr expected string }{ { description: "should return error string if error is set", - err: errors.New("some error"), + ae: &proto.ActionableErr{Message: "some error"}, expected: "some error", }, - { - description: "should return error details if error is not set", - details: "details", - expected: "details", - }, { description: "should return error if both details and error are set", - details: "error details", - err: errors.New("error happened due to something"), + ae: &proto.ActionableErr{Message: "error happened due to something"}, expected: "error happened due to something", }, { description: "should return empty string if all empty", + ae: &proto.ActionableErr{}, }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - status := newStatus(test.details, 0, test.err) + status := newStatus(test.ae) t.CheckDeepEqual(test.expected, status.String()) }) } @@ -67,31 +60,25 @@ func TestEqual(t *testing.T) { expected bool }{ { - description: "status should be same for same details and error", - old: Status{details: "Waiting for 0/1 replicas to be available...", err: nil}, - new: Status{details: "Waiting for 0/1 replicas to be available...", err: nil}, - expected: true, - }, - { - description: "status should be new if error messages are same", - old: Status{details: "same", err: errors.New("same error")}, - new: Status{details: "same", err: errors.New("same error")}, + description: "status should be same if error messages are same", + old: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "Waiting for 0/1 replicas to be available..."}}, + new: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "Waiting for 0/1 replicas to be available..."}}, expected: true, }, { description: "status should be new if error is different", - old: Status{details: "same", err: nil}, - new: Status{details: "same", err: fmt.Errorf("see this error")}, + old: Status{ae: nil}, + new: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "see this error"}}, }, { - description: "status should be new if details and err are different", - old: Status{details: "same", err: nil}, - new: Status{details: "same", err: fmt.Errorf("see this error")}, + description: "status should be new if errcode are different but same message", + old: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "see this error"}}, + new: Status{ae: &proto.ActionableErr{ErrCode: 101, Message: "see this error"}}, }, { - description: "status should be new if details change", - old: Status{details: "same", err: nil}, - new: Status{details: "error", err: nil}, + description: "status should be new if messages change", + old: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "Waiting for 2/2 replicas to be available..."}}, + new: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "Waiting for 1/2 replicas to be available..."}}, }, } for _, test := range tests { diff --git a/pkg/skaffold/deploy/status_check.go b/pkg/skaffold/deploy/status_check.go index 0c2da370860..e85d578e39c 100644 --- a/pkg/skaffold/deploy/status_check.go +++ b/pkg/skaffold/deploy/status_check.go @@ -18,7 +18,6 @@ package deploy import ( "context" - "errors" "fmt" "io" "strings" @@ -36,6 +35,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/event" pkgkubernetes "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext" + "github.com/GoogleContainerTools/skaffold/proto" ) var ( @@ -143,8 +143,9 @@ func pollDeploymentStatus(ctx context.Context, runCtx *runcontext.RunContext, r for { select { case <-timeoutContext.Done(): - err := fmt.Errorf("could not stabilize within %v: %w", r.Deadline(), timeoutContext.Err()) - r.UpdateStatus(err.Error(), err) + msg := fmt.Sprintf("could not stabilize within %v: %v", r.Deadline(), timeoutContext.Err()) + r.UpdateStatus(&proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, + Message: msg}) return case <-time.After(pollDuration): r.CheckStatus(timeoutContext, runCtx) @@ -172,18 +173,18 @@ func getDeadline(d int) time.Duration { } func printStatusCheckSummary(out io.Writer, r *resource.Deployment, c counter) { - err := r.Status().Error() - if errors.Is(err, context.Canceled) { + ae := r.Status().ActionableError() + if ae.ErrCode == proto.StatusCode_STATUSCHECK_CONTEXT_CANCELLED { // Don't print the status summary if the user ctrl-C return } - event.ResourceStatusCheckEventCompleted(r.String(), r.StatusCode, err) + event.ResourceStatusCheckEventCompleted(r.String(), r.Status().ActionableError()) status := fmt.Sprintf("%s %s", tabHeader, r) - if err != nil { + if ae.ErrCode != proto.StatusCode_STATUSCHECK_SUCCESS { status = fmt.Sprintf("%s failed.%s Error: %s.", status, trimNewLine(getPendingMessage(c.pending, c.total)), - trimNewLine(err.Error()), + trimNewLine(ae.Message), ) } else { status = fmt.Sprintf("%s is ready.%s", status, getPendingMessage(c.pending, c.total)) @@ -218,7 +219,7 @@ func printStatus(deployments []*resource.Deployment, out io.Writer) bool { } allDone = false if str := r.ReportSinceLastUpdated(); str != "" { - event.ResourceStatusCheckEventUpdated(r.String(), r.StatusCode, str) + event.ResourceStatusCheckEventUpdated(r.String(), r.Status().ActionableError()) fmt.Fprintln(out, trimNewLine(str)) } } diff --git a/pkg/skaffold/deploy/status_check_test.go b/pkg/skaffold/deploy/status_check_test.go index 22467297f32..42de32f8460 100644 --- a/pkg/skaffold/deploy/status_check_test.go +++ b/pkg/skaffold/deploy/status_check_test.go @@ -35,6 +35,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/resource" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/event" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" + "github.com/GoogleContainerTools/skaffold/proto" "github.com/GoogleContainerTools/skaffold/testutil" ) @@ -269,7 +270,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace string deployment string pending int32 - err error + ae *proto.ActionableErr expected string }{ { @@ -277,7 +278,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "test", deployment: "dep", pending: 0, - err: nil, + ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, expected: " - test:deployment/dep is ready.\n", }, { @@ -285,7 +286,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "default", deployment: "dep", pending: 0, - err: nil, + ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, expected: " - deployment/dep is ready.\n", }, { @@ -293,7 +294,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "test", deployment: "dep", pending: 0, - err: errors.New("context deadline expired"), + ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, Message: "context deadline expired"}, expected: " - test:deployment/dep failed. Error: context deadline expired.\n", }, { @@ -301,7 +302,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "test", deployment: "dep", pending: 4, - err: nil, + ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, expected: " - test:deployment/dep is ready. [4/10 deployment(s) still pending]\n", }, { @@ -309,7 +310,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "test", deployment: "dep", pending: 8, - err: errors.New("context deadline expired"), + ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, Message: "context deadline expired"}, expected: " - test:deployment/dep failed. [8/10 deployment(s) still pending] Error: context deadline expired.\n", }, } @@ -319,9 +320,10 @@ func TestPrintSummaryStatus(t *testing.T) { out := new(bytes.Buffer) rc := newCounter(10) rc.pending = test.pending + event.InitializeState(latest.Pipeline{}, "test", true, true, true) printStatusCheckSummary( out, - withStatus(resource.NewDeployment(test.deployment, test.namespace, 0), "", test.err), + withStatus(resource.NewDeployment(test.deployment, test.namespace, 0), test.ae), *rc, ) t.CheckDeepEqual(test.expected, out.String()) @@ -341,8 +343,7 @@ func TestPrintStatus(t *testing.T) { rs: []*resource.Deployment{ withStatus( resource.NewDeployment("r1", "test", 1), - "deployment successfully rolled out", - nil, + &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, ), }, expected: true, @@ -352,8 +353,7 @@ func TestPrintStatus(t *testing.T) { rs: []*resource.Deployment{ withStatus( resource.NewDeployment("r1", "test", 1), - "error", - errors.New("error"), + &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, Message: "error"}, ), }, expected: true, @@ -363,13 +363,12 @@ func TestPrintStatus(t *testing.T) { rs: []*resource.Deployment{ withStatus( resource.NewDeployment("r1", "test", 1), - "deployment successfully rolled out", - nil, + &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, ), withStatus( resource.NewDeployment("r2", "test", 1), - "pending", - nil, + &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING, + Message: "pending"}, ), }, expectedOut: " - test:deployment/r2: pending\n", @@ -379,13 +378,13 @@ func TestPrintStatus(t *testing.T) { rs: []*resource.Deployment{ withStatus( resource.NewDeployment("r1", "test", 1), - "eployment successfully rolled out", - nil, + &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, ), withStatus( resource.NewDeployment("r2", "test", 1), - "", - resource.ErrKubectlConnection, + &proto.ActionableErr{ + ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR, + Message: resource.MsgKubectlConnection}, ), }, expectedOut: " - test:deployment/r2: kubectl connection error\n", @@ -395,6 +394,7 @@ func TestPrintStatus(t *testing.T) { for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { out := new(bytes.Buffer) + event.InitializeState(latest.Pipeline{}, "test", true, true, true) actual := printStatus(test.rs, out) t.CheckDeepEqual(test.expectedOut, out.String()) t.CheckDeepEqual(test.expected, actual) @@ -402,8 +402,8 @@ func TestPrintStatus(t *testing.T) { } } -func withStatus(d *resource.Deployment, details string, err error) *resource.Deployment { - d.UpdateStatus(details, err) +func withStatus(d *resource.Deployment, ae *proto.ActionableErr) *resource.Deployment { + d.UpdateStatus(ae) return d } @@ -446,7 +446,7 @@ func TestResourceMarkProcessed(t *testing.T) { { description: "when deployment failed, counter is updated", c: newCounter(10), - err: errors.New("some err"), + err: errors.New("some ae"), expected: counter{total: 10, failed: 1, pending: 9}, }, { diff --git a/pkg/skaffold/event/event.go b/pkg/skaffold/event/event.go index fb136cb0a6b..2f7bbed87b2 100644 --- a/pkg/skaffold/event/event.go +++ b/pkg/skaffold/event/event.go @@ -217,9 +217,9 @@ func StatusCheckEventInProgress(s string) { }) } -func ResourceStatusCheckEventCompleted(r string, statusCode proto.StatusCode, err error) { - if err != nil { - resourceStatusCheckEventFailed(r, statusCode, err) +func ResourceStatusCheckEventCompleted(r string, ae *proto.ActionableErr) { + if ae.ErrCode != proto.StatusCode_STATUSCHECK_SUCCESS { + resourceStatusCheckEventFailed(r, ae) return } resourceStatusCheckEventSucceeded(r) @@ -234,24 +234,23 @@ func resourceStatusCheckEventSucceeded(r string) { }) } -func resourceStatusCheckEventFailed(r string, statusCode proto.StatusCode, err error) { +func resourceStatusCheckEventFailed(r string, ae *proto.ActionableErr) { handler.handleResourceStatusCheckEvent(&proto.ResourceStatusCheckEvent{ - Resource: r, - Status: Failed, - Err: err.Error(), - StatusCode: statusCode, - ActionableErr: &proto.ActionableErr{ - ErrCode: statusCode, - Message: err.Error(), - }}) + Resource: r, + Status: Failed, + Err: ae.Message, + StatusCode: ae.ErrCode, + ActionableErr: ae, + }) } -func ResourceStatusCheckEventUpdated(r string, statusCode proto.StatusCode, status string) { +func ResourceStatusCheckEventUpdated(r string, ae *proto.ActionableErr) { handler.handleResourceStatusCheckEvent(&proto.ResourceStatusCheckEvent{ - Resource: r, - Status: InProgress, - Message: status, - StatusCode: statusCode, + Resource: r, + Status: InProgress, + Message: ae.Message, + StatusCode: ae.ErrCode, + ActionableErr: ae, }) } diff --git a/pkg/skaffold/event/event_test.go b/pkg/skaffold/event/event_test.go index 734961ca253..d279c6b1a3e 100644 --- a/pkg/skaffold/event/event_test.go +++ b/pkg/skaffold/event/event_test.go @@ -221,7 +221,10 @@ func TestResourceStatusCheckEventUpdated(t *testing.T) { } wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted }) - ResourceStatusCheckEventUpdated("ns:pod/foo", 509, "img pull error") + ResourceStatusCheckEventUpdated("ns:pod/foo", &proto.ActionableErr{ + ErrCode: 509, + Message: "image pull error", + }) wait(t, func() bool { return handler.getState().StatusCheckState.Resources["ns:pod/foo"] == InProgress }) } @@ -245,7 +248,10 @@ func TestResourceStatusCheckEventFailed(t *testing.T) { } wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted }) - resourceStatusCheckEventFailed("ns:pod/foo", 309, errors.New("one or more deployments failed")) + resourceStatusCheckEventFailed("ns:pod/foo", &proto.ActionableErr{ + ErrCode: 309, + Message: "one or more deployments failed", + }) wait(t, func() bool { return handler.getState().StatusCheckState.Resources["ns:pod/foo"] == Failed }) } diff --git a/proto/skaffold.pb.go b/proto/skaffold.pb.go index bb0be94aae0..2b532e74a3e 100644 --- a/proto/skaffold.pb.go +++ b/proto/skaffold.pb.go @@ -264,6 +264,10 @@ const ( StatusCode_DEVINIT_REGISTER_DEPLOY_DEPS StatusCode = 703 // Failed to configure watcher for Skaffold configuration file. StatusCode_DEVINIT_REGISTER_CONFIG_DEP StatusCode = 704 + // User cancelled the skaffold dev run + StatusCode_STATUSCHECK_CONTEXT_CANCELLED StatusCode = 800 + // Deadline for status check exceeded + StatusCode_STATUSCHECK_DEADLINE_EXCEEDED StatusCode = 801 ) var StatusCode_name = map[int32]string{ @@ -304,6 +308,8 @@ var StatusCode_name = map[int32]string{ 702: "DEVINIT_REGISTER_TEST_DEPS", 703: "DEVINIT_REGISTER_DEPLOY_DEPS", 704: "DEVINIT_REGISTER_CONFIG_DEP", + 800: "STATUSCHECK_CONTEXT_CANCELLED", + 801: "STATUSCHECK_DEADLINE_EXCEEDED", } var StatusCode_value = map[string]int32{ @@ -344,6 +350,8 @@ var StatusCode_value = map[string]int32{ "DEVINIT_REGISTER_TEST_DEPS": 702, "DEVINIT_REGISTER_DEPLOY_DEPS": 703, "DEVINIT_REGISTER_CONFIG_DEP": 704, + "STATUSCHECK_CONTEXT_CANCELLED": 800, + "STATUSCHECK_DEADLINE_EXCEEDED": 801, } func (x StatusCode) String() string { @@ -2344,175 +2352,177 @@ func init() { func init() { proto.RegisterFile("skaffold.proto", fileDescriptor_4f2d38e344f9dbf5) } var fileDescriptor_4f2d38e344f9dbf5 = []byte{ - // 2675 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0x5d, 0x6c, 0x23, 0x57, - 0xf5, 0x8f, 0x3d, 0x76, 0x62, 0x9f, 0x7c, 0xec, 0xec, 0xdd, 0x64, 0xd7, 0xf5, 0xa6, 0xbb, 0xe9, - 0xfc, 0x77, 0xd3, 0x6d, 0xda, 0x7f, 0xd2, 0xed, 0x22, 0x54, 0x96, 0x16, 0x34, 0x19, 0xcf, 0xc6, - 0xb3, 0x99, 0x8c, 0xa3, 0xeb, 0x71, 0xcb, 0x56, 0x42, 0xd6, 0xac, 0x3d, 0x71, 0xad, 0x75, 0x3c, - 0x61, 0x3c, 0xde, 0x92, 0x17, 0x1e, 0x78, 0xe5, 0x05, 0x28, 0x05, 0x81, 0x78, 0xe0, 0x85, 0xb7, - 0x52, 0x78, 0x45, 0x08, 0xca, 0x03, 0x12, 0xf0, 0x8c, 0x84, 0xc4, 0x23, 0x52, 0xfb, 0xc0, 0x7b, - 0xcb, 0x37, 0x12, 0xba, 0x5f, 0x33, 0x77, 0xec, 0xf1, 0xa6, 0x51, 0x1f, 0x78, 0x8a, 0xef, 0xb9, - 0xbf, 0xf3, 0x79, 0xcf, 0x3d, 0xe7, 0xcc, 0x0d, 0xac, 0x8c, 0x1e, 0x79, 0x47, 0x47, 0xc1, 0xa0, - 0xbb, 0x7d, 0x12, 0x06, 0x51, 0x80, 0x8a, 0xf4, 0x4f, 0x75, 0xbd, 0x17, 0x04, 0xbd, 0x81, 0xbf, - 0xe3, 0x9d, 0xf4, 0x77, 0xbc, 0xe1, 0x30, 0x88, 0xbc, 0xa8, 0x1f, 0x0c, 0x47, 0x0c, 0x54, 0xbd, - 0xce, 0x77, 0xe9, 0xea, 0xe1, 0xf8, 0x68, 0x27, 0xea, 0x1f, 0xfb, 0xa3, 0xc8, 0x3b, 0x3e, 0xe1, - 0x80, 0xab, 0x93, 0x00, 0xff, 0xf8, 0x24, 0x3a, 0x65, 0x9b, 0xda, 0x1d, 0x58, 0x6e, 0x46, 0x5e, - 0xe4, 0x63, 0x7f, 0x74, 0x12, 0x0c, 0x47, 0x3e, 0xd2, 0xa0, 0x38, 0x22, 0x84, 0x4a, 0x6e, 0x23, - 0x77, 0x6b, 0xf1, 0xa5, 0x25, 0x86, 0xdb, 0x66, 0x20, 0xb6, 0xa5, 0xad, 0x43, 0x29, 0xc6, 0xab, - 0xa0, 0x1c, 0x8f, 0x7a, 0x14, 0x5d, 0xc6, 0xe4, 0xa7, 0xf6, 0x34, 0x2c, 0x60, 0xff, 0x2b, 0x63, - 0x7f, 0x14, 0x21, 0x04, 0x85, 0xa1, 0x77, 0xec, 0xf3, 0x5d, 0xfa, 0x5b, 0x7b, 0xa7, 0x00, 0x45, - 0x2a, 0x0d, 0xdd, 0x06, 0x78, 0x38, 0xee, 0x0f, 0xba, 0x4d, 0x49, 0xdf, 0x45, 0xae, 0x6f, 0x37, - 0xde, 0xc0, 0x12, 0x08, 0x7d, 0x06, 0x16, 0xbb, 0xfe, 0xc9, 0x20, 0x38, 0x65, 0x3c, 0x79, 0xca, - 0x83, 0x38, 0x4f, 0x2d, 0xd9, 0xc1, 0x32, 0x0c, 0xd5, 0x61, 0xe5, 0x28, 0x08, 0xdf, 0xf2, 0xc2, - 0xae, 0xdf, 0x3d, 0x0c, 0xc2, 0x68, 0x54, 0x29, 0x6c, 0x28, 0xb7, 0x16, 0x5f, 0xda, 0x90, 0x9d, - 0xdb, 0xbe, 0x97, 0x82, 0x98, 0xc3, 0x28, 0x3c, 0xc5, 0x13, 0x7c, 0xc8, 0x00, 0x95, 0x84, 0x60, - 0x3c, 0x32, 0xde, 0xf4, 0x3b, 0x8f, 0x98, 0x11, 0x45, 0x6a, 0xc4, 0x15, 0x49, 0x96, 0xbc, 0x8d, - 0xa7, 0x18, 0xd0, 0x5d, 0x58, 0x3e, 0xea, 0x0f, 0xfc, 0xe6, 0xe9, 0xb0, 0xc3, 0x24, 0xcc, 0x53, - 0x09, 0xab, 0x5c, 0xc2, 0x3d, 0x79, 0x0f, 0xa7, 0xa1, 0xe8, 0x10, 0x2e, 0x75, 0xfd, 0x87, 0xe3, - 0x5e, 0xaf, 0x3f, 0xec, 0x19, 0xc1, 0x30, 0xf2, 0xfa, 0x43, 0x3f, 0x1c, 0x55, 0x16, 0xa8, 0x3f, - 0xd7, 0xe2, 0x40, 0x4c, 0x22, 0xcc, 0xc7, 0xfe, 0x30, 0xc2, 0x59, 0xac, 0xe8, 0x79, 0x28, 0x1d, - 0xfb, 0x91, 0xd7, 0xf5, 0x22, 0xaf, 0x52, 0xa2, 0x86, 0x5c, 0xe0, 0x62, 0x0e, 0x38, 0x19, 0xc7, - 0x80, 0x6a, 0x13, 0x2e, 0x65, 0x84, 0x89, 0x24, 0xc1, 0x23, 0xff, 0x94, 0x1e, 0x61, 0x11, 0x93, - 0x9f, 0x68, 0x13, 0x8a, 0x8f, 0xbd, 0xc1, 0x58, 0x1c, 0x91, 0xca, 0x45, 0x12, 0x1e, 0x66, 0x0b, - 0xdb, 0xbe, 0x9b, 0x7f, 0x39, 0x77, 0xbf, 0x50, 0x52, 0xd4, 0x82, 0xf6, 0x61, 0x0e, 0x4a, 0x42, - 0x23, 0xda, 0x82, 0x22, 0x3d, 0x75, 0x9e, 0x15, 0xab, 0x72, 0x56, 0xc4, 0x66, 0x31, 0x08, 0xfa, - 0x7f, 0x98, 0x67, 0x87, 0xcd, 0x75, 0xad, 0xa5, 0xd2, 0x21, 0x46, 0x73, 0x10, 0xfa, 0x22, 0x80, - 0xd7, 0xed, 0xf6, 0xc9, 0x15, 0xf2, 0x06, 0x95, 0x0e, 0x0d, 0xdc, 0xf5, 0x09, 0x8f, 0xb7, 0xf5, - 0x18, 0xc1, 0xf2, 0x40, 0x62, 0xa9, 0xbe, 0x0a, 0x17, 0x26, 0xb6, 0x65, 0xff, 0xcb, 0xcc, 0xff, - 0x55, 0xd9, 0xff, 0xb2, 0xe4, 0xad, 0xf6, 0x71, 0x1e, 0x96, 0x53, 0x7e, 0xa0, 0x17, 0xe0, 0xe2, - 0x70, 0x7c, 0xfc, 0xd0, 0x0f, 0x1b, 0x47, 0x7a, 0x18, 0xf5, 0x8f, 0xbc, 0x4e, 0x34, 0xe2, 0xb1, - 0x9c, 0xde, 0x40, 0xaf, 0x42, 0x89, 0xfa, 0x4d, 0x8e, 0x3d, 0x4f, 0xad, 0x7f, 0x26, 0x2b, 0x3a, - 0xdb, 0xd6, 0xb1, 0xd7, 0xf3, 0x77, 0x19, 0x12, 0xc7, 0x2c, 0xe8, 0x06, 0x14, 0xa2, 0xd3, 0x13, - 0xbf, 0xa2, 0x6c, 0xe4, 0x6e, 0xad, 0xc4, 0xe7, 0x42, 0x71, 0xee, 0xe9, 0x89, 0x8f, 0xe9, 0x2e, - 0xaa, 0x65, 0x04, 0xe9, 0x46, 0xa6, 0x9a, 0x27, 0x45, 0xca, 0x86, 0x25, 0xd9, 0x0a, 0xb4, 0xc9, - 0x75, 0xe7, 0xa8, 0x6e, 0x24, 0xcb, 0xf3, 0x43, 0x49, 0xfb, 0x2a, 0x14, 0x3b, 0xc1, 0x78, 0x18, - 0xd1, 0xe0, 0x15, 0x31, 0x5b, 0x7c, 0xda, 0xb8, 0xff, 0x36, 0x07, 0x2b, 0xe9, 0x94, 0x40, 0xaf, - 0x40, 0x99, 0x25, 0x05, 0x89, 0x65, 0x6e, 0xe2, 0x0a, 0xc9, 0x48, 0xbe, 0xf4, 0x43, 0x9c, 0x30, - 0xa0, 0x17, 0x60, 0xa1, 0x33, 0x18, 0x8f, 0x22, 0x3f, 0xa4, 0xca, 0x12, 0x87, 0x0c, 0x46, 0xa5, - 0x0e, 0x09, 0x48, 0xd5, 0x82, 0x92, 0x10, 0x82, 0x9e, 0x4d, 0xc5, 0xe1, 0x52, 0x4a, 0xe5, 0xd9, - 0x81, 0xd0, 0xde, 0xcd, 0x01, 0x24, 0xf5, 0x11, 0x7d, 0x01, 0xca, 0x9e, 0x94, 0x36, 0x72, 0x61, - 0x4b, 0x50, 0xdb, 0x71, 0x02, 0xb1, 0x63, 0x4a, 0x58, 0xd0, 0x06, 0x2c, 0x7a, 0xe3, 0x28, 0x70, - 0xc3, 0x7e, 0xaf, 0xc7, 0x7d, 0x29, 0x61, 0x99, 0x54, 0x7d, 0x05, 0x56, 0xd2, 0xec, 0xe7, 0x0a, - 0xfc, 0x1e, 0x2c, 0x4a, 0x95, 0x19, 0x5d, 0x86, 0x79, 0x56, 0x11, 0x39, 0x37, 0x5f, 0x9d, 0x6d, - 0x86, 0xf6, 0x5e, 0x0e, 0xd4, 0xc9, 0xf2, 0x3a, 0x53, 0x5c, 0x0d, 0xca, 0xa1, 0x3f, 0x0a, 0xc6, - 0x61, 0xc7, 0x17, 0xf7, 0x64, 0x73, 0x46, 0x89, 0xde, 0xc6, 0x02, 0xc8, 0x63, 0x13, 0x33, 0x12, - 0xcf, 0xd3, 0x9b, 0xe7, 0xf2, 0xdc, 0x82, 0xe5, 0x54, 0x31, 0xff, 0x14, 0xbe, 0xff, 0xb9, 0x00, - 0x45, 0x5a, 0x38, 0xd1, 0x8b, 0x50, 0x26, 0xe5, 0x98, 0x2e, 0x78, 0x79, 0x54, 0xa5, 0xf2, 0x45, - 0xe9, 0xf5, 0x39, 0x9c, 0x80, 0xd0, 0x1d, 0xde, 0x67, 0x19, 0x4b, 0x7e, 0xba, 0xcf, 0x0a, 0x1e, - 0x09, 0x86, 0x3e, 0x2b, 0x3a, 0x2d, 0xe3, 0x52, 0x32, 0x3a, 0xad, 0x60, 0x93, 0x81, 0xc4, 0xbc, - 0x13, 0x51, 0xe4, 0x2b, 0x85, 0xec, 0xe2, 0x4f, 0xcc, 0x8b, 0x41, 0xc8, 0x4c, 0xf5, 0x54, 0xc6, - 0x38, 0xb3, 0xa7, 0x0a, 0xfe, 0x29, 0x16, 0xf4, 0x65, 0xa8, 0x88, 0x73, 0x9b, 0xc4, 0xf3, 0x06, - 0x2b, 0xaa, 0x3c, 0x9e, 0x01, 0xab, 0xcf, 0xe1, 0x99, 0x22, 0xd0, 0x2b, 0x49, 0xd3, 0x66, 0x32, - 0x17, 0x32, 0x9b, 0xb6, 0x10, 0x94, 0x06, 0xa3, 0x37, 0xe0, 0x4a, 0x37, 0xbb, 0x29, 0xf3, 0x9e, - 0x7b, 0x46, 0xeb, 0xae, 0xcf, 0xe1, 0x59, 0x02, 0xd0, 0xe7, 0x60, 0xa9, 0xeb, 0x3f, 0xb6, 0x83, - 0xe0, 0x84, 0x09, 0x2c, 0x53, 0x81, 0x49, 0x55, 0x49, 0xb6, 0xea, 0x73, 0x38, 0x05, 0xdd, 0x5d, - 0x02, 0xf0, 0xc9, 0x8f, 0x36, 0xa9, 0x36, 0xda, 0x00, 0x96, 0x64, 0x34, 0x5a, 0x87, 0x72, 0x3f, - 0xf2, 0x43, 0x3a, 0x6d, 0xf2, 0x7e, 0x94, 0x10, 0xa4, 0x5c, 0xce, 0xa7, 0x72, 0x79, 0x13, 0x14, - 0x3f, 0x0c, 0x79, 0xc2, 0x88, 0xf0, 0xe8, 0x1d, 0x5a, 0xb6, 0x1f, 0x0e, 0x7c, 0x33, 0x0c, 0x31, - 0x01, 0x68, 0xdf, 0xc8, 0xc1, 0x72, 0x8a, 0x8c, 0x9e, 0x87, 0x05, 0x3f, 0x0c, 0x8d, 0xa0, 0x2b, - 0x2a, 0xe3, 0xc5, 0xf4, 0xf9, 0x07, 0x5d, 0x1f, 0x0b, 0x04, 0xaa, 0xc0, 0xc2, 0xb1, 0x3f, 0x1a, - 0x79, 0x3d, 0x71, 0xef, 0xc4, 0x12, 0xdd, 0x81, 0xc5, 0xd1, 0xb8, 0xd7, 0xf3, 0x47, 0x74, 0x4a, - 0xae, 0x28, 0xf4, 0xee, 0xc7, 0xa2, 0xe2, 0x1d, 0x2c, 0xa3, 0x34, 0x07, 0xca, 0xf1, 0xed, 0x21, - 0x37, 0xda, 0x27, 0x97, 0x9d, 0xdf, 0x52, 0xb6, 0x48, 0x0d, 0x4a, 0xf9, 0x33, 0x06, 0x25, 0xed, - 0x17, 0xa2, 0x46, 0x33, 0x89, 0x55, 0x28, 0x89, 0x82, 0xcb, 0x85, 0xc6, 0xeb, 0x99, 0x81, 0x54, - 0x93, 0x40, 0x96, 0x69, 0xc8, 0xe4, 0x00, 0x15, 0xce, 0x0c, 0xd0, 0x5d, 0x58, 0xf6, 0xe4, 0xf0, - 0xf2, 0x3b, 0x95, 0x7d, 0x22, 0x69, 0xa8, 0xf6, 0xa3, 0x9c, 0xa8, 0xd9, 0xcc, 0xfc, 0x59, 0x75, - 0x8b, 0x9b, 0x98, 0xcf, 0x34, 0x51, 0x39, 0xbf, 0x89, 0x85, 0x4f, 0x6e, 0xe2, 0xfb, 0xe9, 0x66, - 0xf0, 0x64, 0x3b, 0x67, 0x27, 0xcb, 0xff, 0x30, 0xc8, 0x7f, 0xc9, 0x41, 0x65, 0x56, 0x29, 0x22, - 0x09, 0x23, 0x4a, 0x91, 0x48, 0x18, 0xb1, 0x9e, 0x99, 0x30, 0x92, 0x97, 0x4a, 0xa6, 0x97, 0x85, - 0xc4, 0xcb, 0xdb, 0x00, 0xa3, 0xd8, 0x1f, 0x6a, 0x75, 0xa6, 0xa3, 0x12, 0x68, 0xda, 0xd7, 0xf9, - 0x4f, 0xee, 0xeb, 0x8f, 0xf3, 0x50, 0x8e, 0xcb, 0x3f, 0x29, 0x2c, 0x83, 0xa0, 0xe3, 0x0d, 0x08, - 0x45, 0x14, 0x96, 0x98, 0x80, 0xae, 0x01, 0x84, 0xfe, 0x71, 0x10, 0xf9, 0x74, 0x9b, 0x4d, 0x3e, - 0x12, 0x85, 0xb8, 0x79, 0x12, 0x74, 0x1d, 0xf2, 0x5d, 0xc9, 0xdd, 0xe4, 0x4b, 0x74, 0x03, 0x96, - 0x3b, 0xa2, 0x36, 0xd2, 0x7d, 0xe6, 0x70, 0x9a, 0x48, 0xb4, 0x93, 0x0f, 0xd1, 0xd1, 0x89, 0xd7, - 0x61, 0x9e, 0x97, 0x71, 0x42, 0x20, 0x81, 0x27, 0xad, 0x89, 0xb2, 0xcf, 0xb3, 0xc0, 0x8b, 0x35, - 0xd2, 0x60, 0x49, 0x1c, 0x02, 0x19, 0xd2, 0x68, 0x0b, 0x28, 0xe3, 0x14, 0x4d, 0xc6, 0x50, 0x19, - 0xa5, 0x34, 0x86, 0xca, 0xa9, 0xc0, 0x82, 0xd7, 0xed, 0x86, 0xfe, 0x68, 0x44, 0x8b, 0x75, 0x19, - 0x8b, 0xa5, 0xf6, 0xc7, 0x5c, 0x32, 0x32, 0xc4, 0xb1, 0x22, 0xad, 0xc4, 0xa0, 0x63, 0x20, 0x8f, - 0x55, 0x4c, 0x20, 0x95, 0xaa, 0x7f, 0x9c, 0xa4, 0x35, 0x5b, 0x48, 0x09, 0xa2, 0x64, 0x5d, 0xd7, - 0x42, 0x66, 0xb2, 0x17, 0xcf, 0x9f, 0xec, 0xe7, 0x48, 0x80, 0x8f, 0xf2, 0x70, 0x65, 0x46, 0x6f, - 0x7b, 0xd2, 0xad, 0x15, 0x07, 0x9d, 0x3f, 0xe3, 0xa0, 0x95, 0x33, 0x0f, 0xba, 0x90, 0x71, 0xd0, - 0x71, 0x49, 0x2e, 0x4e, 0x94, 0xe4, 0x0a, 0x2c, 0x84, 0xe3, 0x61, 0xd4, 0x8f, 0x73, 0x40, 0x2c, - 0x49, 0x72, 0xbe, 0x15, 0x84, 0x8f, 0xfa, 0xc3, 0x5e, 0xad, 0x1f, 0xf2, 0x04, 0x90, 0x28, 0xc8, - 0x01, 0xa0, 0x7d, 0x9a, 0x3d, 0x33, 0x94, 0x68, 0xef, 0xd9, 0x7e, 0x72, 0x6f, 0x67, 0x74, 0xe9, - 0xd1, 0x41, 0x92, 0x40, 0x3e, 0x7a, 0x26, 0xb6, 0xcf, 0x9a, 0x40, 0x97, 0xe5, 0x09, 0xf4, 0x6b, - 0x50, 0xb2, 0x83, 0x1e, 0xe3, 0x7b, 0x19, 0xca, 0xf1, 0xd3, 0x10, 0x1f, 0x1c, 0xab, 0xdb, 0xec, - 0x6d, 0x68, 0x5b, 0xbc, 0x0d, 0x6d, 0xbb, 0x02, 0x81, 0x13, 0x30, 0xd2, 0xa0, 0xe8, 0x4b, 0xb3, - 0xa3, 0x78, 0x13, 0xe2, 0x1f, 0xf2, 0x7e, 0xba, 0x67, 0x2a, 0x52, 0xcf, 0xd4, 0xee, 0xc2, 0xc5, - 0xd6, 0xc8, 0x0f, 0xad, 0x61, 0x44, 0xa0, 0xfc, 0x55, 0xe8, 0x26, 0xcc, 0xf7, 0x29, 0x81, 0x5b, - 0xb1, 0xcc, 0xe5, 0x71, 0x14, 0xdf, 0xd4, 0x3e, 0x0f, 0x2b, 0x7c, 0xfa, 0x15, 0x8c, 0xcf, 0xa5, - 0xdf, 0xa6, 0xc4, 0x88, 0xc3, 0x51, 0xa9, 0x27, 0xaa, 0xdb, 0xb0, 0x24, 0x93, 0x51, 0x15, 0x16, - 0x7c, 0x9a, 0x8c, 0xec, 0x49, 0xa1, 0x54, 0x9f, 0xc3, 0x82, 0xb0, 0x5b, 0x04, 0xe5, 0xb1, 0x37, - 0xd0, 0xee, 0xc3, 0x3c, 0xb3, 0x80, 0xf8, 0x92, 0xbc, 0x3e, 0x94, 0xc4, 0x3b, 0x03, 0x82, 0xc2, - 0xe8, 0x74, 0xd8, 0xe1, 0xd3, 0x39, 0xfd, 0x4d, 0x52, 0x97, 0xbf, 0x3d, 0x28, 0x94, 0xca, 0x57, - 0x5a, 0x07, 0x20, 0x99, 0x34, 0xd0, 0xab, 0xb0, 0x92, 0xcc, 0x1a, 0xd2, 0x7c, 0xb3, 0x36, 0x35, - 0x94, 0xd0, 0x0b, 0x37, 0x01, 0x26, 0x4a, 0xd8, 0x65, 0x12, 0xf5, 0x9e, 0xad, 0xb6, 0x02, 0x58, - 0x94, 0xbe, 0x9d, 0x51, 0x05, 0x56, 0x5b, 0xce, 0xbe, 0xd3, 0x78, 0xdd, 0x69, 0xef, 0xb6, 0x2c, - 0xbb, 0x66, 0xe2, 0xb6, 0xfb, 0xe0, 0xd0, 0x54, 0xe7, 0xd0, 0x02, 0x28, 0xf7, 0xad, 0x5d, 0x35, - 0x87, 0xca, 0x50, 0xdc, 0xd5, 0xdf, 0x30, 0x6d, 0x35, 0x8f, 0x56, 0x00, 0x28, 0xea, 0x50, 0x37, - 0xf6, 0x9b, 0xaa, 0x82, 0x00, 0xe6, 0x8d, 0x56, 0xd3, 0x6d, 0x1c, 0xa8, 0x05, 0xf2, 0x7b, 0x5f, - 0x77, 0xac, 0xfd, 0x86, 0x5a, 0x24, 0xbf, 0x6b, 0x0d, 0x63, 0xdf, 0xc4, 0xea, 0xfc, 0x56, 0x0d, - 0xca, 0xf1, 0x43, 0x01, 0xba, 0x0c, 0x28, 0xa5, 0x4e, 0x28, 0x5b, 0x84, 0x05, 0xc3, 0x6e, 0x35, - 0x5d, 0x13, 0xab, 0x39, 0xa2, 0x79, 0xcf, 0xd8, 0x55, 0xf3, 0x44, 0xb3, 0xdd, 0x30, 0x74, 0x5b, - 0x55, 0xb6, 0x1a, 0x64, 0xcc, 0x4c, 0x3e, 0x75, 0xd1, 0x53, 0xb0, 0x26, 0x04, 0xd5, 0xcc, 0x43, - 0xbb, 0xf1, 0x20, 0x31, 0xbc, 0x04, 0x85, 0xba, 0x69, 0x1f, 0xa8, 0x39, 0xb4, 0x0c, 0xe5, 0x7d, - 0x6a, 0x9e, 0xf5, 0x86, 0xa9, 0xe6, 0x89, 0x92, 0xfd, 0xd6, 0xae, 0x69, 0xb8, 0x44, 0xa0, 0x05, - 0x8b, 0xd2, 0x27, 0xb7, 0x1c, 0x07, 0x6e, 0x88, 0x10, 0xb7, 0x04, 0xa5, 0x03, 0xcb, 0xb1, 0x08, - 0x27, 0xb7, 0x6d, 0xdf, 0x64, 0xb6, 0x35, 0xdc, 0xba, 0x89, 0x55, 0x65, 0xeb, 0x87, 0x65, 0x80, - 0xa4, 0xf4, 0xa1, 0x79, 0xc8, 0x37, 0xf6, 0xd5, 0x39, 0x54, 0x81, 0x4b, 0x4d, 0x57, 0x77, 0x5b, - 0x4d, 0xa3, 0x6e, 0x1a, 0xfb, 0xed, 0x66, 0xcb, 0x30, 0xcc, 0x66, 0x53, 0xfd, 0x5d, 0x0e, 0x21, - 0x58, 0x66, 0xde, 0x0b, 0xda, 0xef, 0x73, 0x68, 0x1d, 0x2a, 0x8c, 0x76, 0xd8, 0x6a, 0xd6, 0xdb, - 0x3a, 0xa5, 0xb7, 0x6b, 0xa6, 0x63, 0x99, 0x35, 0xd5, 0x47, 0x57, 0xe1, 0x0a, 0xdf, 0xc5, 0x8d, - 0xfb, 0xa6, 0xe1, 0xb6, 0x9d, 0x86, 0xdb, 0xbe, 0xd7, 0x68, 0x39, 0x35, 0xf5, 0x08, 0x5d, 0x87, - 0xaa, 0xac, 0xc8, 0x3a, 0xd0, 0xf7, 0xcc, 0xf6, 0x61, 0xcb, 0xb6, 0xdb, 0x26, 0xc6, 0xea, 0xbb, - 0x79, 0xf4, 0x7f, 0x70, 0x4d, 0x06, 0x18, 0x0d, 0xc7, 0xd5, 0x2d, 0xc7, 0xc4, 0x6d, 0x03, 0x9b, - 0xba, 0x6b, 0x39, 0x7b, 0xea, 0x4f, 0xf2, 0x48, 0x83, 0xa7, 0x65, 0x10, 0x6e, 0x39, 0x12, 0x90, - 0x08, 0x7a, 0x2f, 0x8f, 0x6e, 0xc2, 0x46, 0xb6, 0x20, 0xd7, 0xc4, 0x07, 0x96, 0xa3, 0xbb, 0x66, - 0x4d, 0xfd, 0x69, 0x1e, 0x3d, 0x0f, 0x9b, 0x32, 0x8c, 0x1d, 0xd0, 0x81, 0xe9, 0xb8, 0x6d, 0xdc, - 0xb0, 0xed, 0x46, 0xcb, 0x6d, 0x1f, 0x9a, 0x4e, 0x8d, 0xe8, 0xfd, 0xd9, 0x13, 0x64, 0x62, 0xb3, - 0xe9, 0xea, 0x98, 0x9a, 0xf7, 0x41, 0x1e, 0x55, 0x61, 0x4d, 0x86, 0xb5, 0x9c, 0xba, 0xa9, 0xdb, - 0x6e, 0xfd, 0x81, 0xfa, 0xe1, 0x94, 0x08, 0xa7, 0x51, 0x33, 0xdb, 0x07, 0xe6, 0x41, 0x03, 0x3f, - 0x68, 0x1f, 0x62, 0xb3, 0xd9, 0x6c, 0x61, 0x53, 0xfd, 0xa6, 0x32, 0x19, 0x06, 0x0a, 0xab, 0x59, - 0xcd, 0xfd, 0x04, 0xf4, 0x2d, 0x05, 0x3d, 0x07, 0x37, 0xa6, 0x40, 0x8e, 0xe9, 0xbe, 0xde, 0xc0, - 0x44, 0xa9, 0xfe, 0x9a, 0x6e, 0xd9, 0xfa, 0xae, 0x6d, 0xaa, 0xdf, 0x56, 0x26, 0x23, 0x46, 0xa1, - 0x87, 0x56, 0x2d, 0x11, 0xf7, 0x76, 0xb6, 0xce, 0x96, 0x43, 0x56, 0xb5, 0x16, 0x13, 0xf4, 0x1d, - 0x05, 0x3d, 0x03, 0xeb, 0x19, 0x20, 0x6c, 0xea, 0x46, 0x9d, 0x42, 0xde, 0x51, 0x26, 0xcf, 0x98, - 0x99, 0xd5, 0x70, 0xdb, 0xd8, 0xd4, 0x6b, 0x0f, 0xd4, 0xef, 0x4e, 0x19, 0x73, 0x4f, 0xb7, 0x6c, - 0xb3, 0xd6, 0xe6, 0x8a, 0x48, 0x0c, 0xbf, 0xa7, 0xa0, 0x67, 0x41, 0x93, 0x31, 0xfc, 0x32, 0x90, - 0x90, 0x3b, 0xa6, 0xe1, 0x5a, 0x0d, 0x87, 0x9e, 0xf3, 0xf7, 0xa7, 0xac, 0x16, 0x40, 0xe2, 0xdc, - 0xbe, 0x65, 0xdb, 0x66, 0x4d, 0xfd, 0x81, 0x42, 0xb2, 0x58, 0x5c, 0x19, 0x13, 0xe3, 0x06, 0x56, - 0x3f, 0x52, 0x26, 0x73, 0x9e, 0xef, 0xab, 0x1f, 0x2b, 0x68, 0x13, 0x9e, 0xc9, 0xd8, 0x99, 0x88, - 0xc5, 0x5f, 0x15, 0xb4, 0x05, 0x37, 0xb3, 0xd3, 0xe1, 0x75, 0xdd, 0x22, 0xb9, 0x10, 0xcb, 0xfc, - 0x9b, 0x82, 0xae, 0xc1, 0x53, 0x59, 0x32, 0xcd, 0xd7, 0x4c, 0xc7, 0x55, 0xff, 0xa3, 0xa0, 0x4b, - 0xb0, 0xc2, 0x72, 0x2f, 0x66, 0xfa, 0xbb, 0x82, 0x2e, 0xc2, 0x52, 0xf3, 0x81, 0x63, 0xc4, 0xa4, - 0x7f, 0x28, 0xc9, 0x7d, 0x14, 0xb4, 0x7f, 0x2a, 0x68, 0x15, 0x2e, 0xd4, 0xcc, 0xd7, 0x2c, 0xc7, - 0x72, 0x63, 0xea, 0xbf, 0x28, 0xd5, 0xb0, 0x4d, 0xdd, 0x69, 0x1d, 0xc6, 0xd4, 0x7f, 0x53, 0x2a, - 0x15, 0x49, 0xd1, 0x2c, 0x16, 0x7f, 0x2a, 0xa0, 0x0d, 0xb8, 0x2a, 0x24, 0x60, 0x73, 0xcf, 0xa2, - 0x35, 0x85, 0xa9, 0xa9, 0x99, 0x87, 0x4d, 0xf5, 0x97, 0x45, 0x72, 0xa8, 0x53, 0x08, 0xd7, 0x6c, - 0xba, 0x0c, 0xf0, 0xab, 0x22, 0x49, 0x8c, 0x29, 0x00, 0xf7, 0x88, 0x42, 0xde, 0x2f, 0x66, 0x6a, - 0x31, 0x1a, 0xce, 0x3d, 0x6b, 0x8f, 0x40, 0xd4, 0x5f, 0x17, 0xb7, 0x7e, 0x93, 0x83, 0x95, 0x74, - 0xb3, 0x20, 0x55, 0xcc, 0xb1, 0x6c, 0x75, 0x0e, 0xad, 0x82, 0xaa, 0xd7, 0x88, 0x41, 0xf7, 0xf4, - 0x96, 0x4d, 0x24, 0x1c, 0x36, 0xd4, 0x2e, 0xa9, 0xd2, 0xe2, 0xe6, 0x4a, 0x74, 0x32, 0x41, 0x6d, - 0x4c, 0xd3, 0xdb, 0x7b, 0x76, 0x63, 0x57, 0xb7, 0xb9, 0x52, 0xf5, 0x08, 0x6d, 0xc0, 0xfa, 0x9e, - 0x61, 0x37, 0x5a, 0xb5, 0x36, 0xeb, 0x01, 0x6d, 0xbd, 0xe5, 0xd6, 0xf9, 0x36, 0xb9, 0x15, 0x3d, - 0x52, 0xbc, 0xb3, 0xb7, 0xde, 0x24, 0x75, 0x98, 0xa9, 0xe0, 0x22, 0x78, 0xbd, 0x53, 0xfb, 0x2f, - 0xfd, 0xbc, 0x08, 0x17, 0x9a, 0xfc, 0x5f, 0x5d, 0x4d, 0x3f, 0x7c, 0xdc, 0xef, 0xf8, 0xc8, 0x80, - 0xd2, 0x9e, 0x1f, 0xf1, 0x67, 0xb2, 0xa9, 0xb1, 0xc4, 0x3c, 0x3e, 0x89, 0x4e, 0xab, 0xa9, 0x7f, - 0x46, 0x69, 0x17, 0xbf, 0xfe, 0x87, 0x0f, 0xde, 0xce, 0x2f, 0xa2, 0xf2, 0xce, 0xe3, 0xdb, 0x3b, - 0xb4, 0xeb, 0xa3, 0x3d, 0x28, 0xd1, 0xa1, 0xc4, 0x0e, 0x7a, 0x48, 0x7c, 0x9c, 0x8b, 0xf9, 0xa7, - 0x3a, 0x49, 0xd0, 0xd6, 0xa8, 0x80, 0x0b, 0x68, 0x99, 0x08, 0x60, 0xef, 0x20, 0x83, 0xa0, 0x77, - 0x2b, 0xf7, 0x62, 0x0e, 0xed, 0xc1, 0x3c, 0x15, 0x34, 0x9a, 0x69, 0xcb, 0x94, 0x34, 0x44, 0xa5, - 0x2d, 0x21, 0x88, 0xa5, 0x8d, 0x5e, 0xcc, 0xa1, 0x2f, 0xc1, 0x82, 0xf9, 0x55, 0xbf, 0x33, 0x8e, - 0x7c, 0x54, 0xe1, 0x1c, 0x53, 0x03, 0x51, 0x75, 0x86, 0x0e, 0xed, 0x2a, 0x15, 0xb9, 0xa6, 0x2d, - 0x52, 0x91, 0x4c, 0xcc, 0x5d, 0x3e, 0x1e, 0x21, 0x0f, 0xca, 0xfa, 0x38, 0x0a, 0x68, 0x43, 0x46, - 0x6b, 0xe9, 0x51, 0xe8, 0x2c, 0xc1, 0x37, 0xa9, 0xe0, 0xeb, 0xd5, 0xcb, 0x44, 0x30, 0x9d, 0x6e, - 0x76, 0xbc, 0x71, 0x14, 0xb4, 0x85, 0x0e, 0x36, 0x44, 0xa1, 0x36, 0x94, 0x88, 0x0a, 0xf2, 0x31, - 0x72, 0x5e, 0x0d, 0x37, 0xa8, 0x86, 0x6b, 0xd5, 0x35, 0x7a, 0x38, 0xa7, 0xc3, 0x4e, 0xa6, 0x82, - 0x0e, 0x00, 0x51, 0xc0, 0xc6, 0x81, 0xf3, 0xaa, 0xd8, 0xa4, 0x2a, 0x36, 0xaa, 0x57, 0x88, 0x0a, - 0x36, 0x77, 0x65, 0x2a, 0xb1, 0x61, 0xbe, 0xee, 0x0d, 0xbb, 0x03, 0x1f, 0xa5, 0x06, 0xd7, 0x99, - 0x72, 0xd7, 0xa9, 0xdc, 0xcb, 0xda, 0xc5, 0xe4, 0x20, 0x77, 0xde, 0xa4, 0x02, 0xee, 0xe6, 0xb6, - 0x1e, 0xce, 0x53, 0xf4, 0x9d, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x17, 0x11, 0x94, 0xec, 0xac, - 0x1d, 0x00, 0x00, + // 2708 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0x4d, 0x6c, 0x1b, 0xc7, + 0xf5, 0x17, 0xb9, 0x24, 0x45, 0x3e, 0x7d, 0x78, 0x35, 0x96, 0x6c, 0x86, 0x56, 0x6c, 0x65, 0xff, + 0xb6, 0xe2, 0x28, 0xf9, 0x4b, 0x71, 0x5c, 0x14, 0xa9, 0x9b, 0xb4, 0x58, 0xed, 0x8e, 0xc5, 0xb5, + 0x56, 0x4b, 0x61, 0xb8, 0x4c, 0xe2, 0x00, 0x05, 0xb1, 0x26, 0x57, 0x0c, 0x61, 0x8a, 0xab, 0x2e, + 0x97, 0x4e, 0x75, 0xe9, 0xa1, 0xd7, 0x5e, 0xda, 0xa6, 0x69, 0xd1, 0x9e, 0xd2, 0x43, 0x6f, 0x69, + 0xda, 0x6b, 0x51, 0xb4, 0xe9, 0xa1, 0x40, 0xdb, 0x73, 0x81, 0x02, 0x3d, 0x16, 0x70, 0x0e, 0xbd, + 0x27, 0xfd, 0x2e, 0x50, 0xcc, 0xc7, 0x7e, 0x91, 0x4b, 0x2b, 0x42, 0x0e, 0x3d, 0x89, 0xf3, 0xe6, + 0xf7, 0x3e, 0xe7, 0xcd, 0x7b, 0x6f, 0x47, 0xb0, 0x3c, 0x7a, 0xe8, 0x1c, 0x1d, 0x79, 0x83, 0xee, + 0xf6, 0x89, 0xef, 0x05, 0x1e, 0x2a, 0xb2, 0x3f, 0xb5, 0xf5, 0x9e, 0xe7, 0xf5, 0x06, 0xee, 0x8e, + 0x73, 0xd2, 0xdf, 0x71, 0x86, 0x43, 0x2f, 0x70, 0x82, 0xbe, 0x37, 0x1c, 0x71, 0x50, 0xed, 0x9a, + 0xd8, 0x65, 0xab, 0x07, 0xe3, 0xa3, 0x9d, 0xa0, 0x7f, 0xec, 0x8e, 0x02, 0xe7, 0xf8, 0x44, 0x00, + 0xae, 0x4c, 0x02, 0xdc, 0xe3, 0x93, 0xe0, 0x94, 0x6f, 0x2a, 0xb7, 0x61, 0xa9, 0x19, 0x38, 0x81, + 0x4b, 0xdc, 0xd1, 0x89, 0x37, 0x1c, 0xb9, 0x48, 0x81, 0xe2, 0x88, 0x12, 0xaa, 0xb9, 0x8d, 0xdc, + 0xcd, 0x85, 0x97, 0x16, 0x39, 0x6e, 0x9b, 0x83, 0xf8, 0x96, 0xb2, 0x0e, 0xe5, 0x08, 0x2f, 0x83, + 0x74, 0x3c, 0xea, 0x31, 0x74, 0x85, 0xd0, 0x9f, 0xca, 0xd3, 0x30, 0x4f, 0xdc, 0xaf, 0x8e, 0xdd, + 0x51, 0x80, 0x10, 0x14, 0x86, 0xce, 0xb1, 0x2b, 0x76, 0xd9, 0x6f, 0xe5, 0xdd, 0x02, 0x14, 0x99, + 0x34, 0x74, 0x0b, 0xe0, 0xc1, 0xb8, 0x3f, 0xe8, 0x36, 0x13, 0xfa, 0x56, 0x84, 0xbe, 0xdd, 0x68, + 0x83, 0x24, 0x40, 0xe8, 0x73, 0xb0, 0xd0, 0x75, 0x4f, 0x06, 0xde, 0x29, 0xe7, 0xc9, 0x33, 0x1e, + 0x24, 0x78, 0xf4, 0x78, 0x87, 0x24, 0x61, 0xa8, 0x0e, 0xcb, 0x47, 0x9e, 0xff, 0xb6, 0xe3, 0x77, + 0xdd, 0xee, 0xa1, 0xe7, 0x07, 0xa3, 0x6a, 0x61, 0x43, 0xba, 0xb9, 0xf0, 0xd2, 0x46, 0xd2, 0xb9, + 0xed, 0xbb, 0x29, 0x08, 0x1e, 0x06, 0xfe, 0x29, 0x99, 0xe0, 0x43, 0x1a, 0xc8, 0x34, 0x04, 0xe3, + 0x91, 0xf6, 0x96, 0xdb, 0x79, 0xc8, 0x8d, 0x28, 0x32, 0x23, 0x2e, 0x27, 0x64, 0x25, 0xb7, 0xc9, + 0x14, 0x03, 0xba, 0x03, 0x4b, 0x47, 0xfd, 0x81, 0xdb, 0x3c, 0x1d, 0x76, 0xb8, 0x84, 0x12, 0x93, + 0xb0, 0x2a, 0x24, 0xdc, 0x4d, 0xee, 0x91, 0x34, 0x14, 0x1d, 0xc2, 0xc5, 0xae, 0xfb, 0x60, 0xdc, + 0xeb, 0xf5, 0x87, 0x3d, 0xcd, 0x1b, 0x06, 0x4e, 0x7f, 0xe8, 0xfa, 0xa3, 0xea, 0x3c, 0xf3, 0xe7, + 0x6a, 0x14, 0x88, 0x49, 0x04, 0x7e, 0xe4, 0x0e, 0x03, 0x92, 0xc5, 0x8a, 0x9e, 0x87, 0xf2, 0xb1, + 0x1b, 0x38, 0x5d, 0x27, 0x70, 0xaa, 0x65, 0x66, 0xc8, 0x05, 0x21, 0xe6, 0x40, 0x90, 0x49, 0x04, + 0xa8, 0x35, 0xe1, 0x62, 0x46, 0x98, 0x68, 0x12, 0x3c, 0x74, 0x4f, 0xd9, 0x11, 0x16, 0x09, 0xfd, + 0x89, 0x36, 0xa1, 0xf8, 0xc8, 0x19, 0x8c, 0xc3, 0x23, 0x92, 0x85, 0x48, 0xca, 0xc3, 0x6d, 0xe1, + 0xdb, 0x77, 0xf2, 0x2f, 0xe7, 0xee, 0x15, 0xca, 0x92, 0x5c, 0x50, 0x3e, 0xca, 0x41, 0x39, 0xd4, + 0x88, 0xb6, 0xa0, 0xc8, 0x4e, 0x5d, 0x64, 0xc5, 0x6a, 0x32, 0x2b, 0x22, 0xb3, 0x38, 0x04, 0xfd, + 0x3f, 0x94, 0xf8, 0x61, 0x0b, 0x5d, 0x6b, 0xa9, 0x74, 0x88, 0xd0, 0x02, 0x84, 0xbe, 0x0c, 0xe0, + 0x74, 0xbb, 0x7d, 0x7a, 0x85, 0x9c, 0x41, 0xb5, 0xc3, 0x02, 0x77, 0x6d, 0xc2, 0xe3, 0x6d, 0x35, + 0x42, 0xf0, 0x3c, 0x48, 0xb0, 0xd4, 0x5e, 0x85, 0x0b, 0x13, 0xdb, 0x49, 0xff, 0x2b, 0xdc, 0xff, + 0xd5, 0xa4, 0xff, 0x95, 0x84, 0xb7, 0xca, 0x27, 0x79, 0x58, 0x4a, 0xf9, 0x81, 0x5e, 0x80, 0x95, + 0xe1, 0xf8, 0xf8, 0x81, 0xeb, 0x37, 0x8e, 0x54, 0x3f, 0xe8, 0x1f, 0x39, 0x9d, 0x60, 0x24, 0x62, + 0x39, 0xbd, 0x81, 0x5e, 0x85, 0x32, 0xf3, 0x9b, 0x1e, 0x7b, 0x9e, 0x59, 0xff, 0x4c, 0x56, 0x74, + 0xb6, 0x8d, 0x63, 0xa7, 0xe7, 0xee, 0x72, 0x24, 0x89, 0x58, 0xd0, 0x75, 0x28, 0x04, 0xa7, 0x27, + 0x6e, 0x55, 0xda, 0xc8, 0xdd, 0x5c, 0x8e, 0xce, 0x85, 0xe1, 0xec, 0xd3, 0x13, 0x97, 0xb0, 0x5d, + 0xa4, 0x67, 0x04, 0xe9, 0x7a, 0xa6, 0x9a, 0x27, 0x45, 0xca, 0x84, 0xc5, 0xa4, 0x15, 0x68, 0x53, + 0xe8, 0xce, 0x31, 0xdd, 0x28, 0x29, 0xcf, 0xf5, 0x13, 0xda, 0x57, 0xa1, 0xd8, 0xf1, 0xc6, 0xc3, + 0x80, 0x05, 0xaf, 0x48, 0xf8, 0xe2, 0xb3, 0xc6, 0xfd, 0xb7, 0x39, 0x58, 0x4e, 0xa7, 0x04, 0x7a, + 0x05, 0x2a, 0x3c, 0x29, 0x68, 0x2c, 0x73, 0x13, 0x57, 0x28, 0x89, 0x14, 0x4b, 0xd7, 0x27, 0x31, + 0x03, 0x7a, 0x01, 0xe6, 0x3b, 0x83, 0xf1, 0x28, 0x70, 0x7d, 0xa6, 0x2c, 0x76, 0x48, 0xe3, 0x54, + 0xe6, 0x50, 0x08, 0xa9, 0x19, 0x50, 0x0e, 0x85, 0xa0, 0x67, 0x53, 0x71, 0xb8, 0x98, 0x52, 0x79, + 0x76, 0x20, 0x94, 0xf7, 0x73, 0x00, 0x71, 0x7d, 0x44, 0x5f, 0x82, 0x8a, 0x93, 0x48, 0x9b, 0x64, + 0x61, 0x8b, 0x51, 0xdb, 0x51, 0x02, 0xf1, 0x63, 0x8a, 0x59, 0xd0, 0x06, 0x2c, 0x38, 0xe3, 0xc0, + 0xb3, 0xfd, 0x7e, 0xaf, 0x27, 0x7c, 0x29, 0x93, 0x24, 0xa9, 0xf6, 0x0a, 0x2c, 0xa7, 0xd9, 0xcf, + 0x15, 0xf8, 0x3d, 0x58, 0x48, 0x54, 0x66, 0x74, 0x09, 0x4a, 0xbc, 0x22, 0x0a, 0x6e, 0xb1, 0x3a, + 0xdb, 0x0c, 0xe5, 0x83, 0x1c, 0xc8, 0x93, 0xe5, 0x75, 0xa6, 0x38, 0x1d, 0x2a, 0xbe, 0x3b, 0xf2, + 0xc6, 0x7e, 0xc7, 0x0d, 0xef, 0xc9, 0xe6, 0x8c, 0x12, 0xbd, 0x4d, 0x42, 0xa0, 0x88, 0x4d, 0xc4, + 0x48, 0x3d, 0x4f, 0x6f, 0x9e, 0xcb, 0x73, 0x03, 0x96, 0x52, 0xc5, 0xfc, 0x33, 0xf8, 0xfe, 0xe7, + 0x02, 0x14, 0x59, 0xe1, 0x44, 0x2f, 0x42, 0x85, 0x96, 0x63, 0xb6, 0x10, 0xe5, 0x51, 0x4e, 0x94, + 0x2f, 0x46, 0xaf, 0xcf, 0x91, 0x18, 0x84, 0x6e, 0x8b, 0x3e, 0xcb, 0x59, 0xf2, 0xd3, 0x7d, 0x36, + 0xe4, 0x49, 0xc0, 0xd0, 0xe7, 0xc3, 0x4e, 0xcb, 0xb9, 0xa4, 0x8c, 0x4e, 0x1b, 0xb2, 0x25, 0x81, + 0xd4, 0xbc, 0x93, 0xb0, 0xc8, 0x57, 0x0b, 0xd9, 0xc5, 0x9f, 0x9a, 0x17, 0x81, 0x10, 0x4e, 0xf5, + 0x54, 0xce, 0x38, 0xb3, 0xa7, 0x86, 0xfc, 0x53, 0x2c, 0xe8, 0x2b, 0x50, 0x0d, 0xcf, 0x6d, 0x12, + 0x2f, 0x1a, 0x6c, 0x58, 0xe5, 0xc9, 0x0c, 0x58, 0x7d, 0x8e, 0xcc, 0x14, 0x81, 0x5e, 0x89, 0x9b, + 0x36, 0x97, 0x39, 0x9f, 0xd9, 0xb4, 0x43, 0x41, 0x69, 0x30, 0x7a, 0x13, 0x2e, 0x77, 0xb3, 0x9b, + 0xb2, 0xe8, 0xb9, 0x67, 0xb4, 0xee, 0xfa, 0x1c, 0x99, 0x25, 0x00, 0x7d, 0x01, 0x16, 0xbb, 0xee, + 0x23, 0xd3, 0xf3, 0x4e, 0xb8, 0xc0, 0x0a, 0x13, 0x18, 0x57, 0x95, 0x78, 0xab, 0x3e, 0x47, 0x52, + 0xd0, 0xdd, 0x45, 0x00, 0x97, 0xfe, 0x68, 0xd3, 0x6a, 0xa3, 0x0c, 0x60, 0x31, 0x89, 0x46, 0xeb, + 0x50, 0xe9, 0x07, 0xae, 0xcf, 0xa6, 0x4d, 0xd1, 0x8f, 0x62, 0x42, 0x22, 0x97, 0xf3, 0xa9, 0x5c, + 0xde, 0x04, 0xc9, 0xf5, 0x7d, 0x91, 0x30, 0x61, 0x78, 0xd4, 0x0e, 0x2b, 0xdb, 0x0f, 0x06, 0x2e, + 0xf6, 0x7d, 0x42, 0x01, 0xca, 0x37, 0x73, 0xb0, 0x94, 0x22, 0xa3, 0xe7, 0x61, 0xde, 0xf5, 0x7d, + 0xcd, 0xeb, 0x86, 0x95, 0x71, 0x25, 0x7d, 0xfe, 0x5e, 0xd7, 0x25, 0x21, 0x02, 0x55, 0x61, 0xfe, + 0xd8, 0x1d, 0x8d, 0x9c, 0x5e, 0x78, 0xef, 0xc2, 0x25, 0xba, 0x0d, 0x0b, 0xa3, 0x71, 0xaf, 0xe7, + 0x8e, 0xd8, 0x94, 0x5c, 0x95, 0xd8, 0xdd, 0x8f, 0x44, 0x45, 0x3b, 0x24, 0x89, 0x52, 0x2c, 0xa8, + 0x44, 0xb7, 0x87, 0xde, 0x68, 0x97, 0x5e, 0x76, 0x71, 0x4b, 0xf9, 0x22, 0x35, 0x28, 0xe5, 0xcf, + 0x18, 0x94, 0x94, 0x5f, 0x84, 0x35, 0x9a, 0x4b, 0xac, 0x41, 0x39, 0x2c, 0xb8, 0x42, 0x68, 0xb4, + 0x9e, 0x19, 0x48, 0x39, 0x0e, 0x64, 0x85, 0x85, 0x2c, 0x19, 0xa0, 0xc2, 0x99, 0x01, 0xba, 0x03, + 0x4b, 0x4e, 0x32, 0xbc, 0xe2, 0x4e, 0x65, 0x9f, 0x48, 0x1a, 0xaa, 0xbc, 0x97, 0x0b, 0x6b, 0x36, + 0x37, 0x7f, 0x56, 0xdd, 0x12, 0x26, 0xe6, 0x33, 0x4d, 0x94, 0xce, 0x6f, 0x62, 0xe1, 0xd3, 0x9b, + 0xf8, 0x61, 0xba, 0x19, 0x3c, 0xd9, 0xce, 0xd9, 0xc9, 0xf2, 0x3f, 0x0c, 0xf2, 0x5f, 0x72, 0x50, + 0x9d, 0x55, 0x8a, 0x68, 0xc2, 0x84, 0xa5, 0x28, 0x4c, 0x98, 0x70, 0x3d, 0x33, 0x61, 0x12, 0x5e, + 0x4a, 0x99, 0x5e, 0x16, 0x62, 0x2f, 0x6f, 0x01, 0x8c, 0x22, 0x7f, 0x98, 0xd5, 0x99, 0x8e, 0x26, + 0x40, 0xd3, 0xbe, 0x96, 0x3e, 0xbd, 0xaf, 0x3f, 0xce, 0x43, 0x25, 0x2a, 0xff, 0xb4, 0xb0, 0x0c, + 0xbc, 0x8e, 0x33, 0xa0, 0x94, 0xb0, 0xb0, 0x44, 0x04, 0x74, 0x15, 0xc0, 0x77, 0x8f, 0xbd, 0xc0, + 0x65, 0xdb, 0x7c, 0xf2, 0x49, 0x50, 0xa8, 0x9b, 0x27, 0x5e, 0xd7, 0xa2, 0xdf, 0x95, 0xc2, 0x4d, + 0xb1, 0x44, 0xd7, 0x61, 0xa9, 0x13, 0xd6, 0x46, 0xb6, 0xcf, 0x1d, 0x4e, 0x13, 0xa9, 0x76, 0xfa, + 0x21, 0x3a, 0x3a, 0x71, 0x3a, 0xdc, 0xf3, 0x0a, 0x89, 0x09, 0x34, 0xf0, 0xb4, 0x35, 0x31, 0xf6, + 0x12, 0x0f, 0x7c, 0xb8, 0x46, 0x0a, 0x2c, 0x86, 0x87, 0x40, 0x87, 0x34, 0xd6, 0x02, 0x2a, 0x24, + 0x45, 0x4b, 0x62, 0x98, 0x8c, 0x72, 0x1a, 0xc3, 0xe4, 0x54, 0x61, 0xde, 0xe9, 0x76, 0x7d, 0x77, + 0x34, 0x62, 0xc5, 0xba, 0x42, 0xc2, 0xa5, 0xf2, 0xc7, 0x5c, 0x3c, 0x32, 0x44, 0xb1, 0xa2, 0xad, + 0x44, 0x63, 0x63, 0xa0, 0x88, 0x55, 0x44, 0xa0, 0x95, 0xaa, 0x7f, 0x1c, 0xa7, 0x35, 0x5f, 0x24, + 0x12, 0x44, 0xca, 0xba, 0xae, 0x85, 0xcc, 0x64, 0x2f, 0x9e, 0x3f, 0xd9, 0xcf, 0x91, 0x00, 0x1f, + 0xe7, 0xe1, 0xf2, 0x8c, 0xde, 0xf6, 0xa4, 0x5b, 0x1b, 0x1e, 0x74, 0xfe, 0x8c, 0x83, 0x96, 0xce, + 0x3c, 0xe8, 0x42, 0xc6, 0x41, 0x47, 0x25, 0xb9, 0x38, 0x51, 0x92, 0xab, 0x30, 0xef, 0x8f, 0x87, + 0x41, 0x3f, 0xca, 0x81, 0x70, 0x49, 0x93, 0xf3, 0x6d, 0xcf, 0x7f, 0xd8, 0x1f, 0xf6, 0xf4, 0xbe, + 0x2f, 0x12, 0x20, 0x41, 0x41, 0x16, 0x00, 0xeb, 0xd3, 0xfc, 0x99, 0xa1, 0xcc, 0x7a, 0xcf, 0xf6, + 0x93, 0x7b, 0x3b, 0xa7, 0x27, 0x1e, 0x1d, 0x12, 0x12, 0xe8, 0x47, 0xcf, 0xc4, 0xf6, 0x59, 0x13, + 0xe8, 0x52, 0x72, 0x02, 0xfd, 0x3a, 0x94, 0x4d, 0xaf, 0xc7, 0xf9, 0x5e, 0x86, 0x4a, 0xf4, 0x34, + 0x24, 0x06, 0xc7, 0xda, 0x36, 0x7f, 0x1b, 0xda, 0x0e, 0xdf, 0x86, 0xb6, 0xed, 0x10, 0x41, 0x62, + 0x30, 0x52, 0xa0, 0xe8, 0x26, 0x66, 0xc7, 0xf0, 0x4d, 0x48, 0x7c, 0xc8, 0xbb, 0xe9, 0x9e, 0x29, + 0x25, 0x7a, 0xa6, 0x72, 0x07, 0x56, 0x5a, 0x23, 0xd7, 0x37, 0x86, 0x01, 0x85, 0x8a, 0x57, 0xa1, + 0x1b, 0x50, 0xea, 0x33, 0x82, 0xb0, 0x62, 0x49, 0xc8, 0x13, 0x28, 0xb1, 0xa9, 0x7c, 0x11, 0x96, + 0xc5, 0xf4, 0x1b, 0x32, 0x3e, 0x97, 0x7e, 0x9b, 0x0a, 0x47, 0x1c, 0x81, 0x4a, 0x3d, 0x51, 0xdd, + 0x82, 0xc5, 0x24, 0x19, 0xd5, 0x60, 0xde, 0x65, 0xc9, 0xc8, 0x9f, 0x14, 0xca, 0xf5, 0x39, 0x12, + 0x12, 0x76, 0x8b, 0x20, 0x3d, 0x72, 0x06, 0xca, 0x3d, 0x28, 0x71, 0x0b, 0xa8, 0x2f, 0xf1, 0xeb, + 0x43, 0x39, 0x7c, 0x67, 0x40, 0x50, 0x18, 0x9d, 0x0e, 0x3b, 0x62, 0x3a, 0x67, 0xbf, 0x69, 0xea, + 0x8a, 0xb7, 0x07, 0x89, 0x51, 0xc5, 0x4a, 0xe9, 0x00, 0xc4, 0x93, 0x06, 0x7a, 0x15, 0x96, 0xe3, + 0x59, 0x23, 0x31, 0xdf, 0xac, 0x4d, 0x0d, 0x25, 0xec, 0xc2, 0x4d, 0x80, 0xa9, 0x12, 0x7e, 0x99, + 0xc2, 0x7a, 0xcf, 0x57, 0x5b, 0x1e, 0x2c, 0x24, 0xbe, 0x9d, 0x51, 0x15, 0x56, 0x5b, 0xd6, 0xbe, + 0xd5, 0x78, 0xdd, 0x6a, 0xef, 0xb6, 0x0c, 0x53, 0xc7, 0xa4, 0x6d, 0xdf, 0x3f, 0xc4, 0xf2, 0x1c, + 0x9a, 0x07, 0xe9, 0x9e, 0xb1, 0x2b, 0xe7, 0x50, 0x05, 0x8a, 0xbb, 0xea, 0x9b, 0xd8, 0x94, 0xf3, + 0x68, 0x19, 0x80, 0xa1, 0x0e, 0x55, 0x6d, 0xbf, 0x29, 0x4b, 0x08, 0xa0, 0xa4, 0xb5, 0x9a, 0x76, + 0xe3, 0x40, 0x2e, 0xd0, 0xdf, 0xfb, 0xaa, 0x65, 0xec, 0x37, 0xe4, 0x22, 0xfd, 0xad, 0x37, 0xb4, + 0x7d, 0x4c, 0xe4, 0xd2, 0x96, 0x0e, 0x95, 0xe8, 0xa1, 0x00, 0x5d, 0x02, 0x94, 0x52, 0x17, 0x2a, + 0x5b, 0x80, 0x79, 0xcd, 0x6c, 0x35, 0x6d, 0x4c, 0xe4, 0x1c, 0xd5, 0xbc, 0xa7, 0xed, 0xca, 0x79, + 0xaa, 0xd9, 0x6c, 0x68, 0xaa, 0x29, 0x4b, 0x5b, 0x0d, 0x3a, 0x66, 0xc6, 0x9f, 0xba, 0xe8, 0x29, + 0x58, 0x0b, 0x05, 0xe9, 0xf8, 0xd0, 0x6c, 0xdc, 0x8f, 0x0d, 0x2f, 0x43, 0xa1, 0x8e, 0xcd, 0x03, + 0x39, 0x87, 0x96, 0xa0, 0xb2, 0xcf, 0xcc, 0x33, 0xde, 0xc4, 0x72, 0x9e, 0x2a, 0xd9, 0x6f, 0xed, + 0x62, 0xcd, 0xa6, 0x02, 0x0d, 0x58, 0x48, 0x7c, 0x72, 0x27, 0xe3, 0x20, 0x0c, 0x09, 0xc5, 0x2d, + 0x42, 0xf9, 0xc0, 0xb0, 0x0c, 0xca, 0x29, 0x6c, 0xdb, 0xc7, 0xdc, 0xb6, 0x86, 0x5d, 0xc7, 0x44, + 0x96, 0xb6, 0x1e, 0x57, 0x00, 0xe2, 0xd2, 0x87, 0x4a, 0x90, 0x6f, 0xec, 0xcb, 0x73, 0xa8, 0x0a, + 0x17, 0x9b, 0xb6, 0x6a, 0xb7, 0x9a, 0x5a, 0x1d, 0x6b, 0xfb, 0xed, 0x66, 0x4b, 0xd3, 0x70, 0xb3, + 0x29, 0xff, 0x2e, 0x87, 0x10, 0x2c, 0x71, 0xef, 0x43, 0xda, 0xef, 0x73, 0x68, 0x1d, 0xaa, 0x9c, + 0x76, 0xd8, 0x6a, 0xd6, 0xdb, 0x2a, 0xa3, 0xb7, 0x75, 0x6c, 0x19, 0x58, 0x97, 0x5d, 0x74, 0x05, + 0x2e, 0x8b, 0x5d, 0xd2, 0xb8, 0x87, 0x35, 0xbb, 0x6d, 0x35, 0xec, 0xf6, 0xdd, 0x46, 0xcb, 0xd2, + 0xe5, 0x23, 0x74, 0x0d, 0x6a, 0x49, 0x45, 0xc6, 0x81, 0xba, 0x87, 0xdb, 0x87, 0x2d, 0xd3, 0x6c, + 0x63, 0x42, 0xe4, 0xf7, 0xf3, 0xe8, 0xff, 0xe0, 0x6a, 0x12, 0xa0, 0x35, 0x2c, 0x5b, 0x35, 0x2c, + 0x4c, 0xda, 0x1a, 0xc1, 0xaa, 0x6d, 0x58, 0x7b, 0xf2, 0x4f, 0xf2, 0x48, 0x81, 0xa7, 0x93, 0x20, + 0xd2, 0xb2, 0x12, 0x40, 0x2a, 0xe8, 0x83, 0x3c, 0xba, 0x01, 0x1b, 0xd9, 0x82, 0x6c, 0x4c, 0x0e, + 0x0c, 0x4b, 0xb5, 0xb1, 0x2e, 0xff, 0x34, 0x8f, 0x9e, 0x87, 0xcd, 0x24, 0x8c, 0x1f, 0xd0, 0x01, + 0xb6, 0xec, 0x36, 0x69, 0x98, 0x66, 0xa3, 0x65, 0xb7, 0x0f, 0xb1, 0xa5, 0x53, 0xbd, 0x3f, 0x7b, + 0x82, 0x4c, 0x82, 0x9b, 0xb6, 0x4a, 0x98, 0x79, 0x8f, 0xf3, 0xa8, 0x06, 0x6b, 0x49, 0x58, 0xcb, + 0xaa, 0x63, 0xd5, 0xb4, 0xeb, 0xf7, 0xe5, 0x8f, 0xa6, 0x44, 0x58, 0x0d, 0x1d, 0xb7, 0x0f, 0xf0, + 0x41, 0x83, 0xdc, 0x6f, 0x1f, 0x12, 0xdc, 0x6c, 0xb6, 0x08, 0x96, 0xbf, 0x25, 0x4d, 0x86, 0x81, + 0xc1, 0x74, 0xa3, 0xb9, 0x1f, 0x83, 0xbe, 0x2d, 0xa1, 0xe7, 0xe0, 0xfa, 0x14, 0xc8, 0xc2, 0xf6, + 0xeb, 0x0d, 0x42, 0x95, 0xaa, 0xaf, 0xa9, 0x86, 0xa9, 0xee, 0x9a, 0x58, 0xfe, 0x8e, 0x34, 0x19, + 0x31, 0x06, 0x3d, 0x34, 0xf4, 0x58, 0xdc, 0x3b, 0xd9, 0x3a, 0x5b, 0x16, 0x5d, 0xe9, 0x2d, 0x2e, + 0xe8, 0xbb, 0x12, 0x7a, 0x06, 0xd6, 0x33, 0x40, 0x04, 0xab, 0x5a, 0x9d, 0x41, 0xde, 0x95, 0x26, + 0xcf, 0x98, 0x9b, 0xd5, 0xb0, 0xdb, 0x04, 0xab, 0xfa, 0x7d, 0xf9, 0x7b, 0x53, 0xc6, 0xdc, 0x55, + 0x0d, 0x13, 0xeb, 0x6d, 0xa1, 0x88, 0xc6, 0xf0, 0xfb, 0x12, 0x7a, 0x16, 0x94, 0x24, 0x46, 0x5c, + 0x06, 0x1a, 0x72, 0x0b, 0x6b, 0xb6, 0xd1, 0xb0, 0xd8, 0x39, 0xff, 0x60, 0xca, 0xea, 0x10, 0x48, + 0x9d, 0xdb, 0x37, 0x4c, 0x13, 0xeb, 0xf2, 0x0f, 0x25, 0x9a, 0xc5, 0xe1, 0x95, 0xc1, 0x84, 0x34, + 0x88, 0xfc, 0xb1, 0x34, 0x99, 0xf3, 0x62, 0x5f, 0xfe, 0x44, 0x42, 0x9b, 0xf0, 0x4c, 0xc6, 0xce, + 0x44, 0x2c, 0xfe, 0x2a, 0xa1, 0x2d, 0xb8, 0x91, 0x9d, 0x0e, 0xaf, 0xab, 0x06, 0xcd, 0x85, 0x48, + 0xe6, 0xdf, 0x24, 0x74, 0x15, 0x9e, 0xca, 0x92, 0x89, 0x5f, 0xc3, 0x96, 0x2d, 0xff, 0x47, 0x42, + 0x17, 0x61, 0x99, 0xe7, 0x5e, 0xc4, 0xf4, 0x77, 0x09, 0xad, 0xc0, 0x62, 0xf3, 0xbe, 0xa5, 0x45, + 0xa4, 0x7f, 0x48, 0xf1, 0x7d, 0x0c, 0x69, 0xff, 0x94, 0xd0, 0x2a, 0x5c, 0xd0, 0xf1, 0x6b, 0x86, + 0x65, 0xd8, 0x11, 0xf5, 0x5f, 0x8c, 0xaa, 0x99, 0x58, 0xb5, 0x5a, 0x87, 0x11, 0xf5, 0xdf, 0x8c, + 0xca, 0x44, 0x32, 0x34, 0x8f, 0xc5, 0x9f, 0x0a, 0x68, 0x03, 0xae, 0x84, 0x12, 0x08, 0xde, 0x33, + 0x58, 0x4d, 0xe1, 0x6a, 0x74, 0x7c, 0xd8, 0x94, 0x7f, 0x59, 0xa4, 0x87, 0x3a, 0x85, 0xb0, 0x71, + 0xd3, 0xe6, 0x80, 0x5f, 0x15, 0x69, 0x62, 0x4c, 0x01, 0x84, 0x47, 0x0c, 0xf2, 0x61, 0x31, 0x53, + 0x8b, 0xd6, 0xb0, 0xee, 0x1a, 0x7b, 0x14, 0x22, 0xff, 0xba, 0x38, 0x99, 0x19, 0x34, 0xa2, 0xf8, + 0x0d, 0xbb, 0xad, 0xa9, 0x96, 0x86, 0xd9, 0x59, 0xbe, 0x57, 0x9a, 0xc4, 0xe8, 0x58, 0xd5, 0x4d, + 0xc3, 0xc2, 0x6d, 0xfc, 0x86, 0x86, 0xb1, 0x8e, 0x75, 0xf9, 0x47, 0xa5, 0xad, 0xdf, 0xe4, 0x60, + 0x39, 0xdd, 0x74, 0x68, 0x35, 0xb4, 0x0c, 0x53, 0x9e, 0x43, 0xab, 0x20, 0xab, 0x3a, 0x75, 0xec, + 0xae, 0xda, 0x32, 0xa9, 0x25, 0x87, 0x0d, 0xb9, 0x4b, 0xab, 0x7d, 0x28, 0x2f, 0x41, 0xa7, 0x93, + 0xd8, 0xc6, 0x34, 0xbd, 0xbd, 0x67, 0x36, 0x76, 0x55, 0x53, 0x18, 0x2f, 0x1f, 0xa1, 0x0d, 0x58, + 0xdf, 0xd3, 0xcc, 0x46, 0x4b, 0x6f, 0xf3, 0x5e, 0xd2, 0x56, 0x5b, 0x76, 0x5d, 0x6c, 0xd3, 0xdb, + 0xd5, 0xa3, 0x4d, 0x20, 0x7b, 0xeb, 0x2d, 0x5a, 0xcf, 0xb9, 0x0a, 0x21, 0x42, 0xd4, 0x4d, 0xb9, + 0xff, 0xd2, 0xcf, 0x8b, 0x70, 0xa1, 0x29, 0xfe, 0x65, 0xd6, 0x74, 0xfd, 0x47, 0xfd, 0x8e, 0x8b, + 0x34, 0x28, 0xef, 0xb9, 0x81, 0x78, 0x6e, 0x9b, 0x1a, 0x6f, 0xf0, 0xf1, 0x49, 0x70, 0x5a, 0x4b, + 0xfd, 0x53, 0x4b, 0x59, 0xf9, 0xc6, 0x1f, 0x1e, 0xbf, 0x93, 0x5f, 0x40, 0x95, 0x9d, 0x47, 0xb7, + 0x76, 0xd8, 0xf4, 0x80, 0xf6, 0xa0, 0xcc, 0x86, 0x1b, 0xd3, 0xeb, 0xa1, 0xf0, 0x23, 0x3f, 0x9c, + 0xa3, 0x6a, 0x93, 0x04, 0x65, 0x8d, 0x09, 0xb8, 0x80, 0x96, 0xa8, 0x00, 0xfe, 0x9e, 0x32, 0xf0, + 0x7a, 0x37, 0x73, 0x2f, 0xe6, 0xd0, 0x1e, 0x94, 0x98, 0xa0, 0xd1, 0x4c, 0x5b, 0xa6, 0xa4, 0x21, + 0x26, 0x6d, 0x11, 0x41, 0x24, 0x6d, 0xf4, 0x62, 0x0e, 0xbd, 0x01, 0xf3, 0xf8, 0x6b, 0x6e, 0x67, + 0x1c, 0xb8, 0xa8, 0x2a, 0x38, 0xa6, 0x06, 0xab, 0xda, 0x0c, 0x1d, 0xca, 0x15, 0x26, 0x72, 0x4d, + 0x59, 0x60, 0x22, 0xb9, 0x98, 0x3b, 0x62, 0xcc, 0x42, 0x0e, 0x54, 0xd4, 0x71, 0xe0, 0xb1, 0xc6, + 0x8e, 0xd6, 0xd2, 0x23, 0xd5, 0x59, 0x82, 0x6f, 0x30, 0xc1, 0xd7, 0x6a, 0x97, 0xa8, 0x60, 0x36, + 0x25, 0xed, 0x38, 0xe3, 0xc0, 0x6b, 0x87, 0x3a, 0xf8, 0x30, 0x86, 0xda, 0x50, 0xa6, 0x2a, 0xe8, + 0x47, 0xcd, 0x79, 0x35, 0x5c, 0x67, 0x1a, 0xae, 0xd6, 0xd6, 0xd8, 0xe1, 0x9c, 0x0e, 0x3b, 0x99, + 0x0a, 0x3a, 0x00, 0x54, 0x01, 0x1f, 0x2b, 0xce, 0xab, 0x62, 0x93, 0xa9, 0xd8, 0xa8, 0x5d, 0xa6, + 0x2a, 0xf8, 0xfc, 0x96, 0xa9, 0xc4, 0x84, 0x52, 0xdd, 0x19, 0x76, 0x07, 0x2e, 0x4a, 0x0d, 0xc0, + 0x33, 0xe5, 0xae, 0x33, 0xb9, 0x97, 0x94, 0x95, 0xf8, 0x20, 0x77, 0xde, 0x62, 0x02, 0xee, 0xe4, + 0xb6, 0x1e, 0x94, 0x18, 0xfa, 0xf6, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x30, 0xbf, 0x79, 0x7c, + 0xf4, 0x1d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/proto/skaffold.proto b/proto/skaffold.proto index 427fb7c1b92..11d70df7f1e 100644 --- a/proto/skaffold.proto +++ b/proto/skaffold.proto @@ -474,6 +474,14 @@ enum StatusCode { DEVINIT_REGISTER_DEPLOY_DEPS = 703; // Failed to configure watcher for Skaffold configuration file. DEVINIT_REGISTER_CONFIG_DEP = 704; + + // Timeout or User Cancellation Errors + + // User cancelled the skaffold dev run + STATUSCHECK_CONTEXT_CANCELLED = 800; + + // Deadline for status check exceeded + STATUSCHECK_DEADLINE_EXCEEDED = 801; } // Enum for Suggestion codes From 95787548244548e56f5f3b797aeea16073ce7b25 Mon Sep 17 00:00:00 2001 From: tejal29 Date: Wed, 24 Jun 2020 17:55:10 -0700 Subject: [PATCH 2/3] fix error status detection --- pkg/skaffold/deploy/resource/status.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/skaffold/deploy/resource/status.go b/pkg/skaffold/deploy/resource/status.go index 8b63a40100f..07fe294c1b2 100644 --- a/pkg/skaffold/deploy/resource/status.go +++ b/pkg/skaffold/deploy/resource/status.go @@ -29,6 +29,9 @@ type Status struct { } func (rs Status) Error() error { + if rs.ae.ErrCode == proto.StatusCode_STATUSCHECK_SUCCESS { + return nil + } return fmt.Errorf(rs.ae.Message) } From 270899b38957dd55087a547ebaa00cbc17e19a68 Mon Sep 17 00:00:00 2001 From: tejal29 Date: Wed, 24 Jun 2020 21:07:12 -0700 Subject: [PATCH 3/3] change *proto.ActionableErr to proto.ActionableErr --- pkg/diag/validator/pod.go | 26 ++++++++++++------- pkg/diag/validator/pod_test.go | 26 +++++++++---------- pkg/diag/validator/resource.go | 8 +++--- pkg/diag/validator/resource_test.go | 7 ++--- pkg/skaffold/deploy/resource/deployment.go | 16 ++++++------ .../deploy/resource/deployment_test.go | 18 ++++++------- pkg/skaffold/deploy/resource/status.go | 11 +++----- pkg/skaffold/deploy/resource/status_test.go | 24 ++++++++--------- pkg/skaffold/deploy/status_check.go | 2 +- pkg/skaffold/deploy/status_check_test.go | 26 +++++++++---------- pkg/skaffold/event/event.go | 10 +++---- pkg/skaffold/event/event_test.go | 4 +-- 12 files changed, 91 insertions(+), 87 deletions(-) diff --git a/pkg/diag/validator/pod.go b/pkg/diag/validator/pod.go index 5b6b91ea19f..262745b3df2 100644 --- a/pkg/diag/validator/pod.go +++ b/pkg/diag/validator/pod.go @@ -209,15 +209,15 @@ func processPodEvents(e corev1.EventInterface, pod v1.Pod, ps *podStatus) { } switch recentEvent.Reason { case failedScheduling: - ps.ae.ErrCode = proto.StatusCode_STATUSCHECK_FAILED_SCHEDULING - ps.ae.Message = recentEvent.Message + ps.updateAE(proto.StatusCode_STATUSCHECK_FAILED_SCHEDULING, recentEvent.Message) case unhealthy: - ps.ae.ErrCode = proto.StatusCode_STATUSCHECK_UNHEALTHY - ps.ae.Message = recentEvent.Message + ps.updateAE(proto.StatusCode_STATUSCHECK_UNHEALTHY, recentEvent.Message) default: // TODO: Add unique error codes for reasons - ps.ae.ErrCode = proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT - ps.ae.Message = fmt.Sprintf("%s: %s", recentEvent.Reason, recentEvent.Message) + ps.updateAE( + proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, + fmt.Sprintf("%s: %s", recentEvent.Reason, recentEvent.Message), + ) } } @@ -226,7 +226,7 @@ type podStatus struct { namespace string phase string logs []string - ae *proto.ActionableErr + ae proto.ActionableErr } func (p *podStatus) isStable() bool { @@ -234,14 +234,20 @@ func (p *podStatus) isStable() bool { } func (p *podStatus) withErrAndLogs(errCode proto.StatusCode, l []string, err error) *podStatus { + var msg string if err != nil { - p.ae.Message = err.Error() + msg = err.Error() } - p.ae.ErrCode = errCode + p.updateAE(errCode, msg) p.logs = l return p } +func (p *podStatus) updateAE(errCode proto.StatusCode, msg string) { + p.ae.ErrCode = errCode + p.ae.Message = msg +} + func (p *podStatus) String() string { switch { case p.isStable(): @@ -279,7 +285,7 @@ func newPodStatus(n string, ns string, p string) *podStatus { name: n, namespace: ns, phase: p, - ae: &proto.ActionableErr{ + ae: proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, }, } diff --git a/pkg/diag/validator/pod_test.go b/pkg/diag/validator/pod_test.go index 8f36fd06fc6..a6d6b8c0b67 100644 --- a/pkg/diag/validator/pod_test.go +++ b/pkg/diag/validator/pod_test.go @@ -84,7 +84,7 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "container foo-container is waiting to start: foo-image can't be pulled", ErrCode: proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, }, nil)}, @@ -115,7 +115,7 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "container foo-container is waiting to start: foo-image can't be pulled", ErrCode: proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, }, nil)}, @@ -146,7 +146,7 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "container foo-container is waiting to start: foo-image can't be pulled", ErrCode: proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, }, nil)}, @@ -165,7 +165,7 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Succeeded", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "", ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, }, nil)}, @@ -190,7 +190,7 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Running", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "", ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, }, nil)}, @@ -213,7 +213,7 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "could not determine", ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, }, nil)}, @@ -237,7 +237,7 @@ func TestRun(t *testing.T) { }, }}, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "Unschedulable: 0/2 nodes available: 1 node has disk pressure, 1 node is unreachable", ErrCode: proto.StatusCode_STATUSCHECK_NODE_DISK_PRESSURE, }, nil)}, @@ -265,7 +265,7 @@ func TestRun(t *testing.T) { output: []byte("main.go:57 \ngo panic"), }, expected: []Resource{NewResource("test", "Pod", "foo", "Running", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "container foo-container terminated with exit code 1", ErrCode: proto.StatusCode_STATUSCHECK_CONTAINER_TERMINATED, }, []string{ @@ -295,7 +295,7 @@ func TestRun(t *testing.T) { err: fmt.Errorf("error"), }, expected: []Resource{NewResource("test", "pod", "foo", "Running", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "container foo-container terminated with exit code 1", ErrCode: proto.StatusCode_STATUSCHECK_CONTAINER_TERMINATED, }, []string{ @@ -327,7 +327,7 @@ func TestRun(t *testing.T) { }, }, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "eventCode: dummy event", ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, }, nil)}, @@ -362,7 +362,7 @@ func TestRun(t *testing.T) { }, }, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "eventCode: dummy event", ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, }, nil)}, @@ -397,7 +397,7 @@ func TestRun(t *testing.T) { }, }, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "eventCode: dummy event", ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN_EVENT, }, nil)}, @@ -432,7 +432,7 @@ func TestRun(t *testing.T) { }, }, expected: []Resource{NewResource("test", "Pod", "foo", "Pending", - &proto.ActionableErr{ + proto.ActionableErr{ Message: "0/1 nodes are available: 1 node(s) had taint {key: value}, that the pod didn't tolerate", ErrCode: proto.StatusCode_STATUSCHECK_FAILED_SCHEDULING, }, nil)}, diff --git a/pkg/diag/validator/resource.go b/pkg/diag/validator/resource.go index dd8f8d19c9f..d8deb951d3f 100644 --- a/pkg/diag/validator/resource.go +++ b/pkg/diag/validator/resource.go @@ -31,7 +31,7 @@ type Resource struct { name string logs []string status Status - ae *proto.ActionableErr + ae proto.ActionableErr } func (r Resource) Kind() string { return r.kind } @@ -45,7 +45,7 @@ func (r Resource) String() string { } return fmt.Sprintf("%s:%s/%s", r.namespace, r.kind, r.name) } -func (r Resource) ActionableError() *proto.ActionableErr { +func (r Resource) ActionableError() proto.ActionableErr { return r.ae } func (r Resource) StatusUpdated(another Resource) bool { @@ -53,7 +53,7 @@ func (r Resource) StatusUpdated(another Resource) bool { } // NewResource creates new Resource of kind -func NewResource(namespace, kind, name string, status Status, ae *proto.ActionableErr, logs []string) Resource { +func NewResource(namespace, kind, name string, status Status, ae proto.ActionableErr, logs []string) Resource { return Resource{namespace: namespace, kind: kind, name: name, status: status, ae: ae, logs: logs} } @@ -64,6 +64,6 @@ type objectWithMetadata interface { } // NewResourceFromObject creates new Resource with fields populated from object metadata. -func NewResourceFromObject(object objectWithMetadata, status Status, ae *proto.ActionableErr, logs []string) Resource { +func NewResourceFromObject(object objectWithMetadata, status Status, ae proto.ActionableErr, logs []string) Resource { return NewResource(object.GetNamespace(), object.GetObjectKind().GroupVersionKind().Kind, object.GetName(), status, ae, logs) } diff --git a/pkg/diag/validator/resource_test.go b/pkg/diag/validator/resource_test.go index 9ed0436cf26..1b7c5134c4f 100644 --- a/pkg/diag/validator/resource_test.go +++ b/pkg/diag/validator/resource_test.go @@ -23,6 +23,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/GoogleContainerTools/skaffold/proto" "github.com/GoogleContainerTools/skaffold/testutil" ) @@ -42,7 +43,7 @@ func TestNewResource(t *testing.T) { Name: "foo", }, }, - expected: Resource{"default", "pod", "foo", nil, Status(""), nil}, + expected: Resource{"default", "pod", "foo", nil, Status(""), proto.ActionableErr{}}, expectedName: "pod/foo", }, { @@ -54,13 +55,13 @@ func TestNewResource(t *testing.T) { Name: "bar", }, }, - expected: Resource{"test", "pod", "bar", nil, Status(""), nil}, + expected: Resource{"test", "pod", "bar", nil, Status(""), proto.ActionableErr{}}, expectedName: "test:pod/bar", }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - actual := NewResourceFromObject(test.resource, Status(""), nil, nil) + actual := NewResourceFromObject(test.resource, Status(""), proto.ActionableErr{}, nil) t.CheckDeepEqual(test.expected, actual, cmp.AllowUnexported(Resource{})) t.CheckDeepEqual(test.expectedName, actual.String(), cmp.AllowUnexported(Resource{})) }) diff --git a/pkg/skaffold/deploy/resource/deployment.go b/pkg/skaffold/deploy/resource/deployment.go index b12f33691e9..a33b5f87ced 100644 --- a/pkg/skaffold/deploy/resource/deployment.go +++ b/pkg/skaffold/deploy/resource/deployment.go @@ -63,7 +63,7 @@ func (d *Deployment) Deadline() time.Duration { return d.deadline } -func (d *Deployment) UpdateStatus(ae *proto.ActionableErr) { +func (d *Deployment) UpdateStatus(ae proto.ActionableErr) { updated := newStatus(ae) if d.status.Equal(updated) { d.status.changed = false @@ -81,7 +81,7 @@ func NewDeployment(name string, ns string, deadline time.Duration) *Deployment { name: name, namespace: ns, rType: deploymentType, - status: newStatus(&proto.ActionableErr{}), + status: newStatus(proto.ActionableErr{}), deadline: deadline, podValidator: diag.New(nil), } @@ -174,30 +174,30 @@ func (d *Deployment) cleanupStatus(msg string) string { // $kubectl logs testPod -f // 2020/06/18 17:28:31 service is running // Killed: 9 -func parseKubectlRolloutError(details string, err error) *proto.ActionableErr { +func parseKubectlRolloutError(details string, err error) proto.ActionableErr { switch { case err == nil && strings.Contains(details, rollOutSuccess): - return &proto.ActionableErr{ + return proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, Message: details, } case err == nil: - return &proto.ActionableErr{ + return proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING, Message: details, } case strings.Contains(err.Error(), connectionErrMsg): - return &proto.ActionableErr{ + return proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR, Message: MsgKubectlConnection, } case strings.Contains(err.Error(), killedErrMsg): - return &proto.ActionableErr{ + return proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_PID_KILLED, Message: msgKubectlKilled, } default: - return &proto.ActionableErr{ + return proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, Message: err.Error(), } diff --git a/pkg/skaffold/deploy/resource/deployment_test.go b/pkg/skaffold/deploy/resource/deployment_test.go index eb635203358..9fad404809c 100644 --- a/pkg/skaffold/deploy/resource/deployment_test.go +++ b/pkg/skaffold/deploy/resource/deployment_test.go @@ -105,12 +105,12 @@ func TestParseKubectlError(t *testing.T) { description string details string err error - expectedAe *proto.ActionableErr + expectedAe proto.ActionableErr }{ { description: "rollout status connection error", err: errors.New("Unable to connect to the server"), - expectedAe: &proto.ActionableErr{ + expectedAe: proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR, Message: MsgKubectlConnection, }, @@ -118,7 +118,7 @@ func TestParseKubectlError(t *testing.T) { { description: "rollout status kubectl command killed", err: errors.New("signal: killed"), - expectedAe: &proto.ActionableErr{ + expectedAe: proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_PID_KILLED, Message: msgKubectlKilled, }, @@ -126,7 +126,7 @@ func TestParseKubectlError(t *testing.T) { { description: "rollout status random error", err: errors.New("deployment test not found"), - expectedAe: &proto.ActionableErr{ + expectedAe: proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, Message: "deployment test not found", }, @@ -134,7 +134,7 @@ func TestParseKubectlError(t *testing.T) { { description: "rollout status nil error", details: "successfully rolled out", - expectedAe: &proto.ActionableErr{ + expectedAe: proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS, Message: "successfully rolled out", }, @@ -195,17 +195,17 @@ func TestIsErrAndNotRetriable(t *testing.T) { func TestReportSinceLastUpdated(t *testing.T) { var tests = []struct { description string - ae *proto.ActionableErr + ae proto.ActionableErr expected string }{ { description: "updating an error status", - ae: &proto.ActionableErr{Message: "cannot pull image"}, + ae: proto.ActionableErr{Message: "cannot pull image"}, expected: " - test-ns:deployment/test: cannot pull image", }, { description: "updating a non error status", - ae: &proto.ActionableErr{Message: "waiting for container"}, + ae: proto.ActionableErr{Message: "waiting for container"}, expected: " - test-ns:deployment/test: waiting for container", }, } @@ -251,7 +251,7 @@ func TestReportSinceLastUpdatedMultipleTimes(t *testing.T) { var actual string for i, status := range test.statuses { // update to same status - dep.UpdateStatus(&proto.ActionableErr{ + dep.UpdateStatus(proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING, Message: status, }) diff --git a/pkg/skaffold/deploy/resource/status.go b/pkg/skaffold/deploy/resource/status.go index 07fe294c1b2..3ff71eebaf2 100644 --- a/pkg/skaffold/deploy/resource/status.go +++ b/pkg/skaffold/deploy/resource/status.go @@ -23,7 +23,7 @@ import ( ) type Status struct { - ae *proto.ActionableErr + ae proto.ActionableErr changed bool reported bool } @@ -35,7 +35,7 @@ func (rs Status) Error() error { return fmt.Errorf(rs.ae.Message) } -func (rs Status) ActionableError() *proto.ActionableErr { +func (rs Status) ActionableError() proto.ActionableErr { return rs.ae } @@ -44,13 +44,10 @@ func (rs Status) String() string { } func (rs Status) Equal(other Status) bool { - if rs.ae != nil && other.ae != nil { - return rs.ae.Message == other.ae.Message && rs.ae.ErrCode == other.ae.ErrCode - } - return rs.ae == other.ae + return rs.ae.Message == other.ae.Message && rs.ae.ErrCode == other.ae.ErrCode } -func newStatus(ae *proto.ActionableErr) Status { +func newStatus(ae proto.ActionableErr) Status { return Status{ ae: ae, changed: true, diff --git a/pkg/skaffold/deploy/resource/status_test.go b/pkg/skaffold/deploy/resource/status_test.go index d55e49f7f32..9b9fd7fc19a 100644 --- a/pkg/skaffold/deploy/resource/status_test.go +++ b/pkg/skaffold/deploy/resource/status_test.go @@ -26,22 +26,22 @@ import ( func TestString(t *testing.T) { var tests = []struct { description string - ae *proto.ActionableErr + ae proto.ActionableErr expected string }{ { description: "should return error string if error is set", - ae: &proto.ActionableErr{Message: "some error"}, + ae: proto.ActionableErr{Message: "some error"}, expected: "some error", }, { description: "should return error if both details and error are set", - ae: &proto.ActionableErr{Message: "error happened due to something"}, + ae: proto.ActionableErr{Message: "error happened due to something"}, expected: "error happened due to something", }, { description: "should return empty string if all empty", - ae: &proto.ActionableErr{}, + ae: proto.ActionableErr{}, }, } for _, test := range tests { @@ -61,24 +61,24 @@ func TestEqual(t *testing.T) { }{ { description: "status should be same if error messages are same", - old: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "Waiting for 0/1 replicas to be available..."}}, - new: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "Waiting for 0/1 replicas to be available..."}}, + old: Status{ae: proto.ActionableErr{ErrCode: 100, Message: "Waiting for 0/1 replicas to be available..."}}, + new: Status{ae: proto.ActionableErr{ErrCode: 100, Message: "Waiting for 0/1 replicas to be available..."}}, expected: true, }, { description: "status should be new if error is different", - old: Status{ae: nil}, - new: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "see this error"}}, + old: Status{ae: proto.ActionableErr{}}, + new: Status{ae: proto.ActionableErr{ErrCode: 100, Message: "see this error"}}, }, { description: "status should be new if errcode are different but same message", - old: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "see this error"}}, - new: Status{ae: &proto.ActionableErr{ErrCode: 101, Message: "see this error"}}, + old: Status{ae: proto.ActionableErr{ErrCode: 100, Message: "see this error"}}, + new: Status{ae: proto.ActionableErr{ErrCode: 101, Message: "see this error"}}, }, { description: "status should be new if messages change", - old: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "Waiting for 2/2 replicas to be available..."}}, - new: Status{ae: &proto.ActionableErr{ErrCode: 100, Message: "Waiting for 1/2 replicas to be available..."}}, + old: Status{ae: proto.ActionableErr{ErrCode: 100, Message: "Waiting for 2/2 replicas to be available..."}}, + new: Status{ae: proto.ActionableErr{ErrCode: 100, Message: "Waiting for 1/2 replicas to be available..."}}, }, } for _, test := range tests { diff --git a/pkg/skaffold/deploy/status_check.go b/pkg/skaffold/deploy/status_check.go index e85d578e39c..2dcfd504a74 100644 --- a/pkg/skaffold/deploy/status_check.go +++ b/pkg/skaffold/deploy/status_check.go @@ -144,7 +144,7 @@ func pollDeploymentStatus(ctx context.Context, runCtx *runcontext.RunContext, r select { case <-timeoutContext.Done(): msg := fmt.Sprintf("could not stabilize within %v: %v", r.Deadline(), timeoutContext.Err()) - r.UpdateStatus(&proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, + r.UpdateStatus(proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, Message: msg}) return case <-time.After(pollDuration): diff --git a/pkg/skaffold/deploy/status_check_test.go b/pkg/skaffold/deploy/status_check_test.go index 42de32f8460..e97aa1a7e6f 100644 --- a/pkg/skaffold/deploy/status_check_test.go +++ b/pkg/skaffold/deploy/status_check_test.go @@ -270,7 +270,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace string deployment string pending int32 - ae *proto.ActionableErr + ae proto.ActionableErr expected string }{ { @@ -278,7 +278,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "test", deployment: "dep", pending: 0, - ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, + ae: proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, expected: " - test:deployment/dep is ready.\n", }, { @@ -286,7 +286,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "default", deployment: "dep", pending: 0, - ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, + ae: proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, expected: " - deployment/dep is ready.\n", }, { @@ -294,7 +294,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "test", deployment: "dep", pending: 0, - ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, Message: "context deadline expired"}, + ae: proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, Message: "context deadline expired"}, expected: " - test:deployment/dep failed. Error: context deadline expired.\n", }, { @@ -302,7 +302,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "test", deployment: "dep", pending: 4, - ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, + ae: proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, expected: " - test:deployment/dep is ready. [4/10 deployment(s) still pending]\n", }, { @@ -310,7 +310,7 @@ func TestPrintSummaryStatus(t *testing.T) { namespace: "test", deployment: "dep", pending: 8, - ae: &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, Message: "context deadline expired"}, + ae: proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEADLINE_EXCEEDED, Message: "context deadline expired"}, expected: " - test:deployment/dep failed. [8/10 deployment(s) still pending] Error: context deadline expired.\n", }, } @@ -343,7 +343,7 @@ func TestPrintStatus(t *testing.T) { rs: []*resource.Deployment{ withStatus( resource.NewDeployment("r1", "test", 1), - &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, + proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, ), }, expected: true, @@ -353,7 +353,7 @@ func TestPrintStatus(t *testing.T) { rs: []*resource.Deployment{ withStatus( resource.NewDeployment("r1", "test", 1), - &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, Message: "error"}, + proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, Message: "error"}, ), }, expected: true, @@ -363,11 +363,11 @@ func TestPrintStatus(t *testing.T) { rs: []*resource.Deployment{ withStatus( resource.NewDeployment("r1", "test", 1), - &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, + proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, ), withStatus( resource.NewDeployment("r2", "test", 1), - &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING, + proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_DEPLOYMENT_ROLLOUT_PENDING, Message: "pending"}, ), }, @@ -378,11 +378,11 @@ func TestPrintStatus(t *testing.T) { rs: []*resource.Deployment{ withStatus( resource.NewDeployment("r1", "test", 1), - &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, + proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}, ), withStatus( resource.NewDeployment("r2", "test", 1), - &proto.ActionableErr{ + proto.ActionableErr{ ErrCode: proto.StatusCode_STATUSCHECK_KUBECTL_CONNECTION_ERR, Message: resource.MsgKubectlConnection}, ), @@ -402,7 +402,7 @@ func TestPrintStatus(t *testing.T) { } } -func withStatus(d *resource.Deployment, ae *proto.ActionableErr) *resource.Deployment { +func withStatus(d *resource.Deployment, ae proto.ActionableErr) *resource.Deployment { d.UpdateStatus(ae) return d } diff --git a/pkg/skaffold/event/event.go b/pkg/skaffold/event/event.go index 2f7bbed87b2..20e710c4d09 100644 --- a/pkg/skaffold/event/event.go +++ b/pkg/skaffold/event/event.go @@ -217,7 +217,7 @@ func StatusCheckEventInProgress(s string) { }) } -func ResourceStatusCheckEventCompleted(r string, ae *proto.ActionableErr) { +func ResourceStatusCheckEventCompleted(r string, ae proto.ActionableErr) { if ae.ErrCode != proto.StatusCode_STATUSCHECK_SUCCESS { resourceStatusCheckEventFailed(r, ae) return @@ -234,23 +234,23 @@ func resourceStatusCheckEventSucceeded(r string) { }) } -func resourceStatusCheckEventFailed(r string, ae *proto.ActionableErr) { +func resourceStatusCheckEventFailed(r string, ae proto.ActionableErr) { handler.handleResourceStatusCheckEvent(&proto.ResourceStatusCheckEvent{ Resource: r, Status: Failed, Err: ae.Message, StatusCode: ae.ErrCode, - ActionableErr: ae, + ActionableErr: &ae, }) } -func ResourceStatusCheckEventUpdated(r string, ae *proto.ActionableErr) { +func ResourceStatusCheckEventUpdated(r string, ae proto.ActionableErr) { handler.handleResourceStatusCheckEvent(&proto.ResourceStatusCheckEvent{ Resource: r, Status: InProgress, Message: ae.Message, StatusCode: ae.ErrCode, - ActionableErr: ae, + ActionableErr: &ae, }) } diff --git a/pkg/skaffold/event/event_test.go b/pkg/skaffold/event/event_test.go index d279c6b1a3e..819ce028574 100644 --- a/pkg/skaffold/event/event_test.go +++ b/pkg/skaffold/event/event_test.go @@ -221,7 +221,7 @@ func TestResourceStatusCheckEventUpdated(t *testing.T) { } wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted }) - ResourceStatusCheckEventUpdated("ns:pod/foo", &proto.ActionableErr{ + ResourceStatusCheckEventUpdated("ns:pod/foo", proto.ActionableErr{ ErrCode: 509, Message: "image pull error", }) @@ -248,7 +248,7 @@ func TestResourceStatusCheckEventFailed(t *testing.T) { } wait(t, func() bool { return handler.getState().StatusCheckState.Status == NotStarted }) - resourceStatusCheckEventFailed("ns:pod/foo", &proto.ActionableErr{ + resourceStatusCheckEventFailed("ns:pod/foo", proto.ActionableErr{ ErrCode: 309, Message: "one or more deployments failed", })