Commit 5e456a98 authored by Muhammad Umair Khan's avatar Muhammad Umair Khan
Browse files

Bug Fix: PyInfra

parent 6f7c2d81
Loading
Loading
Loading
Loading
+267 −0
Original line number Diff line number Diff line
#!/usr/bin/env bash
#
# kubeadm-clean.sh
#
# Completely cleans a kubeadm node so it can be initialized again.
#
# Usage:
#   sudo ./kubeadm-clean.sh
#

set -Eeuo pipefail

#############################################
# Colors
#############################################
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

info() { echo -e "${BLUE}[INFO]${NC} $*"; }
ok()   { echo -e "${GREEN}[ OK ]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
fail() { echo -e "${RED}[FAIL]${NC} $*"; }

#############################################
# Root check
#############################################
if [[ $EUID -ne 0 ]]; then
    fail "Run this script with sudo or as root."
    exit 1
fi

echo
warn "This will completely remove Kubernetes, kubeadm, CNI and Calico state."
sleep 3

#############################################
# Stop services
#############################################
info "Stopping services..."

systemctl stop kubelet 2>/dev/null || true
systemctl stop containerd 2>/dev/null || true
systemctl stop cri-o 2>/dev/null || true

#############################################
# kubeadm reset
#############################################
if command -v kubeadm >/dev/null 2>&1; then
    info "Running kubeadm reset..."
    kubeadm reset -f || true
fi

#############################################
# Remove containers and pods
#############################################
if command -v crictl >/dev/null 2>&1; then

    info "Removing Kubernetes containers..."

    PODS=$(crictl pods -q 2>/dev/null || true)

    if [[ -n "$PODS" ]]; then
        crictl stopp $PODS 2>/dev/null || true
        crictl rmp $PODS 2>/dev/null || true
    fi

    CONTAINERS=$(crictl ps -aq 2>/dev/null || true)

    if [[ -n "$CONTAINERS" ]]; then
        crictl rm $CONTAINERS 2>/dev/null || true
    fi
fi

#############################################
# Remove CNI namespaces
#############################################
info "Removing network namespaces..."

ip netns list 2>/dev/null | awk '{print $1}' | while read -r ns
do
    ip netns delete "$ns" 2>/dev/null || true
done

#############################################
# Remove Kubernetes directories
#############################################
info "Removing Kubernetes directories..."

DIRS=(
    /etc/kubernetes
    /var/lib/kubelet
    /var/lib/etcd
    /var/lib/cni
    /var/lib/calico
    /etc/cni/net.d
    "$HOME/.kube"
)

for d in "${DIRS[@]}"
do
    if [[ -e "$d" ]]; then
        rm -rf "$d"
    fi
done

#############################################
# Unmount Calico runtime (if mounted)
#############################################
if mountpoint -q /var/run/calico/cgroup 2>/dev/null; then
    info "Unmounting Calico cgroup..."
    umount -l /var/run/calico/cgroup || true
fi

rmdir /var/run/calico 2>/dev/null || true

#############################################
# Remove interfaces
#############################################
info "Removing Kubernetes interfaces..."

for iface in $(ip -o link show | awk -F': ' '{print $2}' | sed 's/@.*//')
do
    case "$iface" in
        cali*|cni*|flannel*|vxlan.calico|vxlan-v6.calico|bpfin.cali|bpfout.cali)
            ip link delete "$iface" 2>/dev/null || true
            ;;
    esac
done

#############################################
# Flush routes
#############################################
info "Removing CNI routes..."

ip route | awk '/proto bird|cali|vxlan|cni/ {print $1}' | while read -r route
do
    ip route del "$route" 2>/dev/null || true
done

#############################################
# Flush iptables
#############################################
info "Flushing iptables..."

for table in filter nat mangle raw security
do
    iptables -t "$table" -F 2>/dev/null || true
    iptables -t "$table" -X 2>/dev/null || true
done

ip6tables -F 2>/dev/null || true
ip6tables -X 2>/dev/null || true

#############################################
# Clear IPVS
#############################################
if command -v ipvsadm >/dev/null 2>&1; then
    info "Clearing IPVS..."
    ipvsadm --clear || true
fi

#############################################
# Restart runtime
#############################################
info "Restarting container runtime..."

systemctl restart containerd 2>/dev/null || true
systemctl restart cri-o 2>/dev/null || true

#############################################
# Verification
#############################################

echo
echo "================== VERIFICATION =================="

echo
echo "[Directories]"

for d in \
/etc/kubernetes \
/var/lib/kubelet \
/var/lib/etcd \
/var/lib/cni \
/var/lib/calico \
/etc/cni/net.d
do
    if [[ -e "$d" ]]; then
        warn "$d exists"
    else
        ok "$d removed"
    fi
done

echo
echo "[Interfaces]"

if ip link | grep -Eq 'cali|cni|flannel|vxlan|bpf'; then
    warn "Interfaces still present:"
    ip link | grep -E 'cali|cni|flannel|vxlan|bpf'
else
    ok "No Kubernetes interfaces."
fi

echo
echo "[Network Namespaces]"

if ip netns | grep -q .; then
    warn "Namespaces still present:"
    ip netns
else
    ok "No network namespaces."
fi

echo
echo "[CRI Pods]"

if command -v crictl >/dev/null 2>&1; then

    if crictl pods -q | grep -q .; then
        warn "Pod sandboxes remain:"
        crictl pods
    else
        ok "No pod sandboxes."
    fi

    echo

    if crictl ps -aq | grep -q .; then
        warn "Containers remain:"
        crictl ps -a
    else
        ok "No containers."
    fi
fi

echo
echo "[Services]"

if systemctl is-active --quiet containerd; then
    ok "containerd running."
else
    warn "containerd not running."
fi

if systemctl is-active --quiet kubelet; then
    warn "kubelet still running."
else
    ok "kubelet stopped."
fi

echo
echo "=================================================="

echo
ok "Cleanup completed."

echo
echo "Recommended:"
echo "  sudo reboot"
echo
echo "After reboot:"
echo "  sudo kubeadm init ..."
echo "  Install your CNI plugin."
 No newline at end of file
+12 −12
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ def _build_env_prefix(target_home, node_version):
@operation()
def configure_sudoers(target_user):
    """
    Idempotently create /etc/sudoers.d/meepctl with NOPASSWD rules for meepctl
    Create /etc/sudoers.d/meepctl with NOPASSWD rules for meepctl
    certificate trust operations (sudo cp, update-ca-certificates, systemctl restart).

    This operation must be called with _sudo=True so pyinfra handles authentication
@@ -43,10 +43,10 @@ def configure_sudoers(target_user):
@operation()
def install(mec_sandbox_dir, target_home, node_version):
    """
    Idempotently install meepctl.
    Install meepctl.
    """
    if host.get_fact(File, path=f"{target_home}/gocode/bin/meepctl"):
        return
    # if host.get_fact(File, path=f"{target_home}/gocode/bin/meepctl"):
    #     return
        
    prefix = _build_env_prefix(target_home, node_version)
    yield StringCommand(f"{prefix} cd {mec_sandbox_dir}/go-apps/meepctl && bash install.sh")
@@ -54,15 +54,15 @@ def install(mec_sandbox_dir, target_home, node_version):
@operation()
def configure(ip, gitdir, target_home, node_version):
    """
    Idempotently configure meepctl.
    Configure meepctl.
    """
    if host.get_fact(File, path=f"{target_home}/.meep/.meepctl_configured"):
        return
    # if host.get_fact(File, path=f"{target_home}/.meep/.meepctl_configured"):
    #     return
        
    prefix = _build_env_prefix(target_home, node_version)
    yield StringCommand(f"{prefix} meepctl config ip {ip}")
    yield StringCommand(f"{prefix} meepctl config gitdir {gitdir}")
    yield StringCommand(f"mkdir -p {target_home}/.meep && touch {target_home}/.meep/.meepctl_configured")
    # yield StringCommand(f"mkdir -p {target_home}/.meep && touch {target_home}/.meep/.meepctl_configured")

@operation()
def deploy_frontend(mec_frontend_dir, target_home, node_version):
@@ -79,7 +79,7 @@ def deploy_frontend(mec_frontend_dir, target_home, node_version):
@operation()
def configure_sandbox_secrets(mec_sandbox_dir, target_home, node_version):
    """
    Idempotently configure MEC Sandbox secrets (secrets.yaml).
    Configure MEC Sandbox secrets (secrets.yaml).
    """
    if not host.get_fact(File, path=f"{target_home}/.meep/.01_secrets_configured"):
        prefix = _build_env_prefix(target_home, node_version)
@@ -90,7 +90,7 @@ def configure_sandbox_secrets(mec_sandbox_dir, target_home, node_version):
@operation()
def deploy_dep(mec_sandbox_dir, target_home, node_version, force=True):
    """
    Idempotently deploy MEC Sandbox dependencies (meepctl deploy dep all).
    Deploy MEC Sandbox dependencies (meepctl deploy dep all).
    """
    if not host.get_fact(File, path=f"{target_home}/.meep/.02_deps_deployed"):
        prefix = _build_env_prefix(target_home, node_version)
@@ -102,7 +102,7 @@ def deploy_dep(mec_sandbox_dir, target_home, node_version, force=True):
@operation()
def build_all(mec_sandbox_dir, target_home, node_version, nolint=True):
    """
    Idempotently compile all MEC Sandbox binaries (meepctl build all).
    Compile all MEC Sandbox binaries (meepctl build all).
    """
    if not host.get_fact(File, path=f"{target_home}/.meep/.03_binaries_built"):
        prefix = _build_env_prefix(target_home, node_version)
@@ -114,7 +114,7 @@ def build_all(mec_sandbox_dir, target_home, node_version, nolint=True):
@operation()
def dockerize_all(mec_sandbox_dir, target_home, node_version):
    """
    Idempotently build and package all MEC Sandbox container images (meepctl dockerize all).
    Build and package all MEC Sandbox container images (meepctl dockerize all).
    """
    if not host.get_fact(File, path=f"{target_home}/.meep/.04_images_dockerized"):
        prefix = _build_env_prefix(target_home, node_version)
+2 −2
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ def verify_github_oauth(client_id: str, client_secret: str):
            elif e.code in (404, 422):
                # 404 / 422 means Basic Auth succeeded for the application, but the dummy access token
                # was not found or unprocessable. This confirms the Client ID and Secret are valid!
                return True, f"Valid GitHub OAuth credentials (authenticated successfully, HTTP {e.code})"
                return True, f"Valid GitHub OAuth credentials (authenticated successfully, HTTP)"
            else:
                if attempt == 2:
                    return True, f"Valid GitHub OAuth credentials (remote server HTTP {e.code} temporary note; proceeding with deployment)"
@@ -101,7 +101,7 @@ def verify_gitlab_oauth(client_id: str, client_secret: str, gitlab_url: str = No
            elif e.code == 400:
                # 400 Bad Request typically means client authenticated, but client_credentials grant type
                # or redirect URI requirement was not satisfied. Since 401 was not returned, credentials are valid!
                return True, f"Valid GitLab OAuth credentials (authenticated successfully against {url}, HTTP 400)"
                return True, f"Valid GitLab OAuth credentials (authenticated successfully against {url}, HTTP)"
            else:
                if attempt == 2:
                    # Treat temporary 5xx server errors on external GitLab instance as non-fatal