Skip to content

Instantly share code, notes, and snippets.

@rafaelrdealmeida
Created April 15, 2026 15:42
Show Gist options
  • Select an option

  • Save rafaelrdealmeida/fb3bed30af1260d4a7c49f51d1861b3a to your computer and use it in GitHub Desktop.

Select an option

Save rafaelrdealmeida/fb3bed30af1260d4a7c49f51d1861b3a to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
KEEP="${KEEP:-2}"
DRY_RUN="${DRY_RUN:-false}" # true = só imprime comandos; false = executa
log() { echo -e "\n[$(date +'%F %T')] $*\n"; }
run() {
if [[ "$DRY_RUN" == "true" ]]; then
echo "DRY-RUN> $*"
else
eval "$@"
fi
}
if [[ $EUID -ne 0 ]]; then
echo "Rode como root."
exit 1
fi
current="$(uname -r)"
log "Kernel atual (em uso): $current"
log "KEEP=$KEEP | DRY_RUN=$DRY_RUN"
# 1) Consertar dpkg/apt (resolve 'ic' e afins)
log "1) Reparando dpkg/apt (seguro rodar sempre)"
run "dpkg --configure -a || true"
run "apt -y -f install || true"
# 2) Purgar kernels signed quebrados (ic)
log "2) Procurando kernels signed quebrados (status 'ic')"
mapfile -t broken_signed < <(
dpkg -l 'proxmox-kernel-*-pve-signed' 2>/dev/null | awk '$1=="ic"{print $2}'
)
if [[ ${#broken_signed[@]} -gt 0 ]]; then
echo "Encontrados pacotes quebrados (ic):"
printf ' %s\n' "${broken_signed[@]}"
run "apt purge -y ${broken_signed[*]} || true"
else
echo "Nenhum kernel signed em estado 'ic'."
fi
# 3) Descobrir kernels signed instalados de verdade (ii)
log "3) Listando kernels signed instalados (ii)"
mapfile -t signed_ii_kvers < <(
dpkg -l 'proxmox-kernel-*-pve-signed' 2>/dev/null \
| awk '$1=="ii"{print $2}' \
| sed -E 's/^proxmox-kernel-//; s/-signed$//' \
| sort -V
)
if [[ ${#signed_ii_kvers[@]} -eq 0 ]]; then
echo "ERRO: não há nenhum 'ii proxmox-kernel-*-pve-signed' instalado."
echo "Rode: apt update && apt install -y proxmox-kernel-6.8"
exit 1
fi
echo "Kernels signed (ii) encontrados:"
printf ' %s\n' "${signed_ii_kvers[@]}"
newest_signed="${signed_ii_kvers[-1]}"
log "Kernel signed mais novo instalado: $newest_signed"
# 4) Verificar se o kernel atual tem pacote (para segurança)
# Usamos dpkg-query, que é mais confiável que dpkg -l + awk.
log "4) Verificando se o kernel atual tem pacote instalado (dpkg-query)"
current_pkg="proxmox-kernel-$current-signed"
if dpkg-query -W -f='${Status}\n' "$current_pkg" 2>/dev/null | grep -q 'install ok installed'; then
log "4) Kernel atual tem pacote instalado: $current_pkg"
else
log "4) ATENÇÃO: kernel atual ($current) NÃO tem pacote 'ii' correspondente ($current_pkg)."
echo "Isso geralmente significa que você está bootando por um kernel antigo 'sobrado' no /boot."
echo
echo "✅ Ação recomendada (antes de remover qualquer kernel):"
echo " 1) Garanta que existe initrd pro kernel mais novo:"
echo " ls -lh /boot/vmlinuz-$newest_signed /boot/initrd.img-$newest_signed || update-initramfs -c -k $newest_signed"
echo " 2) Force GRUB_DEFAULT=0 e update-grub (se necessário)"
echo " 3) Reboot e confirme: uname -r (deve virar $newest_signed)"
echo
echo "🚫 Por segurança, este script NÃO removerá kernels enquanto você estiver bootando um kernel sem pacote."
exit 0
fi
# 5) Definir quais kernels manter (KEEP mais novos)
log "5) Selecionando os $KEEP kernels signed mais novos para manter"
mapfile -t keep_kvers < <(printf '%s\n' "${signed_ii_kvers[@]}" | tail -n "$KEEP")
echo "Kernels a manter (kver):"
printf ' %s\n' "${keep_kvers[@]}"
# 6) Calcular pacotes a remover (somente signed(ii) fora do keep)
log "6) Calculando pacotes de kernel a remover"
to_remove_pkgs=()
for kver in "${signed_ii_kvers[@]}"; do
if ! printf '%s\n' "${keep_kvers[@]}" | grep -qx "$kver"; then
to_remove_pkgs+=("proxmox-kernel-$kver-signed")
fi
done
echo "Pacotes de kernel a remover:"
if [[ ${#to_remove_pkgs[@]} -gt 0 ]]; then
printf ' %s\n' "${to_remove_pkgs[@]}"
else
echo " (nenhum)"
fi
# 7) Remover kernels antigos via apt
if [[ ${#to_remove_pkgs[@]} -gt 0 ]]; then
log "7) Removendo kernels antigos (via apt remove)"
run "apt remove -y ${to_remove_pkgs[*]}"
else
log "7) Nada a remover (kernels)."
fi
# 8) Headers: manter só os headers correspondentes aos kernels mantidos
log "8) Limpando headers que não correspondem aos kernels mantidos"
mapfile -t installed_headers < <(
dpkg -l 'proxmox-headers-*-pve' 2>/dev/null | awk '$1=="ii"{print $2}' | sort -V
)
hdr_remove=()
for h in "${installed_headers[@]:-}"; do
hv="${h#proxmox-headers-}" # vira kver
if ! printf '%s\n' "${keep_kvers[@]}" | grep -qx "$hv"; then
hdr_remove+=("$h")
fi
done
echo "Headers a remover:"
if [[ ${#hdr_remove[@]} -gt 0 ]]; then
printf ' %s\n' "${hdr_remove[@]}"
run "apt remove -y ${hdr_remove[*]} || true"
else
echo " (nenhum)"
fi
# 9) Purge de pacotes rc (limpeza dpkg)
log "9) Purgando pacotes rc (configs sobrando)"
mapfile -t rc_pkgs < <(dpkg -l | awk '$1=="rc"{print $2}')
if [[ ${#rc_pkgs[@]} -gt 0 ]]; then
run "dpkg --purge ${rc_pkgs[*]} || true"
else
echo "Nenhum pacote rc para purgar."
fi
# 10) Finalização
log "10) Atualizando GRUB e autoremove"
run "update-grub || true"
run "apt autoremove --purge -y || true"
log "Pronto."
echo "Agora confira:"
echo "uname -r"
uname -r
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment