adbrasi commited on
Commit
99c21be
·
verified ·
1 Parent(s): e0d0466

Update desligaRunpod.sh

Browse files
Files changed (1) hide show
  1. desligaRunpod.sh +30 -84
desligaRunpod.sh CHANGED
@@ -1,21 +1,18 @@
1
  #!/usr/bin/env bash
2
- # removeRunpodSafely.sh — Remove o pod atual do RunPod após um atraso controlado.
3
- # Requisitos: bash, runpodctl, variáveis RUNPOD_POD_ID (injetada pelo RunPod).
4
- # Comportamento: aguarda SECONDS_ALIVE (default 7200), mostra barra de progresso,
5
- # permite cancelamento com Ctrl+C e depois executa "runpodctl remove pod $RUNPOD_POD_ID".
6
 
7
- set -u -o pipefail
8
  umask 077
9
 
10
- #-----------------------------#
11
- # Configuração e utilitários #
12
- #-----------------------------#
13
- DEFAULT_SECONDS=7200 # 2 horas por padrão
14
- MAX_SECONDS=$((14*24*3600)) # limite de segurança: 14 dias
15
- PROGRESS_WIDTH=50 # largura da barra de progresso
16
- GRACE_SECONDS=5 # janela de segurança final para abortar
17
 
18
- # Imprime duração como HH:MM:SS
19
  format_duration() {
20
  local sec=${1:-0}
21
  local h=$(( sec / 3600 ))
@@ -23,8 +20,6 @@ format_duration() {
23
  local s=$(( sec % 60 ))
24
  printf "%02d:%02d:%02d" "$h" "$m" "$s"
25
  }
26
-
27
- # Repete um caractere N vezes sem depender de 'seq'
28
  repeat_char() {
29
  local n=${1:-0} ch="${2:-#}" buf=
30
  (( n < 0 )) && n=0
@@ -32,137 +27,88 @@ repeat_char() {
32
  echo "${buf// /$ch}"
33
  }
34
 
35
- #-----------------------------#
36
- # Validações de ambiente #
37
- #-----------------------------#
38
- # Carrega SECONDS_ALIVE ou usa padrão.
39
  SECONDS_TOTAL="${SECONDS_ALIVE:-$DEFAULT_SECONDS}"
40
-
41
- # Verifica se é inteiro não-negativo
42
  if [[ ! "$SECONDS_TOTAL" =~ ^[0-9]+$ ]]; then
43
  echo "ERRO: SECONDS_ALIVE precisa ser um inteiro >= 0 (em segundos)." >&2
44
  exit 2
45
  fi
46
-
47
- # Limite máximo de segurança
48
  if (( SECONDS_TOTAL > MAX_SECONDS )); then
49
- echo "Aviso: SECONDS_ALIVE=$SECONDS_TOTAL excede o limite de segurança."
50
- echo "Limitando para $MAX_SECONDS segundos."
51
  SECONDS_TOTAL="$MAX_SECONDS"
52
  fi
53
 
54
- # runpodctl disponível?
55
  if ! command -v runpodctl >/dev/null 2>&1; then
56
  echo "ERRO: 'runpodctl' não encontrado no PATH. Execute dentro de um pod do RunPod." >&2
57
  exit 3
58
  fi
59
-
60
- # RUNPOD_POD_ID definido?
61
  POD_ID="${RUNPOD_POD_ID:-}"
62
  if [[ -z "$POD_ID" ]]; then
63
  echo "ERRO: RUNPOD_POD_ID não definido. Este script deve rodar dentro de um pod do RunPod." >&2
64
  exit 4
65
  fi
66
 
67
- # Pod existe/é acessível?
68
- if ! runpodctl get pod "$POD_ID" >/dev/null 2>&1; then
69
- echo "ERRO: Não consegui localizar/ler o pod '$POD_ID' via runpodctl." >&2
70
- exit 5
71
- fi
72
-
73
- #-----------------------------#
74
- # Cabeçalho / Avisos #
75
- #-----------------------------#
76
  echo "==================== REMOVER POD RUNPOD (SEGURO) ===================="
77
- echo "Pod atual: $POD_ID"
78
- echo "Ação: REMOVE (apagar/terminar o pod)."
79
  echo "Tempo até a remoção: $(format_duration "$SECONDS_TOTAL")"
80
- echo "Pressione Ctrl+C a QUALQUER momento para cancelar com segurança (nada será removido)."
81
  echo "======================================================================"
82
 
83
- #-----------------------------#
84
- # Barra de progresso + cancel #
85
- #-----------------------------#
86
  CANCELLED=0
87
- on_cancel() {
88
- CANCELLED=1
89
- }
90
  trap on_cancel INT TERM
91
 
92
  START_TS=$(date +%s)
93
  END_TS=$(( START_TS + SECONDS_TOTAL ))
94
 
95
- # Atualiza a barra de progresso uma vez por segundo
96
  while :; do
97
- # Se cancelado, saia sem remover
98
- if (( CANCELLED )); then
99
- echo -e "\nOperação cancelada pelo usuário. Nenhuma alteração foi feita."
100
- exit 130
101
- fi
102
-
103
  NOW=$(date +%s)
104
- # Fim da espera?
105
- if (( NOW >= END_TS )); then
106
- break
107
- fi
108
 
109
  ELAPSED=$(( NOW - START_TS ))
110
  REMAIN=$(( END_TS - NOW ))
111
 
112
- # Evita divisão por zero
113
  if (( SECONDS_TOTAL > 0 )); then
114
  PERCENT=$(( (ELAPSED * 100) / SECONDS_TOTAL ))
115
  FILLED=$(( (ELAPSED * PROGRESS_WIDTH) / SECONDS_TOTAL ))
116
  else
117
- PERCENT=100
118
- FILLED=$PROGRESS_WIDTH
119
  fi
120
  (( FILLED > PROGRESS_WIDTH )) && FILLED=$PROGRESS_WIDTH
121
  EMPTY=$(( PROGRESS_WIDTH - FILLED ))
122
 
123
  BAR_FILLED=$(repeat_char "$FILLED" "#")
124
  BAR_EMPTY=$(repeat_char "$EMPTY" ".")
125
-
126
  printf "\r[%s%s] %3d%% | faltam %s " \
127
  "$BAR_FILLED" "$BAR_EMPTY" "$PERCENT" "$(format_duration "$REMAIN")"
128
 
129
- # O sleep pode ser interrompido por Ctrl+C; não é erro aqui
130
  sleep 1 || true
131
  done
132
-
133
- # Linha nova após a barra
134
  echo
135
 
136
- # Se cancelado exatamente no fim
137
- if (( CANCELLED )); then
138
- echo "Operação cancelada pelo usuário. Nenhuma alteração foi feita."
139
- exit 130
140
- fi
141
 
142
- #-----------------------------#
143
- # Janela de segurança final #
144
- #-----------------------------#
145
  echo "Tempo esgotado."
146
  echo "Janela de segurança: removendo o pod em ${GRACE_SECONDS}s (Ctrl+C para abortar)."
147
  for (( i=GRACE_SECONDS; i>0; i-- )); do
148
- if (( CANCELLED )); then
149
- echo -e "\nCancelado durante a janela de segurança. Nenhuma alteração foi feita."
150
- exit 130
151
- fi
152
  printf "\rRemovendo em %ds... " "$i"
153
  sleep 1 || true
154
  done
155
  echo
156
 
157
- #-----------------------------#
158
- # Execução da remoção #
159
- #-----------------------------#
160
  echo "Executando: runpodctl remove pod \"$POD_ID\""
161
- # A remoção deve encerrar este processo (seu terminal pode fechar).
162
  if runpodctl remove pod "$POD_ID"; then
163
- echo "Comando de remoção enviado. (Este pod será encerrado.)"
164
  else
165
- RC=$?
166
- echo "ERRO: falha ao executar 'runpodctl remove pod \"$POD_ID\"' (código $RC)" >&2
167
- exit "$RC"
168
  fi
 
1
  #!/usr/bin/env bash
2
+ # removeRunpodSafely.sh — Remove o POD atual do RunPod após um atraso.
3
+ # Requisitos: bash, runpodctl; env RUNPOD_POD_ID presente.
4
+ # Comportamento: aguarda SECONDS_ALIVE (default 7200), barra de progresso,
5
+ # Ctrl+C cancela com segurança, janela final de 5s, e então REMOVE o pod.
6
 
7
+ set -Eeuo pipefail
8
  umask 077
9
 
10
+ DEFAULT_SECONDS=7200 # 2 horas
11
+ MAX_SECONDS=$((14*24*3600)) # limite de segurança: 14 dias
12
+ PROGRESS_WIDTH=50
13
+ GRACE_SECONDS=5
 
 
 
14
 
15
+ #--- utils ---#
16
  format_duration() {
17
  local sec=${1:-0}
18
  local h=$(( sec / 3600 ))
 
20
  local s=$(( sec % 60 ))
21
  printf "%02d:%02d:%02d" "$h" "$m" "$s"
22
  }
 
 
23
  repeat_char() {
24
  local n=${1:-0} ch="${2:-#}" buf=
25
  (( n < 0 )) && n=0
 
27
  echo "${buf// /$ch}"
28
  }
29
 
30
+ #--- parâmetros ---#
 
 
 
31
  SECONDS_TOTAL="${SECONDS_ALIVE:-$DEFAULT_SECONDS}"
 
 
32
  if [[ ! "$SECONDS_TOTAL" =~ ^[0-9]+$ ]]; then
33
  echo "ERRO: SECONDS_ALIVE precisa ser um inteiro >= 0 (em segundos)." >&2
34
  exit 2
35
  fi
 
 
36
  if (( SECONDS_TOTAL > MAX_SECONDS )); then
37
+ echo "Aviso: SECONDS_ALIVE=$SECONDS_TOTAL excede o limite de segurança; limitando a $MAX_SECONDS."
 
38
  SECONDS_TOTAL="$MAX_SECONDS"
39
  fi
40
 
41
+ #--- pré-checagens mínimas ---#
42
  if ! command -v runpodctl >/dev/null 2>&1; then
43
  echo "ERRO: 'runpodctl' não encontrado no PATH. Execute dentro de um pod do RunPod." >&2
44
  exit 3
45
  fi
 
 
46
  POD_ID="${RUNPOD_POD_ID:-}"
47
  if [[ -z "$POD_ID" ]]; then
48
  echo "ERRO: RUNPOD_POD_ID não definido. Este script deve rodar dentro de um pod do RunPod." >&2
49
  exit 4
50
  fi
51
 
52
+ #--- header ---#
 
 
 
 
 
 
 
 
53
  echo "==================== REMOVER POD RUNPOD (SEGURO) ===================="
54
+ echo "Pod: $POD_ID"
55
+ echo "Ação: REMOVE (apagar/terminar)"
56
  echo "Tempo até a remoção: $(format_duration "$SECONDS_TOTAL")"
57
+ echo "Pressione Ctrl+C a qualquer momento para CANCELAR sem remover."
58
  echo "======================================================================"
59
 
60
+ #--- progresso + cancelamento ---#
 
 
61
  CANCELLED=0
62
+ on_cancel(){ CANCELLED=1; }
 
 
63
  trap on_cancel INT TERM
64
 
65
  START_TS=$(date +%s)
66
  END_TS=$(( START_TS + SECONDS_TOTAL ))
67
 
 
68
  while :; do
69
+ (( CANCELLED )) && { echo -e "\nCancelado pelo usuário. Nada foi removido."; exit 130; }
 
 
 
 
 
70
  NOW=$(date +%s)
71
+ (( NOW >= END_TS )) && break
 
 
 
72
 
73
  ELAPSED=$(( NOW - START_TS ))
74
  REMAIN=$(( END_TS - NOW ))
75
 
 
76
  if (( SECONDS_TOTAL > 0 )); then
77
  PERCENT=$(( (ELAPSED * 100) / SECONDS_TOTAL ))
78
  FILLED=$(( (ELAPSED * PROGRESS_WIDTH) / SECONDS_TOTAL ))
79
  else
80
+ PERCENT=100; FILLED=$PROGRESS_WIDTH
 
81
  fi
82
  (( FILLED > PROGRESS_WIDTH )) && FILLED=$PROGRESS_WIDTH
83
  EMPTY=$(( PROGRESS_WIDTH - FILLED ))
84
 
85
  BAR_FILLED=$(repeat_char "$FILLED" "#")
86
  BAR_EMPTY=$(repeat_char "$EMPTY" ".")
 
87
  printf "\r[%s%s] %3d%% | faltam %s " \
88
  "$BAR_FILLED" "$BAR_EMPTY" "$PERCENT" "$(format_duration "$REMAIN")"
89
 
 
90
  sleep 1 || true
91
  done
 
 
92
  echo
93
 
94
+ (( CANCELLED )) && { echo "Cancelado pelo usuário. Nada foi removido."; exit 130; }
 
 
 
 
95
 
96
+ #--- janela de segurança final ---#
 
 
97
  echo "Tempo esgotado."
98
  echo "Janela de segurança: removendo o pod em ${GRACE_SECONDS}s (Ctrl+C para abortar)."
99
  for (( i=GRACE_SECONDS; i>0; i-- )); do
100
+ (( CANCELLED )) && { echo -e "\nCancelado durante a janela de segurança. Nada foi removido."; exit 130; }
 
 
 
101
  printf "\rRemovendo em %ds... " "$i"
102
  sleep 1 || true
103
  done
104
  echo
105
 
106
+ #--- remoção ---#
 
 
107
  echo "Executando: runpodctl remove pod \"$POD_ID\""
 
108
  if runpodctl remove pod "$POD_ID"; then
109
+ echo "Comando enviado. Este pod será encerrado."
110
  else
111
+ rc=$?
112
+ echo "ERRO: falha ao executar 'runpodctl remove pod \"$POD_ID\"' (código $rc)" >&2
113
+ exit "$rc"
114
  fi