diff --git a/actions/apply-all.sh b/actions/apply-all.sh index 08599ba13257057dde09d3beb09d098293dde775..4eec911a3cdff82e225f61ff3098559b8edd28f8 100755 --- a/actions/apply-all.sh +++ b/actions/apply-all.sh @@ -7,6 +7,8 @@ actions_dir="$(dirname "$0")" check_venv +require_double_sigint + # Invoke Terraform, if configured if [ "${TF_USAGE:-true}" == 'true' ]; then run "$actions_dir/apply-terraform.sh" diff --git a/actions/apply-custom.sh b/actions/apply-custom.sh index 06578e15758db553f59f5704e935ca0e3b62beec..dd4269b152e4f3cf988acf8785121b83aa8c6c9b 100755 --- a/actions/apply-custom.sh +++ b/actions/apply-custom.sh @@ -9,6 +9,8 @@ check_venv require_vault_token +require_double_sigint + install_prerequisites # Ensure that the latest config is deployed to the inventory diff --git a/actions/apply-k8s-core.sh b/actions/apply-k8s-core.sh index 362c16ba7396dac874919be23e7bea5e687b7080..975762e9a639d4ccc11955c18c2eb4cbe7a3d780 100755 --- a/actions/apply-k8s-core.sh +++ b/actions/apply-k8s-core.sh @@ -9,6 +9,8 @@ check_venv require_vault_token +require_double_sigint + install_prerequisites # Ensure that the latest config is deployed to the inventory diff --git a/actions/apply-k8s-supplements.sh b/actions/apply-k8s-supplements.sh index a738b63076e6c7fb0825ef02ab5ae6b0aa433101..4757b060e5e8d1d255d41b75bd4a324c8e9af957 100755 --- a/actions/apply-k8s-supplements.sh +++ b/actions/apply-k8s-supplements.sh @@ -9,6 +9,8 @@ check_venv require_vault_token +require_double_sigint + install_prerequisites # Ensure that the latest config is deployed to the inventory diff --git a/actions/apply-prepare-gw.sh b/actions/apply-prepare-gw.sh index 24cd9344ee461ff17cd56fb2630ec937a7d0f14c..244bf5d3ddb1070c0d2743c13f35cc6475443e46 100755 --- a/actions/apply-prepare-gw.sh +++ b/actions/apply-prepare-gw.sh @@ -9,6 +9,8 @@ check_venv require_vault_token +require_double_sigint + install_prerequisites # Ensure that the latest config is deployed to the inventory diff --git a/actions/apply-terraform.sh b/actions/apply-terraform.sh index 06276717a48d3d123c45867630794dcf5a34608c..20da3818d005be7934d773193f9c5e3fadfd23ad 100755 --- a/actions/apply-terraform.sh +++ b/actions/apply-terraform.sh @@ -89,6 +89,8 @@ function tf_state_present_on_gitlab () { check_return_code "$GITLAB_RESPONSE" } +require_double_sigint + load_gitlab_vars if all_gitlab_vars_are_set; then diff --git a/actions/destroy.sh b/actions/destroy.sh index f1fd86f34d477d7879186b52bb871ba8e85ad979..d0689701a1aaaa6d72ec159e967e7a28e0084455 100755 --- a/actions/destroy.sh +++ b/actions/destroy.sh @@ -14,6 +14,8 @@ if [ "$("$actions_dir/helpers/semver2.sh" "$(terraform -v -json | jq -r '.terraf exit 5 fi +require_double_sigint + load_gitlab_vars IFS=$'\n' diff --git a/actions/lib.sh b/actions/lib.sh index dd869252c34e6dad03375d6edaa0b4d6f3abc46e..93da7a7af78954bcc32c6570dc6fda93072ed227 100644 --- a/actions/lib.sh +++ b/actions/lib.sh @@ -229,3 +229,33 @@ function check_venv() { exit 1 fi } + +# Require two consecutive SIGINT signals for interruption +function require_double_sigint() { + # shellcheck disable=SC2317 + function sigint_handler() { + exit_code=$? # preserve the original exit code + + echo "SIGINT received. " >&2 + _received_at=$(date +%s) + + function _received_twice() { + # first reception + if [[ -z ${_last_received_at+x} ]] \ + || [[ $((_received_at-_last_received_at)) -gt 5 ]]; then + _last_received_at=$_received_at + return 1 + + # second reception + else return 0; fi + } + + if _received_twice; then + echo "Interrupted." >&2 + exit "$exit_code" + else + echo "Repeat to interrupt." >&2 + fi + } + trap sigint_handler SIGINT +} diff --git a/actions/manual-terraform.sh b/actions/manual-terraform.sh index 0b7c564ef24ec48074a4f66342465b5e367de7f4..bd6dac51e1bbf976b6dac5f9904fa1572e55993f 100755 --- a/actions/manual-terraform.sh +++ b/actions/manual-terraform.sh @@ -5,6 +5,8 @@ actions_dir="$(realpath "$(dirname "$0")")" # shellcheck source=actions/lib.sh . "$actions_dir/lib.sh" +require_double_sigint + cd "$terraform_state_dir" export TF_DATA_DIR="$terraform_state_dir/.terraform" exec terraform -chdir="$terraform_module" "$@" diff --git a/actions/rotate-root-ca.sh b/actions/rotate-root-ca.sh index 41abee0de3d61e282fda911f4bd2560cc9ffdf41..b4e84a1819a07a3e2cea8f80c687f38f8d9fc6bd 100755 --- a/actions/rotate-root-ca.sh +++ b/actions/rotate-root-ca.sh @@ -48,6 +48,8 @@ require_ansible_disruption require_vault_token +require_double_sigint + install_prerequisites # Ensure that the latest config is deployed to the inventory diff --git a/actions/test.sh b/actions/test.sh index bb928ca5247b0832dfd46e7acf30cf14e26966b6..b110c5ca8651d5151fe91e1c3dcf19d88eb5d254 100755 --- a/actions/test.sh +++ b/actions/test.sh @@ -14,6 +14,8 @@ python3 "$actions_dir/update_inventory.py" # Bring the wireguard interface up if configured so "$actions_dir/wg-up.sh" +require_double_sigint + # Test all pushd "$ansible_k8s_supplements_dir" ANSIBLE_ROLES_PATH="$ansible_k8s_core_dir/roles/:$ansible_k8s_supplements_dir/test-roles:$ansible_k8s_supplements_dir/roles/" \ diff --git a/actions/update-frontend-nodes.sh b/actions/update-frontend-nodes.sh index 5732c5a87ca325e470f6a09844299532d6c7b66e..190623d34fa6d12a9c93743895d8aa1f870c1e01 100755 --- a/actions/update-frontend-nodes.sh +++ b/actions/update-frontend-nodes.sh @@ -27,6 +27,8 @@ done shift $(( OPTIND - 1 )) +require_double_sigint + install_prerequisites # Bring the wireguard interface up if configured so diff --git a/actions/update-kubernetes-nodes.sh b/actions/update-kubernetes-nodes.sh index a75d5ea2410880a88d8d122dd06ee09df3ba0a73..8d6497ee858bb8a37a499a5cd99732711f364f2b 100755 --- a/actions/update-kubernetes-nodes.sh +++ b/actions/update-kubernetes-nodes.sh @@ -27,6 +27,8 @@ done shift $(( OPTIND - 1 )) +require_double_sigint + install_prerequisites # Bring the wireguard interface up if configured so diff --git a/actions/upgrade.sh b/actions/upgrade.sh index 90b404077cb8c48a038c2a20c8d3af1fd4fd6d46..79b4e6980f47ccc7901bab686f23aab572314d40 100755 --- a/actions/upgrade.sh +++ b/actions/upgrade.sh @@ -55,6 +55,8 @@ require_ansible_disruption "$actions_dir/wg-up.sh" +require_double_sigint + pushd "$ansible_k8s_supplements_dir" ANSIBLE_ROLES_PATH="$ansible_k8s_core_dir/roles:$ansible_k8s_supplements_dir/roles" \ ansible_playbook -i "$ansible_inventory_host_file" "$playbook" \ diff --git a/actions/verify-cluster-health.sh b/actions/verify-cluster-health.sh index 6cf1274146b6e8973e2400e5345d5958c623da61..21bb737d4710911f46a89aeb79cead1baf5848ed 100755 --- a/actions/verify-cluster-health.sh +++ b/actions/verify-cluster-health.sh @@ -22,6 +22,8 @@ shift $(( OPTIND - 1 )) check_venv +require_double_sigint + pushd "$ansible_k8s_supplements_dir" # Include k8s-core roles ANSIBLE_ROLES_PATH="$ansible_k8s_core_dir/roles:$ansible_k8s_supplements_dir/roles" \ diff --git a/docs/_releasenotes/+.change.guard-long-running-actions-againts-accidental-termination b/docs/_releasenotes/+.change.guard-long-running-actions-againts-accidental-termination new file mode 100644 index 0000000000000000000000000000000000000000..37fee6d711734850b611c0bf422b841b114e35d7 --- /dev/null +++ b/docs/_releasenotes/+.change.guard-long-running-actions-againts-accidental-termination @@ -0,0 +1,3 @@ +Action scripts that usually run more than a few minutes now require two +consecutive SIGINT signals sent to actually abort them thus preventing +termination by accident.